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

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 +297 -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 +18 -18
  21. package/esm2020/viewport/viewport.model.mjs +31 -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 +789 -790
  25. package/fesm2015/ssv-ngx.ux.mjs.map +1 -1
  26. package/fesm2020/ssv-ngx.ux.mjs +783 -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 +57 -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,826 +3,825 @@ 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: 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,
129
129
  };
130
130
 
131
- const UX_DEFAULT_CONFIG = {
132
- viewport: UX_VIEWPORT_DEFAULT_CONFIG,
133
- };
131
+ const UX_DEFAULT_CONFIG = {
132
+ viewport: UX_VIEWPORT_DEFAULT_CONFIG,
133
+ };
134
134
  const UX_CONFIG = new InjectionToken("@ssv/ngx.ux-config");
135
135
 
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 === null || prevRule === void 0 ? void 0 : 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 === null || prevRule === void 0 ? void 0 : 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;
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 === null || prevRule === void 0 ? void 0 : 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 === null || prevRule === void 0 ? void 0 : 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;
233
233
  }
234
234
 
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";
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";
264
264
  })(DeviceType || (DeviceType = {}));
265
265
 
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
- }, {}));
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
+ }, {}));
380
380
  }
381
381
 
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 () {
406
- return [{ type: undefined, decorators: [{
407
- type: Inject,
408
- args: [WINDOW]
409
- }] }];
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 () {
406
+ return [{ type: undefined, decorators: [{
407
+ type: Inject,
408
+ args: [WINDOW]
409
+ }] }];
410
410
  } });
411
411
 
412
- // todo: make this configurable
413
- /** Viewport size for SSR. */
414
- const viewportSizeSSR = {
415
- [DeviceType.desktop]: {
416
- width: 1366,
417
- height: 768,
418
- },
419
- [DeviceType.tablet]: {
420
- width: 768,
421
- height: 1024,
422
- },
423
- [DeviceType.mobile]: {
424
- width: 414,
425
- height: 736,
426
- },
427
- };
428
- const UX_VIEWPORT_SSR_DEVICE = new InjectionToken("@ssv/ngx.ux-config/viewport/ssr-device");
429
- class ViewportServerSizeService {
430
- constructor(deviceType) {
431
- this.deviceType = deviceType;
432
- }
433
- get() {
434
- return viewportSizeSSR[this.deviceType] || viewportSizeSSR[DeviceType.desktop];
435
- }
436
- }
437
- 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 });
438
- ViewportServerSizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, providedIn: "root" });
439
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, decorators: [{
440
- type: Injectable,
441
- args: [{
442
- providedIn: "root",
443
- }]
444
- }], ctorParameters: function () {
445
- return [{ type: DeviceType, decorators: [{
446
- type: Optional
447
- }, {
448
- type: Inject,
449
- args: [UX_VIEWPORT_SSR_DEVICE]
450
- }] }];
412
+ // todo: make this configurable
413
+ /** Viewport size for SSR. */
414
+ const viewportSizeSSR = {
415
+ [DeviceType.desktop]: {
416
+ width: 1366,
417
+ height: 768,
418
+ },
419
+ [DeviceType.tablet]: {
420
+ width: 768,
421
+ height: 1024,
422
+ },
423
+ [DeviceType.mobile]: {
424
+ width: 414,
425
+ height: 736,
426
+ },
427
+ };
428
+ const UX_VIEWPORT_SSR_DEVICE = new InjectionToken("@ssv/ngx.ux-config/viewport/ssr-device");
429
+ class ViewportServerSizeService {
430
+ constructor(deviceType) {
431
+ this.deviceType = deviceType;
432
+ }
433
+ get() {
434
+ return viewportSizeSSR[this.deviceType] || viewportSizeSSR[DeviceType.desktop];
435
+ }
436
+ }
437
+ 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 });
438
+ ViewportServerSizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, providedIn: "root" });
439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportServerSizeService, decorators: [{
440
+ type: Injectable,
441
+ args: [{
442
+ providedIn: "root",
443
+ }]
444
+ }], ctorParameters: function () {
445
+ return [{ type: DeviceType, decorators: [{
446
+ type: Optional
447
+ }, {
448
+ type: Inject,
449
+ args: [UX_VIEWPORT_SSR_DEVICE]
450
+ }] }];
451
451
  } });
