@arsedizioni/ars-utils 22.6.75 → 22.6.77

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 (30) hide show
  1. package/fesm2022/arsedizioni-ars-utils-clipper.common.mjs +15 -15
  2. package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +42 -42
  3. package/fesm2022/arsedizioni-ars-utils-core.date.mjs +68 -120
  4. package/fesm2022/arsedizioni-ars-utils-core.date.mjs.map +1 -1
  5. package/fesm2022/arsedizioni-ars-utils-core.markdown.mjs +3 -3
  6. package/fesm2022/arsedizioni-ars-utils-core.mjs +48 -48
  7. package/fesm2022/arsedizioni-ars-utils-core.validators.mjs +42 -42
  8. package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs +15 -15
  9. package/fesm2022/arsedizioni-ars-utils-support.common.mjs +9 -9
  10. package/fesm2022/arsedizioni-ars-utils-ui.controls.date.mjs +6 -6
  11. package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs +9 -9
  12. package/fesm2022/arsedizioni-ars-utils-ui.controls.tree.mjs +3 -3
  13. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs +18 -18
  14. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs +12 -12
  15. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs +9 -9
  16. package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +15 -15
  17. package/fesm2022/arsedizioni-ars-utils-ui.files.mjs +12 -12
  18. package/fesm2022/arsedizioni-ars-utils-ui.filters.mjs +3 -3
  19. package/fesm2022/arsedizioni-ars-utils-ui.help.mjs +9 -9
  20. package/fesm2022/arsedizioni-ars-utils-ui.mjs +61 -61
  21. package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs +80 -6
  22. package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs.map +1 -1
  23. package/fesm2022/arsedizioni-ars-utils-ui.notifications.mjs +6 -6
  24. package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs +6 -6
  25. package/fesm2022/arsedizioni-ars-utils-ui.paginator.mjs +3 -3
  26. package/fesm2022/arsedizioni-ars-utils-ui.shell.mjs +9 -9
  27. package/fesm2022/arsedizioni-ars-utils-ui.tinymce.mjs +9 -9
  28. package/package.json +1 -1
  29. package/types/arsedizioni-ars-utils-core.date.d.ts +35 -76
  30. package/types/arsedizioni-ars-utils-ui.navigation.d.ts +20 -0
@@ -213,23 +213,36 @@ declare const DEFAULT_TIME_ZONE = "Europe/Rome";
213
213
  */
214
214
  declare const ARS_TIME_ZONE: InjectionToken<string>;
215
215
  /**
216
- * Functional interceptor that serialises every `Date` in an outgoing request
217
- * body as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`: no `Z`, no offset).
216
+ * Functional interceptor that closes the date serialisation boundary of the application, in both
217
+ * directions: it writes the dates of every request and reads back those of every response.
218
218
  *
219
- * WHY: `JSON.stringify` calls `Date.prototype.toJSON`, which emits a UTC instant.
220
- * A date picked as 29/07/2026 00:00 in Rome (UTC+2) becomes
221
- * `2026-07-28T22:00:00.000Z`, so the server stores the 28th — the classic
222
- * "off by one day" bug. Sending the wall-clock value instead makes
223
- * System.Text.Json produce a `DateTime` with `Kind = Unspecified` and the exact
224
- * day/time the user selected.
219
+ * ON THE WAY OUT every `Date` of the request body is serialised as a naive local datetime string
220
+ * (`yyyy-MM-ddTHH:mm:ss`: no `Z`, no offset). `JSON.stringify` would otherwise call
221
+ * `Date.prototype.toJSON`, which emits a UTC instant: a date picked as 29/07/2026 00:00 in Rome
222
+ * (UTC+2) becomes `2026-07-28T22:00:00.000Z`, so the server stores the 28th — the classic
223
+ * "off by one day". Sending the wall-clock value instead makes System.Text.Json produce a
224
+ * `DateTime` with `Kind = Unspecified` and the exact day/time the user selected.
225
225
  *
226
- * This is the single serialisation boundary of the application: no call site has
227
- * to convert anything, and it also covers dates that lost a per-instance
228
- * `toJSON` along the way (e.g. after `structuredClone`).
226
+ * ON THE WAY BACK every ISO date string of the response body is read into a `Date`. Models declare
227
+ * `Date`, but `HttpClient` only runs `JSON.parse`, which has no notion of dates, so without this
228
+ * every one of those properties holds a `string` at runtime and the declared type is a promise
229
+ * nobody keeps. It goes unnoticed for a long time — the `date` pipe accepts strings and
230
+ * {@link DateFnsAdapter.deserialize} parses them for the datepickers — until somebody calls a
231
+ * method of `Date` on one and gets a `TypeError`, or writes `x.someDate = new Date(x.someDate)` to
232
+ * work around it one call site at a time.
229
233
  *
230
- * Register it explicitly in `provideHttpClient(withInterceptors([...]))`.
231
- * If you would rather have the library register it for you, use
232
- * {@link provideArsLocalDates} instead.
234
+ * With both halves here no call site has to convert anything, in either direction, and dates that
235
+ * lost a per-instance `toJSON` along the way (after a `structuredClone`, say) are covered too.
236
+ *
237
+ * Both halves are idempotent — a body already normalised holds no `Date`, a body already revived
238
+ * holds no ISO string — so registering this twice, or over a chain that has already converted,
239
+ * changes nothing.
240
+ *
241
+ * REGISTER IT FIRST in `withInterceptors([...])`. The first interceptor of the array is the first
242
+ * to see the request and the LAST to see the response, which is what this one wants in both
243
+ * directions: every other interceptor keeps seeing the body exactly as the server sent it.
244
+ *
245
+ * If you would rather have the library register it for you, use {@link provideArsLocalDates}.
233
246
  *
234
247
  * @example
235
248
  * provideHttpClient(withInterceptors([
@@ -254,24 +267,27 @@ declare const arsLocalDateInterceptor: HttpInterceptorFn;
254
267
  declare class ArsLocalDateInterceptor implements HttpInterceptor {
255
268
  private readonly timeZone;
256
269
  /**
257
- * Normalises the request body before handing it to the next handler.
270
+ * Normalises the dates of the request and revives those of the response.
258
271
  * @param req - The outgoing request.
259
272
  * @param next - The next handler in the chain.
273
+ * @returns The stream of events, with the dates of the response body revived.
260
274
  */
