[{"data":1,"prerenderedAt":513},["ShallowReactive",2],{"$f7LWX1HT0sT52vAD4shldMw8KHUvuy1q3-rIZsyxRrOE":3},{"newThing":4,"project":5,"cycle":9,"sections":25,"threads":480,"otherDocs":481,"documents":482,"images":486,"archiveItems":510,"links":511},"UxColumnPicker on a new UxPopover primitive — a checkbox popover above the table that shows\u002Fhides DataTable columns, with a locked identity column and a min-one guard; prototyped as design-local components before layer extraction",{"id":6,"label":7,"liveBase":8},"design","Design",null,{"id":10,"num":11,"dir":12,"name":13,"title":14,"focus":15,"status":16,"statusNote":8,"created":17,"completed":8,"mode":18,"report":8,"recordless":19,"thumbnail":20,"imageCount":21,"artifactCount":22,"lastActivity":23,"hasPickup":19,"hasInitialPrompt":24},"c93",93,"c93.table-column-picker","table-column-picker","Table Column Picker","A checkbox popover that shows\u002Fhides a table's columns — `UxColumnPicker` on a new `UxPopover` primitive — prototyped on the design site, then extracted to q-nuxt-layer and wired into a qdash listing","active","2026-09-22","assemblage → evolution — the popover-checkbox idiom already exists three times hand-rolled (design framework-picker-ideas Idea 2, qdash \u002Fcontrols, qdash live FilterPopover); this composes it once as two layer modules",false,"\u002Fcycles\u002Fdesign\u002Fc93-column-picker-open.png",5,2,"2026-09-27",true,[26,65,131,276,466],{"key":27,"title":28,"empty":19,"ast":29},"why","Why",{"type":30,"children":31},"root",[32],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37,40,47,49,55,57,63],{"type":38,"value":39},"text","qdash listing tables are getting wide (Devices carries 7 columns, Sessions and the ",{"type":33,"tag":41,"props":42,"children":44},"code",{"className":43},[],[45],{"type":38,"value":46},"\u002Finventory\u002F*",{"type":38,"value":48}," listings more) and nothing in the ecosystem lets a user hide the columns they don't need. ",{"type":33,"tag":41,"props":50,"children":52},{"className":51},[],[53],{"type":38,"value":54},"DataTable",{"type":38,"value":56}," already takes a ",{"type":33,"tag":41,"props":58,"children":60},{"className":59},[],[61],{"type":38,"value":62},"columns",{"type":38,"value":64}," array, so the missing piece is only the control. The anchored panel it needs has been hand-rolled in three places, which is the signal for a primitive.",{"key":66,"title":67,"empty":19,"ast":68},"objective","Objective",{"type":30,"children":69},[70,126],{"type":33,"tag":71,"props":72,"children":73},"ol",{},[74,86,113],{"type":33,"tag":75,"props":76,"children":77},"li",{},[78,84],{"type":33,"tag":41,"props":79,"children":81},{"className":80},[],[82],{"type":38,"value":83},"UxPopover",{"type":38,"value":85}," — trigger + anchored panel primitive on Headless UI (toggle, Escape, click-outside, focus return owned by Headless; chrome and alignment owned here).",{"type":33,"tag":75,"props":87,"children":88},{},[89,95,97,103,105,111],{"type":33,"tag":41,"props":90,"children":92},{"className":91},[],[93],{"type":38,"value":94},"UxColumnPicker",{"type":38,"value":96}," — ",{"type":33,"tag":41,"props":98,"children":100},{"className":99},[],[101],{"type":38,"value":102},"columns: { key, label, locked? }[]",{"type":38,"value":104}," in, visible keys out via v-model in catalog order; locked columns checked + disabled; min-one guard; Show all \u002F Done footer; trigger with a ",{"type":33,"tag":41,"props":106,"children":108},{"className":107},[],[109],{"type":38,"value":110},"N of M",{"type":38,"value":112}," badge when anything is hidden.",{"type":33,"tag":75,"props":114,"children":115},{},[116,118,124],{"type":38,"value":117},"Both demonstrated on the design site with minimal \u002F overflow \u002F guard \u002F long-label \u002F left-aligned scenarios and the ",{"type":33,"tag":41,"props":119,"children":121},{"className":120},[],[122],{"type":38,"value":123},"UxTableList",{"type":38,"value":125}," v-if pattern, then extracted to the layer, documented, released, and placed on one qdash listing.",{"type":33,"tag":34,"props":127,"children":128},{},[129],{"type":38,"value":130},"Decisions (2026-09-22): target DataTable, popover idiom, trigger above the whole component, v-model only (no persistence), show\u002Fhide only (no reorder), locked identity column + min-one, UxPopover as its own primitive.",{"key":132,"title":133,"empty":19,"ast":134},"scope","Scope",{"type":30,"children":135},[136],{"type":33,"tag":137,"props":138,"children":139},"ul",{},[140,229,256],{"type":33,"tag":75,"props":141,"children":142},{},[143,145,151,153,159,161,167,169,175,177,182,184,189,191,197,199,205,207,213,214,220,221,227],{"type":38,"value":144},"Design: ",{"type":33,"tag":41,"props":146,"children":148},{"className":147},[],[149],{"type":38,"value":150},"cycles\u002Fc93.table-column-picker\u002F",{"type":38,"value":152}," (",{"type":33,"tag":41,"props":154,"children":156},{"className":155},[],[157],{"type":38,"value":158},"initial-prompt.md",{"type":38,"value":160},", ",{"type":33,"tag":41,"props":162,"children":164},{"className":163},[],[165],{"type":38,"value":166},"plan.md",{"type":38,"value":168},", this record); prototypes ",{"type":33,"tag":41,"props":170,"children":172},{"className":171},[],[173],{"type":38,"value":174},"app\u002Fcomponents\u002Fux\u002F{Popover,ColumnPicker}.vue",{"type":38,"value":176}," (auto-import as ",{"type":33,"tag":41,"props":178,"children":180},{"className":179},[],[181],{"type":38,"value":83},{"type":38,"value":183}," \u002F ",{"type":33,"tag":41,"props":185,"children":187},{"className":186},[],[188],{"type":38,"value":94},{"type":38,"value":190}," so extraction is a file move); demo ",{"type":33,"tag":41,"props":192,"children":194},{"className":193},[],[195],{"type":38,"value":196},"app\u002Fpages\u002Fpages\u002Fcolumn-picker.vue",{"type":38,"value":198}," + ",{"type":33,"tag":41,"props":200,"children":202},{"className":201},[],[203],{"type":38,"value":204},"page-registry.ts",{"type":38,"value":206}," entry; later ",{"type":33,"tag":41,"props":208,"children":210},{"className":209},[],[211],{"type":38,"value":212},"_demos\u002FUxPopover.vue",{"type":38,"value":160},{"type":33,"tag":41,"props":215,"children":217},{"className":216},[],[218],{"type":38,"value":219},"_demos\u002FUxColumnPicker.vue",{"type":38,"value":160},{"type":33,"tag":41,"props":222,"children":224},{"className":223},[],[225],{"type":38,"value":226},"component-registry.ts",{"type":38,"value":228},".",{"type":33,"tag":75,"props":230,"children":231},{},[232,234,240,241,247,249,254],{"type":38,"value":233},"q-nuxt-layer (extraction): ",{"type":33,"tag":41,"props":235,"children":237},{"className":236},[],[238],{"type":38,"value":239},"components\u002Fux\u002FPopover.vue",{"type":38,"value":160},{"type":33,"tag":41,"props":242,"children":244},{"className":243},[],[245],{"type":38,"value":246},"components\u002Fux\u002FColumnPicker.vue",{"type":38,"value":248},"; possible ",{"type":33,"tag":41,"props":250,"children":252},{"className":251},[],[253],{"type":38,"value":54},{"type":38,"value":255}," sort fallback when the sorted column is hidden.",{"type":33,"tag":75,"props":257,"children":258},{},[259,261,267,269,275],{"type":38,"value":260},"qcontrol (first consumer, ",{"type":33,"tag":41,"props":262,"children":264},{"className":263},[],[265],{"type":38,"value":266},"feat\u002Fnew-pages",{"type":38,"value":268},"): ",{"type":33,"tag":41,"props":270,"children":272},{"className":271},[],[273],{"type":38,"value":274},"crates\u002Fqdash\u002Fui\u002Fapp\u002Fcomponents\u002FDevicesOverview.vue",{"type":38,"value":228},{"key":277,"title":278,"empty":19,"ast":279},"key-changes","Key Changes",{"type":30,"children":280},[281],{"type":33,"tag":137,"props":282,"children":283},{},[284,302,365,424,456],{"type":33,"tag":75,"props":285,"children":286},{},[287,293,295,300],{"type":33,"tag":288,"props":289,"children":290},"strong",{},[291],{"type":38,"value":292},"plan (2026-09-22):",{"type":38,"value":294}," survey of existing pieces + seven open questions → ",{"type":33,"tag":41,"props":296,"children":298},{"className":297},[],[299],{"type":38,"value":166},{"type":38,"value":301},"; all seven answered the same day.",{"type":33,"tag":75,"props":303,"children":304},{},[305,310,312,317,318,323,325,331,333,339,341,347,349,355,357,363],{"type":33,"tag":288,"props":306,"children":307},{},[308],{"type":38,"value":309},"prototype (2026-09-22):",{"type":38,"value":311}," ",{"type":33,"tag":41,"props":313,"children":315},{"className":314},[],[316],{"type":38,"value":83},{"type":38,"value":198},{"type":33,"tag":41,"props":319,"children":321},{"className":320},[],[322],{"type":38,"value":94},{"type":38,"value":324}," built as design-local components under ",{"type":33,"tag":41,"props":326,"children":328},{"className":327},[],[329],{"type":38,"value":330},"app\u002Fcomponents\u002Fux\u002F",{"type":38,"value":332},"; ",{"type":33,"tag":41,"props":334,"children":336},{"className":335},[],[337],{"type":38,"value":338},"\u002Fpages\u002Fcolumn-picker",{"type":38,"value":340}," demo with the Devices catalog live table, five scenarios, and the UxTableList pattern. Verified on the live :3000 server via ",{"type":33,"tag":41,"props":342,"children":344},{"className":343},[],[345],{"type":38,"value":346},"scripts\u002Fshot-programs\u002Fc93-column-picker.json",{"type":38,"value":348}," (closed → open → Owner toggled off: badge 7→6 of 10, column drops); captures ",{"type":33,"tag":41,"props":350,"children":352},{"className":351},[],[353],{"type":38,"value":354},"public\u002Fcycles\u002Fdesign\u002Fc93-column-picker{,-full,-open,-toggled}.png",{"type":38,"value":356},". Polish from the shots: locked\u002Flast-standing rows dim; list cap raised to ",{"type":33,"tag":41,"props":358,"children":360},{"className":359},[],[361],{"type":38,"value":362},"max-h-96",{"type":38,"value":364}," so a 10-column catalog doesn't scroll. Not committed — Mark reviews first (push = deploy).",{"type":33,"tag":75,"props":366,"children":367},{},[368,373,375,380,381,386,388,393,395,400,401,406,408,414,416,422],{"type":33,"tag":288,"props":369,"children":370},{},[371],{"type":38,"value":372},"component docs (2026-09-22):",{"type":38,"value":374}," both prototypes registered in ",{"type":33,"tag":41,"props":376,"children":378},{"className":377},[],[379],{"type":38,"value":226},{"type":38,"value":152},{"type":33,"tag":41,"props":382,"children":384},{"className":383},[],[385],{"type":38,"value":83},{"type":38,"value":387}," under Interactive, ",{"type":33,"tag":41,"props":389,"children":391},{"className":390},[],[392],{"type":38,"value":94},{"type":38,"value":394}," under Table) with ",{"type":33,"tag":41,"props":396,"children":398},{"className":397},[],[399],{"type":38,"value":212},{"type":38,"value":198},{"type":33,"tag":41,"props":402,"children":404},{"className":403},[],[405],{"type":38,"value":219},{"type":38,"value":407}," (adminProps cover every prop; minimal \u002F typical \u002F overflow scenarios, guard state) — so they appear on ",{"type":33,"tag":41,"props":409,"children":411},{"className":410},[],[412],{"type":38,"value":413},"\u002Fcomponents",{"type":38,"value":415}," now, not only after extraction. ",{"type":33,"tag":41,"props":417,"children":419},{"className":418},[],[420],{"type":38,"value":421},"source",{"type":38,"value":423}," is display-only, so it reads the design-local path with a note.",{"type":33,"tag":75,"props":425,"children":426},{},[427,432,434,439,441,447,449,454],{"type":33,"tag":288,"props":428,"children":429},{},[430],{"type":38,"value":431},"side prop (2026-09-22):",{"type":38,"value":433}," Mark's note that the panel covered the very columns being toggled → ",{"type":33,"tag":41,"props":435,"children":437},{"className":436},[],[438],{"type":38,"value":83},{"type":38,"value":440}," gains ",{"type":33,"tag":41,"props":442,"children":444},{"className":443},[],[445],{"type":38,"value":446},"side: 'below' | 'above'",{"type":38,"value":448}," (passed through ",{"type":33,"tag":41,"props":450,"children":452},{"className":451},[],[453],{"type":38,"value":94},{"type":38,"value":455},"); the live demo and the DevCanvas default open upward over the title area so the table stays fully visible. Trade-off: 'above' needs headroom — a picker at the very top of a page would push the list off-screen, so it suits tables that sit under a title band (every qdash listing does) and the default stays 'below'.",{"type":33,"tag":75,"props":457,"children":458},{},[459,464],{"type":33,"tag":288,"props":460,"children":461},{},[462],{"type":38,"value":463},"known gap:",{"type":38,"value":465}," sorting by a column and then hiding it leaves DataTable unsorted (sort column not found). Candidate rule at extraction: fall back to the first visible sortable column.",{"key":467,"title":468,"empty":19,"ast":469},"outcome","Outcome",{"type":30,"children":470},[471],{"type":33,"tag":34,"props":472,"children":473},{},[474],{"type":33,"tag":475,"props":476,"children":477},"em",{},[478],{"type":38,"value":479},"(open)",[],[158,166],[483,484],{"file":158,"title":14},{"file":166,"title":485},"plan — Table Column Picker",[487,494,497,500,506],{"src":488,"kind":489,"order":490,"caption":491,"capturedAt":492,"subject":493,"route":338},"\u002Fcycles\u002Fdesign\u002Fc93-column-picker.png","hero",0,"The Devices listing with the picker closed — 7 of 10 columns visible, the badge on the trigger says so; scenarios below: minimal, overflow, guard, long labels, UxTableList","2026-09-22T21:27:07.746Z","page\u002Fcolumn-picker",{"src":20,"kind":489,"order":495,"caption":496,"capturedAt":492,"subject":493,"route":338},1,"Picker open with side=above — the list rises over the title area, so every column of the Devices table stays visible while toggling; Device locked, Show all in the header, count + Done in the footer",{"src":498,"kind":489,"order":22,"caption":499,"capturedAt":492,"subject":493,"route":338},"\u002Fcycles\u002Fdesign\u002Fc93-column-picker-toggled.png","Owner unchecked — the column drops out of the fully visible table while the panel stays open; the badge reads 6 of 10",{"src":501,"kind":489,"order":502,"capturedAt":503,"subject":504,"route":505},"\u002Fcycles\u002Fdesign\u002Fc93-ux-column-picker-docs.png",4999,"2026-09-22T21:20:37.341Z","component\u002Fux-column-picker","\u002Fcomponents\u002Ftable\u002Fux-column-picker",{"src":507,"kind":508,"order":509,"capturedAt":492,"subject":493,"route":338},"\u002Fcycles\u002Fdesign\u002Fc93-column-picker-full.png","full",9000,[],[512],{"route":338,"href":338},1794599413232]