@radix-ng/primitives 0.34.0 → 0.35.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 (48) hide show
  1. package/calendar/src/calendar-root.directive.d.ts +3 -3
  2. package/core/index.d.ts +1 -0
  3. package/core/src/accessor/provide-value-accessor.d.ts +1 -1
  4. package/core/src/date-time/index.d.ts +3 -0
  5. package/core/src/date-time/parser.d.ts +37 -0
  6. package/core/src/date-time/parts.d.ts +12 -0
  7. package/core/src/date-time/segment.d.ts +4 -0
  8. package/core/src/date-time/types.d.ts +18 -1
  9. package/core/src/date-time/useDateField.d.ts +141 -0
  10. package/core/src/date-time/utils.d.ts +3 -0
  11. package/core/src/provide-token.d.ts +22 -0
  12. package/date-field/README.md +1 -0
  13. package/date-field/index.d.ts +2 -0
  14. package/date-field/src/date-field-context.token.d.ts +18 -0
  15. package/date-field/src/date-field-input.directive.d.ts +53 -0
  16. package/date-field/src/date-field-root.directive.d.ts +126 -0
  17. package/dialog/src/dialog-ref.d.ts +3 -0
  18. package/dialog/src/dialog.config.d.ts +1 -0
  19. package/fesm2022/radix-ng-primitives-calendar.mjs +6 -15
  20. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-checkbox.mjs +3 -4
  22. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-core.mjs +1014 -8
  24. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  25. package/fesm2022/radix-ng-primitives-date-field.mjs +320 -0
  26. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -0
  27. package/fesm2022/radix-ng-primitives-dialog.mjs +54 -4
  28. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  29. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +0 -2
  30. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-progress.mjs +3 -3
  32. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  33. package/fesm2022/radix-ng-primitives-radio.mjs +7 -7
  34. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-switch.mjs +7 -15
  36. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  37. package/fesm2022/radix-ng-primitives-tabs.mjs +3 -6
  38. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  39. package/fesm2022/radix-ng-primitives-toggle-group.mjs +8 -10
  40. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  41. package/fesm2022/radix-ng-primitives-toggle.mjs +5 -12
  42. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  43. package/hover-card/src/hover-card-root.directive.d.ts +4 -4
  44. package/package.json +5 -1
  45. package/popover/src/popover-root.directive.d.ts +4 -4
  46. package/switch/src/switch-root.directive.d.ts +0 -1
  47. package/toggle/src/toggle.directive.d.ts +0 -1
  48. package/tooltip/src/tooltip-root.directive.d.ts +4 -4
@@ -1,6 +1,6 @@
1
- import { NG_VALUE_ACCESSOR, NgControl, FormControlDirective, FormControlName, NgModel } from '@angular/forms';
2
1
  import * as i0 from '@angular/core';
3
- import { inject, ElementRef, NgZone, booleanAttribute, Input, Directive, APP_ID, Injectable, InjectionToken, effect, untracked } from '@angular/core';
2
+ import { forwardRef, inject, ElementRef, NgZone, booleanAttribute, Input, Directive, APP_ID, Injectable, InjectionToken, computed, effect, untracked } from '@angular/core';
3
+ import { NG_VALUE_ACCESSOR, NgControl, FormControlDirective, FormControlName, NgModel } from '@angular/forms';
4
4
  import { DOCUMENT } from '@angular/common';
5
5
  import { Platform } from '@angular/cdk/platform';
6
6
  import { getLocalTimeZone, CalendarDateTime, ZonedDateTime, getDayOfWeek, DateFormatter, createCalendar, toCalendar, CalendarDate, startOfMonth, endOfMonth, today } from '@internationalized/date';
