igniteui-angular 22.1.4 → 22.2.0-rc.1

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 (145) hide show
  1. package/README.md +2 -2
  2. package/combo/README.md +19 -0
  3. package/drop-down/README.md +40 -4
  4. package/fesm2022/igniteui-angular-accordion.mjs +7 -7
  5. package/fesm2022/igniteui-angular-action-strip.mjs +10 -10
  6. package/fesm2022/igniteui-angular-avatar.mjs +7 -7
  7. package/fesm2022/igniteui-angular-badge.mjs +7 -7
  8. package/fesm2022/igniteui-angular-banner.mjs +10 -10
  9. package/fesm2022/igniteui-angular-bottom-nav.mjs +22 -22
  10. package/fesm2022/igniteui-angular-button-group.mjs +12 -13
  11. package/fesm2022/igniteui-angular-button-group.mjs.map +1 -1
  12. package/fesm2022/igniteui-angular-calendar.mjs +61 -61
  13. package/fesm2022/igniteui-angular-card.mjs +31 -31
  14. package/fesm2022/igniteui-angular-carousel.mjs +22 -22
  15. package/fesm2022/igniteui-angular-chat-extras.mjs +6 -6
  16. package/fesm2022/igniteui-angular-chat.mjs +12 -12
  17. package/fesm2022/igniteui-angular-checkbox.mjs +7 -7
  18. package/fesm2022/igniteui-angular-chips.mjs +10 -10
  19. package/fesm2022/igniteui-angular-combo.mjs +268 -124
  20. package/fesm2022/igniteui-angular-combo.mjs.map +1 -1
  21. package/fesm2022/igniteui-angular-core.mjs +207 -59
  22. package/fesm2022/igniteui-angular-core.mjs.map +1 -1
  23. package/fesm2022/igniteui-angular-date-picker.mjs +80 -106
  24. package/fesm2022/igniteui-angular-date-picker.mjs.map +1 -1
  25. package/fesm2022/igniteui-angular-dialog.mjs +13 -13
  26. package/fesm2022/igniteui-angular-directives.mjs +321 -457
  27. package/fesm2022/igniteui-angular-directives.mjs.map +1 -1
  28. package/fesm2022/igniteui-angular-drop-down.mjs +331 -104
  29. package/fesm2022/igniteui-angular-drop-down.mjs.map +1 -1
  30. package/fesm2022/igniteui-angular-expansion-panel.mjs +28 -28
  31. package/fesm2022/igniteui-angular-grids-core.mjs +552 -516
  32. package/fesm2022/igniteui-angular-grids-core.mjs.map +1 -1
  33. package/fesm2022/igniteui-angular-grids-grid.mjs +79 -80
  34. package/fesm2022/igniteui-angular-grids-grid.mjs.map +1 -1
  35. package/fesm2022/igniteui-angular-grids-hierarchical-grid.mjs +59 -46
  36. package/fesm2022/igniteui-angular-grids-hierarchical-grid.mjs.map +1 -1
  37. package/fesm2022/igniteui-angular-grids-lite.mjs +12 -12
  38. package/fesm2022/igniteui-angular-grids-pivot-grid.mjs +113 -86
  39. package/fesm2022/igniteui-angular-grids-pivot-grid.mjs.map +1 -1
  40. package/fesm2022/igniteui-angular-grids-tree-grid.mjs +57 -57
  41. package/fesm2022/igniteui-angular-grids-tree-grid.mjs.map +1 -1
  42. package/fesm2022/igniteui-angular-icon.mjs +10 -10
  43. package/fesm2022/igniteui-angular-input-group.mjs +73 -83
  44. package/fesm2022/igniteui-angular-input-group.mjs.map +1 -1
  45. package/fesm2022/igniteui-angular-list.mjs +40 -40
  46. package/fesm2022/igniteui-angular-navbar.mjs +13 -13
  47. package/fesm2022/igniteui-angular-navigation-drawer.mjs +16 -16
  48. package/fesm2022/igniteui-angular-paginator.mjs +19 -19
  49. package/fesm2022/igniteui-angular-progressbar.mjs +19 -19
  50. package/fesm2022/igniteui-angular-query-builder.mjs +23 -23
  51. package/fesm2022/igniteui-angular-query-builder.mjs.map +1 -1
  52. package/fesm2022/igniteui-angular-radio.mjs +59 -35
  53. package/fesm2022/igniteui-angular-radio.mjs.map +1 -1
  54. package/fesm2022/igniteui-angular-select.mjs +36 -48
  55. package/fesm2022/igniteui-angular-select.mjs.map +1 -1
  56. package/fesm2022/igniteui-angular-simple-combo.mjs +44 -33
  57. package/fesm2022/igniteui-angular-simple-combo.mjs.map +1 -1
  58. package/fesm2022/igniteui-angular-slider.mjs +28 -28
  59. package/fesm2022/igniteui-angular-snackbar.mjs +7 -7
  60. package/fesm2022/igniteui-angular-splitter.mjs +13 -13
  61. package/fesm2022/igniteui-angular-stepper.mjs +34 -34
  62. package/fesm2022/igniteui-angular-switch.mjs +7 -7
  63. package/fesm2022/igniteui-angular-tabs.mjs +34 -34
  64. package/fesm2022/igniteui-angular-time-picker.mjs +32 -51
  65. package/fesm2022/igniteui-angular-time-picker.mjs.map +1 -1
  66. package/fesm2022/igniteui-angular-toast.mjs +7 -7
  67. package/fesm2022/igniteui-angular-tree.mjs +28 -28
  68. package/fesm2022/igniteui-angular-virtual-scroll.mjs +1257 -0
  69. package/fesm2022/igniteui-angular-virtual-scroll.mjs.map +1 -0
  70. package/fesm2022/igniteui-angular.mjs +1 -0
  71. package/fesm2022/igniteui-angular.mjs.map +1 -1
  72. package/input-group/README.md +2 -0
  73. package/lib/core/styles/components/scrollbar/scrollbar-component.scss +0 -2
  74. package/lib/core/styles/components/scrollbar/scrollbar-theme.scss +23 -51
  75. package/lib/grids/core/src/column-actions/themes/_derived.scss +3 -3
  76. package/lib/grids/core/src/filtering/excel-style/themes/_derived.scss +3 -3
  77. package/lib/grids/themes/_derived.scss +3 -3
  78. package/lib/query-builder/src/query-builder/themes/_derived.scss +3 -3
  79. package/migrations/common/UpdateChanges.d.ts +36 -0
  80. package/migrations/common/UpdateChanges.js +175 -31
  81. package/migrations/common/UpdateChanges.spec.js +66 -0
  82. package/migrations/migration-collection.json +10 -0
  83. package/migrations/update-22_2_0/changes/theme-changes.json +77 -0
  84. package/migrations/update-22_2_0/index.d.ts +3 -0
  85. package/migrations/update-22_2_0/index.js +18 -0
  86. package/migrations/update-22_2_0/index.spec.d.ts +1 -0
  87. package/migrations/update-22_2_0/index.spec.js +161 -0
  88. package/migrations/update-22_2_0_grid-summary-borders/changes/theme-changes.json +17 -0
  89. package/migrations/update-22_2_0_grid-summary-borders/index.d.ts +3 -0
  90. package/migrations/update-22_2_0_grid-summary-borders/index.js +64 -0
  91. package/migrations/update-22_2_0_grid-summary-borders/index.spec.d.ts +1 -0
  92. package/migrations/update-22_2_0_grid-summary-borders/index.spec.js +100 -0
  93. package/package.json +6 -2
  94. package/schematics/tsconfig.tsbuildinfo +1 -1
  95. package/simple-combo/README.md +3 -0
  96. package/skills/igniteui-angular-components/references/form-controls.md +58 -0
  97. package/styles/igniteui-angular-dark.css +1 -1
  98. package/styles/igniteui-angular.css +1 -1
  99. package/styles/igniteui-bootstrap-dark.css +1 -1
  100. package/styles/igniteui-bootstrap-light.css +1 -1
  101. package/styles/igniteui-dark-green.css +1 -1
  102. package/styles/igniteui-fluent-dark-excel.css +1 -1
  103. package/styles/igniteui-fluent-dark-word.css +1 -1
  104. package/styles/igniteui-fluent-dark.css +1 -1
  105. package/styles/igniteui-fluent-light-excel.css +1 -1
  106. package/styles/igniteui-fluent-light-word.css +1 -1
  107. package/styles/igniteui-fluent-light.css +1 -1
  108. package/styles/igniteui-indigo-dark.css +1 -1
  109. package/styles/igniteui-indigo-light.css +1 -1
  110. package/styles/maps/igniteui-angular-dark.css.map +1 -1
  111. package/styles/maps/igniteui-angular.css.map +1 -1
  112. package/styles/maps/igniteui-bootstrap-dark.css.map +1 -1
  113. package/styles/maps/igniteui-bootstrap-light.css.map +1 -1
  114. package/styles/maps/igniteui-dark-green.css.map +1 -1
  115. package/styles/maps/igniteui-fluent-dark-excel.css.map +1 -1
  116. package/styles/maps/igniteui-fluent-dark-word.css.map +1 -1
  117. package/styles/maps/igniteui-fluent-dark.css.map +1 -1
  118. package/styles/maps/igniteui-fluent-light-excel.css.map +1 -1
  119. package/styles/maps/igniteui-fluent-light-word.css.map +1 -1
  120. package/styles/maps/igniteui-fluent-light.css.map +1 -1
  121. package/styles/maps/igniteui-indigo-dark.css.map +1 -1
  122. package/styles/maps/igniteui-indigo-light.css.map +1 -1
  123. package/types/igniteui-angular-calendar.d.ts +1 -1
  124. package/types/igniteui-angular-combo.d.ts +55 -12
  125. package/types/igniteui-angular-core.d.ts +73 -11
  126. package/types/igniteui-angular-date-picker.d.ts +3 -4
  127. package/types/igniteui-angular-directives.d.ts +50 -164
  128. package/types/igniteui-angular-drop-down.d.ts +76 -4
  129. package/types/igniteui-angular-grids-core.d.ts +63 -28
  130. package/types/igniteui-angular-grids-grid.d.ts +2 -7
  131. package/types/igniteui-angular-grids-hierarchical-grid.d.ts +5 -4
  132. package/types/igniteui-angular-grids-pivot-grid.d.ts +11 -5
  133. package/types/igniteui-angular-grids-tree-grid.d.ts +1 -1
  134. package/types/igniteui-angular-icon.d.ts +1 -1
  135. package/types/igniteui-angular-input-group.d.ts +18 -5
  136. package/types/igniteui-angular-query-builder.d.ts +1 -1
  137. package/types/igniteui-angular-radio.d.ts +16 -1
  138. package/types/igniteui-angular-select.d.ts +1 -2
  139. package/types/igniteui-angular-simple-combo.d.ts +7 -0
  140. package/types/igniteui-angular-stepper.d.ts +1 -1
  141. package/types/igniteui-angular-time-picker.d.ts +1 -3
  142. package/types/igniteui-angular-tree.d.ts +3 -3
  143. package/types/igniteui-angular-virtual-scroll.d.ts +408 -0
  144. package/types/igniteui-angular.d.ts +1 -0
  145. package/virtual-scroll/README.md +332 -0
