@filip.mazev/blocks 1.2.35 → 1.2.37

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 (29) hide show
  1. package/blocks/schematics/ng-add/schema.json +6 -1
  2. package/core/styles/_index.scss +1 -0
  3. package/core/styles/_palettes.scss +31 -2
  4. package/core/styles/_theme-engine.scss +38 -30
  5. package/core/styles/themes/_cyberpunk-theme.scss +4 -0
  6. package/core/styles/themes/_high-contrast-theme.scss +6 -2
  7. package/fesm2022/filip.mazev-blocks-core.mjs +181 -44
  8. package/fesm2022/filip.mazev-blocks-core.mjs.map +1 -1
  9. package/fesm2022/filip.mazev-blocks-forms.mjs +341 -6
  10. package/fesm2022/filip.mazev-blocks-forms.mjs.map +1 -1
  11. package/fesm2022/filip.mazev-blocks-icons.mjs +2 -2
  12. package/fesm2022/filip.mazev-blocks-icons.mjs.map +1 -1
  13. package/fesm2022/filip.mazev-blocks-modal.mjs +8 -8
  14. package/fesm2022/filip.mazev-blocks-modal.mjs.map +1 -1
  15. package/fesm2022/filip.mazev-blocks-navigation.mjs +2 -2
  16. package/fesm2022/filip.mazev-blocks-navigation.mjs.map +1 -1
  17. package/fesm2022/filip.mazev-blocks-primitives.mjs +14 -11
  18. package/fesm2022/filip.mazev-blocks-primitives.mjs.map +1 -1
  19. package/fesm2022/filip.mazev-blocks-toastr.mjs +4 -4
  20. package/fesm2022/filip.mazev-blocks-toastr.mjs.map +1 -1
  21. package/fesm2022/filip.mazev-blocks.mjs +1 -1
  22. package/fesm2022/filip.mazev-blocks.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/schematics/ng-add/index.d.ts +1 -1
  25. package/schematics/ng-add/schema.json +6 -1
  26. package/types/filip.mazev-blocks-core.d.ts +86 -45
  27. package/types/filip.mazev-blocks-forms.d.ts +153 -3
  28. package/types/filip.mazev-blocks-primitives.d.ts +5 -2
  29. package/types/filip.mazev-blocks.d.ts +1 -1
@@ -11,7 +11,8 @@
11
11
  "purple",
12
12
  "orange",
13
13
  "red",
14
- "green"
14
+ "green",
15
+ "cyberpunk"
15
16
  ],
16
17
  "x-prompt": {
17
18
  "message": "Which theme would you like to use?",
@@ -32,6 +33,10 @@
32
33
  {
33
34
  "value": "green",
34
35
  "label": "Green Theme"
36
+ },
37
+ {
38
+ "value": "cyberpunk",
39
+ "label": "Cyberpunk"
35
40
  }
36
41
  ]
37
42
  },
@@ -9,4 +9,5 @@
9
9
  @forward 'themes/orange-theme';
10
10
  @forward 'themes/red-theme';
11
11
  @forward 'themes/green-theme';
12
+ @forward 'themes/cyberpunk-theme';
12
13
  @forward 'themes/high-contrast-theme';
