@oardi/ts-utils 0.0.21 → 0.0.22

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 (95) hide show
  1. package/extensions/array-extension.d.ts +13 -0
  2. package/extensions/array-extension.d.ts.map +1 -0
  3. package/extensions/date-extension.d.ts +18 -0
  4. package/extensions/date-extension.d.ts.map +1 -0
  5. package/extensions/{index.ts → index.d.ts} +1 -0
  6. package/extensions/index.d.ts.map +1 -0
  7. package/extensions/string-extensions.d.ts +9 -0
  8. package/extensions/string-extensions.d.ts.map +1 -0
  9. package/helpers/browser/browser-type.enum.d.ts +14 -0
  10. package/helpers/browser/browser-type.enum.d.ts.map +1 -0
  11. package/helpers/browser/browser.helper.d.ts +16 -0
  12. package/helpers/browser/browser.helper.d.ts.map +1 -0
  13. package/helpers/browser/{index.ts → index.d.ts} +1 -0
  14. package/helpers/browser/index.d.ts.map +1 -0
  15. package/helpers/clipboard.helper.d.ts +2 -0
  16. package/helpers/clipboard.helper.d.ts.map +1 -0
  17. package/helpers/csv.helper.d.ts +6 -0
  18. package/helpers/csv.helper.d.ts.map +1 -0
  19. package/helpers/download.helper.d.ts +14 -0
  20. package/helpers/download.helper.d.ts.map +1 -0
  21. package/helpers/enum.helper.d.ts +6 -0
  22. package/helpers/enum.helper.d.ts.map +1 -0
  23. package/helpers/file.helper.d.ts +16 -0
  24. package/helpers/file.helper.d.ts.map +1 -0
  25. package/helpers/{index.ts → index.d.ts} +1 -0
  26. package/helpers/index.d.ts.map +1 -0
  27. package/helpers/local-storage.helper.d.ts +8 -0
  28. package/helpers/local-storage.helper.d.ts.map +1 -0
  29. package/helpers/logger/index.d.ts +4 -0
  30. package/helpers/logger/index.d.ts.map +1 -0
  31. package/helpers/logger/logger-type.enum.d.ts +8 -0
  32. package/helpers/logger/logger-type.enum.d.ts.map +1 -0
  33. package/helpers/logger/logger.helper.d.ts +15 -0
  34. package/helpers/logger/logger.helper.d.ts.map +1 -0
  35. package/helpers/logger/{logger.types.ts → logger.types.d.ts} +4 -5
  36. package/helpers/logger/logger.types.d.ts.map +1 -0
  37. package/helpers/sort.helper.d.ts +2 -0
  38. package/helpers/sort.helper.d.ts.map +1 -0
  39. package/helpers/token/{index.ts → index.d.ts} +1 -0
  40. package/helpers/token/index.d.ts.map +1 -0
  41. package/helpers/token/{token-type.enum.ts → token-type.enum.d.ts} +1 -0
  42. package/helpers/token/token-type.enum.d.ts.map +1 -0
  43. package/helpers/token/token.helper.d.ts +7 -0
  44. package/helpers/token/token.helper.d.ts.map +1 -0
  45. package/index.cjs.js +15 -0
  46. package/{index.ts → index.d.ts} +1 -0
  47. package/index.d.ts.map +1 -0
  48. package/index.es.js +1126 -0
  49. package/index.umd.js +15 -0
  50. package/interfaces/{index.ts → index.d.ts} +1 -0
  51. package/interfaces/index.d.ts.map +1 -0
  52. package/interfaces/keyvalue.interface.d.ts +5 -0
  53. package/interfaces/keyvalue.interface.d.ts.map +1 -0
  54. package/package.json +1 -1
  55. package/readme.md +15 -0
  56. package/services/browser/browser.consts.d.ts +3 -0
  57. package/services/browser/browser.consts.d.ts.map +1 -0
  58. package/services/browser/browser.interface.d.ts +6 -0
  59. package/services/browser/browser.interface.d.ts.map +1 -0
  60. package/services/browser/browser.service.d.ts +30 -0
  61. package/services/browser/browser.service.d.ts.map +1 -0
  62. package/services/browser/{browser.types.ts → browser.types.d.ts} +1 -1
  63. package/services/browser/browser.types.d.ts.map +1 -0
  64. package/services/browser/{index.ts → index.d.ts} +1 -0
  65. package/services/browser/index.d.ts.map +1 -0
  66. package/services/index.d.ts +2 -0
  67. package/services/index.d.ts.map +1 -0
  68. package/types/index.d.ts +9 -0
  69. package/types/index.d.ts.map +1 -0
  70. package/vite.config.d.ts +3 -0
  71. package/vite.config.d.ts.map +1 -0
  72. package/extensions/array-extension.ts +0 -54
  73. package/extensions/date-extension.ts +0 -69
  74. package/extensions/string-extensions.ts +0 -21
  75. package/helpers/browser/browser-type.enum.ts +0 -13
  76. package/helpers/browser/browser.helper.ts +0 -95
  77. package/helpers/clipboard.helper.ts +0 -3
  78. package/helpers/csv.helper.ts +0 -23
  79. package/helpers/download.helper.ts +0 -127
  80. package/helpers/enum.helper.ts +0 -20
  81. package/helpers/file.helper.ts +0 -105
  82. package/helpers/local-storage.helper.ts +0 -30
  83. package/helpers/logger/index.ts +0 -1
  84. package/helpers/logger/logger-type.enum.ts +0 -7
  85. package/helpers/logger/logger.helper.ts +0 -63
  86. package/helpers/sort.helper.ts +0 -33
  87. package/helpers/token/token.helper.ts +0 -16
  88. package/interfaces/keyvalue.interface.ts +0 -7
  89. package/services/browser/browser.consts.ts +0 -11
  90. package/services/browser/browser.interface.ts +0 -6
  91. package/services/browser/browser.service.ts +0 -119
  92. package/services/index.ts +0 -1
  93. package/tsconfig.json +0 -33
  94. package/types/index.ts +0 -11
  95. package/vite.config.ts +0 -21
