@filip.mazev/blocks 1.4.14 → 1.4.16

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 (44) hide show
  1. package/README.md +5 -5
  2. package/core/styles/_a11y.scss +5 -0
  3. package/core/styles/_field-state.scss +12 -3
  4. package/core/styles/_helpers.scss +1 -0
  5. package/core/styles/_index.scss +4 -9
  6. package/core/styles/_palettes.scss +54 -10
  7. package/core/styles/_slider.scss +116 -6
  8. package/core/styles/_text-overflow.scss +7 -0
  9. package/core/styles/_text.scss +5 -0
  10. package/core/styles/_validation.scss +48 -0
  11. package/core/styles/themes/_azure-ember-theme.scss +4 -0
  12. package/core/styles/themes/_brick-rose-cyan-theme.scss +4 -0
  13. package/core/styles/themes/_carbon-cobalt-theme.scss +4 -0
  14. package/fesm2022/filip.mazev-blocks-core.mjs +102 -48
  15. package/fesm2022/filip.mazev-blocks-core.mjs.map +1 -1
  16. package/fesm2022/filip.mazev-blocks-effects-runtime.mjs +14 -3
  17. package/fesm2022/filip.mazev-blocks-effects-runtime.mjs.map +1 -1
  18. package/fesm2022/filip.mazev-blocks-effects.mjs +16 -8
  19. package/fesm2022/filip.mazev-blocks-effects.mjs.map +1 -1
  20. package/fesm2022/filip.mazev-blocks-forms.mjs +5004 -1078
  21. package/fesm2022/filip.mazev-blocks-forms.mjs.map +1 -1
  22. package/fesm2022/filip.mazev-blocks-primitives.mjs +2373 -1294
  23. package/fesm2022/filip.mazev-blocks-primitives.mjs.map +1 -1
  24. package/fesm2022/filip.mazev-blocks.mjs +1 -1
  25. package/fesm2022/filip.mazev-blocks.mjs.map +1 -1
  26. package/forms/README.md +80 -0
  27. package/package.json +1 -1
  28. package/schematics/ng-add/index.d.ts +1 -10
  29. package/schematics/ng-add/index.js +4 -13
  30. package/schematics/ng-add/schema.json +11 -17
  31. package/types/filip.mazev-blocks-core.d.ts +26 -15
  32. package/types/filip.mazev-blocks-effects.d.ts +1 -1
  33. package/types/filip.mazev-blocks-forms.d.ts +1216 -76
  34. package/types/filip.mazev-blocks-primitives.d.ts +304 -6
  35. package/types/filip.mazev-blocks.d.ts +1 -1
  36. package/core/styles/themes/_azure-coral-theme.scss +0 -4
  37. package/core/styles/themes/_blue-theme.scss +0 -5
  38. package/core/styles/themes/_graphite-sky-blue-theme.scss +0 -19
  39. package/core/styles/themes/_green-theme.scss +0 -5
  40. package/core/styles/themes/_orange-theme.scss +0 -5
  41. package/core/styles/themes/_purple-theme.scss +0 -5
  42. package/core/styles/themes/_red-theme.scss +0 -5
  43. package/core/styles/themes/_scarlet-cyan-theme.scss +0 -4
  44. package/core/styles/themes/_white-theme.scss +0 -5
@@ -1,11 +1,12 @@
1
1
  import * as i0 from "@angular/core";
2
- import { DOCUMENT, DestroyRef, Directive, Injectable, InjectionToken, NgZone, PLATFORM_ID, computed, effect, inject, input, isDevMode, signal } from "@angular/core";
2
+ import { DOCUMENT, DestroyRef, Directive, ElementRef, Injectable, InjectionToken, NgZone, PLATFORM_ID, afterNextRender, booleanAttribute, computed, effect, inject, input, isDevMode, signal } from "@angular/core";
3
3
  import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from "@angular/common";
4
4
  import { fromEvent } from "rxjs";
5
5
  import { debounceTime, distinctUntilChanged, map } from "rxjs/operators";