452
452
 
453
- class ViewportService {
454
- constructor(windowRef, viewportServerSize, config) {
455
- this.windowRef = windowRef;
456
- this.viewportServerSize = viewportServerSize;
457
- console.warn(">>>> yolo service");
458
- this._sizeTypes = generateViewportSizeTypeInfoList(config.viewport.breakpoints);
459
- this._sizeTypeMap = generateViewportSizeTypeInfoRefs(this._sizeTypes);
460
- if (windowRef.hasNative) {
461
- this.resizeSnap$ = fromEvent(window, "resize").pipe(map(() => this.getViewportSize()), share());
462
- this.resize$ = this.resizeSnap$.pipe(auditTime(config.viewport.resizePollingSpeed), share());
463
- }
464
- else {
465
- this.resizeSnap$ = this.resize$ = of(viewportServerSize.get());
466
- }
467
- const size = this.getViewportSize();
468
- this._sizeTypeSnapshot = getSizeTypeInfo(size.width, this.sizeTypes);
469
- const sizeFn = (obs$) => obs$.pipe(startWith(size), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), shareReplay(1));
470
- this.sizeSnap$ = sizeFn(this.resizeSnap$);
471
- this.size$ = sizeFn(this.resize$);
472
- 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));
473
- this.sizeType$ = sizeTypeFn(this.size$);
474
- this.sizeTypeSnap$ = sizeTypeFn(this.sizeSnap$);
475
- }
476
- /** Viewport size type snapshot of the last value. (Prefer use `sizeType$` observable when possible.) */
477
- get sizeTypeSnapshot() { return this._sizeTypeSnapshot; }
478
- /** Size types refs of the generated viewport size type info. */
479
- get sizeTypeMap() { return this._sizeTypeMap; }
480
- /** Viewport size types list ordered by type, smallest to largest. */
481
- get sizeTypes() { return this._sizeTypes; }
482
- /** Returns the current viewport size */
483
- getViewportSize() {
484
- if (!this.windowRef.hasNative) {
485
- return this.viewportServerSize.get();
486
- }
487
- const ua = navigator.userAgent.toLowerCase();
488
- if (ua.indexOf("safari") !== -1 && ua.indexOf("chrome") === -1) { // safari subtracts the scrollbar width
489
- return {
490
- width: this.windowRef.native.document.documentElement.clientWidth,
491
- height: this.windowRef.native.document.documentElement.clientHeight,
492
- };
493
- }
494
- return {
495
- width: this.windowRef.native.innerWidth,
496
- height: this.windowRef.native.innerHeight,
497
- };
498
- }
499
- }
500
- 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 });
501
- ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, providedIn: "root" });
502
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, decorators: [{
503
- type: Injectable,
504
- args: [{
505
- providedIn: "root",
506
- }]
507
- }], ctorParameters: function () {
508
- return [{ type: WindowRef }, { type: ViewportServerSizeService }, { type: undefined, decorators: [{
509
- type: Inject,
510
- args: [UX_CONFIG]
511
- }] }];
453
+ class ViewportService {
454
+ constructor(windowRef, viewportServerSize, config) {
455
+ this.windowRef = windowRef;
456
+ this.viewportServerSize = viewportServerSize;
457
+ this._sizeTypes = generateViewportSizeTypeInfoList(config.viewport.breakpoints);
458
+ this._sizeTypeMap = generateViewportSizeTypeInfoRefs(this._sizeTypes);
459
+ if (windowRef.hasNative) {
460
+ this.resizeSnap$ = fromEvent(window, "resize").pipe(map(() => this.getViewportSize()), share());
461
+ this.resize$ = this.resizeSnap$.pipe(auditTime(config.viewport.resizePollingSpeed), share());
462
+ }
463
+ else {
464
+ this.resizeSnap$ = this.resize$ = of(viewportServerSize.get());
465
+ }
466
+ const size = this.getViewportSize();
467
+ this._sizeTypeSnapshot = getSizeTypeInfo(size.width, this.sizeTypes);
468
+ const sizeFn = (obs$) => obs$.pipe(startWith(size), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), shareReplay(1));
469
+ this.sizeSnap$ = sizeFn(this.resizeSnap$);
470
+ this.size$ = sizeFn(this.resize$);
471
+ 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));
472
+ this.sizeType$ = sizeTypeFn(this.size$);
473
+ this.sizeTypeSnap$ = sizeTypeFn(this.sizeSnap$);
474
+ }
475
+ /** Viewport size type snapshot of the last value. (Prefer use `sizeType$` observable when possible.) */
476
+ get sizeTypeSnapshot() { return this._sizeTypeSnapshot; }
477
+ /** Size types refs of the generated viewport size type info. */
478
+ get sizeTypeMap() { return this._sizeTypeMap; }
479
+ /** Viewport size types list ordered by type, smallest to largest. */
480
+ get sizeTypes() { return this._sizeTypes; }
481
+ /** Returns the current viewport size */
482
+ getViewportSize() {
483
+ if (!this.windowRef.hasNative) {
484
+ return this.viewportServerSize.get();
485
+ }
486
+ const ua = navigator.userAgent.toLowerCase();
487
+ if (ua.indexOf("safari") !== -1 && ua.indexOf("chrome") === -1) { // safari subtracts the scrollbar width
488
+ return {
489
+ width: this.windowRef.native.document.documentElement.clientWidth,
490
+ height: this.windowRef.native.document.documentElement.clientHeight,
491
+ };
492
+ }
493
+ return {
494
+ width: this.windowRef.native.innerWidth,
495
+ height: this.windowRef.native.innerHeight,
496
+ };
497
+ }
498
+ }
499
+ 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 });
500
+ ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, providedIn: "root" });
501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportService, decorators: [{
502
+ type: Injectable,
503
+ args: [{
504
+ providedIn: "root",
505
+ }]
506
+ }], ctorParameters: function () {
507
+ return [{ type: WindowRef }, { type: ViewportServerSizeService }, { type: undefined, decorators: [{
508
+ type: Inject,
509
+ args: [UX_CONFIG]
510
+ }] }];
512
511
  } });
