class DesktopFilesSidebar extends Shadow { constructor(groups, activeGroupIds, onToggleGroup, locations, activeLocation, onSelectLocation) { super() this.groups = groups this.activeGroupIds = activeGroupIds this.onToggleGroup = onToggleGroup this.locations = locations this.activeLocation = activeLocation this.onSelectLocation = onSelectLocation } render() { const self = this VStack(() => { // ── Locations ───────────────────────────────────────────── VStack(() => { this.sectionLabel("BROWSE") this.locations.forEach(loc => { const isActive = this.activeLocation === loc.id; HStack(() => { p(loc.icon) .margin(0) .fontSize(0.88, em) .lineHeight("1") .flexShrink(0) p(loc.label) .margin(0) .fontSize(0.88, em) .fontWeight(isActive ? "600" : "400") .color("var(--headertext)") .opacity(isActive ? 1 : 0.75) }) .gap(0.6, em) .paddingHorizontal(0.85, em) .paddingVertical(0.42, em) .marginHorizontal(0.4, em) .borderRadius(0.45, em) .background(isActive ? "var(--app)" : "transparent") .cursor("pointer") .alignItems("center") .width("calc(100% - 0.8em)") .boxSizing("border-box") .onClick(function(done){ if(done){ self.onSelectLocation(loc.id) } }) }) }) .paddingTop(0.9, em) // ── Divider ─────────────────────────────────────────────── VStack(() => {}) .height(1, px) .background("var(--divider)") .marginVertical(0.65, em) .marginHorizontal(1, em) // ── Permission groups ───────────────────────────────────── VStack(() => { this.sectionLabel("PERMISSION GROUPS") this.groups.forEach(group => { const isOn = this.activeGroupIds.has(group.id); HStack(() => { // Colored dot / checkbox area HStack(() => { VStack(() => { if (isOn) { p("✓") .margin(0) .fontSize(0.6, em) .fontWeight("800") .color("white") .lineHeight("1") } }) .width(0.95, em) .height(0.95, em) .borderRadius(0.22, em) .background(isOn ? group.color : "transparent") .border(`1.5px solid ${group.color}`) .justifyContent("center") .alignItems("center") .boxSizing("border-box") .flexShrink(0) }) .cursor("pointer") p(group.name) .margin(0) .fontSize(0.85, em) .fontWeight("400") .color("var(--headertext)") .opacity(isOn ? 1 : 0.45) .flex(1) .minWidth(0) .overflow("hidden") .whiteSpace("nowrap") .textOverflow("ellipsis") p(`${group.fileCount}`) .margin(0) .fontSize(0.68, em) .color("var(--headertext)") .opacity(0.3) .flexShrink(0) }) .gap(0.6, em) .paddingHorizontal(0.85, em) .paddingVertical(0.38, em) .marginHorizontal(0.4, em) .borderRadius(0.45, em) .cursor("pointer") .alignItems("center") .width("calc(100% - 0.8em)") .boxSizing("border-box") .onClick(function(done){ if(done){ self.onToggleGroup(group.id) } }) }) }) VStack(() => {}).flex(1) // ── Storage usage ───────────────────────────────────────── VStack(() => { HStack(() => { p("Storage") .margin(0) .fontSize(0.75, em) .color("var(--headertext)") .opacity(0.45) .flex(1) p("4.2 GB / 10 GB") .margin(0) .fontSize(0.7, em) .color("var(--headertext)") .opacity(0.3) }) .alignItems("center") .marginBottom(0.45, em) // Bar VStack(() => { VStack(() => {}) .width(42, pct) .height(100, pct) .background("var(--quillred)") .borderRadius(100, px) }) .width(100, pct) .height(4, px) .background("var(--darkaccent)") .borderRadius(100, px) .overflow("hidden") }) .paddingHorizontal(1.1, em) .paddingBottom(1.1, em) .flexShrink(0) }) .height(100, pct) .width(100, pct) .boxSizing("border-box") .overflowY("auto") } sectionLabel(text) { p(text) .margin(0) .marginBottom(0.25, em) .paddingHorizontal(1.1, em) .fontSize(0.62, em) .fontWeight("700") .letterSpacing("0.07em") .color("var(--headertext)") .opacity(0.35) } } register(DesktopFilesSidebar)