@@ -18,7 +18,7 @@ import { getLocalTimeZone, CalendarDateTime, ZonedDateTime, getDayOfWeek, DateFo
18
18
  function provideValueAccessor(type) {
19
19
  return {
20
20
  provide: NG_VALUE_ACCESSOR,
21
- useExisting: type,
21
+ useExisting: forwardRef(() => type),
22
22
  multi: true
23
23
  };
24
24
  }
@@ -239,6 +239,33 @@ const j = 'j';
239
239
  const k = 'k';
240
240
  const SPACE_CODE = 'Space';
241
241
 
242
+ /**
243
+ * Creates an Angular provider that binds the given token to the existing instance
244
+ * of the specified class. This is especially useful when you want multiple
245
+ * tokens (or interfaces) to resolve to the same directive/component instance.
246
+ *
247
+ * @template T - The type associated with the injection token.
248
+ * @param token - The InjectionToken or abstract type you want to provide.
249
+ * @param type - The class type whose existing instance will be used for this token.
250
+ * @returns A Provider configuration object for Angular's DI system.
251
+ *
252
+ * @example
253
+ *
254
+ * @Directive({
255
+ * providers: [
256
+ * provideToken(RdxToggleGroupToken, RdxToggleGroupDirective),
257
+ * provideValueAccessor(RdxToggleGroupDirective)
258
+ * ]
259
+ * })
260
+ * export class RdxToggleGroupDirective {}
261
+ */
262
+ function provideToken(token, type) {
263
+ return {
264
+ provide: token,
265
+ useExisting: forwardRef(() => type)
266
+ };
267
+ }
268
+
242
269
  const WINDOW = new InjectionToken('An abstraction over global window object', {
243
270
  factory: () => {
244
271
  const { defaultView } = injectDocument();
@@ -606,6 +633,32 @@ function createFormatter(initialLocale) {
606
633
  };
607
634
  }
608
635
 
636
+ /*
637
+ * Implementation ported from https://github.com/melt-ui/melt-ui/blob/develop/src/lib/builders/date-field/_internal/helpers.ts
638
+ */
639
+ const DATE_SEGMENT_PARTS = ['day', 'month', 'year'];
640
+ const TIME_SEGMENT_PARTS = ['hour', 'minute', 'second', 'dayPeriod'];
641
+ const NON_EDITABLE_SEGMENT_PARTS = ['literal', 'timeZoneName'];
642
+ const EDITABLE_SEGMENT_PARTS = [...DATE_SEGMENT_PARTS, ...TIME_SEGMENT_PARTS];
643
+ const EDITABLE_TIME_SEGMENT_PARTS = [...TIME_SEGMENT_PARTS];
644
+ const ALL_SEGMENT_PARTS = [
645
+ ...EDITABLE_SEGMENT_PARTS,
646
+ ...NON_EDITABLE_SEGMENT_PARTS
647
+ ];
648
+ const ALL_EXCEPT_LITERAL_PARTS = ALL_SEGMENT_PARTS.filter((part) => part !== 'literal');
649
+ function isDateSegmentPart(part) {
650
+ return DATE_SEGMENT_PARTS.includes(part);
651
+ }
652
+ function isTimeSegmentPart(part) {
653
+ return TIME_SEGMENT_PARTS.includes(part);
654
+ }
655
+ function isSegmentPart(part) {
656
+ return EDITABLE_SEGMENT_PARTS.includes(part);
657
+ }
658
+ function isAnySegmentPart(part) {
659
+ return ALL_SEGMENT_PARTS.includes(part);
660
+ }
661
+
609
662
  /*
610
663
  * Implementation ported from from from https://github.com/melt-ui/melt-ui/blob/develop/src/lib/internal/helpers/date/placeholders.ts
611
664
  */
@@ -739,10 +792,37 @@ function getLocaleLanguage(locale) {
739
792
  return locale.split('-')[0];
740
793
  }
741
794
 
742
- /*
743
- * Implementation ported from https://github.com/melt-ui/melt-ui/blob/develop/src/lib/internal/helpers/date/types.ts
744
- */
745
-
795
+ function getOptsByGranularity(granularity, hourCycle, isTimeValue = false) {
796
+ const opts = {
797
+ year: 'numeric',
798
+ month: '2-digit',
799
+ day: '2-digit',
800
+ hour: '2-digit',
801
+ minute: '2-digit',
802
+ second: '2-digit',
803
+ timeZoneName: 'short',
804
+ hourCycle: hourCycle === 24 ? 'h23' : undefined,
805
+ hour12: hourCycle === 24 ? false : undefined
806
+ };
807
+ if (isTimeValue) {
808
+ delete opts.year;
809
+ delete opts.month;
810
+ delete opts.day;
811
+ }
812
+ if (granularity === 'day') {
813
+ delete opts.second;
814
+ delete opts.hour;
815
+ delete opts.minute;
816
+ delete opts.timeZoneName;
817
+ }
818
+ if (granularity === 'hour') {
819
+ delete opts.minute;
820
+ delete opts.second;
821
+ }
822
+ if (granularity === 'minute')
823
+ delete opts.second;
824
+ return opts;
825
+ }
746
826
  function handleCalendarInitialFocus(calendar) {
747
827
  const selectedDay = calendar.querySelector('[data-selected]');
748
828
  if (selectedDay)
@@ -755,6 +835,932 @@ function handleCalendarInitialFocus(calendar) {
755
835
  return firstDay.focus();
756
836
  }
757
837
 
838
+ const calendarDateTimeGranularities = ['hour', 'minute', 'second'];
839
+ function syncTimeSegmentValues(props) {
840
+ return Object.fromEntries(TIME_SEGMENT_PARTS.map((part) => {
841
+ if (part === 'dayPeriod')
842
+ return [part, props.formatter.dayPeriod(toDate(props.value))];
843
+ return [part, props.value[part]];
844
+ }));
845
+ }
846
+ function initializeSegmentValues(granularity) {
847
+ const initialParts = EDITABLE_SEGMENT_PARTS.map((part) => {
848
+ if (part === 'dayPeriod')
849
+ return [part, 'AM'];
850
+ return [part, null];
851
+ }).filter(([key]) => {
852
+ if (key === 'literal' || key === null)
853
+ return false;
854
+ if (granularity === 'minute' && key === 'second')
855
+ return false;
856
+ if (granularity === 'hour' && (key === 'second' || key === 'minute'))
857
+ return false;
858
+ if (granularity === 'day')
859
+ return !calendarDateTimeGranularities.includes(key) && key !== 'dayPeriod';
860
+ else
861
+ return true;
862
+ });
863
+ return Object.fromEntries(initialParts);
864
+ }
865
+ function syncSegmentValues(props) {
866
+ const { formatter } = props;
867
+ const dateValues = DATE_SEGMENT_PARTS.map((part) => {
868
+ return [part, props.value[part]];
869
+ });
870
+ if ('hour' in props.value) {
871
+ const timeValues = syncTimeSegmentValues({ value: props.value, formatter });
872
+ return { ...Object.fromEntries(dateValues), ...timeValues };
873
+ }
874
+ return Object.fromEntries(dateValues);
875
+ }
876
+ function createContentObj(props) {
877
+ const { segmentValues, formatter, locale } = props;
878
+ function getPartContent(part) {
879
+ if ('hour' in segmentValues) {
880
+ const value = segmentValues[part];
881
+ if (value !== null) {
882
+ /**
883
+ * Edge case for when the month field is filled and the day field snaps to the maximum value of the value of the placeholder month
884
+ */
885
+ if (part === 'day' && segmentValues.month !== null) {
886
+ return formatter.part(props.dateRef.set({ [part]: value, month: segmentValues.month }), part, {
887
+ hourCycle: props.hourCycle === 24 ? 'h23' : undefined
888
+ });
889
+ }
890
+ return formatter.part(props.dateRef.set({ [part]: value }), part, {
891
+ hourCycle: props.hourCycle === 24 ? 'h23' : undefined
892
+ });
893
+ }
894
+ else {
895
+ return getPlaceholder(part, '', locale());
896
+ }
897
+ }
898
+ else {
899
+ if (isDateSegmentPart(part)) {
900
+ const value = segmentValues[part];
901
+ if (value !== null) {
902
+ if (part === 'day' && segmentValues.month !== null)
903
+ /**
904
+ * As described above, same function
905
+ */
906
+ return formatter.part(props.dateRef.set({ [part]: value, month: segmentValues.month }), part);
907
+ return formatter.part(props.dateRef.set({ [part]: value }), part);
908
+ }
909
+ else {
910
+ return getPlaceholder(part, '', locale());
911
+ }
912
+ }
913
+ return '';
914
+ }
915
+ }
916
+ const content = Object.keys(segmentValues).reduce((obj, part) => {
917
+ if (!isSegmentPart(part))
918
+ return obj;
919
+ if ('hour' in segmentValues && part === 'dayPeriod') {
920
+ const value = segmentValues[part];
921
+ if (value !== null)
922
+ obj[part] = value;
923
+ else
924
+ obj[part] = getPlaceholder(part, 'AM', locale());
925
+ }
926
+ else {
927
+ obj[part] = getPartContent(part);
928
+ }
929
+ return obj;
930
+ }, {});
931
+ return content;
932
+ }
933
+ function createContentArr(props) {
934
+ const { granularity, formatter, contentObj, hideTimeZone, hourCycle, isTimeValue } = props;
935
+ const parts = formatter.toParts(props.dateRef, getOptsByGranularity(granularity, hourCycle, isTimeValue));
936
+ const segmentContentArr = parts
937
+ .map((part) => {
938
+ const defaultParts = ['literal', 'timeZoneName', null];
939
+ if (defaultParts.includes(part.type) || !isSegmentPart(part.type)) {
940
+ return {
941
+ part: part.type,
942
+ value: part.value
943
+ };
944
+ }
945
+ return {
946
+ part: part.type,
947
+ value: contentObj[part.type]
948
+ };
949
+ })
950
+ .filter((segment) => {
951
+ if (segment.part === null || segment.value === null)
952
+ return false;
953
+ if (segment.part === 'timeZoneName' && (!isZonedDateTime(props.dateRef) || hideTimeZone))
954
+ return false;
955
+ return true;
956
+ });
957
+ return segmentContentArr;
958
+ }
959
+ function createContent(props) {
960
+ const contentObj = createContentObj(props);
961
+ const contentArr = createContentArr({
962
+ contentObj,
963
+ ...props
964
+ });
965
+ return {
966
+ obj: contentObj,
967
+ arr: contentArr
968
+ };
969
+ }
970
+
971
+ function isSegmentNavigationKey(key) {
972
+ if (key === ARROW_RIGHT || key === ARROW_LEFT)
973
+ return true;
974
+ return false;
975
+ }
976
+ function isNumberString(value) {
977
+ if (Number.isNaN(Number.parseInt(value)))
978
+ return false;
979
+ return true;
980
+ }
981
+ function isAcceptableSegmentKey(key) {
982
+ const acceptableSegmentKeys = [
983
+ ENTER,
984
+ ARROW_UP,
985
+ ARROW_DOWN,
986
+ ARROW_LEFT,
987
+ ARROW_RIGHT,
988
+ BACKSPACE,
989
+ SPACE,
990
+ 'a',
991
+ 'A',
992
+ 'p',
993
+ 'P'
994
+ ];
995
+ if (acceptableSegmentKeys.includes(key))
996
+ return true;
997
+ if (isNumberString(key))
998
+ return true;
999
+ return false;
1000
+ }
1001
+ function getSegmentElements(parentElement) {
1002
+ return Array.from(parentElement.querySelectorAll('[data-rdx-date-field-segment]')).filter((item) => item.getAttribute('data-rdx-date-field-segment') !== 'literal');
1003
+ }
1004
+
1005
+ /*
1006
+ * Implementation ported from https://github.com/melt-ui/melt-ui/blob/develop/src/lib/internal/helpers/date/types.ts
1007
+ */
1008
+
1009
+ // https://github.com/unovue/reka-ui/blob/v2/packages/core/src/shared/date/useDateField.ts
1010
+ function commonSegmentAttrs(props) {
1011
+ return {
1012
+ role: 'spinbutton',
1013
+ contenteditable: true,
1014
+ tabindex: props.disabled ? undefined : 0,
1015
+ spellcheck: false,
1016
+ inputmode: 'numeric',
1017
+ autocorrect: 'off',
1018
+ enterkeyhint: 'next',
1019
+ style: 'caret-color: transparent;'
1020
+ };
1021
+ }
1022
+ function daySegmentAttrs(props) {
1023
+ const { segmentValues, placeholder } = props;
1024
+ const isEmpty = segmentValues.day === null;
1025
+ const date = segmentValues.day ? placeholder.set({ day: segmentValues.day }) : placeholder;
1026
+ const valueNow = date.day;
1027
+ const valueMin = 1;
1028
+ const valueMax = getDaysInMonth(date);
1029
+ const valueText = isEmpty ? 'Empty' : `${valueNow}`;
1030
+ return {
1031
+ ...commonSegmentAttrs(props),
1032
+ 'aria-label': 'day,',
1033
+ 'aria-valuemin': valueMin,
1034
+ 'aria-valuemax': valueMax,
1035
+ 'aria-valuenow': valueNow,
1036
+ 'aria-valuetext': valueText,
1037
+ 'data-placeholder': isEmpty ? '' : undefined
1038
+ };
1039
+ }
1040
+ function monthSegmentAttrs(props) {
1041
+ const { segmentValues, placeholder, formatter } = props;
1042
+ const isEmpty = segmentValues.month === null;
1043
+ const date = segmentValues.month ? placeholder.set({ month: segmentValues.month }) : placeholder;
1044
+ const valueNow = date.month;
1045
+ const valueMin = 1;
1046
+ const valueMax = 12;
1047
+ const valueText = isEmpty ? 'Empty' : `${valueNow} - ${formatter.fullMonth(toDate(date))}`;
1048
+ return {
1049
+ ...commonSegmentAttrs(props),
1050
+ 'aria-label': 'month, ',
1051
+ contenteditable: true,
1052
+ 'aria-valuemin': valueMin,
1053
+ 'aria-valuemax': valueMax,
1054
+ 'aria-valuenow': valueNow,
1055
+ 'aria-valuetext': valueText,
1056
+ 'data-placeholder': isEmpty ? '' : undefined
1057
+ };
1058
+ }
1059
+ function yearSegmentAttrs(props) {
1060
+ const { segmentValues, placeholder } = props;
1061
+ const isEmpty = segmentValues.year === null;
1062
+ const date = segmentValues.year ? placeholder.set({ year: segmentValues.year }) : placeholder;
1063
+ const valueMin = 1;
1064
+ const valueMax = 9999;
1065
+ const valueNow = date.year;
1066
+ const valueText = isEmpty ? 'Empty' : `${valueNow}`;
1067
+ return {
1068
+ ...commonSegmentAttrs(props),
1069
+ 'aria-label': 'year, ',
1070
+ 'aria-valuemin': valueMin,
1071
+ 'aria-valuemax': valueMax,
1072
+ 'aria-valuenow': valueNow,
1073
+ 'aria-valuetext': valueText,
1074
+ 'data-placeholder': isEmpty ? '' : undefined
1075
+ };
1076
+ }
1077
+ function hourSegmentAttrs(props) {
1078
+ const { segmentValues, hourCycle, placeholder } = props;
1079
+ if (!('hour' in segmentValues) || !('hour' in placeholder))
1080
+ return {};
1081
+ const isEmpty = segmentValues.hour === null;
1082
+ const date = segmentValues.hour ? placeholder.set({ hour: segmentValues.hour }) : placeholder;
1083
+ const valueMin = hourCycle === 12 ? 1 : 0;
1084
+ const valueMax = hourCycle === 12 ? 12 : 23;
1085
+ const valueNow = date.hour;
1086
+ const valueText = isEmpty ? 'Empty' : `${valueNow} ${segmentValues.dayPeriod ?? ''}`;
1087
+ return {
1088
+ ...commonSegmentAttrs(props),
1089
+ 'aria-label': 'hour, ',
1090
+ 'aria-valuemin': valueMin,
1091
+ 'aria-valuemax': valueMax,
1092
+ 'aria-valuenow': valueNow,
1093
+ 'aria-valuetext': valueText,
1094
+ 'data-placeholder': isEmpty ? '' : undefined
1095
+ };
1096
+ }
1097
+ function minuteSegmentAttrs(props) {
1098
+ const { segmentValues, placeholder } = props;
1099
+ if (!('minute' in segmentValues) || !('minute' in placeholder))
1100
+ return {};
1101
+ const isEmpty = segmentValues.minute === null;
1102
+ const date = segmentValues.minute ? placeholder.set({ minute: segmentValues.minute }) : placeholder;
1103
+ const valueNow = date.minute;
1104
+ const valueMin = 0;
1105
+ const valueMax = 59;
1106
+ const valueText = isEmpty ? 'Empty' : `${valueNow}`;
1107
+ return {
1108
+ ...commonSegmentAttrs(props),
1109
+ 'aria-label': 'minute, ',
1110
+ 'aria-valuemin': valueMin,
1111
+ 'aria-valuemax': valueMax,
1112
+ 'aria-valuenow': valueNow,
1113
+ 'aria-valuetext': valueText,
1114
+ 'data-placeholder': isEmpty ? '' : undefined
1115
+ };
1116
+ }
1117
+ function secondSegmentAttrs(props) {
1118
+ const { segmentValues, placeholder } = props;
1119
+ if (!('second' in segmentValues) || !('second' in placeholder))
1120
+ return {};
1121
+ const isEmpty = segmentValues.second === null;
1122
+ const date = segmentValues.second ? placeholder.set({ second: segmentValues.second }) : placeholder;
1123
+ const valueNow = date.second;
1124
+ const valueMin = 0;
1125
+ const valueMax = 59;
1126
+ const valueText = isEmpty ? 'Empty' : `${valueNow}`;
1127
+ return {
1128
+ ...commonSegmentAttrs(props),
1129
+ 'aria-label': 'second, ',
1130
+ 'aria-valuemin': valueMin,
1131
+ 'aria-valuemax': valueMax,
1132
+ 'aria-valuenow': valueNow,
1133
+ 'aria-valuetext': valueText,
1134
+ 'data-placeholder': isEmpty ? '' : undefined
1135
+ };
1136
+ }
1137
+ function dayPeriodSegmentAttrs(props) {
1138
+ const { segmentValues } = props;
1139
+ if (!('dayPeriod' in segmentValues))
1140
+ return {};
1141
+ const valueMin = 0;
1142
+ const valueMax = 12;
1143
+ const valueNow = segmentValues.hour ? (segmentValues.hour > 12 ? segmentValues.hour - 12 : segmentValues.hour) : 0;
1144
+ const valueText = segmentValues.dayPeriod ?? 'AM';
1145
+ return {
1146
+ ...commonSegmentAttrs(props),
1147
+ inputmode: 'text',
1148
+ 'aria-label': 'AM/PM',
1149
+ 'aria-valuemin': valueMin,
1150
+ 'aria-valuemax': valueMax,
1151
+ 'aria-valuenow': valueNow,
1152
+ 'aria-valuetext': valueText
1153
+ };
1154
+ }
1155
+ function literalSegmentAttrs(_props) {
1156
+ return {
1157
+ 'aria-hidden': true,
1158
+ 'data-segment': 'literal'
1159
+ };
1160
+ }
1161
+ function timeZoneSegmentAttrs(props) {
1162
+ return {
1163
+ role: 'textbox',
1164
+ 'aria-label': 'timezone, ',
1165
+ 'data-readonly': true,
1166
+ 'data-segment': 'timeZoneName',
1167
+ tabindex: props.disabled ? undefined : 0,
1168
+ style: 'caret-color: transparent;'
1169
+ };
1170
+ }
1171
+ function eraSegmentAttrs(props) {
1172
+ const { segmentValues, placeholder } = props;
1173
+ const valueMin = 0;
1174
+ const valueMax = 0;
1175
+ const valueNow = 0;
1176
+ const valueText = 'era' in segmentValues ? segmentValues.era : placeholder.era;
1177
+ return {
1178
+ ...commonSegmentAttrs(props),
1179
+ 'aria-label': 'era',
1180
+ 'aria-valuemin': valueMin,
1181
+ 'aria-valuemax': valueMax,
1182
+ 'aria-valuenow': valueNow,
1183
+ 'aria-valuetext': valueText
1184
+ };
1185
+ }
1186
+ const segmentBuilders = {
1187
+ day: {
1188
+ attrs: daySegmentAttrs
1189
+ },
1190
+ month: {
1191
+ attrs: monthSegmentAttrs
1192
+ },
1193
+ year: {
1194
+ attrs: yearSegmentAttrs
1195
+ },
1196
+ hour: {
1197
+ attrs: hourSegmentAttrs
1198
+ },
1199
+ minute: {
1200
+ attrs: minuteSegmentAttrs
1201
+ },
1202
+ second: {
1203
+ attrs: secondSegmentAttrs
1204
+ },
1205
+ dayPeriod: {
1206
+ attrs: dayPeriodSegmentAttrs
1207
+ },
1208
+ literal: {
1209
+ attrs: literalSegmentAttrs
1210
+ },
1211
+ timeZoneName: {
1212
+ attrs: timeZoneSegmentAttrs
1213
+ },
1214
+ era: {
1215
+ attrs: eraSegmentAttrs
1216
+ }
1217
+ };
1218
+ function useDateField(props) {
1219
+ function handleSegmentClick(e) {
1220
+ const disabled = props.disabled();
1221
+ if (disabled)
1222
+ e.preventDefault();
1223
+ }
1224
+ function deleteValue(prevValue) {
1225
+ props.hasLeftFocus.set(false);
1226
+ if (prevValue === null)
1227
+ return prevValue;
1228
+ const str = prevValue.toString();
1229
+ if (str.length === 1) {
1230
+ props.modelValue.set(undefined);
1231
+ return null;
1232
+ }
1233
+ return Number.parseInt(str.slice(0, -1));
1234
+ }
1235
+ function dateTimeValueIncrementation({ e, part, dateRef, prevValue, hourCycle }) {
1236
+ const sign = e.key === ARROW_UP ? 1 : -1;
1237
+ if (prevValue === null)
1238
+ return dateRef[part];
1239
+ if (part === 'hour' && 'hour' in dateRef) {
1240
+ const cycleArgs = [
1241
+ part,
1242
+ sign,
1243
+ { hourCycle }
1244
+ ];
1245
+ return dateRef.set({ [part]: prevValue }).cycle(...cycleArgs)[part];
1246
+ }
1247
+ const cycleArgs = [part, sign];
1248
+ if (part === 'day' && props.segmentValues().month !== null)
1249
+ return dateRef
1250
+ .set({ [part]: prevValue, month: props.segmentValues().month })
1251
+ .cycle(...cycleArgs)[part];
1252
+ return dateRef.set({ [part]: prevValue }).cycle(...cycleArgs)[part];
1253
+ }
1254
+ function updateDayOrMonth(max, num, prev) {
1255
+ let moveToNext = false;
1256
+ const maxStart = Math.floor(max / 10);
1257
+ /**
1258
+ * If the user has left the segment, we want to reset the
1259
+ * `prev` value so that we can start the segment over again
1260
+ * when the user types a number.
1261
+ */
1262
+ if (props.hasLeftFocus()) {
1263
+ props.hasLeftFocus.set(false);
1264
+ prev = null;
1265
+ }
1266
+ if (prev === null) {
1267
+ /**
1268
+ * If the user types a 0 as the first number, we want
1269
+ * to keep track of that so that when they type the next
1270
+ * number, we can move to the next segment.
1271
+ */
1272
+ if (num === 0) {
1273
+ props.lastKeyZero.set(true);
1274
+ return { value: null, moveToNext };
1275
+ }
1276
+ /**
1277
+ * If the last key was a 0, or if the first number is
1278
+ * greater than the max start digit (0-3 in most cases), then
1279
+ * we want to move to the next segment, since it's not possible
1280
+ * to continue typing a valid number in this segment.
1281
+ */
1282
+ if (props.lastKeyZero() || num > maxStart) {
1283
+ // move to next
1284
+ moveToNext = true;
1285
+ }
1286
+ props.lastKeyZero.set(false);
1287
+ /**
1288
+ * If none of the above conditions are met, then we can just
1289
+ * return the number as the segment value and continue typing
1290
+ * in this segment.
1291
+ */
1292
+ return { value: num, moveToNext };
1293
+ }
1294
+ /**
1295
+ * If the number of digits is 2, or if the total with the existing digit
1296
+ * and the pressed digit is greater than the maximum value for this
1297
+ * month, then we will reset the segment as if the user had pressed the
1298
+ * backspace key and then typed the number.
1299
+ */
1300
+ const digits = prev.toString().length;
1301
+ const total = Number.parseInt(prev.toString() + num.toString());
1302
+ /**
1303
+ * If the number of digits is 2, or if the total with the existing digit
1304
+ * and the pressed digit is greater than the maximum value for this
1305
+ * month, then we will reset the segment as if the user had pressed the
1306
+ * backspace key and then typed the number.
1307
+ */
1308
+ if (digits === 2 || total > max) {
1309
+ /**
1310
+ * As we're doing elsewhere, we're checking if the number is greater
1311
+ * than the max start digit (0-3 in most months), and if so, we're
1312
+ * going to move to the next segment.
1313
+ */
1314
+ if (num > maxStart || total > max) {
1315
+ // move to next
1316
+ moveToNext = true;
1317
+ }
1318
+ return { value: num, moveToNext };
1319
+ }
1320
+ // move to next
1321
+ moveToNext = true;
1322
+ return { value: total, moveToNext };
1323
+ }
1324
+ function updateYear(num, prev) {
1325
+ let moveToNext = false;
1326
+ /**
1327
+ * If the user has left the segment, we want to reset the
1328
+ * `prev` value so that we can start the segment over again
1329
+ * when the user types a number.
1330
+ */
1331
+ // probably not implement, kind of weird
1332
+ if (props.hasLeftFocus()) {
1333
+ props.hasLeftFocus.set(false);
1334
+ prev = null;
1335
+ }
1336
+ if (prev === null)
1337
+ return { value: num === 0 ? 1 : num, moveToNext };
1338
+ const str = prev.toString() + num.toString();
1339
+ if (str.length > 4)
1340
+ return { value: num === 0 ? 1 : num, moveToNext };
1341
+ if (str.length === 4)
1342
+ moveToNext = true;
1343
+ const int = Number.parseInt(str);
1344
+ return { value: int, moveToNext };
1345
+ }
1346
+ function updateHour(num, prev) {
1347
+ const max = 24;
1348
+ let moveToNext = false;
1349
+ const maxStart = Math.floor(max / 10);
1350
+ /**
1351
+ * If the user has left the segment, we want to reset the
1352
+ * `prev` value so that we can start the segment over again
1353
+ * when the user types a number.
1354
+ */
1355
+ // probably not implement, kind of weird
1356
+ if (props.hasLeftFocus()) {
1357
+ props.hasLeftFocus.set(false);
1358
+ prev = null;
1359
+ }
1360
+ if (prev === null) {
1361
+ /**
1362
+ * If the user types a 0 as the first number, we want
1363
+ * to keep track of that so that when they type the next
1364
+ * number, we can move to the next segment.
1365
+ */
1366
+ if (num === 0) {
1367
+ props.lastKeyZero.set(true);
1368
+ return { value: 0, moveToNext };
1369
+ }
1370
+ /**
1371
+ * If the last key was a 0, or if the first number is
1372
+ * greater than the max start digit (0-3 in most cases), then
1373
+ * we want to move to the next segment, since it's not possible
1374
+ * to continue typing a valid number in this segment.
1375
+ */
1376
+ if (props.lastKeyZero() || num > maxStart) {
1377
+ // move to next
1378
+ moveToNext = true;
1379
+ }
1380
+ props.lastKeyZero.set(false);
1381
+ /**
1382
+ * If none of the above conditions are met, then we can just
1383
+ * return the number as the segment value and continue typing
1384
+ * in this segment.
1385
+ */
1386
+ return { value: num, moveToNext };
1387
+ }
1388
+ /**
1389
+ * If the number of digits is 2, or if the total with the existing digit
1390
+ * and the pressed digit is greater than the maximum value for this
1391
+ * month, then we will reset the segment as if the user had pressed the
1392
+ * backspace key and then typed the number.
1393
+ */
1394
+ const digits = prev.toString().length;
1395
+ const total = Number.parseInt(prev.toString() + num.toString());
1396
+ /**
1397
+ * If the number of digits is 2, or if the total with the existing digit
1398
+ * and the pressed digit is greater than the maximum value for this
1399
+ * month, then we will reset the segment as if the user had pressed the
1400
+ * backspace key and then typed the number.
1401
+ */
1402
+ if (digits === 2 || total > max) {
1403
+ /**
1404
+ * As we're doing elsewhere, we're checking if the number is greater
1405
+ * than the max start digit (0-3 in most months), and if so, we're
1406
+ * going to move to the next segment.
1407
+ */
1408
+ if (num > maxStart) {
1409
+ // move to next
1410
+ moveToNext = true;
1411
+ }
1412
+ return { value: num, moveToNext };
1413
+ }
1414
+ // move to next
1415
+ moveToNext = true;
1416
+ return { value: total, moveToNext };
1417
+ }
1418
+ function updateMinuteOrSecond(num, prev) {
1419
+ const max = 59;
1420
+ let moveToNext = false;
1421
+ const maxStart = Math.floor(max / 10);
1422
+ /**
1423
+ * If the user has left the segment, we want to reset the
1424
+ * `prev` value so that we can start the segment over again
1425
+ * when the user types a number.
1426
+ */
1427
+ if (props.hasLeftFocus()) {
1428
+ props.hasLeftFocus.set(false);
1429
+ prev = null;
1430
+ }
1431
+ if (prev === null) {
1432
+ /**
1433
+ * If the user types a 0 as the first number, we want
1434
+ * to keep track of that so that when they type the next
1435
+ * number, we can move to the next segment.
1436
+ */
1437
+ if (num === 0) {
1438
+ props.lastKeyZero.set(true);
1439
+ return { value: 0, moveToNext };
1440
+ }
1441
+ /**
1442
+ * If the last key was a 0, or if the first number is
1443
+ * greater than the max start digit (0-3 in most cases), then
1444
+ * we want to move to the next segment, since it's not possible
1445
+ * to continue typing a valid number in this segment.
1446
+ */
1447
+ if (props.lastKeyZero() || num > maxStart) {
1448
+ // move to next
1449
+ moveToNext = true;
1450
+ }
1451
+ props.lastKeyZero.set(false);
1452
+ /**
1453
+ * If none of the above conditions are met, then we can just
1454
+ * return the number as the segment value and continue typing
1455
+ * in this segment.
1456
+ */
1457
+ return { value: num, moveToNext };
1458
+ }
1459
+ /**
1460
+ * If the number of digits is 2, or if the total with the existing digit
1461
+ * and the pressed digit is greater than the maximum value for this
1462
+ * month, then we will reset the segment as if the user had pressed the
1463
+ * backspace key and then typed the number.
1464
+ */
1465
+ const digits = prev.toString().length;
1466
+ const total = Number.parseInt(prev.toString() + num.toString());
1467
+ /**
1468
+ * If the number of digits is 2, or if the total with the existing digit
1469
+ * and the pressed digit is greater than the maximum value for this
1470
+ * month, then we will reset the segment as if the user had pressed the
1471
+ * backspace key and then typed the number.
1472
+ */
1473
+ if (digits === 2 || total > max) {
1474
+ /**
1475
+ * As we're doing elsewhere, we're checking if the number is greater
1476
+ * than the max start digit (0-3 in most months), and if so, we're
1477
+ * going to move to the next segment.
1478
+ */
1479
+ if (num > maxStart) {
1480
+ // move to next
1481
+ moveToNext = true;
1482
+ }
1483
+ return { value: num, moveToNext };
1484
+ }
1485
+ // move to next
1486
+ moveToNext = true;
1487
+ return { value: total, moveToNext };
1488
+ }
1489
+ function minuteSecondIncrementation({ e, part, dateRef, prevValue }) {
1490
+ const sign = e.key === ARROW_UP ? 1 : -1;
1491
+ const min = 0;
1492
+ const max = 59;
1493
+ if (prevValue === null)
1494
+ return sign > 0 ? min : max;
1495
+ const cycleArgs = [part, sign];
1496
+ return dateRef.set({ [part]: prevValue }).cycle(...cycleArgs)[part];
1497
+ }
1498
+ const attributes = computed(() => segmentBuilders[props.part]?.attrs({
1499
+ disabled: props.disabled(),
1500
+ placeholder: props.placeholder(),
1501
+ hourCycle: props.hourCycle,
1502
+ segmentValues: props.segmentValues(),
1503
+ formatter: props.formatter
1504
+ }) ?? {});
1505
+ function handleMonthSegmentKeydown(e) {
1506
+ if (!isAcceptableSegmentKey(e.key) || isSegmentNavigationKey(e.key))
1507
+ return;
1508
+ const prevValue = props.segmentValues().month;
1509
+ if (e.key === ARROW_DOWN || e.key === ARROW_UP) {
1510
+ props.segmentValues.update((prev) => ({
1511
+ ...prev,
1512
+ month: dateTimeValueIncrementation({
1513
+ e,
1514
+ part: 'month',
1515
+ dateRef: props.placeholder(),
1516
+ prevValue
1517
+ })
1518
+ }));
1519
+ return;
1520
+ }
1521
+ if (isNumberString(e.key)) {
1522
+ const num = Number.parseInt(e.key);
1523
+ const { value, moveToNext } = updateDayOrMonth(12, num, prevValue);
1524
+ props.segmentValues.update((prev) => ({ ...prev, month: value }));
1525
+ if (moveToNext)
1526
+ props.focusNext();
1527
+ }
1528
+ if (e.key === BACKSPACE) {
1529
+ props.hasLeftFocus.set(false);
1530
+ props.segmentValues.update((prev) => ({ ...prev, month: deleteValue(prevValue) }));
1531
+ }
1532
+ }
1533
+ function handleDaySegmentKeydown(e) {
1534
+ if (!isAcceptableSegmentKey(e.key) || isSegmentNavigationKey(e.key))
1535
+ return;
1536
+ const prevValue = props.segmentValues().day;
1537
+ if (e.key === ARROW_DOWN || e.key === ARROW_UP) {
1538
+ props.segmentValues.update((prev) => ({
1539
+ ...prev,
1540
+ day: dateTimeValueIncrementation({
1541
+ e,
1542
+ part: 'day',
1543
+ dateRef: props.placeholder(),
1544
+ prevValue
1545
+ })
1546
+ }));
1547
+ return;
1548
+ }
1549
+ if (isNumberString(e.key)) {
1550
+ const num = Number.parseInt(e.key);
1551
+ const segmentMonthValue = props.segmentValues().month;
1552
+ const daysInMonth = segmentMonthValue
1553
+ ? getDaysInMonth(props.placeholder().set({ month: segmentMonthValue }))
1554
+ : getDaysInMonth(props.placeholder());
1555
+ const { value, moveToNext } = updateDayOrMonth(daysInMonth, num, prevValue);
1556
+ props.segmentValues.update((prev) => ({ ...prev, day: value }));
1557
+ if (moveToNext)
1558
+ props.focusNext();
1559
+ }
1560
+ if (e.key === BACKSPACE) {
1561
+ props.hasLeftFocus.set(false);
1562
+ props.segmentValues.update((prev) => ({ ...prev, day: deleteValue(prevValue) }));
1563
+ }
1564
+ }
1565
+ function handleYearSegmentKeydown(e) {
1566
+ if (!isAcceptableSegmentKey(e.key) || isSegmentNavigationKey(e.key))
1567
+ return;
1568
+ const prevValue = props.segmentValues().year;
1569
+ if (e.key === ARROW_DOWN || e.key === ARROW_UP) {
1570
+ props.segmentValues.update((prev) => ({
1571
+ ...prev,
1572
+ year: dateTimeValueIncrementation({
1573
+ e,
1574
+ part: 'year',
1575
+ dateRef: props.placeholder(),
1576
+ prevValue
1577
+ })
1578
+ }));
1579
+ return;
1580
+ }
1581
+ if (isNumberString(e.key)) {
1582
+ const num = Number.parseInt(e.key);
1583
+ const { value, moveToNext } = updateYear(num, prevValue);
1584
+ props.segmentValues.update((prev) => ({ ...prev, year: value }));
1585
+ if (moveToNext)
1586
+ props.focusNext();
1587
+ }
1588
+ if (e.key === BACKSPACE) {
1589
+ props.hasLeftFocus.set(false);
1590
+ props.segmentValues.update((prev) => ({ ...prev, year: deleteValue(prevValue) }));
1591
+ }
1592
+ }
1593
+ function handleHourSegmentKeydown(e) {
1594
+ const dateRef = props.placeholder();
1595
+ const values = props.segmentValues();
1596
+ if (!isAcceptableSegmentKey(e.key) ||
1597
+ isSegmentNavigationKey(e.key) ||
1598
+ !('hour' in dateRef) ||
1599
+ !('hour' in values))
1600
+ return;
1601
+ const prevValue = values.hour;
1602
+ const hourCycle = props.hourCycle;
1603
+ if (e.key === ARROW_UP || e.key === ARROW_DOWN) {
1604
+ props.segmentValues.update((prev) => ({
1605
+ ...prev,
1606
+ hour: dateTimeValueIncrementation({
1607
+ e,
1608
+ part: 'hour',
1609
+ dateRef: props.placeholder(),
1610
+ prevValue,
1611
+ hourCycle
1612
+ })
1613
+ }));
1614
+ if ('dayPeriod' in props.segmentValues() && values.hour != null) {
1615
+ if (values.hour < 12)
1616
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'AM' }));
1617
+ else if (values.hour)
1618
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'PM' }));
1619
+ }
1620
+ return;
1621
+ }
1622
+ if (isNumberString(e.key)) {
1623
+ const num = Number.parseInt(e.key);
1624
+ const { value, moveToNext } = updateHour(num, prevValue);
1625
+ if ('dayPeriod' in props.segmentValues() && value && value > 12)
1626
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'AM' }));
1627
+ else if ('dayPeriod' in props.segmentValues() && value)
1628
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'PM' }));
1629
+ props.segmentValues.update((prev) => ({ ...prev, hour: value }));
1630
+ if (moveToNext)
1631
+ props.focusNext();
1632
+ }
1633
+ if (e.key === BACKSPACE) {
1634
+ props.hasLeftFocus.set(false);
1635
+ props.segmentValues.update((prev) => ({ ...prev, hour: deleteValue(prevValue) }));
1636
+ }
1637
+ }
1638
+ function handleMinuteSegmentKeydown(e) {
1639
+ const dateRef = props.placeholder();
1640
+ const values = props.segmentValues();
1641
+ if (!isAcceptableSegmentKey(e.key) ||
1642
+ isSegmentNavigationKey(e.key) ||
1643
+ !('minute' in dateRef) ||
1644
+ !('minute' in values))
1645
+ return;
1646
+ const prevValue = values.minute;
1647
+ props.segmentValues.update((prev) => ({
1648
+ ...prev,
1649
+ minute: minuteSecondIncrementation({
1650
+ e,
1651
+ part: 'minute',
1652
+ dateRef: props.placeholder(),
1653
+ prevValue
1654
+ })
1655
+ }));
1656
+ if (isNumberString(e.key)) {
1657
+ const num = Number.parseInt(e.key);
1658
+ const { value, moveToNext } = updateMinuteOrSecond(num, prevValue);
1659
+ props.segmentValues.update((prev) => ({ ...prev, minute: value }));
1660
+ if (moveToNext)
1661
+ props.focusNext();
1662
+ }
1663
+ if (e.key === BACKSPACE) {
1664
+ props.hasLeftFocus.set(false);
1665
+ props.segmentValues.update((prev) => ({ ...prev, minute: deleteValue(prevValue) }));
1666
+ }
1667
+ }
1668
+ function handleSecondSegmentKeydown(e) {
1669
+ const dateRef = props.placeholder();
1670
+ const values = props.segmentValues();
1671
+ if (!isAcceptableSegmentKey(e.key) ||
1672
+ isSegmentNavigationKey(e.key) ||
1673
+ !('second' in dateRef) ||
1674
+ !('second' in values))
1675
+ return;
1676
+ const prevValue = values.second;
1677
+ props.segmentValues.update((prev) => ({
1678
+ ...prev,
1679
+ second: minuteSecondIncrementation({
1680
+ e,
1681
+ part: 'second',
1682
+ dateRef: props.placeholder(),
1683
+ prevValue
1684
+ })
1685
+ }));
1686
+ if (isNumberString(e.key)) {
1687
+ const num = Number.parseInt(e.key);
1688
+ const { value, moveToNext } = updateMinuteOrSecond(num, prevValue);
1689
+ props.segmentValues.update((prev) => ({ ...prev, second: value }));
1690
+ if (moveToNext)
1691
+ props.focusNext();
1692
+ }
1693
+ if (e.key === BACKSPACE) {
1694
+ props.hasLeftFocus.set(false);
1695
+ props.segmentValues.update((prev) => ({ ...prev, second: deleteValue(prevValue) }));
1696
+ }
1697
+ }
1698
+ function handleDayPeriodSegmentKeydown(e) {
1699
+ if (((!isAcceptableSegmentKey(e.key) || isSegmentNavigationKey(e.key)) && e.key !== 'a' && e.key !== 'p') ||
1700
+ !('hour' in props.placeholder()) ||
1701
+ !('dayPeriod' in props.segmentValues()))
1702
+ return;
1703
+ const values = props.segmentValues();
1704
+ if (e.key === ARROW_UP || e.key === ARROW_DOWN) {
1705
+ if (values.dayPeriod === 'AM') {
1706
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'PM' }));
1707
+ props.segmentValues.update((prev) => ({ ...prev, hour: values.hour + 12 }));
1708
+ return;
1709
+ }
1710
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'AM' }));
1711
+ props.segmentValues.update((prev) => ({ ...prev, hour: values.hour - 12 }));
1712
+ return;
1713
+ }
1714
+ if (['a', 'A'].includes(e.key) && values.dayPeriod !== 'AM') {
1715
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'AM' }));
1716
+ props.segmentValues.update((prev) => ({ ...prev, hour: values.hour - 12 }));
1717
+ return;
1718
+ }
1719
+ if (['p', 'P'].includes(e.key) && values.dayPeriod !== 'PM') {
1720
+ props.segmentValues.update((prev) => ({ ...prev, dayPeriod: 'PM' }));
1721
+ props.segmentValues.update((prev) => ({ ...prev, hour: values.hour + 12 }));
1722
+ }
1723
+ }
1724
+ function handleSegmentKeydown(e) {
1725
+ const disabled = props.disabled();
1726
+ const readonly = props.readonly();
1727
+ if (e.key !== TAB)
1728
+ e.preventDefault();
1729
+ if (disabled || readonly)
1730
+ return;
1731
+ const segmentKeydownHandlers = {
1732
+ month: handleMonthSegmentKeydown,
1733
+ day: handleDaySegmentKeydown,
1734
+ year: handleYearSegmentKeydown,
1735
+ hour: handleHourSegmentKeydown,
1736
+ minute: handleMinuteSegmentKeydown,
1737
+ second: handleSecondSegmentKeydown,
1738
+ dayPeriod: handleDayPeriodSegmentKeydown,
1739
+ timeZoneName: () => { }
1740
+ };
1741
+ segmentKeydownHandlers[props.part](e);
1742
+ if (![ARROW_LEFT, ARROW_RIGHT].includes(e.key) &&
1743
+ e.key !== TAB &&
1744
+ e.key !== SHIFT &&
1745
+ isAcceptableSegmentKey(e.key)) {
1746
+ if (Object.values(props.segmentValues()).every((item) => item !== null)) {
1747
+ const updateObject = { ...props.segmentValues() };
1748
+ let dateRef = props.placeholder().copy();
1749
+ Object.keys(updateObject).forEach((part) => {
1750
+ const value = updateObject[part];
1751
+ dateRef = dateRef.set({ [part]: value });
1752
+ });
1753
+ props.modelValue.set(dateRef.copy());
1754
+ }
1755
+ }
1756
+ }
1757
+ return {
1758
+ handleSegmentClick,
1759
+ handleSegmentKeydown,
1760
+ attributes
1761
+ };
1762
+ }
1763
+
758
1764
  var RdxPositionSide;