513
512
 
514
- class ViewportDataService {
515
- constructor(viewport, config) {
516
- this.viewport = viewport;
517
- this.config = config;
518
- }
519
- /** Get data for match. */
520
- get(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy, sizeType = this.viewport.sizeTypeSnapshot) {
521
- return matchViewportData(dataConfig, sizeType, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
522
- }
523
- /** Get data for match as observable. */
524
- get$(dataConfig, strategy, throttle = true) {
525
- return (throttle ? this.viewport.sizeType$ : this.viewport.sizeTypeSnap$).pipe(map(sizeType => this.get(dataConfig, strategy, sizeType)), distinctUntilChanged());
526
- }
527
- /** Generate rules based on strategies for data. */
528
- generateRules(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy) {
529
- return generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
530
- }
531
- }
532
- 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 });
533
- ViewportDataService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, providedIn: "root" });
534
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, decorators: [{
535
- type: Injectable,
536
- args: [{
537
- providedIn: "root",
538
- }]
539
- }], ctorParameters: function () {
540
- return [{ type: ViewportService }, { type: undefined, decorators: [{
541
- type: Inject,
542
- args: [UX_CONFIG]
543
- }] }];
513
+ class ViewportDataService {
514
+ constructor(viewport, config) {
515
+ this.viewport = viewport;
516
+ this.config = config;
517
+ }
518
+ /** Get data for match. */
519
+ get(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy, sizeType = this.viewport.sizeTypeSnapshot) {
520
+ return matchViewportData(dataConfig, sizeType, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
521
+ }
522
+ /** Get data for match as observable. */
523
+ get$(dataConfig, strategy, throttle = true) {
524
+ return (throttle ? this.viewport.sizeType$ : this.viewport.sizeTypeSnap$).pipe(map(sizeType => this.get(dataConfig, strategy, sizeType)), distinctUntilChanged());
525
+ }
526
+ /** Generate rules based on strategies for data. */
527
+ generateRules(dataConfig, strategy = this.config.viewport.defaultDataMatchStrategy) {
528
+ return generateViewportRulesRangeFromDataMatcher(dataConfig, strategy, this.viewport.sizeTypes, this.viewport.sizeTypeMap);
529
+ }
530
+ }
531
+ 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 });
532
+ ViewportDataService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, providedIn: "root" });
533
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataService, decorators: [{
534
+ type: Injectable,
535
+ args: [{
536
+ providedIn: "root",
537
+ }]
538
+ }], ctorParameters: function () {
539
+ return [{ type: ViewportService }, { type: undefined, decorators: [{
540
+ type: Inject,
541
+ args: [UX_CONFIG]
542
+ }] }];
544
543
  } });
