@acorex/core 22.0.0-next.9 → 22.0.1-next.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 (34) hide show
  1. package/README.md +1 -0
  2. package/constants/README.md +7 -1
  3. package/fesm2022/acorex-core-constants.mjs +27809 -1
  4. package/fesm2022/acorex-core-constants.mjs.map +1 -1
  5. package/fesm2022/acorex-core-date-time.mjs +30 -16
  6. package/fesm2022/acorex-core-date-time.mjs.map +1 -1
  7. package/fesm2022/acorex-core-file.mjs +118 -96
  8. package/fesm2022/acorex-core-file.mjs.map +1 -1
  9. package/fesm2022/acorex-core-full-screen.mjs +229 -56
  10. package/fesm2022/acorex-core-full-screen.mjs.map +1 -1
  11. package/fesm2022/acorex-core-locale.mjs +3 -0
  12. package/fesm2022/acorex-core-locale.mjs.map +1 -1
  13. package/fesm2022/acorex-core-theme-builder.mjs +1329 -0
  14. package/fesm2022/acorex-core-theme-builder.mjs.map +1 -0
  15. package/fesm2022/acorex-core-translation.mjs +20 -8
  16. package/fesm2022/acorex-core-translation.mjs.map +1 -1
  17. package/fesm2022/acorex-core-utils.mjs +250 -74
  18. package/fesm2022/acorex-core-utils.mjs.map +1 -1
  19. package/i18n/en-AU/acorex.json +1096 -0
  20. package/i18n/en-AU/common.json +290 -0
  21. package/i18n/en-US/acorex.json +1096 -0
  22. package/i18n/en-US/common.json +285 -0
  23. package/i18n/fa-IR/acorex.json +1096 -0
  24. package/i18n/fa-IR/common.json +284 -0
  25. package/package.json +7 -2
  26. package/theme-builder/README.md +53 -0
  27. package/types/acorex-core-constants.d.ts +58 -2
  28. package/types/acorex-core-date-time.d.ts +5 -0
  29. package/types/acorex-core-file.d.ts +10 -2
  30. package/types/acorex-core-full-screen.d.ts +67 -18
  31. package/types/acorex-core-locale.d.ts +2 -0
  32. package/types/acorex-core-theme-builder.d.ts +42 -0
  33. package/types/acorex-core-translation.d.ts +11 -5
  34. package/types/acorex-core-utils.d.ts +52 -14