261
275
  intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
262
276
  static ɵfac: i0.ɵɵFactoryDeclaration<ArsLocalDateInterceptor, never>;
263
277
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
264
278
  }
265
279
  /**
266
- * Standalone providers for date serialisation towards the backend.
280
+ * Standalone providers for date conversion towards and from the backend.
267
281
  *
268
- * Registers {@link ArsLocalDateInterceptor} so that every `Date` in a request
269
- * body travels as a naive local datetime string instead of a UTC instant.
282
+ * Registers {@link ArsLocalDateInterceptor}, so that every `Date` of a request body travels as a
283
+ * naive local datetime string instead of a UTC instant, and every ISO date string of a response
284
+ * body comes back as the `Date` the model declares.
270
285
  *
271
286
  * IMPORTANT: the application MUST call `withInterceptorsFromDi()`, otherwise
272
287
  * these providers have no effect at all (no error is raised).
273
288
  *
274
289
  * @param timeZone - IANA timezone name (default: `Europe/Rome`).
290
+ * @returns The environment providers to add to the application configuration.
275
291
  *
276
292
  * @example
277
293
  * providers: [
@@ -280,63 +296,6 @@ declare class ArsLocalDateInterceptor implements HttpInterceptor {
280
296
  * ]
281
297
  */
282
298
  declare function provideArsLocalDates(timeZone?: string): EnvironmentProviders;