759
1765
  (function (RdxPositionSide) {
760
1766
  RdxPositionSide["Top"] = "top";
@@ -1011,5 +2017,5 @@ function watch(deps, fn, options) {
1011
2017
  * Generated bundle index. Do not edit.
1012
2018
  */
1013
2019
 
1014
- export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RDX_POSITIONING_DEFAULTS, RDX_POSITIONS, RdxAutoFocusDirective, RdxFocusInitialDirective, RdxPositionAlign, RdxPositionSide, SHIFT, SPACE, SPACE_CODE, TAB, WINDOW, _IdGenerator, a, areAllDaysBetweenValid, createFormatter, createMonth, createMonths, getAllPossibleConnectedPositions, getArrowPositionParams, getContentPosition, getDaysBetween, getDaysInMonth, getDefaultDate, getLastFirstDayOfWeek, getNextLastDayOfWeek, getPlaceholder, getSideAndAlignFromAllPossibleConnectedPositions, handleCalendarInitialFocus, hasTime, injectDocument, injectIsClient, injectNgControl, injectWindow, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isInsideForm, isNullish, isNumber, isZonedDateTime, j, k, n, p, provideValueAccessor, toDate, watch };
2020
+ export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RDX_POSITIONING_DEFAULTS, RDX_POSITIONS, RdxAutoFocusDirective, RdxFocusInitialDirective, RdxPositionAlign, RdxPositionSide, SHIFT, SPACE, SPACE_CODE, TAB, WINDOW, _IdGenerator, a, areAllDaysBetweenValid, createContent, createFormatter, createMonth, createMonths, getAllPossibleConnectedPositions, getArrowPositionParams, getContentPosition, getDaysBetween, getDaysInMonth, getDefaultDate, getLastFirstDayOfWeek, getNextLastDayOfWeek, getOptsByGranularity, getPlaceholder, getSegmentElements, getSideAndAlignFromAllPossibleConnectedPositions, handleCalendarInitialFocus, hasTime, initializeSegmentValues, injectDocument, injectIsClient, injectNgControl, injectWindow, isAcceptableSegmentKey, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isInsideForm, isNullish, isNumber, isNumberString, isSegmentNavigationKey, isZonedDateTime, j, k, n, p, provideToken, provideValueAccessor, segmentBuilders, syncSegmentValues, syncTimeSegmentValues, toDate, useDateField, watch };
1015
2021
  //# sourceMappingURL=radix-ng-primitives-core.mjs.map