Skip to content

Commit 6a3c36c

Browse files
simeonoffkdinev
andauthored
refactor(themes): change how the dependency tree is built and checked (#12709)
* refactor(themes): change how the dependency tree is built and checked This PR adds support for registering theme dependencies by extension. --------- Co-authored-by: Konstantin Dinev <[email protected]>
1 parent 748a398 commit 6a3c36c

File tree

4 files changed

+102
-24
lines changed

4 files changed

+102
-24
lines changed

projects/igniteui-angular/src/lib/core/styles/base/_functions.scss

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,31 @@
33
@use 'sass:list';
44
@use 'sass:string';
55

6+
/// Get the difference between two lists.
7+
/// @access private
8+
/// @param {List} $list1 - The source list.
9+
/// @param {List} $list2 - The list to check against the source list.
10+
/// @return {List} - A list containing the diff items.
11+
@function list-diff($list1, $list2) {
12+
$result: ();
13+
14+
@each $item in $list1 {
15+
@if not list.index($list2, $item) {
16+
$result: list.append($result, $item, comma);
17+
}
18+
}
19+
20+
@return $result;
21+
}
22+
623
/// @group Utilities
724
/// @author <a href="https://github.com/simeonoff" target="_blank">Simeon Simeonoff</a>
825
/// @access private
9-
@function is-used($name, $checklist) {
26+
@function is-used($component, $checklist) {
1027
$used: true;
1128

12-
@if list.index($checklist, $name) {
13-
$deps: map.get($components, $name, 'usedBy');
29+
@if list.index($checklist, $component) {
30+
$deps: map.get($components, $component, 'usedBy');
1431
$excluded: ();
1532

1633
@each $item in $checklist {
@@ -22,9 +39,11 @@
2239
$used: list.length($deps) != list.length($excluded);
2340

2441
@if not($used) {
25-
$dropped-themes: list.append($dropped-themes, $name) !global;
42+
$dropped-themes: list.append($dropped-themes, $component) !global;
2643
} @else {
27-
@warn string.unquote('You\'ve opted to exclude the "#{$name}" theme but it was held back as the following themes depend on it: "#{$deps}".');
44+
$remaining: list-diff($deps, $excluded);
45+
46+
@warn string.unquote('You\'ve opted to exclude the "#{$component}" theme but it was held back as the following components depend on it: "#{$remaining}".');
2847
}
2948
}
3049

projects/igniteui-angular/src/lib/core/styles/base/_mixins.scss

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,65 @@
1515

1616
/// Registers a component to the list of known components.
1717
/// @access private
18-
/// @param {String} $name - The component name to register.
18+
/// @param {String} $name - The component name.
19+
/// @param {List} $deps - A list of all components the component depends on.
1920
@mixin register-component($name, $deps: ()) {
2021
$component: map.get($components, $name);
22+
$deps: if($component, map.get($component, 'deps'), $deps);
23+
$usedBy: if($component, map.get($component, 'usedBy'), ());
2124

22-
@if $component == null {
23-
$components: map.merge($components, (
24-
#{$name}: (
25-
usedBy: ()
26-
),
27-
)) !global;
28-
}
25+
$components: map.merge($components, (
26+
#{$name}: (
27+
deps: $deps,
28+
usedBy: $usedBy
29+
)
30+
)) !global;
31+
}
2932

33+
/// Adds dependecies to a component's internal usedBy list.
34+
/// @access private
35+
/// @param {String} $component - The component name.
36+
/// @param {List} $deps - The dependecies to be added to the component's usedBy list.
37+
@mixin add-deps($component, $deps) {
3038
@each $dep in $deps {
31-
@include register-component($dep);
39+
$c: map.get($components, $dep);
40+
$d: ();
41+
$u: ();
42+
43+
@if $c != null {
44+
$cu: map.get($c, 'usedBy');
3245

33-
@if map.has-key($components, $dep) {
34-
$component: map.get($components, $dep);
35-
$usedBy: map.get($component, 'usedBy');
46+
$d: map.get($c, 'deps');
3647

37-
$components: map.merge($components, (
38-
#{$dep}: map.merge($component, (
39-
usedBy: list.append($usedBy, $name, $separator: comma)
40-
))
41-
)) !global;
48+
@if not list.index($cu, $component) {
49+
$u: list.append($cu, $component, comma);
50+
} @else {
51+
$u: $cu;
52+
}
53+
} @else {
54+
$u: list.append($u, $component, comma);
4255
}
56+
57+
$components: map.merge($components, (
58+
#{$dep}: (
59+
deps: $d,
60+
usedBy: $u
61+
)
62+
)) !global;
63+
64+
@include add-deps($component, $d);
65+
}
66+
}
67+
68+
/// Modifies the global components register by updating the usedBy list for each component.
69+
/// @access private
70+
/// @param {Map} $components - A map of all registered components.
71+
@mixin dependecy-tree($components) {
72+
@each $c in $components {
73+
$component: list.nth($c, 1);
74+
$deps: map.get($components, $component, 'deps');
75+
76+
@include add-deps($component, $deps);
4377
}
4478
}
4579

projects/igniteui-angular/src/lib/core/styles/spec/_functions.spec.scss

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@use 'sass:map';
2+
@use 'sass:list';
13
@use 'node_modules/sass-true' as *;
24
@use '../base' as *;
35

@@ -11,10 +13,28 @@
1113
)
1214
) !global;
1315

16+
@include it('should register a component') {
17+
$result: (
18+
'deps': (igx-drop-down),
19+
'usedBy': ()
20+
);
21+
22+
@include register-component($name: igx-test, $deps: (igx-drop-down));
23+
@include assert-equal(map.get($components, igx-test), $result);
24+
}
25+
26+
@include it('should build a dependency tree and register dependencies by extension') {
27+
@include register-component($name: igx-drop-down, $deps: (igx-overlay));
28+
@include dependecy-tree($components);
29+
30+
$usedBy: map.get($components, igx-overlay, 'usedBy');
31+
@include assert-equal(list.index($usedBy, igx-test) != null, true);
32+
}
33+
1434
@include it('should include theme if other themes depend on it') {
1535
$excluded: (igx-checkbox, igx-combo);
1636
$test: is-used(
17-
$name: 'igx-checkbox',
37+
$component: 'igx-checkbox',
1838
$checklist: $excluded,
1939
);
2040
@include assert-equal($test, true);
@@ -23,7 +43,7 @@
2343
@include it('should exclude theme if no themes depend on it') {
2444
$excluded: (igx-checkbox, igx-grid, igx-combo);
2545
$test: is-used(
26-
$name: 'igx-checkbox',
46+
$component: 'igx-checkbox',
2747
$checklist: $excluded,
2848
);
2949

projects/igniteui-angular/src/lib/core/styles/themes/_core.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
/// @author <a href="https://github.com/simeonoff" target="_blank">Simeon Simeonoff</a>
44
////
55

6+
@use '../base';
7+
68
// Used to configure color accessibility for charts
79
@use 'igniteui-theming/sass/color/functions' as color;
810

@@ -169,6 +171,9 @@
169171
@include tree.component();
170172
@include watermark.component();
171173

174+
// Build the component dependecy-tree
175+
@include base.dependecy-tree(base.$components);
176+
172177
@if $print-layout == true {
173178
@include print.layout();
174179
}

0 commit comments

Comments
 (0)