545
544
 
546
- /* eslint-disable @angular-eslint/no-pipe-impure */
547
- class ViewportDataPipe {
548
- constructor(viewportData, cdr) {
549
- this.viewportData = viewportData;
550
- this.cdr = cdr;
551
- this.markForTransform = true;
552
- this.data$$ = Subscription.EMPTY;
553
- }
554
- transform(data, strategy) {
555
- if (!this.markForTransform && data === this.data && strategy === this.strategy) {
556
- return this.value;
557
- }
558
- this.data = data;
559
- this.strategy = strategy;
560
- this.data$$.unsubscribe();
561
- this.data$$ = this.viewportData.get$(data, ViewportDataMatchStrategy[strategy]).pipe(tap(value => {
562
- this.markForTransform = true;
563
- this.value = value;
564
- this.cdr.markForCheck();
565
- })).subscribe();
566
- this.markForTransform = false;
567
- return this.value;
568
- }
569
- ngOnDestroy() {
570
- this.data$$.unsubscribe();
571
- }
572
- }
573
- 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 });
574
- ViewportDataPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, name: "ssvViewportData", pure: false });
575
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, decorators: [{
576
- type: Pipe,
577
- args: [{
578
- name: "ssvViewportData",
579
- pure: false
580
- }]
545
+ /* eslint-disable @angular-eslint/no-pipe-impure */
546
+ class ViewportDataPipe {
547
+ constructor(viewportData, cdr) {
548
+ this.viewportData = viewportData;
549
+ this.cdr = cdr;
550
+ this.markForTransform = true;
551
+ this.data$$ = Subscription.EMPTY;
552
+ }
553
+ transform(data, strategy) {
554
+ if (!this.markForTransform && data === this.data && strategy === this.strategy) {
555
+ return this.value;
556
+ }
557
+ this.data = data;
558
+ this.strategy = strategy;
559
+ this.data$$.unsubscribe();
560
+ this.data$$ = this.viewportData.get$(data, ViewportDataMatchStrategy[strategy]).pipe(tap(value => {
561
+ this.markForTransform = true;
562
+ this.value = value;
563
+ this.cdr.markForCheck();
564
+ })).subscribe();
565
+ this.markForTransform = false;
566
+ return this.value;
567
+ }
568
+ ngOnDestroy() {
569
+ this.data$$.unsubscribe();
570
+ }
571
+ }
572
+ 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 });
573
+ ViewportDataPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, name: "ssvViewportData", pure: false });
574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ViewportDataPipe, decorators: [{
575
+ type: Pipe,
576
+ args: [{
577
+ name: "ssvViewportData",
578
+ pure: false
579
+ }]
581
580
  }], ctorParameters: function () { return [{ type: ViewportDataService }, { type: i0.ChangeDetectorRef }]; } });
582
581
 
