@ssv/ngx.ux 2.0.2 → 2.1.0-dev.23

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 (75) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +296 -297
  3. package/config.d.ts +7 -7
  4. package/esm2020/config.mjs +7 -7
  5. package/esm2020/index.mjs +5 -5
  6. package/esm2020/internal/internal.model.mjs +2 -2
  7. package/esm2020/module.mjs +65 -65
  8. package/esm2020/platform/window.mjs +30 -30
  9. package/esm2020/ssv-ngx.ux.mjs +4 -4
  10. package/esm2020/version.mjs +2 -2
  11. package/esm2020/viewport/index.mjs +9 -9
  12. package/esm2020/viewport/viewport-data/index.mjs +4 -4
  13. package/esm2020/viewport/viewport-data/viewport-data-matcher.mjs +108 -108
  14. package/esm2020/viewport/viewport-data/viewport-data.pipe.mjs +43 -43
  15. package/esm2020/viewport/viewport-data/viewport-data.service.mjs +37 -37
  16. package/esm2020/viewport/viewport-data/viewport-data.utils.mjs +100 -100
  17. package/esm2020/viewport/viewport-matcher-var.directive.mjs +63 -63
  18. package/esm2020/viewport/viewport-matcher.directive.mjs +131 -131
  19. package/esm2020/viewport/viewport-server-size.service.mjs +43 -43
  20. package/esm2020/viewport/viewport.const.mjs +17 -18
  21. package/esm2020/viewport/viewport.model.mjs +30 -31
  22. package/esm2020/viewport/viewport.service.mjs +66 -67
  23. package/esm2020/viewport/viewport.util.mjs +117 -117
  24. package/fesm2015/ssv-ngx.ux.mjs +787 -790
  25. package/fesm2015/ssv-ngx.ux.mjs.map +1 -1
  26. package/fesm2020/ssv-ngx.ux.mjs +781 -784
  27. package/fesm2020/ssv-ngx.ux.mjs.map +1 -1
  28. package/index.d.ts +4 -4
  29. package/internal/internal.model.d.ts +9 -9
  30. package/module.d.ts +19 -19
  31. package/package.json +1 -1
  32. package/platform/window.d.ts +13 -13
  33. package/version.d.ts +1 -1
  34. package/viewport/index.d.ts +8 -8
  35. package/viewport/viewport-data/index.d.ts +3 -3
  36. package/viewport/viewport-data/viewport-data-matcher.d.ts +32 -32
  37. package/viewport/viewport-data/viewport-data.pipe.d.ts +18 -18
  38. package/viewport/viewport-data/viewport-data.service.d.ts +20 -20
  39. package/viewport/viewport-data/viewport-data.utils.d.ts +21 -21
  40. package/viewport/viewport-matcher-var.directive.d.ts +25 -25
  41. package/viewport/viewport-matcher.directive.d.ts +33 -33
  42. package/viewport/viewport-server-size.service.d.ts +12 -12
  43. package/viewport/viewport.const.d.ts +5 -5
  44. package/viewport/viewport.model.d.ts +56 -57
  45. package/viewport/viewport.service.d.ts +37 -37
  46. package/viewport/viewport.util.d.ts +25 -25
  47. package/CHANGELOG.md +0 -149
  48. package/bundles/ssv-ngx.ux.umd.js +0 -1219
  49. package/bundles/ssv-ngx.ux.umd.js.map +0 -1
  50. package/bundles/ssv-ngx.ux.umd.min.js +0 -16
  51. package/bundles/ssv-ngx.ux.umd.min.js.map +0 -1
  52. package/esm2015/config.js +0 -7
  53. package/esm2015/index.js +0 -5
  54. package/esm2015/internal/internal.model.js +0 -2
  55. package/esm2015/module.js +0 -50
  56. package/esm2015/platform/window.js +0 -28
  57. package/esm2015/ssv-ngx.ux.js +0 -7
  58. package/esm2015/version.js +0 -2
  59. package/esm2015/viewport/index.js +0 -9
  60. package/esm2015/viewport/viewport-data/index.js +0 -4
  61. package/esm2015/viewport/viewport-data/viewport-data-matcher.js +0 -108
  62. package/esm2015/viewport/viewport-data/viewport-data.pipe.js +0 -43
  63. package/esm2015/viewport/viewport-data/viewport-data.service.js +0 -38
  64. package/esm2015/viewport/viewport-data/viewport-data.utils.js +0 -100
  65. package/esm2015/viewport/viewport-matcher-var.directive.js +0 -64
  66. package/esm2015/viewport/viewport-matcher.directive.js +0 -134
  67. package/esm2015/viewport/viewport-server-size.service.js +0 -38
  68. package/esm2015/viewport/viewport.const.js +0 -18
  69. package/esm2015/viewport/viewport.model.js +0 -31
  70. package/esm2015/viewport/viewport.service.js +0 -69
  71. package/esm2015/viewport/viewport.util.js +0 -117
  72. package/fesm2015/ssv-ngx.ux.js +0 -807
  73. package/fesm2015/ssv-ngx.ux.js.map +0 -1
  74. package/ssv-ngx.ux.d.ts +0 -6
  75. package/ssv-ngx.ux.metadata.json +0 -1
