@haloduck/util 2.0.5 → 2.1.1

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/README.md CHANGED
@@ -11,15 +11,18 @@ npm install @haloduck/util
11
11
  ## Key Features
12
12
 
13
13
  ### File Utilities
14
+
14
15
  - **download**: File download function
15
16
 
16
17
  ### Form Utilities
18
+
17
19
  - **hasRequired**: Check required field validation
18
20
  - **hasError**: Check form error status
19
21
  - **getDirtyValues**: Extract only changed form values
20
22
  - **englishAndNumberOnlyValidator**: Validator that allows only English and numbers
21
23
 
22
24
  ### Services
25
+
23
26
  - **UtilService**: File icon URL provider service
24
27
  - **provideHaloduckUtilIconSet**: File icon configuration provider
25
28
 
@@ -33,13 +33,12 @@ function isEqual(a, b) {
33
33
  if (!a || !b)
34
34
  return false;
35
35
  if (Array.isArray(a) && Array.isArray(b)) {
36
- return (a.length === b.length && a.every((val, i) => isEqual(val, b[i])));
36
+ return a.length === b.length && a.every((val, i) => isEqual(val, b[i]));
37
37
  }
38
38
  if (typeof a === 'object' && typeof b === 'object') {
39
39
  const keysA = Object.keys(a);
40
40
  const keysB = Object.keys(b);
41
- return (keysA.length === keysB.length &&
42
- keysA.every((key) => isEqual(a[key], b[key])));
41
+ return keysA.length === keysB.length && keysA.every((key) => isEqual(a[key], b[key]));
43
42
  }
44
43
  return false;
45
44
  }
@@ -116,7 +115,11 @@ class FitTextDirective {
116
115
  }
117
116
  // Observe text/content changes
118
117
  this.mutationObserver = new MutationObserver(() => this.scheduleFit());
119
- this.mutationObserver.observe(this.host, { childList: true, characterData: true, subtree: true });
118
+ this.mutationObserver.observe(this.host, {
119
+ childList: true,
120
+ characterData: true,
121
+ subtree: true,
122
+ });
120
123
  });
121
124
  }
