@nxgt/material-core 0.1.1 → 0.3.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 (42) hide show
  1. package/README.md +178 -5
  2. package/dist/file-preview/describe-file.d.ts +30 -0
  3. package/dist/file-preview/describe-file.d.ts.map +1 -0
  4. package/dist/file-preview/file-kind.d.ts +41 -0
  5. package/dist/file-preview/file-kind.d.ts.map +1 -0
  6. package/dist/file-preview/index.d.ts +10 -0
  7. package/dist/file-preview/index.d.ts.map +1 -0
  8. package/dist/file-preview/index.js +260 -0
  9. package/dist/file-preview/index.js.map +13 -0
  10. package/dist/file-preview/safe-url.d.ts +22 -0
  11. package/dist/file-preview/safe-url.d.ts.map +1 -0
  12. package/dist/file-preview/text-preview.d.ts +32 -0
  13. package/dist/file-preview/text-preview.d.ts.map +1 -0
  14. package/dist/lib/date-range.d.ts +84 -0
  15. package/dist/lib/date-range.d.ts.map +1 -0
  16. package/dist/lib/date-range.js +105 -0
  17. package/dist/lib/date-range.js.map +10 -0
  18. package/dist/lib/format-file-size.d.ts +10 -0
  19. package/dist/lib/format-file-size.d.ts.map +1 -0
  20. package/dist/lib/format-file-size.js +17 -0
  21. package/dist/lib/format-file-size.js.map +10 -0
  22. package/dist/lib/slider-ticks.d.ts +7 -0
  23. package/dist/lib/slider-ticks.d.ts.map +1 -0
  24. package/dist/lib/slider-ticks.js +16 -0
  25. package/dist/lib/slider-ticks.js.map +10 -0
  26. package/dist/pdf-viewer/index.d.ts +1 -0
  27. package/dist/pdf-viewer/index.d.ts.map +1 -1
  28. package/dist/pdf-viewer/index.js +68 -33
  29. package/dist/pdf-viewer/index.js.map +6 -4
  30. package/dist/pdf-viewer/pdf-pin-page.d.ts +16 -0
  31. package/dist/pdf-viewer/pdf-pin-page.d.ts.map +1 -0
  32. package/dist/pdf-viewer/pdf-scroll-spy.d.ts +2 -8
  33. package/dist/pdf-viewer/pdf-scroll-spy.d.ts.map +1 -1
  34. package/dist/pdf-viewer/pdf-user-input.d.ts +7 -0
  35. package/dist/pdf-viewer/pdf-user-input.d.ts.map +1 -0
  36. package/dist/pdfkit-fonts/index.d.ts +61 -0
  37. package/dist/pdfkit-fonts/index.d.ts.map +1 -0
  38. package/dist/pdfkit-fonts/index.js +80 -0
  39. package/dist/pdfkit-fonts/index.js.map +10 -0
  40. package/docs/roadmap.md +12 -1
  41. package/docs/troubleshooting.md +65 -0
  42. package/package.json +33 -3
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Which URLs `FilePreview` lets reach a link's `href` or a media element's
3
+ * `src`. Pure: nothing runs at import.
4
+ */
5
+ /**
6
+ * `url` when it is safe to put in an `href` or a `src`, else `null`.
7
+ *
8
+ * Allowed: `http:` and `https:`, a relative URL (`/a.pdf`, `files/a.pdf`,
9
+ * `//host/a.pdf`, `?q`, `#x`), `blob:`, and a `data:` URL of an image, a
10
+ * video, an audio file, plain text, CSV, Markdown, JSON or a PDF. Refused:
11
+ * `javascript:`, `vbscript:`, a `data:` URL of anything else (HTML, for
12
+ * one), and every other scheme. What the browser ignores (spaces and
13
+ * control characters at the ends, tabs and newlines anywhere) is removed
14
+ * first, so it cannot hide a scheme.
15
+ */
16
+ export declare function safePreviewUrl(url: string | null | undefined): string | null;
17
+ /** A file given as a URL that `safePreviewUrl` refused. */
18
+ export declare class FilePreviewUnsafeUrlError extends Error {
19
+ name: string;
20
+ constructor();
21
+ }
22
+ //# sourceMappingURL=safe-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-url.d.ts","sourceRoot":"","sources":["../../src/file-preview/safe-url.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmB5E;AAED,2DAA2D;AAC3D,qBAAa,yBAA0B,SAAQ,KAAK;IAC1C,IAAI,SAA+B;;CAK5C"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A text file's beginning, read with a size cap, for `FilePreview`. Nothing
3
+ * runs at import: `fetch` and `TextDecoder` are reached only when
4
+ * `readTextPreview` is called.
5
+ */
6
+ /** How much of a text file `FilePreview` reads by default: 256 KB. */
7
+ export declare const TEXT_PREVIEW_MAX_BYTES: number;
8
+ /** A text file's first bytes, decoded, and whether there was more. */
9
+ export type TextPreview = {
10
+ text: string;
11
+ /** The file is longer than `maxBytes`; `text` is its beginning. */
12
+ truncated: boolean;
13
+ };
14
+ /** A URL that answered with an HTTP error. */
15
+ export declare class FilePreviewHttpError extends Error {
16
+ name: string;
17
+ readonly status: number;
18
+ constructor(url: string, status: number);
19
+ }
20
+ /**
21
+ * The first `maxBytes` of a `Blob` / `File`, or of what a URL answers, as
22
+ * text, decoded with the `charset` of the URL's `Content-Type` (or of the
23
+ * `Blob`'s `type`) when `TextDecoder` supports it, else as UTF-8. A URL is
24
+ * fetched, and stops downloading once past the cap; an HTTP error throws
25
+ * `FilePreviewHttpError`. Pass `signal` to abort: the promise then rejects
26
+ * with the signal's reason, also for a `Blob`.
27
+ */
28
+ export declare function readTextPreview(source: Blob | string, options?: {
29
+ maxBytes?: number;
30
+ signal?: AbortSignal;
31
+ }): Promise<TextPreview>;
32
+ //# sourceMappingURL=text-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-preview.d.ts","sourceRoot":"","sources":["../../src/file-preview/text-preview.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,QAAa,CAAC;AAEjD,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,8CAA8C;AAC9C,qBAAa,oBAAqB,SAAQ,KAAK;IACrC,IAAI,SAA0B;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIvC;AAiFD;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,IAAI,GAAG,MAAM,EACrB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACvD,OAAO,CAAC,WAAW,CAAC,CAatB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The pure half of both libraries' `DateRangeField`: the built-in presets'
3
+ * ranges, a preset's state against the field's rules and value, and the time
4
+ * of day on each end. Plain `Date` maths in the local time zone; nothing reads
5
+ * the clock unless you leave `now` out.
6
+ */
7
+ /** Both ends of a range, set. */
8
+ export type DayRange = {
9
+ from: Date;
10
+ to: Date;
11
+ };
12
+ /** A range being picked: `to` is unset until the second day is. */
13
+ export type PartialDayRange = {
14
+ from?: Date;
15
+ to?: Date;
16
+ };
17
+ /** The built-in presets, in the order a field lists them. */
18
+ export declare const DATE_RANGE_PRESET_IDS: readonly ["today", "yesterday", "last-7-days", "last-30-days", "this-month", "last-month", "this-year"];
19
+ export type DateRangePresetId = (typeof DATE_RANGE_PRESET_IDS)[number];
20
+ /**
21
+ * A preset of your own: its label, and its range or a function of "now"
22
+ * that returns one (called each time the list renders).
23
+ */
24
+ export type DateRangePreset = {
25
+ label: string;
26
+ range: DayRange | ((now: Date) => DayRange);
27
+ };
28
+ /** What a field's `presets` takes: a built-in id, or a preset of your own. */
29
+ export type DateRangePresetOption = DateRangePresetId | DateRangePreset;
30
+ /** What a day must not be: a rule of the field's, and its first and last day. */
31
+ export type DateRangeRules = {
32
+ isDayDisabled?: (day: Date) => boolean;
33
+ min?: Date;
34
+ max?: Date;
35
+ };
36
+ /**
37
+ * A built-in preset's range at `now`, both ends at the start of their day.
38
+ * The last N days end today and count it; this month and this year run from
39
+ * their first day to today; last month is the whole previous month.
40
+ */
41
+ export declare function presetRange(id: DateRangePresetId, now?: Date): DayRange;
42
+ /**
43
+ * A preset's range at `now`: a built-in id's, or yours (called with `now`).
44
+ * With `withTime`, a built-in range ends at 23:59 on its last day, so it
45
+ * covers that day; your own ranges keep the times you gave them.
46
+ */
47
+ export declare function resolvePresetRange(preset: DateRangePresetOption, now?: Date, { withTime }?: {
48
+ withTime?: boolean;
49
+ }): DayRange;
50
+ /** Whether two ranges cover the same days (times are not compared). */
51
+ export declare function isSameDayRange(a: PartialDayRange | undefined, b: PartialDayRange | undefined): boolean;
52
+ /**
53
+ * Whether a field cannot take `range`: its end comes before its start (a
54
+ * preset of your own with its ends reversed), it starts before `min`, ends
55
+ * after `max`, or either end is a day `isDayDisabled` rules out. The days
56
+ * between the ends are not checked, as the calendar lets a range span a
57
+ * disabled day.
58
+ */
59
+ export declare function isRangeDisabled(range: DayRange, rules?: DateRangeRules): boolean;
60
+ /**
61
+ * `day`'s date with `time`'s hours and minutes; the start of `day` without
62
+ * a `time`. Seconds and milliseconds are dropped.
63
+ */
64
+ export declare function withTimeOf(day: Date, time?: Date): Date;
65
+ /** `day` at 23:59, the end time a preset gets when the field shows times. */
66
+ export declare function endOfDayTime(day: Date): Date;
67
+ /**
68
+ * The range with its end no earlier than its start: an end before the start
69
+ * becomes the start (the same day and time). The field calls it after a time
70
+ * change, after a day pick (through `keepRangeTimes`) and after a preset
71
+ * pick; the only end that can come first is an earlier time on the start's
72
+ * day. A range missing an end, or already in order, is returned as it is. A
73
+ * preset with its ends reversed never reaches it: `isRangeDisabled` disables
74
+ * it.
75
+ */
76
+ export declare function clampRangeEnd<R extends PartialDayRange>(range: R): R;
77
+ /**
78
+ * Days picked on a calendar, with times: each end keeps the time `previous`
79
+ * had at the same end. An end that had none starts at 00:00 or ends at 23:59
80
+ * (`endOfDayTime`), as a built-in preset does, so the range covers its last
81
+ * day. The end is then clamped to the start (`clampRangeEnd`).
82
+ */
83
+ export declare function keepRangeTimes<R extends PartialDayRange>(next: R, previous?: PartialDayRange): R;
84
+ //# sourceMappingURL=date-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.d.ts","sourceRoot":"","sources":["../../src/lib/date-range.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iCAAiC;AACjC,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC;AAEhD,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,EAAE,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzD,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,yGAQxB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;CAC5C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAExE,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG;IAC5B,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC;IACvC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,IAAI,CAAC;CACX,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,WAAW,CAC1B,EAAE,EAAE,iBAAiB,EACrB,GAAG,GAAE,IAAiB,GACpB,QAAQ,CAyBV;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,qBAAqB,EAC7B,GAAG,GAAE,IAAiB,EACtB,EAAE,QAAgB,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/C,QAAQ,CAQV;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAC7B,CAAC,EAAE,eAAe,GAAG,SAAS,EAC9B,CAAC,EAAE,eAAe,GAAG,SAAS,WAI9B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAE,cAAmB,WAM1E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,QAIhD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,QAIrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAIpE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,eAAe,EACvD,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,eAAe,GACxB,CAAC,CAQH"}
@@ -0,0 +1,105 @@
1
+ // src/lib/date-range.ts
2
+ var DATE_RANGE_PRESET_IDS = [
3
+ "today",
4
+ "yesterday",
5
+ "last-7-days",
6
+ "last-30-days",
7
+ "this-month",
8
+ "last-month",
9
+ "this-year"
10
+ ];
11
+ function startOfDay(date) {
12
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
13
+ }
14
+ function addDays(date, days) {
15
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
16
+ }
17
+ function sameDay(a, b) {
18
+ return startOfDay(a).getTime() === startOfDay(b).getTime();
19
+ }
20
+ function presetRange(id, now = new Date) {
21
+ const today = startOfDay(now);
22
+ const year = today.getFullYear();
23
+ const month = today.getMonth();
24
+ switch (id) {
25
+ case "today":
26
+ return { from: today, to: today };
27
+ case "yesterday": {
28
+ const day = addDays(today, -1);
29
+ return { from: day, to: day };
30
+ }
31
+ case "last-7-days":
32
+ return { from: addDays(today, -6), to: today };
33
+ case "last-30-days":
34
+ return { from: addDays(today, -29), to: today };
35
+ case "this-month":
36
+ return { from: new Date(year, month, 1), to: today };
37
+ case "last-month":
38
+ return {
39
+ from: new Date(year, month - 1, 1),
40
+ to: new Date(year, month, 0)
41
+ };
42
+ case "this-year":
43
+ return { from: new Date(year, 0, 1), to: today };
44
+ }
45
+ }
46
+ function resolvePresetRange(preset, now = new Date, { withTime = false } = {}) {
47
+ if (typeof preset !== "string") {
48
+ return typeof preset.range === "function" ? preset.range(now) : preset.range;
49
+ }
50
+ const range = presetRange(preset, now);
51
+ return withTime ? { from: range.from, to: endOfDayTime(range.to) } : range;
52
+ }
53
+ function isSameDayRange(a, b) {
54
+ if (!a?.from || !a.to || !b?.from || !b.to)
55
+ return false;
56
+ return sameDay(a.from, b.from) && sameDay(a.to, b.to);
57
+ }
58
+ function isRangeDisabled(range, rules = {}) {
59
+ const { isDayDisabled, min, max } = rules;
60
+ if (range.to.getTime() < range.from.getTime())
61
+ return true;
62
+ if (min && startOfDay(range.from) < startOfDay(min))
63
+ return true;
64
+ if (max && startOfDay(range.to) > startOfDay(max))
65
+ return true;
66
+ return Boolean(isDayDisabled?.(range.from) || isDayDisabled?.(range.to));
67
+ }
68
+ function withTimeOf(day, time) {
69
+ const next = startOfDay(day);
70
+ if (time)
71
+ next.setHours(time.getHours(), time.getMinutes());
72
+ return next;
73
+ }
74
+ function endOfDayTime(day) {
75
+ const next = startOfDay(day);
76
+ next.setHours(23, 59);
77
+ return next;
78
+ }
79
+ function clampRangeEnd(range) {
80
+ const { from, to } = range;
81
+ if (!from || !to || to.getTime() >= from.getTime())
82
+ return range;
83
+ return { ...range, to: new Date(from) };
84
+ }
85
+ function keepRangeTimes(next, previous) {
86
+ return clampRangeEnd({
87
+ ...next,
88
+ from: next.from && withTimeOf(next.from, previous?.from),
89
+ to: next.to && (previous?.to ? withTimeOf(next.to, previous.to) : endOfDayTime(next.to))
90
+ });
91
+ }
92
+ export {
93
+ DATE_RANGE_PRESET_IDS,
94
+ clampRangeEnd,
95
+ endOfDayTime,
96
+ isRangeDisabled,
97
+ isSameDayRange,
98
+ keepRangeTimes,
99
+ presetRange,
100
+ resolvePresetRange,
101
+ withTimeOf
102
+ };
103
+
104
+ //# debugId=DE919010B55B550A64756E2164756E21
105
+ //# sourceMappingURL=date-range.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/date-range.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * The pure half of both libraries' `DateRangeField`: the built-in presets'\n * ranges, a preset's state against the field's rules and value, and the time\n * of day on each end. Plain `Date` maths in the local time zone; nothing reads\n * the clock unless you leave `now` out.\n */\n\n/** Both ends of a range, set. */\nexport type DayRange = { from: Date; to: Date };\n\n/** A range being picked: `to` is unset until the second day is. */\nexport type PartialDayRange = { from?: Date; to?: Date };\n\n/** The built-in presets, in the order a field lists them. */\nexport const DATE_RANGE_PRESET_IDS = [\n\t'today',\n\t'yesterday',\n\t'last-7-days',\n\t'last-30-days',\n\t'this-month',\n\t'last-month',\n\t'this-year',\n] as const;\n\nexport type DateRangePresetId = (typeof DATE_RANGE_PRESET_IDS)[number];\n\n/**\n * A preset of your own: its label, and its range or a function of \"now\"\n * that returns one (called each time the list renders).\n */\nexport type DateRangePreset = {\n\tlabel: string;\n\trange: DayRange | ((now: Date) => DayRange);\n};\n\n/** What a field's `presets` takes: a built-in id, or a preset of your own. */\nexport type DateRangePresetOption = DateRangePresetId | DateRangePreset;\n\n/** What a day must not be: a rule of the field's, and its first and last day. */\nexport type DateRangeRules = {\n\tisDayDisabled?: (day: Date) => boolean;\n\tmin?: Date;\n\tmax?: Date;\n};\n\nfunction startOfDay(date: Date) {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction addDays(date: Date, days: number) {\n\treturn new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\nfunction sameDay(a: Date, b: Date) {\n\treturn startOfDay(a).getTime() === startOfDay(b).getTime();\n}\n\n/**\n * A built-in preset's range at `now`, both ends at the start of their day.\n * The last N days end today and count it; this month and this year run from\n * their first day to today; last month is the whole previous month.\n */\nexport function presetRange(\n\tid: DateRangePresetId,\n\tnow: Date = new Date(),\n): DayRange {\n\tconst today = startOfDay(now);\n\tconst year = today.getFullYear();\n\tconst month = today.getMonth();\n\tswitch (id) {\n\t\tcase 'today':\n\t\t\treturn { from: today, to: today };\n\t\tcase 'yesterday': {\n\t\t\tconst day = addDays(today, -1);\n\t\t\treturn { from: day, to: day };\n\t\t}\n\t\tcase 'last-7-days':\n\t\t\treturn { from: addDays(today, -6), to: today };\n\t\tcase 'last-30-days':\n\t\t\treturn { from: addDays(today, -29), to: today };\n\t\tcase 'this-month':\n\t\t\treturn { from: new Date(year, month, 1), to: today };\n\t\tcase 'last-month':\n\t\t\treturn {\n\t\t\t\tfrom: new Date(year, month - 1, 1),\n\t\t\t\tto: new Date(year, month, 0),\n\t\t\t};\n\t\tcase 'this-year':\n\t\t\treturn { from: new Date(year, 0, 1), to: today };\n\t}\n}\n\n/**\n * A preset's range at `now`: a built-in id's, or yours (called with `now`).\n * With `withTime`, a built-in range ends at 23:59 on its last day, so it\n * covers that day; your own ranges keep the times you gave them.\n */\nexport function resolvePresetRange(\n\tpreset: DateRangePresetOption,\n\tnow: Date = new Date(),\n\t{ withTime = false }: { withTime?: boolean } = {},\n): DayRange {\n\tif (typeof preset !== 'string') {\n\t\treturn typeof preset.range === 'function'\n\t\t\t? preset.range(now)\n\t\t\t: preset.range;\n\t}\n\tconst range = presetRange(preset, now);\n\treturn withTime ? { from: range.from, to: endOfDayTime(range.to) } : range;\n}\n\n/** Whether two ranges cover the same days (times are not compared). */\nexport function isSameDayRange(\n\ta: PartialDayRange | undefined,\n\tb: PartialDayRange | undefined,\n) {\n\tif (!a?.from || !a.to || !b?.from || !b.to) return false;\n\treturn sameDay(a.from, b.from) && sameDay(a.to, b.to);\n}\n\n/**\n * Whether a field cannot take `range`: its end comes before its start (a\n * preset of your own with its ends reversed), it starts before `min`, ends\n * after `max`, or either end is a day `isDayDisabled` rules out. The days\n * between the ends are not checked, as the calendar lets a range span a\n * disabled day.\n */\nexport function isRangeDisabled(range: DayRange, rules: DateRangeRules = {}) {\n\tconst { isDayDisabled, min, max } = rules;\n\tif (range.to.getTime() < range.from.getTime()) return true;\n\tif (min && startOfDay(range.from) < startOfDay(min)) return true;\n\tif (max && startOfDay(range.to) > startOfDay(max)) return true;\n\treturn Boolean(isDayDisabled?.(range.from) || isDayDisabled?.(range.to));\n}\n\n/**\n * `day`'s date with `time`'s hours and minutes; the start of `day` without\n * a `time`. Seconds and milliseconds are dropped.\n */\nexport function withTimeOf(day: Date, time?: Date) {\n\tconst next = startOfDay(day);\n\tif (time) next.setHours(time.getHours(), time.getMinutes());\n\treturn next;\n}\n\n/** `day` at 23:59, the end time a preset gets when the field shows times. */\nexport function endOfDayTime(day: Date) {\n\tconst next = startOfDay(day);\n\tnext.setHours(23, 59);\n\treturn next;\n}\n\n/**\n * The range with its end no earlier than its start: an end before the start\n * becomes the start (the same day and time). The field calls it after a time\n * change, after a day pick (through `keepRangeTimes`) and after a preset\n * pick; the only end that can come first is an earlier time on the start's\n * day. A range missing an end, or already in order, is returned as it is. A\n * preset with its ends reversed never reaches it: `isRangeDisabled` disables\n * it.\n */\nexport function clampRangeEnd<R extends PartialDayRange>(range: R): R {\n\tconst { from, to } = range;\n\tif (!from || !to || to.getTime() >= from.getTime()) return range;\n\treturn { ...range, to: new Date(from) };\n}\n\n/**\n * Days picked on a calendar, with times: each end keeps the time `previous`\n * had at the same end. An end that had none starts at 00:00 or ends at 23:59\n * (`endOfDayTime`), as a built-in preset does, so the range covers its last\n * day. The end is then clamped to the start (`clampRangeEnd`).\n */\nexport function keepRangeTimes<R extends PartialDayRange>(\n\tnext: R,\n\tprevious?: PartialDayRange,\n): R {\n\treturn clampRangeEnd({\n\t\t...next,\n\t\tfrom: next.from && withTimeOf(next.from, previous?.from),\n\t\tto:\n\t\t\tnext.to &&\n\t\t\t(previous?.to ? withTimeOf(next.to, previous.to) : endOfDayTime(next.to)),\n\t});\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "DE919010B55B550A64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A byte count as people read it: `'512 B'`, `'1.5 KB'`, `'2.0 MB'`,
3
+ * `'1.0 GB'` (1024-based, one decimal above bytes, capped at GB), and `''`
4
+ * for a negative, `NaN` or infinite size. Locale-free, so a server and a
5
+ * browser print the same thing. The file list, the upload field and its
6
+ * constraints, the file card and the chat attachment chip of both libraries
7
+ * use it.
8
+ */
9
+ export declare function formatFileSize(bytes: number): string;
10
+ //# sourceMappingURL=format-file-size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-file-size.d.ts","sourceRoot":"","sources":["../../src/lib/format-file-size.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUpD"}
@@ -0,0 +1,17 @@
1
+ // src/lib/format-file-size.ts
2
+ function formatFileSize(bytes) {
3
+ if (bytes < 0 || !Number.isFinite(bytes))
4
+ return "";
5
+ if (bytes === 0)
6
+ return "0 B";
7
+ const units = ["B", "KB", "MB", "GB"];
8
+ const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
9
+ const value = bytes / 1024 ** exponent;
10
+ return `${exponent === 0 ? value : value.toFixed(1)} ${units[exponent]}`;
11
+ }
12
+ export {
13
+ formatFileSize
14
+ };
15
+
16
+ //# debugId=5CC787DB991D0F4A64756E2164756E21
17
+ //# sourceMappingURL=format-file-size.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/format-file-size.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * A byte count as people read it: `'512 B'`, `'1.5 KB'`, `'2.0 MB'`,\n * `'1.0 GB'` (1024-based, one decimal above bytes, capped at GB), and `''`\n * for a negative, `NaN` or infinite size. Locale-free, so a server and a\n * browser print the same thing. The file list, the upload field and its\n * constraints, the file card and the chat attachment chip of both libraries\n * use it.\n */\nexport function formatFileSize(bytes: number): string {\n\tif (bytes < 0 || !Number.isFinite(bytes)) return '';\n\tif (bytes === 0) return '0 B';\n\tconst units = ['B', 'KB', 'MB', 'GB'];\n\tconst exponent = Math.min(\n\t\tMath.floor(Math.log(bytes) / Math.log(1024)),\n\t\tunits.length - 1,\n\t);\n\tconst value = bytes / 1024 ** exponent;\n\treturn `${exponent === 0 ? value : value.toFixed(1)} ${units[exponent]}`;\n}\n"
6
+ ],
7
+ "mappings": ";AAQO,SAAS,cAAc,CAAC,OAAuB;AAAA,EACrD,IAAI,QAAQ,KAAK,CAAC,OAAO,SAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EACjD,IAAI,UAAU;AAAA,IAAG,OAAO;AAAA,EACxB,MAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AAAA,EACpC,MAAM,WAAW,KAAK,IACrB,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC,GAC3C,MAAM,SAAS,CAChB;AAAA,EACA,MAAM,QAAQ,QAAQ,QAAQ;AAAA,EAC9B,OAAO,GAAG,aAAa,IAAI,QAAQ,MAAM,QAAQ,CAAC,KAAK,MAAM;AAAA;",
8
+ "debugId": "5CC787DB991D0F4A64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The values a slider's tick marks sit at, from `min` to `max` inclusive:
3
+ * `false` none, a number that many, `true` one per `step` (or 5 without one).
4
+ * Always 2 to 21 marks, evenly spaced; one when `min` and `max` are equal.
5
+ */
6
+ export declare function tickValues(min: number, max: number, ticks: boolean | number, step?: number): number[];
7
+ //# sourceMappingURL=slider-ticks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider-ticks.d.ts","sourceRoot":"","sources":["../../src/lib/slider-ticks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GAAG,MAAM,EACvB,IAAI,CAAC,EAAE,MAAM,YAeb"}
@@ -0,0 +1,16 @@
1
+ // src/lib/slider-ticks.ts
2
+ function tickValues(min, max, ticks, step) {
3
+ if (ticks === false)
4
+ return [];
5
+ let count = typeof ticks === "number" ? ticks : step && step > 0 ? Math.round((max - min) / step) + 1 : 5;
6
+ count = Math.min(Math.max(Math.round(count), 2), 21);
7
+ if (max === min)
8
+ return [min];
9
+ return Array.from({ length: count }, (_, index) => min + (max - min) * index / (count - 1));
10
+ }
11
+ export {
12
+ tickValues
13
+ };
14
+
15
+ //# debugId=68EBFB8D67762FE364756E2164756E21
16
+ //# sourceMappingURL=slider-ticks.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib/slider-ticks.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * The values a slider's tick marks sit at, from `min` to `max` inclusive:\n * `false` none, a number that many, `true` one per `step` (or 5 without one).\n * Always 2 to 21 marks, evenly spaced; one when `min` and `max` are equal.\n */\nexport function tickValues(\n\tmin: number,\n\tmax: number,\n\tticks: boolean | number,\n\tstep?: number,\n) {\n\tif (ticks === false) return [];\n\tlet count =\n\t\ttypeof ticks === 'number'\n\t\t\t? ticks\n\t\t\t: step && step > 0\n\t\t\t\t? Math.round((max - min) / step) + 1\n\t\t\t\t: 5;\n\tcount = Math.min(Math.max(Math.round(count), 2), 21);\n\tif (max === min) return [min];\n\treturn Array.from(\n\t\t{ length: count },\n\t\t(_, index) => min + ((max - min) * index) / (count - 1),\n\t);\n}\n"
6
+ ],
7
+ "mappings": ";AAKO,SAAS,UAAU,CACzB,KACA,KACA,OACA,MACC;AAAA,EACD,IAAI,UAAU;AAAA,IAAO,OAAO,CAAC;AAAA,EAC7B,IAAI,QACH,OAAO,UAAU,WACd,QACA,QAAQ,OAAO,IACd,KAAK,OAAO,MAAM,OAAO,IAAI,IAAI,IACjC;AAAA,EACL,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;AAAA,EACnD,IAAI,QAAQ;AAAA,IAAK,OAAO,CAAC,GAAG;AAAA,EAC5B,OAAO,MAAM,KACZ,EAAE,QAAQ,MAAM,GAChB,CAAC,GAAG,UAAU,OAAQ,MAAM,OAAO,SAAU,QAAQ,EACtD;AAAA;",
8
+ "debugId": "68EBFB8D67762FE364756E2164756E21",
9
+ "names": []
10
+ }
@@ -9,6 +9,7 @@ export * from './pdf-document-search';
9
9
  export * from './pdf-escape';