@@ -47,6 +47,7 @@ const tsUtils_1 = require("./tsUtils");
47
47
  const util_1 = require("./util");
48
48
  const project_service_container_1 = require("./project-service-container");
49
49
  const TSCONFIG_PATH = 'tsconfig.json';
50
+ const URL_TOKEN = 'url(';
50
51
  var InputPropertyType;
51
52
  (function (InputPropertyType) {
52
53
  InputPropertyType["EVAL"] = "eval";
@@ -361,52 +362,187 @@ class UpdateChanges {
361
362
  }
362
363
  }
363
364
  updateThemeProps(entryPath) {
364
- var _a;
365
365
  let fileContent = this.host.read(entryPath).toString();
366
366
  let overwrite = false;
367
367
  for (const change of this.themeChanges.changes) {
368
368
  if (change.type !== schema_1.ThemeType.Property) {
369
369
  continue;
370
370
  }
371
- if (fileContent.indexOf(change.owner) !== -1) {
372
- /** owner-func:( * ); */
373
- const searchPattern = String.raw `${change.owner}\([\s\S]+?\);`;
374
- const matches = fileContent.match(new RegExp(searchPattern, 'g'));
375
- if (!matches) {
371
+ if (fileContent.indexOf(change.owner) === -1) {
372
+ continue;
373
+ }
374
+ /** owner-func:( * ) */
375
+ const calls = this.findFunctionCalls(fileContent, change.owner);
376
+ // rewrite back to front so the collected indices stay valid
377
+ for (const call of calls.reverse()) {
378
+ const rawBody = fileContent.substring(call.bodyStart, call.bodyEnd);
379
+ if (rawBody.indexOf(change.name) === -1) {
376
380
  continue;
377
381
  }
378
- for (const match of matches) {
379
- if (match.indexOf(change.name) !== -1) {
380
- const name = change.name.replace('$', '\\$');
381
- const replaceWith = (_a = change.replaceWith) === null || _a === void 0 ? void 0 : _a.replace('$', '\\$');
382
- const reg = new RegExp(String.raw `^\s*${name}:`);
383
- const existing = new RegExp(String.raw `${replaceWith}:`);
384
- const opening = `${change.owner}(`;
385
- const closing = /\s*\);$/.exec(match).pop();
386
- const body = match.substr(opening.length, match.length - opening.length - closing.length);
387
- let params = this.splitFunctionProps(body);
388
- params = params.reduce((arr, param) => {
389
- if (reg.test(param)) {
390
- const duplicate = !!replaceWith && arr.some(p => existing.test(p));
391
- if (!change.remove && !duplicate) {
392
- arr.push(param.replace(change.name, change.replaceWith));
393
- }
394
- }
395
- else {
396
- arr.push(param);
397
- }
398
- return arr;
399
- }, []);
400
- fileContent = fileContent.replace(match, opening + params.join(',') + closing);
401
- overwrite = true;
382
+ const name = (0, util_1.escapeRegExp)(change.name);
383
+ const replaceWith = change.replaceWith ? (0, util_1.escapeRegExp)(change.replaceWith) : undefined;
384
+ const reg = new RegExp(String.raw `^\s*${name}:`);
385
+ const existing = new RegExp(String.raw `${replaceWith}:`);
386
+ // keep whatever sits in front of the closing bracket so the formatting is preserved
387
+ const trailing = /\s*$/.exec(rawBody).pop();
388
+ const body = rawBody.substring(0, rawBody.length - trailing.length);
389
+ let params = this.splitFunctionProps(body);
390
+ params = params.reduce((arr, param) => {
391
+ if (reg.test(param)) {
392
+ const duplicate = !!replaceWith && arr.some(p => existing.test(p));
393
+ if (!change.remove && !duplicate) {
394
+ arr.push(param.replace(change.name, change.replaceWith));
395
+ }
402
396
  }
403
- }
397
+ else {
398
+ arr.push(param);
399
+ }
400
+ return arr;
401
+ }, []);
402
+ fileContent = fileContent.substring(0, call.bodyStart)
403
+ + params.join(',')
404
+ + trailing
405
+ + fileContent.substring(call.bodyEnd);
406
+ overwrite = true;
404
407
  }
405
408
  }
406
409
  if (overwrite) {
407
410
  this.host.overwrite(entryPath, fileContent);
408
411
  }
409
412
  }
413
+ /**
414
+ * Returns the argument list boundaries of every top-level `owner(...)` call in the content.
415
+ * Strings, comments and `url()` tokens are scanned over, so an `owner(` that is only mentioned
416
+ * in one of those is not taken for a call, and a `@mixin` or `@function` that declares the same
417
+ * name is left alone. The brackets are tracked too, so a call nested in another one -
418
+ * `@include scrollbar(scrollbar-theme($sb-size: 6px))` - reports its own closing bracket
419
+ * rather than the one of the call surrounding it.
420
+ */
421
+ findFunctionCalls(content, owner) {
422
+ const calls = [];
423
+ const opening = `${owner}(`;
424
+ for (let i = 0; i < content.length; i++) {
425
+ const nonCodeEnd = this.skipNonCode(content, i);
426
+ if (nonCodeEnd !== -1) {
427
+ i = nonCodeEnd;
428
+ continue;
429
+ }
430
+ if (!content.startsWith(opening, i) || this.isDeclaredName(content, i)) {
431
+ continue;
432
+ }
433
+ const bodyStart = i + opening.length;
434
+ const bodyEnd = this.findClosingBracket(content, bodyStart);
435
+ if (bodyEnd === -1) {
436
+ // unbalanced from here on, leave this call rather than the rest of the file
437
+ continue;
438
+ }
439
+ calls.push({ bodyStart, bodyEnd });
440
+ // a same-owner call nested in this one is already covered by it
441
+ i = bodyEnd;
442
+ }
443
+ return calls;
444
+ }
445
+ /**
446
+ * Returns the index of the bracket closing the one `start` is inside of, or -1 when the
447
+ * content is unbalanced. Brackets in strings, comments and `url()` tokens are ignored.
448
+ */
449
+ findClosingBracket(content, start) {
450
+ let level = 0;
451
+ for (let i = start; i < content.length; i++) {
452
+ const nonCodeEnd = this.skipNonCode(content, i);
453
+ if (nonCodeEnd !== -1) {
454
+ i = nonCodeEnd;
455
+ continue;
456
+ }
457
+ const char = content[i];
458
+ if (char === '(') {
459
+ level++;
460
+ }
461
+ else if (char === ')') {
462
+ if (!level) {
463
+ return i;
464
+ }
465
+ level--;
466
+ }
467
+ }
468
+ return -1;
469
+ }
470
+ /**
471
+ * Tells whether the name at `index` is the one a `@mixin` or a `@function` declares rather
472
+ * than a call to it. Rewriting a declaration would strip a parameter its body still reads.
473
+ */
474
+ isDeclaredName(content, index) {
475
+ let end = index;
476
+ while (end > 0 && /\s/.test(content[end - 1])) {
477
+ end--;
478
+ }
479
+ let start = end;
480
+ while (start > 0 && /[\w@-]/.test(content[start - 1])) {
481
+ start--;
482
+ }
483
+ const keyword = content.substring(start, end);
484
+ return keyword === '@mixin' || keyword === '@function';
485
+ }
486
+ /**
487
+ * When a string, a comment or a `url()` token starts at `index`, returns the index of its last
488
+ * character so that a scan can carry on past it. Returns -1 when `index` is on code.
489
+ */
490
+ skipNonCode(content, index) {
491
+ const char = content[index];
492
+ const next = content[index + 1];
493
+ if (char === '\'' || char === '"') {
494
+ return this.skipString(content, index);
495
+ }
496
+ if (char === '/' && next === '*') {
497
+ const end = content.indexOf('*/', index + 2);
498
+ return end === -1 ? content.length : end + 1;
499
+ }
500
+ if (char === '/' && next === '/') {
501
+ const end = content.indexOf('\n', index + 2);
502
+ return end === -1 ? content.length : end;
503
+ }
504
+ if (this.isUrlToken(content, index)) {
505
+ return this.skipUrl(content, index + URL_TOKEN.length);
506
+ }
507
+ return -1;
508
+ }
509
+ /**
510
+ * Sass parses an unquoted `url()` as a single token, so a `//` inside one is part of the
511
+ * address - `url(//cdn.example.com/bg.png)` - and not the start of a comment.
512
+ */
513
+ isUrlToken(content, index) {
514
+ if (content.substr(index, URL_TOKEN.length).toLowerCase() !== URL_TOKEN) {
515
+ return false;
516
+ }
517
+ const previous = content[index - 1];
518
+ return previous === undefined || !/[\w-]/.test(previous);
519
+ }
520
+ /** Returns the index of the bracket closing a `url(` whose contents start at `start`. */
521
+ skipUrl(content, start) {
522
+ for (let i = start; i < content.length; i++) {
523
+ const char = content[i];
524
+ if (char === '\'' || char === '"') {
525
+ i = this.skipString(content, i);
526
+ }
527
+ else if (char === ')') {
528
+ return i;
529
+ }
530
+ }
531
+ return content.length;
532
+ }
533
+ /** Returns the index of the quote closing the string opened at `start`. */
534
+ skipString(content, start) {
535
+ const quote = content[start];
536
+ for (let i = start + 1; i < content.length; i++) {
537
+ if (content[i] === '\\') {
538
+ i++;
539
+ }
540
+ else if (content[i] === quote) {
541
+ return i;
542
+ }
543
+ }
544
+ return content.length;
545
+ }
410
546
  isNamedArgument(fileContent, i, occurrences, change) {
411
547
  const openingBrackets = [];
412
548
  const closingBrackets = [];
@@ -777,12 +913,20 @@ class UpdateChanges {
777
913
  * prop: inner-func(),
778
914
  * prop2: inner2(inner-param: 3, inner-param: inner-func(..))
779
915
  * ```
916
+ *
917
+ * Strings, comments and `url()` tokens are scanned over the same way the rest of the scanner
918
+ * does it, so a `','` inside one of them is not taken for an argument separator.
780
919
  */
781
920
  splitFunctionProps(body) {
782
921
  const parts = [];
783
922
  let lastIndex = 0;
784
923
  let level = 0;
785
924
  for (let i = 0; i < body.length; i++) {
925
+ const nonCodeEnd = this.skipNonCode(body, i);
926
+ if (nonCodeEnd !== -1) {
927
+ i = nonCodeEnd;
928
+ continue;
929
+ }
786
930
  const char = body[i];
787
931
  switch (char) {
788
932
  case '(':
@@ -567,6 +567,72 @@ $var3: igx-comp-theme(
567
567
  expect(appTree.readContent('test.component.scss')).toEqual(`igx-theme-func($replaced: 10px, $old-prop: 3, $prop3: 2);`);
568
568
  done();
569
569
  });
570
+ it('should keep the brackets balanced for nested theme functions', done => {
571
+ const themeChangesJson = {
572
+ changes: [
573
+ {
574
+ name: '$remove-me', remove: true,
575
+ owner: 'igx-theme-func',
576
+ type: schema_1.ThemeType.Property
577
+ },
578
+ {
579
+ name: '$replace-me', replaceWith: '$replaced',
580
+ owner: 'igx-theme-func',
581
+ type: schema_1.ThemeType.Property
582
+ }
583
+ ]
584
+ };
585
+ const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
586
+ spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
587
+ spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
588
+ appTree.create('styles.scss', `@include igx-mixin(igx-theme-func($remove-me: 6px));
589
+ @include igx-mixin(igx-theme-func($prop1: red, $remove-me: 6px));
590
+ @include igx-mixin(igx-theme-func($remove-me: 6px, $prop1: red));
591
+ @include igx-mixin(igx-theme-func($replace-me: 6px));
592
+ $var: igx-theme-func($content: "not a ( bracket", $remove-me: 6px);
593
+ $var2: igx-theme-func($image: url(https://example.com/a.png), $remove-me: 6px);
594
+ $var3: igx-theme-func(
595
+ $remove-me: 6px, // not a ) bracket
596
+ $prop1: red
597
+ );`);
598
+ const update = new UnitUpdateChanges(__dirname, appTree);
599
+ update.applyChanges();
600
+ expect(appTree.readContent('styles.scss')).toEqual(`@include igx-mixin(igx-theme-func());
601
+ @include igx-mixin(igx-theme-func($prop1: red));
602
+ @include igx-mixin(igx-theme-func( $prop1: red));
603
+ @include igx-mixin(igx-theme-func($replaced: 6px));
604
+ $var: igx-theme-func($content: "not a ( bracket");
605
+ $var2: igx-theme-func($image: url(https://example.com/a.png));
606
+ $var3: igx-theme-func( // not a ) bracket
607
+ $prop1: red
608
+ );`);
609
+ done();
610
+ });
611
+ it('should not treat a theme function mentioned in a comment or a string as a call', done => {
612
+ const themeChangesJson = {
613
+ changes: [
614
+ {
615
+ name: '$remove-me', remove: true,
616
+ owner: 'igx-theme-func',
617
+ type: schema_1.ThemeType.Property
618
+ }
619
+ ]
620
+ };
621
+ const jsonPath = path.join(__dirname, 'changes', 'theme-changes.json');
622
+ spyOn(fs, 'existsSync').and.callFake((filePath) => filePath === jsonPath);
623
+ spyOn(fs, 'readFileSync').and.callFake(() => JSON.stringify(themeChangesJson));
624
+ appTree.create('styles.scss', `// igx-theme-func($remove-me: 1px) is gone, use the grid's own borders
625
+ /* igx-theme-func($remove-me: 2px */
626
+ $doc: "igx-theme-func($remove-me: 3px";
627
+ $var: igx-theme-func($remove-me: 4px, $prop1: red);`);
628
+ const update = new UnitUpdateChanges(__dirname, appTree);
629
+ update.applyChanges();
630
+ expect(appTree.readContent('styles.scss')).toEqual(`// igx-theme-func($remove-me: 1px) is gone, use the grid's own borders
631
+ /* igx-theme-func($remove-me: 2px */
632
+ $doc: "igx-theme-func($remove-me: 3px";
633
+ $var: igx-theme-func( $prop1: red);`);
634
+ done();
635
+ });
570
636
  it('should replace imports', done => {
571
637
  const importsJson = {
572
638
  changes: [
@@ -309,6 +309,16 @@
309
309
  "version": "22.1.0",
310
310
  "description": "Update Chip outline properties",
311
311
  "factory": "./update-22_1_0_chip-outline"
312
+ },
313
+ "migration-61": {
314
+ "version": "22.2.0",
315
+ "description": "Removes scrollbar-theme properties with no effect under the standard scrollbar properties",
316
+ "factory": "./update-22_2_0"
317
+ },
318
+ "migration-62": {
319
+ "version": "22.2.0",
320
+ "description": "Removes the grid-summary border width properties now driven by the grid's own borders",
321
+ "factory": "./update-22_2_0_grid-summary-borders"
312
322
  }
313
323
  }
314
324
  }
@@ -0,0 +1,77 @@
1
+ {
2
+ "$schema": "../../common/schema/theme-changes.schema.json",
3
+ "changes": [
4
+ {
5
+ "name": "$sb-size",
6
+ "remove": true,
7
+ "owner": "scrollbar-theme",
8
+ "type": "property"
9
+ },
10
+ {
11
+ "name": "$sb-thumb-min-height",
12
+ "remove": true,
13
+ "owner": "scrollbar-theme",
14
+ "type": "property"
15
+ },
16
+ {
17
+ "name": "$sb-thumb-bg-color-hover",
18
+ "remove": true,
19
+ "owner": "scrollbar-theme",
20
+ "type": "property"
21
+ },
22
+ {
23
+ "name": "$sb-thumb-border-color",
24
+ "remove": true,
25
+ "owner": "scrollbar-theme",
26
+ "type": "property"
27
+ },
28
+ {
29
+ "name": "$sb-thumb-border-size",
30
+ "remove": true,
31
+ "owner": "scrollbar-theme",
32
+ "type": "property"
33
+ },
34
+ {
35
+ "name": "$sb-thumb-border-radius",
36
+ "remove": true,
37
+ "owner": "scrollbar-theme",
38
+ "type": "property"
39
+ },
40
+ {
41
+ "name": "$sb-track-bg-color-hover",
42
+ "remove": true,
43
+ "owner": "scrollbar-theme",
44
+ "type": "property"
45
+ },
46
+ {
47
+ "name": "$sb-track-border-color",
48
+ "remove": true,
49
+ "owner": "scrollbar-theme",
50
+ "type": "property"
51
+ },
52
+ {
53
+ "name": "$sb-track-border-size",
54
+ "remove": true,
55
+ "owner": "scrollbar-theme",
56
+ "type": "property"
57
+ },
58
+ {
59
+ "name": "$sb-corner-bg",
60
+ "remove": true,
61
+ "owner": "scrollbar-theme",
62
+ "type": "property"
63
+ },
64
+ {
65
+ "name": "$sb-corner-border-color",
66
+ "remove": true,
67
+ "owner": "scrollbar-theme",
68
+ "type": "property"
69
+ },
70
+ {
71
+ "name": "$sb-corner-border-size",
72
+ "remove": true,
73
+ "owner": "scrollbar-theme",
74
+ "type": "property"
75
+ }
76
+ ]
77
+ }
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '@angular-devkit/schematics';
2
+ declare const _default: () => Rule;
3
+ export default _default;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const UpdateChanges_1 = require("../common/UpdateChanges");
13
+ const version = '22.2.0';
14
+ exports.default = () => (host, context) => __awaiter(void 0, void 0, void 0, function* () {
15
+ context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`);
16
+ const update = new UpdateChanges_1.UpdateChanges(__dirname, host, context);
17
+ update.applyChanges();
18
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ const path = __importStar(require("path"));
46
+ const index_js_1 = require("@angular-devkit/schematics/testing/index.js");
47
+ const setup_spec_1 = require("../common/setup.spec");
48
+ const version = '22.2.0';
49
+ describe(`Update to ${version}`, () => {
50
+ let appTree;
51
+ const schematicRunner = new index_js_1.SchematicTestRunner('ig-migrate', path.join(__dirname, '../migration-collection.json'));
52
+ beforeEach(() => {
53
+ appTree = (0, setup_spec_1.setupTestTree)();
54
+ });
55
+ const migrationName = 'migration-61';
56
+ it('should remove scrollbar-theme properties that no longer have effect', () => __awaiter(void 0, void 0, void 0, function* () {
57
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `$my-scrollbar: scrollbar-theme(
58
+ $sb-size: 16px,
59
+ $sb-thumb-bg-color: blue,
60
+ $sb-thumb-bg-color-hover: navy,
61
+ $sb-thumb-border-radius: 4px,
62
+ $sb-track-bg-color: black,
63
+ $sb-corner-bg: gray
64
+ );`);
65
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
66
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`$my-scrollbar: scrollbar-theme(
67
+ $sb-thumb-bg-color: blue,
68
+ $sb-track-bg-color: black
69
+ );`);
70
+ }));
71
+ it('should leave the supported scrollbar-theme properties untouched', () => __awaiter(void 0, void 0, void 0, function* () {
72
+ const content = `$my-scrollbar: scrollbar-theme(
73
+ $sb-thumb-bg-color: blue,
74
+ $sb-track-bg-color: black
75
+ );`;
76
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, content);
77
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
78
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(content);
79
+ }));
80
+ it('should keep the brackets balanced when the theme is nested in another call', () => __awaiter(void 0, void 0, void 0, function* () {
81
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `.selection-area {
82
+ @include scrollbar(scrollbar-theme($sb-size: 6px));
83
+ }
84
+
85
+ igx-grid {
86
+ @include scrollbar(scrollbar-theme($sb-thumb-bg-color: blue, $sb-size: 16px));
87
+ }`);
88
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
89
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`.selection-area {
90
+ @include scrollbar(scrollbar-theme());
91
+ }
92
+
93
+ igx-grid {
94
+ @include scrollbar(scrollbar-theme($sb-thumb-bg-color: blue));
95
+ }`);
96
+ }));
97
+ it('should migrate a theme call that is not terminated by a semicolon', () => __awaiter(void 0, void 0, void 0, function* () {
98
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `$my-scrollbar: scrollbar-theme(
99
+ $sb-size: 16px,
100
+ $sb-thumb-bg-color: blue
101
+ )`);
102
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
103
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`$my-scrollbar: scrollbar-theme(
104
+ $sb-thumb-bg-color: blue
105
+ )`);
106
+ }));
107
+ it('should keep a retained property when a comment in the argument list holds an apostrophe', () => __awaiter(void 0, void 0, void 0, function* () {
108
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `$my-scrollbar: scrollbar-theme($sb-size: 6px /* user's size */, $sb-thumb-bg-color: red);`);
109
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
110
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`$my-scrollbar: scrollbar-theme( $sb-thumb-bg-color: red);`);
111
+ }));
112
+ it('should remove the properties that follow a comment holding an apostrophe', () => __awaiter(void 0, void 0, void 0, function* () {
113
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `$my-scrollbar: scrollbar-theme(
114
+ $sb-size: 16px, // don't need this anymore
115
+ $sb-thumb-bg-color: blue,
116
+ $sb-corner-bg: gray
117
+ );`);
118
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
119
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`$my-scrollbar: scrollbar-theme( // don't need this anymore
120
+ $sb-thumb-bg-color: blue
121
+ );`);
122
+ }));
123
+ it('should migrate a theme below a comment glued to a closing brace', () => __awaiter(void 0, void 0, void 0, function* () {
124
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `.selection-area {
125
+ color: red;
126
+ }// don't set $sb-size here
127
+
128
+ $my-scrollbar: scrollbar-theme($sb-size: 16px, $sb-thumb-bg-color: blue);`);
129
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
130
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`.selection-area {
131
+ color: red;
132
+ }// don't set $sb-size here
133
+
134
+ $my-scrollbar: scrollbar-theme( $sb-thumb-bg-color: blue);`);
135
+ }));
136
+ it('should migrate a theme preceded on the same line by a protocol-relative url()', () => __awaiter(void 0, void 0, void 0, function* () {
137
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, `.a { background: url(//cdn.example.com/bg.png); $my: scrollbar-theme($sb-size: 16px, $sb-thumb-bg-color: red); }`);
138
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
139
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(`.a { background: url(//cdn.example.com/bg.png); $my: scrollbar-theme( $sb-thumb-bg-color: red); }`);
140
+ }));
141
+ it('should not rewrite a mixin or a function declared with the theme name', () => __awaiter(void 0, void 0, void 0, function* () {
142
+ const content = `@mixin scrollbar-theme($sb-size: 16px) {
143
+ width: $sb-size;
144
+ }
145
+
146
+ @function scrollbar-theme($sb-size: 6px) {
147
+ @return ($size: $sb-size);
148
+ }`;
149
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, content);
150
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
151
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(content);
152
+ }));
153
+ it('should not touch same-named properties on other themes', () => __awaiter(void 0, void 0, void 0, function* () {
154
+ const content = `$my-grid: grid-theme(
155
+ $sb-size: 16px
156
+ );`;
157
+ appTree.create(`/testSrc/appPrefix/component/test.component.scss`, content);
158
+ const tree = yield schematicRunner.runSchematic(migrationName, { shouldInvokeLS: false }, appTree);
159
+ expect(tree.readContent('/testSrc/appPrefix/component/test.component.scss')).toEqual(content);
160
+ }));
161
+ });
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "../../common/schema/theme-changes.schema.json",
3
+ "changes": [
4
+ {
5
+ "name": "$border-width",
6
+ "remove": true,
7
+ "owner": "grid-summary-theme",
8
+ "type": "property"
9
+ },
10
+ {
11
+ "name": "$pinned-border-width",
12
+ "remove": true,
13
+ "owner": "grid-summary-theme",
14
+ "type": "property"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '@angular-devkit/schematics';
2
+ declare const _default: () => Rule;
3
+ export default _default;