|
116 | 116 | return Array.from(selectedPackages.keys()).filter((pkg) => !presetPkgs.has(pkg)); |
117 | 117 | } |
118 | 118 |
|
| 119 | + function getGroupedExtras(): { cli: string[]; apps: string[]; taps: string[] } { |
| 120 | + const extras = getExtraPackages(); |
| 121 | + const cli: string[] = []; |
| 122 | + const apps: string[] = []; |
| 123 | + const taps: string[] = []; |
| 124 | + for (const pkg of extras) { |
| 125 | + const t = selectedPackages.get(pkg) || 'formula'; |
| 126 | + if (t === 'cask') apps.push(pkg); |
| 127 | + else if (t === 'tap') taps.push(pkg); |
| 128 | + else cli.push(pkg); |
| 129 | + } |
| 130 | + return { cli, apps, taps }; |
| 131 | + } |
| 132 | +
|
119 | 133 |
|
120 | 134 |
|
121 | 135 | function initPackagesForPreset(preset: string) { |
|
535 | 549 | {/if} |
536 | 550 | </div> |
537 | 551 | {#if getExtraPackages().length > 0} |
| 552 | + {@const grouped = getGroupedExtras()} |
538 | 553 | <div class="selected-extras"> |
539 | | - {#each getExtraPackages() as pkg} |
540 | | - {@const pkgType = selectedPackages.get(pkg) || 'formula'} |
541 | | - <button type="button" class="extra-tag {pkgType}" onclick={() => togglePackage(pkg, pkgType)}> |
542 | | - {pkg} |
543 | | - <span class="remove-icon">×</span> |
544 | | - </button> |
545 | | - {/each} |
| 554 | + {#if grouped.cli.length > 0} |
| 555 | + <div class="extras-group"> |
| 556 | + <span class="group-label">CLI</span> |
| 557 | + {#each grouped.cli as pkg} |
| 558 | + <button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'formula')}> |
| 559 | + {pkg}<span class="remove-icon">×</span> |
| 560 | + </button> |
| 561 | + {/each} |
| 562 | + </div> |
| 563 | + {/if} |
| 564 | + {#if grouped.apps.length > 0} |
| 565 | + <div class="extras-group"> |
| 566 | + <span class="group-label">Apps</span> |
| 567 | + {#each grouped.apps as pkg} |
| 568 | + <button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'cask')}> |
| 569 | + {pkg}<span class="remove-icon">×</span> |
| 570 | + </button> |
| 571 | + {/each} |
| 572 | + </div> |
| 573 | + {/if} |
| 574 | + {#if grouped.taps.length > 0} |
| 575 | + <div class="extras-group"> |
| 576 | + <span class="group-label">Taps</span> |
| 577 | + {#each grouped.taps as pkg} |
| 578 | + <button type="button" class="extra-tag" onclick={() => togglePackage(pkg, 'tap')}> |
| 579 | + {pkg}<span class="remove-icon">×</span> |
| 580 | + </button> |
| 581 | + {/each} |
| 582 | + </div> |
| 583 | + {/if} |
546 | 584 | </div> |
547 | 585 | {/if} |
548 | 586 | <div class="packages-search"> |
|
1078 | 1116 | } |
1079 | 1117 |
|
1080 | 1118 | .selected-extras { |
1081 | | - display: flex; |
1082 | | - flex-wrap: wrap; |
1083 | | - gap: 6px; |
1084 | 1119 | margin-bottom: 12px; |
1085 | 1120 | padding: 10px; |
1086 | | - background: rgba(34, 197, 94, 0.05); |
1087 | | - border: 1px dashed var(--accent); |
| 1121 | + background: rgba(255, 255, 255, 0.02); |
| 1122 | + border: 1px solid var(--border); |
1088 | 1123 | border-radius: 8px; |
1089 | 1124 | } |
1090 | 1125 |
|
| 1126 | + .extras-group { |
| 1127 | + display: flex; |
| 1128 | + flex-wrap: wrap; |
| 1129 | + align-items: center; |
| 1130 | + gap: 6px; |
| 1131 | + margin-bottom: 8px; |
| 1132 | + } |
| 1133 | +
|
| 1134 | + .extras-group:last-child { |
| 1135 | + margin-bottom: 0; |
| 1136 | + } |
| 1137 | +
|
| 1138 | + .group-label { |
| 1139 | + font-size: 0.6rem; |
| 1140 | + text-transform: uppercase; |
| 1141 | + letter-spacing: 0.05em; |
| 1142 | + color: var(--text-muted); |
| 1143 | + font-weight: 600; |
| 1144 | + width: 32px; |
| 1145 | + flex-shrink: 0; |
| 1146 | + } |
| 1147 | +
|
1091 | 1148 | .extra-tag { |
1092 | 1149 | display: inline-flex; |
1093 | 1150 | align-items: center; |
1094 | 1151 | gap: 4px; |
1095 | 1152 | padding: 4px 8px; |
1096 | | - border: none; |
| 1153 | + background: rgba(255, 255, 255, 0.08); |
| 1154 | + border: 1px solid rgba(255, 255, 255, 0.12); |
| 1155 | + color: var(--text-secondary); |
1097 | 1156 | border-radius: 4px; |
1098 | 1157 | font-size: 0.75rem; |
1099 | 1158 | font-family: 'JetBrains Mono', monospace; |
1100 | 1159 | cursor: pointer; |
1101 | 1160 | transition: all 0.15s; |
1102 | 1161 | } |
1103 | 1162 |
|
1104 | | - .extra-tag.formula { |
1105 | | - background: var(--accent); |
1106 | | - color: #000; |
1107 | | - } |
1108 | | -
|
1109 | | - .extra-tag.formula:hover { |
1110 | | - background: #1a9f4a; |
1111 | | - } |
1112 | | -
|
1113 | | - .extra-tag.cask { |
1114 | | - background: #60a5fa; |
1115 | | - color: #000; |
1116 | | - } |
1117 | | -
|
1118 | | - .extra-tag.cask:hover { |
1119 | | - background: #3b82f6; |
1120 | | - } |
1121 | | -
|
1122 | | - .extra-tag.tap { |
1123 | | - background: #fbbf24; |
1124 | | - color: #000; |
1125 | | - } |
1126 | | -
|
1127 | | - .extra-tag.tap:hover { |
1128 | | - background: #f59e0b; |
| 1163 | + .extra-tag:hover { |
| 1164 | + background: rgba(255, 255, 255, 0.14); |
| 1165 | + color: var(--text-primary); |
1129 | 1166 | } |
1130 | 1167 |
|
1131 | 1168 | .remove-icon { |
|
0 commit comments