@@ -115,7 +115,33 @@ $neutral-palette: (
115
115
  700: #404040,
116
116
  800: #262626,
117
117
  900: #171717,
118
- 1000: #0A0A0A) !default;
118
+ 1000: #0b0b0b) !default;
119
+
120
+ $cyber-yellow-palette: (
121
+ 50: #FFFEF2,
122
+ 100: #FFFDD1,
123
+ 200: #FFF9A3,
124
+ 300: #FFF370,
125
+ 400: #FFEB33,
126
+ 500: #e6da00,
127
+ 600: #CCBD00,
128
+ 700: #998E00,
129
+ 800: #665E00,
130
+ 900: #332F00,
131
+ 1000: #141300) !default;
132
+
133
+ $cyber-slate-palette: (
134
+ 50: #EBEFF2,
135
+ 100: #CDD6DF,
136
+ 200: #A8B8C6,
137
+ 300: #7E96A9,
138
+ 400: #5D788C,
139
+ 500: #3E5669,
140
+ 600: #283C4C,
141
+ 700: #1B2936,
142
+ 800: #121A21,
143
+ 900: #0B1015,
144
+ 1000: #05080A) !default;
119
145
 
120
146
  $hc-black: #000000;
121
147
  $hc-white: #ffffff;
@@ -133,7 +159,10 @@ $all-palettes: (
133
159
  'warn': $warn-palette,
134
160
  'success': $success-palette,
135
161
  'information': $information-palette,
136
- 'neutral': $neutral-palette) !default;
162
+ 'neutral': $neutral-palette,
163
+
164
+ 'cyber-yellow': $cyber-yellow-palette,
165
+ 'cyber-slate': $cyber-slate-palette) !default;
137
166
 
138
167
  @function get-palette($name) {
139
168
  @if map.has-key($all-palettes, $name) {
@@ -62,7 +62,9 @@ $required-theme-keys: (
62
62
 
63
63
  'scroll-bg',
64
64
  'scroll-thumb',
65
- 'scroll-thumb-hover'
65
+ 'scroll-thumb-hover',
66
+
67
+ 'meta-brand-palette'
66
68
  );
67
69
 
68
70
  @function validate-theme($theme, $theme-name) {
@@ -73,33 +75,35 @@ $required-theme-keys: (
73
75
  }
74
76
 
75
77
  @each $key, $value in $theme {
76
- @if not list.index($required-theme-keys, $key) {
77
- @error "Strict Theme Error: '#{$theme-name}' contains an invalid key '#{$key}'. Remove or rename it.";
78
+ @if string.index($key, 'meta-') !=1 {
79
+ @if not list.index($required-theme-keys, $key) {
80
+ @error "Strict Theme Error: '#{$theme-name}' contains an invalid key '#{$key}'. Remove or rename it.";
81
+ }
78
82
  }
79
83
  }
80
84
 
81
85
  @return $theme;
82
86
  }
83
87
 
84
- @function make-light-theme($brand, $overrides: ()) {
88
+ @function make-light-theme($surface-brand, $accent: $surface-brand, $overrides: ()) {
85
89
  $base: (
86
90
  'bg-canvas': #ffffff,
87
91
  'bg-surface': #ffffff,
88
- 'bg-surface-alt': get-color-from-palette($brand, 50),
92
+ 'bg-surface-alt': get-color-from-palette($surface-brand, 50),
89
93
  'bg-element': get-color-from-palette('neutral', 100),
90
- 'bg-element-hover': get-color-from-palette($brand, 200),
91
- 'bg-element-active': get-color-from-palette($brand, 300),
94
+ 'bg-element-hover': get-color-from-palette($surface-brand, 200),
95
+ 'bg-element-active': get-color-from-palette($surface-brand, 300),
92
96
 
93
- 'primary': get-color-from-palette($brand, 500),
94
- 'primary-hover': get-color-from-palette($brand, 600),
95
- 'primary-active': get-color-from-palette($brand, 700),
96
- 'primary-subtle': rgba(get-color-from-palette($brand, 300), 0.6),
97
+ 'primary': get-color-from-palette($accent, 500),
98
+ 'primary-hover': get-color-from-palette($accent, 600),
99
+ 'primary-active': get-color-from-palette($accent, 700),
100
+ 'primary-subtle': rgba(get-color-from-palette($accent, 300), 0.6),
97
101
  'on-primary': get-color-from-palette('neutral', 100),
98
102
 
99
103
  'text-heading': get-color-from-palette('neutral', 900),
100
104
  'text-primary': get-color-from-palette('neutral', 700),
101
105
  'text-secondary': get-color-from-palette('neutral', 500),
102
- 'text-brand': get-color-from-palette($brand, 700),
106
+ 'text-brand': get-color-from-palette($accent, 700),
103
107
  'text-inverse': get-color-from-palette('neutral', 100),
104
108
  'text-info': get-color-from-palette('information', 700),
105
109
  'text-warn': get-color-from-palette('warn', 700),
@@ -109,7 +113,7 @@ $required-theme-keys: (
109
113
  'border-subtle': get-color-from-palette('neutral', 200),
110
114
  'border-default': get-color-from-palette('neutral', 300),
111
115
  'border-strong': get-color-from-palette('neutral', 400),
112
- 'border-brand': get-color-from-palette($brand, 400),
116
+ 'border-brand': get-color-from-palette($accent, 400),
113
117
  'border-info': get-color-from-palette('information', 400),
114
118
  'border-success': get-color-from-palette('success', 400),
115
119
  'border-warn': get-color-from-palette('warn', 400),
@@ -139,35 +143,37 @@ $required-theme-keys: (
139
143
  'bg-danger-disabled': get-color-from-palette('danger', 50),
140
144
  'bg-danger-subtle': rgba(get-color-from-palette('danger', 50), 0.95),
141
145
 
142
- 'scroll-bg': get-color-from-palette($brand, 100),
143
- 'scroll-thumb': linear-gradient(278deg, get-color-from-palette($brand, 300) -10.44%, get-color-from-palette($brand, 400) 100%),
144
- 'scroll-thumb-hover': linear-gradient(278deg, get-color-from-palette($brand, 400) -10.44%, get-color-from-palette($brand, 700) 100%),
146
+ 'scroll-bg': get-color-from-palette($surface-brand, 100),
147
+ 'scroll-thumb': linear-gradient(278deg, get-color-from-palette($accent, 300) -10.44%, get-color-from-palette($accent, 400) 100%),
148
+ 'scroll-thumb-hover': linear-gradient(278deg, get-color-from-palette($accent, 400) -10.44%, get-color-from-palette($accent, 700) 100%),
149
+
150
+ 'meta-brand-palette': $accent
145
151
  );
146
152
 
147
153
  $merged-theme: map.merge($base, $overrides);
148
154
 
149
- @return validate-theme($merged-theme, '#{$brand}-light');
155
+ @return validate-theme($merged-theme, '#{$surface-brand}-#{$accent}-light');
150
156
  }
151
157
 
152
- @function make-dark-theme($brand, $overrides: ()) {
158
+ @function make-dark-theme($surface-brand, $accent: $surface-brand, $overrides: ()) {
153
159
  $base: (
154
160
  'bg-canvas': #000000,
155
161
  'bg-surface': get-color-from-palette('neutral', 1000),
156
162
  'bg-surface-alt': get-color-from-palette('neutral', 900),
157
163
  'bg-element': get-color-from-palette('neutral', 800),
158
- 'bg-element-hover': get-color-from-palette($brand, 700),
159
- 'bg-element-active': get-color-from-palette($brand, 800),
164
+ 'bg-element-hover': get-color-from-palette($surface-brand, 700),
165
+ 'bg-element-active': get-color-from-palette($surface-brand, 800),
160
166
 
161
- 'primary': get-color-from-palette($brand, 500),
162
- 'primary-hover': get-color-from-palette($brand, 400),
163
- 'primary-active': get-color-from-palette($brand, 300),
164
- 'primary-subtle': rgba(get-color-from-palette($brand, 700), 0.6),
167
+ 'primary': get-color-from-palette($accent, 500),
168
+ 'primary-hover': get-color-from-palette($accent, 400),
169
+ 'primary-active': get-color-from-palette($accent, 300),
170
+ 'primary-subtle': rgba(get-color-from-palette($accent, 700), 0.6),
165
171
  'on-primary': #ffffff,
166
172
 
167
173
  'text-heading': #ffffff,
168
174
  'text-primary': get-color-from-palette('neutral', 200),
169
175
  'text-secondary': get-color-from-palette('neutral', 400),
170
- 'text-brand': get-color-from-palette($brand, 300),
176
+ 'text-brand': get-color-from-palette($accent, 300),
171
177
  'text-inverse': get-color-from-palette('neutral', 900),
172
178
  'text-info': get-color-from-palette('information', 400),
173
179
  'text-success': get-color-from-palette('success', 400),
@@ -177,7 +183,7 @@ $merged-theme: map.merge($base, $overrides);
177
183
  'border-subtle': get-color-from-palette('neutral', 900),
178
184
  'border-default': get-color-from-palette('neutral', 800),
179
185
  'border-strong': get-color-from-palette('neutral', 700),
180
- 'border-brand': get-color-from-palette($brand, 600),
186
+ 'border-brand': get-color-from-palette($accent, 600),
181
187
  'border-info': get-color-from-palette('information', 400),
182
188
  'border-success': get-color-from-palette('success', 400),
183
189
  'border-warn': get-color-from-palette('warn', 400),
@@ -207,14 +213,16 @@ $merged-theme: map.merge($base, $overrides);
207
213
  'bg-danger-disabled': get-color-from-palette('danger', 1000),
208
214
  'bg-danger-subtle': rgba(get-color-from-palette('danger', 1000), 0.95),
209
215
 
210
- 'scroll-bg': get-color-from-palette($brand, 900),
211
- 'scroll-thumb': linear-gradient(278deg, get-color-from-palette($brand, 700) -10.44%, get-color-from-palette($brand, 500) 100%),
212
- 'scroll-thumb-hover': linear-gradient(278deg, get-color-from-palette($brand, 500) -10.44%, get-color-from-palette($brand, 400) 100%),
216
+ 'scroll-bg': get-color-from-palette($surface-brand, 900),
217
+ 'scroll-thumb': linear-gradient(278deg, get-color-from-palette($accent, 700) -10.44%, get-color-from-palette($accent, 500) 100%),
218
+ 'scroll-thumb-hover': linear-gradient(278deg, get-color-from-palette($accent, 500) -10.44%, get-color-from-palette($accent, 400) 100%),
219
+
220
+ 'meta-brand-palette': $accent
213
221
  );
214
222
 
215
223
  $merged-theme: map.merge($base, $overrides);
216
224
 
217
- @return validate-theme($merged-theme, '#{$brand}-dark');
225
+ @return validate-theme($merged-theme, '#{$surface-brand}-#{$accent}-dark');
218
226
  }
219
227
 
220
228
  @mixin bx-theme($config) {
@@ -0,0 +1,4 @@
1
+ @use '../theme-engine' as *;
2
+
3
+ $cyberpunk-light-theme: make-light-theme('cyber-slate', 'cyber-yellow');
4
+ $cyberpunk-dark-theme: make-dark-theme('cyber-slate', 'cyber-yellow');
@@ -59,7 +59,9 @@ $high-contrast-light-theme: validate-theme(('bg-canvas': $hc-white,
59
59
 
60
60
  'scroll-bg': $hc-white,
61
61
  'scroll-thumb': $hc-black,
62
- 'scroll-thumb-hover': $hc-yellow), 'high-contrast-light') !default;
62
+ 'scroll-thumb-hover': $hc-yellow,
63
+
64
+ 'meta-brand-palette': 'neutral'), 'high-contrast-light') !default;
63
65
 
64
66
  $high-contrast-dark-theme: validate-theme(('bg-canvas': $hc-black,
65
67
  'bg-surface': $hc-black,
@@ -119,4 +121,6 @@ $high-contrast-dark-theme: validate-theme(('bg-canvas': $hc-black,
119
121
 
120
122
  'scroll-bg': $hc-black,
121
123
  'scroll-thumb': $hc-white,
122
- 'scroll-thumb-hover': $hc-yellow), 'high-contrast-dark') !default;
124
+ 'scroll-thumb-hover': $hc-yellow,
125
+
126
+ 'meta-brand-palette': 'neutral'), 'high-contrast-dark') !default;
@@ -1,10 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, NgZone, PLATFORM_ID, signal, computed, effect, InjectionToken } from '@angular/core';
3
- import { isPlatformBrowser, DOCUMENT } from '@angular/common';
2
+ import { inject, PLATFORM_ID, Injectable, NgZone, signal, computed, effect, input, isDevMode, Directive, InjectionToken } from '@angular/core';
3
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
4
4
  import { fromEvent } from 'rxjs';
5
5
  import { debounceTime, map, distinctUntilChanged } from 'rxjs/operators';
6
6
  import { toObservable } from '@angular/core/rxjs-interop';
7
7
  import { Overlay, ConnectionPositionPair } from '@angular/cdk/overlay';
8
+ import { NgControl } from '@angular/forms';
8
9
 
9
10
  var DesktopOS;
10
11
  (function (DesktopOS) {
@@ -24,22 +25,38 @@ var MobileOS;
24
25
  })(MobileOS || (MobileOS = {}));
25
26
 
26
27
  class DeviceTypeService {
27
- isDesktopDevice = !this.isMobileDevice() && !this.isTabletDevice();
28
- userAgent = navigator.userAgent || navigator.vendor || window?.opera || undefined;
29
- supportedScreenOrientation = (screen?.orientation || {}).type ?? screen.mozOrientation ?? screen.msOrientation;
30
- safariScreenOrientation = !screen?.orientation && matchMedia('(orientation: portrait)').matches ? 'portrait-primary' : 'landscape-primary';
31
- initialScreenOrientation = this.supportedScreenOrientation ?? this.safariScreenOrientation ?? 'portrait-primary';
32
- screenOrientation = this.initialScreenOrientation;
28
+ document = inject(DOCUMENT);
29
+ platformId = inject(PLATFORM_ID);
30
+ isBrowser = isPlatformBrowser(this.platformId);
31
+ screenOrientation = 'portrait-primary';
33
32
  constructor() {
34
- if (screen.orientation) {
35
- screen.orientation.addEventListener('change', (ev) => {
36
- const orientation = ev.target;
37
- if (orientation?.type) {
38
- this.screenOrientation = orientation.type;
39
- }
40
- });
33
+ if (this.isBrowser) {
34
+ const win = this.document.defaultView;
35
+ const screenObj = win?.screen;
36
+ this.screenOrientation =
37
+ (screenObj?.orientation || {}).type ??
38
+ screenObj?.mozOrientation ??
39
+ screenObj?.msOrientation ??
40
+ (!screenObj?.orientation && win?.matchMedia('(orientation: portrait)').matches ? 'portrait-primary' : 'landscape-primary');
41
+ if (screenObj?.orientation) {
42
+ screenObj.orientation.addEventListener('change', (ev) => {
43
+ const orientation = ev.target;
44
+ if (orientation?.type) {
45
+ this.screenOrientation = orientation.type;
46
+ }
47
+ });
48
+ }
41
49
  }
42
50
  }
51
+ get userAgent() {
52
+ if (!this.isBrowser)
53
+ return '';
54
+ const win = this.document.defaultView;
55
+ return win?.navigator?.userAgent || win?.navigator?.vendor || win?.opera || '';
56
+ }
57
+ get isDesktopDevice() {
58
+ return !this.isMobileDevice() && !this.isTabletDevice();
59
+ }
43
60
  isLandscapeOrientation() {
44
61
  return ['landscape-primary', 'landscape-secondary'].includes(this.screenOrientation);
45
62
  }
@@ -47,26 +64,22 @@ class DeviceTypeService {
47
64
  return ['portrait-primary', 'portrait-secondary'].includes(this.screenOrientation);
48
65
  }
49
66
  getDeviceState() {
50
- const isDesktop = this.isDesktopDevice;
51
67
  const isMobile = this.isMobileDevice();
52
68
  const isTablet = this.isTabletDevice();
69
+ const isDesktop = this.isDesktopDevice;
53
70
  const mobileOS = this.getMobileOS();
54
- const isAndroidDevice = this.getDeviceOS() === MobileOS.Android;
55
- const isAppleDevice = this.getDeviceOS() === MobileOS.iOS || this.getDeviceOS() === DesktopOS.MacOS;
56
- const isUnknownMobileDevice = this.getDeviceOS() === MobileOS.Unknown;
57
71
  const desktopOS = this.getDesktopOS();
58
- const isWindowsDesktop = this.getDeviceOS() === DesktopOS.Windows;
59
- const isLinuxOrUnixDesktop = this.getDeviceOS() === DesktopOS.Linux || this.getDeviceOS() === DesktopOS.Unix;
72
+ const deviceOS = mobileOS ?? desktopOS;
60
73
  return {
61
74
  isDesktop,
62
75
  desktopOS,
63
- isWindowsDesktop,
64
- isLinuxOrUnixDesktop,
76
+ isWindowsDesktop: deviceOS === DesktopOS.Windows,
77
+ isLinuxOrUnixDesktop: deviceOS === DesktopOS.Linux || deviceOS === DesktopOS.Unix,
65
78
  isMobile,
66
79
  mobileOS,
67
- isAndroidDevice,
68
- isAppleDevice,
69
- isUnknownMobileDevice,
80
+ isAndroidDevice: deviceOS === MobileOS.Android,
81
+ isAppleDevice: deviceOS === MobileOS.iOS || deviceOS === DesktopOS.MacOS,
82
+ isUnknownMobileDevice: deviceOS === MobileOS.Unknown,
70
83
  isTablet,
71
84
  isLandscapeOrientation: () => this.isLandscapeOrientation(),
72
85
  isPortraitOrientation: () => this.isPortraitOrientation()
@@ -74,41 +87,39 @@ class DeviceTypeService {
74
87
  }
75
88
  isMobileDevice() {
76
89
  const regexs = [/(Android)(.+)(Mobile)/i, /BlackBerry/i, /iPhone|iPod/i, /Opera Mini/i, /IEMobile/i];
77
- return regexs.some((b) => this.userAgent?.match(b) !== null);
90
+ return regexs.some((regex) => regex.test(this.userAgent));
78
91
  }
79
92
  isTabletDevice() {
80
- const regex = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/;
81
- return regex.test(this.userAgent?.toLowerCase() ?? '');
93
+ const regex = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/i;
94
+ return regex.test(this.userAgent);
82
95
  }
83
96
  getMobileOS() {
84
- if (this.isMobileDevice() && this.userAgent) {
85
- if (/windows phone/i.test(this.userAgent))
97
+ if (this.isMobileDevice()) {
98
+ const ua = this.userAgent;
99
+ if (/windows phone/i.test(ua))
86
100
  return MobileOS.WindowsPhone;
87
- else if (/android/i.test(this.userAgent))
101
+ if (/android/i.test(ua))
88
102
  return MobileOS.Android;
89
- else if (/iPad|iPhone|iPod/.test(this.userAgent) && !window.MSStream)
103
+ if (/iPad|iPhone|iPod/.test(ua) && !this.document.defaultView?.MSStream)
90
104
  return MobileOS.iOS;
91
105
  return MobileOS.Unknown;
92
106
  }
93
107
  return undefined;
94
108
  }
95
109
  getDesktopOS() {
96
- if (this.isDesktopDevice && this.userAgent) {
97
- if (this.userAgent.indexOf('Win') !== -1)
110
+ if (this.isDesktopDevice) {
111
+ const ua = this.userAgent;
112
+ if (ua.includes('Win'))
98
113
  return DesktopOS.Windows;
99
- else if (this.userAgent.indexOf('Mac') !== -1)
114
+ if (ua.includes('Mac'))
100
115
  return DesktopOS.MacOS;
101
- else if (this.userAgent.indexOf('X11') !== -1)
116
+ if (ua.includes('X11'))
102
117
  return DesktopOS.Unix;
103
- else if (this.userAgent.indexOf('Linux') !== -1)
118
+ if (ua.includes('Linux'))
104
119
  return DesktopOS.Linux;
105
120
  return DesktopOS.Unknown;
106
121
  }
107
- else
108
- return undefined;
109
- }
110
- getDeviceOS() {
111
- return this.getMobileOS() ?? this.getDesktopOS();
122
+ return undefined;
112
123
  }
113
124
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DeviceTypeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
114
125
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DeviceTypeService, providedIn: 'root' });
@@ -469,6 +480,132 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
469
480
  args: [{ providedIn: 'root' }]
470
481
  }] });
471
482
 
483
+ function isOSShortcut(val) {
484
+ return (typeof val === 'object' &&
485
+ val !== null &&
486
+ !Array.isArray(val) &&
487
+ 'default' in val);
488
+ }
489
+
490
+ class BxShortcutService {
491
+ deviceTypeService = inject(DeviceTypeService);
492
+ resolve(shortcut) {
493
+ if (!shortcut)
494
+ return undefined;
495
+ let resolvedKey;
496
+ if (isOSShortcut(shortcut)) {
497
+ const state = this.deviceTypeService.getDeviceState();
498
+ if (state.isAppleDevice && shortcut.mac) {
499
+ resolvedKey = shortcut.mac;
500
+ }
501
+ else if (state.isWindowsDesktop && shortcut.windows) {
502
+ resolvedKey = shortcut.windows;
503
+ }
504
+ else if (state.isLinuxOrUnixDesktop && shortcut.linux) {
505
+ resolvedKey = shortcut.linux;
506
+ }
507
+ else {
508
+ resolvedKey = shortcut.default;
509
+ }
510
+ }
511
+ else {
512
+ resolvedKey = shortcut;
513
+ }
514
+ return Array.isArray(resolvedKey) ? resolvedKey : [resolvedKey];
515
+ }
516
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BxShortcutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
517
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BxShortcutService, providedIn: 'root' });
518
+ }
519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BxShortcutService, decorators: [{
520
+ type: Injectable,
521
+ args: [{
522
+ providedIn: 'root'
523
+ }]
524
+ }] });
525
+
526
+ class BxBaseControl {
527
+ ngControl = inject(NgControl, { optional: true, self: true });
528
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
529
+ placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
530
+ tooltip = input(undefined, ...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
531
+ dataTestId = input(undefined, ...(ngDevMode ? [{ debugName: "dataTestId" }] : /* istanbul ignore next */ []));
532
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
533
+ errorMessages = input({}, ...(ngDevMode ? [{ debugName: "errorMessages" }] : /* istanbul ignore next */ []));
534
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
535
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
536
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
537
+ internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
538
+ isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : /* istanbul ignore next */ []));
539
+ isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
540
+ onChange = () => { };
541
+ onTouched = () => { };
542
+ constructor() {
543
+ if (this.ngControl) {
544
+ this.ngControl.valueAccessor = this;
545
+ }
546
+ }
547
+ ngOnInit() {
548
+ this.isDisabled.set(this.disabled());
549
+ if (isDevMode() && this.ngControl?.control?.validator) {
550
+ const hasMessages = Object.keys(this.errorMessages()).length > 0;
551
+ if (!hasMessages) {
552
+ 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.`);
553
+ }
554
+ }
555
+ }
556
+ writeValue(value) {
557
+ this.internalValue.set(value);
558
+ }
559
+ registerOnChange(fn) {
560
+ this.onChange = fn;
561
+ }
562
+ registerOnTouched(fn) {
563
+ this.onTouched = fn;
564
+ }
565
+ setDisabledState(isDisabled) {
566
+ this.isDisabled.set(isDisabled);
567
+ }
568
+ updateValue(value) {
569
+ if (this.isDisabled())
570
+ return;
571
+ this.internalValue.set(value);
572
+ this.onChange(value);
573
+ }
574
+ markAsTouched() {
575
+ if (!this.isTouched()) {
576
+ this.isTouched.set(true);
577
+ this.onTouched();
578
+ }
579
+ }
580
+ get errorMessage() {
581
+ if (this.ngControl?.invalid && (this.ngControl.touched || this.ngControl.dirty)) {
582
+ const errors = this.ngControl.errors;
583
+ if (!errors)
584
+ return undefined;
585
+ const firstKey = Object.keys(errors)[0];
586
+ const customErrorMap = this.errorMessages();
587
+ if (customErrorMap && customErrorMap[firstKey]) {
588
+ return customErrorMap[firstKey];
589
+ }
590
+ if (typeof errors[firstKey] === 'string') {
591
+ return errors[firstKey];
592
+ }
593
+ if (isDevMode()) {
594
+ console.error(`[Blocks UI Strict Mode] Validation failed for key '${firstKey}', but no message was provided in [errorMessages].`);
595
+ }
596
+ return `[Missing error message: ${firstKey}]`;
597
+ }
598
+ return undefined;
599
+ }
600
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BxBaseControl, deps: [], target: i0.ɵɵFactoryTarget.Directive });
601
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: BxBaseControl, isStandalone: true, inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, dataTestId: { classPropertyName: "dataTestId", publicName: "dataTestId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
602
+ }
603
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BxBaseControl, decorators: [{
604
+ type: Directive
605
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], dataTestId: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataTestId", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
606
+
607
+ const DEFAULT_DEBOUNCE_TIME = 300;
608
+
472
609
  const SCROLL_LOCK_INSTANCE_IDENTIFIER = 'scroll_lock_instance_';
473
610
 
474
611
  const PALETTE_NAMES = ['orange', 'purple', 'red', 'green', 'danger', 'success', 'information', 'neutral'];
@@ -614,5 +751,5 @@ function uuidv4() {
614
751
  * Generated bundle index. Do not edit.
615
752
  */
616
753
 
617
- export { BREAKPOINTS, BX_I18N, BxA11yService, BxOverlayPositionService, DesktopOS, DeviceTypeService, FALLBACK_COLOR, MobileOS, PALETTE_NAMES, SCROLL_LOCK_INSTANCE_IDENTIFIER, SEMANTIC_PAIRS, SHADE_NUMBERS, ScrollLockService, TOKEN_COLOR_DELIMITER, TOKEN_DELIMITER, TOKEN_PREFIX, ThemingService, WindowDimensionsService, getComplementaryToken, invertPaletteToken, isPaletteToken, isTextWithKey, isThemedColor, resolveTokenToCssVar, uuidv4 };
754
+ export { BREAKPOINTS, BX_I18N, BxA11yService, BxBaseControl, BxOverlayPositionService, BxShortcutService, DEFAULT_DEBOUNCE_TIME, DesktopOS, DeviceTypeService, FALLBACK_COLOR, MobileOS, PALETTE_NAMES, SCROLL_LOCK_INSTANCE_IDENTIFIER, SEMANTIC_PAIRS, SHADE_NUMBERS, ScrollLockService, TOKEN_COLOR_DELIMITER, TOKEN_DELIMITER, TOKEN_PREFIX, ThemingService, WindowDimensionsService, getComplementaryToken, invertPaletteToken, isOSShortcut, isPaletteToken, isTextWithKey, isThemedColor, resolveTokenToCssVar, uuidv4 };
618
755
  //# sourceMappingURL=filip.mazev-blocks-core.mjs.map