583
- const NAME_CAMEL = "ssvViewportMatcherVar";
584
- class SsvViewportMatcherVarContext {
585
- constructor($implicit = false) {
586
- this.$implicit = $implicit;
587
- }
588
- }
589
- class SsvViewportMatcherVarDirective {
590
- constructor(viewport, viewContainer, templateRef) {
591
- this.viewport = viewport;
592
- this.viewContainer = viewContainer;
593
- this.templateRef = templateRef;
594
- this._matchConditions = {};
595
- this._context = new SsvViewportMatcherVarContext();
596
- this._destroy$ = new Subject();
597
- this._update$ = new ReplaySubject(1);
598
- }
599
- set condition(value) {
600
- if (isViewportSizeMatcherExpression(value)) {
601
- this._matchConditions.expression = value;
602
- }
603
- else if (isViewportSizeMatcherTupleExpression(value)) {
604
- const [op, size] = value;
605
- this._matchConditions.expression = {
606
- operation: op,
607
- size
608
- };
609
- }
610
- else {
611
- this._matchConditions.sizeType = value;
612
- }
613
- this._update$.next();
614
- }
615
- ngOnInit() {
616
- this.updateView();
617
- 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();
618
- }
619
- ngOnDestroy() {
620
- this._destroy$.next();
621
- this._destroy$.complete();
622
- }
623
- updateView() {
624
- this.viewContainer.clear();
625
- this._viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this._context);
626
- }
627
- }
628
- 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 });
629
- SsvViewportMatcherVarDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherVarDirective, selector: "[ssvViewportMatcherVar]", inputs: { condition: ["ssvViewportMatcherVarWhen", "condition"] }, ngImport: i0 });
630
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, decorators: [{
631
- type: Directive,
632
- args: [{
633
- selector: `[${NAME_CAMEL}]`,
634
- }]
635
- }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { condition: [{
636
- type: Input,
637
- args: [`${NAME_CAMEL}When`]
582
+ const NAME_CAMEL = "ssvViewportMatcherVar";
583
+ class SsvViewportMatcherVarContext {
584
+ constructor($implicit = false) {
585
+ this.$implicit = $implicit;
586
+ }
587
+ }
588
+ class SsvViewportMatcherVarDirective {
589
+ constructor(viewport, viewContainer, templateRef) {
590
+ this.viewport = viewport;
591
+ this.viewContainer = viewContainer;
592
+ this.templateRef = templateRef;
593
+ this._matchConditions = {};
594
+ this._context = new SsvViewportMatcherVarContext();
595
+ this._destroy$ = new Subject();
596
+ this._update$ = new ReplaySubject(1);
597
+ }
598
+ set condition(value) {
599
+ if (isViewportSizeMatcherExpression(value)) {
600
+ this._matchConditions.expression = value;
601
+ }
602
+ else if (isViewportSizeMatcherTupleExpression(value)) {
603
+ const [op, size] = value;
604
+ this._matchConditions.expression = {
605
+ operation: op,
606
+ size
607
+ };
608
+ }
609
+ else {
610
+ this._matchConditions.sizeType = value;
611
+ }
612
+ this._update$.next();
613
+ }
614
+ ngOnInit() {
615
+ this.updateView();
616
+ 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();
617
+ }
618
+ ngOnDestroy() {
619
+ this._destroy$.next();
620
+ this._destroy$.complete();
621
+ }
622
+ updateView() {
623
+ this.viewContainer.clear();
624
+ this._viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this._context);
625
+ }
626
+ }
627
+ 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 });
628
+ SsvViewportMatcherVarDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SsvViewportMatcherVarDirective, selector: "[ssvViewportMatcherVar]", inputs: { condition: ["ssvViewportMatcherVarWhen", "condition"] }, ngImport: i0 });
629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherVarDirective, decorators: [{
630
+ type: Directive,
631
+ args: [{
632
+ selector: `[${NAME_CAMEL}]`,
633
+ }]
634
+ }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { condition: [{
635
+ type: Input,
636
+ args: [`${NAME_CAMEL}When`]
638
637
  }] } });
639
638
 