@@ -261,7 +261,7 @@ function runFileTypeUtility(type, ctx, extension, name, ...args) {
261
261
  /** Runs a catalog utility with optional file-based extension resolution. */
262
262
  function runFileTypeUtilityForFile(type, ctx, file, name, ...args) {
263
263
  const extension = file ? findFileTypeExtension(file, type) : undefined;
264
- return runFileTypeUtility(type, ctx, extension, name, ...args);
264
+ return runFileTypeUtility(type, ctx, extension, name, file, ...args);
265
265
  }
266
266
 
267
267
  /** Runs `open` from extension first, then parent type, in the caller's injection context. */
@@ -389,9 +389,110 @@ async function validateFileAgainstType(validation, file, type, extension) {
389
389
  return validateFileWithValidations(validation, file, resolved);
390
390
  }
391
391
 
392
+ class AXFileMaxSizeValidationRule {
393
+ get name() {
394
+ return 'fileMaxSize';
395
+ }
396
+ async validate(value, options) {
397
+ const size = value instanceof File || value instanceof Blob ? value.size : 0;
398
+ const valid = size <= options.maxSize;
399
+ const limitLabel = formatFileSizeBytes(options.maxSize);
400
+ return {
401
+ rule: this.name,
402
+ result: valid,
403
+ message: valid
404
+ ? ''
405
+ : (options.message ??
406
+ `File is too large. Maximum size is ${limitLabel}.`),
407
+ value: size,
408
+ maxSize: options.maxSize,
409
+ };
410
+ }
411
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
412
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule }); }
413
+ }
414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule, decorators: [{
415
+ type: Injectable
416
+ }] });
417
+
418
+ class AXFileMimeTypeValidationRule {
419
+ get name() {
420
+ return 'fileMimeType';
421
+ }
422
+ async validate(value, options) {
423
+ const mime = (value instanceof File || value instanceof Blob ? value.type : '').trim().toLowerCase();
424
+ const allowed = options.allowed ?? [];
425
+ const valid = allowed.length === 0 ||
426
+ allowed.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));
427
+ return {
428
+ rule: this.name,
429
+ result: valid,
430
+ message: valid ? '' : (options.message ?? 'File type is not allowed.'),
431
+ value: mime,
432
+ };
433
+ }
434
+ matchesMime(mime, pattern) {
435
+ if (!pattern || pattern === '*/*' || pattern === '*') {
436
+ return true;
437
+ }
438
+ if (pattern.endsWith('/*')) {
439
+ const category = pattern.slice(0, -2);
440
+ return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');
441
+ }
442
+ return mime === pattern;
443
+ }
444
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
445
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule }); }
446
+ }
447
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule, decorators: [{
448
+ type: Injectable
449
+ }] });
450
+
451
+ class AXFileMinSizeValidationRule {
452
+ get name() {
453
+ return 'fileMinSize';
454
+ }
455
+ async validate(value, options) {
456
+ const size = value instanceof File || value instanceof Blob ? value.size : 0;
457
+ const valid = size >= options.minSize;
458
+ const limitLabel = formatFileSizeBytes(options.minSize);
459
+ return {
460
+ rule: this.name,
461
+ result: valid,
462
+ message: valid
463
+ ? ''
464
+ : (options.message ?? `File is too small. Minimum size is ${limitLabel}.`),
465
+ value: size,
466
+ minSize: options.minSize,
467
+ };
468
+ }
469
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
470
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule }); }
471
+ }
472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule, decorators: [{
473
+ type: Injectable
474
+ }] });
475
+
476
+ /** Validation rule classes to register with {@link AXValidationModule}. */
477
+ const AX_FILE_VALIDATION_RULES = [
478
+ AXFileMimeTypeValidationRule,
479
+ AXFileMinSizeValidationRule,
480
+ AXFileMaxSizeValidationRule,
481
+ ];
482
+ let fileValidationRulesRegistered = false;
483
+ /** Idempotent registration for bootstrap providers and first validation call. */
484
+ function ensureFileValidationRules(registry) {
485
+ if (fileValidationRulesRegistered) {
486
+ return;
487
+ }
488
+ registry.register(...AX_FILE_VALIDATION_RULES);
489
+ fileValidationRulesRegistered = true;
490
+ }
491
+
392
492
  class AXFileTypeRegistryService {
393
493
  constructor() {
394
494
  this.validation = inject(AXValidationService);
495
+ this.validationRegistry = inject(AXValidationRegistryService);
395
496
  this.providers = inject(AX_FILE_TYPE_INFO_PROVIDER, { optional: true }) ?? [];
396
497
  this.registeredTypes = [];
397
498
  this.cache = null;
@@ -491,6 +592,7 @@ class AXFileTypeRegistryService {
491
592
  });
492
593
  }