6
- import { toObservable } from "@angular/core/rxjs-interop";
6
+ import { takeUntilDestroyed, toObservable } from "@angular/core/rxjs-interop";
7
7
  import { configureAppearance } from "@filip.mazev/blocks/effects/runtime";
8
8
  import { ConnectionPositionPair, FlexibleConnectedPositionStrategy, Overlay } from "@angular/cdk/overlay";
9
+ import { FocusMonitor } from "@angular/cdk/a11y";
9
10
  import { NgControl, Validators } from "@angular/forms";
10
11
  var DesktopOS;
11
12
  (function(DesktopOS) {
@@ -348,26 +349,18 @@ const DEFAULT_APPEARANCE_CONFIG = Object.freeze({
348
349
  quality: "auto",
349
350
  reducedTransparency: false
350
351
  });
351
- const LEGACY_THEME_IDS = {
352
- white: "graphite-sky-blue",
353
- blue: "azure-coral",
354
- purple: "violet-teal",
355
- orange: "tangerine-indigo",
356
- red: "scarlet-cyan",
357
- green: "lime-violet"
358
- };
359
352
  const THEME_PALETTES = [
360
353
  {
361
- id: "graphite-sky-blue",
362
- label: "Graphite / Sky Blue",
363
- className: "theme-graphite-sky-blue",
364
- colors: ["#525252", "#38bdf8"]
354
+ id: "carbon-cobalt",
355
+ label: "Carbon / Cobalt",
356
+ className: "theme-carbon-cobalt",
357
+ colors: ["#292a2d", "#356fe8"]
365
358
  },
366
359
  {
367
- id: "azure-coral",
368
- label: "Azure / Coral",
369
- className: "theme-azure-coral",
370
- colors: ["#217eff", "#f87763"]
360
+ id: "azure-ember",
361
+ label: "Azure / Ember",
362
+ className: "theme-azure-ember",
363
+ colors: ["#217eff", "#d85a1a"]
371
364
  },
372
365
  {
373
366
  id: "violet-teal",
@@ -382,10 +375,10 @@ const THEME_PALETTES = [
382
375
  colors: ["#ff6900", "#4f78f5"]
383
376
  },
384
377
  {
385
- id: "scarlet-cyan",
386
- label: "Scarlet / Cyan",
387
- className: "theme-scarlet-cyan",
388
- colors: ["#e3241b", "#0891b2"]
378
+ id: "brick-rose-cyan",
379
+ label: "Brick Rose / Cyan",
380
+ className: "theme-brick-rose-cyan",
381
+ colors: ["#b64a50", "#0891b2"]
389
382
  },
390
383
  {
391
384
  id: "lime-violet",
@@ -401,9 +394,7 @@ const THEME_PALETTES = [
401
394
  }
402
395
  ];
403
396
  function resolveThemeId(value) {
404
- const palette = THEME_PALETTES.find((item) => item.id === value);
405
- if (palette) return palette.id;
406
- if (value && Object.prototype.hasOwnProperty.call(LEGACY_THEME_IDS, value)) return LEGACY_THEME_IDS[value];
397
+ return THEME_PALETTES.find((item) => item.id === value)?.id;
407
398
  }
408
399
  var BxA11yService = class BxA11yService {
409
400
  document = inject(DOCUMENT$1);
@@ -477,7 +468,7 @@ var ThemingService = class ThemingService {
477
468
  _appearance = signal({ ...DEFAULT_APPEARANCE_CONFIG }, ...ngDevMode ? [{ debugName: "_appearance" }] : /* istanbul ignore next */ []);
478
469
  appearance = this._appearance.asReadonly();
479
470
  palettes = THEME_PALETTES;
480
- _palette = signal("graphite-sky-blue", ...ngDevMode ? [{ debugName: "_palette" }] : /* istanbul ignore next */ []);
471
+ _palette = signal("carbon-cobalt", ...ngDevMode ? [{ debugName: "_palette" }] : /* istanbul ignore next */ []);
481
472
  palette = this._palette.asReadonly();
482
473
  paletteLabel = computed(() => this.palettes.find((item) => item.id === this.palette())?.label ?? this.palettes[0].label, ...ngDevMode ? [{ debugName: "paletteLabel" }] : /* istanbul ignore next */ []);
483
474
  _highContrast = signal(false, ...ngDevMode ? [{ debugName: "_highContrast" }] : /* istanbul ignore next */ []);
@@ -505,7 +496,7 @@ var ThemingService = class ThemingService {
505
496
  this.restoreAppearance();
506
497
  const palette = this.readStored("theme-palette");
507
498
  const storedHighContrast = this.readStored("theme-high-contrast");
508
- this.setPalette(resolveThemeId(palette) ?? "graphite-sky-blue");
499
+ this.setPalette(resolveThemeId(palette) ?? "carbon-cobalt");
509
500
  this.setHighContrast(storedHighContrast === null ? palette === "high-contrast" : storedHighContrast === "true");
510
501
  this.appearanceController = configureAppearance(this.document.documentElement, {
511
502
  ...this.appearance(),
@@ -527,7 +518,6 @@ var ThemingService = class ThemingService {
527
518
  const id = resolveThemeId(palette);
528
519
  if (!id) return;
529
520
  this._palette.set(id);
530
- for (const legacy of Object.keys(LEGACY_THEME_IDS)) this.document.documentElement.classList.remove(`theme-${legacy}`);
531
521
  for (const item of this.palettes) this.document.documentElement.classList.toggle(item.className, item.id === id);
532
522
  if (this.isBrowser) this.writeStored("theme-palette", id);
533
523
  }
@@ -764,14 +754,13 @@ i0.ɵɵngDeclareClassMetadata({
764
754
  }]
765
755
  });
766
756
  var BxBaseControl = class BxBaseControl {
767
- isFieldRequired = computed(() => {
768
- if (this.required && this.required()) return true;
769
- const control = this.ngControl?.control;
770
- return control?.hasValidator ? control.hasValidator(Validators.required) : false;
771
- }, ...ngDevMode ? [{ debugName: "isFieldRequired" }] : /* istanbul ignore next */ []);
757
+ focusMonitor = inject(FocusMonitor);
758
+ focusElement = inject(ElementRef).nativeElement;
759
+ destroyRef = inject(DestroyRef);
772
760
  internalValue = signal(null, ...ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []);
773
761
  isTouched = signal(false, ...ngDevMode ? [{ debugName: "isTouched" }] : /* istanbul ignore next */ []);
774
762
  isDisabled = signal(false, ...ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []);
763
+ keyboardFocused = signal(false, ...ngDevMode ? [{ debugName: "keyboardFocused" }] : /* istanbul ignore next */ []);
775
764
  ngControl = inject(NgControl, {
776
765
  optional: true,
777
766
  self: true
@@ -783,18 +772,31 @@ var BxBaseControl = class BxBaseControl {
783
772
  ariaLabel = input(void 0, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
784
773
  errorMessages = input({}, ...ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []);
785
774
  required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
775
+ readonly = input(false, {
776
+ ...ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {},
777
+ transform: booleanAttribute
778
+ });
779
+ readOnly = input(false, {
780
+ ...ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {},
781
+ transform: booleanAttribute
782
+ });
783
+ isReadonly = computed(() => this.readonly() || this.readOnly(), ...ngDevMode ? [{ debugName: "isReadonly" }] : /* istanbul ignore next */ []);
786
784
  loading = input(false, ...ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []);
787
785
  disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
788
786
  onChange = () => {};
789
787
  onTouched = () => {};
790
788
  constructor() {
789
+ afterNextRender(() => {
790
+ this.focusMonitor.monitor(this.focusElement, true).pipe(takeUntilDestroyed(this.destroyRef)).subscribe((origin) => this.keyboardFocused.set(origin === "keyboard"));
791
+ this.destroyRef.onDestroy(() => this.focusMonitor.stopMonitoring(this.focusElement));
792
+ });
793
+ effect(() => {
794
+ this.isDisabled.set(this.disabled() || this.ngControl?.disabled === true);
795
+ });
791
796
  if (this.ngControl) this.ngControl.valueAccessor = this;
792
797
  }
793
798
  ngOnInit() {
794
799
  this.isDisabled.set(this.disabled() || this.ngControl?.disabled === true);
795
- if (isDevMode() && this.ngControl?.control?.validator) {
796
- if (!(Object.keys(this.errorMessages()).length > 0)) console.error(`[Blocks UI Strict Mode] The form control for this field has validators, but the [errorMessages] input is empty. You must provide error messages for all applied validators.`);
797
- }
798
800
  }
799
801
  writeValue(value) {
800
802
  this.internalValue.set(value);
@@ -809,15 +811,20 @@ var BxBaseControl = class BxBaseControl {
809
811
  this.isDisabled.set(isDisabled);
810
812
  }
811
813
  updateValue(value) {
812
- if (this.isDisabled()) return;
814
+ if (this.isDisabled() || this.isReadonly()) return;
813
815
  this.internalValue.set(value);
814
816
  this.onChange(value);
815
817
  }
816
818
  markAsTouched() {
817
- if (!this.isTouched()) {
818
- this.isTouched.set(true);
819
- this.onTouched();
820
- }
819
+ this.isTouched.set(true);
820
+ this.onTouched();
821
+ }
822
+ onControlPointerDown() {
823
+ if (this.isReadonly()) this.keyboardFocused.set(false);
824
+ }
825
+ isFieldRequired() {
826
+ const control = this.ngControl?.control;
827
+ return this.required() || !!control?.hasValidator?.(Validators.required) || !!control?.hasValidator?.(Validators.requiredTrue);
821
828
  }
822
829
  get errorMessage() {
823
830
  if (this.ngControl?.invalid && (this.ngControl.touched || this.ngControl.dirty)) {
@@ -826,7 +833,9 @@ var BxBaseControl = class BxBaseControl {
826
833
  const firstKey = Object.keys(errors)[0];
827
834
  const customErrorMap = this.errorMessages();
828
835
  if (customErrorMap && customErrorMap[firstKey]) return customErrorMap[firstKey];
829
- if (typeof errors[firstKey] === "string") return errors[firstKey];
836
+ const error = errors[firstKey];
837
+ if (typeof error === "string") return error;
838
+ if (error && typeof error === "object" && "message" in error && typeof error.message === "string") return error.message;
830
839
  if (isDevMode()) console.error(`[Blocks UI Strict Mode] Validation failed for key '${firstKey}', but no message was provided in [errorMessages].`);
831
840
  return `[Missing error message: ${firstKey}]`;
832
841
  }
@@ -894,6 +903,20 @@ var BxBaseControl = class BxBaseControl {
894
903
  isRequired: false,
895
904
  transformFunction: null
896
905
  },
906
+ readonly: {
907
+ classPropertyName: "readonly",
908
+ publicName: "readonly",
909
+ isSignal: true,
910
+ isRequired: false,
911
+ transformFunction: null
912
+ },
913
+ readOnly: {
914
+ classPropertyName: "readOnly",
915
+ publicName: "readOnly",
916
+ isSignal: true,
917
+ isRequired: false,
918
+ transformFunction: null
919
+ },
897
920
  loading: {
898
921
  classPropertyName: "loading",
899
922
  publicName: "loading",
@@ -909,6 +932,10 @@ var BxBaseControl = class BxBaseControl {
909
932
  transformFunction: null
910
933
  }
911
934
  },
935
+ host: {
936
+ listeners: { "pointerdown": "onControlPointerDown()" },
937
+ properties: { "class.bx-readonly": "isReadonly()" }
938
+ },
912
939
  ngImport: i0
913
940
  });
914
941
  };
@@ -917,7 +944,13 @@ i0.ɵɵngDeclareClassMetadata({
917
944
  version: "22.2.3",
918
945
  ngImport: i0,
919
946
  type: BxBaseControl,
920
- decorators: [{ type: Directive }],
947
+ decorators: [{
948
+ type: Directive,
949
+ args: [{ host: {
950
+ "[class.bx-readonly]": "isReadonly()",
951
+ "(pointerdown)": "onControlPointerDown()"
952
+ } }]
953
+ }],
921
954
  ctorParameters: () => [],
922
955
  propDecorators: {
923
956
  label: [{
@@ -976,6 +1009,22 @@ i0.ɵɵngDeclareClassMetadata({
976
1009
  required: false
977
1010
  }]
978
1011
  }],
1012
+ readonly: [{
1013
+ type: i0.Input,
1014
+ args: [{
1015
+ isSignal: true,
1016
+ alias: "readonly",
1017
+ required: false
1018
+ }]
1019
+ }],
1020
+ readOnly: [{
1021
+ type: i0.Input,
1022
+ args: [{
1023
+ isSignal: true,
1024
+ alias: "readOnly",
1025
+ required: false
1026
+ }]
1027
+ }],
979
1028
  loading: [{
980
1029
  type: i0.Input,
981
1030
  args: [{
@@ -999,15 +1048,15 @@ const SCROLL_LOCK_INSTANCE_IDENTIFIER = "scroll_lock_instance_";
999
1048
  const PALETTE_NAMES = [
1000
1049
  "primary",
1001
1050
  "accent",
1002
- "graphite",
1003
- "sky-blue",
1051
+ "carbon",
1052
+ "cobalt",
1053
+ "ember",
1054
+ "brick-rose",
1004
1055
  "azure",
1005
- "coral",
1006
1056
  "violet",
1007
1057
  "teal",
1008
1058
  "tangerine",
1009
1059
  "indigo",
1010
- "scarlet",
1011
1060
  "cyan",
1012
1061
  "lime",
1013
1062
  "cool-violet",
@@ -1282,6 +1331,11 @@ function trackOverlayOrigin(overlay, origin) {
1282
1331
  host.classList.remove("bx-overlay-tracked");
1283
1332
  };
1284
1333
  }
1285
- export { BREAKPOINTS, BX_I18N, BxA11yService, BxBaseControl, BxOverlayPositionService, BxShortcutService, DEFAULT_APPEARANCE_CONFIG, DEFAULT_DEBOUNCE_TIME, DesktopOS, DeviceTypeService, FALLBACK_COLOR, LEGACY_THEME_IDS, MobileOS, PALETTE_NAMES, SCROLL_LOCK_INSTANCE_IDENTIFIER, SEMANTIC_PAIRS, SHADE_NUMBERS, ScrollLockService, THEME_PALETTES, TOKEN_COLOR_DELIMITER, TOKEN_DELIMITER, TOKEN_PREFIX, ThemingService, WindowDimensionsService, getComplementaryToken, inheritOverlayTheme, invertPaletteToken, isOSShortcut, isPaletteToken, isTextWithKey, isThemedColor, resolveThemeId, resolveTokenToCssVar, trackOverlayOrigin, uuidv4 };
1334
+ function resolveText(text, adapter, params) {
1335
+ adapter?.version?.();
1336
+ if (text === void 0) return "";
1337
+ return isTextWithKey(text) ? adapter?.translate(text.key, params) ?? text.key : text;
1338
+ }
1339
+ export { BREAKPOINTS, BX_I18N, BxA11yService, BxBaseControl, BxOverlayPositionService, BxShortcutService, DEFAULT_APPEARANCE_CONFIG, DEFAULT_DEBOUNCE_TIME, DesktopOS, DeviceTypeService, FALLBACK_COLOR, MobileOS, PALETTE_NAMES, SCROLL_LOCK_INSTANCE_IDENTIFIER, SEMANTIC_PAIRS, SHADE_NUMBERS, ScrollLockService, THEME_PALETTES, TOKEN_COLOR_DELIMITER, TOKEN_DELIMITER, TOKEN_PREFIX, ThemingService, WindowDimensionsService, getComplementaryToken, inheritOverlayTheme, invertPaletteToken, isOSShortcut, isPaletteToken, isTextWithKey, isThemedColor, resolveText, resolveThemeId, resolveTokenToCssVar, trackOverlayOrigin, uuidv4 };
1286
1340
 
1287
1341
  //# sourceMappingURL=filip.mazev-blocks-core.mjs.map