640
- class SsvViewportMatcherContext {
641
- constructor() {
642
- this.sizeType = null;
643
- this.sizeTypeExclude = null;
644
- }
645
- }
646
- class SsvViewportMatcherDirective {
647
- constructor(viewport, renderer, viewContainer, cdr, templateRef) {
648
- this.viewport = viewport;
649
- this.renderer = renderer;
650
- this.viewContainer = viewContainer;
651
- this.cdr = cdr;
652
- this._context = new SsvViewportMatcherContext();
653
- this._thenTemplateRef = null;
654
- this._elseTemplateRef = null;
655
- this._thenViewRef = null;
656
- this._elseViewRef = null;
657
- this.sizeType$$ = Subscription.EMPTY;
658
- this.cssClass$$ = Subscription.EMPTY;
659
- this._update$ = new Subject();
660
- this._thenTemplateRef = templateRef;
661
- }
662
- set ssvViewportMatcher(value) {
663
- if (isViewportSizeMatcherExpression(value)) {
664
- this._context.expression = value;
665
- }
666
- else if (isViewportSizeMatcherTupleExpression(value)) {
667
- const [op, size] = value;
668
- this._context.expression = {
669
- operation: op,
670
- size
671
- };
672
- }
673
- else {
674
- this._context.sizeType = value;
675
- }
676
- if (this.sizeInfo) {
677
- this._update$.next(this._context);
678
- }
679
- }
680
- set ssvViewportMatcherExclude(value) {
681
- this._context.sizeTypeExclude = value;
682
- if (this.sizeInfo) {
683
- this._update$.next(this._context);
684
- }
685
- }
686
- set ssvViewportMatcherElse(templateRef) {
687
- this._elseTemplateRef = templateRef;
688
- this._elseViewRef = null; // clear previous view if any.
689
- if (this.sizeInfo) {
690
- this._update$.next(this._context);
691
- }
692
- }
693
- ngOnInit() {
694
- // console.log("ssvViewportMatcher init");
695
- this._update$
696
- .pipe(
697
- // tap(x => console.log(">>> ssvViewportMatcher - update triggered", x)),
698
- filter(() => !!this.sizeInfo),
699
- // tap(x => console.log(">>> ssvViewportMatcher - updating...", x)),
700
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
701
- tap(() => this._updateView(this.sizeInfo)), tap(() => this.cdr.markForCheck()))
702
- .subscribe();
703
- this.sizeType$$ = this.viewport.sizeType$
704
- .pipe(
705
- // tap(x => console.log("ssvViewportMatcher - sizeType changed", x)),
706
- tap(x => this.sizeInfo = x), tap(() => this._update$.next(this._context)))
707
- .subscribe();
708
- this.cssClass$$ = this.viewport.sizeType$
709
- .pipe(startWith(undefined), filter(() => !!(this._thenViewRef || this._elseViewRef)), pairwise(), tap(([prev, curr]) => {
710
- var _a;
711
- const el = this._thenViewRef
712
- ? this._thenViewRef.rootNodes[0]
713
- : (_a = this._elseViewRef) === null || _a === void 0 ? void 0 : _a.rootNodes[0];
714
- if (!el.classList) {
715
- return;
716
- }
717
- if (prev) {
718
- this.renderer.removeClass(el, `ssv-vp-size--${prev.name}`);
719
- }
720
- this.renderer.addClass(el, `ssv-vp-size--${curr === null || curr === void 0 ? void 0 : curr.name}`);
721
- }))
722
- .subscribe();
723
- }
724
- ngOnDestroy() {
725
- this.cssClass$$.unsubscribe();
726
- this.sizeType$$.unsubscribe();
727
- this._update$.complete();
728
- }
729
- _updateView(sizeInfo) {
730
- if (isViewportConditionMatch(sizeInfo, this._context, this.viewport.sizeTypeMap)) {
731
- if (!this._thenViewRef) {
732
- this.viewContainer.clear();
733
- this._elseViewRef = null;
734
- if (this._thenTemplateRef) {
735
- this._thenViewRef = this.viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
736
- }
737
- }
738
- }
739
- else {
740
- if (!this._elseViewRef) {
741
- this.viewContainer.clear();
742
- this._thenViewRef = null;
743
- if (this._elseTemplateRef) {
744
- this._elseViewRef = this.viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
745
- }
746
- }
747
- }
748
- }
749
- }
750
- 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 });
751
- 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 });
752
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, decorators: [{
753
- type: Directive,
754
- args: [{
755
- selector: "[ssvViewportMatcher]",
756
- exportAs: "ssvViewportMatcher",
757
- }]
758
- }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.TemplateRef }]; }, propDecorators: { ssvViewportMatcher: [{
759
- type: Input
760
- }], ssvViewportMatcherExclude: [{
761
- type: Input
762
- }], ssvViewportMatcherElse: [{
763
- type: Input
639
+ class SsvViewportMatcherContext {
640
+ constructor() {
641
+ this.sizeType = null;
642
+ this.sizeTypeExclude = null;
643
+ }
644
+ }
645
+ class SsvViewportMatcherDirective {
646
+ constructor(viewport, renderer, viewContainer, cdr, templateRef) {
647
+ this.viewport = viewport;
648
+ this.renderer = renderer;
649
+ this.viewContainer = viewContainer;
650
+ this.cdr = cdr;
651
+ this._context = new SsvViewportMatcherContext();
652
+ this._thenTemplateRef = null;
653
+ this._elseTemplateRef = null;
654
+ this._thenViewRef = null;
655
+ this._elseViewRef = null;
656
+ this.sizeType$$ = Subscription.EMPTY;
657
+ this.cssClass$$ = Subscription.EMPTY;
658
+ this._update$ = new Subject();
659
+ this._thenTemplateRef = templateRef;
660
+ }
661
+ set ssvViewportMatcher(value) {
662
+ if (isViewportSizeMatcherExpression(value)) {
663
+ this._context.expression = value;
664
+ }
665
+ else if (isViewportSizeMatcherTupleExpression(value)) {
666
+ const [op, size] = value;
667
+ this._context.expression = {
668
+ operation: op,
669
+ size
670
+ };
671
+ }
672
+ else {
673
+ this._context.sizeType = value;
674
+ }
675
+ if (this.sizeInfo) {
676
+ this._update$.next(this._context);
677
+ }
678
+ }
679
+ set ssvViewportMatcherExclude(value) {
680
+ this._context.sizeTypeExclude = value;
681
+ if (this.sizeInfo) {
682
+ this._update$.next(this._context);
683
+ }
684
+ }
685
+ set ssvViewportMatcherElse(templateRef) {
686
+ this._elseTemplateRef = templateRef;
687
+ this._elseViewRef = null; // clear previous view if any.
688
+ if (this.sizeInfo) {
689
+ this._update$.next(this._context);
690
+ }
691
+ }
692
+ ngOnInit() {
693
+ // console.log("ssvViewportMatcher init");
694
+ this._update$
695
+ .pipe(
696
+ // tap(x => console.log(">>> ssvViewportMatcher - update triggered", x)),
697
+ filter(() => !!this.sizeInfo),
698
+ // tap(x => console.log(">>> ssvViewportMatcher - updating...", x)),
699
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
700
+ tap(() => this._updateView(this.sizeInfo)), tap(() => this.cdr.markForCheck()))
701
+ .subscribe();
702
+ this.sizeType$$ = this.viewport.sizeType$
703
+ .pipe(
704
+ // tap(x => console.log("ssvViewportMatcher - sizeType changed", x)),
705
+ tap(x => this.sizeInfo = x), tap(() => this._update$.next(this._context)))
706
+ .subscribe();
707
+ this.cssClass$$ = this.viewport.sizeType$
708
+ .pipe(startWith(undefined), filter(() => !!(this._thenViewRef || this._elseViewRef)), pairwise(), tap(([prev, curr]) => {
709
+ var _a;
710
+ const el = this._thenViewRef
711
+ ? this._thenViewRef.rootNodes[0]
712
+ : (_a = this._elseViewRef) === null || _a === void 0 ? void 0 : _a.rootNodes[0];
713
+ if (!el.classList) {
714
+ return;
715
+ }
716
+ if (prev) {
717
+ this.renderer.removeClass(el, `ssv-vp-size--${prev.name}`);
718
+ }
719
+ this.renderer.addClass(el, `ssv-vp-size--${curr === null || curr === void 0 ? void 0 : curr.name}`);
720
+ }))
721
+ .subscribe();
722
+ }
723
+ ngOnDestroy() {
724
+ this.cssClass$$.unsubscribe();
725
+ this.sizeType$$.unsubscribe();
726
+ this._update$.complete();
727
+ }
728
+ _updateView(sizeInfo) {
729
+ if (isViewportConditionMatch(sizeInfo, this._context, this.viewport.sizeTypeMap)) {
730
+ if (!this._thenViewRef) {
731
+ this.viewContainer.clear();
732
+ this._elseViewRef = null;
733
+ if (this._thenTemplateRef) {
734
+ this._thenViewRef = this.viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
735
+ }
736
+ }
737
+ }
738
+ else {
739
+ if (!this._elseViewRef) {
740
+ this.viewContainer.clear();
741
+ this._thenViewRef = null;
742
+ if (this._elseTemplateRef) {
743
+ this._elseViewRef = this.viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
744
+ }
745
+ }
746
+ }
747
+ }
748
+ }
749
+ 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 });
750
+ 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 });
751
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvViewportMatcherDirective, decorators: [{
752
+ type: Directive,
753
+ args: [{
754
+ selector: "[ssvViewportMatcher]",
755
+ exportAs: "ssvViewportMatcher",
756
+ }]
757
+ }], ctorParameters: function () { return [{ type: ViewportService }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i0.TemplateRef }]; }, propDecorators: { ssvViewportMatcher: [{
758
+ type: Input
759
+ }], ssvViewportMatcherExclude: [{
760
+ type: Input
761
+ }], ssvViewportMatcherElse: [{
762
+ type: Input
764
763
  }] } });