493
594
  async validate(file, typeName) {
595
+ ensureFileValidationRules(this.validationRegistry);
494
596
  const type = await this.get(typeName);
495
597
  if (!type) {
496
598
  return [
@@ -560,19 +662,26 @@ class AXFileTypeRendererOutletComponent {
560
662
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
561
663
  this.mergedInputs = signal({}, /* @ts-ignore */
562
664
  ...(ngDevMode ? [{ debugName: "mergedInputs" }] : /* istanbul ignore next */ []));
665
+ this.loadId = 0;
563
666
  effect(() => {
564
667
  const name = this.fileType();
565
- const payload = this.payload();
566
668
  const hint = this.extensionHint();
567
- const extra = this.inputs();
568
- this.mergedInputs.set({ payload, ...extra });
669
+ const id = ++this.loadId;
569
670
  this.loading.set(true);
570
671
  this.resolvedComponent.set(null);
571
672
  void this.registry.loadComponent(name, hint).then((component) => {
673
+ if (id !== this.loadId)
674
+ return;
572
675
  this.resolvedComponent.set(component ?? null);
573
676
  this.loading.set(false);
574
677
  });
575
678
  });
679
+ effect(() => {
680
+ this.mergedInputs.set({
681
+ payload: this.payload(),
682
+ ...this.inputs(),
683
+ });
684
+ });
576
685
  }
577
686
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileTypeRendererOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
578
687
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXFileTypeRendererOutletComponent, isStandalone: true, selector: "ax-file-type-renderer", inputs: { fileType: { classPropertyName: "fileType", publicName: "fileType", isSignal: true, isRequired: true, transformFunction: null }, payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: true, transformFunction: null }, extensionHint: { classPropertyName: "extensionHint", publicName: "extensionHint", isSignal: true, isRequired: false, transformFunction: null }, inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
@@ -747,110 +856,23 @@ function provideBuiltinFileTypeProviders() {
747
856
  /** @deprecated Use {@link provideBuiltinFileTypeProviders}. */
748
857
  const provideDefaultFileTypeProviders = provideBuiltinFileTypeProviders;
749
858
 
750
- class AXFileMimeTypeValidationRule {
751
- get name() {
752
- return 'fileMimeType';
753
- }
754
- async validate(value, options) {
755
- const mime = (value instanceof File || value instanceof Blob ? value.type : '').trim().toLowerCase();
756
- const allowed = options.allowed ?? [];
757
- const valid = allowed.length === 0 ||
758
- allowed.some((pattern) => this.matchesMime(mime, pattern.trim().toLowerCase()));
759
- return {
760
- rule: this.name,
761
- result: valid,
762
- message: valid ? '' : (options.message ?? 'File type is not allowed.'),
763
- value: mime,
764
- };
765
- }
766
- matchesMime(mime, pattern) {
767
- if (!pattern || pattern === '*/*' || pattern === '*') {
768
- return true;
769
- }
770
- if (pattern.endsWith('/*')) {
771
- const category = pattern.slice(0, -2);
772
- return mime.startsWith(`${category}/`) || (mime === '' && category === 'application');
773
- }
774
- return mime === pattern;
775
- }
776
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
777
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule }); }
778
- }
779
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMimeTypeValidationRule, decorators: [{
780
- type: Injectable
781
- }] });
782
-
783
- class AXFileMinSizeValidationRule {
784
- get name() {
785
- return 'fileMinSize';
786
- }
787
- async validate(value, options) {
788
- const size = value instanceof File || value instanceof Blob ? value.size : 0;
789
- const valid = size >= options.minSize;
790
- const limitLabel = formatFileSizeBytes(options.minSize);
791
- return {
792
- rule: this.name,
793
- result: valid,
794
- message: valid
795
- ? ''
796
- : (options.message ?? `File is too small. Minimum size is ${limitLabel}.`),
797
- value: size,
798
- minSize: options.minSize,
799
- };
800
- }
801
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
802
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule }); }
803
- }
804
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMinSizeValidationRule, decorators: [{
805
- type: Injectable
806
- }] });
807
-
808
- class AXFileMaxSizeValidationRule {
809
- get name() {
810
- return 'fileMaxSize';
811
- }
812
- async validate(value, options) {
813
- const size = value instanceof File || value instanceof Blob ? value.size : 0;
814
- const valid = size <= options.maxSize;
815
- const limitLabel = formatFileSizeBytes(options.maxSize);
816
- return {
817
- rule: this.name,
818
- result: valid,
819
- message: valid
820
- ? ''
821
- : (options.message ??
822
- `File is too large. Maximum size is ${limitLabel}.`),
823
- value: size,
824
- maxSize: options.maxSize,
825
- };
826
- }
827
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
828
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule }); }
829
- }
830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFileMaxSizeValidationRule, decorators: [{
831
- type: Injectable
832
- }] });
833
-
834
- /** Validation rule classes to register with {@link AXValidationModule}. */
835
- const AX_FILE_VALIDATION_RULES = [
836
- AXFileMimeTypeValidationRule,
837
- AXFileMinSizeValidationRule,
838
- AXFileMaxSizeValidationRule,
839
- ];
840
859
  /** Registers file validation rules with {@link AXValidationRegistryService}. */
