@radix-ng/primitives 0.34.0 → 0.36.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.
- package/calendar/src/calendar-root.directive.d.ts +3 -3
- package/core/index.d.ts +3 -0
- package/core/src/accessor/provide-value-accessor.d.ts +1 -1
- package/core/src/clamp.d.ts +38 -0
- package/core/src/date-time/index.d.ts +3 -0
- package/core/src/date-time/parser.d.ts +37 -0
- package/core/src/date-time/parts.d.ts +12 -0
- package/core/src/date-time/segment.d.ts +4 -0
- package/core/src/date-time/types.d.ts +18 -1
- package/core/src/date-time/useDateField.d.ts +141 -0
- package/core/src/date-time/utils.d.ts +3 -0
- package/core/src/getActiveElement.d.ts +1 -0
- package/core/src/provide-token.d.ts +22 -0
- package/date-field/README.md +1 -0
- package/date-field/index.d.ts +11 -0
- package/date-field/src/date-field-context.token.d.ts +18 -0
- package/date-field/src/date-field-input.directive.d.ts +53 -0
- package/date-field/src/date-field-root.directive.d.ts +126 -0
- package/dialog/src/dialog-ref.d.ts +3 -0
- package/dialog/src/dialog.config.d.ts +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs +6 -15
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +3 -4
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +1097 -8
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +334 -0
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-dialog.mjs +54 -4
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +0 -2
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +502 -0
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-progress.mjs +3 -3
- package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +7 -7
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +7 -15
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +3 -6
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +8 -10
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +5 -12
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/hover-card/src/hover-card-root.directive.d.ts +4 -4
- package/number-field/README.md +1 -0
- package/number-field/index.d.ts +17 -0
- package/number-field/src/number-field-context.token.d.ts +24 -0
- package/number-field/src/number-field-decrement.directive.d.ts +23 -0
- package/number-field/src/number-field-increment.directive.d.ts +23 -0
- package/number-field/src/number-field-input.directive.d.ts +22 -0
- package/number-field/src/number-field-root.directive.d.ts +86 -0
- package/number-field/src/types.d.ts +1 -0
- package/number-field/src/utils.d.ts +18 -0
- package/package.json +9 -1
- package/popover/src/popover-root.directive.d.ts +4 -4
- package/switch/src/switch-root.directive.d.ts +0 -1
- package/toggle/src/toggle.directive.d.ts +0 -1
- package/tooltip/src/tooltip-root.directive.d.ts +4 -4
@@ -0,0 +1,334 @@
|
|
1
|
+
import * as i0 from '@angular/core';
|
2
|
+
import { InjectionToken, inject, input, computed, signal, effect, Directive, ElementRef, model, booleanAttribute, NgModule } from '@angular/core';
|
3
|
+
import { useDateField, getDefaultDate, hasTime, isBefore, createContent, watch, isNullish, createFormatter, initializeSegmentValues, syncSegmentValues, getSegmentElements, ARROW_LEFT, ARROW_RIGHT, isSegmentNavigationKey, provideToken } from '@radix-ng/primitives/core';
|
4
|
+
|
5
|
+
const DATE_FIELDS_ROOT_CONTEXT = new InjectionToken('DATE_FIELDS_ROOT_CONTEXT');
|
6
|
+
function injectDateFieldsRootContext() {
|
7
|
+
return inject(DATE_FIELDS_ROOT_CONTEXT);
|
8
|
+
}
|
9
|
+
|
10
|
+
class RdxDateFieldInputDirective {
|
11
|
+
constructor(el) {
|
12
|
+
this.el = el;
|
13
|
+
this.rootContext = injectDateFieldsRootContext();
|
14
|
+
/**
|
15
|
+
* The part of the date to render
|
16
|
+
* `'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'dayPeriod' | 'literal' | 'timeZoneName'`
|
17
|
+
*/
|
18
|
+
this.part = input();
|
19
|
+
/**
|
20
|
+
* @ignore
|
21
|
+
*/
|
22
|
+
this.disabled = computed(() => this.rootContext.disabled());
|
23
|
+
/**
|
24
|
+
* @ignore
|
25
|
+
*/
|
26
|
+
this.readonly = computed(() => this.rootContext.readonly());
|
27
|
+
/**
|
28
|
+
* @ignore
|
29
|
+
*/
|
30
|
+
this.isInvalid = computed(() => this.rootContext.isInvalid());
|
31
|
+
/**
|
32
|
+
* @ignore
|
33
|
+
*/
|
34
|
+
this.hasLeftFocus = signal(true);
|
35
|
+
/**
|
36
|
+
* @ignore
|
37
|
+
*/
|
38
|
+
this.lastKeyZero = signal(false);
|
39
|
+
this.fieldData = computed(() => {
|
40
|
+
return useDateField({
|
41
|
+
hasLeftFocus: this.hasLeftFocus,
|
42
|
+
lastKeyZero: this.lastKeyZero,
|
43
|
+
placeholder: this.rootContext.placeholder,
|
44
|
+
hourCycle: this.rootContext.hourCycle(),
|
45
|
+
segmentValues: this.rootContext.segmentValues,
|
46
|
+
formatter: this.rootContext.formatter,
|
47
|
+
part: this.part(),
|
48
|
+
disabled: this.rootContext.disabled,
|
49
|
+
readonly: this.rootContext.readonly,
|
50
|
+
modelValue: this.rootContext.value,
|
51
|
+
focusNext: this.rootContext.focusNext
|
52
|
+
});
|
53
|
+
});
|
54
|
+
this.attributes = computed(() => this.fieldData().attributes());
|
55
|
+
effect(() => {
|
56
|
+
const { handleSegmentClick, handleSegmentKeydown } = this.fieldData();
|
57
|
+
this.handleSegmentKeydown = handleSegmentKeydown;
|
58
|
+
this.handleSegmentClick = handleSegmentClick;
|
59
|
+
});
|
60
|
+
effect(() => {
|
61
|
+
const attrs = this.attributes();
|
62
|
+
Object.entries(attrs).forEach(([attr, value]) => {
|
63
|
+
this.el.nativeElement.setAttribute(attr, String(value));
|
64
|
+
});
|
65
|
+
});
|
66
|
+
}
|
67
|
+
/**
|
68
|
+
* @ignore
|
69
|
+
*/
|
70
|
+
onFocus(e) {
|
71
|
+
this.rootContext.setFocusedElement(e.target);
|
72
|
+
}
|
73
|
+
/**
|
74
|
+
* @ignore
|
75
|
+
*/
|
76
|
+
onFocusOut() {
|
77
|
+
this.hasLeftFocus.set(true);
|
78
|
+
}
|
79
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldInputDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
80
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.4", type: RdxDateFieldInputDirective, isStandalone: true, selector: "[rdxDateFieldInput]", inputs: { part: { classPropertyName: "part", publicName: "part", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mousedown": "part() !== \"literal\" && handleSegmentClick($event)", "keydown": "part() !== \"literal\" && handleSegmentKeydown($event)", "focus": "part() !== \"literal\" && onFocus($event)", "focusout": "part() !== \"literal\" && onFocusOut()" }, properties: { "attr.contenteditable": "disabled() || readonly() ? false : part() !== \"literal\"", "attr.data-rdx-date-field-segment": "part()", "attr.aria-disabled": "disabled() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-invalid": "isInvalid() ? \"\" : undefined", "attr.aria-invalid": "isInvalid() ? true : undefined" } }, ngImport: i0 }); }
|
81
|
+
}
|
82
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldInputDirective, decorators: [{
|
83
|
+
type: Directive,
|
84
|
+
args: [{
|
85
|
+
selector: '[rdxDateFieldInput]',
|
86
|
+
host: {
|
87
|
+
'[attr.contenteditable]': 'disabled() || readonly() ? false : part() !== "literal"',
|
88
|
+
'[attr.data-rdx-date-field-segment]': 'part()',
|
89
|
+
'[attr.aria-disabled]': 'disabled() ? "" : undefined',
|
90
|
+
'[attr.data-disabled]': 'disabled() ? "" : undefined',
|
91
|
+
'[attr.data-invalid]': 'isInvalid() ? "" : undefined',
|
92
|
+
'[attr.aria-invalid]': 'isInvalid() ? true : undefined',
|
93
|
+
'(mousedown)': 'part() !== "literal" && handleSegmentClick($event)',
|
94
|
+
'(keydown)': 'part() !== "literal" && handleSegmentKeydown($event)',
|
95
|
+
'(focus)': 'part() !== "literal" && onFocus($event)',
|
96
|
+
'(focusout)': 'part() !== "literal" && onFocusOut()'
|
97
|
+
}
|
98
|
+
}]
|
99
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }] });
|
100
|
+
|
101
|
+
class RdxDateFieldRootDirective {
|
102
|
+
constructor() {
|
103
|
+
this.elementRef = inject((ElementRef));
|
104
|
+
/**
|
105
|
+
* The controlled checked state of the calendar.
|
106
|
+
*/
|
107
|
+
this.value = model();
|
108
|
+
/**
|
109
|
+
* A callback fired when the date field's value is invalid.
|
110
|
+
*/
|
111
|
+
this.isDateUnavailable = input(undefined);
|
112
|
+
/**
|
113
|
+
* The hour cycle to use for formatting times. Defaults to the locale preference
|
114
|
+
*/
|
115
|
+
this.hourCycle = input();
|
116
|
+
/**
|
117
|
+
* The granularity to use for formatting the field. Defaults to 'day' if a CalendarDate is provided, otherwise defaults to 'minute'.
|
118
|
+
* The field will render segments for each part of the date up to and including the specified granularity.
|
119
|
+
*/
|
120
|
+
this.granularity = input();
|
121
|
+
/**
|
122
|
+
* The locale to use for formatting dates.
|
123
|
+
*/
|
124
|
+
this.locale = input('en');
|
125
|
+
this.dir = input('ltr');
|
126
|
+
/**
|
127
|
+
* The minimum valid date that can be entered.
|
128
|
+
*/
|
129
|
+
this.minValue = input();
|
130
|
+
/**
|
131
|
+
* The maximum valid date that can be entered.
|
132
|
+
*/
|
133
|
+
this.maxValue = input();
|
134
|
+
/**
|
135
|
+
* Whether or not to hide the time zone segment of the field.
|
136
|
+
*/
|
137
|
+
this.hideTimeZone = input(false, { transform: booleanAttribute });
|
138
|
+
this.disabled = input(false, { transform: booleanAttribute });
|
139
|
+
/**
|
140
|
+
* Whether or not the field is readonly.
|
141
|
+
*/
|
142
|
+
this.readonly = input(false, { transform: booleanAttribute });
|
143
|
+
/**
|
144
|
+
* @ignore
|
145
|
+
*/
|
146
|
+
this.defaultDate = computed(() => getDefaultDate({
|
147
|
+
defaultPlaceholder: undefined,
|
148
|
+
granularity: this.granularity(),
|
149
|
+
defaultValue: this.value(),
|
150
|
+
locale: this.locale()
|
151
|
+
}));
|
152
|
+
/**
|
153
|
+
* The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view
|
154
|
+
*/
|
155
|
+
this.placeholder = model(this.defaultDate().copy());
|
156
|
+
// Internal state
|
157
|
+
/**
|
158
|
+
* @ignore
|
159
|
+
*/
|
160
|
+
this.segmentElements = signal(new Set());
|
161
|
+
/**
|
162
|
+
* @ignore
|
163
|
+
*/
|
164
|
+
this.currentFocusedElement = signal(null);
|
165
|
+
/**
|
166
|
+
* @ignore
|
167
|
+
*/
|
168
|
+
this.segmentValues = signal({
|
169
|
+
year: null,
|
170
|
+
month: null,
|
171
|
+
day: null,
|
172
|
+
hour: null,
|
173
|
+
minute: null,
|
174
|
+
second: null,
|
175
|
+
dayPeriod: null
|
176
|
+
});
|
177
|
+
/**
|
178
|
+
* @ignore
|
179
|
+
*/
|
180
|
+
this.inferredGranularity = computed(() => {
|
181
|
+
const placeholder = this.placeholder();
|
182
|
+
if (this.granularity())
|
183
|
+
return placeholder && !hasTime(placeholder) ? 'day' : this.granularity();
|
184
|
+
return placeholder && hasTime(placeholder) ? 'minute' : 'day';
|
185
|
+
});
|
186
|
+
/**
|
187
|
+
* @ignore
|
188
|
+
*/
|
189
|
+
this.isInvalid = computed(() => {
|
190
|
+
if (!this.value())
|
191
|
+
return false;
|
192
|
+
if (this.isDateUnavailable()?.(this.value()))
|
193
|
+
return true;
|
194
|
+
if (this.minValue() && isBefore(this.value(), this.minValue()))
|
195
|
+
return true;
|
196
|
+
if (this.maxValue() && isBefore(this.maxValue(), this.value()))
|
197
|
+
return true;
|
198
|
+
return false;
|
199
|
+
});
|
200
|
+
/**
|
201
|
+
* @ignore
|
202
|
+
*/
|
203
|
+
this.allSegmentContent = computed(() => createContent({
|
204
|
+
granularity: this.inferredGranularity(),
|
205
|
+
dateRef: this.placeholder(),
|
206
|
+
formatter: this.formatter,
|
207
|
+
hideTimeZone: this.hideTimeZone(),
|
208
|
+
hourCycle: this.hourCycle(),
|
209
|
+
segmentValues: this.segmentValues(),
|
210
|
+
locale: this.locale
|
211
|
+
}));
|
212
|
+
/**
|
213
|
+
* An array of segments that should be readonly, which prevent user input on them.
|
214
|
+
*/
|
215
|
+
this.segmentContents = computed(() => this.allSegmentContent().arr);
|
216
|
+
/**
|
217
|
+
* @ignore
|
218
|
+
*/
|
219
|
+
this.currentSegmentIndex = computed(() => Array.from(this.segmentElements()).findIndex((el) => el.getAttribute('data-rdx-date-field-segment') ===
|
220
|
+
this.currentFocusedElement()?.getAttribute('data-rdx-date-field-segment')));
|
221
|
+
/**
|
222
|
+
* @ignore
|
223
|
+
*/
|
224
|
+
this.prevFocusableSegment = computed(() => {
|
225
|
+
const sign = this.dir() === 'rtl' ? -1 : 1;
|
226
|
+
const prevCondition = sign > 0 ? this.currentSegmentIndex() < 0 : this.currentSegmentIndex() > this.segmentElements().size - 1;
|
227
|
+
if (prevCondition)
|
228
|
+
return null;
|
229
|
+
const segmentToFocus = Array.from(this.segmentElements())[this.currentSegmentIndex() - sign];
|
230
|
+
return segmentToFocus;
|
231
|
+
});
|
232
|
+
/**
|
233
|
+
* @ignore
|
234
|
+
*/
|
235
|
+
this.nextFocusableSegment = computed(() => {
|
236
|
+
const sign = this.dir() === 'rtl' ? -1 : 1;
|
237
|
+
const nextCondition = sign < 0 ? this.currentSegmentIndex() < 0 : this.currentSegmentIndex() > this.segmentElements().size - 1;
|
238
|
+
if (nextCondition)
|
239
|
+
return null;
|
240
|
+
const segmentToFocus = Array.from(this.segmentElements())[this.currentSegmentIndex() + sign];
|
241
|
+
return segmentToFocus;
|
242
|
+
});
|
243
|
+
/**
|
244
|
+
* @ignore
|
245
|
+
*/
|
246
|
+
this.focusNext = () => {
|
247
|
+
this.nextFocusableSegment()?.focus();
|
248
|
+
};
|
249
|
+
watch([this.value], ([modelValue]) => {
|
250
|
+
if (!isNullish(modelValue) && this.placeholder()?.compare(modelValue) !== 0) {
|
251
|
+
this.placeholder.set(modelValue.copy());
|
252
|
+
}
|
253
|
+
});
|
254
|
+
}
|
255
|
+
ngOnInit() {
|
256
|
+
const defDate = getDefaultDate({
|
257
|
+
defaultPlaceholder: undefined,
|
258
|
+
granularity: this.granularity(),
|
259
|
+
defaultValue: this.value(),
|
260
|
+
locale: this.locale()
|
261
|
+
});
|
262
|
+
this.placeholder.set(defDate.copy());
|
263
|
+
this.formatter = createFormatter(this.locale());
|
264
|
+
const initialSegments = initializeSegmentValues(this.inferredGranularity());
|
265
|
+
this.segmentValues.set(this.value()
|
266
|
+
? { ...syncSegmentValues({ value: this.value(), formatter: this.formatter }) }
|
267
|
+
: { ...initialSegments });
|
268
|
+
}
|
269
|
+
ngAfterViewInit() {
|
270
|
+
getSegmentElements(this.elementRef.nativeElement).forEach((item) => this.segmentElements().add(item));
|
271
|
+
}
|
272
|
+
/**
|
273
|
+
* @ignore
|
274
|
+
*/
|
275
|
+
onKeydown(event) {
|
276
|
+
const code = event.code;
|
277
|
+
if ([ARROW_LEFT, ARROW_RIGHT].includes(code)) {
|
278
|
+
if (!isSegmentNavigationKey(event.key))
|
279
|
+
return;
|
280
|
+
if (code === ARROW_LEFT) {
|
281
|
+
this.prevFocusableSegment()?.focus();
|
282
|
+
}
|
283
|
+
if (code === ARROW_RIGHT) {
|
284
|
+
this.nextFocusableSegment()?.focus();
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
/**
|
289
|
+
* @ignore
|
290
|
+
*/
|
291
|
+
setFocusedElement(el) {
|
292
|
+
this.currentFocusedElement.set(el);
|
293
|
+
}
|
294
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
295
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.4", type: RdxDateFieldRootDirective, isStandalone: true, selector: "[rdxDateFieldRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, isDateUnavailable: { classPropertyName: "isDateUnavailable", publicName: "isDateUnavailable", isSignal: true, isRequired: false, transformFunction: null }, hourCycle: { classPropertyName: "hourCycle", publicName: "hourCycle", isSignal: true, isRequired: false, transformFunction: null }, granularity: { classPropertyName: "granularity", publicName: "granularity", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, hideTimeZone: { classPropertyName: "hideTimeZone", publicName: "hideTimeZone", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", placeholder: "placeholderChange" }, host: { attributes: { "role": "group" }, listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.aria-disabled": "disabled() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-readonly": "readonly() ? \"\" : undefined", "attr.data-invalid": "isInvalid() ? \"\" : undefined", "attr.dir": "dir()" } }, providers: [provideToken(DATE_FIELDS_ROOT_CONTEXT, RdxDateFieldRootDirective)], exportAs: ["rdxDateFieldRoot"], ngImport: i0 }); }
|
296
|
+
}
|
297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldRootDirective, decorators: [{
|
298
|
+
type: Directive,
|
299
|
+
args: [{
|
300
|
+
selector: '[rdxDateFieldRoot]',
|
301
|
+
exportAs: 'rdxDateFieldRoot',
|
302
|
+
providers: [provideToken(DATE_FIELDS_ROOT_CONTEXT, RdxDateFieldRootDirective)],
|
303
|
+
host: {
|
304
|
+
role: 'group',
|
305
|
+
'[attr.aria-disabled]': 'disabled() ? "" : undefined',
|
306
|
+
'[attr.data-disabled]': 'disabled() ? "" : undefined',
|
307
|
+
'[attr.data-readonly]': 'readonly() ? "" : undefined',
|
308
|
+
'[attr.data-invalid]': 'isInvalid() ? "" : undefined',
|
309
|
+
'[attr.dir]': 'dir()',
|
310
|
+
'(keydown)': 'onKeydown($event)'
|
311
|
+
}
|
312
|
+
}]
|
313
|
+
}], ctorParameters: () => [] });
|
314
|
+
|
315
|
+
const _imports = [RdxDateFieldRootDirective, RdxDateFieldInputDirective];
|
316
|
+
class RdxDateFieldModule {
|
317
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
318
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldModule, imports: [RdxDateFieldRootDirective, RdxDateFieldInputDirective], exports: [RdxDateFieldRootDirective, RdxDateFieldInputDirective] }); }
|
319
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldModule }); }
|
320
|
+
}
|
321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxDateFieldModule, decorators: [{
|
322
|
+
type: NgModule,
|
323
|
+
args: [{
|
324
|
+
imports: [..._imports],
|
325
|
+
exports: [..._imports]
|
326
|
+
}]
|
327
|
+
}] });
|
328
|
+
|
329
|
+
/**
|
330
|
+
* Generated bundle index. Do not edit.
|
331
|
+
*/
|
332
|
+
|
333
|
+
export { DATE_FIELDS_ROOT_CONTEXT, RdxDateFieldInputDirective, RdxDateFieldModule, RdxDateFieldRootDirective, injectDateFieldsRootContext };
|
334
|
+
//# sourceMappingURL=radix-ng-primitives-date-field.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"radix-ng-primitives-date-field.mjs","sources":["../../../packages/primitives/date-field/src/date-field-context.token.ts","../../../packages/primitives/date-field/src/date-field-input.directive.ts","../../../packages/primitives/date-field/src/date-field-root.directive.ts","../../../packages/primitives/date-field/index.ts","../../../packages/primitives/date-field/radix-ng-primitives-date-field.ts"],"sourcesContent":["import { inject, InjectionToken, InputSignal, ModelSignal, Signal, WritableSignal } from '@angular/core';\nimport { DateValue } from '@internationalized/date';\nimport { Formatter, HourCycle, SegmentValueObj } from '@radix-ng/primitives/core';\n\nexport interface DateFieldContextToken {\n locale: InputSignal<string>;\n value: ModelSignal<DateValue | undefined>;\n disabled: InputSignal<boolean>;\n readonly: InputSignal<boolean>;\n isInvalid: Signal<boolean>;\n placeholder: ModelSignal<DateValue>;\n hourCycle: InputSignal<HourCycle>;\n formatter: Formatter;\n segmentValues: WritableSignal<SegmentValueObj>;\n focusNext: () => void;\n setFocusedElement: (el: HTMLElement) => void;\n}\n\nexport const DATE_FIELDS_ROOT_CONTEXT = new InjectionToken<DateFieldContextToken>('DATE_FIELDS_ROOT_CONTEXT');\n\nexport function injectDateFieldsRootContext(): DateFieldContextToken {\n return inject(DATE_FIELDS_ROOT_CONTEXT);\n}\n","import { computed, Directive, effect, ElementRef, input, signal } from '@angular/core';\nimport { SegmentPart, useDateField } from '@radix-ng/primitives/core';\nimport { injectDateFieldsRootContext } from './date-field-context.token';\n\n@Directive({\n selector: '[rdxDateFieldInput]',\n host: {\n '[attr.contenteditable]': 'disabled() || readonly() ? false : part() !== \"literal\"',\n '[attr.data-rdx-date-field-segment]': 'part()',\n '[attr.aria-disabled]': 'disabled() ? \"\" : undefined',\n '[attr.data-disabled]': 'disabled() ? \"\" : undefined',\n '[attr.data-invalid]': 'isInvalid() ? \"\" : undefined',\n '[attr.aria-invalid]': 'isInvalid() ? true : undefined',\n\n '(mousedown)': 'part() !== \"literal\" && handleSegmentClick($event)',\n '(keydown)': 'part() !== \"literal\" && handleSegmentKeydown($event)',\n '(focus)': 'part() !== \"literal\" && onFocus($event)',\n '(focusout)': 'part() !== \"literal\" && onFocusOut()'\n }\n})\nexport class RdxDateFieldInputDirective {\n private readonly rootContext = injectDateFieldsRootContext();\n\n /**\n * The part of the date to render\n * `'day' | 'month' | 'year' | 'hour' | 'minute' | 'second' | 'dayPeriod' | 'literal' | 'timeZoneName'`\n */\n readonly part = input<SegmentPart>();\n\n /**\n * @ignore\n */\n readonly disabled = computed(() => this.rootContext.disabled());\n\n /**\n * @ignore\n */\n readonly readonly = computed(() => this.rootContext.readonly());\n\n /**\n * @ignore\n */\n readonly isInvalid = computed(() => this.rootContext.isInvalid());\n\n /**\n * @ignore\n */\n readonly hasLeftFocus = signal<boolean>(true);\n\n /**\n * @ignore\n */\n readonly lastKeyZero = signal<boolean>(false);\n\n private readonly fieldData = computed(() => {\n return useDateField({\n hasLeftFocus: this.hasLeftFocus,\n lastKeyZero: this.lastKeyZero,\n placeholder: this.rootContext.placeholder,\n hourCycle: this.rootContext.hourCycle(),\n segmentValues: this.rootContext.segmentValues,\n formatter: this.rootContext.formatter,\n part: <SegmentPart>this.part(),\n disabled: this.rootContext.disabled,\n readonly: this.rootContext.readonly,\n modelValue: this.rootContext.value,\n focusNext: this.rootContext.focusNext\n });\n });\n\n private readonly attributes = computed(() => this.fieldData().attributes());\n\n /**\n * @ignore\n */\n handleSegmentClick: (e: MouseEvent) => void;\n\n /**\n * @ignore\n */\n handleSegmentKeydown: (e: KeyboardEvent) => void;\n\n constructor(private el: ElementRef) {\n effect(() => {\n const { handleSegmentClick, handleSegmentKeydown } = this.fieldData();\n this.handleSegmentKeydown = handleSegmentKeydown;\n this.handleSegmentClick = handleSegmentClick;\n });\n\n effect(() => {\n const attrs = this.attributes();\n Object.entries(attrs).forEach(([attr, value]) => {\n this.el.nativeElement.setAttribute(attr, String(value));\n });\n });\n }\n\n /**\n * @ignore\n */\n onFocus(e: FocusEvent) {\n this.rootContext.setFocusedElement(e.target as HTMLElement);\n }\n\n /**\n * @ignore\n */\n onFocusOut() {\n this.hasLeftFocus.set(true);\n }\n}\n","import { Direction } from '@angular/cdk/bidi';\nimport { BooleanInput } from '@angular/cdk/coercion';\nimport {\n AfterViewInit,\n booleanAttribute,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n model,\n OnInit,\n signal\n} from '@angular/core';\nimport { DateValue } from '@internationalized/date';\nimport {\n ARROW_LEFT,\n ARROW_RIGHT,\n createContent,\n createFormatter,\n DateMatcher,\n Formatter,\n getDefaultDate,\n getSegmentElements,\n Granularity,\n hasTime,\n HourCycle,\n initializeSegmentValues,\n isBefore,\n isNullish,\n isSegmentNavigationKey,\n provideToken,\n SegmentValueObj,\n syncSegmentValues,\n watch\n} from '@radix-ng/primitives/core';\nimport { DATE_FIELDS_ROOT_CONTEXT } from './date-field-context.token';\n\n@Directive({\n selector: '[rdxDateFieldRoot]',\n exportAs: 'rdxDateFieldRoot',\n providers: [provideToken(DATE_FIELDS_ROOT_CONTEXT, RdxDateFieldRootDirective)],\n host: {\n role: 'group',\n '[attr.aria-disabled]': 'disabled() ? \"\" : undefined',\n '[attr.data-disabled]': 'disabled() ? \"\" : undefined',\n '[attr.data-readonly]': 'readonly() ? \"\" : undefined',\n '[attr.data-invalid]': 'isInvalid() ? \"\" : undefined',\n '[attr.dir]': 'dir()',\n\n '(keydown)': 'onKeydown($event)'\n }\n})\nexport class RdxDateFieldRootDirective implements OnInit, AfterViewInit {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * The controlled checked state of the calendar.\n */\n readonly value = model<DateValue | undefined>();\n\n /**\n * A callback fired when the date field's value is invalid.\n */\n readonly isDateUnavailable = input<DateMatcher | undefined>(undefined);\n\n /**\n * The hour cycle to use for formatting times. Defaults to the locale preference\n */\n readonly hourCycle = input<HourCycle>();\n\n /**\n * The granularity to use for formatting the field. Defaults to 'day' if a CalendarDate is provided, otherwise defaults to 'minute'.\n * The field will render segments for each part of the date up to and including the specified granularity.\n */\n readonly granularity = input<Granularity>();\n\n /**\n * The locale to use for formatting dates.\n */\n readonly locale = input<string>('en');\n\n readonly dir = input<Direction>('ltr');\n\n /**\n * The minimum valid date that can be entered.\n */\n readonly minValue = input<DateValue>();\n\n /**\n * The maximum valid date that can be entered.\n */\n readonly maxValue = input<DateValue>();\n\n /**\n * Whether or not to hide the time zone segment of the field.\n */\n readonly hideTimeZone = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether or not the field is readonly.\n */\n readonly readonly = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * @ignore\n */\n readonly defaultDate = computed(() =>\n getDefaultDate({\n defaultPlaceholder: undefined,\n granularity: this.granularity(),\n defaultValue: this.value(),\n locale: this.locale()\n })\n );\n\n /**\n * The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view\n */\n readonly placeholder = model<DateValue | undefined>(this.defaultDate().copy());\n\n // Internal state\n\n /**\n * @ignore\n */\n readonly segmentElements = signal<Set<HTMLElement>>(new Set());\n\n /**\n * @ignore\n */\n readonly currentFocusedElement = signal<HTMLElement | null>(null);\n\n /**\n * @ignore\n */\n formatter: Formatter;\n\n /**\n * @ignore\n */\n readonly segmentValues = signal<SegmentValueObj>({\n year: null,\n month: null,\n day: null,\n hour: null,\n minute: null,\n second: null,\n dayPeriod: null\n } as SegmentValueObj);\n\n /**\n * @ignore\n */\n readonly inferredGranularity = computed(() => {\n const placeholder = this.placeholder();\n\n if (this.granularity()) return placeholder && !hasTime(placeholder) ? 'day' : this.granularity();\n\n return placeholder && hasTime(placeholder) ? 'minute' : 'day';\n });\n\n /**\n * @ignore\n */\n readonly isInvalid = computed(() => {\n if (!this.value()) return false;\n\n if (this.isDateUnavailable()?.(<DateValue>this.value())) return true;\n\n if (this.minValue() && isBefore(<DateValue>this.value(), <DateValue>this.minValue())) return true;\n\n if (this.maxValue() && isBefore(<DateValue>this.maxValue(), <DateValue>this.value())) return true;\n\n return false;\n });\n\n /**\n * @ignore\n */\n readonly allSegmentContent = computed(() =>\n createContent({\n granularity: <Granularity>this.inferredGranularity(),\n dateRef: <DateValue>this.placeholder(),\n formatter: this.formatter,\n hideTimeZone: this.hideTimeZone(),\n hourCycle: this.hourCycle(),\n segmentValues: this.segmentValues(),\n locale: this.locale\n })\n );\n\n /**\n * An array of segments that should be readonly, which prevent user input on them.\n */\n readonly segmentContents = computed(() => this.allSegmentContent().arr);\n\n /**\n * @ignore\n */\n readonly currentSegmentIndex = computed(() =>\n Array.from(this.segmentElements()).findIndex(\n (el) =>\n el.getAttribute('data-rdx-date-field-segment') ===\n this.currentFocusedElement()?.getAttribute('data-rdx-date-field-segment')\n )\n );\n\n /**\n * @ignore\n */\n readonly prevFocusableSegment = computed(() => {\n const sign = this.dir() === 'rtl' ? -1 : 1;\n const prevCondition =\n sign > 0 ? this.currentSegmentIndex() < 0 : this.currentSegmentIndex() > this.segmentElements().size - 1;\n if (prevCondition) return null;\n\n const segmentToFocus = Array.from(this.segmentElements())[this.currentSegmentIndex() - sign];\n return segmentToFocus;\n });\n\n /**\n * @ignore\n */\n readonly nextFocusableSegment = computed(() => {\n const sign = this.dir() === 'rtl' ? -1 : 1;\n const nextCondition =\n sign < 0 ? this.currentSegmentIndex() < 0 : this.currentSegmentIndex() > this.segmentElements().size - 1;\n if (nextCondition) return null;\n const segmentToFocus = Array.from(this.segmentElements())[this.currentSegmentIndex() + sign];\n return segmentToFocus;\n });\n\n /**\n * @ignore\n */\n readonly focusNext = () => {\n this.nextFocusableSegment()?.focus();\n };\n\n constructor() {\n watch([this.value], ([modelValue]) => {\n if (!isNullish(modelValue) && this.placeholder()?.compare(modelValue) !== 0) {\n this.placeholder.set(modelValue.copy());\n }\n });\n }\n\n ngOnInit() {\n const defDate = getDefaultDate({\n defaultPlaceholder: undefined,\n granularity: this.granularity(),\n defaultValue: this.value(),\n locale: this.locale()\n });\n\n this.placeholder.set(defDate.copy());\n\n this.formatter = createFormatter(this.locale());\n\n const initialSegments = initializeSegmentValues(this.inferredGranularity()!);\n\n this.segmentValues.set(\n this.value()\n ? { ...syncSegmentValues({ value: <DateValue>this.value(), formatter: this.formatter }) }\n : { ...initialSegments }\n );\n }\n\n ngAfterViewInit() {\n getSegmentElements(this.elementRef.nativeElement).forEach((item) =>\n this.segmentElements().add(item as HTMLElement)\n );\n }\n\n /**\n * @ignore\n */\n onKeydown(event: KeyboardEvent) {\n const code = event.code;\n if ([ARROW_LEFT, ARROW_RIGHT].includes(code)) {\n if (!isSegmentNavigationKey(event.key)) return;\n\n if (code === ARROW_LEFT) {\n this.prevFocusableSegment()?.focus();\n }\n\n if (code === ARROW_RIGHT) {\n this.nextFocusableSegment()?.focus();\n }\n }\n }\n\n /**\n * @ignore\n */\n setFocusedElement(el: HTMLElement) {\n this.currentFocusedElement.set(el);\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RdxDateFieldInputDirective } from './src/date-field-input.directive';\nimport { RdxDateFieldRootDirective } from './src/date-field-root.directive';\n\nexport * from './src/date-field-context.token';\nexport * from './src/date-field-input.directive';\nexport * from './src/date-field-root.directive';\n\nconst _imports = [RdxDateFieldRootDirective, RdxDateFieldInputDirective];\n\n@NgModule({\n imports: [..._imports],\n exports: [..._imports]\n})\nexport class RdxDateFieldModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
|
-
import { inject, Directive, DestroyRef,
|
2
|
+
import { signal, computed, inject, Directive, DestroyRef, Injector, RendererFactory2, runInInjectionContext, effect, Renderer2, Injectable, makeEnvironmentProviders, importProvidersFrom, input, Input, NgModule } from '@angular/core';
|
3
3
|
import { map, filter, isObservable, of, take, merge, switchMap, takeUntil } from 'rxjs';
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
5
5
|
import { Dialog, DialogModule, DIALOG_DATA } from '@angular/cdk/dialog';
|
@@ -21,6 +21,9 @@ class RdxDialogRef {
|
|
21
21
|
constructor(cdkRef, config) {
|
22
22
|
this.cdkRef = cdkRef;
|
23
23
|
this.config = config;
|
24
|
+
// state tracking
|
25
|
+
this._openSignal = signal(true);
|
26
|
+
this.state = computed(() => (this._openSignal() ? 'open' : 'closed'));
|
24
27
|
this.closed$ = this.cdkRef.closed.pipe(map((res) => (isDismissed(res) ? undefined : res)));
|
25
28
|
this.dismissed$ = this.cdkRef.closed.pipe(filter((res) => res === DISMISSED_VALUE), map(() => undefined));
|
26
29
|
this.result$ = this.cdkRef.closed.pipe(filter((res) => !isDismissed(res)));
|
@@ -45,7 +48,19 @@ class RdxDialogRef {
|
|
45
48
|
});
|
46
49
|
}
|
47
50
|
close(result) {
|
48
|
-
|
51
|
+
// check if dialog is already in closing state to prevent double-closing
|
52
|
+
if (this.state() === 'closed') {
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
this._openSignal.set(false);
|
56
|
+
if (this._previousTimeout) {
|
57
|
+
clearTimeout(this._previousTimeout);
|
58
|
+
}
|
59
|
+
const closeDelay = this.config.closeDelay ?? 100; // Default to 100ms if not specified
|
60
|
+
// Actual closing happens after delay
|
61
|
+
this._previousTimeout = setTimeout(() => {
|
62
|
+
this.cdkRef.close(result ?? DISMISSED_VALUE);
|
63
|
+
}, closeDelay);
|
49
64
|
}
|
50
65
|
}
|
51
66
|
|
@@ -183,6 +198,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
183
198
|
class RdxDialogService {
|
184
199
|
#cdkDialog = inject(Dialog);
|
185
200
|
#injector = inject(Injector);
|
201
|
+
#rendererFactory = inject(RendererFactory2);
|
202
|
+
#renderer = this.#rendererFactory.createRenderer(null, null);
|
186
203
|
open(config) {
|
187
204
|
let dialogRef;
|
188
205
|
let modeClasses = [];
|
@@ -203,6 +220,11 @@ class RdxDialogService {
|
|
203
220
|
modeClasses = ['mod-sheet', 'mod-top'];
|
204
221
|
break;
|
205
222
|
}
|
223
|
+
// Create a new configuration with default closeDelay if not provided
|
224
|
+
const extendedConfig = {
|
225
|
+
...config,
|
226
|
+
closeDelay: config.closeDelay ?? 0
|
227
|
+
};
|
206
228
|
const cdkRef = this.#cdkDialog.open(config.content, {
|
207
229
|
ariaModal: config.modal ?? true,
|
208
230
|
hasBackdrop: config.modal ?? true,
|
@@ -218,7 +240,33 @@ class RdxDialogService {
|
|
218
240
|
ariaLabel: config.ariaLabel,
|
219
241
|
templateContext: () => ({ dialogRef: dialogRef }),
|
220
242
|
providers: (ref) => {
|
221
|
-
|
243
|
+
// Create dialog ref with state tracking
|
244
|
+
dialogRef = new RdxDialogRef(ref, extendedConfig);
|
245
|
+
// Get overlay and backdrop references
|
246
|
+
const overlay = ref.overlayRef.overlayElement;
|
247
|
+
const backdrop = ref.overlayRef.backdropElement;
|
248
|
+
// Set up effect to track and update state attributes
|
249
|
+
runInInjectionContext(this.#injector, () => {
|
250
|
+
effect(() => {
|
251
|
+
const currentState = dialogRef.state();
|
252
|
+
if (overlay) {
|
253
|
+
this.#renderer.setAttribute(overlay, 'data-state', currentState);
|
254
|
+
}
|
255
|
+
if (backdrop) {
|
256
|
+
this.#renderer.setAttribute(backdrop, 'data-state', currentState);
|
257
|
+
}
|
258
|
+
// For sheet dialogs, add data-side attribute
|
259
|
+
if (config.mode?.startsWith('sheet-')) {
|
260
|
+
const side = config.mode.substring(6);
|
261
|
+
if (overlay) {
|
262
|
+
this.#renderer.setAttribute(overlay, 'data-side', side);
|
263
|
+
}
|
264
|
+
if (backdrop) {
|
265
|
+
this.#renderer.setAttribute(backdrop, 'data-side', side);
|
266
|
+
}
|
267
|
+
}
|
268
|
+
});
|
269
|
+
});
|
222
270
|
return [
|
223
271
|
{
|
224
272
|
provide: RdxDialogRef,
|
@@ -243,7 +291,9 @@ class RdxDialogService {
|
|
243
291
|
}), takeUntil(dialogRef.closed$))
|
244
292
|
.subscribe((canClose) => {
|
245
293
|
if (canClose) {
|
246
|
-
cdkRef.close(
|
294
|
+
// rather than `cdkRef.close()`, closing the `dialogRef` directly
|
295
|
+
// ensures that the `state` is represented correctly
|
296
|
+
dialogRef.close(undefined);
|
247
297
|
}
|
248
298
|
});
|
249
299
|
}
|