765
764
 
766
- /** @internal */
767
- const MODULE_CONFIG_DATA = new InjectionToken("@ssv/ngx.ux/configData");
768
- const components = [
769
- SsvViewportMatcherDirective,
770
- SsvViewportMatcherVarDirective,
771
- ViewportDataPipe,
772
- ];
773
- // todo: create module for Viewport
774
- class SsvUxModule {
775
- static forRoot(config) {
776
- return {
777
- ngModule: SsvUxModule,
778
- providers: [
779
- { provide: MODULE_CONFIG_DATA, useValue: config },
780
- ],
781
- };
782
- }
783
- }
784
- SsvUxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
785
- SsvUxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, declarations: [SsvViewportMatcherDirective,
786
- SsvViewportMatcherVarDirective,
787
- ViewportDataPipe], exports: [SsvViewportMatcherDirective,
788
- SsvViewportMatcherVarDirective,
789
- ViewportDataPipe] });
790
- SsvUxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, providers: [
791
- { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
792
- { provide: WINDOW, useFactory: _window },
793
- ] });
794
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, decorators: [{
795
- type: NgModule,
796
- args: [{
797
- declarations: [components],
798
- providers: [
799
- { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
800
- { provide: WINDOW, useFactory: _window },
801
- ],
802
- exports: [...components],
803
- }]
804
- }] });
805
- /** @internal */
806
- function _moduleConfigFactory(config) {
807
- if (!config) {
808
- return UX_DEFAULT_CONFIG;
809
- }
810
- const uxOptions = typeof config === "function" ? config() : config;
811
- const viewport = Object.assign(Object.assign({}, UX_DEFAULT_CONFIG.viewport), uxOptions.viewport); // breakpoints shouldn't be merged
812
- return { viewport };
813
- }
814
- /** @internal */
815
- function _window() {
816
- if (typeof window !== "undefined") {
817
- return window;
818
- }
819
- return {};
765
+ /** @internal */
766
+ const MODULE_CONFIG_DATA = new InjectionToken("@ssv/ngx.ux/configData");
767
+ const components = [
768
+ SsvViewportMatcherDirective,
769
+ SsvViewportMatcherVarDirective,
770
+ ViewportDataPipe,
771
+ ];
772
+ // todo: create module for Viewport
773
+ class SsvUxModule {
774
+ static forRoot(config) {
775
+ return {
776
+ ngModule: SsvUxModule,
777
+ providers: [
778
+ { provide: MODULE_CONFIG_DATA, useValue: config },
779
+ ],
780
+ };
781
+ }
782
+ }
783
+ SsvUxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
784
+ SsvUxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, declarations: [SsvViewportMatcherDirective,
785
+ SsvViewportMatcherVarDirective,
786
+ ViewportDataPipe], exports: [SsvViewportMatcherDirective,
787
+ SsvViewportMatcherVarDirective,
788
+ ViewportDataPipe] });
789
+ SsvUxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, providers: [
790
+ { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
791
+ { provide: WINDOW, useFactory: _window },
792
+ ] });
793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SsvUxModule, decorators: [{
794
+ type: NgModule,
795
+ args: [{
796
+ declarations: [components],
797
+ providers: [
798
+ { provide: UX_CONFIG, useFactory: _moduleConfigFactory, deps: [[MODULE_CONFIG_DATA, new Optional()]] },
799
+ { provide: WINDOW, useFactory: _window },
800
+ ],
801
+ exports: [...components],
802
+ }]
803
+ }] });
804
+ /** @internal */
805
+ function _moduleConfigFactory(config) {
806
+ if (!config) {
807
+ return UX_DEFAULT_CONFIG;
808
+ }
809
+ const uxOptions = typeof config === "function" ? config() : config;
810
+ const viewport = Object.assign(Object.assign({}, UX_DEFAULT_CONFIG.viewport), uxOptions.viewport); // breakpoints shouldn't be merged
811
+ return { viewport };
812
+ }
813
+ /** @internal */
814
+ function _window() {
815
+ if (typeof window !== "undefined") {
816
+ return window;
817
+ }
818
+ return {};
820
819
  }
821
820
 
822
821
  const VERSION = "0.0.0-PLACEHOLDER";
823
822
 
824
- /**
825
- * Generated bundle index. Do not edit.
823
+ /**
824
+ * Generated bundle index. Do not edit.
826
825
  */
827
826
 
828
827
  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 };