@@ -1,127 +0,0 @@
1
- export type SaveSource = Blob | ArrayBuffer | Uint8Array | string;
2
-
3
- export interface SaveOptions {
4
- mimeType?: string; /** MIME-Type, falls `source` kein Blob ist (z. B. "application/pdf") */
5
- showSaveFilePicker?: boolean;
6
- }
7
-
8
- /**
9
- * save file on client
10
- *
11
- * 1) File System Access API (showSaveFilePicker) – if supported
12
- * 2) Fallback: <a download> + blob: URL
13
- * 3) iOS-/Safari-Fallback: open new Tab if download-attribute is being ignored
14
- */
15
- export async function saveAs(source: SaveSource, fileName: string, options?: SaveOptions): Promise<void> {
16
- const mime: string = options?.mimeType ?? guessMimeFromFilename(fileName);
17
- const blob: Blob = ensureBlob(source, mime);
18
-
19
- // 1) experimental - feature check
20
- if ('showSaveFilePicker' in window && options?.showSaveFilePicker) {
21
- try {
22
- const handle: FileSystemFileHandle = await (
23
- window as unknown as {
24
- showSaveFilePicker: (opts: {
25
- suggestedName?: string;
26
- types?: { description?: string; accept: Record<string, string[]> }[];
27
- }) => Promise<FileSystemFileHandle>;
28
- }
29
- ).showSaveFilePicker({
30
- suggestedName: fileName,
31
- types: [{ description: 'Datei', accept: { [mime]: [`.${extOf(fileName)}`] } }],
32
- });
33
-
34
- const writable: FileSystemWritableFileStream = await handle.createWritable();
35
- await writable.write(blob);
36
- await writable.close();
37
- return;
38
- } catch (err) {
39
- // Abbruch durch Nutzer oder fehlende Berechtigung -> auf Fallback gehen
40
- // (keine Early-Return mitten in der Funktion – wir laufen weiter)
41
- }
42
- }
43
-
44
- // 2) classic: <a download> + blob: URL
45
- const url: string = URL.createObjectURL(blob);
46
-
47
- // In iOS Safari kann `download` für blob:-URLs ignoriert werden.
48
- // Wir versuchen es zuerst regulär, und fallbacken dann auf "neuen Tab öffnen".
49
- const anchor: HTMLAnchorElement = document.createElement('a');
50
- anchor.href = url;
51
- anchor.download = fileName;
52
- anchor.rel = 'noopener'; // gute Praxis
53
- anchor.style.display = 'none';
54
- document.body.appendChild(anchor);
55
-
56
- triggerClick(anchor);
57
-
58
- // Kurzer Delay, dann Cleanup + optionaler iOS-Fallback
59
- window.setTimeout(() => {
60
- document.body.removeChild(anchor);
61
- URL.revokeObjectURL(url);
62
- }, 0);
63
-
64
- // Heuristik: Wenn Safari das download-Attribut ignoriert, bleibt häufig dieselbe Seite,
65
- // ohne dass ein Download-Dialog erscheint. Wir bieten dann eine Sicht-Alternative an.
66
- // (Bewusst defensiv: wir öffnen nur, wenn `download` potenziell ignoriert wird.)
67
- if (isProbablyIOSorOldSafari()) {
68
- // Öffnet die Ressource in einem neuen Tab, damit der Nutzer manuell speichern kann.
69
- // (Für PDFs & Bilder oft ausreichend; für Binärdateien hilft korrekter MIME-Type.)
70
- window.open(url, '_blank', 'noopener,noreferrer');
71
- }
72
- }
73
-
74
- function ensureBlob(source: SaveSource, mime: string): Blob {
75
- if (source instanceof Blob) {
76
- return source.type ? source : new Blob([source], { type: mime });
77
- }
78
- if (source instanceof ArrayBuffer || source instanceof Uint8Array) {
79
- const buf: Uint8Array<ArrayBufferLike> = source instanceof Uint8Array ? source : new Uint8Array(source);
80
- return new Blob([buf as BlobPart], { type: mime });
81
- }
82
- // string -> als Text-BLOB speichern
83
- return new Blob([source], { type: mime || 'text/plain;charset=utf-8' });
84
- }
85
-
86
- function guessMimeFromFilename(filename: string): string {
87
- const ext: string = extOf(filename).toLowerCase();
88
- switch (ext) {
89
- case 'txt':
90
- return 'text/plain;charset=utf-8';
91
- case 'csv':
92
- return 'text/csv;charset=utf-8';
93
- case 'json':
94
- return 'application/json;charset=utf-8';
95
- case 'pdf':
96
- return 'application/pdf';
97
- case 'png':
98
- return 'image/png';
99
- case 'jpg':
100
- case 'jpeg':
101
- return 'image/jpeg';
102
- case 'svg':
103
- return 'image/svg+xml';
104
- case 'zip':
105
- return 'application/zip';
106
- default:
107
- return 'application/octet-stream';
108
- }
109
- }
110
-
111
- function extOf(filename: string): string {
112
- const idx: number = filename.lastIndexOf('.');
113
- return idx >= 0 && idx < filename.length - 1 ? filename.slice(idx + 1) : '';
114
- }
115
-
116
- function triggerClick(el: HTMLElement): void {
117
- const evt: MouseEvent = document.createEvent('MouseEvents');
118
- evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
119
- el.dispatchEvent(evt);
120
- }
121
-
122
- function isProbablyIOSorOldSafari(): boolean {
123
- const userAgent: string = navigator.userAgent;
124
- const isIOS: boolean = /iPad|iPhone|iPod/.test(userAgent);
125
- const isSafari: boolean = /^((?!chrome|android).)*safari/i.test(userAgent);
126
- return isIOS || isSafari;
127
- }
@@ -1,20 +0,0 @@
1
- import { IKeyValue } from '../interfaces/keyvalue.interface';
2
-
3
- export class EnumHelper {
4
- static getEnumValue<T extends object>(enumObj: T, key: string): T[keyof T] {
5
- if (!(key in enumObj)) {
6
- throw Error(`${key} not found in ${enumObj}`);
7
- } else {
8
- return enumObj[key as keyof T];
9
- }
10
- }
11
-
12
- static getKeyValues<T extends object>(enumObj: T): IKeyValue<string>[] {
13
- return Object.keys(enumObj)
14
- .filter(key => !isNaN(Number(key)))
15
- .map(key => ({
16
- key: Number(key),
17
- value: enumObj[key as unknown as keyof T] as string,
18
- }));
19
- }
20
- }
@@ -1,105 +0,0 @@
1
- import { saveAs } from './download.helper';
2
-
3
- export class FileHelper {
4
- static getFileExtension(filename: string): string {
5
- let result: string = '';
6
- const index: number = filename.lastIndexOf('.');
7
- const hasExtension: boolean = index > 0 && index < filename.length - 1; // index > 0 verhindert z.B.: ".bashrc" als Extension
8
- if (hasExtension) {
9
- const ext: string = filename.substring(index + 1);
10
- result = `.${ext.toLowerCase()}`;
11
- }
12
- return result;
13
- }
14
-
15
- /**
16
- * read content from a file or blob
17
- */
18
- static readAsText(file: File): Promise<string> {
19
- const fileReader: FileReader = new FileReader();
20
- return new Promise((resolve, reject) => {
21
- fileReader.onload = (): void => {
22
- fileReader.onload = null;
23
- fileReader.onerror = null;
24
- if (typeof fileReader.result === 'string') {
25
- resolve(fileReader.result);
26
- } else {
27
- reject(new Error('Unexpected result type'));
28
- }
29
- };
30
- fileReader.onerror = (): void => {
31
- const error = fileReader.error ?? new Error('FileReader error');
32
- fileReader.onload = null;
33
- fileReader.onerror = null;
34
- reject(error);
35
- };
36
- fileReader.readAsText(file);
37
- });
38
- }
39
-
40
- static readAsArrayBuffer(file: File): Promise<ArrayBuffer> {
41
- const fileReader: FileReader = new FileReader();
42
- return new Promise((resolve, reject) => {
43
- fileReader.onload = (): void => {
44
- fileReader.onload = null;
45
- fileReader.onerror = null;
46
- if (fileReader.result instanceof ArrayBuffer) {
47
- resolve(fileReader.result);
48
- } else {
49
- reject(new Error('Unexpected result type'));
50
- }
51
- };
52
- fileReader.onerror = (): void => {
53
- const error = fileReader.error ?? new Error('FileReader error');
54
- fileReader.onload = null;
55
- fileReader.onerror = null;
56
- reject(error);
57
- };
58
- fileReader.readAsArrayBuffer(file);
59
- });
60
- }
61
-
62
- static readAsDataUrl(file: File): Promise<ProgressEvent<FileReader>> {
63
- const reader: FileReader = new FileReader();
64
- return new Promise((resolve, reject) => {
65
- reader.onload = (event: ProgressEvent<FileReader>): void => {
66
- resolve(event);
67
- };
68
- reader.onerror = (error): void => reject(error);
69
- reader.readAsDataURL(file);
70
- });
71
- }
72
-
73
- /** usage:
74
- * const file = new File(['Hello'], 'test.txt');
75
- * FileHelper.formatFileSize(file.size);
76
- * */
77
- static formatFileSize(bytes: number, decimals: number = 2, unit?: 'Bytes' | 'KB' | 'MB' | 'GB' | 'TB'): string {
78
- if (bytes === 0) {
79
- return '0 Bytes';
80
- }
81
-
82
- const k = 1024;
83
- const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
84
-
85
- let i = Math.floor(Math.log(bytes) / Math.log(k));
86
-
87
- if (unit && sizes.includes(unit)) {
88
- i = sizes.indexOf(unit);
89
- }
90
-
91
- const value = bytes / Math.pow(k, i);
92
- const fixed = parseFloat(value.toFixed(decimals));
93
-
94
- return `${fixed} ${sizes[i]}`;
95
- }
96
-
97
- static save(content: BlobPart, fileName: string, fileType: string): void {
98
- const blob: Blob = new Blob([content], { type: fileType });
99
- saveAs(blob, fileName);
100
- }
101
- }
102
-
103
- // usage
104
- // const extension: string = FileHelper.getFileExtension('asdf.txt');
105
- // -> .txt
@@ -1,30 +0,0 @@
1
- export class LocalStorageHelper {
2
- static set<T>(key: string, value: T): void {
3
- localStorage.setItem(key, JSON.stringify(value));
4
- }
5
-
6
- static get<T>(key: string): Nullable<T> {
7
- let result: Nullable<T> = null;
8
- const local: Nullable<string> = localStorage.getItem(key);
9
- if (local) {
10
- result = JSON.parse(local);
11
- }
12
- return result;
13
- }
14
-
15
- static remove(key: string): boolean {
16
- let result: boolean = !!LocalStorageHelper.get(key);
17
- if (result) {
18
- localStorage.removeItem(key);
19
- }
20
- return result;
21
- }
22
-
23
- static removeAll(): void {
24
- localStorage.clear();
25
- }
26
-
27
- static getKeysBy(key: string): string[] {
28
- return Object.keys(localStorage).filter(k => k.startsWith(key));
29
- }
30
- }
@@ -1 +0,0 @@
1
- export * from './logger.helper';
@@ -1,7 +0,0 @@
1
- export enum LoggerType {
2
- log = 'log',
3
- info = 'info',
4
- warn = 'warn',
5
- debug = 'debug',
6
- error = 'error',
7
- }
@@ -1,63 +0,0 @@
1
- import { LoggerType } from './logger-type.enum';
2
- import { LoggerListener, LoggerPayload } from './logger.types';
3
-
4
- export class LoggerHelper {
5
- private static listeners: Set<LoggerListener> = new Set();
6
-
7
- public static log(...args: unknown[]): void {
8
- LoggerHelper.doLog(LoggerType.log, args);
9
- }
10
-
11
- public static info(...args: unknown[]): void {
12
- LoggerHelper.doLog(LoggerType.info, args);
13
- }
14
-
15
- public static warn(...args: unknown[]): void {
16
- LoggerHelper.doLog(LoggerType.warn, args);
17
- }
18
-
19
- public static debug(...args: unknown[]): void {
20
- LoggerHelper.doLog(LoggerType.debug, args);
21
- }
22
-
23
- public static error(...args: unknown[]): void {
24
- LoggerHelper.doLog(LoggerType.error, args);
25
- }
26
-
27
- private static doLog(level: LoggerType, args: unknown[]): void {
28
- const payload: LoggerPayload = {
29
- type: level,
30
- args,
31
- timestamp: new Date().toISOString(),
32
- };
33
- for (const listener of LoggerHelper.listeners) {
34
- try {
35
- const res = listener(payload);
36
- if (res === false) {
37
- return; // cancelled by listener
38
- }
39
- } catch {
40
- // swallow listener errors so logging never breaks the app
41
- }
42
- }
43
-
44
- (console as Console)[level].apply(console, args);
45
- }
46
-
47
- public static onLog(listener: LoggerListener, once = false): () => void {
48
- if (once) {
49
- const wrapper: LoggerListener = (payload) => {
50
- try {
51
- return listener(payload);
52
- } finally {
53
- LoggerHelper.listeners.delete(wrapper);
54
- }
55
- };
56
- LoggerHelper.listeners.add(wrapper);
57
- return () => LoggerHelper.listeners.delete(wrapper);
58
- }
59
-
60
- LoggerHelper.listeners.add(listener);
61
- return () => LoggerHelper.listeners.delete(listener);
62
- }
63
- }
@@ -1,33 +0,0 @@
1
- enum SortOrder {
2
- NONE = 0,
3
- ASC = 1,
4
- DESC = -1,
5
- }
6
-
7
- const compareString = (valA: string, valB: string, ascending: boolean | undefined): number => {
8
- return valA.localeCompare(valB) * (ascending ? SortOrder.ASC : SortOrder.DESC);
9
- };
10
-
11
- const getSortOrder = <T>(valA: T, valB: T): SortOrder => {
12
- return valA < valB ? SortOrder.DESC : valA === valB ? SortOrder.NONE : SortOrder.ASC;
13
- };
14
-
15
- const compareNonString = <T>(valA: T, valB: T, ascending: boolean | undefined): number => {
16
- return getSortOrder(valA, valB) * (ascending ? SortOrder.ASC : SortOrder.DESC);
17
- };
18
-
19
- const getValue = <T>(valA: T, valB: T, ascending: boolean | undefined): number => {
20
- let result: number = 0;
21
- if (typeof valA === 'string' && typeof valB === 'string') {
22
- result = compareString(valA, valB, ascending);
23
- } else {
24
- result = compareNonString(valA, valB, ascending);
25
- }
26
- return result;
27
- };
28
-
29
- export const sortHelper = <T, G>(a: T, b: T, valueGetter: (a: T) => G, ascending?: boolean): number => {
30
- const valA: G = valueGetter(a);
31
- const valB: G = valueGetter(b);
32
- return getValue(valA, valB, ascending);
33
- };
@@ -1,16 +0,0 @@
1
- import { LocalStorageHelper } from '../local-storage.helper';
2
- import { TokenType } from './token-type.enum';
3
-
4
- export class TokenHelper {
5
- static get(key: TokenType): string | null {
6
- return LocalStorageHelper.get<string>(key);
7
- }
8
-
9
- static set(key: TokenType, token: string): void {
10
- LocalStorageHelper.set(key, token);
11
- }
12
-
13
- static remove(key: TokenType): void {
14
- LocalStorageHelper.remove(key);
15
- }
16
- }
@@ -1,7 +0,0 @@
1
- export interface IKeyValue<T> {
2
- key: number | string;
3
- value: T;
4
- }
5
-
6
- // refactor?
7
- // export type KeyValue<T> = Record<string | number, T>;
@@ -1,11 +0,0 @@
1
- import { Size } from '../../types';
2
-
3
- export const ScreenBreakpoints: Record<Size, number> = {
4
- xs: 0,
5
- sm: 576,
6
- md: 768,
7
- lg: 992,
8
- xl: 1200,
9
- xxl: 1400,
10
- xxxl: 1600,
11
- };
@@ -1,6 +0,0 @@
1
- import { Size } from '../../types';
2
-
3
- export interface IScreenBreakpoint {
4
- breakpoint: Size;
5
- screenWidth: number;
6
- }
@@ -1,119 +0,0 @@
1
- import { Size } from '../../types';
2
- import { ScreenBreakpoints } from './browser.consts';
3
- import { IScreenBreakpoint } from './browser.interface';
4
- import { OnResizeCallback, ResizeCallback } from './browser.types';
5
-
6
- // TODO - extract into Resize and breakpoint separated?
7
-
8
- export class BrowserService {
9
- private screenBreakpoints!: Record<Size, number>;
10
- private screenWidth: number = 0;
11
- private lastBreakpoint!: IScreenBreakpoint;
12
- private resizeListener!: (event: UIEvent) => void;
13
- private breakpointChangeCallbacks: Set<ResizeCallback> = new Set(); // feuert nur bei Breakpoint-Änderung
14
- private onResizeCallbacks: Set<OnResizeCallback> = new Set(); // feuert bei jedem throttled Resize
15
- private rafId: number | null = null;
16
- private emitTimeoutId: number | null = null; // für debounce der onResizeCallbacks
17
- private pendingWidth?: number;
18
- private pendingBreakpoint?: IScreenBreakpoint;
19
- private duplicateThresholdMs = 60;
20
-
21
- constructor(screenBreakpoints?: Record<Size, number>) {
22
- if (typeof window !== 'undefined') {
23
- this.screenBreakpoints = screenBreakpoints || ScreenBreakpoints;
24
-
25
- this.screenWidth = window.innerWidth;
26
- this.resizeListener = this.onResize.bind(this);
27
-
28
- window.addEventListener('resize', this.resizeListener, { passive: true }); // passive: true für bessere Scroll/Resize-Performance
29
- this.lastBreakpoint = this.getBreakpointByScreenWidth(this.screenWidth);
30
- }
31
- }
32
-
33
- public destroy(): void {
34
- if (typeof window !== 'undefined') {
35
- window.removeEventListener('resize', this.resizeListener);
36
- }
37
- this.breakpointChangeCallbacks.clear();
38
- this.onResizeCallbacks.clear();
39
- if (this.rafId !== null) {
40
- cancelAnimationFrame(this.rafId);
41
- this.rafId = null;
42
- }
43
- }
44
-
45
- public getCurrentScreenWidth(): number {
46
- return this.screenWidth;
47
- }
48
-
49
- public getCurrentBreakpoint(): IScreenBreakpoint {
50
- return this.lastBreakpoint;
51
- }
52
-
53
- public onBreakpointChange(callback: ResizeCallback): void {
54
- this.breakpointChangeCallbacks.add(callback);
55
- }
56
-
57
- public offBreakpointChange(callback: ResizeCallback): void {
58
- this.breakpointChangeCallbacks.delete(callback);
59
- }
60
-
61
- public onResizeChange(callback: OnResizeCallback): void {
62
- this.onResizeCallbacks.add(callback);
63
- }
64
-
65
- public offResizeChange(callback: OnResizeCallback): void {
66
- this.onResizeCallbacks.delete(callback);
67
- }
68
-
69
- public getBreakpointByScreenWidth(width: number = this.screenWidth): IScreenBreakpoint {
70
- let result: Size = 'xs';
71
- for (const key of Object.keys(this.screenBreakpoints) as Size[]) {
72
- if (this.screenBreakpoints[key] <= width) {
73
- result = key;
74
- }
75
- }
76
- return { breakpoint: result, screenWidth: this.screenBreakpoints[result] };
77
- }
78
-
79
- public isScreenGreaterThan(size: Size): boolean {
80
- return this.screenWidth > this.screenBreakpoints[size];
81
- }
82
-
83
- public isScreenSmallerThan(size: Size): boolean {
84
- return this.screenWidth < this.screenBreakpoints[size];
85
- }
86
-
87
- public getBreakpoint(size: Size): IScreenBreakpoint {
88
- return {
89
- breakpoint: size,
90
- screenWidth: this.screenBreakpoints[size],
91
- };
92
- }
93
-
94
- private onResize = (): void => {
95
- if (typeof window === 'undefined') return;
96
-
97
- const width: number = window.innerWidth;
98
- const breakpoint: IScreenBreakpoint = this.getBreakpointByScreenWidth(width);
99
-
100
- if (this.lastBreakpoint?.breakpoint !== breakpoint?.breakpoint) {
101
- this.lastBreakpoint = breakpoint;
102
- breakpoint && this.breakpointChangeCallbacks.forEach((cb) => cb(breakpoint));
103
- }
104
-
105
- this.pendingWidth = width;
106
- this.pendingBreakpoint = breakpoint;
107
-
108
- if (this.emitTimeoutId) clearTimeout(this.emitTimeoutId);
109
-
110
- this.emitTimeoutId = window.setTimeout(() => {
111
- if (this.pendingBreakpoint) {
112
- this.onResizeCallbacks.forEach((cb) => cb(this.pendingWidth!, this.pendingBreakpoint!));
113
- }
114
- this.pendingWidth = undefined;
115
- this.pendingBreakpoint = undefined;
116
- this.emitTimeoutId = null;
117
- }, this.duplicateThresholdMs);
118
- };
119
- }
package/services/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './browser';
package/tsconfig.json DELETED
@@ -1,33 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "declaration": true,
4
- "declarationMap": true,
5
- "emitDeclarationOnly": true,
6
- "outDir": "dist",
7
-
8
- "target": "ES2022",
9
- "useDefineForClassFields": true,
10
- "module": "ESNext",
11
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
12
- "skipLibCheck": true,
13
-
14
- /* Bundler mode */
15
- "moduleResolution": "bundler",
16
- "allowImportingTsExtensions": true,
17
- "isolatedModules": true,
18
- "moduleDetection": "force",
19
- "noEmit": true,
20
-
21
- /* Linting */
22
- "strict": true,
23
- "noImplicitAny": true,
24
- "noImplicitOverride": true,
25
- "noPropertyAccessFromIndexSignature": true,
26
- "noImplicitReturns": true,
27
- "noFallthroughCasesInSwitch": true,
28
- "noUnusedLocals": true,
29
- "noUnusedParameters": true
30
- },
31
- "include": ["**/*"],
32
- "exclude": ["node_modules", "dist"]
33
- }
package/types/index.ts DELETED
@@ -1,11 +0,0 @@
1
- export type Dictionary<T> = Record<string, T>;
2
-
3
- export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl';
4
-
5
- declare global {
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
- export type UnknownObject = any;
8
- export type Nullable<T> = T | null;
9
- export type Optional<T> = T | undefined;
10
- export const InstallTrigger: unknown;
11
- }
package/vite.config.ts DELETED
@@ -1,21 +0,0 @@
1
- import { defineConfig } from 'vite';
2
- import dts from 'vite-plugin-dts';
3
-
4
- export default defineConfig({
5
- root: './lib',
6
- build: {
7
- lib: {
8
- entry: 'index.ts',
9
- name: 'ts-utils',
10
- fileName: (format) => `index.${format}.js`,
11
- formats: ['es', 'cjs', 'umd'],
12
- },
13
- outDir: '../dist/lib',
14
- emptyOutDir: true,
15
- },
16
- plugins: [
17
- dts({
18
- insertTypesEntry: true,
19
- }),
20
- ],
21
- });