283
- /**
284
- * Functional interceptor that reads every ISO date string in a response body back into a `Date`.
285
- *
286
- * WHY: models declare `Date`, but `HttpClient` only runs `JSON.parse`, which has no notion of
287
- * dates, so without this every one of those properties holds a `string` at runtime and the declared
288
- * type is a promise nobody keeps. It goes unnoticed for a long time — Angular's `date` pipe accepts
289
- * strings and {@link DateFnsAdapter.deserialize} parses them for the datepickers — until somebody
290
- * calls a method of `Date` on one and gets a `TypeError`, or writes
291
- * `x.someDate = new Date(x.someDate)` to work around it one call site at a time.
292
- *
293
- * Together with {@link arsLocalDateInterceptor} it closes the serialisation boundary: no call site
294
- * has to convert anything, in either direction.
295
- *
296
- * NOT registered by {@link provideArsLocalDates}, on purpose: turning strings into Dates changes
297
- * what an application already reading those fields receives, so it stays opt-in and each
298
- * application decides when to take it. Register it explicitly, or use
299
- * {@link provideArsLocalDateResponses}.
300
- *
301
- * @example
302
- * provideHttpClient(withInterceptors([
303
- * arsLocalDateInterceptor,
304
- * arsLocalDateResponseInterceptor,
305
- * ]));
306
- */
307
- declare const arsLocalDateResponseInterceptor: HttpInterceptorFn;
308
- /**
309
- * Class-based twin of {@link arsLocalDateResponseInterceptor}, for the same reason
310
- * {@link ArsLocalDateInterceptor} exists: only a class can be contributed through
311
- * `HTTP_INTERCEPTORS` by an `EnvironmentProviders`.
312
- *
313
- * REQUIRES `withInterceptorsFromDi()` in the application's `provideHttpClient()`.
314
- */
315
- declare class ArsLocalDateResponseInterceptor implements HttpInterceptor {
316
- private readonly timeZone;
317
- /**
318
- * Revives the dates of the response before handing it to the caller.
319
- * @param req - The outgoing request.
320
- * @param next - The next handler in the chain.
321
- */
322
- intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
323
- static ɵfac: i0.ɵɵFactoryDeclaration<ArsLocalDateResponseInterceptor, never>;
324
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
325
- }
326
- /**
327
- * Standalone providers for date deserialisation coming back from the backend.
328
- *
329
- * Registers {@link ArsLocalDateResponseInterceptor}, the counterpart of
330
- * {@link provideArsLocalDates}. Kept separate because it is the half that changes what existing
331
- * code receives: an application whose models declare those fields as `string` has to be looked at
332
- * before switching it on.
333
- *
334
- * IMPORTANT: the application MUST call `withInterceptorsFromDi()`, otherwise these providers have
335
- * no effect at all (no error is raised).
336
- *
337
- * @param timeZone - IANA timezone name (default: `Europe/Rome`).
338
- */
339
- declare function provideArsLocalDateResponses(timeZone?: string): EnvironmentProviders;
340
299
  /**
341
300
  * Formats a date as a date-only ISO string (`yyyy-MM-dd`) using its wall-clock
342
301
  * calendar day in the given timezone. Use it for query-string parameters and for
@@ -358,4 +317,4 @@ declare function toLocalDateOnlyString(value?: Date | null, timeZone?: string):
358
317
  */
359
318
  declare function toLocalDateTimeString(value?: Date | null, timeZone?: string): string | undefined;
360
319
 
361
- export { ARS_TIME_ZONE, ArsLocalDateInterceptor, ArsLocalDateResponseInterceptor, DEFAULT_TIME_ZONE, DateFnsAdapter, MAT_DATE_FNS_FORMATS, arsLocalDateInterceptor, arsLocalDateResponseInterceptor, provideArsDateFns, provideArsLocalDateResponses, provideArsLocalDates, toLocalDateOnlyString, toLocalDateTimeString };
320
+ export { ARS_TIME_ZONE, ArsLocalDateInterceptor, DEFAULT_TIME_ZONE, DateFnsAdapter, MAT_DATE_FNS_FORMATS, arsLocalDateInterceptor, provideArsDateFns, provideArsLocalDates, toLocalDateOnlyString, toLocalDateTimeString };
@@ -332,6 +332,8 @@ declare class NavigationBarComponent {
332
332
  private readonly router;
333
333
  private readonly directionality;
334
334
  private readonly hostRef;
335
+ /** Used to schedule the post-render read that reveals a branch just expanded. */
336
+ private readonly injector;
335
337
  private readonly destroyRef;
336
338
  /** Flat list of destinations. Ignored when `sections` is provided. */
337
339
  readonly items: _angular_core.InputSignal<readonly NavigationItem[]>;
@@ -650,6 +652,24 @@ declare class NavigationBarComponent {
650
652
  * @returns `true` when a matching destination was found and focused.
651
653
  */
652
654
  focusItem(id: string): boolean;
655
+ /**
656
+ * Scrolls the list so that the destinations a branch has just revealed are visible.
657
+ *
658
+ * Opening a parent sitting near the bottom of the list adds its children BELOW the fold: the
659
+ * row answers the click, and nothing seems to happen. This scrolls to the end of the branch so
660
+ * the options show up where the user is already looking.
661
+ *
662
+ * The parent row is never pushed out of the top: when a branch is taller than the list, showing
663
+ * its end would cost the row that was clicked, so the scroll stops with the parent at the top
664
+ * edge and the branch runs off the bottom — the user reads it downwards from there.
665
+ *
666
+ * Only the wide variants expand inline; in the compact ones the children live in the floating
667
+ * panel and there is nothing to scroll.
668
+ *
669
+ * @param id - Identifier of the parent destination that has just been expanded.
670
+ * @returns void
671
+ */
672
+ private revealBranch;
653
673
  /**
654
674
  * Moves the compact-only destinations of a group into a synthesized overflow
655
675
  * destination appended at the end of the group.