122
125
  ngOnDestroy() {
@@ -135,7 +138,9 @@ class FitTextDirective {
135
138
  if (this.destroyed || this.scheduled)
136
139
  return;
137
140
  this.scheduled = true;
138
- const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (cb) => setTimeout(() => cb(performance.now()), 16);
141
+ const raf = typeof requestAnimationFrame === 'function'
142
+ ? requestAnimationFrame
143
+ : (cb) => setTimeout(() => cb(performance.now()), 16);
139
144
  this.rafId = raf(() => {
140
145
  this.rafId = null;
141
146
  this.scheduled = false;
@@ -151,7 +156,9 @@ class FitTextDirective {
151
156
  return;
152
157
  const computed = window.getComputedStyle(element);
153
158
  const originalFontSizePx = this.parsePx(computed.fontSize) || 16;
154
- const maxPx = this.hddFitTextMaxPx ? Math.min(this.hddFitTextMaxPx, originalFontSizePx) : originalFontSizePx;
159
+ const maxPx = this.hddFitTextMaxPx
160
+ ? Math.min(this.hddFitTextMaxPx, originalFontSizePx)
161
+ : originalFontSizePx;
155
162
  let low = this.hddFitTextMinPx;
156
163
  let high = Math.max(low, Math.floor(maxPx));
157
164
  // Quick accept if it already fits
@@ -193,7 +200,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
193
200
  type: Directive,
194
201
  args: [{
195
202
  selector: '[haloduckFitText]',
196
- standalone: true
203
+ standalone: true,
197
204
  }]
198
205
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { hddFitTextMinPx: [{
199
206
  type: Input
@@ -1 +1 @@
1
- {"version":3,"file":"haloduck-util.mjs","sources":["../../../../projects/haloduck/util/src/lib/function/util.file.ts","../../../../projects/haloduck/util/src/lib/function/util.form.ts","../../../../projects/haloduck/util/src/lib/service/util.service.ts","../../../../projects/haloduck/util/src/lib/directive/fit-text.directive.ts","../../../../projects/haloduck/util/src/public-api.ts","../../../../projects/haloduck/util/src/haloduck-util.ts"],"sourcesContent":["\nexport function download(href: string) {\n const link = document.createElement('a');\n link.href = href;\n link.target = '_blank';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n","import { AbstractControl, Validators, FormGroup } from '@angular/forms';\n\nexport function hasRequired(control: AbstractControl<any, any> | null) {\n return control?.hasValidator(Validators.required);\n}\n\nexport function hasError(\n control: AbstractControl<any, any> | null,\n errorType: string,\n): boolean | undefined {\n return control?.touched && (control?.hasError(errorType) ?? false);\n}\n\nexport function getDirtyValues(fg: FormGroup) {\n const dirtyValues = Object.keys(fg.controls)\n .filter((key) => fg.controls[key].dirty)\n .reduce((acc: { [key: string]: any }, key) => {\n acc[key] = fg.controls[key].value;\n return acc;\n }, {});\n\n return dirtyValues;\n}\n\nexport const englishAndNumberOnlyValidator =\n Validators.pattern(/^[0-9A-Za-z\\s]*$/);\n\nexport function isEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n return (\n a.length === b.length && a.every((val, i) => isEqual(val, b[i]))\n );\n }\n if (typeof a === 'object' && typeof b === 'object') {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n return (\n keysA.length === keysB.length &&\n keysA.every((key) => isEqual(a[key], b[key]))\n );\n }\n return false;\n}\n","import {\n Injectable,\n inject,\n InjectionToken,\n Provider,\n EnvironmentInjector,\n} from '@angular/core';\n\nexport const FILE_ICON_SET = new InjectionToken<Record<string, string>>(\n 'FILE_ICON_SET',\n {\n providedIn: 'root',\n factory: () => ({\n pdf: 'assets/pdf.svg',\n stl: 'assets/stl.svg',\n default: 'assets/default.svg',\n }),\n },\n);\n\nexport function provideHaloduckUtilIconSet(\n iconSet: Record<string, string>,\n): Provider {\n return {\n provide: FILE_ICON_SET,\n useValue: iconSet,\n };\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class UtilService {\n // private readonly environmentInjector = inject(EnvironmentInjector);\n iconSet = inject(FILE_ICON_SET);\n\n getFileIconUrl(filename: string): string {\n const extension = filename.split('.').pop()?.toLowerCase();\n return this.iconSet[extension || ''] || this.iconSet['default'];\n }\n}\n","import { AfterViewInit, Directive, ElementRef, Input, NgZone, OnDestroy } from '@angular/core';\n\n/**\n * Shrinks the font-size so the text fits within the element's width.\n * - Only scales down; never scales up beyond the computed font size\n * - Observes element resize and text mutations\n */\n@Directive({\n selector: '[haloduckFitText]',\n standalone: true\n})\nexport class FitTextDirective implements AfterViewInit, OnDestroy {\n @Input() hddFitTextMinPx = 6; // reasonable minimum for small cards\n @Input() hddFitTextMaxPx?: number; // if provided, caps the max font size\n\n private readonly host: HTMLElement;\n private resizeObserver?: ResizeObserver;\n private mutationObserver?: MutationObserver;\n private destroyed = false;\n private removeWindowResizeListener?: () => void;\n private rafId: number | null = null;\n private scheduled = false;\n private readonly handleWindowResize = () => this.scheduleFit();\n\n constructor(private readonly elRef: ElementRef<HTMLElement>, private readonly zone: NgZone) {\n this.host = elRef.nativeElement;\n }\n\n ngAfterViewInit(): void {\n // Avoid layout thrash during Angular change detection\n this.zone.runOutsideAngular(() => {\n // Ensure single line to match width-fit semantics\n this.host.style.whiteSpace = this.host.style.whiteSpace || 'nowrap';\n // Trigger initial fit after current microtask\n setTimeout(() => this.scheduleFit(), 0);\n\n // Observe element size changes\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.scheduleFit());\n this.resizeObserver.observe(this.host);\n } else if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('resize', this.handleWindowResize);\n this.removeWindowResizeListener = () => window.removeEventListener('resize', this.handleWindowResize);\n }\n\n // Observe text/content changes\n this.mutationObserver = new MutationObserver(() => this.scheduleFit());\n this.mutationObserver.observe(this.host, { childList: true, characterData: true, subtree: true });\n });\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n this.removeWindowResizeListener?.();\n this.mutationObserver?.disconnect();\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private scheduleFit = (): void => {\n if (this.destroyed || this.scheduled) return;\n this.scheduled = true;\n const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (cb: FrameRequestCallback) => setTimeout(() => cb(performance.now()), 16) as unknown as number;\n this.rafId = raf(() => {\n this.rafId = null;\n this.scheduled = false;\n this.fit();\n });\n };\n\n private fit = (): void => {\n if (this.destroyed) return;\n\n const element = this.host;\n const availableWidth = element.clientWidth;\n if (!availableWidth) return;\n\n const computed = window.getComputedStyle(element);\n const originalFontSizePx = this.parsePx(computed.fontSize) || 16;\n const maxPx = this.hddFitTextMaxPx ? Math.min(this.hddFitTextMaxPx, originalFontSizePx) : originalFontSizePx;\n let low = this.hddFitTextMinPx;\n let high = Math.max(low, Math.floor(maxPx));\n\n // Quick accept if it already fits\n element.style.fontSize = `${high}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n return;\n }\n\n // Binary search for the largest font-size that fits\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n element.style.fontSize = `${mid}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n low = mid + 1; // try bigger\n } else {\n high = mid - 1; // too big\n }\n }\n // After loop, test final candidates\n for (let size = Math.min(high, maxPx); size >= this.hddFitTextMinPx; size--) {\n element.style.fontSize = `${size}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n break;\n }\n }\n };\n\n private scrollsWithin(element: HTMLElement, availableWidth: number): boolean {\n // Add a small epsilon for sub-pixel rounding\n return element.scrollWidth <= Math.ceil(availableWidth + 0.5);\n }\n\n private parsePx(value: string): number {\n const num = Number(String(value || '').replace('px', ''));\n return isFinite(num) ? num : 0;\n }\n}\n\n\n","/*\n * Public API Surface of util\n */\n\nexport * from './lib';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AACM,SAAU,QAAQ,CAAC,IAAY,EAAA;IACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC;AACxC,IAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,IAAA,IAAI,CAAC,MAAM,GAAG,QAAQ;AACtB,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE;AACZ,IAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACjC;;ACNM,SAAU,WAAW,CAAC,OAAyC,EAAA;IACnE,OAAO,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;AACnD;AAEM,SAAU,QAAQ,CACtB,OAAyC,EACzC,SAAiB,EAAA;AAEjB,IAAA,OAAO,OAAO,EAAE,OAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;AACpE;AAEM,SAAU,cAAc,CAAC,EAAa,EAAA;IAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AACxC,SAAA,MAAM,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK;AACtC,SAAA,MAAM,CAAC,CAAC,GAA2B,EAAE,GAAG,KAAI;AAC3C,QAAA,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK;AACjC,QAAA,OAAO,GAAG;KACX,EAAE,EAAE,CAAC;AAER,IAAA,OAAO,WAAW;AACpB;AAEO,MAAM,6BAA6B,GACxC,UAAU,CAAC,OAAO,CAAC,kBAAkB;AAEjC,SAAU,OAAO,CAAC,CAAM,EAAE,CAAM,EAAA;IACpC,IAAI,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,IAAI;AACxB,IAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAAE,QAAA,OAAO,KAAK;AAC1B,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;AACxC,QAAA,QACE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;IAGpE,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;QAClD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,QAAA,QACE,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAC7B,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;;AAGjD,IAAA,OAAO,KAAK;AACd;;MCpCa,aAAa,GAAG,IAAI,cAAc,CAC7C,eAAe,EACf;AACE,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,OAAO;AACd,QAAA,GAAG,EAAE,gBAAgB;AACrB,QAAA,GAAG,EAAE,gBAAgB;AACrB,QAAA,OAAO,EAAE,oBAAoB;KAC9B,CAAC;AACH,CAAA;AAGG,SAAU,0BAA0B,CACxC,OAA+B,EAAA;IAE/B,OAAO;AACL,QAAA,OAAO,EAAE,aAAa;AACtB,QAAA,QAAQ,EAAE,OAAO;KAClB;AACH;MAKa,WAAW,CAAA;;AAEtB,IAAA,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC;AAE/B,IAAA,cAAc,CAAC,QAAgB,EAAA;AAC7B,QAAA,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE;AAC1D,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;;uGANtD,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cAFV,MAAM,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;AC7BD;;;;AAIG;MAKU,gBAAgB,CAAA;AAaE,IAAA,KAAA;AAAiD,IAAA,IAAA;AAZrE,IAAA,eAAe,GAAG,CAAC,CAAC;IACpB,eAAe,CAAU;AAEjB,IAAA,IAAI;AACb,IAAA,cAAc;AACd,IAAA,gBAAgB;IAChB,SAAS,GAAG,KAAK;AACjB,IAAA,0BAA0B;IAC1B,KAAK,GAAkB,IAAI;IAC3B,SAAS,GAAG,KAAK;IACR,kBAAkB,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE;IAE9D,WAAA,CAA6B,KAA8B,EAAmB,IAAY,EAAA;QAA7D,IAAA,CAAA,KAAK,GAAL,KAAK;QAA4C,IAAA,CAAA,IAAI,GAAJ,IAAI;AAChF,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,aAAa;;IAGjC,eAAe,GAAA;;AAEb,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAK;;AAE/B,YAAA,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ;;YAEnE,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;;AAGvC,YAAA,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;AACzC,gBAAA,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;gBAClE,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;;AACjC,iBAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,gBAAgB,KAAK,UAAU,EAAE;gBACzF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC;AAC1D,gBAAA,IAAI,CAAC,0BAA0B,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,CAAC;;;AAIvG,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACtE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACnG,SAAC,CAAC;;IAGJ,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,IAAI,IAAI,CAAC,cAAc,EAAE;AACvB,YAAA,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE;;AAElC,QAAA,IAAI,CAAC,0BAA0B,IAAI;AACnC,QAAA,IAAI,CAAC,gBAAgB,EAAE,UAAU,EAAE;AACnC,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE;AACvB,YAAA,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC;AAChC,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;;;IAIb,WAAW,GAAG,MAAW;AAC/B,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YAAE;AACtC,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,MAAM,GAAG,GAAG,OAAO,qBAAqB,KAAK,UAAU,GAAG,qBAAqB,GAAG,CAAC,EAAwB,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAsB;AAChL,QAAA,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,MAAK;AACpB,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;YACtB,IAAI,CAAC,GAAG,EAAE;AACZ,SAAC,CAAC;AACJ,KAAC;IAEO,GAAG,GAAG,MAAW;QACvB,IAAI,IAAI,CAAC,SAAS;YAAE;AAEpB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI;AACzB,QAAA,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW;AAC1C,QAAA,IAAI,CAAC,cAAc;YAAE;QAErB,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC;AACjD,QAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,kBAAkB;AAC5G,QAAA,IAAI,GAAG,GAAG,IAAI,CAAC,eAAe;AAC9B,QAAA,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;;QAG3C,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAA,EAAG,IAAI,IAAI;QACpC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE;YAC/C;;;AAIF,QAAA,OAAO,GAAG,GAAG,IAAI,EAAE;AACjB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAA,EAAG,GAAG,IAAI;YACnC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE;AAC/C,gBAAA,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;;iBACT;AACL,gBAAA,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;;;;QAInB,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE;YAC3E,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAA,EAAG,IAAI,IAAI;YACpC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE;gBAC/C;;;AAGN,KAAC;IAEO,aAAa,CAAC,OAAoB,EAAE,cAAsB,EAAA;;AAEhE,QAAA,OAAO,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;;AAGvD,IAAA,OAAO,CAAC,KAAa,EAAA;AAC3B,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACzD,QAAA,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;;uGA7GrB,gBAAgB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAJ5B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,UAAU,EAAE;AACb,iBAAA;oGAEU,eAAe,EAAA,CAAA;sBAAvB;gBACQ,eAAe,EAAA,CAAA;sBAAvB;;;ACbH;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"haloduck-util.mjs","sources":["../../../../projects/haloduck/util/src/lib/function/util.file.ts","../../../../projects/haloduck/util/src/lib/function/util.form.ts","../../../../projects/haloduck/util/src/lib/service/util.service.ts","../../../../projects/haloduck/util/src/lib/directive/fit-text.directive.ts","../../../../projects/haloduck/util/src/public-api.ts","../../../../projects/haloduck/util/src/haloduck-util.ts"],"sourcesContent":["export function download(href: string) {\n const link = document.createElement('a');\n link.href = href;\n link.target = '_blank';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n","import { AbstractControl, Validators, FormGroup } from '@angular/forms';\n\nexport function hasRequired(control: AbstractControl<any, any> | null) {\n return control?.hasValidator(Validators.required);\n}\n\nexport function hasError(\n control: AbstractControl<any, any> | null,\n errorType: string,\n): boolean | undefined {\n return control?.touched && (control?.hasError(errorType) ?? false);\n}\n\nexport function getDirtyValues(fg: FormGroup) {\n const dirtyValues = Object.keys(fg.controls)\n .filter((key) => fg.controls[key].dirty)\n .reduce((acc: { [key: string]: any }, key) => {\n acc[key] = fg.controls[key].value;\n return acc;\n }, {});\n\n return dirtyValues;\n}\n\nexport const englishAndNumberOnlyValidator = Validators.pattern(/^[0-9A-Za-z\\s]*$/);\n\nexport function isEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((val, i) => isEqual(val, b[i]));\n }\n if (typeof a === 'object' && typeof b === 'object') {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n return keysA.length === keysB.length && keysA.every((key) => isEqual(a[key], b[key]));\n }\n return false;\n}\n","import { Injectable, inject, InjectionToken, Provider, EnvironmentInjector } from '@angular/core';\n\nexport const FILE_ICON_SET = new InjectionToken<Record<string, string>>('FILE_ICON_SET', {\n providedIn: 'root',\n factory: () => ({\n pdf: 'assets/pdf.svg',\n stl: 'assets/stl.svg',\n default: 'assets/default.svg',\n }),\n});\n\nexport function provideHaloduckUtilIconSet(iconSet: Record<string, string>): Provider {\n return {\n provide: FILE_ICON_SET,\n useValue: iconSet,\n };\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class UtilService {\n // private readonly environmentInjector = inject(EnvironmentInjector);\n iconSet = inject(FILE_ICON_SET);\n\n getFileIconUrl(filename: string): string {\n const extension = filename.split('.').pop()?.toLowerCase();\n return this.iconSet[extension || ''] || this.iconSet['default'];\n }\n}\n","import { AfterViewInit, Directive, ElementRef, Input, NgZone, OnDestroy } from '@angular/core';\n\n/**\n * Shrinks the font-size so the text fits within the element's width.\n * - Only scales down; never scales up beyond the computed font size\n * - Observes element resize and text mutations\n */\n@Directive({\n selector: '[haloduckFitText]',\n standalone: true,\n})\nexport class FitTextDirective implements AfterViewInit, OnDestroy {\n @Input() hddFitTextMinPx = 6; // reasonable minimum for small cards\n @Input() hddFitTextMaxPx?: number; // if provided, caps the max font size\n\n private readonly host: HTMLElement;\n private resizeObserver?: ResizeObserver;\n private mutationObserver?: MutationObserver;\n private destroyed = false;\n private removeWindowResizeListener?: () => void;\n private rafId: number | null = null;\n private scheduled = false;\n private readonly handleWindowResize = () => this.scheduleFit();\n\n constructor(\n private readonly elRef: ElementRef<HTMLElement>,\n private readonly zone: NgZone,\n ) {\n this.host = elRef.nativeElement;\n }\n\n ngAfterViewInit(): void {\n // Avoid layout thrash during Angular change detection\n this.zone.runOutsideAngular(() => {\n // Ensure single line to match width-fit semantics\n this.host.style.whiteSpace = this.host.style.whiteSpace || 'nowrap';\n // Trigger initial fit after current microtask\n setTimeout(() => this.scheduleFit(), 0);\n\n // Observe element size changes\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.scheduleFit());\n this.resizeObserver.observe(this.host);\n } else if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('resize', this.handleWindowResize);\n this.removeWindowResizeListener = () =>\n window.removeEventListener('resize', this.handleWindowResize);\n }\n\n // Observe text/content changes\n this.mutationObserver = new MutationObserver(() => this.scheduleFit());\n this.mutationObserver.observe(this.host, {\n childList: true,\n characterData: true,\n subtree: true,\n });\n });\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n this.removeWindowResizeListener?.();\n this.mutationObserver?.disconnect();\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private scheduleFit = (): void => {\n if (this.destroyed || this.scheduled) return;\n this.scheduled = true;\n const raf =\n typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame\n : (cb: FrameRequestCallback) =>\n setTimeout(() => cb(performance.now()), 16) as unknown as number;\n this.rafId = raf(() => {\n this.rafId = null;\n this.scheduled = false;\n this.fit();\n });\n };\n\n private fit = (): void => {\n if (this.destroyed) return;\n\n const element = this.host;\n const availableWidth = element.clientWidth;\n if (!availableWidth) return;\n\n const computed = window.getComputedStyle(element);\n const originalFontSizePx = this.parsePx(computed.fontSize) || 16;\n const maxPx = this.hddFitTextMaxPx\n ? Math.min(this.hddFitTextMaxPx, originalFontSizePx)\n : originalFontSizePx;\n let low = this.hddFitTextMinPx;\n let high = Math.max(low, Math.floor(maxPx));\n\n // Quick accept if it already fits\n element.style.fontSize = `${high}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n return;\n }\n\n // Binary search for the largest font-size that fits\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n element.style.fontSize = `${mid}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n low = mid + 1; // try bigger\n } else {\n high = mid - 1; // too big\n }\n }\n // After loop, test final candidates\n for (let size = Math.min(high, maxPx); size >= this.hddFitTextMinPx; size--) {\n element.style.fontSize = `${size}px`;\n if (this.scrollsWithin(element, availableWidth)) {\n break;\n }\n }\n };\n\n private scrollsWithin(element: HTMLElement, availableWidth: number): boolean {\n // Add a small epsilon for sub-pixel rounding\n return element.scrollWidth <= Math.ceil(availableWidth + 0.5);\n }\n\n private parsePx(value: string): number {\n const num = Number(String(value || '').replace('px', ''));\n return isFinite(num) ? num : 0;\n }\n}\n","/*\n * Public API Surface of util\n */\n\nexport * from './lib';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haloduck/util",
3
- "version": "2.0.5",
3
+ "version": "2.1.1",
4
4
  "description": "HaloDuck Util Library - Angular",
5
5
  "keywords": [
6
6
  "angular",
@@ -27,17 +27,6 @@
27
27
  "esm2022": "fesm2022/haloduck-util.mjs",
28
28
  "fesm2022": "fesm2022/haloduck-util.mjs",
29
29
  "typings": "index.d.ts",
30
- "exports": {
31
- ".": {
32
- "import": "./fesm2022/haloduck-util.mjs",
33
- "require": "./bundles/haloduck-util.umd.js",
34
- "types": "./index.d.ts",
35
- "default": "./fesm2022/haloduck-util.mjs"
36
- },
37
- "./package.json": {
38
- "default": "./package.json"
39
- }
40
- },
41
30
  "peerDependencies": {
42
31
  "@angular/common": "^20.0.0",
43
32
  "@angular/core": "^20.0.0",
@@ -49,5 +38,14 @@
49
38
  "sideEffects": false,
50
39
  "publishConfig": {
51
40
  "access": "public"
41
+ },
42
+ "exports": {
43
+ "./package.json": {
44
+ "default": "./package.json"
45
+ },
46
+ ".": {
47
+ "types": "./index.d.ts",
48
+ "default": "./fesm2022/haloduck-util.mjs"
49
+ }
52
50
  }
53
51
  }