@ahrowe/ui 0.39.0 → 0.40.0

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 (138) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs-types/common/calendar/calendar.d.ts +4 -0
  3. package/dist/cjs-types/common/calendar/calendar.types.d.ts +141 -0
  4. package/dist/cjs-types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
  5. package/dist/cjs-types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
  6. package/dist/cjs-types/common/calendar/components/agendaList/index.d.ts +1 -0
  7. package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
  8. package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
  9. package/dist/cjs-types/common/calendar/components/calendarHeader/index.d.ts +1 -0
  10. package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
  11. package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
  12. package/dist/cjs-types/common/calendar/components/compactMonth/index.d.ts +1 -0
  13. package/dist/cjs-types/common/calendar/components/monthView/index.d.ts +1 -0
  14. package/dist/cjs-types/common/calendar/components/monthView/monthView.d.ts +5 -0
  15. package/dist/cjs-types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
  16. package/dist/cjs-types/common/calendar/components/timeGrid/index.d.ts +1 -0
  17. package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
  18. package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
  19. package/dist/cjs-types/common/calendar/dates.d.ts +50 -0
  20. package/dist/cjs-types/common/calendar/format.d.ts +32 -0
  21. package/dist/cjs-types/common/calendar/gesture.d.ts +32 -0
  22. package/dist/cjs-types/common/calendar/index.d.ts +2 -0
  23. package/dist/cjs-types/common/calendar/layout.d.ts +74 -0
  24. package/dist/cjs-types/common/calendar/useGestures.d.ts +37 -0
  25. package/dist/cjs-types/common/calendar/usePager.d.ts +20 -0
  26. package/dist/cjs-types/common/calendar/view.types.d.ts +26 -0
  27. package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +3 -0
  28. package/dist/cjs-types/common/confirmModal/confirmModal.types.d.ts +1 -1
  29. package/dist/cjs-types/common/datePicker/index.d.ts +1 -1
  30. package/dist/cjs-types/common/modal/modal.types.d.ts +4 -3
  31. package/dist/cjs-types/common/themeProvider/theme.types.d.ts +8 -0
  32. package/dist/cjs-types/common/utils/day.d.ts +8 -0
  33. package/dist/cjs-types/common/virtualList/useColumns.d.ts +3 -1
  34. package/dist/cjs-types/index.d.ts +2 -0
  35. package/dist/esm/common/calendar/calendar.mjs +2 -0
  36. package/dist/esm/common/calendar/calendar.mjs.map +1 -0
  37. package/dist/esm/common/calendar/calendar.module.mjs +2 -0
  38. package/dist/esm/common/calendar/calendar.module.mjs.map +1 -0
  39. package/dist/esm/common/calendar/calendar.types.mjs +2 -0
  40. package/dist/esm/common/calendar/calendar.types.mjs.map +1 -0
  41. package/dist/esm/common/calendar/components/agendaList/agendaList.mjs +2 -0
  42. package/dist/esm/common/calendar/components/agendaList/agendaList.mjs.map +1 -0
  43. package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs +2 -0
  44. package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs.map +1 -0
  45. package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs +2 -0
  46. package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs.map +1 -0
  47. package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs +2 -0
  48. package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs.map +1 -0
  49. package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs +2 -0
  50. package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs.map +1 -0
  51. package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs +2 -0
  52. package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs.map +1 -0
  53. package/dist/esm/common/calendar/components/monthView/monthView.mjs +2 -0
  54. package/dist/esm/common/calendar/components/monthView/monthView.mjs.map +1 -0
  55. package/dist/esm/common/calendar/components/monthView/monthView.module.mjs +2 -0
  56. package/dist/esm/common/calendar/components/monthView/monthView.module.mjs.map +1 -0
  57. package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs +2 -0
  58. package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs.map +1 -0
  59. package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs +2 -0
  60. package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs.map +1 -0
  61. package/dist/esm/common/calendar/dates.mjs +2 -0
  62. package/dist/esm/common/calendar/dates.mjs.map +1 -0
  63. package/dist/esm/common/calendar/format.mjs +2 -0
  64. package/dist/esm/common/calendar/format.mjs.map +1 -0
  65. package/dist/esm/common/calendar/gesture.mjs +2 -0
  66. package/dist/esm/common/calendar/gesture.mjs.map +1 -0
  67. package/dist/esm/common/calendar/layout.mjs +2 -0
  68. package/dist/esm/common/calendar/layout.mjs.map +1 -0
  69. package/dist/esm/common/calendar/pager.module.mjs +2 -0
  70. package/dist/esm/common/calendar/pager.module.mjs.map +1 -0
  71. package/dist/esm/common/calendar/useGestures.mjs +2 -0
  72. package/dist/esm/common/calendar/useGestures.mjs.map +1 -0
  73. package/dist/esm/common/calendar/usePager.mjs +2 -0
  74. package/dist/esm/common/calendar/usePager.mjs.map +1 -0
  75. package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
  76. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  77. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
  78. package/dist/esm/common/datePicker/dateFunctions.mjs +1 -1
  79. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  80. package/dist/esm/common/input/input.mjs +1 -1
  81. package/dist/esm/common/input/input.mjs.map +1 -1
  82. package/dist/esm/common/modal/modal.mjs +1 -1
  83. package/dist/esm/common/modal/modal.mjs.map +1 -1
  84. package/dist/esm/common/popover/popover.mjs +1 -1
  85. package/dist/esm/common/popover/popover.mjs.map +1 -1
  86. package/dist/esm/common/scrollFade/scrollFade.mjs +1 -1
  87. package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
  88. package/dist/esm/common/utils/day.mjs +1 -1
  89. package/dist/esm/common/utils/day.mjs.map +1 -1
  90. package/dist/esm/common/virtualList/useColumns.mjs +1 -1
  91. package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
  92. package/dist/esm/common/virtualList/virtualList.mjs +1 -1
  93. package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
  94. package/dist/esm/index.mjs +1 -1
  95. package/dist/index.cjs +3 -3
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/style.css +1 -1
  98. package/dist/types/common/calendar/calendar.d.ts +4 -0
  99. package/dist/types/common/calendar/calendar.types.d.ts +141 -0
  100. package/dist/types/common/calendar/components/agendaList/agendaList.d.ts +5 -0
  101. package/dist/types/common/calendar/components/agendaList/agendaList.types.d.ts +23 -0
  102. package/dist/types/common/calendar/components/agendaList/index.d.ts +1 -0
  103. package/dist/types/common/calendar/components/calendarHeader/calendarHeader.d.ts +4 -0
  104. package/dist/types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +17 -0
  105. package/dist/types/common/calendar/components/calendarHeader/index.d.ts +1 -0
  106. package/dist/types/common/calendar/components/compactMonth/compactMonth.d.ts +9 -0
  107. package/dist/types/common/calendar/components/compactMonth/compactMonth.types.d.ts +1 -0
  108. package/dist/types/common/calendar/components/compactMonth/index.d.ts +1 -0
  109. package/dist/types/common/calendar/components/monthView/index.d.ts +1 -0
  110. package/dist/types/common/calendar/components/monthView/monthView.d.ts +5 -0
  111. package/dist/types/common/calendar/components/monthView/monthView.types.d.ts +10 -0
  112. package/dist/types/common/calendar/components/timeGrid/index.d.ts +1 -0
  113. package/dist/types/common/calendar/components/timeGrid/timeGrid.d.ts +5 -0
  114. package/dist/types/common/calendar/components/timeGrid/timeGrid.types.d.ts +40 -0
  115. package/dist/types/common/calendar/dates.d.ts +50 -0
  116. package/dist/types/common/calendar/format.d.ts +32 -0
  117. package/dist/types/common/calendar/gesture.d.ts +32 -0
  118. package/dist/types/common/calendar/index.d.ts +2 -0
  119. package/dist/types/common/calendar/layout.d.ts +74 -0
  120. package/dist/types/common/calendar/useGestures.d.ts +37 -0
  121. package/dist/types/common/calendar/usePager.d.ts +20 -0
  122. package/dist/types/common/calendar/view.types.d.ts +26 -0
  123. package/dist/types/common/configProvider/configProvider.types.d.ts +3 -0
  124. package/dist/types/common/confirmModal/confirmModal.types.d.ts +1 -1
  125. package/dist/types/common/datePicker/index.d.ts +1 -1
  126. package/dist/types/common/modal/modal.types.d.ts +4 -3
  127. package/dist/types/common/themeProvider/theme.types.d.ts +8 -0
  128. package/dist/types/common/utils/day.d.ts +8 -0
  129. package/dist/types/common/virtualList/useColumns.d.ts +3 -1
  130. package/dist/types/index.d.ts +2 -0
  131. package/docs/CLAUDE.md +7 -5
  132. package/docs/Calendar.md +184 -0
  133. package/docs/ConfigProvider.md +2 -1
  134. package/docs/ConfirmModal.md +1 -1
  135. package/docs/DatePicker.md +9 -2
  136. package/docs/Modal.md +2 -2
  137. package/docs/TimeInput.md +2 -0
  138. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeGrid.module.mjs","names":[],"sources":["../../../../../../package/common/calendar/components/timeGrid/timeGrid.module.pcss"],"sourcesContent":["/* One vertical scroller holds the sticky head and the body, so the head's day columns line up\n with the body's by construction, scrollbar or not. Only the two tracks inside move sideways.\n Everything positioned in time uses percentages of the day, so zooming rewrites one custom\n property and nothing else. */\n.timeGrid {\n --gutter: 3.5em;\n --lane: 1.375em;\n\n position: relative;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n outline: none;\n user-select: none;\n -webkit-touch-callout: none;\n\n /* Horizontal swipes page, pinches zoom, vertical drags still scroll. */\n touch-action: pan-y;\n\n &-head {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n grid-template-columns: var(--gutter) minmax(0, 1fr);\n border-bottom: 1px solid var(--border-color);\n background: var(--background);\n }\n\n &-corner {\n display: flex;\n align-items: flex-end;\n justify-content: center;\n padding-bottom: 0.25em;\n }\n\n &-toggle {\n display: grid;\n place-items: center;\n width: 1.75em;\n height: 1.75em;\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--text-dark);\n font-size: 0.75em;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: transform 0.2s ease;\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-open {\n transform: rotate(180deg);\n }\n }\n\n &-headPane {\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n align-content: start;\n background: var(--background);\n }\n\n &-dayHeader {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.125em;\n padding: 0.375em 0 0.25em;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n\n &-link {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover .timeGrid-dayNumber:not(.timeGrid-dayNumber-today) {\n background: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -2px;\n border-radius: var(--default-border-radius);\n }\n }\n }\n\n &-weekday {\n font-size: 0.6875em;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--text-dark);\n }\n\n &-dayNumber {\n display: grid;\n place-items: center;\n width: 1.875em;\n height: 1.875em;\n border-radius: 50%;\n font-size: 1.125em;\n font-weight: 500;\n font-variant-numeric: tabular-nums;\n transition: background-color 0.15s ease;\n\n &-today {\n background: var(--custom-calendar-today-color);\n color: var(--text-on-primary);\n font-weight: 700;\n }\n }\n\n &-allDay {\n grid-column: 1 / -1;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n grid-auto-rows: var(--lane);\n row-gap: 2px;\n min-height: 0.5em;\n padding: 2px 0 4px;\n }\n\n &-bar {\n --event: var(--event-color, var(--primary-color));\n\n min-width: 0;\n margin: 0 2px;\n padding: 0 0.5em;\n overflow: hidden;\n border: 0;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n box-shadow: inset 3px 0 0 var(--event);\n color: var(--text-color);\n font: inherit;\n font-size: 0.75em;\n font-weight: 500;\n text-align: left;\n white-space: nowrap;\n text-overflow: ellipsis;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-continuesBefore {\n margin-left: 0;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n box-shadow: none;\n }\n\n &-continuesAfter {\n margin-right: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &-title {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n &-more {\n align-self: center;\n margin: 0 2px;\n padding: 0 0.5em;\n border-radius: var(--custom-calendar-event-radius);\n font-size: 0.75em;\n font-weight: 600;\n white-space: nowrap;\n color: var(--text-dark);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n\n /* Its own stacking context, which keeps everything drawn in the hours under the sticky head\n above. Inside it, the now-line and the drag preview come after the events in the markup,\n and so paint over them without a z-index. */\n &-body {\n isolation: isolate;\n display: grid;\n grid-template-columns: var(--gutter) minmax(0, 1fr);\n height: calc(24 * var(--custom-calendar-hour-height));\n }\n\n &-gutter {\n position: relative;\n }\n\n &-hour {\n position: absolute;\n right: 0.625em;\n font-size: 0.6875em;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n color: var(--text-light);\n transform: translateY(-50%);\n }\n\n &-bodyPane {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--days), minmax(0, 1fr));\n height: 100%;\n background: var(--background);\n }\n\n /* Hour lines, and fainter half-hour lines between them. */\n &-column {\n /* Events leave a strip on the right free, so there is always somewhere to press to create. */\n --column-width: calc(100% - 0.75em);\n\n position: relative;\n min-width: 0;\n border-left: 1px solid var(--border-color);\n background-image:\n linear-gradient(var(--border-color) 1px, transparent 1px),\n linear-gradient(color-mix(in oklab, var(--border-color) 45%, transparent) 1px, transparent 1px);\n background-position:\n 0 0,\n 0 calc(var(--custom-calendar-hour-height) / 2);\n background-size: 100% var(--custom-calendar-hour-height);\n\n &-today {\n background-color: color-mix(in oklab, var(--custom-calendar-today-color) 4%, transparent);\n }\n\n &-creatable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n }\n\n &-event {\n --event: var(--event-color, var(--primary-color));\n\n position: absolute;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n min-width: 0;\n height: var(--span);\n margin: 0;\n padding: 0.2em 0.45em 0.2em 0.6em;\n overflow: hidden;\n container-type: size;\n border: 0;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n\n /* The outline in the page colour keeps side-by-side events apart. */\n box-shadow:\n inset 3px 0 0 var(--event),\n 0 0 0 1px var(--background);\n color: var(--text-color);\n font: inherit;\n font-size: 0.75em;\n line-height: 1.3;\n text-align: left;\n transition:\n background-color 0.15s ease,\n opacity 0.15s ease;\n\n &:hover {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n }\n\n &:focus-visible {\n z-index: 1;\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n }\n\n &-short {\n flex-direction: row;\n\n /* Not `baseline`: a 15-minute event is shorter than its line, and centring clips it evenly\n rather than cutting off the bottom. Title and time share a font size, so they still line up. */\n align-items: center;\n gap: 0.4em;\n padding-block: 0;\n }\n\n /* Too short for its label, which would be clipped to nothing: a bar of its real length, and\n the label on a line of its own beneath it, in the room packDay leaves for it. */\n &-brief {\n /* One line, with room for the descenders that a line height of 1 clips in Firefox. Keep\n BRIEF_LABEL_MINUTES in layout.ts at least this tall at the default hour height. */\n --label: 1.25em;\n\n isolation: isolate;\n height: calc(var(--span) + var(--label));\n align-items: flex-end;\n line-height: var(--label);\n background: none;\n box-shadow: none;\n\n /* Under the label, which it covers once zoomed in: see the @container rule below. */\n &::before {\n content: '';\n position: absolute;\n z-index: -1;\n top: 0;\n right: 0;\n left: 0;\n height: max(2px, 100% - var(--label));\n border-radius: inherit;\n background: var(--event);\n transition:\n background-color 0.15s ease,\n opacity 0.15s ease;\n }\n\n &:hover {\n background: none;\n\n &::before {\n opacity: 0.75;\n }\n }\n\n /* On the bar's end, which is the event's, rather than under the label. */\n .timeGrid-resize {\n bottom: calc(var(--label) - 0.3em);\n height: 0.6em;\n max-height: none;\n }\n }\n\n &-continuesBefore {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n &-continuesAfter {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n &-interactive {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-dragged {\n opacity: 0.4;\n }\n\n &-title {\n flex: none;\n overflow: hidden;\n font-weight: 600;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n &-time {\n overflow: hidden;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n text-overflow: ellipsis;\n color: var(--text-dark);\n }\n }\n\n &-resize {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 0.625em;\n\n /* Half at most, so a short event keeps a part that moves it: a finger's grip is taller. */\n max-height: 50%;\n cursor: ns-resize;\n\n /* A visible grip where a finger is the pointer, since there is no hover to reveal it. */\n @media (pointer: coarse) {\n height: 1.5em;\n\n &::after {\n content: '';\n position: absolute;\n bottom: 0.3em;\n left: 50%;\n width: 1.5em;\n height: 0.25em;\n border-radius: 0.125em;\n background: color-mix(in oklab, var(--event) 70%, var(--background));\n translate: -50% 0;\n }\n }\n }\n\n &-preview {\n --event: var(--event-color, var(--primary-color));\n\n position: absolute;\n left: 0;\n width: var(--column-width);\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n padding: 0.2em 0.45em 0.2em 0.6em;\n overflow: hidden;\n border-radius: var(--custom-calendar-event-radius);\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n box-shadow:\n inset 3px 0 0 var(--event),\n 0 0.5em 1.25em color-mix(in oklab, var(--text-color) 22%, transparent);\n color: var(--text-color);\n font-size: 0.75em;\n line-height: 1.3;\n pointer-events: none;\n\n &-time {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n }\n\n /* The anchor `onSlotCreate` hands out, moved over each new slot. Transparent rather than\n hidden, so it keeps the box a popover measures and anchors to. */\n &-slot {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n }\n\n &-now {\n position: absolute;\n right: 0;\n left: 0;\n height: 2px;\n margin-top: -1px;\n background: var(--custom-calendar-now-color);\n pointer-events: none;\n\n &::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 0;\n width: 0.625em;\n height: 0.625em;\n border-radius: 50%;\n background: var(--custom-calendar-now-color);\n translate: -50% -50%;\n animation: calendarNowPulse 2.4s ease-in-out infinite;\n }\n }\n}\n\n/* Zoomed in until its bar holds its label, a brief event is drawn like any other, its label\n centred in the bar. 2.5em is twice the label's line: a condition cannot read `--label`. */\n@container (height >= 2.5em) {\n .timeGrid-event-brief::before {\n background: color-mix(in oklab, var(--event) 22%, var(--background));\n box-shadow: inset 3px 0 0 var(--event);\n }\n\n .timeGrid-event-brief:hover::before {\n background: color-mix(in oklab, var(--event) 32%, var(--background));\n opacity: 1;\n }\n\n .timeGrid-event-brief .timeGrid-event-title,\n .timeGrid-event-brief .timeGrid-event-time {\n align-self: flex-start;\n margin-top: calc((100cqh - 2 * var(--label)) / 2);\n }\n}\n\n/* An event shorter than its text shows its colour alone, not a slice of clipped letters. The `em`\n is the event's own font size, and zooming in brings the text back. */\n@container (height < 0.8em) {\n .timeGrid-event-title,\n .timeGrid-event-time {\n display: none;\n }\n}\n\n@keyframes calendarNowPulse {\n 50% {\n box-shadow: 0 0 0 0.3em color-mix(in oklab, var(--custom-calendar-now-color) 25%, transparent);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .timeGrid-toggle {\n transition: none;\n }\n\n .timeGrid-now::before {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use client";import{dateToDay as e}from"../utils/day.mjs";import{CalendarView as t}from"./calendar.types.mjs";var n=1440;function r(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())}function i(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t)}function a(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate()+t,e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())}function o(e,t){return new Date(e,t+1,0).getDate()}function s(e,t){let n=new Date(e.getFullYear(),e.getMonth()+t,1),r=Math.min(e.getDate(),o(n.getFullYear(),n.getMonth()));return new Date(n.getFullYear(),n.getMonth(),r)}function c(e){return new Date(e.getFullYear(),e.getMonth(),1)}function l(e,t){return i(e,-((e.getDay()-t+7)%7))}function u(e,t){let n=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()),r=Date.UTC(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((r-n)/864e5)}function d(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}function f(e){return e.getHours()*60+e.getMinutes()}function p(e,t){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),0,t)}function m(e,t,n){return t>e?t:new Date(e.getTime()+n*6e4)}function h(e,n,i){switch(e){case t.Week:return l(n,i);case t.Day:return r(n);default:return c(n)}}function g(e,n,r){let a=h(e,n,r);switch(e){case t.Month:{let e=l(a,r);return{start:e,end:i(e,42)}}case t.Week:return{start:a,end:i(a,7)};case t.Day:return{start:a,end:i(a,1)};default:return{start:a,end:s(a,1)}}}var _=new Set;function v(e){let t=new Set(e);return t.size===0||[0,1,2,3,4,5,6].every(e=>t.has(e))?_:t}function y(e,t,n=1){let a=r(e);for(;t.has(a.getDay());)a=i(a,n);return a}function b(e,n,r,a=_){switch(e){case t.Week:return i(n,7*r);case t.Day:{let e=r<0?-1:1,t=n;for(let n=0;n<Math.abs(r);n++)t=y(i(t,e),a,e);return t}default:return s(n,r)}}function x(e,t,n,r=_){return{start:g(e,b(e,t,-1,r),n).start,end:g(e,b(e,t,1,r),n).end}}function S(e,t){return Array.from({length:t},(t,n)=>i(e,n))}function C(e,t,n=_){return S(e,t).filter(e=>!n.has(e.getDay()))}var w={ArrowLeft:-1,ArrowRight:1,ArrowUp:-7,ArrowDown:7};function T(e,t,n){return e in w?i(t,w[e]):e===`Home`?l(t,n):e===`End`?i(l(t,n),6):e===`PageUp`?s(t,-1):e===`PageDown`?s(t,1):null}function E(e,t,n,r=_){let i=T(e,t,n);return i&&y(i,r,e===`ArrowLeft`||e===`End`?-1:1)}export{n as MINUTES_PER_DAY,i as addDays,s as addMonths,p as atMinutes,e as dateToDay,u as dayDiff,S as daysFrom,o as daysInMonth,m as endAfter,E as gridKeyTarget,v as hiddenDaySet,d as isSameDay,f as minutesOfDay,g as periodRange,h as periodStart,x as rangeWithNeighbours,a as shiftDays,y as shownDay,C as shownDays,r as startOfDay,c as startOfMonth,l as startOfWeek,b as stepDate};
2
+ //# sourceMappingURL=dates.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dates.mjs","names":[],"sources":["../../../../package/common/calendar/dates.ts"],"sourcesContent":["import { CalendarView, type CalendarRange, type CalendarWeekStart } from './calendar.types';\n\n// All arithmetic goes through the local date fields rather than milliseconds: a day with a\n// daylight-saving change is 23 or 25 hours long, so adding 86 400 000 ms lands on the wrong day.\n\nexport const MINUTES_PER_DAY = 1440;\n\nexport function startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\n/** Midnight, `days` calendar days away. */\nexport function addDays(date: Date, days: number): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\n/** The same wall-clock time, `days` calendar days away. */\nexport function shiftDays(date: Date, days: number): Date {\n return new Date(\n date.getFullYear(),\n date.getMonth(),\n date.getDate() + days,\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n );\n}\n\nexport function daysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate();\n}\n\n/** Midnight, `months` months away. The day is clamped, so 31 January plus one month is the end of February. */\nexport function addMonths(date: Date, months: number): Date {\n const target = new Date(date.getFullYear(), date.getMonth() + months, 1);\n const day = Math.min(date.getDate(), daysInMonth(target.getFullYear(), target.getMonth()));\n return new Date(target.getFullYear(), target.getMonth(), day);\n}\n\nexport function startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nexport function startOfWeek(date: Date, weekStartsOn: CalendarWeekStart): Date {\n return addDays(date, -((date.getDay() - weekStartsOn + 7) % 7));\n}\n\n/** Calendar days from `a` to `b`, whatever their times of day. */\nexport function dayDiff(a: Date, b: Date): number {\n const utcA = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());\n const utcB = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());\n return Math.round((utcB - utcA) / 86_400_000);\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\n// `'2026-09-26'` is also the key for lookups and React keys. Never `getTime()`: where a clock\n// change happens at midnight (America/Santiago), the day's first moment is 01:00, and two paths to\n// the same day disagree.\nexport { dateToDay } from '../utils/day';\n\n/** Wall-clock minutes since midnight. On a 25-hour day the repeated hour maps onto itself. */\nexport function minutesOfDay(date: Date): number {\n return date.getHours() * 60 + date.getMinutes();\n}\n\n/**\n * The wall-clock time `minutes` after the start of `day`; 1440 is the next midnight. A time the\n * clock skips resolves forwards (02:30 becomes 03:30) and a repeated one to its first occurrence.\n */\nexport function atMinutes(day: Date, minutes: number): Date {\n return new Date(day.getFullYear(), day.getMonth(), day.getDate(), 0, minutes);\n}\n\n/**\n * `end`, unless a clock change turned the range around: where one end lands in the hour the\n * clocks skip, a wall-clock end can fall on or before its start. Then `minutes` of real time\n * after the start instead.\n */\nexport function endAfter(start: Date, end: Date, minutes: number): Date {\n return end > start ? end : new Date(start.getTime() + minutes * 60_000);\n}\n\n/** Midnight of the first day of the period `date` is in. */\nexport function periodStart(view: CalendarView, date: Date, weekStartsOn: CalendarWeekStart): Date {\n switch (view) {\n case CalendarView.Week:\n return startOfWeek(date, weekStartsOn);\n case CalendarView.Day:\n return startOfDay(date);\n default:\n return startOfMonth(date);\n }\n}\n\n/** The days a view shows for `date`. The month view is always six full weeks. */\nexport function periodRange(view: CalendarView, date: Date, weekStartsOn: CalendarWeekStart): CalendarRange {\n const start = periodStart(view, date, weekStartsOn);\n switch (view) {\n case CalendarView.Month: {\n const gridStart = startOfWeek(start, weekStartsOn);\n return { start: gridStart, end: addDays(gridStart, 42) };\n }\n case CalendarView.Week:\n return { start, end: addDays(start, 7) };\n case CalendarView.Day:\n return { start, end: addDays(start, 1) };\n default:\n return { start, end: addMonths(start, 1) };\n }\n}\n\nconst NO_DAYS: ReadonlySet<number> = new Set();\n\n/** `hiddenDays` as a lookup. A list that leaves no day of the week hides nothing. */\nexport function hiddenDaySet(hiddenDays: readonly number[] | undefined): ReadonlySet<number> {\n const hidden = new Set(hiddenDays);\n return hidden.size === 0 || [0, 1, 2, 3, 4, 5, 6].every((day) => hidden.has(day)) ? NO_DAYS : hidden;\n}\n\n/** `date`, or the first shown day from it on in `direction`. */\nexport function shownDay(date: Date, hidden: ReadonlySet<number>, direction: 1 | -1 = 1): Date {\n let day = startOfDay(date);\n while (hidden.has(day.getDay())) day = addDays(day, direction);\n return day;\n}\n\n/** `date` moved by `steps` periods, keeping its place in the period where it can. */\nexport function stepDate(view: CalendarView, date: Date, steps: number, hidden: ReadonlySet<number> = NO_DAYS): Date {\n switch (view) {\n case CalendarView.Week:\n return addDays(date, 7 * steps);\n case CalendarView.Day: {\n const direction = steps < 0 ? -1 : 1;\n let day = date;\n for (let i = 0; i < Math.abs(steps); i++) day = shownDay(addDays(day, direction), hidden, direction);\n return day;\n }\n default:\n return addMonths(date, steps);\n }\n}\n\n/** The shown period plus one on either side: what the swipe pager can reveal. */\nexport function rangeWithNeighbours(\n view: CalendarView,\n date: Date,\n weekStartsOn: CalendarWeekStart,\n hidden: ReadonlySet<number> = NO_DAYS,\n): CalendarRange {\n return {\n start: periodRange(view, stepDate(view, date, -1, hidden), weekStartsOn).start,\n end: periodRange(view, stepDate(view, date, 1, hidden), weekStartsOn).end,\n };\n}\n\n/** Midnight of each of `count` days from `start`. */\nexport function daysFrom(start: Date, count: number): Date[] {\n return Array.from({ length: count }, (_, i) => addDays(start, i));\n}\n\n/** The days of `count` from `start` that are not hidden: the columns a row of them draws. */\nexport function shownDays(start: Date, count: number, hidden: ReadonlySet<number> = NO_DAYS): Date[] {\n return daysFrom(start, count).filter((day) => !hidden.has(day.getDay()));\n}\n\nconst KEY_DAYS: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -7, ArrowDown: 7 };\n\nfunction keyTarget(key: string, day: Date, weekStartsOn: CalendarWeekStart): Date | null {\n if (key in KEY_DAYS) return addDays(day, KEY_DAYS[key]);\n if (key === 'Home') return startOfWeek(day, weekStartsOn);\n if (key === 'End') return addDays(startOfWeek(day, weekStartsOn), 6);\n if (key === 'PageUp') return addMonths(day, -1);\n if (key === 'PageDown') return addMonths(day, 1);\n return null;\n}\n\n/**\n * The day a month grid moves to for `key`, or `null` for a key it does not handle. A hidden day\n * gives way to the next shown one in the direction the key points, so the focus stays on a cell.\n */\nexport function gridKeyTarget(\n key: string,\n day: Date,\n weekStartsOn: CalendarWeekStart,\n hidden: ReadonlySet<number> = NO_DAYS,\n): Date | null {\n const target = keyTarget(key, day, weekStartsOn);\n return target && shownDay(target, hidden, key === 'ArrowLeft' || key === 'End' ? -1 : 1);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";import{CalendarView as e}from"./calendar.types.mjs";import{addDays as t}from"./dates.mjs";var n=new Map,r;function i(){return r===void 0&&(r=new Intl.DateTimeFormat().resolvedOptions().timeZone,queueMicrotask(()=>{r=void 0})),r}function a(e,t){let r=`${i()}|${e??``}|${JSON.stringify(t)}`,a=n.get(r);return a||(a=new Intl.DateTimeFormat(e,t),n.set(r,a)),a}function o(e,t,n){return e.formatRange(t,n)}var s=new Map;function c(e){let t=e??``,n=s.get(t);if(n!==void 0)return n;let r=1;try{let t=e??new Intl.DateTimeFormat().resolvedOptions().locale,n=new Intl.Locale(t),i=n.getWeekInfo?.()??n.weekInfo;i&&(r=i.firstDay%7)}catch{}return s.set(t,r),r}function l(e){let t=a(e,{hour:`numeric`}).resolvedOptions().hourCycle;return t===`h11`||t===`h12`}function u(e,t){return a(t,{hour:`numeric`,minute:`2-digit`}).format(e)}function d(e,t,n){return o(a(n,{hour:`numeric`,minute:`2-digit`}),e,t)}function f(e,t,n){let r=new Date(2e3,0,1,e.getHours(),e.getMinutes()),i=new Date(2e3,0,1,t.getHours(),t.getMinutes());try{return o(a(n,{hour:`numeric`,minute:`2-digit`}),r,i)}catch{return u(e,n)}}function p(e,t){let n=new Date(2e3,0,1,e);return l(t)?a(t,{hour:`numeric`}).format(n):a(t,{hour:`2-digit`,minute:`2-digit`}).format(n)}function m(e,t,n){return a(t,{weekday:n}).format(e)}function h(e,t){return a(t,{day:`numeric`}).format(e)}function g(e,t){return a(t,{weekday:`long`,day:`numeric`,month:`long`,year:`numeric`}).format(e)}function _(e,t){return a(t,{month:`long`,year:`numeric`}).format(e)}function v(n,r,i,s){switch(n){case e.Week:return o(a(s,{day:`numeric`,month:`short`,year:`numeric`}),i.start,t(i.end,-1));case e.Day:return g(r,s);default:return _(r,s)}}export{f as formatClockRange,h as formatDayNumber,p as formatHour,g as formatLongDate,_ as formatMonthTitle,v as formatPeriodTitle,u as formatTime,d as formatTimeRange,m as formatWeekday,a as formatter,c as localeWeekStart};
2
+ //# sourceMappingURL=format.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.mjs","names":[],"sources":["../../../../package/common/calendar/format.ts"],"sourcesContent":["import { CalendarView, type CalendarRange, type CalendarWeekStart } from './calendar.types';\nimport { addDays } from './dates';\n\n// `locale` is passed to Intl as given, and `undefined` means the browser's locale. Not\n// `getLocale()` from services/localization: it narrows to a few supported locales and maps\n// en-GB to en-US, which would give British users 12-hour times.\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\nlet zone: string | undefined;\n\n/**\n * Read once per task: reading the zone costs as much as building a formatter. Its name, not its\n * offsets, because Casablanca and Brazzaville share January's and July's but not March's.\n */\nfunction currentZone(): string {\n if (zone === undefined) {\n zone = new Intl.DateTimeFormat().resolvedOptions().timeZone;\n queueMicrotask(() => {\n zone = undefined;\n });\n }\n return zone;\n}\n\n/**\n * Cached, since building one costs about fifty times more than using it. A formatter keeps the\n * time zone it was built in while `Date` follows the current one, so the key carries the zone: a\n * zone change (the device's, or `process.env.TZ` between tests) then builds a new formatter\n * instead of labelling days in the old zone.\n */\nexport function formatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n const key = `${currentZone()}|${locale ?? ''}|${JSON.stringify(options)}`;\n let cached = formatters.get(key);\n if (!cached) {\n cached = new Intl.DateTimeFormat(locale, options);\n formatters.set(key, cached);\n }\n return cached;\n}\n\n// ES2020's lib predates `formatRange`, which every supported browser has had since 2021.\nfunction formatRange(format: Intl.DateTimeFormat, start: Date, end: Date): string {\n return (format as Intl.DateTimeFormat & { formatRange(a: Date, b: Date): string }).formatRange(start, end);\n}\n\ntype WeekInfoLocale = Intl.Locale & {\n getWeekInfo?: () => { firstDay: number };\n /** The accessor form Chrome 99 to 129 and Safari 15.4 to 16 shipped before the method. */\n weekInfo?: { firstDay: number };\n};\n\nconst weekStarts = new Map<string, CalendarWeekStart>();\n\n/**\n * The locale's first day of the week, falling back to Monday where `getWeekInfo` is missing:\n * it is Baseline only since July 2026 (Chrome 130, Firefox 153, Safari 17).\n */\nexport function localeWeekStart(locale: string | undefined): CalendarWeekStart {\n const key = locale ?? '';\n const cached = weekStarts.get(key);\n if (cached !== undefined) return cached;\n\n let result: CalendarWeekStart = 1;\n try {\n const tag = locale ?? new Intl.DateTimeFormat().resolvedOptions().locale;\n const info = new Intl.Locale(tag) as WeekInfoLocale;\n const weekInfo = info.getWeekInfo?.() ?? info.weekInfo;\n // `firstDay` counts 1 (Monday) to 7 (Sunday); `getDay()` counts 0 (Sunday) to 6.\n if (weekInfo) result = (weekInfo.firstDay % 7) as CalendarWeekStart;\n } catch {\n // An invalid tag: Intl.DateTimeFormat would have thrown for it too, so keep the fallback.\n }\n weekStarts.set(key, result);\n return result;\n}\n\nfunction uses12Hour(locale: string | undefined): boolean {\n // `hourCycle` is missing from ES2020's lib typings, not from any supported browser.\n const options = formatter(locale, { hour: 'numeric' }).resolvedOptions() as { hourCycle?: string };\n const cycle = options.hourCycle;\n return cycle === 'h11' || cycle === 'h12';\n}\n\nexport function formatTime(date: Date, locale: string | undefined): string {\n return formatter(locale, { hour: 'numeric', minute: '2-digit' }).format(date);\n}\n\n/** A time span, with the dates added by Intl where the two ends fall on different days. */\nexport function formatTimeRange(start: Date, end: Date, locale: string | undefined): string {\n return formatRange(formatter(locale, { hour: 'numeric', minute: '2-digit' }), start, end);\n}\n\n/**\n * The clock times alone, `10:00 PM to 2:00 AM` as the locale writes it, where `formatTimeRange` would add both dates for\n * an event that crosses midnight. Both ends are moved onto one day for it. The first spec of\n * `formatRange` threw a RangeError for an end earlier than the start; an engine still doing that\n * gets the start time alone.\n */\nexport function formatClockRange(start: Date, end: Date, locale: string | undefined): string {\n const from = new Date(2000, 0, 1, start.getHours(), start.getMinutes());\n const to = new Date(2000, 0, 1, end.getHours(), end.getMinutes());\n try {\n return formatRange(formatter(locale, { hour: 'numeric', minute: '2-digit' }), from, to);\n } catch {\n return formatTime(start, locale);\n }\n}\n\n/** `9 AM` where the locale counts to twelve, `09:00` where it counts to 24. */\nexport function formatHour(hour: number, locale: string | undefined): string {\n const date = new Date(2000, 0, 1, hour);\n return uses12Hour(locale)\n ? formatter(locale, { hour: 'numeric' }).format(date)\n : formatter(locale, { hour: '2-digit', minute: '2-digit' }).format(date);\n}\n\nexport function formatWeekday(date: Date, locale: string | undefined, width: 'long' | 'short' | 'narrow'): string {\n return formatter(locale, { weekday: width }).format(date);\n}\n\n/** The day of the month in the locale's own digits. */\nexport function formatDayNumber(date: Date, locale: string | undefined): string {\n return formatter(locale, { day: 'numeric' }).format(date);\n}\n\nexport function formatLongDate(date: Date, locale: string | undefined): string {\n return formatter(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }).format(date);\n}\n\nexport function formatShortDate(date: Date, locale: string | undefined): string {\n return formatter(locale, { weekday: 'short', day: 'numeric', month: 'short' }).format(date);\n}\n\nexport function formatMonthTitle(date: Date, locale: string | undefined): string {\n return formatter(locale, { month: 'long', year: 'numeric' }).format(date);\n}\n\nexport function formatPeriodTitle(\n view: CalendarView,\n date: Date,\n range: CalendarRange,\n locale: string | undefined,\n): string {\n switch (view) {\n case CalendarView.Week:\n return formatRange(\n formatter(locale, { day: 'numeric', month: 'short', year: 'numeric' }),\n range.start,\n addDays(range.end, -1),\n );\n case CalendarView.Day:\n return formatLongDate(date, locale);\n default:\n return formatMonthTitle(date, locale);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";var e=.2,t=.5;function n(e,t,n){return e===0||!(Math.abs(e)>=t*.2)&&!(Math.abs(n)>=.5&&Math.sign(n)===Math.sign(e))?0:e<0?1:-1}function r(e,t,n){return e<t+48?-18*Math.min(1,(t+48-e)/48):e>n-48?18*Math.min(1,(e-(n-48))/48):0}function i(e,t){return Math.round(e/t)*t}function a(e,t,n){return Math.min(Math.max(e,t),n)}function o(e,t){let n=e.filter(e=>t-e.time<=100);if(n.length<2)return 0;let r=n[0],i=n[n.length-1],a=i.time-r.time;return a>0?(i.x-r.x)/a:0}export{e as COMMIT_RATIO,t as COMMIT_VELOCITY,a as clamp,r as edgeSpeed,n as pageStep,i as snap,o as velocityOf};
2
+ //# sourceMappingURL=gesture.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gesture.mjs","names":[],"sources":["../../../../package/common/calendar/gesture.ts"],"sourcesContent":["// Thresholds the library already settled on elsewhere, so a swipe or a long press feels the same\n// here as in Carousel, Toast and VirtualList.\n\n/** Touch movement before a press is read as a swipe or a scroll (carousel.tsx, useSwipeDismiss.ts). */\nexport const LOCK_DISTANCE = 10;\n/** Mouse movement before a press becomes a drag. */\nexport const MOUSE_DRAG_DISTANCE = 4;\n/** Hold before a touch picks something up (VirtualList's `longPressDelay`). */\nexport const LONG_PRESS_MS = 400;\n/** A touch this soon after a scroll is stopping momentum, not picking something up. */\nexport const RECENT_SCROLL_MS = 150;\n/** Share of the width a swipe must travel to page (carousel.tsx). */\nexport const COMMIT_RATIO = 0.2;\n/** px/ms a shorter flick must reach to page anyway (useSwipeDismiss.ts). */\nexport const COMMIT_VELOCITY = 0.5;\n/** How far back the flick velocity is measured. */\nexport const VELOCITY_WINDOW_MS = 100;\n/** Distance from a scroller's edge where a drag starts scrolling it (useRowDrag.ts). */\nexport const EDGE_ZONE = 48;\n/** px per frame at the very edge. */\nexport const EDGE_SPEED = 18;\n/** How long after a gesture the click it ends in is swallowed (useRowDrag.ts). */\nexport const CLICK_SUPPRESS_MS = 350;\n\n/** `1` to page forwards, `-1` back, `0` to return. A swipe to the left reveals the next period. */\nexport function pageStep(dx: number, width: number, velocity: number): -1 | 0 | 1 {\n if (dx === 0) return 0;\n const far = Math.abs(dx) >= width * COMMIT_RATIO;\n const flicked = Math.abs(velocity) >= COMMIT_VELOCITY && Math.sign(velocity) === Math.sign(dx);\n if (!far && !flicked) return 0;\n return dx < 0 ? 1 : -1;\n}\n\n/** Scroll speed for a pointer at `y` in a scroller spanning `top` to `bottom`: negative scrolls up. */\nexport function edgeSpeed(y: number, top: number, bottom: number): number {\n if (y < top + EDGE_ZONE) return -EDGE_SPEED * Math.min(1, (top + EDGE_ZONE - y) / EDGE_ZONE);\n if (y > bottom - EDGE_ZONE) return EDGE_SPEED * Math.min(1, (y - (bottom - EDGE_ZONE)) / EDGE_ZONE);\n return 0;\n}\n\nexport function snap(minutes: number, step: number): number {\n return Math.round(minutes / step) * step;\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport interface VelocitySample {\n time: number;\n x: number;\n}\n\n/** px/ms over the samples of the last `VELOCITY_WINDOW_MS`. */\nexport function velocityOf(samples: readonly VelocitySample[], now: number): number {\n const recent = samples.filter((sample) => now - sample.time <= VELOCITY_WINDOW_MS);\n if (recent.length < 2) return 0;\n const first = recent[0];\n const last = recent[recent.length - 1];\n const elapsed = last.time - first.time;\n return elapsed > 0 ? (last.x - first.x) / elapsed : 0;\n}\n"],"mappings":"aAYA,IAAa,EAAe,GAEf,EAAkB,GAW/B,SAAgB,EAAS,EAAY,EAAe,EAA8B,CAKhF,OAJI,IAAO,GAGP,EAFQ,KAAK,IAAI,CAAE,GAAK,EAAA,KAEhB,EADI,KAAK,IAAI,CAAQ,GAAA,IAAwB,KAAK,KAAK,CAAQ,IAAM,KAAK,KAAK,CAAE,GAChE,EACtB,EAAK,EAAI,EAAI,EACtB,CAGA,SAAgB,EAAU,EAAW,EAAa,EAAwB,CAGxE,OAFI,EAAI,EAAA,GAAwB,IAAc,KAAK,IAAI,GAAI,EAAA,GAAkB,GAAA,EAAc,EACvF,EAAI,EAAA,GAAoB,GAAoB,KAAK,IAAI,GAAI,GAAK,EAAA,KAAA,EAAgC,EAC3F,CACT,CAEA,SAAgB,EAAK,EAAiB,EAAsB,CAC1D,OAAO,KAAK,MAAM,EAAU,CAAI,EAAI,CACtC,CAEA,SAAgB,EAAM,EAAe,EAAa,EAAqB,CACrE,OAAO,KAAK,IAAI,KAAK,IAAI,EAAO,CAAG,EAAG,CAAG,CAC3C,CAQA,SAAgB,EAAW,EAAoC,EAAqB,CAClF,IAAM,EAAS,EAAQ,OAAQ,GAAW,EAAM,EAAO,MAAA,GAA0B,EACjF,GAAI,EAAO,OAAS,EAAG,MAAO,GAC9B,IAAM,EAAQ,EAAO,GACf,EAAO,EAAO,EAAO,OAAS,GAC9B,EAAU,EAAK,KAAO,EAAM,KAClC,OAAO,EAAU,GAAK,EAAK,EAAI,EAAM,GAAK,EAAU,CACtD"}
@@ -0,0 +1,2 @@
1
+ "use client";import{MINUTES_PER_DAY as e,addDays as t,dayDiff as n,minutesOfDay as r,startOfDay as i}from"./dates.mjs";var a=864e5,o=20;function s(e){return e.end<e.start?e.start:e.end}function c(e){return!!e.allDay||s(e).getTime()-e.start.getTime()>=a}function l(e){let r=i(e.start),a=s(e);if(e.allDay){let e=i(a);return{first:r,last:n(r,e)>=1?t(e,-1):r}}return{first:r,last:a>e.start?i(new Date(a.getTime()-1)):r}}function u(e,t){let n=Number(c(t))-Number(c(e));if(n!==0)return n;let r=e.start.getTime()-t.start.getTime();if(r!==0)return r;let i=s(t).getTime()-s(e).getTime();return i===0?e.title.localeCompare(t.title):i}function d(e,t){let r=t.map(()=>[]);for(let i of e){let{first:e,last:a}=l(i);t.forEach((t,o)=>{n(e,t)>=0&&n(t,a)>=0&&r[o].push(i)})}for(let e of r)e.sort(u);return r}function f(n,a){let l=i(a),u=t(l,1),d=[];for(let t of n){if(c(t))continue;let{start:n}=t,i=s(t);if(n>=u||i<=l&&n<l)continue;let a=n<l,f=i>u,p=a?0:r(n),m=Math.max(i>=u?e:r(i),p),h=m-p<15?Math.min(m+o,e):m;d.push({event:t,top:p,bottom:m,reach:h,column:0,columns:1,span:1,continuesBefore:a,continuesAfter:f})}d.sort((e,t)=>e.top-t.top||t.reach-e.reach);let f=[],m=-1;for(let e of d)f.length>0&&e.top>=m&&(p(f),f=[]),f.push(e),m=Math.max(m,e.reach);return f.length>0&&p(f),d}function p(e){let t=[];for(let n of e){let e=t.findIndex(e=>e<=n.top);e===-1&&(e=t.push(0)-1),n.column=e,t[e]=n.reach}let n=t.length;for(let t of e){t.columns=n;let r=1;for(let i=t.column+1;i<n&&!e.some(e=>e.column===i&&e.top<t.reach&&e.reach>t.top);i++)r++;t.span=r}}function m(e,t,r=()=>!0){let i=[];for(let a of e){if(!r(a))continue;let{first:e,last:o}=l(a),s=t.findIndex(t=>n(e,t)>=0&&n(t,o)>=0);if(s===-1)continue;let c=s;for(;c+1<t.length&&n(t[c+1],o)>=0;)c++;i.push({event:a,start:s,span:c-s+1,lane:0,continuesBefore:n(e,t[s])>0,continuesAfter:n(t[c],o)>0})}i.sort((e,t)=>e.start-t.start||t.span-e.span||u(e.event,t.event));let a=[];for(let e of i){let t=a.findIndex(t=>t<=e.start);t===-1&&(t=a.push(0)-1),e.lane=t,a[t]=e.start+e.span}return i}function h(e,t,n){let r=Math.max(n-1,0),i=Array.from({length:t},()=>0);for(let t of e)for(let e=t.start;e<t.start+t.span;e++)i[e]=Math.max(i[e],t.lane+1);let a=Array.from({length:t},()=>0),o=[];for(let t of e){let e=t.lane<r;if(!e&&t.lane===r){e=!0;for(let r=t.start;r<t.start+t.span;r++)i[r]>n&&(e=!1)}if(e){o.push(t);continue}for(let e=t.start;e<t.start+t.span;e++)a[e]++}return{visible:o,moreLane:r,hidden:a}}export{u as compareEvents,l as eventDays,s as eventEnd,d as eventsByDay,c as isAllDayLike,h as limitLanes,f as packDay,m as packLanes};
2
+ //# sourceMappingURL=layout.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.mjs","names":[],"sources":["../../../../package/common/calendar/layout.ts"],"sourcesContent":["import type { CalendarEvent } from './calendar.types';\nimport { addDays, dayDiff, MINUTES_PER_DAY, minutesOfDay, startOfDay } from './dates';\n\nconst DAY_MS = 86_400_000;\n\n/**\n * Below this an event has no room for a line of text at the default hour height. It is drawn as a\n * bar of its real length with its label beneath, and packed with room for that label.\n */\nexport const BRIEF_EVENT_MINUTES = 15;\n/** The label's line (`--label` in timeGrid.module.pcss) at the default 48px hour: 15px. */\nconst BRIEF_LABEL_MINUTES = 20;\n\n/** `end`, clamped so an event that ends before it starts is treated as having no length. */\nexport function eventEnd(event: CalendarEvent): Date {\n return event.end < event.start ? event.start : event.end;\n}\n\n/** Drawn in the all-day row rather than the time grid. */\nexport function isAllDayLike(event: CalendarEvent): boolean {\n return Boolean(event.allDay) || eventEnd(event).getTime() - event.start.getTime() >= DAY_MS;\n}\n\n/** First and last day (both midnight, both inclusive) the event appears on. */\nexport function eventDays(event: CalendarEvent): { first: Date; last: Date } {\n const first = startOfDay(event.start);\n const end = eventEnd(event);\n if (event.allDay) {\n // `end` is exclusive, but an all-day event ending on its own start day still takes that day.\n const endDay = startOfDay(end);\n return { first, last: dayDiff(first, endDay) >= 1 ? addDays(endDay, -1) : first };\n }\n // One millisecond back, so a timed event ending at midnight does not appear on the next day.\n const last = end > event.start ? startOfDay(new Date(end.getTime() - 1)) : first;\n return { first, last };\n}\n\n/** All-day events first, then by start, then the longer first, so a day reads the same everywhere. */\nexport function compareEvents(a: CalendarEvent, b: CalendarEvent): number {\n const allDay = Number(isAllDayLike(b)) - Number(isAllDayLike(a));\n if (allDay !== 0) return allDay;\n const start = a.start.getTime() - b.start.getTime();\n if (start !== 0) return start;\n const length = eventEnd(b).getTime() - eventEnd(a).getTime();\n if (length !== 0) return length;\n return a.title.localeCompare(b.title);\n}\n\n/** The events on each of `dates`, sorted with `compareEvents`. */\nexport function eventsByDay<E extends CalendarEvent>(events: readonly E[], dates: readonly Date[]): E[][] {\n const result: E[][] = dates.map(() => []);\n for (const event of events) {\n const { first, last } = eventDays(event);\n dates.forEach((day, i) => {\n if (dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0) result[i].push(event);\n });\n }\n for (const day of result) day.sort(compareEvents);\n return result;\n}\n\nexport interface TimedBox<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** Wall-clock minutes from the column's midnight. */\n top: number;\n bottom: number;\n /** Where the next event in its column may start: below the label of a brief event. */\n reach: number;\n /** Left edge, as a column of `columns`. */\n column: number;\n columns: number;\n /** Columns it can widen into to its right without covering another event. */\n span: number;\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Lays out one day column of the time grid: events that overlap share the width in columns, and\n * each one widens right into columns that are free for its whole height.\n *\n * Positions are wall-clock minutes, never milliseconds from midnight. Drawing and packing have\n * to agree on that: on a 25-hour day two events in the repeated hour occupy the same rows, and\n * packing them by real time would put them in one column, drawn over each other.\n */\nexport function packDay<E extends CalendarEvent>(events: readonly E[], day: Date): TimedBox<E>[] {\n const dayStart = startOfDay(day);\n const next = addDays(dayStart, 1);\n\n const boxes: TimedBox<E>[] = [];\n for (const event of events) {\n if (isAllDayLike(event)) continue;\n const { start } = event;\n const end = eventEnd(event);\n if (start >= next) continue;\n // A zero-length event at midnight belongs to the day it starts on.\n if (end <= dayStart && start < dayStart) continue;\n\n const continuesBefore = start < dayStart;\n const continuesAfter = end > next;\n const top = continuesBefore ? 0 : minutesOfDay(start);\n // Never upside down: on the day the clocks go back, an event can end on an earlier clock time.\n const bottom = Math.max(end >= next ? MINUTES_PER_DAY : minutesOfDay(end), top);\n const reach = bottom - top < BRIEF_EVENT_MINUTES ? Math.min(bottom + BRIEF_LABEL_MINUTES, MINUTES_PER_DAY) : bottom;\n boxes.push({ event, top, bottom, reach, column: 0, columns: 1, span: 1, continuesBefore, continuesAfter });\n }\n\n boxes.sort((a, b) => a.top - b.top || b.reach - a.reach);\n\n let cluster: TimedBox<E>[] = [];\n let clusterEnd = -1;\n for (const box of boxes) {\n if (cluster.length > 0 && box.top >= clusterEnd) {\n packCluster(cluster);\n cluster = [];\n }\n cluster.push(box);\n clusterEnd = Math.max(clusterEnd, box.reach);\n }\n if (cluster.length > 0) packCluster(cluster);\n\n return boxes;\n}\n\nfunction packCluster(cluster: TimedBox[]): void {\n const columnBottoms: number[] = [];\n for (const box of cluster) {\n let column = columnBottoms.findIndex((bottom) => bottom <= box.top);\n if (column === -1) column = columnBottoms.push(0) - 1;\n box.column = column;\n columnBottoms[column] = box.reach;\n }\n const columns = columnBottoms.length;\n for (const box of cluster) {\n box.columns = columns;\n let span = 1;\n for (let column = box.column + 1; column < columns; column++) {\n const blocked = cluster.some(\n (other) => other.column === column && other.top < box.reach && other.reach > box.top,\n );\n if (blocked) break;\n span++;\n }\n box.span = span;\n }\n}\n\nexport interface LaneBar<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** First column of the row it covers, 0-based. */\n start: number;\n /** Columns it covers within the row. */\n span: number;\n lane: number;\n /** It starts before its first column: in an earlier row, or on a hidden day. */\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Stacks the events of one row of days into lanes, as the month view and the all-day row draw\n * them: longer bars first, so a multi-day event keeps one lane across the week. `dates` are the\n * row's columns, so a hidden day between two of them is simply not drawn.\n */\nexport function packLanes<E extends CalendarEvent>(\n events: readonly E[],\n dates: readonly Date[],\n include: (event: E) => boolean = () => true,\n): LaneBar<E>[] {\n const bars: LaneBar<E>[] = [];\n for (const event of events) {\n if (!include(event)) continue;\n const { first, last } = eventDays(event);\n const start = dates.findIndex((day) => dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0);\n if (start === -1) continue;\n let end = start;\n while (end + 1 < dates.length && dayDiff(dates[end + 1], last) >= 0) end++;\n bars.push({\n event,\n start,\n span: end - start + 1,\n lane: 0,\n continuesBefore: dayDiff(first, dates[start]) > 0,\n continuesAfter: dayDiff(dates[end], last) > 0,\n });\n }\n\n bars.sort((a, b) => a.start - b.start || b.span - a.span || compareEvents(a.event, b.event));\n\n const laneEnds: number[] = [];\n for (const bar of bars) {\n let lane = laneEnds.findIndex((end) => end <= bar.start);\n if (lane === -1) lane = laneEnds.push(0) - 1;\n bar.lane = lane;\n laneEnds[lane] = bar.start + bar.span;\n }\n return bars;\n}\n\nexport interface LimitedLanes<E extends CalendarEvent = CalendarEvent> {\n visible: LaneBar<E>[];\n /** Lane the `+N` buttons go in, on the days that have one. */\n moreLane: number;\n /** Events hidden on each day of the row. */\n hidden: number[];\n}\n\n/**\n * Fits the bars into `capacity` lanes. A day that needs more gives its last lane to a `+N`\n * button; a day that does not keeps every bar. Decided per day, so one crowded day does not\n * hide events on the quiet days next to it. A bar crossing into a crowded day's `+N` lane is\n * hidden along its whole length and counted on each day it covers.\n */\nexport function limitLanes<E extends CalendarEvent>(\n bars: LaneBar<E>[],\n days: number,\n capacity: number,\n): LimitedLanes<E> {\n const moreLane = Math.max(capacity - 1, 0);\n const lanesPerDay = Array.from({ length: days }, () => 0);\n for (const bar of bars) {\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n lanesPerDay[day] = Math.max(lanesPerDay[day], bar.lane + 1);\n }\n }\n\n const hidden = Array.from({ length: days }, () => 0);\n const visible: LaneBar<E>[] = [];\n for (const bar of bars) {\n let fits = bar.lane < moreLane;\n if (!fits && bar.lane === moreLane) {\n fits = true;\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n if (lanesPerDay[day] > capacity) fits = false;\n }\n }\n if (fits) {\n visible.push(bar);\n continue;\n }\n for (let day = bar.start; day < bar.start + bar.span; day++) hidden[day]++;\n }\n return { visible, moreLane, hidden };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";var e=`pager-viewport_Mq7zC`,t=`pager-track_MTNN6`,n=`pager-pane_b38-h`,r=`pager-pane-prev_PEY3n`,i=`pager-pane-next_B62PQ`,a={"pager-viewport":`pager-viewport_Mq7zC`,pagerViewport:e,"pager-track":`pager-track_MTNN6`,pagerTrack:t,"pager-pane":`pager-pane_b38-h`,pagerPane:n,"pager-pane-prev":`pager-pane-prev_PEY3n`,pagerPanePrev:r,"pager-pane-next":`pager-pane-next_B62PQ`,pagerPaneNext:i};export{a as default,n as pagerPane,i as pagerPaneNext,r as pagerPanePrev,t as pagerTrack,e as pagerViewport};
2
+ //# sourceMappingURL=pager.module.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pager.module.mjs","names":[],"sources":["../../../../package/common/calendar/pager.module.pcss"],"sourcesContent":["/* The three panes of a pageable view share one grid cell, so the track is as tall as its\n tallest pane and does not change height mid-swipe. `clip` rather than `hidden` on the viewport:\n `hidden` makes it a scroll container, which the neighbours would then extend sideways.\n The neighbours' transforms are positions, not motion: the slide itself runs in usePager,\n which skips it under reduced motion. */\n.pager {\n &-viewport {\n position: relative;\n min-width: 0;\n overflow: clip;\n }\n\n &-track {\n display: grid;\n height: 100%;\n }\n\n &-pane {\n grid-area: 1 / 1;\n min-width: 0;\n min-height: 0;\n\n &-prev {\n transform: translateX(-100%);\n }\n\n &-next {\n transform: translateX(100%);\n }\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use client";import{edgeSpeed as e,velocityOf as t}from"./gesture.mjs";import{useEffect as n,useLayoutEffect as r,useRef as i}from"react";function a(a,o){let s=i(o);r(()=>{s.current=o}),n(()=>{let n=a.current;if(!n)return;let r=()=>s.current,i=`idle`,o=-1,c=``,l={x:0,y:0},u={x:0,y:0},d=[],f=null,p,m=0,h=-1/0,g=0,_=new Map;function v(e){try{n.setPointerCapture(e)}catch{}}function y(){clearTimeout(p),p=void 0}function b(){y(),cancelAnimationFrame(m),m=0,f=null,i=`passive`,g=performance.now()+350}function x(){let[e,t]=[..._.values()];return{center:{x:(e.x+t.x)/2,y:(e.y+t.y)/2},distance:Math.hypot(e.x-t.x,e.y-t.y)}}function S(){if(i!==`dragging`)return;let t=r().autoScroll?.();if(t){let n=e(u.y,t.top,t.bottom),i=t.element.scrollTop;n!==0&&(t.element.scrollTop+=n),t.element.scrollTop!==i&&r().onDragMove?.(u)}m=requestAnimationFrame(S)}function C(){p=void 0,f!==null&&i===`pressed`&&(i=`dragging`,v(o),c!==`mouse`&&`vibrate`in navigator&&navigator.vibrate(10),r().onDragStart?.(f,u),m=requestAnimationFrame(S))}function w(e){if(e.isPrimary&&i!==`idle`&&(i===`dragging`?r().onDragCancel?.():i===`swiping`?r().onSwipeEnd?.(0,0):i===`pinching`&&r().onPinchEnd?.(),y(),cancelAnimationFrame(m),f=null,i=`idle`),i===`idle`){if(e.pointerType===`mouse`&&e.button!==0)return;r().onPress?.(),o=e.pointerId,c=e.pointerType,l=u={x:e.clientX,y:e.clientY},_.clear(),_.set(e.pointerId,l),d=[{time:e.timeStamp,x:e.clientX}],f=e.target instanceof Element?r().dragFrom?.(e.target,l)??null:null,i=`pressed`;let t=performance.now()-h<150;f!==null&&c!==`mouse`&&!t&&(p=setTimeout(C,400));return}if(e.pointerType!==`mouse`&&(_.set(e.pointerId,{x:e.clientX,y:e.clientY}),i===`pressed`&&_.size===2&&r().onPinchStart)){y(),i=`pinching`,v(o),v(e.pointerId);let{center:t,distance:n}=x();r().onPinchStart?.(t,n)}}function T(e){if(!_.has(e.pointerId))return;let t={x:e.clientX,y:e.clientY};if(_.set(e.pointerId,t),i===`pinching`){if(_.size<2)return;let{center:e,distance:t}=x();r().onPinchMove?.(e,t);return}if(e.pointerId!==o)return;u=t;let n=t.x-l.x,a=t.y-l.y;if(i===`pressed`){let e=Math.hypot(n,a);if(c===`mouse`){if(e<=4)return;if(f===null){i=`passive`;return}C()}else{if(e<=10)return;if(y(),Math.abs(n)<=Math.abs(a)||!r().canSwipe?.()){i=`passive`;return}i=`swiping`,v(o)}}i===`swiping`?(d.push({time:e.timeStamp,x:t.x}),d.length>20&&d.shift(),r().onSwipeMove?.(n)):i===`dragging`&&r().onDragMove?.(t)}function E(e){_.delete(e),_.size===0&&(y(),f=null,i=`idle`)}function D(e){_.has(e.pointerId)&&(i===`pinching`?(r().onPinchEnd?.(),b()):e.pointerId===o&&(i===`swiping`?(d.push({time:e.timeStamp,x:e.clientX}),r().onSwipeEnd?.(e.clientX-l.x,t(d,e.timeStamp)),b()):i===`dragging`?(u={x:e.clientX,y:e.clientY},r().onDragEnd?.(u),b()):i===`pressed`&&(y(),i=`passive`)),E(e.pointerId))}function O(e){_.has(e.pointerId)&&(i===`swiping`?(r().onSwipeEnd?.(0,0),b()):i===`dragging`?(r().onDragCancel?.(),b()):i===`pinching`?(r().onPinchEnd?.(),b()):(y(),i=`passive`),E(e.pointerId))}function k(e){(i===`swiping`||i===`dragging`||i===`pinching`)&&e.cancelable&&e.preventDefault()}function A(e){(i===`dragging`||i===`pressed`&&c!==`mouse`&&f!==null)&&e.preventDefault()}function j(e){e.preventDefault()}function M(e){performance.now()<g&&(e.stopPropagation(),e.preventDefault(),g=0)}function N(){h=performance.now()}function P(e){e.key===`Escape`&&i===`dragging`&&(e.preventDefault(),r().onDragCancel?.(),b())}return n.addEventListener(`pointerdown`,w),n.addEventListener(`pointermove`,T),n.addEventListener(`pointerup`,D),n.addEventListener(`pointercancel`,O),n.addEventListener(`touchmove`,k,{passive:!1}),n.addEventListener(`contextmenu`,A),n.addEventListener(`dragstart`,j),n.addEventListener(`click`,M,!0),n.addEventListener(`scroll`,N,{capture:!0,passive:!0}),window.addEventListener(`scroll`,N,{passive:!0}),window.addEventListener(`keydown`,P),()=>{y(),cancelAnimationFrame(m),n.removeEventListener(`pointerdown`,w),n.removeEventListener(`pointermove`,T),n.removeEventListener(`pointerup`,D),n.removeEventListener(`pointercancel`,O),n.removeEventListener(`touchmove`,k),n.removeEventListener(`contextmenu`,A),n.removeEventListener(`dragstart`,j),n.removeEventListener(`click`,M,!0),n.removeEventListener(`scroll`,N,{capture:!0}),window.removeEventListener(`scroll`,N),window.removeEventListener(`keydown`,P)}},[a])}export{a as useGestures};
2
+ //# sourceMappingURL=useGestures.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGestures.mjs","names":[],"sources":["../../../../package/common/calendar/useGestures.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, type RefObject } from 'react';\n\nimport {\n CLICK_SUPPRESS_MS,\n edgeSpeed,\n LOCK_DISTANCE,\n LONG_PRESS_MS,\n MOUSE_DRAG_DISTANCE,\n RECENT_SCROLL_MS,\n velocityOf,\n type VelocitySample,\n} from './gesture';\n\nexport interface GesturePoint {\n x: number;\n y: number;\n}\n\nexport interface GestureHandlers<D> {\n /** Every press that starts a gesture, before anything else: where a running settle is finished. */\n onPress?: () => void;\n /** Whether a horizontal swipe may page right now. */\n canSwipe?: () => boolean;\n onSwipeMove?: (dx: number) => void;\n /** Also called with `(0, 0)` when the browser takes the gesture over. */\n onSwipeEnd?: (dx: number, velocity: number) => void;\n /** What a press on `target` would pick up, or `null` where nothing can be dragged. */\n dragFrom?: (target: Element, point: GesturePoint) => D | null;\n onDragStart?: (drag: D, point: GesturePoint) => void;\n onDragMove?: (point: GesturePoint) => void;\n onDragEnd?: (point: GesturePoint) => void;\n onDragCancel?: () => void;\n onPinchStart?: (center: GesturePoint, distance: number) => void;\n onPinchMove?: (center: GesturePoint, distance: number) => void;\n onPinchEnd?: () => void;\n /** The element a drag scrolls near its edges, and the band of the viewport that counts as its inside. */\n autoScroll?: () => { element: HTMLElement; top: number; bottom: number } | null;\n}\n\ntype Phase = 'idle' | 'pressed' | 'swiping' | 'dragging' | 'pinching' | 'passive';\n\n/**\n * One owner for every pointer gesture inside `ref`, so a swipe, a long-press drag, a pinch and\n * the browser's own scrolling can never both act on the same touch.\n *\n * Mouse or touch rules are chosen per event from `pointerType`, not once from a media query,\n * which answers wrongly on a laptop with a touch screen.\n */\nexport function useGestures<D>(ref: RefObject<HTMLElement | null>, handlers: GestureHandlers<D>): void {\n const handlersRef = useRef(handlers);\n useLayoutEffect(() => {\n handlersRef.current = handlers;\n });\n\n useEffect(() => {\n const root = ref.current;\n if (!root) return;\n const h = () => handlersRef.current;\n\n let phase: Phase = 'idle';\n let primary = -1;\n let pointerType = '';\n let origin: GesturePoint = { x: 0, y: 0 };\n let last: GesturePoint = { x: 0, y: 0 };\n let samples: VelocitySample[] = [];\n let drag: D | null = null;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let frame = 0;\n let lastScroll = -Infinity;\n let suppressUntil = 0;\n const pointers = new Map<number, GesturePoint>();\n\n function capture(pointerId: number) {\n // Only once the gesture is ours: a captured pointer sends its click to the capture target,\n // so capturing on press would swallow every click meant for an event inside the grid.\n try {\n root!.setPointerCapture(pointerId);\n } catch {\n // The pointer is already gone.\n }\n }\n\n function clearTimer() {\n clearTimeout(timer);\n timer = undefined;\n }\n\n function finishGesture() {\n clearTimer();\n cancelAnimationFrame(frame);\n frame = 0;\n drag = null;\n phase = 'passive';\n suppressUntil = performance.now() + CLICK_SUPPRESS_MS;\n }\n\n function pinchGeometry() {\n const [a, b] = [...pointers.values()];\n return {\n center: { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n distance: Math.hypot(a.x - b.x, a.y - b.y),\n };\n }\n\n function scrollStep() {\n if (phase !== 'dragging') return;\n const area = h().autoScroll?.();\n if (area) {\n const speed = edgeSpeed(last.y, area.top, area.bottom);\n const before = area.element.scrollTop;\n if (speed !== 0) area.element.scrollTop += speed;\n // The content moved under a finger that did not, so the drag target did.\n if (area.element.scrollTop !== before) h().onDragMove?.(last);\n }\n frame = requestAnimationFrame(scrollStep);\n }\n\n function startDrag() {\n timer = undefined;\n if (drag === null || phase !== 'pressed') return;\n phase = 'dragging';\n capture(primary);\n if (pointerType !== 'mouse' && 'vibrate' in navigator) navigator.vibrate(10);\n h().onDragStart?.(drag, last);\n frame = requestAnimationFrame(scrollStep);\n }\n\n function onPointerDown(event: PointerEvent) {\n // A primary pointer means every earlier one is up, even where its pointerup never reached\n // us (a mouse released outside the window before the drag captured it).\n if (event.isPrimary && phase !== 'idle') {\n if (phase === 'dragging') h().onDragCancel?.();\n else if (phase === 'swiping') h().onSwipeEnd?.(0, 0);\n else if (phase === 'pinching') h().onPinchEnd?.();\n clearTimer();\n cancelAnimationFrame(frame);\n drag = null;\n phase = 'idle';\n }\n if (phase === 'idle') {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n h().onPress?.();\n primary = event.pointerId;\n pointerType = event.pointerType;\n origin = last = { x: event.clientX, y: event.clientY };\n pointers.clear();\n pointers.set(event.pointerId, origin);\n samples = [{ time: event.timeStamp, x: event.clientX }];\n drag = event.target instanceof Element ? (h().dragFrom?.(event.target, origin) ?? null) : null;\n phase = 'pressed';\n const stoppingMomentum = performance.now() - lastScroll < RECENT_SCROLL_MS;\n if (drag !== null && pointerType !== 'mouse' && !stoppingMomentum) {\n timer = setTimeout(startDrag, LONG_PRESS_MS);\n }\n return;\n }\n if (event.pointerType === 'mouse') return;\n pointers.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (phase === 'pressed' && pointers.size === 2 && h().onPinchStart) {\n clearTimer();\n phase = 'pinching';\n capture(primary);\n capture(event.pointerId);\n const { center, distance } = pinchGeometry();\n h().onPinchStart?.(center, distance);\n }\n }\n\n function onPointerMove(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n const point = { x: event.clientX, y: event.clientY };\n pointers.set(event.pointerId, point);\n\n if (phase === 'pinching') {\n if (pointers.size < 2) return;\n const { center, distance } = pinchGeometry();\n h().onPinchMove?.(center, distance);\n return;\n }\n if (event.pointerId !== primary) return;\n last = point;\n const dx = point.x - origin.x;\n const dy = point.y - origin.y;\n\n if (phase === 'pressed') {\n const distance = Math.hypot(dx, dy);\n if (pointerType === 'mouse') {\n if (distance <= MOUSE_DRAG_DISTANCE) return;\n if (drag === null) {\n phase = 'passive';\n return;\n }\n startDrag();\n } else {\n if (distance <= LOCK_DISTANCE) return;\n clearTimer();\n if (Math.abs(dx) <= Math.abs(dy) || !h().canSwipe?.()) {\n phase = 'passive';\n return;\n }\n phase = 'swiping';\n capture(primary);\n }\n }\n\n if (phase === 'swiping') {\n samples.push({ time: event.timeStamp, x: point.x });\n if (samples.length > 20) samples.shift();\n h().onSwipeMove?.(dx);\n } else if (phase === 'dragging') {\n h().onDragMove?.(point);\n }\n }\n\n function release(pointerId: number) {\n pointers.delete(pointerId);\n if (pointers.size === 0) {\n clearTimer();\n drag = null;\n phase = 'idle';\n }\n }\n\n function onPointerUp(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n if (phase === 'pinching') {\n h().onPinchEnd?.();\n finishGesture();\n } else if (event.pointerId === primary) {\n if (phase === 'swiping') {\n samples.push({ time: event.timeStamp, x: event.clientX });\n h().onSwipeEnd?.(event.clientX - origin.x, velocityOf(samples, event.timeStamp));\n finishGesture();\n } else if (phase === 'dragging') {\n last = { x: event.clientX, y: event.clientY };\n h().onDragEnd?.(last);\n finishGesture();\n } else if (phase === 'pressed') {\n // Left to the click that follows, so a tap, a mouse click and Enter share one path.\n clearTimer();\n phase = 'passive';\n }\n }\n release(event.pointerId);\n }\n\n // The browser took the touch over, usually to scroll: whatever was in progress is undone.\n function onPointerCancel(event: PointerEvent) {\n if (!pointers.has(event.pointerId)) return;\n if (phase === 'swiping') {\n h().onSwipeEnd?.(0, 0);\n finishGesture();\n } else if (phase === 'dragging') {\n h().onDragCancel?.();\n finishGesture();\n } else if (phase === 'pinching') {\n h().onPinchEnd?.();\n finishGesture();\n } else {\n clearTimer();\n phase = 'passive';\n }\n release(event.pointerId);\n }\n\n // The only way to keep iOS Safari from scrolling under a drag that has already begun:\n // `touch-action` is read once, when the touch starts, so changing it mid-gesture does\n // nothing. Registered here at mount rather than on touchstart, so the area is already known\n // to block scrolling before the first touch arrives.\n function onTouchMove(event: TouchEvent) {\n if ((phase === 'swiping' || phase === 'dragging' || phase === 'pinching') && event.cancelable) {\n event.preventDefault();\n }\n }\n\n // Android opens the context menu on a long press, iOS the callout, both around the time a\n // drag arms.\n function onContextMenu(event: Event) {\n if (phase === 'dragging' || (phase === 'pressed' && pointerType !== 'mouse' && drag !== null)) {\n event.preventDefault();\n }\n }\n\n function onDragStartNative(event: Event) {\n event.preventDefault();\n }\n\n function onClickCapture(event: MouseEvent) {\n if (performance.now() < suppressUntil) {\n event.stopPropagation();\n event.preventDefault();\n suppressUntil = 0;\n }\n }\n\n function onScroll() {\n lastScroll = performance.now();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== 'Escape' || phase !== 'dragging') return;\n event.preventDefault();\n h().onDragCancel?.();\n finishGesture();\n }\n\n root.addEventListener('pointerdown', onPointerDown);\n root.addEventListener('pointermove', onPointerMove);\n root.addEventListener('pointerup', onPointerUp);\n root.addEventListener('pointercancel', onPointerCancel);\n root.addEventListener('touchmove', onTouchMove, { passive: false });\n root.addEventListener('contextmenu', onContextMenu);\n root.addEventListener('dragstart', onDragStartNative);\n root.addEventListener('click', onClickCapture, true);\n // `scroll` does not bubble, but it does pass through capturing listeners on the way down.\n root.addEventListener('scroll', onScroll, { capture: true, passive: true });\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('keydown', onKeyDown);\n return () => {\n clearTimer();\n cancelAnimationFrame(frame);\n root.removeEventListener('pointerdown', onPointerDown);\n root.removeEventListener('pointermove', onPointerMove);\n root.removeEventListener('pointerup', onPointerUp);\n root.removeEventListener('pointercancel', onPointerCancel);\n root.removeEventListener('touchmove', onTouchMove);\n root.removeEventListener('contextmenu', onContextMenu);\n root.removeEventListener('dragstart', onDragStartNative);\n root.removeEventListener('click', onClickCapture, true);\n root.removeEventListener('scroll', onScroll, { capture: true });\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('keydown', onKeyDown);\n };\n }, [ref]);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";import e from"../hooks/useMediaQuery.mjs";import{useCallback as t,useEffect as n,useLayoutEffect as r,useRef as i}from"react";import{flushSync as a}from"react-dom";var o=240;function s(s,c,l){let u=i(new Set),d=i(0),f=i([]),p=i(0),m=i(s),h=e(`(prefers-reduced-motion: reduce)`),g=i({onPage:c,focusFallback:l,reducedMotion:h});r(()=>{g.current={onPage:c,focusFallback:l,reducedMotion:h}});let _=t(e=>{d.current=e;for(let t of u.current)t.style.transform=e===0?``:`translateX(${e}px)`},[]);r(()=>{m.current=s,_(0);let e=document.activeElement;e instanceof HTMLElement&&e.closest(`[inert]`)&&[...u.current].some(t=>t.contains(e))&&g.current.focusFallback()?.focus()},[s,_]);let v=t(e=>{if(e)return u.current.add(e),()=>{u.current.delete(e)}},[]),y=t(()=>{let[e]=u.current;return e?.parentElement?.clientWidth??0},[]),b=t(e=>{if(f.current=[],e===0){_(0);return}let t=m.current;a(()=>g.current.onPage(e)),m.current===t&&_(0)},[_]),x=t(e=>{let t=y(),n=d.current,r=e===0?0:-e*t,i=[...u.current];_(r);let a=typeof i[0]?.animate==`function`;if(g.current.reducedMotion||n===r||!a){b(e);return}let s=Math.max(120,o*Math.min(1,Math.abs(r-n)/Math.max(t,1))),c=[{transform:`translateX(${n}px)`},{transform:`translateX(${r}px)`}];p.current=e,f.current=i.map(e=>e.animate(c,{duration:s,easing:`cubic-bezier(0.25, 1, 0.5, 1)`})),f.current[0].onfinish=()=>b(e)},[b,y,_]),S=t(()=>{if(f.current.length!==0){for(let e of f.current)e.onfinish=null,e.cancel();b(p.current)}},[b]);return n(()=>{let e=f;return()=>{for(let t of e.current)t.onfinish=null,t.cancel()}},[]),{trackRef:v,width:y,move:t(e=>_(e),[_]),settle:x,finish:S}}export{s as usePager};
2
+ //# sourceMappingURL=usePager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePager.mjs","names":[],"sources":["../../../../package/common/calendar/usePager.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';\nimport { flushSync } from 'react-dom';\n\nimport { useMediaQuery } from '../hooks/useMediaQuery';\n\nconst SETTLE_MS = 240;\n\nexport interface Pager {\n /** Ref for each element that slides. The time grid has two, its head and its body. */\n trackRef: (element: HTMLElement | null) => void;\n /** Width of one pane. */\n width: () => number;\n /** Offset every track by `dx` px, following the finger. */\n move: (dx: number) => void;\n /** Animate to the next (`1`) or previous (`-1`) pane and page, or back (`0`). */\n settle: (step: -1 | 0 | 1) => void;\n /** Jump to the end of a running settle: a new press arrived before it finished. */\n finish: () => void;\n}\n\n/**\n * Drives the three panes a pageable view renders: previous, current and next, keyed by period, so\n * after paging the pane that slid in is the same DOM node as the one now current. The track is\n * reset in the same commit that swaps them, which is why nothing flashes.\n *\n * `focusFallback` receives focus when it would otherwise be left inside a pane that just went inert.\n */\nexport function usePager(\n periodKey: string,\n onPage: (step: 1 | -1) => void,\n focusFallback: () => HTMLElement | null,\n): Pager {\n const tracks = useRef(new Set<HTMLElement>());\n const offset = useRef(0);\n const animations = useRef<Animation[]>([]);\n const pendingStep = useRef<-1 | 0 | 1>(0);\n const keyRef = useRef(periodKey);\n const reducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');\n\n const latest = useRef({ onPage, focusFallback, reducedMotion });\n useLayoutEffect(() => {\n latest.current = { onPage, focusFallback, reducedMotion };\n });\n\n const write = useCallback((dx: number) => {\n offset.current = dx;\n for (const track of tracks.current) track.style.transform = dx === 0 ? '' : `translateX(${dx}px)`;\n }, []);\n\n useLayoutEffect(() => {\n keyRef.current = periodKey;\n write(0);\n const active = document.activeElement;\n if (active instanceof HTMLElement && active.closest('[inert]')) {\n const inPager = [...tracks.current].some((track) => track.contains(active));\n if (inPager) latest.current.focusFallback()?.focus();\n }\n }, [periodKey, write]);\n\n const trackRef = useCallback((element: HTMLElement | null) => {\n if (!element) return;\n tracks.current.add(element);\n return () => {\n tracks.current.delete(element);\n };\n }, []);\n\n const width = useCallback(() => {\n const [first] = tracks.current;\n return first?.parentElement?.clientWidth ?? 0;\n }, []);\n\n const complete = useCallback(\n (step: -1 | 0 | 1) => {\n animations.current = [];\n if (step === 0) {\n write(0);\n return;\n }\n const before = keyRef.current;\n flushSync(() => latest.current.onPage(step));\n // A controlled parent that did not take the new date leaves the old panes in place.\n if (keyRef.current === before) write(0);\n },\n [write],\n );\n\n const settle = useCallback(\n (step: -1 | 0 | 1) => {\n const paneWidth = width();\n const from = offset.current;\n const to = step === 0 ? 0 : -step * paneWidth;\n const elements = [...tracks.current];\n write(to);\n const canAnimate = typeof elements[0]?.animate === 'function';\n if (latest.current.reducedMotion || from === to || !canAnimate) {\n complete(step);\n return;\n }\n // Shorter the less of the way is left, so a flick that has almost arrived does not crawl.\n const duration = Math.max(120, SETTLE_MS * Math.min(1, Math.abs(to - from) / Math.max(paneWidth, 1)));\n const keyframes = [{ transform: `translateX(${from}px)` }, { transform: `translateX(${to}px)` }];\n pendingStep.current = step;\n animations.current = elements.map((element) =>\n element.animate(keyframes, { duration, easing: 'cubic-bezier(0.25, 1, 0.5, 1)' }),\n );\n animations.current[0].onfinish = () => complete(step);\n },\n [complete, width, write],\n );\n\n const finish = useCallback(() => {\n if (animations.current.length === 0) return;\n // Not `Animation#finish()`: it queues the finish event for a later frame, and the new press\n // has to start from the paged state now.\n for (const animation of animations.current) {\n animation.onfinish = null;\n animation.cancel();\n }\n complete(pendingStep.current);\n }, [complete]);\n\n useEffect(() => {\n const running = animations;\n return () => {\n for (const animation of running.current) {\n animation.onfinish = null;\n animation.cancel();\n }\n };\n }, []);\n\n const move = useCallback((dx: number) => write(dx), [write]);\n\n return { trackRef, width, move, settle, finish };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonStyleType as n}from"../button/button.types.mjs";import r from"../actionButtons/actionButtons.mjs";import i from"../modal/modal.mjs";import{useState as a}from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";var c={submit:`Confirm`,cancel:`Cancel`};function l(l){let{children:u=null,className:d=``,onClose:f=()=>{},onConfirm:p=()=>{},title:m=``,content:h=null,isOpen:g=void 0,labels:_,isDelete:v=!1,actionButtonsProps:y={},style:b,...x}=e(`ConfirmModal`,l),S=t(`ConfirmModal`,_,c),[C,w]=a(!1),[T,E]=a(!1);function D(e=!1){w(!1),f(e)}async function O(){E(!0);try{await p(),D(!0)}catch{}finally{E(!1)}}let k=o(i,{title:m,isOpen:g===void 0?C:g,onClose:()=>D(),className:u?void 0:d,footer:o(r,{onClose:()=>D(),onSubmit:O,labels:{submit:S.submit,cancel:S.cancel},submitButtonStyle:v?n.Delete:void 0,isSubmitButtonLoading:T,noMargin:!0,...y}),children:h});return u?s(`div`,{...x,className:d,style:b,children:[o(`span`,{onClick:()=>w(!0),children:u}),k]}):k}export{l as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonStyleType as n}from"../button/button.types.mjs";import r from"../actionButtons/actionButtons.mjs";import i from"../modal/modal.mjs";import{useState as a}from"react";import{jsx as o,jsxs as s}from"react/jsx-runtime";var c={submit:`Confirm`,cancel:`Cancel`};function l(l){let{children:u=null,className:d=``,onClose:f=()=>{},onConfirm:p=()=>{},title:m,content:h=null,isOpen:g=void 0,labels:_,isDelete:v=!1,actionButtonsProps:y={},style:b,...x}=e(`ConfirmModal`,l),S=t(`ConfirmModal`,_,c),[C,w]=a(!1),[T,E]=a(!1);function D(e=!1){w(!1),f(e)}async function O(){E(!0);try{await p(),D(!0)}catch{}finally{E(!1)}}let k=o(i,{title:m,isOpen:g===void 0?C:g,onClose:()=>D(),className:u?void 0:d,footer:o(r,{onClose:()=>D(),onSubmit:O,labels:{submit:S.submit,cancel:S.cancel},submitButtonStyle:v?n.Delete:void 0,isSubmitButtonLoading:T,noMargin:!0,...y}),children:h});return u?s(`div`,{...x,className:d,style:b,children:[o(`span`,{onClick:()=>w(!0),children:u}),k]}):k}export{l as default};
2
2
  //# sourceMappingURL=confirmModal.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport { ButtonStyleType } from '../button';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { ConfirmModalLabels, ConfirmModalProps } from './confirmModal.types';\n\nconst DEFAULT_LABELS: Required<ConfirmModalLabels> = {\n submit: 'Confirm',\n cancel: 'Cancel',\n};\n\nfunction ConfirmModal(props: ConfirmModalProps): ReactElement {\n const {\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title = '',\n content = null,\n isOpen: propIsOpen = undefined,\n labels,\n isDelete = false,\n actionButtonsProps = {},\n style,\n ...rest\n } = useComponentDefaults('ConfirmModal', props);\n const text = useLabels('ConfirmModal', labels, DEFAULT_LABELS);\n const [internalOpen, setInternalOpen] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n function handleClose(didSubmit = false) {\n setInternalOpen(false);\n onClose(didSubmit);\n }\n\n async function handleConfirm() {\n setIsSubmitting(true);\n try {\n await onConfirm();\n handleClose(true);\n } catch {\n // Nothing is awaiting this handler, so a rejection would surface as an unhandled one.\n // The dialog staying open is the signal that the action did not go through; reporting\n // the failure itself belongs to whoever wrote `onConfirm`.\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const isOpen = propIsOpen === undefined ? internalOpen : propIsOpen;\n\n const modal = (\n <Modal\n title={title}\n isOpen={isOpen}\n onClose={() => handleClose()}\n className={children ? undefined : className}\n footer={\n <ActionButtons\n onClose={() => handleClose()}\n onSubmit={handleConfirm}\n labels={{ submit: text.submit, cancel: text.cancel }}\n submitButtonStyle={isDelete ? ButtonStyleType.Delete : undefined}\n isSubmitButtonLoading={isSubmitting}\n // The footer slot already supplies the gap above the buttons.\n noMargin\n {...actionButtonsProps}\n />\n }\n >\n {content}\n </Modal>\n );\n\n if (!children) return modal;\n\n return (\n <div {...rest} className={className} style={style}>\n <span onClick={() => setInternalOpen(true)}>{children}</span>\n {modal}\n </div>\n );\n}\n\nexport default ConfirmModal;\n"],"mappings":"+XAQA,IAAM,EAA+C,CACnD,OAAQ,UACR,OAAQ,QACV,EAEA,SAAS,EAAa,EAAwC,CAC5D,GAAM,CACJ,WAAW,KACX,YAAY,GACZ,cAAgB,CAAC,EACjB,gBAAkB,CAAC,EACnB,QAAQ,GACR,UAAU,KACV,OAAQ,EAAa,IAAA,GACrB,SACA,WAAW,GACX,qBAAqB,CAAC,EACtB,QACA,GAAG,GACD,EAAqB,eAAgB,CAAK,EACxC,EAAO,EAAU,eAAgB,EAAQ,CAAc,EACvD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAChD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAEtD,SAAS,EAAY,EAAY,GAAO,CACtC,EAAgB,EAAK,EACrB,EAAQ,CAAS,CACnB,CAEA,eAAe,GAAgB,CAC7B,EAAgB,EAAI,EACpB,GAAI,CACF,MAAM,EAAU,EAChB,EAAY,EAAI,CAClB,MAAQ,CAIR,QAAU,CACR,EAAgB,EAAK,CACvB,CACF,CAIA,IAAM,EACJ,EAAC,EAAD,CACS,QACC,OALG,IAAe,IAAA,GAAY,EAAe,EAMrD,YAAe,EAAY,EAC3B,UAAW,EAAW,IAAA,GAAY,EAClC,OACE,EAAC,EAAD,CACE,YAAe,EAAY,EAC3B,SAAU,EACV,OAAQ,CAAE,OAAQ,EAAK,OAAQ,OAAQ,EAAK,MAAO,EACnD,kBAAmB,EAAW,EAAgB,OAAS,IAAA,GACvD,sBAAuB,EAEvB,SAAA,GACA,GAAI,CACL,CAAA,EAGF,SAAA,CACI,CAAA,EAKT,OAFK,EAGH,EAAC,MAAD,CAAK,GAAI,EAAiB,YAAkB,QAA5C,SAAA,CACE,EAAC,OAAD,CAAM,YAAe,EAAgB,EAAI,EAAI,UAAe,CAAA,EAC3D,CACE,IANe,CAQxB"}
1
+ {"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport { ButtonStyleType } from '../button';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { ConfirmModalLabels, ConfirmModalProps } from './confirmModal.types';\n\nconst DEFAULT_LABELS: Required<ConfirmModalLabels> = {\n submit: 'Confirm',\n cancel: 'Cancel',\n};\n\nfunction ConfirmModal(props: ConfirmModalProps): ReactElement {\n const {\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title,\n content = null,\n isOpen: propIsOpen = undefined,\n labels,\n isDelete = false,\n actionButtonsProps = {},\n style,\n ...rest\n } = useComponentDefaults('ConfirmModal', props);\n const text = useLabels('ConfirmModal', labels, DEFAULT_LABELS);\n const [internalOpen, setInternalOpen] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n function handleClose(didSubmit = false) {\n setInternalOpen(false);\n onClose(didSubmit);\n }\n\n async function handleConfirm() {\n setIsSubmitting(true);\n try {\n await onConfirm();\n handleClose(true);\n } catch {\n // Nothing is awaiting this handler, so a rejection would surface as an unhandled one.\n // The dialog staying open is the signal that the action did not go through; reporting\n // the failure itself belongs to whoever wrote `onConfirm`.\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const isOpen = propIsOpen === undefined ? internalOpen : propIsOpen;\n\n const modal = (\n <Modal\n title={title}\n isOpen={isOpen}\n onClose={() => handleClose()}\n className={children ? undefined : className}\n footer={\n <ActionButtons\n onClose={() => handleClose()}\n onSubmit={handleConfirm}\n labels={{ submit: text.submit, cancel: text.cancel }}\n submitButtonStyle={isDelete ? ButtonStyleType.Delete : undefined}\n isSubmitButtonLoading={isSubmitting}\n // The footer slot already supplies the gap above the buttons.\n noMargin\n {...actionButtonsProps}\n />\n }\n >\n {content}\n </Modal>\n );\n\n if (!children) return modal;\n\n return (\n <div {...rest} className={className} style={style}>\n <span onClick={() => setInternalOpen(true)}>{children}</span>\n {modal}\n </div>\n );\n}\n\nexport default ConfirmModal;\n"],"mappings":"+XAQA,IAAM,EAA+C,CACnD,OAAQ,UACR,OAAQ,QACV,EAEA,SAAS,EAAa,EAAwC,CAC5D,GAAM,CACJ,WAAW,KACX,YAAY,GACZ,cAAgB,CAAC,EACjB,gBAAkB,CAAC,EACnB,QACA,UAAU,KACV,OAAQ,EAAa,IAAA,GACrB,SACA,WAAW,GACX,qBAAqB,CAAC,EACtB,QACA,GAAG,GACD,EAAqB,eAAgB,CAAK,EACxC,EAAO,EAAU,eAAgB,EAAQ,CAAc,EACvD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAChD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAEtD,SAAS,EAAY,EAAY,GAAO,CACtC,EAAgB,EAAK,EACrB,EAAQ,CAAS,CACnB,CAEA,eAAe,GAAgB,CAC7B,EAAgB,EAAI,EACpB,GAAI,CACF,MAAM,EAAU,EAChB,EAAY,EAAI,CAClB,MAAQ,CAIR,QAAU,CACR,EAAgB,EAAK,CACvB,CACF,CAIA,IAAM,EACJ,EAAC,EAAD,CACS,QACC,OALG,IAAe,IAAA,GAAY,EAAe,EAMrD,YAAe,EAAY,EAC3B,UAAW,EAAW,IAAA,GAAY,EAClC,OACE,EAAC,EAAD,CACE,YAAe,EAAY,EAC3B,SAAU,EACV,OAAQ,CAAE,OAAQ,EAAK,OAAQ,OAAQ,EAAK,MAAO,EACnD,kBAAmB,EAAW,EAAgB,OAAS,IAAA,GACvD,sBAAuB,EAEvB,SAAA,GACA,GAAI,CACL,CAAA,EAGF,SAAA,CACI,CAAA,EAKT,OAFK,EAGH,EAAC,MAAD,CAAK,GAAI,EAAiB,YAAkB,QAA5C,SAAA,CACE,EAAC,OAAD,CAAM,YAAe,EAAgB,EAAI,EAAI,UAAe,CAAA,EAC3D,CACE,IANe,CAQxB"}
@@ -1,2 +1,2 @@
1
- "use client";import e from"../../../interactableDiv/index.mjs";import t from"./datePickerMonth.module.mjs";import{getLocale as n}from"../../../../services/localization.mjs";import{dateToDay as r,daysInMonth as i,formatDay as a,parseDay as o}from"../../../utils/day.mjs";import{addDays as s,getStartWeekDayOfMonth as c,getToday as l,getWeekDays as u}from"../../dateFunctions.mjs";import{useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{jsx as h,jsxs as g}from"react/jsx-runtime";function _(e,t,n){let r=o(n);if(r&&r.month===e&&r.year===t)return r.day;let i=l();return i.month===e&&i.year===t?i.day:1}function v(e,t,n){return{isStartDate:e===t,isEndDate:e===n,isInRange:!!t&&!!n&&e>=t&&e<=n}}function y(e,t,n){return!!t&&e<t||!!n&&e>n}function b({style:o,className:b=``,month:x=l().month,year:S=l().year,onSelect:C=()=>null,selectionStart:w,selectionEnd:T,minDate:E=null,maxDate:D=null,onNavigateMonth:O}){let k=n(`-`),A=i({year:S,month:x}),j=c(x,S),M=r(new Date),N=f({}),[P,F]=p(()=>_(x,S,w)),I=f(null);d(()=>{if(I.current!=null){let e=I.current;I.current=null,F(e),N.current[e]?.focus()}else F(_(x,S,w))},[x,S]);function L(e,t){let n=0;if(e.key===`ArrowRight`)n=1;else if(e.key===`ArrowLeft`)n=-1;else if(e.key===`ArrowDown`)n=7;else if(e.key===`ArrowUp`)n=-7;else return;e.preventDefault();let r=s(t,x,S,n);r.month!==x||r.year!==S?(I.current=r.day,O?.(r.month>x||r.year>S?1:-1)):(F(r.day),N.current[r.day]?.focus())}return h(`div`,{className:m(t.datePickerMonth,b),style:o,children:g(`div`,{className:m(t.datePickerMonthContent),children:[u(k).map((e,t)=>h(`div`,{children:e},t)),Array.from(Array(j-1).keys()).map(e=>h(`div`,{className:m(t.datePickerMonthItem,t.datePickerMonthPlaceholder)},e)),Array.from(Array(A).keys()).map(n=>{let r=n+1,i=a({day:r,month:x,year:S}),o=v(i,w,T),s=y(i,E,D),c=i===M;return h(e,{ref:e=>{N.current[r]=e},tabIndex:r===P?0:-1,onKeyDown:e=>L(e,r),onClick:()=>s?null:C(i),className:m(t.datePickerMonthDay,t.datePickerMonthItem,{[t.datePickerMonthDaySelected]:o.isInRange,[t.datePickerMonthDaySelectedStart]:o.isStartDate,[t.datePickerMonthDaySelectedEnd]:o.isEndDate,[t.datePickerMonthDayDisabled]:s,[t.datePickerMonthDayToday]:c}),children:r},r)}),Array.from(Array(42-(j+A-1)).keys()).map(e=>h(`div`,{className:m(t.datePickerMonthItem,t.datePickerMonthPlaceholder),children:`\xA0`},e))]})})}export{b as default};
1
+ "use client";import e from"../../../interactableDiv/index.mjs";import{dateToDay as t,daysInMonth as n,formatDay as r,parseDay as i}from"../../../utils/day.mjs";import a from"./datePickerMonth.module.mjs";import{getLocale as o}from"../../../../services/localization.mjs";import{addDays as s,getStartWeekDayOfMonth as c,getToday as l,getWeekDays as u}from"../../dateFunctions.mjs";import{useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{jsx as h,jsxs as g}from"react/jsx-runtime";function _(e,t,n){let r=i(n);if(r&&r.month===e&&r.year===t)return r.day;let a=l();return a.month===e&&a.year===t?a.day:1}function v(e,t,n){return{isStartDate:e===t,isEndDate:e===n,isInRange:!!t&&!!n&&e>=t&&e<=n}}function y(e,t,n){return!!t&&e<t||!!n&&e>n}function b({style:i,className:b=``,month:x=l().month,year:S=l().year,onSelect:C=()=>null,selectionStart:w,selectionEnd:T,minDate:E=null,maxDate:D=null,onNavigateMonth:O}){let k=o(`-`),A=n({year:S,month:x}),j=c(x,S),M=t(new Date),N=f({}),[P,F]=p(()=>_(x,S,w)),I=f(null);d(()=>{if(I.current!=null){let e=I.current;I.current=null,F(e),N.current[e]?.focus()}else F(_(x,S,w))},[x,S]);function L(e,t){let n=0;if(e.key===`ArrowRight`)n=1;else if(e.key===`ArrowLeft`)n=-1;else if(e.key===`ArrowDown`)n=7;else if(e.key===`ArrowUp`)n=-7;else return;e.preventDefault();let r=s(t,x,S,n);r.month!==x||r.year!==S?(I.current=r.day,O?.(r.month>x||r.year>S?1:-1)):(F(r.day),N.current[r.day]?.focus())}return h(`div`,{className:m(a.datePickerMonth,b),style:i,children:g(`div`,{className:m(a.datePickerMonthContent),children:[u(k).map((e,t)=>h(`div`,{children:e},t)),Array.from(Array(j-1).keys()).map(e=>h(`div`,{className:m(a.datePickerMonthItem,a.datePickerMonthPlaceholder)},e)),Array.from(Array(A).keys()).map(t=>{let n=t+1,i=r({day:n,month:x,year:S}),o=v(i,w,T),s=y(i,E,D),c=i===M;return h(e,{ref:e=>{N.current[n]=e},tabIndex:n===P?0:-1,onKeyDown:e=>L(e,n),onClick:()=>s?null:C(i),className:m(a.datePickerMonthDay,a.datePickerMonthItem,{[a.datePickerMonthDaySelected]:o.isInRange,[a.datePickerMonthDaySelectedStart]:o.isStartDate,[a.datePickerMonthDaySelectedEnd]:o.isEndDate,[a.datePickerMonthDayDisabled]:s,[a.datePickerMonthDayToday]:c}),children:n},n)}),Array.from(Array(42-(j+A-1)).keys()).map(e=>h(`div`,{className:m(a.datePickerMonthItem,a.datePickerMonthPlaceholder),children:`\xA0`},e))]})})}export{b as default};
2
2
  //# sourceMappingURL=datePickerMonth.mjs.map
@@ -1,2 +1,2 @@
1
- "use client";import{getLocale as e}from"../../services/localization.mjs";import{dateToDay as t,daysInMonth as n,formatDay as r,parseDay as i}from"../utils/day.mjs";function a(e,t,n){let r=new Date(0);return r.setUTCFullYear(e,t-1,n),r}function o(e,t,n,r,i=!1){return a(t,n,r).toLocaleDateString(e,{month:i?`short`:`long`,timeZone:`UTC`})}function s(t=e(`-`)){return Array.from(Array(12).keys()).map(e=>o(t,2023,e+1,1))}function c(e,t=!0){return Array.from(Array(7).keys()).map(n=>a(2023,4,10+n).toLocaleDateString(e,{weekday:t?`short`:`long`,timeZone:`UTC`}))}function l(e,t){return a(t,e,1).getUTCDay()||7}function u(e,t,r,i){let a=e+i,o=t,s=r;for(;a<1;)--o,o<1&&(o=12,--s),a+=n({year:s,month:o});for(;a>n({year:s,month:o});)a-=n({year:s,month:o}),o+=1,o>12&&(o=1,s+=1);return{day:a,month:o,year:s}}function d(){return i(t(new Date))}function f(e){let t=i(e);return t?`${String(t.day).padStart(2,`0`)}.${String(t.month).padStart(2,`0`)}.${String(t.year).padStart(4,`0`)}`:``}function p(e){let t=/^(\d{2})\.(\d{2})\.(\d{4})$/.exec(e);if(!t)return null;let n=r({day:Number(t[1]),month:Number(t[2]),year:Number(t[3])});return i(n)?n:null}function m(e,t,n){let r=e,i=n;return r[0]!==`_`&&(r[0]>`3`?(r=`0${r[0]}${t.substring(2)}`,i={start:3,end:3}):r[0]===`3`&&r[1]!==`_`&&r[1]>`1`&&(r=`0${r[1]}${t.substring(2)}`,i={start:3,end:3})),r[3]!==`_`&&r[3]>`1`&&(r=`${r.substring(0,3)}0${r[3]}${t.substring(5)}`,i={start:6,end:6}),r[3]===`1`&&r[4]!==`_`&&r[4]>`2`&&(r=`${r.substring(0,3)}${r[3]}2${t.substring(5)}`),{value:r,selection:i}}export{u as addDays,m as correctDateMaskValue,f as getDateString,o as getMonthName,s as getMonthNames,l as getStartWeekDayOfMonth,d as getToday,c as getWeekDays,p as parseDateString};
1
+ "use client";import{dateToDay as e,daysInMonth as t,formatDay as n,parseDay as r}from"../utils/day.mjs";import{getLocale as i}from"../../services/localization.mjs";function a(e,t,n){let r=new Date(0);return r.setUTCFullYear(e,t-1,n),r}function o(e,t,n,r,i=!1){return a(t,n,r).toLocaleDateString(e,{month:i?`short`:`long`,timeZone:`UTC`})}function s(e=i(`-`)){return Array.from(Array(12).keys()).map(t=>o(e,2023,t+1,1))}function c(e,t=!0){return Array.from(Array(7).keys()).map(n=>a(2023,4,10+n).toLocaleDateString(e,{weekday:t?`short`:`long`,timeZone:`UTC`}))}function l(e,t){return a(t,e,1).getUTCDay()||7}function u(e,n,r,i){let a=e+i,o=n,s=r;for(;a<1;)--o,o<1&&(o=12,--s),a+=t({year:s,month:o});for(;a>t({year:s,month:o});)a-=t({year:s,month:o}),o+=1,o>12&&(o=1,s+=1);return{day:a,month:o,year:s}}function d(){return r(e(new Date))}function f(e){let t=r(e);return t?`${String(t.day).padStart(2,`0`)}.${String(t.month).padStart(2,`0`)}.${String(t.year).padStart(4,`0`)}`:``}function p(e){let t=/^(\d{2})\.(\d{2})\.(\d{4})$/.exec(e);if(!t)return null;let i=n({day:Number(t[1]),month:Number(t[2]),year:Number(t[3])});return r(i)?i:null}function m(e,t,n){let r=e,i=n;return r[0]!==`_`&&(r[0]>`3`?(r=`0${r[0]}${t.substring(2)}`,i={start:3,end:3}):r[0]===`3`&&r[1]!==`_`&&r[1]>`1`&&(r=`0${r[1]}${t.substring(2)}`,i={start:3,end:3})),r[3]!==`_`&&r[3]>`1`&&(r=`${r.substring(0,3)}0${r[3]}${t.substring(5)}`,i={start:6,end:6}),r[3]===`1`&&r[4]!==`_`&&r[4]>`2`&&(r=`${r.substring(0,3)}${r[3]}2${t.substring(5)}`),{value:r,selection:i}}export{u as addDays,m as correctDateMaskValue,f as getDateString,o as getMonthName,s as getMonthNames,l as getStartWeekDayOfMonth,d as getToday,c as getWeekDays,p as parseDateString};
2
2
  //# sourceMappingURL=dateFunctions.mjs.map
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../button/button.mjs";import n from"../actionIcon/actionIcon.mjs";import{PopoverAlign as r,PopoverPlacement as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import ne from"../tooltip/tooltip.mjs";import re from"../input/input.mjs";import ie from"../modal/modal.mjs";import{getLocale as ae}from"../../services/localization.mjs";import{asDay as i,parseDay as a}from"../utils/day.mjs";import{correctDateMaskValue as oe,getDateString as o,getMonthName as se,getMonthNames as ce,getToday as s,parseDateString as le}from"./dateFunctions.mjs";import ue from"./components/datePickerMonth/datePickerMonth.mjs";import c from"../dropdown/dropdown.mjs";import de from"../maskedInput/maskedInput.mjs";import l from"./datePicker.module.mjs";import{useEffect as u,useRef as d,useState as f}from"react";import p from"classnames";import{faChevronLeft as fe,faChevronRight as pe}from"@fortawesome/free-solid-svg-icons";import{Fragment as me,jsx as m,jsxs as h}from"react/jsx-runtime";function he(e){return e==null||e===``||i(e)?null:Object.prototype.toString.call(e)===`[object Date]`?`a Date. Convert it with dateToDay()`:`${JSON.stringify(e)}, which is not a day`}function g(g){let{className:ge=``,selected:_,onSelect:_e=()=>null,formValidator:v=null,noInput:ve=!1,noHeader:ye=!1,isModal:y=!1,isInline:b=!1,onChange:be=()=>null,minDate:x=null,maxDate:S=null,children:xe=null,showClearButton:Se=!1,label:C=``,isValid:Ce=!0,errorMessage:w=``,isRequired:we=!1,startDate:T,endDate:E,style:Te,classNames:D,styles:O,...Ee}=e(`DatePicker`,g),k=()=>i(v?v.value:_),A=i(x),j=i(S),M=k(),N=a(M)??s(),[P,F]=f(N.month),[I,L]=f(N.year),[R,z]=f(!1),[B,V]=f(()=>o(M)),[De,H]=f(!1),[Oe,U]=f(!1),[,ke]=f(0),[Ae,je]=f(_),W=d(v);if(Ae!==_){je(_);let e=a(_)??s();F(e.month),L(e.year),V(o(_))}let G=d(new Set),K=v?.value;u(()=>{let e={selected:_,formValidator:K,minDate:x,maxDate:S,startDate:T,endDate:E};for(let[t,n]of Object.entries(e)){let e=he(n);e&&!G.current.has(t)&&(G.current.add(t),console.warn(`DatePicker: \`${t}\` takes a day as a 'YYYY-MM-DD' string, and got ${e}. See "Migration from Date values" in docs/DatePicker.md.`))}},[_,K,x,S,T,E]),u(()=>{if(W.current=v,!v)return;v.label=C,v.validate();let e=()=>{let e=a(v.value);e&&(F(e.month),L(e.year)),V(o(v.value)),ke(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v,C]);let Me=()=>v?v.touched&&v.hasError():!Ce||!!w,Ne=()=>!!(we||v?.validators.find(e=>e.validatorId===`required`)),q=e=>{V(o(e)),v&&v.set(e),be(e)},J=e=>{q(e),_e(e),z(!1)},Y=e=>{let t=I*12+P-1+e,n=Math.floor(t/12);n<0||n>9999||(L(n),F(t%12+1))},X=e=>{let t=le(e);return!t||A&&t<A||j&&t>j?null:t},Pe=({previousState:e,nextState:t})=>{if(t.value===e.value)return t;let n=oe(t.value,e.value,t.selection??null),r=X(n.value);return r&&q(r),n},Fe=()=>{let e=400,t=s().year-200,n=a(A),r=a(j);return n&&(t=n.year),r&&(e=Math.max(0,r.year-t+1)),Array.from(Array(e).keys()).map(e=>({key:e+t,label:e+t}))},Z=k(),Ie=Me(),Le=ye?null:h(`div`,{className:p(l.datePickerHeader,D?.header),style:O?.header,children:[m(n,{icon:fe,onClick:()=>Y(-1)}),m(`div`,{className:l.datePickerHeaderMonthAndYearContainer,children:h(`div`,{className:l.datePickerHeaderMonthAndYear,children:[m(c,{plainStyle:!0,scrollToSelected:!0,onChange:e=>F(e),className:p(l.datePickerHeaderMonth,D?.monthDropdown),style:O?.monthDropdown,value:se(ae(`-`),I,P,1),items:ce().map((e,t)=>({key:t+1,label:e}))}),m(c,{plainStyle:!0,scrollToSelected:!0,useMatLabelStyle:!1,className:p(l.datePickerHeaderYear,D?.yearDropdown),style:O?.yearDropdown,onChange:e=>L(e),value:I,items:Fe()})]})}),m(n,{icon:pe,onClick:()=>Y(1)})]}),Q=h(me,{children:[Le,m(ue,{className:p(l.datePickerMonth,D?.calendar),style:O?.calendar,month:P,year:I,onSelect:J,selectionStart:i(T)??Z,selectionEnd:i(E)??Z,minDate:A,maxDate:j,onNavigateMonth:Y}),Se&&m(t,{onClick:()=>J(null),className:D?.clearButton,style:O?.clearButton,children:`Clear`}),xe]}),$=ve?null:m(re,{autoComplete:`off`,className:D?.input,style:O?.input,readOnly:y,classNames:y?{input:l.datePickerModalInput}:void 0,label:`${C}${Ne()?` *`:``}`,value:B,onChange:e=>V(e),onClick:()=>z(!0),customInput:m(de,{mask:`99.99.9999`,beforeMaskedStateChange:Pe}),onBlur:()=>{W.current&&(W.current.touched=!0),H(!1),B!==o(k())&&q(X(B))},onFocus:()=>H(!0),onMouseEnter:()=>U(!0),onMouseLeave:()=>U(!1),isValid:!Ie}),Re=b?Q:y?m(ie,{hideHeader:!0,isOpen:R,onClose:()=>z(!1),children:Q}):m(te,{isOpen:R,onOpenChange:e=>z(e),content:Q,placement:ee.Bottom,align:r.Start,closeOnTriggerClick:!1,constrainWidth:!1,children:$});return h(`div`,{...Ee,className:p(l.datePicker,ge,D?.root),style:{...Te,...O?.root},children:[(y||b)&&$,Re,m(ne,{variant:`error`,message:v?v.getCurrentErrorMessage():w||``,isVisible:Ie&&(De||Oe)})]})}export{g as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../button/button.mjs";import n from"../actionIcon/actionIcon.mjs";import{PopoverAlign as r,PopoverPlacement as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import{asDay as i,parseDay as a}from"../utils/day.mjs";import ne from"../tooltip/tooltip.mjs";import re from"../input/input.mjs";import ie from"../modal/modal.mjs";import{getLocale as ae}from"../../services/localization.mjs";import{correctDateMaskValue as oe,getDateString as o,getMonthName as se,getMonthNames as ce,getToday as s,parseDateString as le}from"./dateFunctions.mjs";import ue from"./components/datePickerMonth/datePickerMonth.mjs";import c from"../dropdown/dropdown.mjs";import de from"../maskedInput/maskedInput.mjs";import l from"./datePicker.module.mjs";import{useEffect as u,useRef as d,useState as f}from"react";import p from"classnames";import{faChevronLeft as fe,faChevronRight as pe}from"@fortawesome/free-solid-svg-icons";import{Fragment as me,jsx as m,jsxs as h}from"react/jsx-runtime";function he(e){return e==null||e===``||i(e)?null:Object.prototype.toString.call(e)===`[object Date]`?`a Date. Convert it with dateToDay()`:`${JSON.stringify(e)}, which is not a day`}function g(g){let{className:ge=``,selected:_,onSelect:_e=()=>null,formValidator:v=null,noInput:ve=!1,noHeader:ye=!1,isModal:y=!1,isInline:b=!1,onChange:be=()=>null,minDate:x=null,maxDate:S=null,children:xe=null,showClearButton:Se=!1,label:C=``,isValid:Ce=!0,errorMessage:w=``,isRequired:we=!1,startDate:T,endDate:E,style:Te,classNames:D,styles:O,...Ee}=e(`DatePicker`,g),k=()=>i(v?v.value:_),A=i(x),j=i(S),M=k(),N=a(M)??s(),[P,F]=f(N.month),[I,L]=f(N.year),[R,z]=f(!1),[B,V]=f(()=>o(M)),[De,H]=f(!1),[Oe,U]=f(!1),[,ke]=f(0),[Ae,je]=f(_),W=d(v);if(Ae!==_){je(_);let e=a(_)??s();F(e.month),L(e.year),V(o(_))}let G=d(new Set),K=v?.value;u(()=>{let e={selected:_,formValidator:K,minDate:x,maxDate:S,startDate:T,endDate:E};for(let[t,n]of Object.entries(e)){let e=he(n);e&&!G.current.has(t)&&(G.current.add(t),console.warn(`DatePicker: \`${t}\` takes a day as a 'YYYY-MM-DD' string, and got ${e}. See "Migration from Date values" in docs/DatePicker.md.`))}},[_,K,x,S,T,E]),u(()=>{if(W.current=v,!v)return;v.label=C,v.validate();let e=()=>{let e=a(v.value);e&&(F(e.month),L(e.year)),V(o(v.value)),ke(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v,C]);let Me=()=>v?v.touched&&v.hasError():!Ce||!!w,Ne=()=>!!(we||v?.validators.find(e=>e.validatorId===`required`)),q=e=>{V(o(e)),v&&v.set(e),be(e)},J=e=>{q(e),_e(e),z(!1)},Y=e=>{let t=I*12+P-1+e,n=Math.floor(t/12);n<0||n>9999||(L(n),F(t%12+1))},X=e=>{let t=le(e);return!t||A&&t<A||j&&t>j?null:t},Pe=({previousState:e,nextState:t})=>{if(t.value===e.value)return t;let n=oe(t.value,e.value,t.selection??null),r=X(n.value);return r&&q(r),n},Fe=()=>{let e=400,t=s().year-200,n=a(A),r=a(j);return n&&(t=n.year),r&&(e=Math.max(0,r.year-t+1)),Array.from(Array(e).keys()).map(e=>({key:e+t,label:e+t}))},Z=k(),Ie=Me(),Le=ye?null:h(`div`,{className:p(l.datePickerHeader,D?.header),style:O?.header,children:[m(n,{icon:fe,onClick:()=>Y(-1)}),m(`div`,{className:l.datePickerHeaderMonthAndYearContainer,children:h(`div`,{className:l.datePickerHeaderMonthAndYear,children:[m(c,{plainStyle:!0,scrollToSelected:!0,onChange:e=>F(e),className:p(l.datePickerHeaderMonth,D?.monthDropdown),style:O?.monthDropdown,value:se(ae(`-`),I,P,1),items:ce().map((e,t)=>({key:t+1,label:e}))}),m(c,{plainStyle:!0,scrollToSelected:!0,useMatLabelStyle:!1,className:p(l.datePickerHeaderYear,D?.yearDropdown),style:O?.yearDropdown,onChange:e=>L(e),value:I,items:Fe()})]})}),m(n,{icon:pe,onClick:()=>Y(1)})]}),Q=h(me,{children:[Le,m(ue,{className:p(l.datePickerMonth,D?.calendar),style:O?.calendar,month:P,year:I,onSelect:J,selectionStart:i(T)??Z,selectionEnd:i(E)??Z,minDate:A,maxDate:j,onNavigateMonth:Y}),Se&&m(t,{onClick:()=>J(null),className:D?.clearButton,style:O?.clearButton,children:`Clear`}),xe]}),$=ve?null:m(re,{autoComplete:`off`,className:D?.input,style:O?.input,readOnly:y,classNames:y?{input:l.datePickerModalInput}:void 0,label:`${C}${Ne()?` *`:``}`,value:B,onChange:e=>V(e),onClick:()=>z(!0),customInput:m(de,{mask:`99.99.9999`,beforeMaskedStateChange:Pe}),onBlur:()=>{W.current&&(W.current.touched=!0),H(!1),B!==o(k())&&q(X(B))},onFocus:()=>H(!0),onMouseEnter:()=>U(!0),onMouseLeave:()=>U(!1),isValid:!Ie}),Re=b?Q:y?m(ie,{hideHeader:!0,isOpen:R,onClose:()=>z(!1),children:Q}):m(te,{isOpen:R,onOpenChange:e=>z(e),content:Q,placement:ee.Bottom,align:r.Start,closeOnTriggerClick:!1,constrainWidth:!1,children:$});return h(`div`,{...Ee,className:p(l.datePicker,ge,D?.root),style:{...Te,...O?.root},children:[(y||b)&&$,Re,m(ne,{variant:`error`,message:v?v.getCurrentErrorMessage():w||``,isVisible:Ie&&(De||Oe)})]})}export{g as default};
2
2
  //# sourceMappingURL=datePicker.mjs.map
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import n from"../tooltip/tooltip.mjs";import ee from"../animatedIcon/animatedIcon.mjs";import r from"./input.module.mjs";import{mergeRefs as te}from"../utils/mergeRefs.mjs";import{InputIconPosition as i,InputType as a}from"./input.types.mjs";import ne,{useCallback as re,useEffect as o,useId as ie,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faEnvelope as ae,faEye as oe,faEyeSlash as se,faPen as ce,faPhone as le,faSearch as ue,faXmark as de}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";var fe={clear:`Clear`,showPassword:`Show password`,hidePassword:`Hide password`,clearSearch:`Clear search`};function p(e){if(e)return{role:`button`,tabIndex:0,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e(t))}}}function pe(pe){let{name:me=``,id:he,label:m=``,errorMessage:h=``,isValid:ge=!0,className:_e=``,style:ve,value:ye=``,icon:g=null,iconPosition:be,onChange:_=()=>{},onFocus:xe=null,onBlur:Se=null,onMouseEnter:Ce=null,onMouseLeave:we=null,isUppercase:Te=!1,isRequired:Ee=!1,tabIndex:De=0,type:v=void 0,isRow:Oe=!1,onIconClick:y=null,parse:ke=null,formValidator:b=null,autoFocus:Ae=!1,suffix:je=null,upperRightLabel:x=null,labelInBorder:Me=!1,showCancel:Ne=!1,onClearClicked:Pe,min:Fe=null,max:Ie=null,placeholder:S=``,useMatLabelStyle:C=!0,alwaysFloatLabel:Le=!1,autoComplete:Re=null,onClick:ze=()=>null,readOnly:w=!1,customInput:T,alwaysShowCancel:Be=!1,multiline:E=!1,rows:Ve,autoResize:D=!1,classNames:O,styles:k,disabled:He=!1,labels:Ue,ref:We,...A}=e(`Input`,pe),j=t(`Input`,Ue,fe),[M,Ge]=c(!1),[Ke,N]=c(!1),[P,F]=c(!1),[I,L]=c(!1),[,qe]=c(0),R=s(null),z=s(b),Je=ie(),Ye=he||me||Je,B=b?b.value:ye,Xe=s(!1),V=re(()=>{let e=R.current;if(e){if(!D){Xe.current&&=(e.style.height=``,!1);return}e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`,Xe.current=!0}},[D]);o(()=>{V()},[V,B]),o(()=>{Ae&&R.current&&setTimeout(()=>{R.current?.focus()},1)},[Ae]),o(()=>{z.current=b;let e=z.current;if(!e)return;e.label=m??``,e.validate();let t=()=>qe(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[b,m]);let Ze=()=>b?b.touched&&b.hasError():!ge||!!h,Qe=()=>!!(Ee||b&&b.validators.find(e=>e.validatorId===`required`)),$e=e=>{F(!0),Ce&&Ce(e)},et=e=>{F(!1),we&&we(e)},tt=e=>{Ge(!0),xe&&xe(e)},nt=e=>{z.current&&(z.current.touched=!0),Ge(!1),Se&&Se(e)},rt=e=>{let t,n;typeof e==`string`?n=e:(t=e,n=e.target.value),ke&&(n=ke(n)),b&&b.set(n),_&&_(n,t),V()},it=()=>{if(v!==a.Email)return v===a.Phone?`tel`:v===a.Search?`search`:v===`password`&&I?`text`:v},at=()=>{if(v===a.Email)return`email`;if(v===a.Phone)return`tel`;if(v===a.Search)return`search`},ot=v&&v!==a.Date&&v!==a.Iban&&v!==a.HasNoIcon,st=v===a.Search||v===a.Password,H=!!g,ct=H&&!st,lt=v===a.Email||v===a.Phone||v===a.Search,U=(be??(!C&&lt?i.Left:i.Right))===i.Left,W={className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!y,[r.inputFieldIconLeft]:U}),onClick:y??void 0,...p(y)},G=g,K=y??G?.props.onClick,ut=ct&&G?ne.cloneElement(G,{className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!K,[r.inputFieldIconLeft]:U},G.props.className),onClick:K,...p(K)}):null,dt=(ot||H)&&U,ft={className:l(r.inputFieldIcon,r.inputFieldIconPassword,{[r.inputFieldIconLeft]:U}),onClick:()=>L(!I),...p(()=>L(!I)),"aria-label":I?j.hidePassword:j.showPassword},q=Ze(),J=m;J&&Qe()&&(J=`${J} *`);let pt=Qe()?d(`span`,{className:r.requiredMark,children:`*`}):null,Y=M&&!w,X=C&&(Le||Y||B||Ke||v===a.Date),mt=e=>{let{animationName:t}=e;if(t===r.inputAutofillStart){N(!0);let t=e.currentTarget.value;t&&t!==String(B??``)&&rt(t);return}if(t===r.inputAutofillEnd){N(!1);return}A.onAnimationStart?.(e)},Z=v===a.Search&&!!B,Q=T?.props;function $(){b&&b.set(``),_?.(``),Pe?.()}return f(`div`,{className:l(r.input,{[r.inputIconLeft]:dt},_e),style:ve,children:[f(`label`,{htmlFor:Ye,className:l(r.inputLabel,O?.label,{[r.inputLabelColumn]:!Oe,[r.inputLabelInBorder]:Me}),style:k?.label,children:[m&&!C?f(`span`,{className:r.inputLabelText,children:[m,pt]}):null,x&&d(`div`,{className:l(r.inputUpperRightLabel,O?.upperRightLabel),style:k?.upperRightLabel,children:x}),f(`div`,{className:l(r.inputContainer,{[r.inputContainerMultiline]:E},O?.container),style:k?.container,onMouseEnter:$e,onMouseLeave:et,children:[ut,ne.cloneElement(T||d(E?`textarea`:`input`,{}),{...A,className:l(r.inputField,{[r.inputFieldUppercase]:Te,[r.inputFieldDate]:v===a.Date,[r.inputFieldDefault]:v!==a.Date,[r.inputFieldWithIcon]:ot||H,[r.inputFieldWithIconLeft]:dt,[r.inputFieldMultiline]:E,[r.inputFieldMultilineAutoResize]:E&&D,[r.inputFieldReadOnly]:w&&!He},O?.input,Q?.className),style:Q?.style||k?.input?{...Q?.style,...k?.input}:void 0,name:me,id:Ye,value:B,tabIndex:De,ref:T?void 0:te(R,We),onChange:rt,onAnimationStart:mt,onFocus:tt,onBlur:nt,placeholder:C?``:S,autoComplete:Re,onClick:ze,readOnly:w,disabled:He,...!E&&{type:it(),inputMode:A.inputMode??at(),min:Fe,max:Ie},...E&&Ve!==void 0&&{rows:Ve}}),je&&d(`div`,{className:l(r.inputFieldSuffix,O?.suffix),style:k?.suffix,children:je})]}),d(`fieldset`,{className:l(r.inputFieldset,O?.fieldset,{[r.inputContainerBorderFocused]:Y,[r.inputContainerBorderSearchFocused]:v===a.Search&&(Y||!!B),[r.inputContainerBorderInvalid]:q,[r.inputContainerBorderError]:q}),style:k?.fieldset,children:d(`legend`,{className:l(r.inputFieldsetLegend,{[r.inputFieldsetLegendActive]:X}),children:d(`span`,{children:J})})}),C&&m&&f(`div`,{className:l(r.inputMatLabel,{[r.inputMatLabelFloating]:X,[r.inputMatLabelMultiline]:E&&!X}),children:[m,pt]}),C&&S&&d(`div`,{className:l(r.inputPlaceholder,Y&&!B&&!Ke&&r.inputPlaceholderShown,E&&r.inputPlaceholderMultiline),children:S}),d(n,{variant:`error`,message:b?b.getCurrentErrorMessage():h||``,isVisible:q&&(M||P)})]}),v===a.Phone&&!H&&d(u,{icon:le,...W}),v===a.Email&&!H&&d(u,{icon:ae,...W}),v===a.Edit&&!H&&d(u,{icon:ce,...W}),v===a.Search&&d(ee,{icon:Z?de:ue,className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!Z,[r.inputFieldIconLeft]:U}),onClick:Z?$:void 0,...p(Z?$:void 0),"aria-label":Z?j.clearSearch:void 0}),v===a.Password&&d(u,{icon:I?se:oe,...ft}),(Ne&&B&&(M||P)||Be)&&v!==a.Search&&d(u,{icon:de,className:r.inputFieldIcon,onClick:$,onMouseEnter:()=>F(!0),onMouseLeave:()=>F(!1),...p($),"aria-label":j.clear})]})}export{pe as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{mergeRefs as n}from"../utils/mergeRefs.mjs";import ee from"../tooltip/tooltip.mjs";import te from"../animatedIcon/animatedIcon.mjs";import r from"./input.module.mjs";import{InputIconPosition as i,InputType as a}from"./input.types.mjs";import ne,{useCallback as re,useEffect as o,useId as ie,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faEnvelope as ae,faEye as oe,faEyeSlash as se,faPen as ce,faPhone as le,faSearch as ue,faXmark as de}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";var fe={clear:`Clear`,showPassword:`Show password`,hidePassword:`Hide password`,clearSearch:`Clear search`};function p(e){if(e)return{role:`button`,tabIndex:0,onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),e(t))}}}function pe(pe){let{name:me=``,id:he,label:m=``,errorMessage:h=``,isValid:ge=!0,className:_e=``,style:ve,value:ye=``,icon:g=null,iconPosition:be,onChange:_=()=>{},onFocus:xe=null,onBlur:Se=null,onMouseEnter:Ce=null,onMouseLeave:we=null,isUppercase:Te=!1,isRequired:Ee=!1,tabIndex:De=0,type:v=void 0,isRow:Oe=!1,onIconClick:y=null,parse:ke=null,formValidator:b=null,autoFocus:Ae=!1,suffix:je=null,upperRightLabel:x=null,labelInBorder:Me=!1,showCancel:Ne=!1,onClearClicked:Pe,min:Fe=null,max:Ie=null,placeholder:S=``,useMatLabelStyle:C=!0,alwaysFloatLabel:Le=!1,autoComplete:Re=null,onClick:ze=()=>null,readOnly:w=!1,customInput:T,alwaysShowCancel:Be=!1,multiline:E=!1,rows:Ve,autoResize:D=!1,classNames:O,styles:k,disabled:He=!1,labels:Ue,ref:We,...A}=e(`Input`,pe),j=t(`Input`,Ue,fe),[M,Ge]=c(!1),[Ke,N]=c(!1),[P,F]=c(!1),[I,L]=c(!1),[,qe]=c(0),R=s(null),z=s(b),Je=ie(),Ye=he||me||Je,B=b?b.value:ye,Xe=s(!1),V=re(()=>{let e=R.current;if(e){if(!D){Xe.current&&=(e.style.height=``,!1);return}e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`,Xe.current=!0}},[D]);o(()=>{V()},[V,B]),o(()=>{Ae&&R.current&&setTimeout(()=>{R.current?.focus()},1)},[Ae]),o(()=>{z.current=b;let e=z.current;if(!e)return;e.label=m??``,e.validate();let t=()=>qe(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[b,m]);let Ze=()=>b?b.touched&&b.hasError():!ge||!!h,Qe=()=>!!(Ee||b&&b.validators.find(e=>e.validatorId===`required`)),$e=e=>{F(!0),Ce&&Ce(e)},et=e=>{F(!1),we&&we(e)},tt=e=>{Ge(!0),xe&&xe(e)},nt=e=>{z.current&&(z.current.touched=!0),Ge(!1),Se&&Se(e)},rt=e=>{let t,n;typeof e==`string`?n=e:(t=e,n=e.target.value),ke&&(n=ke(n)),b&&b.set(n),_&&_(n,t),V()},it=()=>{if(v!==a.Email)return v===a.Phone?`tel`:v===a.Search?`search`:v===`password`&&I?`text`:v},at=()=>{if(v===a.Email)return`email`;if(v===a.Phone)return`tel`;if(v===a.Search)return`search`},ot=v&&v!==a.Date&&v!==a.Iban&&v!==a.HasNoIcon,st=v===a.Search||v===a.Password,H=!!g,ct=H&&!st,lt=v===a.Email||v===a.Phone||v===a.Search,U=(be??(!C&&lt?i.Left:i.Right))===i.Left,W={className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!y,[r.inputFieldIconLeft]:U}),onClick:y??void 0,...p(y)},G=g,K=y??G?.props.onClick,ut=ct&&G?ne.cloneElement(G,{className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!K,[r.inputFieldIconLeft]:U},G.props.className),onClick:K,...p(K)}):null,dt=(ot||H)&&U,ft={className:l(r.inputFieldIcon,r.inputFieldIconPassword,{[r.inputFieldIconLeft]:U}),onClick:()=>L(!I),...p(()=>L(!I)),"aria-label":I?j.hidePassword:j.showPassword},q=Ze(),J=m;J&&Qe()&&(J=`${J} *`);let pt=Qe()?d(`span`,{className:r.requiredMark,children:`*`}):null,Y=M&&!w,X=C&&(Le||Y||B||Ke||v===a.Date),mt=e=>{let{animationName:t}=e;if(t===r.inputAutofillStart){N(!0);let t=e.currentTarget.value;t&&t!==String(B??``)&&rt(t);return}if(t===r.inputAutofillEnd){N(!1);return}A.onAnimationStart?.(e)},Z=v===a.Search&&!!B,Q=T?.props;function $(){b&&b.set(``),_?.(``),Pe?.()}return f(`div`,{className:l(r.input,{[r.inputIconLeft]:dt},_e),style:ve,children:[f(`label`,{htmlFor:Ye,className:l(r.inputLabel,O?.label,{[r.inputLabelColumn]:!Oe,[r.inputLabelInBorder]:Me}),style:k?.label,children:[m&&!C?f(`span`,{className:r.inputLabelText,children:[m,pt]}):null,x&&d(`div`,{className:l(r.inputUpperRightLabel,O?.upperRightLabel),style:k?.upperRightLabel,children:x}),f(`div`,{className:l(r.inputContainer,{[r.inputContainerMultiline]:E},O?.container),style:k?.container,onMouseEnter:$e,onMouseLeave:et,children:[ut,ne.cloneElement(T||d(E?`textarea`:`input`,{}),{...A,className:l(r.inputField,{[r.inputFieldUppercase]:Te,[r.inputFieldDate]:v===a.Date,[r.inputFieldDefault]:v!==a.Date,[r.inputFieldWithIcon]:ot||H,[r.inputFieldWithIconLeft]:dt,[r.inputFieldMultiline]:E,[r.inputFieldMultilineAutoResize]:E&&D,[r.inputFieldReadOnly]:w&&!He},O?.input,Q?.className),style:Q?.style||k?.input?{...Q?.style,...k?.input}:void 0,name:me,id:Ye,value:B,tabIndex:De,ref:T?void 0:n(R,We),onChange:rt,onAnimationStart:mt,onFocus:tt,onBlur:nt,placeholder:C?``:S,autoComplete:Re,onClick:ze,readOnly:w,disabled:He,...!E&&{type:it(),inputMode:A.inputMode??at(),min:Fe,max:Ie},...E&&Ve!==void 0&&{rows:Ve}}),je&&d(`div`,{className:l(r.inputFieldSuffix,O?.suffix),style:k?.suffix,children:je})]}),d(`fieldset`,{className:l(r.inputFieldset,O?.fieldset,{[r.inputContainerBorderFocused]:Y,[r.inputContainerBorderSearchFocused]:v===a.Search&&(Y||!!B),[r.inputContainerBorderInvalid]:q,[r.inputContainerBorderError]:q}),style:k?.fieldset,children:d(`legend`,{className:l(r.inputFieldsetLegend,{[r.inputFieldsetLegendActive]:X}),children:d(`span`,{children:J})})}),C&&m&&f(`div`,{className:l(r.inputMatLabel,{[r.inputMatLabelFloating]:X,[r.inputMatLabelMultiline]:E&&!X}),children:[m,pt]}),C&&S&&d(`div`,{className:l(r.inputPlaceholder,Y&&!B&&!Ke&&r.inputPlaceholderShown,E&&r.inputPlaceholderMultiline),children:S}),d(ee,{variant:`error`,message:b?b.getCurrentErrorMessage():h||``,isVisible:q&&(M||P)})]}),v===a.Phone&&!H&&d(u,{icon:le,...W}),v===a.Email&&!H&&d(u,{icon:ae,...W}),v===a.Edit&&!H&&d(u,{icon:ce,...W}),v===a.Search&&d(te,{icon:Z?de:ue,className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!Z,[r.inputFieldIconLeft]:U}),onClick:Z?$:void 0,...p(Z?$:void 0),"aria-label":Z?j.clearSearch:void 0}),v===a.Password&&d(u,{icon:I?se:oe,...ft}),(Ne&&B&&(M||P)||Be)&&v!==a.Search&&d(u,{icon:de,className:r.inputFieldIcon,onClick:$,onMouseEnter:()=>F(!0),onMouseLeave:()=>F(!1),...p($),"aria-label":j.clear})]})}export{pe as default};
2
2
  //# sourceMappingURL=input.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults, useLabels } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport { mergeRefs } from '../utils/mergeRefs';\nimport type { InputLabels, InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nconst DEFAULT_LABELS: Required<InputLabels> = {\n clear: 'Clear',\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n clearSearch: 'Clear search',\n};\n\nfunction keyboardActivationProps(onActivate?: ((event: React.SyntheticEvent) => void) | null) {\n if (!onActivate) return undefined;\n return {\n role: 'button' as const,\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onActivate(event);\n },\n };\n}\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n labels,\n ref,\n ...rest\n } = useComponentDefaults('Input', props);\n const text = useLabels('Input', labels, DEFAULT_LABELS);\n const [isFocused, setIsFocused] = useState(false);\n // Chrome fills a field on page load without firing anything React sees. The animation the\n // stylesheet binds to :-webkit-autofill is the only notification it gives.\n const [isAutofilled, setIsAutofilled] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const currVal = formValidator ? formValidator.value : value;\n const didSetAutoHeightRef = useRef(false);\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (!autoResize) {\n // Only undo a height this set, so an explicit one from `styles.input` survives.\n if (didSetAutoHeightRef.current) {\n el.style.height = '';\n didSetAutoHeightRef.current = false;\n }\n return;\n }\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n didSetAutoHeightRef.current = true;\n }, [autoResize]);\n\n // `currVal` is a dependency because the value can change without passing through\n // `onChangeHandler`: the clear button, a parent resetting it, or `formValidator.set` elsewhere.\n useEffect(() => {\n resizeTextarea();\n }, [resizeTextarea, currVal]);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => {\n inputRef.current?.focus();\n }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n };\n\n const computedIsRequired = (): boolean => {\n return !!(\n isRequired ||\n (formValidator &&\n formValidator.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'))\n );\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon = type && type !== InputType.Date && type !== InputType.Iban && type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition =\n iconPosition ??\n (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n ...keyboardActivationProps(onIconClick),\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const resolvedCustomIconClick = onIconClick ?? customIcon?.props.onClick;\n const renderedIcon =\n customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !resolvedCustomIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: resolvedCustomIconClick,\n ...keyboardActivationProps(resolvedCustomIconClick as ((event: React.SyntheticEvent) => void) | undefined),\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n ...keyboardActivationProps(() => setIsPasswordShown(!isPasswordShown)),\n 'aria-label': isPasswordShown ? text.hidePassword : text.showPassword,\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel =\n useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || isAutofilled || type === InputType.Date);\n\n const handleAutofillAnimation = (event: React.AnimationEvent) => {\n const { animationName } = event;\n if (animationName === styles.inputAutofillStart) {\n setIsAutofilled(true);\n // The field is controlled, so the commit this triggers would write `value` back over\n // what the browser just put there and blank it. Replay it as an ordinary change first.\n const filled = (event.currentTarget as HTMLInputElement).value;\n if (filled && filled !== String(currVal ?? '')) onChangeHandler(filled);\n return;\n }\n if (animationName === styles.inputAutofillEnd) {\n setIsAutofilled(false);\n return;\n }\n // Not ours. `onAnimationStart` arrives through `rest`, and the consumer must not receive\n // the two above: the `:not()` rule fires one of them on every mount.\n rest.onAnimationStart?.(event as React.AnimationEvent<HTMLInputElement>);\n };\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n const customInputProps = customInput?.props as { className?: string; style?: React.CSSProperties } | undefined;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div\n className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)}\n style={slotStyles?.upperRightLabel}\n >\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input,\n customInputProps?.className,\n ),\n style:\n customInputProps?.style || slotStyles?.input\n ? { ...customInputProps?.style, ...slotStyles?.input }\n : undefined,\n name,\n id: inputId,\n value: currVal,\n tabIndex,\n ref: customInput ? undefined : mergeRefs(inputRef, ref),\n onChange: onChangeHandler,\n onAnimationStart: handleAutofillAnimation,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && (\n <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>\n {suffix}\n </div>\n )}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]: type === InputType.Search && (showFocus || !!currVal),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && !isAutofilled && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant='error'\n message={formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n {...keyboardActivationProps(isSearchCleared ? handleClear : undefined)}\n aria-label={isSearchCleared ? text.clearSearch : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon} {...passwordIconProps} />\n )}\n\n {((showCancel && currVal && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...keyboardActivationProps(handleClear)}\n aria-label={text.clear}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"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"}
1
+ {"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults, useLabels } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport { mergeRefs } from '../utils/mergeRefs';\nimport type { InputLabels, InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nconst DEFAULT_LABELS: Required<InputLabels> = {\n clear: 'Clear',\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n clearSearch: 'Clear search',\n};\n\nfunction keyboardActivationProps(onActivate?: ((event: React.SyntheticEvent) => void) | null) {\n if (!onActivate) return undefined;\n return {\n role: 'button' as const,\n tabIndex: 0,\n onKeyDown: (event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onActivate(event);\n },\n };\n}\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n labels,\n ref,\n ...rest\n } = useComponentDefaults('Input', props);\n const text = useLabels('Input', labels, DEFAULT_LABELS);\n const [isFocused, setIsFocused] = useState(false);\n // Chrome fills a field on page load without firing anything React sees. The animation the\n // stylesheet binds to :-webkit-autofill is the only notification it gives.\n const [isAutofilled, setIsAutofilled] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const currVal = formValidator ? formValidator.value : value;\n const didSetAutoHeightRef = useRef(false);\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (!autoResize) {\n // Only undo a height this set, so an explicit one from `styles.input` survives.\n if (didSetAutoHeightRef.current) {\n el.style.height = '';\n didSetAutoHeightRef.current = false;\n }\n return;\n }\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n didSetAutoHeightRef.current = true;\n }, [autoResize]);\n\n // `currVal` is a dependency because the value can change without passing through\n // `onChangeHandler`: the clear button, a parent resetting it, or `formValidator.set` elsewhere.\n useEffect(() => {\n resizeTextarea();\n }, [resizeTextarea, currVal]);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => {\n inputRef.current?.focus();\n }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n };\n\n const computedIsRequired = (): boolean => {\n return !!(\n isRequired ||\n (formValidator &&\n formValidator.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'))\n );\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon = type && type !== InputType.Date && type !== InputType.Iban && type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition =\n iconPosition ??\n (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n ...keyboardActivationProps(onIconClick),\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const resolvedCustomIconClick = onIconClick ?? customIcon?.props.onClick;\n const renderedIcon =\n customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !resolvedCustomIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: resolvedCustomIconClick,\n ...keyboardActivationProps(resolvedCustomIconClick as ((event: React.SyntheticEvent) => void) | undefined),\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n ...keyboardActivationProps(() => setIsPasswordShown(!isPasswordShown)),\n 'aria-label': isPasswordShown ? text.hidePassword : text.showPassword,\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel =\n useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || isAutofilled || type === InputType.Date);\n\n const handleAutofillAnimation = (event: React.AnimationEvent) => {\n const { animationName } = event;\n if (animationName === styles.inputAutofillStart) {\n setIsAutofilled(true);\n // The field is controlled, so the commit this triggers would write `value` back over\n // what the browser just put there and blank it. Replay it as an ordinary change first.\n const filled = (event.currentTarget as HTMLInputElement).value;\n if (filled && filled !== String(currVal ?? '')) onChangeHandler(filled);\n return;\n }\n if (animationName === styles.inputAutofillEnd) {\n setIsAutofilled(false);\n return;\n }\n // Not ours. `onAnimationStart` arrives through `rest`, and the consumer must not receive\n // the two above: the `:not()` rule fires one of them on every mount.\n rest.onAnimationStart?.(event as React.AnimationEvent<HTMLInputElement>);\n };\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n const customInputProps = customInput?.props as { className?: string; style?: React.CSSProperties } | undefined;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div\n className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)}\n style={slotStyles?.upperRightLabel}\n >\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input,\n customInputProps?.className,\n ),\n style:\n customInputProps?.style || slotStyles?.input\n ? { ...customInputProps?.style, ...slotStyles?.input }\n : undefined,\n name,\n id: inputId,\n value: currVal,\n tabIndex,\n ref: customInput ? undefined : mergeRefs(inputRef, ref),\n onChange: onChangeHandler,\n onAnimationStart: handleAutofillAnimation,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && (\n <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>\n {suffix}\n </div>\n )}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]: type === InputType.Search && (showFocus || !!currVal),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && !isAutofilled && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant='error'\n message={formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n {...keyboardActivationProps(isSearchCleared ? handleClear : undefined)}\n aria-label={isSearchCleared ? text.clearSearch : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon} {...passwordIconProps} />\n )}\n\n {((showCancel && currVal && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n {...keyboardActivationProps(handleClear)}\n aria-label={text.clear}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"../styles/scrollFade.module.mjs";import l from"./modal.module.mjs";import{useScrollEdges as u}from"../hooks/useScrollEdges.mjs";import{useEffect as d,useId as f,useRef as p,useState as m}from"react";import h from"classnames";import{FontAwesomeIcon as g}from"@fortawesome/react-fontawesome";import{faXmark as _}from"@fortawesome/free-solid-svg-icons";import{jsx as v,jsxs as y}from"react/jsx-runtime";var b={close:`Close`};function x(x){let{children:S=null,title:C=``,isOpen:w=!1,onClose:T=()=>null,footer:E=null,className:D=``,style:O,hideHeader:k=!1,closeOnEscape:A=!0,presentation:j,classNames:M,styles:N,labels:P,...F}=e(`Modal`,x),I=t(`Modal`,P,b),[L,R]=m(w),[z,B]=m(w),V=p(null),H=p(null),U=f(),{height:W,offsetTop:G}=a(),K=n(),{isSheet:q,sheetStyle:J}=o(j??K);d(()=>{w?(R(w),setTimeout(()=>B(!0),1)):(B(!1),setTimeout(()=>R(w),300))},[w]),s({isActive:L&&z,containerRef:V,onEscape:A?T:void 0});let{hasStart:Y,hasEnd:X}=u(H,{isEnabled:L&&z});if(!L)return null;let Z=!k&&!!C;return v(r,{children:y(`div`,{className:h(l.modalContainer,M?.container),style:{height:W,top:G,...N?.container},children:[v(`div`,{className:h(l.modalWrapper,z&&l.modalWrapperShown,M?.backdrop),style:N?.backdrop,onClick:T}),z&&y(`div`,{...F,ref:V,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Z?U:void 0,tabIndex:-1,className:h(l.modal,z&&l.modalShown,q&&[i.sheet,i.sheetSurface,l.modalSheet],D,M?.modal),style:{...q?J:void 0,...O,...N?.modal},onClick:e=>e.stopPropagation(),children:[!k&&y(`div`,{className:h(l.modalHeader,M?.header),style:N?.header,children:[v(`div`,{id:U,className:M?.title,style:N?.title,children:C}),v(`button`,{type:`button`,onClick:T,"aria-label":I.close,className:h(l.modalCloseButton,M?.closeButton),style:N?.closeButton,children:v(g,{icon:_})})]}),v(`div`,{ref:H,className:h(l.modalBody,c.scrollFade,c.scrollFadeY,Y&&c.scrollFadeFadedStart,X&&c.scrollFadeFadedEnd,M?.body),style:N?.body,children:S}),E&&v(`div`,{className:h(l.modalFooter,M?.footer),style:N?.footer,children:E})]})]})})}export{x as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"../styles/scrollFade.module.mjs";import l from"./modal.module.mjs";import{useScrollEdges as u}from"../hooks/useScrollEdges.mjs";import{useEffect as d,useId as f,useRef as p,useState as m}from"react";import h from"classnames";import{FontAwesomeIcon as g}from"@fortawesome/react-fontawesome";import{faXmark as _}from"@fortawesome/free-solid-svg-icons";import{jsx as v,jsxs as y}from"react/jsx-runtime";var b={close:`Close`};function x(x){let{children:S=null,title:C,isOpen:w=!1,onClose:T=()=>null,footer:E=null,className:D=``,style:O,hideHeader:k=!1,closeOnEscape:A=!0,presentation:j,classNames:M,styles:N,labels:P,...F}=e(`Modal`,x),I=t(`Modal`,P,b),[L,R]=m(w),[z,B]=m(w),V=p(null),H=p(null),U=f(),{height:W,offsetTop:G}=a(),K=n(),{isSheet:q,sheetStyle:J}=o(j??K);d(()=>{w?(R(w),setTimeout(()=>B(!0),1)):(B(!1),setTimeout(()=>R(w),300))},[w]),s({isActive:L&&z,containerRef:V,onEscape:A?T:void 0});let{hasStart:Y,hasEnd:X}=u(H,{isEnabled:L&&z});if(!L)return null;let Z=!k&&!!C;return v(r,{children:y(`div`,{className:h(l.modalContainer,M?.container),style:{height:W,top:G,...N?.container},children:[v(`div`,{className:h(l.modalWrapper,z&&l.modalWrapperShown,M?.backdrop),style:N?.backdrop,onClick:T}),z&&y(`div`,{...F,ref:V,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Z&&!F[`aria-label`]?U:void 0,tabIndex:-1,className:h(l.modal,z&&l.modalShown,q&&[i.sheet,i.sheetSurface,l.modalSheet],D,M?.modal),style:{...q?J:void 0,...O,...N?.modal},onClick:e=>e.stopPropagation(),children:[!k&&y(`div`,{className:h(l.modalHeader,M?.header),style:N?.header,children:[v(`div`,{id:U,className:M?.title,style:N?.title,children:C}),v(`button`,{type:`button`,onClick:T,"aria-label":I.close,className:h(l.modalCloseButton,M?.closeButton),style:N?.closeButton,children:v(g,{icon:_})})]}),v(`div`,{ref:H,className:h(l.modalBody,c.scrollFade,c.scrollFadeY,Y&&c.scrollFadeFadedStart,X&&c.scrollFadeFadedEnd,M?.body),style:N?.body,children:S}),E&&v(`div`,{className:h(l.modalFooter,M?.footer),style:N?.footer,children:E})]})]})})}export{x as default};
2
2
  //# sourceMappingURL=modal.mjs.map