|
2 | 2 | import { categories } from './scripts/rules.js';
|
3 | 3 |
|
4 | 4 | export let rules = {};
|
| 5 | + let categoryState = Object.fromEntries( |
| 6 | + categories.map((c) => { |
| 7 | + return [ |
| 8 | + c.title, |
| 9 | + { |
| 10 | + close: true |
| 11 | + } |
| 12 | + ]; |
| 13 | + }) |
| 14 | + ); |
5 | 15 | function onAllClick(category, e) {
|
6 | 16 | const newRules = Object.assign({}, rules);
|
7 | 17 | for (const rule of category.rules) {
|
|
30 | 40 | <div class="rules-settings">
|
31 | 41 | <ul class="categories">
|
32 | 42 | {#each categories as category (category.title)}
|
33 |
| - <li class="category"> |
34 |
| - <div class="category-title-wrapper"> |
35 |
| - <label class="category-title"> |
36 |
| - <input |
37 |
| - type="checkbox" |
38 |
| - checked={category.rules.every((rule) => isErrorState(rules, rule.ruleId))} |
39 |
| - indeterminate={!category.rules.every((rule) => isErrorState(rules, rule.ruleId)) && |
40 |
| - !category.rules.every((rule) => !isErrorState(rules, rule.ruleId))} |
41 |
| - on:input={(e) => onAllClick(category, e)} |
42 |
| - /> |
43 |
| - {category.title} |
44 |
| - </label> |
45 |
| - </div> |
| 43 | + {#if category.rules.length} |
| 44 | + <li class="category"> |
| 45 | + <button |
| 46 | + class="category-button" |
| 47 | + class:category-button--close={categoryState[category.title].close} |
| 48 | + on:click={() => { |
| 49 | + categoryState = Object.fromEntries( |
| 50 | + categories.map((c) => { |
| 51 | + const close = categoryState[c.title].close; |
| 52 | + return [ |
| 53 | + c.title, |
| 54 | + { |
| 55 | + close: category.title === c.title ? !close : close |
| 56 | + } |
| 57 | + ]; |
| 58 | + }) |
| 59 | + ); |
| 60 | + }} |
| 61 | + > |
| 62 | + <svg xmlns="http://www.w3.org/2000/svg" height="10" viewBox="0 0 10 10" width="10"> |
| 63 | + <path d="M2.5 10l5-5-5-5v10z" fill="#ddd" /> |
| 64 | + </svg> |
| 65 | + </button> |
| 66 | + <div class="category-title-wrapper"> |
| 67 | + <label class="category-title"> |
| 68 | + <input |
| 69 | + type="checkbox" |
| 70 | + checked={category.rules.every((rule) => isErrorState(rules, rule.ruleId))} |
| 71 | + indeterminate={!category.rules.every((rule) => isErrorState(rules, rule.ruleId)) && |
| 72 | + !category.rules.every((rule) => !isErrorState(rules, rule.ruleId))} |
| 73 | + on:input={(e) => onAllClick(category, e)} |
| 74 | + /> |
| 75 | + {category.title} |
| 76 | + </label> |
| 77 | + </div> |
46 | 78 |
|
47 |
| - <ul class="rules"> |
48 |
| - {#each category.rules as rule (rule.ruleId)} |
49 |
| - <li class="rule"> |
50 |
| - <label> |
51 |
| - <input |
52 |
| - type="checkbox" |
53 |
| - checked={isErrorState(rules, rule.ruleId)} |
54 |
| - on:input={(e) => onClick(rule.ruleId, e)} |
55 |
| - /> |
56 |
| - {rule.ruleId} |
57 |
| - </label> |
58 |
| - <a href={rule.url} target="_blank" |
59 |
| - ><svg |
60 |
| - xmlns="http://www.w3.org/2000/svg" |
61 |
| - aria-hidden="true" |
62 |
| - x="0px" |
63 |
| - y="0px" |
64 |
| - viewBox="0 0 100 100" |
65 |
| - width="15" |
66 |
| - height="15" |
67 |
| - class="icon outbound" |
68 |
| - > |
69 |
| - <path |
70 |
| - fill="currentColor" |
71 |
| - d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z" |
72 |
| - /> |
73 |
| - <polygon |
74 |
| - fill="currentColor" |
75 |
| - points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9" |
76 |
| - /></svg |
77 |
| - ></a |
78 |
| - > |
79 |
| - </li> |
80 |
| - {/each} |
81 |
| - </ul> |
82 |
| - </li> |
| 79 | + {#if !categoryState[category.title].close} |
| 80 | + <ul class="rules"> |
| 81 | + {#each category.rules as rule (rule.ruleId)} |
| 82 | + <li class="rule"> |
| 83 | + <label> |
| 84 | + <input |
| 85 | + type="checkbox" |
| 86 | + checked={isErrorState(rules, rule.ruleId)} |
| 87 | + on:input={(e) => onClick(rule.ruleId, e)} |
| 88 | + /> |
| 89 | + {rule.ruleId} |
| 90 | + </label> |
| 91 | + <a href={rule.url} target="_blank" |
| 92 | + ><svg |
| 93 | + xmlns="http://www.w3.org/2000/svg" |
| 94 | + aria-hidden="true" |
| 95 | + x="0px" |
| 96 | + y="0px" |
| 97 | + viewBox="0 0 100 100" |
| 98 | + width="15" |
| 99 | + height="15" |
| 100 | + class="icon outbound" |
| 101 | + > |
| 102 | + <path |
| 103 | + fill="currentColor" |
| 104 | + d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z" |
| 105 | + /> |
| 106 | + <polygon |
| 107 | + fill="currentColor" |
| 108 | + points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9" |
| 109 | + /></svg |
| 110 | + ></a |
| 111 | + > |
| 112 | + </li> |
| 113 | + {/each} |
| 114 | + </ul> |
| 115 | + {/if} |
| 116 | + </li> |
| 117 | + {/if} |
83 | 118 | {/each}
|
84 | 119 | </ul>
|
85 | 120 | </div>
|
|
94 | 129 |
|
95 | 130 | .categories {
|
96 | 131 | font-size: 14px;
|
| 132 | + list-style-type: none; |
| 133 | + } |
| 134 | + .category { |
| 135 | + position: relative; |
| 136 | + } |
| 137 | + .category-button { |
| 138 | + position: absolute; |
| 139 | + left: -24px; |
| 140 | + top: 2px; |
| 141 | +
|
| 142 | + background-color: transparent; |
| 143 | + color: #ddd; |
| 144 | + border: none; |
| 145 | + appearance: none; |
| 146 | + cursor: pointer; |
| 147 | + padding: 0; |
| 148 | + } |
| 149 | + .category-button--close { |
| 150 | + transform: rotate(90deg); |
97 | 151 | }
|
98 | 152 |
|
99 | 153 | .category-title {
|
|
0 commit comments