10
10
  export * from './pdf-page-geometry';
11
11
  export * from './pdf-page-sizes';
12
+ export * from './pdf-pin-page';
12
13
  export * from './pdf-scroll-spy';
13
14
  export * from './pdf-text-search';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pdf-viewer/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pdf-viewer/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
@@ -215,6 +215,24 @@ function createPageSizesLoader(onSizes) {
215
215
  }
216
216
  };
217
217
  }
218
+ // src/pdf-viewer/pdf-user-input.ts
219
+ var USER_SCROLL_EVENTS = [
220
+ "wheel",
221
+ "touchstart",
222
+ "pointerdown",
223
+ "keydown"
224
+ ];
225
+ function listenForUserInput(target, run) {
226
+ for (const type of USER_SCROLL_EVENTS) {
227
+ target.addEventListener(type, run, { capture: true, passive: true });
228
+ }
229
+ return () => {
230
+ for (const type of USER_SCROLL_EVENTS) {
231
+ target.removeEventListener(type, run, { capture: true });
232
+ }
233
+ };
234
+ }
235
+
218
236
  // src/pdf-viewer/pdf-scroll-spy.ts
219
237
  function mostVisiblePage(view, pages) {
220
238
  let best = null;
@@ -244,38 +262,6 @@ function scrollIntoArea(node, block, behavior = "smooth") {
244
262
  top -= (view.height - box.height) / 2;
245
263
  area.scrollTo({ top: Math.max(0, top), behavior });
246
264
  }
247
- var USER_SCROLL_EVENTS = [
248
- "wheel",
249
- "touchstart",
250
- "pointerdown",
251
- "keydown"
252
- ];
253
- function pinToPage(node, beforeScroll) {
254
- const area = node()?.closest('[data-slot="scroll-area-viewport"]');
255
- const content = area?.firstElementChild;
256
- if (!area || !content || typeof ResizeObserver === "undefined") {
257
- return () => {};
258
- }
259
- const surface = area.closest('[data-slot="scroll-area"]') ?? area;
260
- const observer = new ResizeObserver(() => {
261
- const target = node();
262
- if (!target)
263
- return;
264
- beforeScroll();
265
- scrollIntoArea(target, "start", "auto");
266
- });
267
- observer.observe(content);
268
- const unpin = () => {
269
- observer.disconnect();
270
- for (const type of USER_SCROLL_EVENTS) {
271
- surface.removeEventListener(type, unpin, true);
272
- }
273
- };
274
- for (const type of USER_SCROLL_EVENTS) {
275
- surface.addEventListener(type, unpin, { capture: true, passive: true });
276
- }
277
- return unpin;
278
- }
279
265
  function createScrollSpy(root, pages, onPage, idleMs = 150) {
280
266
  let frame = 0;
281
267
  let held = false;
@@ -313,10 +299,18 @@ function createScrollSpy(root, pages, onPage, idleMs = 150) {
313
299
  if (!frame)
314
300
  frame = requestAnimationFrame(measure);
315
301
  };
302
+ const onUserInput = (event) => {
303
+ const target = event.target;
304
+ if (!target || !root()?.contains(target))
305
+ return;
306
+ held = false;
307
+ clearTimeout(idle);
308
+ };
316
309
  document.addEventListener("scroll", onScroll, {
317
310
  capture: true,
318
311
  passive: true
319
312
  });
313
+ const stopInput = listenForUserInput(document, onUserInput);
320
314
  return {
321
315
  hold() {
322
316
  held = true;
@@ -326,6 +320,7 @@ function createScrollSpy(root, pages, onPage, idleMs = 150) {
326
320
  },
327
321
  stop() {
328
322
  document.removeEventListener("scroll", onScroll, { capture: true });
323
+ stopInput();
329
324
  cancelAnimationFrame(frame);
330
325
  clearTimeout(idle);
331
326
  }
@@ -347,6 +342,45 @@ function revealHit(findPage, hit, beforeScroll = () => {}, timeout = 5000) {
347
342
  frame = requestAnimationFrame(look);
348
343
  return () => cancelAnimationFrame(frame);
349
344
  }
345
+
346
+ // src/pdf-viewer/pdf-pin-page.ts
347
+ var VIEWPORT = '[data-slot="scroll-area-viewport"]';
348
+ function pinToPage(node, beforeScroll, onRelease = () => {}) {
349
+ const area = node()?.closest(VIEWPORT);
350
+ const content = area?.firstElementChild;
351
+ if (!area || !content || typeof ResizeObserver === "undefined") {
352
+ onRelease();
353
+ return () => {};
354
+ }
355
+ const surface = area.closest('[data-slot="scroll-area"]') ?? area;
356
+ const observer = new ResizeObserver(() => {
357
+ const target = node();
358
+ if (!target)
359
+ return;
360
+ beforeScroll();
361
+ scrollIntoArea(target, "start", "auto");
362
+ });
363
+ observer.observe(content);
364
+ let pinned = true;
365
+ const unpin = () => {
366
+ if (!pinned)
367
+ return;
368
+ pinned = false;
369
+ observer.disconnect();
370
+ stopListening();
371
+ onRelease();
372
+ };
373
+ const stopListening = listenForUserInput(surface, unpin);
374
+ return unpin;
375
+ }
376
+ function pinHolds(node) {
377
+ const area = node?.closest(VIEWPORT);
378
+ if (!node || !area)
379
+ return false;
380
+ const atEnd = area.scrollTop + area.clientHeight >= area.scrollHeight - 2;
381
+ const offset = node.getBoundingClientRect().top - area.getBoundingClientRect().top;
382
+ return atEnd && offset >= -2 || Math.abs(offset) <= 2;
383
+ }
350
384
  export {
351
385
  DEFAULT_PAGE_SIZE,
352
386
  FIT_PAGES,
@@ -364,6 +398,7 @@ export {
364
398
  mostVisiblePage,
365
399
  pageRotation,
366
400
  pageTextFromItems,
401
+ pinHolds,
367
402
  pinToPage,
368
403
  placeholderSize,
369
404
  readPageSizes,
@@ -376,5 +411,5 @@ export {
376
411
  withPageMatches
377
412
  };
378
413
 
379
- //# debugId=5A356F61366FB1EB64756E2164756E21
414
+ //# debugId=71863DCA45A690D164756E2164756E21
380
415
  //# sourceMappingURL=index.js.map