@@ -3,820 +3,817 @@ import { InjectionToken, Injectable, Inject, Optional, Pipe, Directive, Input, N
3
3
  import { map, share, auditTime, startWith, distinctUntilChanged, shareReplay, tap, takeUntil, filter, pairwise } from 'rxjs/operators';
4
4
  import { fromEvent, of, Subscription, Subject, ReplaySubject, combineLatest } from 'rxjs';
5
5
 
6
- var ViewportDataMatchStrategy;
7
- (function (ViewportDataMatchStrategy) {
8
- /** Indicates that size should match exact or default. */
9
- ViewportDataMatchStrategy[ViewportDataMatchStrategy["exact"] = 0] = "exact";
10
- /** Indicates that size matches when exact match, first match smaller (down) or default. */
11
- ViewportDataMatchStrategy[ViewportDataMatchStrategy["smaller"] = 1] = "smaller";
12
- /** Indicates that size matches when exact match, first match larger (up) or default. */
13
- ViewportDataMatchStrategy[ViewportDataMatchStrategy["larger"] = 2] = "larger";
14
- /** Indicates that size matches when exact match, or it tries both smaller/larger (smaller is preferred) until match or default. */
15
- ViewportDataMatchStrategy[ViewportDataMatchStrategy["closestSmallerFirst"] = 3] = "closestSmallerFirst";
16
- /** Indicates that size matches when exact match, or it tries both larger/smaller (larger is preferred) until match or default. */
17
- ViewportDataMatchStrategy[ViewportDataMatchStrategy["closestLargerFirst"] = 4] = "closestLargerFirst";
18
- })(ViewportDataMatchStrategy || (ViewportDataMatchStrategy = {}));
19
- /**
20
- * Utility function to match data based on strategy and size.
21
- *
22
- * @param dataConfig Data config to generate rules based on.
23
- * @param sizeType Size type to get data for.
24
- * @param strategy Strategy to use when building rules.
25
- * @param sizeTypes Available size types ordered by index type. (Can be obtained from `ViewportService`)
26
- * @param sizeTypeMap Available size type map. (Can be obtained from `ViewportService`)
27
- * @returns Returns the matched data value.
28
- */
29
- function matchViewportData(dataConfig, sizeType, strategy, sizeTypes, sizeTypeMap) {
30
- const matchFn = matchStrategyHandlerMap$1[strategy];
31
- if (!matchFn) {
32
- throw Error(`matchViewportData: Viewport Data strategy not implemented. Strategy: '${strategy}'`);
33
- }
34
- const data = matchFn(dataConfig, sizeType, sizeTypes, sizeTypeMap);
35
- if (data !== undefined) {
36
- return data;
37
- }
38
- return dataConfig.default;
39
- }
40
- const matchStrategyHandlerMap$1 = {
41
- [ViewportDataMatchStrategy.exact]: matchWithExact,
42
- [ViewportDataMatchStrategy.larger]: matchWithLargerMatch,
43
- [ViewportDataMatchStrategy.smaller]: matchWithSmallerMatch,
44
- [ViewportDataMatchStrategy.closestSmallerFirst]: matchWithClosestSmallerFirstMatch,
45
- [ViewportDataMatchStrategy.closestLargerFirst]: matchWithClosestLargerFirstMatch,
46
- };
47
- function matchWithExact(dataConfig, currentSizeType) {
48
- return dataConfig[currentSizeType.name];
49
- }
50
- function matchWithLargerMatch(dataConfig, currentSizeType, sizeTypes) {
51
- let data = dataConfig[currentSizeType.name];
52
- if (data !== undefined) {
53
- return data;
54
- }
55
- const largestTypeIdx = sizeTypes[sizeTypes.length - 1].type;
56
- if (currentSizeType.type >= largestTypeIdx) {
57
- return undefined;
58
- }
59
- for (let index = currentSizeType.type; index < sizeTypes.length; index++) {
60
- const sizeType = sizeTypes[index];
61
- data = dataConfig[sizeType.name];
62
- if (data !== undefined) {
63
- return data;
64
- }
65
- }
66
- return undefined;
67
- }
68
- function matchWithSmallerMatch(dataConfig, currentSizeType, sizeTypes) {
69
- let data = dataConfig[currentSizeType.name];
70
- if (data !== undefined) {
71
- return data;
72
- }
73
- if (currentSizeType.type <= 0) {
74
- return undefined;
75
- }
76
- // eslint-disable-next-line for-direction
77
- for (let index = currentSizeType.type; index < sizeTypes.length; index--) {
78
- const sizeType = sizeTypes[index];
79
- data = dataConfig[sizeType.name];
80
- if (data !== undefined) {
81
- return data;
82
- }
83
- }
84
- return undefined;
85
- }
86
- function matchWithClosestSmallerFirstMatch(dataConfig, currentSizeType, sizeTypes) {
87
- return closestMatch(dataConfig, currentSizeType, sizeTypes, true);
88
- }
89
- function matchWithClosestLargerFirstMatch(dataConfig, currentSizeType, sizeTypes) {
90
- return closestMatch(dataConfig, currentSizeType, sizeTypes, false);
91
- }
92
- function closestMatch(dataConfig, currentSizeType, sizeTypes, isSmallerFirst) {
93
- let data = dataConfig[currentSizeType.name];
94
- if (data !== undefined) {
95
- return data;
96
- }
97
- let downIndex = currentSizeType.type;
98
- let upIndex = currentSizeType.type;
99
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
100
- for (let index = 0; index < sizeTypes.length; index++) {
101
- for (const idx of isSmallerFirst ? [--downIndex, ++upIndex] : [++upIndex, --downIndex]) {
102
- const sizeType = sizeTypes[idx];
103
- if (sizeType) {
104
- data = dataConfig[sizeType.name];
105
- if (data !== undefined) {
106
- return data;
107
- }
108
- }
109
- }
110
- }
111
- return undefined;
6
+ var ViewportDataMatchStrategy;
7
+ (function (ViewportDataMatchStrategy) {
8
+ /** Indicates that size should match exact or default. */
9
+ ViewportDataMatchStrategy[ViewportDataMatchStrategy["exact"] = 0] = "exact";
10
+ /** Indicates that size matches when exact match, first match smaller (down) or default. */
11
+ ViewportDataMatchStrategy[ViewportDataMatchStrategy["smaller"] = 1] = "smaller";
12
+ /** Indicates that size matches when exact match, first match larger (up) or default. */
13
+ ViewportDataMatchStrategy[ViewportDataMatchStrategy["larger"] = 2] = "larger";
14
+ /** Indicates that size matches when exact match, or it tries both smaller/larger (smaller is preferred) until match or default. */
15
+ ViewportDataMatchStrategy[ViewportDataMatchStrategy["closestSmallerFirst"] = 3] = "closestSmallerFirst";
16
+ /** Indicates that size matches when exact match, or it tries both larger/smaller (larger is preferred) until match or default. */
17
+ ViewportDataMatchStrategy[ViewportDataMatchStrategy["closestLargerFirst"] = 4] = "closestLargerFirst";
18
+ })(ViewportDataMatchStrategy || (ViewportDataMatchStrategy = {}));
19
+ /**
20
+ * Utility function to match data based on strategy and size.
21
+ *
22
+ * @param dataConfig Data config to generate rules based on.
23
+ * @param sizeType Size type to get data for.
24
+ * @param strategy Strategy to use when building rules.
25
+ * @param sizeTypes Available size types ordered by index type. (Can be obtained from `ViewportService`)
26
+ * @param sizeTypeMap Available size type map. (Can be obtained from `ViewportService`)
27
+ * @returns Returns the matched data value.
28
+ */
29
+ function matchViewportData(dataConfig, sizeType, strategy, sizeTypes, sizeTypeMap) {
30
+ const matchFn = matchStrategyHandlerMap$1[strategy];
31
+ if (!matchFn) {
32
+ throw Error(`matchViewportData: Viewport Data strategy not implemented. Strategy: '${strategy}'`);
33
+ }
34
+ const data = matchFn(dataConfig, sizeType, sizeTypes, sizeTypeMap);
35
+ if (data !== undefined) {
36
+ return data;
37
+ }
38
+ return dataConfig.default;
39
+ }
40
+ const matchStrategyHandlerMap$1 = {
41
+ [ViewportDataMatchStrategy.exact]: matchWithExact,
42
+ [ViewportDataMatchStrategy.larger]: matchWithLargerMatch,
43
+ [ViewportDataMatchStrategy.smaller]: matchWithSmallerMatch,
44
+ [ViewportDataMatchStrategy.closestSmallerFirst]: matchWithClosestSmallerFirstMatch,
45
+ [ViewportDataMatchStrategy.closestLargerFirst]: matchWithClosestLargerFirstMatch,
46
+ };
47
+ function matchWithExact(dataConfig, currentSizeType) {
48
+ return dataConfig[currentSizeType.name];
49
+ }
50
+ function matchWithLargerMatch(dataConfig, currentSizeType, sizeTypes) {
51
+ let data = dataConfig[currentSizeType.name];
52
+ if (data !== undefined) {
53
+ return data;
54
+ }
55
+ const largestTypeIdx = sizeTypes[sizeTypes.length - 1].type;
56
+ if (currentSizeType.type >= largestTypeIdx) {
57
+ return undefined;
58
+ }
59
+ for (let index = currentSizeType.type; index < sizeTypes.length; index++) {
60
+ const sizeType = sizeTypes[index];
61
+ data = dataConfig[sizeType.name];
62
+ if (data !== undefined) {
63
+ return data;
64
+ }
65
+ }
66
+ return undefined;
67
+ }
68
+ function matchWithSmallerMatch(dataConfig, currentSizeType, sizeTypes) {
69
+ let data = dataConfig[currentSizeType.name];
70
+ if (data !== undefined) {
71
+ return data;
72
+ }
73
+ if (currentSizeType.type <= 0) {
74
+ return undefined;
75
+ }
76
+ // eslint-disable-next-line for-direction
77
+ for (let index = currentSizeType.type; index < sizeTypes.length; index--) {
78
+ const sizeType = sizeTypes[index];
79
+ data = dataConfig[sizeType.name];
80
+ if (data !== undefined) {
81
+ return data;
82
+ }
83
+ }
84
+ return undefined;
85
+ }
86
+ function matchWithClosestSmallerFirstMatch(dataConfig, currentSizeType, sizeTypes) {
87
+ return closestMatch(dataConfig, currentSizeType, sizeTypes, true);
88
+ }
89
+ function matchWithClosestLargerFirstMatch(dataConfig, currentSizeType, sizeTypes) {
90
+ return closestMatch(dataConfig, currentSizeType, sizeTypes, false);
91
+ }
92
+ function closestMatch(dataConfig, currentSizeType, sizeTypes, isSmallerFirst) {
93
+ let data = dataConfig[currentSizeType.name];
94
+ if (data !== undefined) {
95
+ return data;
96
+ }
97
+ let downIndex = currentSizeType.type;
98
+ let upIndex = currentSizeType.type;
99
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
100
+ for (let index = 0; index < sizeTypes.length; index++) {
101
+ for (const idx of isSmallerFirst ? [--downIndex, ++upIndex] : [++upIndex, --downIndex]) {
102
+ const sizeType = sizeTypes[idx];
103
+ if (sizeType) {
104
+ data = dataConfig[sizeType.name];
105
+ if (data !== undefined) {
106
+ return data;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ return undefined;
112
112
  }
113
113
 
114
- /** Default viewport breakpoints. */
115
- const UX_VIEWPORT_DEFAULT_BREAKPOINTS = {
116
- xsmall: 450,
117
- small: 767,
118
- medium: 992,
119
- large: 1280,
120
- fhd: 1920,
121
- qhd: 2560,
122
- uhd4k: 3840,
123
- uhd8k: 7680,
124
- };
125
- const UX_VIEWPORT_DEFAULT_CONFIG = {
126
- resizePollingSpeed: 33,
127
- breakpoints: UX_VIEWPORT_DEFAULT_BREAKPOINTS,
128
- defaultDataMatchStrategy: ViewportDataMatchStrategy.smaller,
114
+ /** Default viewport breakpoints. */
115
+ const UX_VIEWPORT_DEFAULT_BREAKPOINTS = {
116
+ xsmall: 450,
117
+ small: 767,
118
+ medium: 992,
119
+ large: 1200,
120
+ xlarge: 1500,
121
+ xxlarge: 1920,
122
+ xxlarge1: 2100,
123
+ };
124
+ const UX_VIEWPORT_DEFAULT_CONFIG = {
125
+ resizePollingSpeed: 33,
126
+ breakpoints: UX_VIEWPORT_DEFAULT_BREAKPOINTS,
127
+ defaultDataMatchStrategy: ViewportDataMatchStrategy.smaller,
129
128
  };
130
129
 
131
- const UX_DEFAULT_CONFIG = {
132
- viewport: UX_VIEWPORT_DEFAULT_CONFIG,
133
- };
130
+ const UX_DEFAULT_CONFIG = {
131
+ viewport: UX_VIEWPORT_DEFAULT_CONFIG,
132
+ };
134
133
  const UX_CONFIG = new InjectionToken("@ssv/ngx.ux-config");
135
134
 
136
- /**
137
- * Utility function to generate rules based on strategies.
138
- *
139
- * @param dataConfig Data config to generate rules based on.
140
- * @param strategy Strategy to use when building rules.
141
- * @param sizeTypes Available size types ordered by index type. (Can be obtained from `ViewportService`)
142
- * @param sizeTypeMap Available size type map. (Can be obtained from `ViewportService`)
143
- * @returns Returns a collection of rules (ordered).
144
- */
145
- function generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, sizeTypes, sizeTypeMap) {
146
- const ruleBuilderFn = matchStrategyHandlerMap[strategy];
147
- if (!ruleBuilderFn) {
148
- throw Error(`generateViewportRulesRangeFromDataMatcher: Viewport Data strategy not implemented. Strategy: '${strategy}'`);
149
- }
150
- let dataSizes = [];
151
- for (const key in dataConfig) {
152
- if (Object.prototype.hasOwnProperty.call(dataConfig, key)) {
153
- const data = dataConfig[key];
154
- if (data === undefined) {
155
- continue;
156
- }
157
- const size = sizeTypeMap[key];
158
- if (size) {
159
- dataSizes.push(size);
160
- }
161
- }
162
- }
163
- dataSizes = dataSizes.sort(({ type: typeA }, { type: typeB }) => typeA - typeB);
164
- const rules = [];
165
- if (dataConfig.default) {
166
- rules.push({ value: dataConfig.default, min: undefined, max: undefined });
167
- }
168
- let prevRule;
169
- for (let index = 0; index < dataSizes.length; index++) {
170
- const prevDataSize = dataSizes[index - 1];
171
- const nextDataSize = dataSizes[index + 1];
172
- const dataSize = dataSizes[index];
173
- const prevSize = sizeTypes[dataSize.type - 1];
174
- // const nextSize = sizeTypes[dataSize.type + 1];
175
- const data = dataConfig[dataSize.name];
176
- const rule = {
177
- value: data,
178
- min: undefined,
179
- max: undefined,
180
- };
181
- ruleBuilderFn(rule, dataSize, nextDataSize, prevDataSize, prevSize, prevRule, sizeTypes);
182
- prevRule = rule;
183
- rules.push(rule);
184
- }
185
- return rules;
186
- }
187
- const matchStrategyHandlerMap = {
188
- [ViewportDataMatchStrategy.exact]: (rule, dataSize, _nextDataSize, _prevDataSize, prevSize) => {
189
- rule.max = dataSize.widthThreshold;
190
- if (prevSize) {
191
- rule.min = prevSize.widthThreshold + 1;
192
- }
193
- },
194
- [ViewportDataMatchStrategy.smaller]: (rule, dataSize, nextDataSize, _prevDataSize, prevSize) => {
195
- if (nextDataSize) {
196
- rule.max = dataSize.widthThreshold;
197
- }
198
- if (prevSize) {
199
- rule.min = prevSize.widthThreshold + 1;
200
- }
201
- },
202
- [ViewportDataMatchStrategy.larger]: (rule, dataSize, _nextDataSize, prevDataSize) => {
203
- if (dataSize) {
204
- rule.max = dataSize.widthThreshold;
205
- }
206
- if (prevDataSize) {
207
- rule.min = prevDataSize.widthThreshold + 1;
208
- }
209
- },
210
- [ViewportDataMatchStrategy.closestSmallerFirst]: (rule, dataSize, nextDataSize, _prevDataSize, _prevSize, prevRule, sizeTypes) => {
211
- if (nextDataSize) {
212
- rule.max = calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, true);
213
- }
214
- if (prevRule?.max) {
215
- rule.min = prevRule.max + 1;
216
- }
217
- },
218
- [ViewportDataMatchStrategy.closestLargerFirst]: (rule, dataSize, nextDataSize, _prevDataSize, _prevSize, prevRule, sizeTypes) => {
219
- if (nextDataSize) {
220
- rule.max = calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, false);
221
- }
222
- if (prevRule?.max) {
223
- rule.min = prevRule.max + 1;
224
- }
225
- },
226
- };
227
- function calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, isSmallerPreferred) {
228
- const fn = isSmallerPreferred ? Math.ceil : Math.floor;
229
- // get closest between curr and next
230
- const diffIndex = fn((nextDataSize.type - dataSize.type - 1) / 2);
231
- const diffNextSize = sizeTypes[dataSize.type + diffIndex];
232
- return (diffNextSize || dataSize).widthThreshold;
135
+ /**
136
+ * Utility function to generate rules based on strategies.
137
+ *
138
+ * @param dataConfig Data config to generate rules based on.
139
+ * @param strategy Strategy to use when building rules.
140
+ * @param sizeTypes Available size types ordered by index type. (Can be obtained from `ViewportService`)
141
+ * @param sizeTypeMap Available size type map. (Can be obtained from `ViewportService`)
142
+ * @returns Returns a collection of rules (ordered).
143
+ */
144
+ function generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, sizeTypes, sizeTypeMap) {
145
+ const ruleBuilderFn = matchStrategyHandlerMap[strategy];
146
+ if (!ruleBuilderFn) {
147
+ throw Error(`generateViewportRulesRangeFromDataMatcher: Viewport Data strategy not implemented. Strategy: '${strategy}'`);
148
+ }
149
+ let dataSizes = [];
150
+ for (const key in dataConfig) {
151
+ if (Object.prototype.hasOwnProperty.call(dataConfig, key)) {
152
+ const data = dataConfig[key];
153
+ if (data === undefined) {
154
+ continue;
155
+ }
156
+ const size = sizeTypeMap[key];
157
+ if (size) {
158
+ dataSizes.push(size);
159
+ }
160
+ }
161
+ }
162
+ dataSizes = dataSizes.sort(({ type: typeA }, { type: typeB }) => typeA - typeB);
163
+ const rules = [];
164
+ if (dataConfig.default) {
165
+ rules.push({ value: dataConfig.default, min: undefined, max: undefined });
166
+ }
167
+ let prevRule;
168
+ for (let index = 0; index < dataSizes.length; index++) {
169
+ const prevDataSize = dataSizes[index - 1];
170
+ const nextDataSize = dataSizes[index + 1];
171
+ const dataSize = dataSizes[index];
172
+ const prevSize = sizeTypes[dataSize.type - 1];
173
+ // const nextSize = sizeTypes[dataSize.type + 1];
174
+ const data = dataConfig[dataSize.name];
175
+ const rule = {
176
+ value: data,
177
+ min: undefined,
178
+ max: undefined,
179
+ };
180
+ ruleBuilderFn(rule, dataSize, nextDataSize, prevDataSize, prevSize, prevRule, sizeTypes);
181
+ prevRule = rule;
182
+ rules.push(rule);
183
+ }
184
+ return rules;
185
+ }
186
+ const matchStrategyHandlerMap = {
187
+ [ViewportDataMatchStrategy.exact]: (rule, dataSize, _nextDataSize, _prevDataSize, prevSize) => {
188
+ rule.max = dataSize.widthThreshold;
189
+ if (prevSize) {
190
+ rule.min = prevSize.widthThreshold + 1;
191
+ }
192
+ },
193
+ [ViewportDataMatchStrategy.smaller]: (rule, dataSize, nextDataSize, _prevDataSize, prevSize) => {
194
+ if (nextDataSize) {
195
+ rule.max = dataSize.widthThreshold;
196
+ }
197
+ if (prevSize) {
198
+ rule.min = prevSize.widthThreshold + 1;
199
+ }
200
+ },
201
+ [ViewportDataMatchStrategy.larger]: (rule, dataSize, _nextDataSize, prevDataSize) => {
202
+ if (dataSize) {
203
+ rule.max = dataSize.widthThreshold;
204
+ }
205
+ if (prevDataSize) {
206
+ rule.min = prevDataSize.widthThreshold + 1;
207
+ }
208
+ },
209
+ [ViewportDataMatchStrategy.closestSmallerFirst]: (rule, dataSize, nextDataSize, _prevDataSize, _prevSize, prevRule, sizeTypes) => {
210
+ if (nextDataSize) {
211
+ rule.max = calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, true);
212
+ }
213
+ if (prevRule?.max) {
214
+ rule.min = prevRule.max + 1;
215
+ }
216
+ },
217
+ [ViewportDataMatchStrategy.closestLargerFirst]: (rule, dataSize, nextDataSize, _prevDataSize, _prevSize, prevRule, sizeTypes) => {
218
+ if (nextDataSize) {
219
+ rule.max = calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, false);
220
+ }
221
+ if (prevRule?.max) {
222
+ rule.min = prevRule.max + 1;
223
+ }
224
+ },
225
+ };
226
+ function calculateClosestWidthThreshold(nextDataSize, dataSize, sizeTypes, isSmallerPreferred) {
227
+ const fn = isSmallerPreferred ? Math.ceil : Math.floor;
228
+ // get closest between curr and next
229
+ const diffIndex = fn((nextDataSize.type - dataSize.type - 1) / 2);
230
+ const diffNextSize = sizeTypes[dataSize.type + diffIndex];
231
+ return (diffNextSize || dataSize).widthThreshold;
233
232
  }
234
233
 
235
- /**
236
- * The indices of each breakpoint provided based on the `UX_VIEWPORT_DEFAULT_BREAKPOINTS`.
237
- * @see UX_VIEWPORT_DEFAULT_BREAKPOINTS
238
- */
239
- var ViewportSizeType;
240
- (function (ViewportSizeType) {
241
- ViewportSizeType[ViewportSizeType["xsmall"] = 0] = "xsmall";
242
- ViewportSizeType[ViewportSizeType["small"] = 1] = "small";
243
- ViewportSizeType[ViewportSizeType["medium"] = 2] = "medium";
244
- ViewportSizeType[ViewportSizeType["large"] = 3] = "large";
245
- ViewportSizeType[ViewportSizeType["fhd"] = 4] = "fhd";
246
- ViewportSizeType[ViewportSizeType["qhd"] = 6] = "qhd";
247
- ViewportSizeType[ViewportSizeType["uhd4k"] = 7] = "uhd4k";
248
- ViewportSizeType[ViewportSizeType["uhd8k"] = 8] = "uhd8k";
249
- })(ViewportSizeType || (ViewportSizeType = {}));
250
- var ComparisonOperation;
251
- (function (ComparisonOperation) {
252
- ComparisonOperation["equals"] = "=";
253
- ComparisonOperation["notEquals"] = "<>";
254
- ComparisonOperation["lessThan"] = "<";
255
- ComparisonOperation["lessOrEqualThan"] = "<=";
256
- ComparisonOperation["greaterThan"] = ">";
257
- ComparisonOperation["greaterOrEqualThan"] = ">=";
258
- })(ComparisonOperation || (ComparisonOperation = {}));
259
- var DeviceType;
260
- (function (DeviceType) {
261
- DeviceType["desktop"] = "desktop";
262
- DeviceType["mobile"] = "mobile";
263
- DeviceType["tablet"] = "tablet";
234
+ /**
235
+ * The indices of each breakpoint provided based on the `UX_VIEWPORT_DEFAULT_BREAKPOINTS`.
236
+ * @see UX_VIEWPORT_DEFAULT_BREAKPOINTS
237
+ */
238
+ var ViewportSizeType;
239
+ (function (ViewportSizeType) {
240
+ ViewportSizeType[ViewportSizeType["xsmall"] = 0] = "xsmall";
241
+ ViewportSizeType[ViewportSizeType["small"] = 1] = "small";
242
+ ViewportSizeType[ViewportSizeType["medium"] = 2] = "medium";
243
+ ViewportSizeType[ViewportSizeType["large"] = 3] = "large";
244
+ ViewportSizeType[ViewportSizeType["xlarge"] = 4] = "xlarge";
245
+ ViewportSizeType[ViewportSizeType["xxlarge"] = 5] = "xxlarge";
246
+ ViewportSizeType[ViewportSizeType["xxlarge1"] = 6] = "xxlarge1";
247
+ })(ViewportSizeType || (ViewportSizeType = {}));
248
+ var ComparisonOperation;
249
+ (function (ComparisonOperation) {
250
+ ComparisonOperation["equals"] = "=";
251
+ ComparisonOperation["notEquals"] = "<>";
252
+ ComparisonOperation["lessThan"] = "<";
253
+ ComparisonOperation["lessOrEqualThan"] = "<=";
254
+ ComparisonOperation["greaterThan"] = ">";
255
+ ComparisonOperation["greaterOrEqualThan"] = ">=";
256
+ })(ComparisonOperation || (ComparisonOperation = {}));
257
+ var DeviceType;
258
+ (function (DeviceType) {
259
+ DeviceType["desktop"] = "desktop";
260
+ DeviceType["mobile"] = "mobile";
261
+ DeviceType["tablet"] = "tablet";
264
262
  })(DeviceType || (DeviceType = {}));
265
263
 
266
- function isViewportSizeMatcherExpression(value) {
267
- if (typeof value !== "object" || !value) {
268
- return false;
269
- }
270
- const args = value;
271
- if (args.size && args.operation) {
272
- return true;
273
- }
274
- return false;
275
- }
276
- function isViewportSizeMatcherTupleExpression(arg) {
277
- if (!arg) {
278
- return false;
279
- }
280
- if (Array.isArray(arg)) {
281
- if (arg.length === 2) {
282
- const [op] = arg;
283
- return operations.includes(op);
284
- }
285
- }
286
- return false;
287
- }
288
- const operations = Object.values(ComparisonOperation);
289
- const COMPARISON_OPERATION_FUNC_MAPPING = {
290
- [ComparisonOperation.equals]: (a, b) => a === b,
291
- [ComparisonOperation.notEquals]: (a, b) => a !== b,
292
- [ComparisonOperation.lessThan]: (a, b) => a < b,
293
- [ComparisonOperation.lessOrEqualThan]: (a, b) => a <= b,
294
- [ComparisonOperation.greaterThan]: (a, b) => a > b,
295
- [ComparisonOperation.greaterOrEqualThan]: (a, b) => a >= b,
296
- };
297
- function isViewportConditionMatch(evaluateSize, conditions, viewportSizeTypeInfoRefs) {
298
- const isExcluded = match(conditions.sizeTypeExclude, evaluateSize.name, false);
299
- let isIncluded;
300
- let isExpressionTruthy;
301
- if (!isExcluded && conditions.expression) {
302
- const ref = viewportSizeTypeInfoRefs[conditions.expression.size];
303
- if (!ref) {
304
- throw new Error(`Viewport size type is invalid. Size type: '${conditions.expression.size}'`);
305
- }
306
- const expMatcher = COMPARISON_OPERATION_FUNC_MAPPING[conditions.expression.operation];
307
- isExpressionTruthy = expMatcher(evaluateSize.type, ref.type);
308
- }
309
- else {
310
- isIncluded = match(conditions.sizeType, evaluateSize.name, true);
311
- }
312
- const shouldRender = (isExpressionTruthy || isIncluded) && !isExcluded;
313
- // console.warn(">>> shouldRender", { evaluateSize, conditions, shouldRender });
314
- return !!shouldRender;
315
- }
316
- function match(value, targetValue, defaultValue) {
317
- if (!value) {
318
- return defaultValue;
319
- }
320
- return Array.isArray(value)
321
- ? value.includes(targetValue)
322
- : value === targetValue;
323
- }
324
- function getSizeTypeInfo(width, sizeTypes) {
325
- const lastEntryIndex = sizeTypes.length - 1;
326
- for (let idx = 0; idx < lastEntryIndex; idx++) {
327
- const viewportSizeTypeInfo = sizeTypes[idx];
328
- if (width <= viewportSizeTypeInfo.widthThreshold) {
329
- return viewportSizeTypeInfo;
330
- }
331
- }
332
- return sizeTypes[lastEntryIndex];
333
- }
334
- /**
335
- * Converts the breakpoints into a 2 dimensional array containing the name and width, and sorted from
336
- * smallest to largest.
337
- * @param breakpoints the breakpoints obtained from the config
338
- * @internal
339
- */
340
- function getSortedBreakpoints(breakpoints) {
341
- return Object.entries(breakpoints)
342
- .sort(([, widthA], [, widthB]) => widthA - widthB);
343
- }
344
- /**
345
- * A util function which generates the ViewportSizeTypeInfo.type for each breakpoint.
346
- * @param breakpoints the custom breakpoints
347
- */
348
- function generateViewportSizeType(breakpoints) {
349
- return Object.freeze(getSortedBreakpoints(breakpoints).reduce((dictionary, [name], index) => {
350
- dictionary[name] = index;
351
- dictionary[index] = name;
352
- return dictionary;
353
- }, {}));
354
- }
355
- /**
356
- * Pre-processes the given breakpoints into an ordered list from smallest to largest while generating
357
- * all the necessary information on the viewport.
358
- * @param breakpoints the breakpoints obtained from the config
359
- * @internal
360
- */
361
- function generateViewportSizeTypeInfoList(breakpoints) {
362
- return getSortedBreakpoints(breakpoints)
363
- .map(([name, width], index) => (Object.freeze({
364
- name,
365
- type: index,
366
- widthThreshold: width
367
- })));
368
- }
369
- /**
370
- * Converts the breakpoint list into a dictionary while using the name as key.
371
- * @param breakpointList the list of breakpoints
372
- * @internal
373
- */
374
- function generateViewportSizeTypeInfoRefs(breakpointList) {
375
- return Object.freeze(breakpointList.reduce((dictionary, breakpoint) => {
376
- dictionary[breakpoint.name] = breakpoint;
377
- dictionary[breakpoint.type] = breakpoint;
378
- return dictionary;
379
- }, {}));
264
+ function isViewportSizeMatcherExpression(value) {
265
+ if (typeof value !== "object" || !value) {
266
+ return false;
267
+ }
268
+ const args = value;
269
+ if (args.size && args.operation) {
270
+ return true;
271
+ }
272
+ return false;
273
+ }
274
+ function isViewportSizeMatcherTupleExpression(arg) {
275
+ if (!arg) {
276
+ return false;
277
+ }
278
+ if (Array.isArray(arg)) {
279
+ if (arg.length === 2) {
280
+ const [op] = arg;
281
+ return operations.includes(op);
282
+ }
283
+ }
284
+ return false;
285
+ }
286
+ const operations = Object.values(ComparisonOperation);
287
+ const COMPARISON_OPERATION_FUNC_MAPPING = {
288
+ [ComparisonOperation.equals]: (a, b) => a === b,
289
+ [ComparisonOperation.notEquals]: (a, b) => a !== b,
290
+ [ComparisonOperation.lessThan]: (a, b) => a < b,
291
+ [ComparisonOperation.lessOrEqualThan]: (a, b) => a <= b,
292
+ [ComparisonOperation.greaterThan]: (a, b) => a > b,
293
+ [ComparisonOperation.greaterOrEqualThan]: (a, b) => a >= b,
294
+ };
295
+ function isViewportConditionMatch(evaluateSize, conditions, viewportSizeTypeInfoRefs) {
296
+ const isExcluded = match(conditions.sizeTypeExclude, evaluateSize.name, false);
297
+ let isIncluded;
298
+ let isExpressionTruthy;
299
+ if (!isExcluded && conditions.expression) {
300
+ const ref = viewportSizeTypeInfoRefs[conditions.expression.size];
301
+ if (!ref) {
302
+ throw new Error(`Viewport size type is invalid. Size type: '${conditions.expression.size}'`);
303
+ }
304
+ const expMatcher = COMPARISON_OPERATION_FUNC_MAPPING[conditions.expression.operation];
305
+ isExpressionTruthy = expMatcher(evaluateSize.type, ref.type);
306
+ }
307
+ else {
308
+ isIncluded = match(conditions.sizeType, evaluateSize.name, true);
309
+ }
310
+ const shouldRender = (isExpressionTruthy || isIncluded) && !isExcluded;
311
+ // console.warn(">>> shouldRender", { evaluateSize, conditions, shouldRender });
312
+ return !!shouldRender;
313
+ }
314
+ function match(value, targetValue, defaultValue) {
315
+ if (!value) {
316
+ return defaultValue;
317
+ }
318
+ return Array.isArray(value)
319
+ ? value.includes(targetValue)
320
+ : value === targetValue;
321
+ }
322
+ function getSizeTypeInfo(width, sizeTypes) {
323
+ const lastEntryIndex = sizeTypes.length - 1;
324
+ for (let idx = 0; idx < lastEntryIndex; idx++) {
325
+ const viewportSizeTypeInfo = sizeTypes[idx];
326
+ if (width <= viewportSizeTypeInfo.widthThreshold) {
327
+ return viewportSizeTypeInfo;
328
+ }
329
+ }
330
+ return sizeTypes[lastEntryIndex];
331
+ }
332
+ /**
333
+ * Converts the breakpoints into a 2 dimensional array containing the name and width, and sorted from
334
+ * smallest to largest.
335
+ * @param breakpoints the breakpoints obtained from the config
336
+ * @internal
337
+ */
338
+ function getSortedBreakpoints(breakpoints) {
339
+ return Object.entries(breakpoints)
340
+ .sort(([, widthA], [, widthB]) => widthA - widthB);
341
+ }
342
+ /**
343
+ * A util function which generates the ViewportSizeTypeInfo.type for each breakpoint.
344
+ * @param breakpoints the custom breakpoints
345
+ */
346
+ function generateViewportSizeType(breakpoints) {
347
+ return Object.freeze(getSortedBreakpoints(breakpoints).reduce((dictionary, [name], index) => {
348
+ dictionary[name] = index;
349
+ dictionary[index] = name;
350
+ return dictionary;
351
+ }, {}));
352
+ }
353
+ /**
354
+ * Pre-processes the given breakpoints into an ordered list from smallest to largest while generating
355
+ * all the necessary information on the viewport.
356
+ * @param breakpoints the breakpoints obtained from the config
357
+ * @internal
358
+ */
359
+ function generateViewportSizeTypeInfoList(breakpoints) {
360
+ return getSortedBreakpoints(breakpoints)
361
+ .map(([name, width], index) => (Object.freeze({
362
+ name,
363
+ type: index,
364
+ widthThreshold: width
365
+ })));
366
+ }
367
+ /**
368
+ * Converts the breakpoint list into a dictionary while using the name as key.
369
+ * @param breakpointList the list of breakpoints
370
+ * @internal
371
+ */
372
+ function generateViewportSizeTypeInfoRefs(breakpointList) {
373
+ return Object.freeze(breakpointList.reduce((dictionary, breakpoint) => {
374
+ dictionary[breakpoint.name] = breakpoint;
375
+ dictionary[breakpoint.type] = breakpoint;
376
+ return dictionary;
377
+ }, {}));
380
378
  }
381
379
 
382
- const WINDOW = new InjectionToken("Window");
383
- class WindowRef {
384
- constructor(
385
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
386
- window) {
387
- this.window = window;
388
- }
389
- /** Window underlying native object. */
390
- get native() {
391
- return this.window;
392
- }
393
- /** Determines whether native element is supported or not. Generally `false` when executing in SSR. */
394
- get hasNative() {
395
- return !!this.native.window;
396
- }
397
- }
398
- WindowRef.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, deps: [{ token: WINDOW }], target: i0.ɵɵFactoryTarget.Injectable });
399
- WindowRef.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, providedIn: "root" });
400
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, decorators: [{
401
- type: Injectable,
402
- args: [{
403
- providedIn: "root",
404
- }]
405
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
406
- type: Inject,
407
- args: [WINDOW]
380
+ const WINDOW = new InjectionToken("Window");
381
+ class WindowRef {
382
+ constructor(
383
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
384
+ window) {
385
+ this.window = window;
386
+ }
387
+ /** Window underlying native object. */
388
+ get native() {
389
+ return this.window;
390
+ }
391
+ /** Determines whether native element is supported or not. Generally `false` when executing in SSR. */
392
+ get hasNative() {
393
+ return !!this.native.window;
394
+ }
395
+ }
396
+ WindowRef.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, deps: [{ token: WINDOW }], target: i0.ɵɵFactoryTarget.Injectable });
397
+ WindowRef.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, providedIn: "root" });
398
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: WindowRef, decorators: [{
399
+ type: Injectable,
400
+ args: [{
401
+ providedIn: "root",
402
+ }]
403
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
404
+ type: Inject,
405
+ args: [WINDOW]
408
406
  }] }]; } });