841
860
  function provideFileValidationRules() {
842
861
  return {
843
862
  provide: 'AXValidationModuleFactory',
844
863
  useFactory: (registry) => () => {
845
- registry.register(...AX_FILE_VALIDATION_RULES);
864
+ ensureFileValidationRules(registry);
846
865
  },
847
866
  deps: [AXValidationRegistryService],
848
867
  multi: true,
849
868
  };
850
869
  }
851
870
  /**
871
+
852
872
  * Registers validation rules and optional built-in file type providers.
873
+
853
874
  * {@link AXFileTypeRegistryService} and {@link AXFileService} are `providedIn: 'root'`.
875
+
854
876
  */
855
877
  function provideFileTypeSystem() {
856
878
  return [provideFileValidationRules(), ...provideBuiltinFileTypeProviders()];
@@ -1009,5 +1031,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1009
1031
  * Generated bundle index. Do not edit.
1010
1032
  */
1011
1033
 
1012
- export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXFileTypeRendererOutletComponent, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, defineFileType, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, findFileTypeExtensionByName, findFileTypeExtensionForMime, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, isLazyFileTypeComponentLoader, loadFileTypeComponent, matchesFileMime, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileTypes, provideFileValidationRules, resolveFileCopyText, resolveFileTypeComponent, resolveFileTypeComponentType, resolveFileTypeCopy, resolveFileTypeExtension, resolveFileTypeOpen, resolveFileTypePaste, resolveFileTypeUtility, resolveFileValidations, runFileTypeCopy, runFileTypeOpen, runFileTypeUtility, runFileTypeUtilityForFile, validateFileAgainstType, validateFileWithValidations };
1034
+ export { AXAudioFileTypeProvider, AXDocumentFileTypeProvider, AXFileFileTypeProvider, AXFileMaxSizeValidationRule, AXFileMimeTypeValidationRule, AXFileMinSizeValidationRule, AXFileModule, AXFileService, AXFileSizeFormatter, AXFileTypeInfoProvider, AXFileTypeRegistryService, AXFileTypeRendererOutletComponent, AXImageFileTypeProvider, AXVideoFileTypeProvider, AX_AUDIO_FILE_TYPE, AX_BUILTIN_FILE_TYPE_PROVIDERS, AX_DOCUMENT_FILE_TYPE, AX_FILE_FILE_TYPE, AX_FILE_TYPE_INFO_PROVIDER, AX_FILE_TYPE_METADATA_PURPOSE, AX_FILE_VALIDATION_RULES, AX_IMAGE_FILE_TYPE, AX_VIDEO_FILE_TYPE, createFileTypeMetadata, defineFileType, ensureFileValidationRules, fileTypeMatchesPurpose, fileValidationsToRules, filterFileTypesByPurpose, findFileTypeExtension, findFileTypeExtensionByName, findFileTypeExtensionForMime, formatFileSizeBytes, getFileExtension, getFileTypePurposes, isEmptyFileValidations, isExtensionsOnlyType, isLazyFileTypeComponentLoader, loadFileTypeComponent, matchesFileMime, mergeFileValidations, provideBuiltinFileTypeProviders, provideDefaultFileTypeProviders, provideFileTypeInfoProvider, provideFileTypeSystem, provideFileTypes, provideFileValidationRules, resolveFileCopyText, resolveFileTypeComponent, resolveFileTypeComponentType, resolveFileTypeCopy, resolveFileTypeExtension, resolveFileTypeOpen, resolveFileTypePaste, resolveFileTypeUtility, resolveFileValidations, runFileTypeCopy, runFileTypeOpen, runFileTypeUtility, runFileTypeUtilityForFile, validateFileAgainstType, validateFileWithValidations };
1013
1035
  //# sourceMappingURL=acorex-core-file.mjs.map