409
407
 
410
- // todo: make this configurable
411
- /** Viewport size for SSR. */
412
- const viewportSizeSSR = {
413
- [DeviceType.desktop]: {
414
- width: 1366,
415
- height: 768,
416
- },
417
- [DeviceType.tablet]: {
418
- width: 768,
419
- height: 1024,
420
- },
421
- [DeviceType.mobile]: {
422
- width: 414,
423
- height: 736,
424
- },
425
- };
426
- const UX_VIEWPORT_SSR_DEVICE = new InjectionToken("@ssv/ngx.ux-config/viewport/ssr-device");
427
- class ViewportServerSizeService {
428
- constructor(deviceType) {
429
- this.deviceType = deviceType;
430
- }
431
- get() {
432
- return viewportSizeSSR[this.deviceType] || viewportSizeSSR[DeviceType.desktop];
433
- }
434
- }
435
- ViewportServerSizeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, deps: [{ token: UX_VIEWPORT_SSR_DEVICE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
436
- ViewportServerSizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, providedIn: "root" });
437
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, decorators: [{
438
- type: Injectable,
439
- args: [{
440
- providedIn: "root",
441
- }]
442
- }], ctorParameters: function () { return [{ type: DeviceType, decorators: [{
443
- type: Optional
444
- }, {
445
- type: Inject,
446
- args: [UX_VIEWPORT_SSR_DEVICE]
408
+ // todo: make this configurable
409
+ /** Viewport size for SSR. */
410
+ const viewportSizeSSR = {
411
+ [DeviceType.desktop]: {
412
+ width: 1366,
413
+ height: 768,
414
+ },
415
+ [DeviceType.tablet]: {
416
+ width: 768,
417
+ height: 1024,
418
+ },
419
+ [DeviceType.mobile]: {
420
+ width: 414,
421
+ height: 736,
422
+ },
423
+ };
424
+ const UX_VIEWPORT_SSR_DEVICE = new InjectionToken("@ssv/ngx.ux-config/viewport/ssr-device");
425
+ class ViewportServerSizeService {
426
+ constructor(deviceType) {
427
+ this.deviceType = deviceType;
428
+ }
429
+ get() {
430
+ return viewportSizeSSR[this.deviceType] || viewportSizeSSR[DeviceType.desktop];
431
+ }
432
+ }
433
+ ViewportServerSizeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, deps: [{ token: UX_VIEWPORT_SSR_DEVICE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
434
+ ViewportServerSizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, providedIn: "root" });
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, decorators: [{
436
+ type: Injectable,
437
+ args: [{
438
+ providedIn: "root",
439
+ }]
440
+ }], ctorParameters: function () { return [{ type: DeviceType, decorators: [{
441
+ type: Optional
442
+ }, {
443
+ type: Inject,
444
+ args: [UX_VIEWPORT_SSR_DEVICE]
447
445
  }] }]; } });
448
446
 
449
- class ViewportService {
450
- constructor(windowRef, viewportServerSize, config) {
451
- this.windowRef = windowRef;
452
- this.viewportServerSize = viewportServerSize;
453
- console.warn(">>>> yolo service");
454
- this._sizeTypes = generateViewportSizeTypeInfoList(config.viewport.breakpoints);
455
- this._sizeTypeMap = generateViewportSizeTypeInfoRefs(this._sizeTypes);
456
- if (windowRef.hasNative) {
457
- this.resizeSnap$ = fromEvent(window, "resize").pipe(map(() => this.getViewportSize()), share());
458
- this.resize$ = this.resizeSnap$.pipe(auditTime(config.viewport.resizePollingSpeed), share());
459
- }
460
- else {
461
- this.resizeSnap$ = this.resize$ = of(viewportServerSize.get());
462
- }
463
- const size = this.getViewportSize();
464
- this._sizeTypeSnapshot = getSizeTypeInfo(size.width, this.sizeTypes);
465
- const sizeFn = (obs$) => obs$.pipe(startWith(size), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), shareReplay(1));
466
- this.sizeSnap$ = sizeFn(this.resizeSnap$);
467
- this.size$ = sizeFn(this.resize$);
468
- const sizeTypeFn = (obs$) => obs$.pipe(distinctUntilChanged((a, b) => a.width === b.width), map(x => getSizeTypeInfo(x.width, this.sizeTypes)), distinctUntilChanged(), tap(x => this._sizeTypeSnapshot = x), shareReplay(1));
469
- this.sizeType$ = sizeTypeFn(this.size$);
470
- this.sizeTypeSnap$ = sizeTypeFn(this.sizeSnap$);
471
- }
472
- /** Viewport size type snapshot of the last value. (Prefer use `sizeType$` observable when possible.) */
473
- get sizeTypeSnapshot() { return this._sizeTypeSnapshot; }
474
- /** Size types refs of the generated viewport size type info. */
475
- get sizeTypeMap() { return this._sizeTypeMap; }
476
- /** Viewport size types list ordered by type, smallest to largest. */
477
- get sizeTypes() { return this._sizeTypes; }
478
- /** Returns the current viewport size */
479
- getViewportSize() {
480
- if (!this.windowRef.hasNative) {
481
- return this.viewportServerSize.get();
482
- }
483
- const ua = navigator.userAgent.toLowerCase();
484
- if (ua.indexOf("safari") !== -1 && ua.indexOf("chrome") === -1) { // safari subtracts the scrollbar width
485
- return {
486
- width: this.windowRef.native.document.documentElement.clientWidth,
487
- height: this.windowRef.native.document.documentElement.clientHeight,
488
- };
489
- }
490
- return {
491
- width: this.windowRef.native.innerWidth,
492
- height: this.windowRef.native.innerHeight,
493
- };
494
- }
495
- }
496
- ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, deps: [{ token: WindowRef }, { token: ViewportServerSizeService }, { token: UX_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
497
- ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, providedIn: "root" });
498
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, decorators: [{
499
- type: Injectable,
500
- args: [{
501
- providedIn: "root",
502
- }]
503
- }], ctorParameters: function () { return [{ type: WindowRef }, { type: ViewportServerSizeService }, { type: undefined, decorators: [{
504
- type: Inject,
505
- args: [UX_CONFIG]
447
+ class ViewportService {
448
+ constructor(windowRef, viewportServerSize, config) {
449
+ this.windowRef = windowRef;
450
+ this.viewportServerSize = viewportServerSize;
451
+ this._sizeTypes = generateViewportSizeTypeInfoList(config.viewport.breakpoints);
452
+ this._sizeTypeMap = generateViewportSizeTypeInfoRefs(this._sizeTypes);
453
+ if (windowRef.hasNative) {
454
+ this.resizeSnap$ = fromEvent(window, "resize").pipe(map(() => this.getViewportSize()), share());
455
+ this.resize$ = this.resizeSnap$.pipe(auditTime(config.viewport.resizePollingSpeed), share());
456
+ }
457
+ else {
458
+ this.resizeSnap$ = this.resize$ = of(viewportServerSize.get());
459
+ }
460
+ const size = this.getViewportSize();
461
+ this._sizeTypeSnapshot = getSizeTypeInfo(size.width, this.sizeTypes);
462
+ const sizeFn = (obs$) => obs$.pipe(startWith(size), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), shareReplay(1));
463
+ this.sizeSnap$ = sizeFn(this.resizeSnap$);
464
+ this.size$ = sizeFn(this.resize$);
465
+ const sizeTypeFn = (obs$) => obs$.pipe(distinctUntilChanged((a, b) => a.width === b.width), map(x => getSizeTypeInfo(x.width, this.sizeTypes)), distinctUntilChanged(), tap(x => this._sizeTypeSnapshot = x), shareReplay(1));
466
+ this.sizeType$ = sizeTypeFn(this.size$);
467
+ this.sizeTypeSnap$ = sizeTypeFn(this.sizeSnap$);
468
+ }
469
+ /** Viewport size type snapshot of the last value. (Prefer use `sizeType$` observable when possible.) */
470
+ get sizeTypeSnapshot() { return this._sizeTypeSnapshot; }
471
+ /** Size types refs of the generated viewport size type info. */
472
+ get sizeTypeMap() { return this._sizeTypeMap; }
473
+ /** Viewport size types list ordered by type, smallest to largest. */
474
+ get sizeTypes() { return this._sizeTypes; }
475
+ /** Returns the current viewport size */
476
+ getViewportSize() {
477
+ if (!this.windowRef.hasNative) {
478
+ return this.viewportServerSize.get();
479
+ }
480
+ const ua = navigator.userAgent.toLowerCase();
481
+ if (ua.indexOf("safari") !== -1 && ua.indexOf("chrome") === -1) { // safari subtracts the scrollbar width
482
+ return {
483
+ width: this.windowRef.native.document.documentElement.clientWidth,
484
+ height: this.windowRef.native.document.documentElement.clientHeight,
485
+ };
486
+ }
487
+ return {
488
+ width: this.windowRef.native.innerWidth,
489
+ height: this.windowRef.native.innerHeight,
490
+ };
491
+ }
492
+ }
493
+ ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, deps: [{ token: WindowRef }, { token: ViewportServerSizeService }, { token: UX_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
494
+ ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, providedIn: "root" });
495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, decorators: [{
496
+ type: Injectable,
497
+ args: [{
498
+ providedIn: "root",
499
+ }]
500
+ }], ctorParameters: function () { return [{ type: WindowRef }, { type: ViewportServerSizeService }, { type: undefined, decorators: [{
501
+ type: Inject,
502
+ args: [UX_CONFIG]
506
503
  }] }]; } });
507
504
 
508
- class ViewportDataService {
509
- constructor(viewport, config) {
510
- this.viewport = viewport;
511
- this.config = config;
512
- }
513
- /** Get data for match. */
514
- get(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy, sizeType = this.viewport.sizeTypeSnapshot) {
515
- return matchViewportData(dataConfig, sizeType, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
516
- }
517
- /** Get data for match as observable. */
518
- get$(dataConfig, strategy, throttle = true) {
519
- return (throttle ? this.viewport.sizeType$ : this.viewport.sizeTypeSnap$).pipe(map(sizeType => this.get(dataConfig, strategy, sizeType)), distinctUntilChanged());
520
- }
521
- /** Generate rules based on strategies for data. */
522
- generateRules(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy) {
523
- return generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
524
- }
525
- }
526
- ViewportDataService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, deps: [{ token: ViewportService }, { token: UX_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
527
- ViewportDataService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, providedIn: "root" });
528
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, decorators: [{
529
- type: Injectable,
530
- args: [{
531
- providedIn: "root",
532
- }]
533
- }], ctorParameters: function () { return [{ type: ViewportService }, { type: undefined, decorators: [{
534
- type: Inject,
535
- args: [UX_CONFIG]
505
+ class ViewportDataService {
506
+ constructor(viewport, config) {
507
+ this.viewport = viewport;
508
+ this.config = config;
509
+ }
510
+ /** Get data for match. */
511
+ get(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy, sizeType = this.viewport.sizeTypeSnapshot) {
512
+ return matchViewportData(dataConfig, sizeType, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
513
+ }
514
+ /** Get data for match as observable. */
515
+ get$(dataConfig, strategy, throttle = true) {
516
+ return (throttle ? this.viewport.sizeType$ : this.viewport.sizeTypeSnap$).pipe(map(sizeType => this.get(dataConfig, strategy, sizeType)), distinctUntilChanged());
517
+ }
518
+ /** Generate rules based on strategies for data. */
519
+ generateRules(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy) {
520
+ return generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
521
+ }
522
+ }
523
+ ViewportDataService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, deps: [{ token: ViewportService }, { token: UX_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
524
+ ViewportDataService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, providedIn: "root" });
525
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, decorators: [{
526
+ type: Injectable,
527
+ args: [{
528
+ providedIn: "root",
529
+ }]
530
+ }], ctorParameters: function () { return [{ type: ViewportService }, { type: undefined, decorators: [{
531
+ type: Inject,
532
+ args: [UX_CONFIG]
536
533
  }] }]; } });
537
534
 
538
- /* eslint-disable @angular-eslint/no-pipe-impure */
539
- class ViewportDataPipe {
540
- constructor(viewportData, cdr) {
541
- this.viewportData = viewportData;
542
- this.cdr = cdr;
543
- this.markForTransform = true;
544
- this.data$$ = Subscription.EMPTY;
545
- }
546
- transform(data, strategy) {
547
- if (!this.markForTransform && data === this.data && strategy === this.strategy) {
548
- return this.value;
549
- }
550
- this.data = data;
551
- this.strategy = strategy;
552
- this.data$$.unsubscribe();
553
- this.data$$ = this.viewportData.get$(data, ViewportDataMatchStrategy[strategy]).pipe(tap(value => {
554
- this.markForTransform = true;
555
- this.value = value;
556
- this.cdr.markForCheck();
557
- })).subscribe();
558
- this.markForTransform = false;
559
- return this.value;
560
- }
561
- ngOnDestroy() {
562
- this.data$$.unsubscribe();
563
- }
564
- }
565
- ViewportDataPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, deps: [{ token: ViewportDataService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Pipe });
566
- ViewportDataPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, name: "ssvViewportData", pure: false });
567
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, decorators: [{
568
- type: Pipe,
569
- args: [{
570
- name: "ssvViewportData",
571
- pure: false
572
- }]
535
+ /* eslint-disable @angular-eslint/no-pipe-impure */
536
+ class ViewportDataPipe {
537
+ constructor(viewportData, cdr) {
538
+ this.viewportData = viewportData;
539
+ this.cdr = cdr;
540
+ this.markForTransform = true;
541
+ this.data$$ = Subscription.EMPTY;
542
+ }
543
+ transform(data, strategy) {
544
+ if (!this.markForTransform && data === this.data && strategy === this.strategy) {
545
+ return this.value;
546
+ }
547
+ this.data = data;
548
+ this.strategy = strategy;
549
+ this.data$$.unsubscribe();
550
+ this.data$$ = this.viewportData.get$(data, ViewportDataMatchStrategy[strategy]).pipe(tap(value => {
551
+ this.markForTransform = true;
552
+ this.value = value;
553
+ this.cdr.markForCheck();
554
+ })).subscribe();
555
+ this.markForTransform = false;
556
+ return this.value;
557
+ }
558
+ ngOnDestroy() {
559
+ this.data$$.unsubscribe();
560
+ }
561
+ }
562
+ ViewportDataPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, deps: [{ token: ViewportDataService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Pipe });
563
+ ViewportDataPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, name: "ssvViewportData", pure: false });
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, decorators: [{
565
+ type: Pipe,
566
+ args: [{
567
+ name: "ssvViewportData",
568
+ pure: false
569
+ }]
573
570
  }], ctorParameters: function () { return [{ type: ViewportDataService }, { type: i0.ChangeDetectorRef }]; } });
574
571
 
575
- const NAME_CAMEL = "ssvViewportMatcherVar";
576
- class SsvViewportMatcherVarContext {
577
- constructor($implicit = false) {
578
- this.$implicit = $implicit;
579
- }
580
- }
581
- class SsvViewportMatcherVarDirective {
582
- constructor(viewport, viewContainer, templateRef) {
583
- this.viewport = viewport;
584
- this.viewContainer = viewContainer;
585
- this.templateRef = templateRef;
586
- this._matchConditions = {};
587
- this._context = new SsvViewportMatcherVarContext();
588
- this._destroy$ = new Subject();
589
- this._update$ = new ReplaySubject(1);
590
- }
591
- set condition(value) {
592
- if (isViewportSizeMatcherExpression(value)) {
593
- this._matchConditions.expression = value;
594
- }
595
- else if (isViewportSizeMatcherTupleExpression(value)) {
596
- const [op, size] = value;
597
- this._matchConditions.expression = {
598
- operation: op,
599
- size
600
- };
601
- }
602
- else {
603
- this._matchConditions.sizeType = value;
604
- }
605
- this._update$.next();
606
- }
607
- ngOnInit() {
608
- this.updateView();
609
- combineLatest([this.viewport.sizeType$, this._update$]).pipe(map(([sizeType]) => isViewportConditionMatch(sizeType, this._matchConditions, this.viewport.sizeTypeMap)), tap(x => this._context.$implicit = x), tap(() => this._viewRef.markForCheck()), takeUntil(this._destroy$)).subscribe();
610
- }
611
- ngOnDestroy() {
612
- this._destroy$.next();
613
- this._destroy$.complete();
614
- }
615
- updateView() {
616
- this.viewContainer.clear();
617
- this._viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this._context);
618
- }
619
- }
620
- SsvViewportMatcherVarDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, deps: [{ token: ViewportService }, { token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
621
- SsvViewportMatcherVarDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherVarDirective, selector: "[ssvViewportMatcherVar]", inputs: { condition: ["ssvViewportMatcherVarWhen", "condition"] }, ngImport: i0 });
622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, decorators: [{
623
- type: Directive,
624
- args: [{
625
- selector: `[${NAME_CAMEL}]`,
626
- }]
627
- }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { condition: [{
628
- type: Input,
629
- args: [`${NAME_CAMEL}When`]
572
+ const NAME_CAMEL = "ssvViewportMatcherVar";
573
+ class SsvViewportMatcherVarContext {
574
+ constructor($implicit = false) {
575
+ this.$implicit = $implicit;
576
+ }
577
+ }
578
+ class SsvViewportMatcherVarDirective {
579
+ constructor(viewport, viewContainer, templateRef) {
580
+ this.viewport = viewport;
581
+ this.viewContainer = viewContainer;
582
+ this.templateRef = templateRef;
583
+ this._matchConditions = {};
584
+ this._context = new SsvViewportMatcherVarContext();
585
+ this._destroy$ = new Subject();
586
+ this._update$ = new ReplaySubject(1);
587
+ }
588
+ set condition(value) {
589
+ if (isViewportSizeMatcherExpression(value)) {
590
+ this._matchConditions.expression = value;
591
+ }
592
+ else if (isViewportSizeMatcherTupleExpression(value)) {
593
+ const [op, size] = value;
594
+ this._matchConditions.expression = {
595
+ operation: op,
596
+ size
597
+ };
598
+ }
599
+ else {
600
+ this._matchConditions.sizeType = value;
601
+ }
602
+ this._update$.next();
603
+ }
604
+ ngOnInit() {
605
+ this.updateView();
606
+ combineLatest([this.viewport.sizeType$, this._update$]).pipe(map(([sizeType]) => isViewportConditionMatch(sizeType, this._matchConditions, this.viewport.sizeTypeMap)), tap(x => this._context.$implicit = x), tap(() => this._viewRef.markForCheck()), takeUntil(this._destroy$)).subscribe();
607
+ }
608
+ ngOnDestroy() {
609
+ this._destroy$.next();
610
+ this._destroy$.complete();
611
+ }
612
+ updateView() {
613
+ this.viewContainer.clear();
614
+ this._viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this._context);
615
+ }
616
+ }
617
+ SsvViewportMatcherVarDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, deps: [{ token: ViewportService }, { token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
618
+ SsvViewportMatcherVarDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherVarDirective, selector: "[ssvViewportMatcherVar]", inputs: { condition: ["ssvViewportMatcherVarWhen", "condition"] }, ngImport: i0 });
619
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, decorators: [{
620
+ type: Directive,
621
+ args: [{
622
+ selector: `[${NAME_CAMEL}]`,
623
+ }]
624
+ }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { condition: [{
625
+ type: Input,
626
+ args: [`${NAME_CAMEL}When`]
630
627
  }] } });
631
628
 
632
- class SsvViewportMatcherContext {
633
- constructor() {
634
- this.sizeType = null;
635
- this.sizeTypeExclude = null;
636
- }
637
- }
638
- class SsvViewportMatcherDirective {
639
- constructor(viewport, renderer, viewContainer, cdr, templateRef) {
640
- this.viewport = viewport;
641
- this.renderer = renderer;
642
- this.viewContainer = viewContainer;
643
- this.cdr = cdr;
644
- this._context = new SsvViewportMatcherContext();
645
- this._thenTemplateRef = null;
646
- this._elseTemplateRef = null;
647
- this._thenViewRef = null;
648
- this._elseViewRef = null;
649
- this.sizeType$$ = Subscription.EMPTY;
650
- this.cssClass$$ = Subscription.EMPTY;
651
- this._update$ = new Subject();
652
- this._thenTemplateRef = templateRef;
653
- }
654
- set ssvViewportMatcher(value) {
655
- if (isViewportSizeMatcherExpression(value)) {
656
- this._context.expression = value;
657
- }
658
- else if (isViewportSizeMatcherTupleExpression(value)) {
659
- const [op, size] = value;
660
- this._context.expression = {
661
- operation: op,
662
- size
663
- };
664
- }
665
- else {
666
- this._context.sizeType = value;
667
- }
668
- if (this.sizeInfo) {
669
- this._update$.next(this._context);
670
- }
671
- }
672
- set ssvViewportMatcherExclude(value) {
673
- this._context.sizeTypeExclude = value;
674
- if (this.sizeInfo) {
675
- this._update$.next(this._context);
676
- }
677
- }
678
- set ssvViewportMatcherElse(templateRef) {
679
- this._elseTemplateRef = templateRef;
680
- this._elseViewRef = null; // clear previous view if any.
681
- if (this.sizeInfo) {
682
- this._update$.next(this._context);
683
- }
684
- }
685
- ngOnInit() {
686
- // console.log("ssvViewportMatcher init");
687
- this._update$
688
- .pipe(
689
- // tap(x => console.log(">>> ssvViewportMatcher - update triggered", x)),
690
- filter(() => !!this.sizeInfo),
691
- // tap(x => console.log(">>> ssvViewportMatcher - updating...", x)),
692
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
693
- tap(() => this._updateView(this.sizeInfo)), tap(() => this.cdr.markForCheck()))
694
- .subscribe();
695
- this.sizeType$$ = this.viewport.sizeType$
696
- .pipe(
697
- // tap(x => console.log("ssvViewportMatcher - sizeType changed", x)),
698
- tap(x => this.sizeInfo = x), tap(() => this._update$.next(this._context)))
699
- .subscribe();
700
- this.cssClass$$ = this.viewport.sizeType$
701
- .pipe(startWith(undefined), filter(() => !!(this._thenViewRef || this._elseViewRef)), pairwise(), tap(([prev, curr]) => {
702
- const el = this._thenViewRef
703
- ? this._thenViewRef.rootNodes[0]
704
- : this._elseViewRef?.rootNodes[0];
705
- if (!el.classList) {
706
- return;
707
- }
708
- if (prev) {
709
- this.renderer.removeClass(el, `ssv-vp-size--${prev.name}`);
710
- }
711
- this.renderer.addClass(el, `ssv-vp-size--${curr?.name}`);
712
- }))
713
- .subscribe();
714
- }
715
- ngOnDestroy() {
716
- this.cssClass$$.unsubscribe();
717
- this.sizeType$$.unsubscribe();
718
- this._update$.complete();
719
- }
720
- _updateView(sizeInfo) {
721
- if (isViewportConditionMatch(sizeInfo, this._context, this.viewport.sizeTypeMap)) {
722
- if (!this._thenViewRef) {
723
- this.viewContainer.clear();
724
- this._elseViewRef = null;
725
- if (this._thenTemplateRef) {
726
- this._thenViewRef = this.viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
727
- }
728
- }
729
- }
730
- else {
731
- if (!this._elseViewRef) {
732
- this.viewContainer.clear();
733
- this._thenViewRef = null;
734
- if (this._elseTemplateRef) {
735
- this._elseViewRef = this.viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
736
- }
737
- }
738
- }
739
- }
740
- }
741
- SsvViewportMatcherDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, deps: [{ token: ViewportService }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
742
- SsvViewportMatcherDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherDirective, selector: "[ssvViewportMatcher]", inputs: { ssvViewportMatcher: "ssvViewportMatcher", ssvViewportMatcherExclude: "ssvViewportMatcherExclude", ssvViewportMatcherElse: "ssvViewportMatcherElse" }, exportAs: ["ssvViewportMatcher"], ngImport: i0 });
743
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, decorators: [{
744
- type: Directive,
745
- args: [{
746
- selector: "[ssvViewportMatcher]",
747
- exportAs: "ssvViewportMatcher",
748
- }]
749
- }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.TemplateRef }]; }, propDecorators: { ssvViewportMatcher: [{
750
- type: Input
751
- }], ssvViewportMatcherExclude: [{
752
- type: Input
753
- }], ssvViewportMatcherElse: [{
754
- type: Input
629
+ class SsvViewportMatcherContext {
630
+ constructor() {
631
+ this.sizeType = null;
632
+ this.sizeTypeExclude = null;
633
+ }
634
+ }
635
+ class SsvViewportMatcherDirective {
636
+ constructor(viewport, renderer, viewContainer, cdr, templateRef) {
637
+ this.viewport = viewport;
638
+ this.renderer = renderer;
639
+ this.viewContainer = viewContainer;
640
+ this.cdr = cdr;
641
+ this._context = new SsvViewportMatcherContext();
642
+ this._thenTemplateRef = null;
643
+ this._elseTemplateRef = null;
644
+ this._thenViewRef = null;
645
+ this._elseViewRef = null;
646
+ this.sizeType$$ = Subscription.EMPTY;
647
+ this.cssClass$$ = Subscription.EMPTY;
648
+ this._update$ = new Subject();
649
+ this._thenTemplateRef = templateRef;
650
+ }
651
+ set ssvViewportMatcher(value) {
652
+ if (isViewportSizeMatcherExpression(value)) {
653
+ this._context.expression = value;
654
+ }
655
+ else if (isViewportSizeMatcherTupleExpression(value)) {
656
+ const [op, size] = value;
657
+ this._context.expression = {
658
+ operation: op,
659
+ size
660
+ };
661
+ }
662
+ else {
663
+ this._context.sizeType = value;
664
+ }
665
+ if (this.sizeInfo) {
666
+ this._update$.next(this._context);
667
+ }
668
+ }
669
+ set ssvViewportMatcherExclude(value) {
670
+ this._context.sizeTypeExclude = value;
671
+ if (this.sizeInfo) {
672
+ this._update$.next(this._context);
673
+ }
674
+ }
675
+ set ssvViewportMatcherElse(templateRef) {
676
+ this._elseTemplateRef = templateRef;
677
+ this._elseViewRef = null; // clear previous view if any.
678
+ if (this.sizeInfo) {
679
+ this._update$.next(this._context);
680
+ }
681
+ }
682
+ ngOnInit() {
683
+ // console.log("ssvViewportMatcher init");
684
+ this._update$
685
+ .pipe(
686
+ // tap(x => console.log(">>> ssvViewportMatcher - update triggered", x)),
687
+ filter(() => !!this.sizeInfo),
688
+ // tap(x => console.log(">>> ssvViewportMatcher - updating...", x)),
689
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
690
+ tap(() => this._updateView(this.sizeInfo)), tap(() => this.cdr.markForCheck()))
691
+ .subscribe();
692
+ this.sizeType$$ = this.viewport.sizeType$
693
+ .pipe(
694
+ // tap(x => console.log("ssvViewportMatcher - sizeType changed", x)),
695
+ tap(x => this.sizeInfo = x), tap(() => this._update$.next(this._context)))
696
+ .subscribe();
697
+ this.cssClass$$ = this.viewport.sizeType$
698
+ .pipe(startWith(undefined), filter(() => !!(this._thenViewRef || this._elseViewRef)), pairwise(), tap(([prev, curr]) => {
699
+ const el = this._thenViewRef
700
+ ? this._thenViewRef.rootNodes[0]
701
+ : this._elseViewRef?.rootNodes[0];
702
+ if (!el.classList) {
703
+ return;
704
+ }
705
+ if (prev) {
706
+ this.renderer.removeClass(el, `ssv-vp-size--${prev.name}`);
707
+ }
708
+ this.renderer.addClass(el, `ssv-vp-size--${curr?.name}`);
709
+ }))
710
+ .subscribe();
711
+ }
712
+ ngOnDestroy() {
713
+ this.cssClass$$.unsubscribe();
714
+ this.sizeType$$.unsubscribe();
715
+ this._update$.complete();
716
+ }
717
+ _updateView(sizeInfo) {
718
+ if (isViewportConditionMatch(sizeInfo, this._context, this.viewport.sizeTypeMap)) {
719
+ if (!this._thenViewRef) {
720
+ this.viewContainer.clear();
721
+ this._elseViewRef = null;
722
+ if (this._thenTemplateRef) {
723
+ this._thenViewRef = this.viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
724
+ }
725
+ }
726
+ }
727
+ else {
728
+ if (!this._elseViewRef) {
729
+ this.viewContainer.clear();
730
+ this._thenViewRef = null;
731
+ if (this._elseTemplateRef) {
732
+ this._elseViewRef = this.viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
733
+ }
734
+ }
735
+ }
736
+ }
737
+ }
738
+ SsvViewportMatcherDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, deps: [{ token: ViewportService }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
739
+ SsvViewportMatcherDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherDirective, selector: "[ssvViewportMatcher]", inputs: { ssvViewportMatcher: "ssvViewportMatcher", ssvViewportMatcherExclude: "ssvViewportMatcherExclude", ssvViewportMatcherElse: "ssvViewportMatcherElse" }, exportAs: ["ssvViewportMatcher"], ngImport: i0 });
740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, decorators: [{
741
+ type: Directive,
742
+ args: [{
743
+ selector: "[ssvViewportMatcher]",
744
+ exportAs: "ssvViewportMatcher",
745
+ }]
746
+ }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.TemplateRef }]; }, propDecorators: { ssvViewportMatcher: [{
747
+ type: Input
748
+ }], ssvViewportMatcherExclude: [{
749
+ type: Input
750
+ }], ssvViewportMatcherElse: [{
751
+ type: Input
755
752
  }] } });
756
753
 
757
- /** @internal */
758
- const MODULE_CONFIG_DATA = new InjectionToken("@ssv/ngx.ux/configData");
759
- const components = [
760
- SsvViewportMatcherDirective,
761
- SsvViewportMatcherVarDirective,
762
- ViewportDataPipe,
763
- ];
764
- // todo: create module for Viewport
765
- class SsvUxModule {
766
- static forRoot(config) {
767
- return {
768
- ngModule: SsvUxModule,
769
- providers: [
770
- { provide: MODULE_CONFIG_DATA, useValue: config },
771
- ],
772
- };
773
- }
774
- }
775
- SsvUxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
776
- SsvUxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, declarations: [SsvViewportMatcherDirective,
777
- SsvViewportMatcherVarDirective,
778
- ViewportDataPipe], exports: [SsvViewportMatcherDirective,
779
- SsvViewportMatcherVarDirective,
780
- ViewportDataPipe] });
781
- SsvUxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, providers: [
782
- { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
783
- { provide: WINDOW, useFactory: _window },
784
- ] });
785
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, decorators: [{
786
- type: NgModule,
787
- args: [{
788
- declarations: [components],
789
- providers: [
790
- { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
791
- { provide: WINDOW, useFactory: _window },
792
- ],
793
- exports: [...components],
794
- }]
795
- }] });
796
- /** @internal */
797
- function _moduleConfigFactory(config) {
798
- if (!config) {
799
- return UX_DEFAULT_CONFIG;
800
- }
801
- const uxOptions = typeof config === "function" ? config() : config;
802
- const viewport = {
803
- ...UX_DEFAULT_CONFIG.viewport,
804
- ...uxOptions.viewport
805
- }; // breakpoints shouldn't be merged
806
- return { viewport };
807
- }
808
- /** @internal */
809
- function _window() {
810
- if (typeof window !== "undefined") {
811
- return window;
812
- }
813
- return {};
754
+ /** @internal */
755
+ const MODULE_CONFIG_DATA = new InjectionToken("@ssv/ngx.ux/configData");
756
+ const components = [
757
+ SsvViewportMatcherDirective,
758
+ SsvViewportMatcherVarDirective,
759
+ ViewportDataPipe,
760
+ ];
761
+ // todo: create module for Viewport
762
+ class SsvUxModule {
763
+ static forRoot(config) {
764
+ return {
765
+ ngModule: SsvUxModule,
766
+ providers: [
767
+ { provide: MODULE_CONFIG_DATA, useValue: config },
768
+ ],
769
+ };
770
+ }
771
+ }
772
+ SsvUxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
773
+ SsvUxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, declarations: [SsvViewportMatcherDirective,
774
+ SsvViewportMatcherVarDirective,
775
+ ViewportDataPipe], exports: [SsvViewportMatcherDirective,
776
+ SsvViewportMatcherVarDirective,
777
+ ViewportDataPipe] });
778
+ SsvUxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, providers: [
779
+ { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
780
+ { provide: WINDOW, useFactory: _window },
781
+ ] });
782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, decorators: [{
783
+ type: NgModule,
784
+ args: [{
785
+ declarations: [components],
786
+ providers: [
787
+ { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
788
+ { provide: WINDOW, useFactory: _window },
789
+ ],
790
+ exports: [...components],
791
+ }]
792
+ }] });
793
+ /** @internal */
794
+ function _moduleConfigFactory(config) {
795
+ if (!config) {
796
+ return UX_DEFAULT_CONFIG;
797
+ }
798
+ const uxOptions = typeof config === "function" ? config() : config;
799
+ const viewport = {
800
+ ...UX_DEFAULT_CONFIG.viewport,
801
+ ...uxOptions.viewport
802
+ }; // breakpoints shouldn't be merged
803
+ return { viewport };
804
+ }
805
+ /** @internal */
806
+ function _window() {
807
+ if (typeof window !== "undefined") {
808
+ return window;
809
+ }
810
+ return {};
814
811
  }
815
812
 
816
813
  const VERSION = "0.0.0-PLACEHOLDER";
817
814
 
818
- /**
819
- * Generated bundle index. Do not edit.
815
+ /**
816
+ * Generated bundle index. Do not edit.
820
817
  */
821
818
 
822
819
  export { ComparisonOperation, DeviceType, MODULE_CONFIG_DATA, SsvUxModule, SsvViewportMatcherContext, SsvViewportMatcherDirective, SsvViewportMatcherVarContext, SsvViewportMatcherVarDirective, UX_CONFIG, UX_DEFAULT_CONFIG, UX_VIEWPORT_DEFAULT_BREAKPOINTS, UX_VIEWPORT_SSR_DEVICE, VERSION, ViewportDataMatchStrategy, ViewportDataPipe, ViewportDataService, ViewportServerSizeService, ViewportService, ViewportSizeType, _moduleConfigFactory, _window, generateViewportSizeType };