feat(dialog): introduce Reka-UI dialog primitives + opt-in renderer branch (Phase 0)#11719
feat(dialog): introduce Reka-UI dialog primitives + opt-in renderer branch (Phase 0)#11719dante01yoon wants to merge 1 commit intomainfrom
Conversation
…hase 0) Introduces shadcn-style dialog primitives at src/components/ui/dialog/ wrapping Reka-UI's Dialog* components, with size variants (sm/md/lg/xl/full). Adds an opt-in renderer flag (`dialogComponentProps.renderer: 'primevue' | 'reka'`) to dialogStore. GlobalDialog.vue branches between PrimeVue (default, unchanged) and the new Reka-UI path. No production dialog opts in yet — this PR only lands the infrastructure. Motivation: GitHub issue #11688 surfaced PrimeVue Dialog max-width limitations that are hard to fix cleanly through PrimeVue's pass-through styling. ADR 0004 (Rejected) endorses selective shadcn/Reka-UI replacement of problematic PrimeVue components. This is Phase 0 of a phased migration; the #11688 fix arrives naturally in Phase 1 once prompt/confirm dialogs migrate to the new primitive's `md` default (max-width 36rem). See temp/plans/adr-0009-dialog-reka-migration-DRAFT.md and temp/plans/dialog-migration-phase-0.md for the full plan.
📝 WalkthroughWalkthroughA new dialog system based on reka-ui is introduced alongside the existing PrimeVue implementation. GlobalDialog now conditionally renders either PrimeVue or ReKa dialogs based on a Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant GlobalDialog
participant DialogStore as Dialog Store
participant Renderer as Renderer Decision
participant PrimeVueDialog as PrimeVue Dialog
participant RekaDialog as ReKa Dialog
User->>DialogStore: showDialog(config)
DialogStore->>DialogStore: Push item to dialogStack
DialogStore-->>GlobalDialog: Update dialogStack (reactive)
GlobalDialog->>Renderer: Check item.dialogComponentProps.renderer
alt renderer === 'reka'
Renderer->>RekaDialog: Render with DialogPortal, DialogOverlay, DialogContent, etc.
RekaDialog->>RekaDialog: Handle open/close via :open, `@update`:open
RekaDialog-->>User: Display ReKa dialog
else renderer === 'primevue' or undefined
Renderer->>PrimeVueDialog: Render with v-model:visible and pass-through props
PrimeVueDialog-->>User: Display PrimeVue dialog
end
User->>RekaDialog: Interact (click close, escape, etc.)
RekaDialog->>DialogStore: riseDialog({ key }) / update:open event
DialogStore->>DialogStore: Remove/modify dialogStack entry
DialogStore-->>GlobalDialog: Trigger re-render
GlobalDialog-->>User: Dialog closes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎨 Storybook: ✅ Built — View Storybook |
🎭 Playwright: ✅ 1357 passed, 0 failed · 4 flaky📊 Browser Reports
|
📦 Bundle: 5.23 MB gzip 🔴 +1.73 kBDetailsSummary
Category Glance App Entry Points — 31.2 kB (baseline 22.5 kB) • 🔴 +8.63 kBMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.23 MB (baseline 1.23 MB) • ⚪ 0 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 77.7 kB (baseline 77.7 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed / 2 unchanged Panels & Settings — 484 kB (baseline 484 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 10 added / 10 removed / 11 unchanged User & Accounts — 17.4 kB (baseline 17.4 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 5 added / 5 removed / 2 unchanged Editors & Dialogs — 113 kB (baseline 113 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 4 added / 4 removed UI Components — 61 kB (baseline 61 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 removed / 8 unchanged Data & Services — 3.04 MB (baseline 3.04 MB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 4 unchanged Utilities & Hooks — 363 kB (baseline 363 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 13 added / 13 removed / 18 unchanged Vendor & Third-Party — 9.88 MB (baseline 9.88 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 8.83 MB (baseline 8.83 MB) • ⚪ 0 BBundles that do not match a named category
Status: 57 added / 57 removed / 78 unchanged ⚡ Performance Report
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-04-28T08:08:08.072Z",
"gitSha": "096922422621646f613eead42dc80ebf37a8e60a",
"branch": "jaewon/dialog-reka-migration-phase-0",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2029.5860000000516,
"styleRecalcs": 8,
"styleRecalcDurationMs": 8.049,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 350.735,
"heapDeltaBytes": 20421400,
"heapUsedBytes": 64427856,
"domNodes": 16,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 16.233999999999998,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-idle",
"durationMs": 2014.6540000000073,
"styleRecalcs": 11,
"styleRecalcDurationMs": 9.218,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 337.634,
"heapDeltaBytes": 21221356,
"heapUsedBytes": 65095636,
"domNodes": 22,
"jsHeapTotalBytes": 22806528,
"scriptDurationMs": 17.722,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 1995.480999999927,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.82,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 328.4050000000001,
"heapDeltaBytes": 20367536,
"heapUsedBytes": 64433316,
"domNodes": 18,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 15.406000000000002,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2026.219000000026,
"styleRecalcs": 83,
"styleRecalcDurationMs": 46.556,
"layouts": 12,
"layoutDurationMs": 3.903,
"taskDurationMs": 1021.8990000000001,
"heapDeltaBytes": 15661056,
"heapUsedBytes": 59695956,
"domNodes": 64,
"jsHeapTotalBytes": 23855104,
"scriptDurationMs": 141.582,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1999.0469999999618,
"styleRecalcs": 79,
"styleRecalcDurationMs": 38.729,
"layouts": 12,
"layoutDurationMs": 3.333,
"taskDurationMs": 915.2829999999999,
"heapDeltaBytes": 15708892,
"heapUsedBytes": 59775884,
"domNodes": 62,
"jsHeapTotalBytes": 23330816,
"scriptDurationMs": 124.82100000000001,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-mouse-sweep",
"durationMs": 2022.9409999999461,
"styleRecalcs": 84,
"styleRecalcDurationMs": 45.406,
"layouts": 12,
"layoutDurationMs": 3.6769999999999996,
"taskDurationMs": 961.3399999999999,
"heapDeltaBytes": 18620440,
"heapUsedBytes": 68526976,
"domNodes": 66,
"jsHeapTotalBytes": 25165824,
"scriptDurationMs": 136.763,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1731.1990000000037,
"styleRecalcs": 31,
"styleRecalcDurationMs": 16.215,
"layouts": 6,
"layoutDurationMs": 0.604,
"taskDurationMs": 293.13200000000006,
"heapDeltaBytes": 24749272,
"heapUsedBytes": 68790556,
"domNodes": 76,
"jsHeapTotalBytes": 21495808,
"scriptDurationMs": 18.383000000000003,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1726.8810000000485,
"styleRecalcs": 30,
"styleRecalcDurationMs": 21.284999999999997,
"layouts": 6,
"layoutDurationMs": 0.7390000000000001,
"taskDurationMs": 324.128,
"heapDeltaBytes": 24695572,
"heapUsedBytes": 68123628,
"domNodes": 76,
"jsHeapTotalBytes": 21233664,
"scriptDurationMs": 22.235,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1723.555000000033,
"styleRecalcs": 30,
"styleRecalcDurationMs": 16.995000000000005,
"layouts": 6,
"layoutDurationMs": 0.541,
"taskDurationMs": 302.18,
"heapDeltaBytes": 25036524,
"heapUsedBytes": 68763660,
"domNodes": 77,
"jsHeapTotalBytes": 21495808,
"scriptDurationMs": 25.998,
"eventListeners": 19,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "dom-widget-clipping",
"durationMs": 545.7269999999994,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.558999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 325.624,
"heapDeltaBytes": 6735964,
"heapUsedBytes": 50780760,
"domNodes": 17,
"jsHeapTotalBytes": 12845056,
"scriptDurationMs": 57.836999999999996,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 551.5800000000013,
"styleRecalcs": 13,
"styleRecalcDurationMs": 8.562,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 325.29999999999995,
"heapDeltaBytes": 6959392,
"heapUsedBytes": 50754488,
"domNodes": 21,
"jsHeapTotalBytes": 12582912,
"scriptDurationMs": 63.54,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 529.3689999999742,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.754000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 316.109,
"heapDeltaBytes": 6764896,
"heapUsedBytes": 50788392,
"domNodes": 18,
"jsHeapTotalBytes": 12582912,
"scriptDurationMs": 57.153,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.669999999999998,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2037.7690000000257,
"styleRecalcs": 9,
"styleRecalcDurationMs": 9.797999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 554.7599999999999,
"heapDeltaBytes": 4776136,
"heapUsedBytes": 57332756,
"domNodes": -260,
"jsHeapTotalBytes": 15892480,
"scriptDurationMs": 102.632,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2081.446000000028,
"styleRecalcs": 11,
"styleRecalcDurationMs": 10.526,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 559.8000000000001,
"heapDeltaBytes": 4750392,
"heapUsedBytes": 57165368,
"domNodes": -257,
"jsHeapTotalBytes": 16941056,
"scriptDurationMs": 106.752,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-idle",
"durationMs": 2036.7539999999735,
"styleRecalcs": 10,
"styleRecalcDurationMs": 10.280000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 548.7040000000001,
"heapDeltaBytes": 4425240,
"heapUsedBytes": 56523556,
"domNodes": -258,
"jsHeapTotalBytes": 16416768,
"scriptDurationMs": 103.88399999999999,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2123.2860000000073,
"styleRecalcs": 68,
"styleRecalcDurationMs": 18.954,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1090.589,
"heapDeltaBytes": -822572,
"heapUsedBytes": 54214580,
"domNodes": -265,
"jsHeapTotalBytes": 17932288,
"scriptDurationMs": 399.262,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2132.7989999999772,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.307999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1109.9589999999998,
"heapDeltaBytes": 15601096,
"heapUsedBytes": 71088632,
"domNodes": -263,
"jsHeapTotalBytes": 18194432,
"scriptDurationMs": 405.64500000000004,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2126.062999999931,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.394999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1082.6009999999999,
"heapDeltaBytes": 20469324,
"heapUsedBytes": 75658000,
"domNodes": -264,
"jsHeapTotalBytes": 17145856,
"scriptDurationMs": 389.634,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3153.300999999999,
"styleRecalcs": 65,
"styleRecalcDurationMs": 18.253,
"layouts": 60,
"layoutDurationMs": 7.1450000000000005,
"taskDurationMs": 1318.2179999999998,
"heapDeltaBytes": 1033944,
"heapUsedBytes": 57497564,
"domNodes": -266,
"jsHeapTotalBytes": 16678912,
"scriptDurationMs": 482.093,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "large-graph-zoom",
"durationMs": 3133.066000000042,
"styleRecalcs": 66,
"styleRecalcDurationMs": 18.952999999999996,
"layouts": 60,
"layoutDurationMs": 7.433999999999999,
"taskDurationMs": 1336.106,
"heapDeltaBytes": -5745896,
"heapUsedBytes": 59671044,
"domNodes": -263,
"jsHeapTotalBytes": 14172160,
"scriptDurationMs": 491.62799999999993,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3184.933000000001,
"styleRecalcs": 66,
"styleRecalcDurationMs": 19.076000000000004,
"layouts": 60,
"layoutDurationMs": 7.079000000000001,
"taskDurationMs": 1300.017,
"heapDeltaBytes": 8362752,
"heapUsedBytes": 64749016,
"domNodes": -264,
"jsHeapTotalBytes": 15630336,
"scriptDurationMs": 491.23799999999994,
"eventListeners": -123,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2019.3360000000098,
"styleRecalcs": 10,
"styleRecalcDurationMs": 8.979999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 557.712,
"heapDeltaBytes": 4479572,
"heapUsedBytes": 68453500,
"domNodes": -260,
"jsHeapTotalBytes": 16093184,
"scriptDurationMs": 101.19,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2035.9680000000253,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.923000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 563.9320000000001,
"heapDeltaBytes": 4533780,
"heapUsedBytes": 59022908,
"domNodes": -260,
"jsHeapTotalBytes": 15892480,
"scriptDurationMs": 109.63600000000001,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 2010.114999999928,
"styleRecalcs": 8,
"styleRecalcDurationMs": 7.859000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 519.0819999999999,
"heapDeltaBytes": 2455168,
"heapUsedBytes": 58672460,
"domNodes": -264,
"jsHeapTotalBytes": 16154624,
"scriptDurationMs": 90.79699999999998,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 548.5089999999673,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.066999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 359.64799999999997,
"heapDeltaBytes": 8643016,
"heapUsedBytes": 58897440,
"domNodes": 20,
"jsHeapTotalBytes": 13893632,
"scriptDurationMs": 127.073,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 592.5290000000132,
"styleRecalcs": 47,
"styleRecalcDurationMs": 12.702,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 367.71299999999997,
"heapDeltaBytes": 7048188,
"heapUsedBytes": 51081336,
"domNodes": 20,
"jsHeapTotalBytes": 12845056,
"scriptDurationMs": 128.672,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 551.6340000000355,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.838,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 348.472,
"heapDeltaBytes": 7015516,
"heapUsedBytes": 51093100,
"domNodes": 20,
"jsHeapTotalBytes": 12320768,
"scriptDurationMs": 122.93199999999999,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "subgraph-idle",
"durationMs": 2004.9109999999928,
"styleRecalcs": 9,
"styleRecalcDurationMs": 8.112,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 324.11,
"heapDeltaBytes": 20111176,
"heapUsedBytes": 64287116,
"domNodes": 18,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 12.133000000000001,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 1991.579999999999,
"styleRecalcs": 10,
"styleRecalcDurationMs": 9.974999999999998,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 347.75800000000004,
"heapDeltaBytes": 20909840,
"heapUsedBytes": 64420124,
"domNodes": 20,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 19.904999999999998,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 1999.2670000000317,
"styleRecalcs": 11,
"styleRecalcDurationMs": 11.259,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 351.988,
"heapDeltaBytes": 19935372,
"heapUsedBytes": 63994204,
"domNodes": 21,
"jsHeapTotalBytes": 23068672,
"scriptDurationMs": 16.209,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1722.6029999999923,
"styleRecalcs": 77,
"styleRecalcDurationMs": 36.699999999999996,
"layouts": 16,
"layoutDurationMs": 4.401999999999999,
"taskDurationMs": 645.956,
"heapDeltaBytes": 11758304,
"heapUsedBytes": 56220644,
"domNodes": 64,
"jsHeapTotalBytes": 23330816,
"scriptDurationMs": 96.721,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1983.1930000000284,
"styleRecalcs": 88,
"styleRecalcDurationMs": 48.065,
"layouts": 16,
"layoutDurationMs": 4.843999999999999,
"taskDurationMs": 922.152,
"heapDeltaBytes": 11892292,
"heapUsedBytes": 55932192,
"domNodes": 73,
"jsHeapTotalBytes": 22282240,
"scriptDurationMs": 98.67500000000001,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1990.3410000000576,
"styleRecalcs": 87,
"styleRecalcDurationMs": 48.167,
"layouts": 16,
"layoutDurationMs": 4.651,
"taskDurationMs": 932.9719999999999,
"heapDeltaBytes": 11819524,
"heapUsedBytes": 56061592,
"domNodes": 72,
"jsHeapTotalBytes": 22544384,
"scriptDurationMs": 97.679,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8184.910000000002,
"styleRecalcs": 251,
"styleRecalcDurationMs": 51.37899999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3615.965,
"heapDeltaBytes": 27721108,
"heapUsedBytes": 80193072,
"domNodes": -259,
"jsHeapTotalBytes": 18980864,
"scriptDurationMs": 1236.3069999999998,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8179.059999999992,
"styleRecalcs": 251,
"styleRecalcDurationMs": 51.18,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3762.7360000000003,
"heapDeltaBytes": 27223808,
"heapUsedBytes": 79625260,
"domNodes": -258,
"jsHeapTotalBytes": 19505152,
"scriptDurationMs": 1269.626,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8167.371000000003,
"styleRecalcs": 250,
"styleRecalcDurationMs": 51.91,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3675.34,
"heapDeltaBytes": 27498724,
"heapUsedBytes": 80965104,
"domNodes": -260,
"jsHeapTotalBytes": 18980864,
"scriptDurationMs": 1241.208,
"eventListeners": -111,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 12178.802000000018,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12152.940999999999,
"heapDeltaBytes": -48310936,
"heapUsedBytes": 169130464,
"domNodes": -9850,
"jsHeapTotalBytes": 25751552,
"scriptDurationMs": 614.877,
"eventListeners": -23959,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-idle",
"durationMs": 12600.783999999976,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12590.730999999998,
"heapDeltaBytes": -9229620,
"heapUsedBytes": 187900524,
"domNodes": -9850,
"jsHeapTotalBytes": 20770816,
"scriptDurationMs": 641.062,
"eventListeners": -23959,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.773333333333238,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 11922.195999999985,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 11911.432999999999,
"heapDeltaBytes": -30147056,
"heapUsedBytes": 187055444,
"domNodes": -9850,
"jsHeapTotalBytes": 20770816,
"scriptDurationMs": 596.643,
"eventListeners": -23959,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666763,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14126.78900000003,
"styleRecalcs": 65,
"styleRecalcDurationMs": 15.806000000000042,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14083.157,
"heapDeltaBytes": -44321812,
"heapUsedBytes": 168764572,
"domNodes": -9849,
"jsHeapTotalBytes": 25751552,
"scriptDurationMs": 945.097,
"eventListeners": -23955,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.219999999999953,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14672.05899999999,
"styleRecalcs": 66,
"styleRecalcDurationMs": 16.901,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14648.67,
"heapDeltaBytes": -40515076,
"heapUsedBytes": 173893052,
"domNodes": -9850,
"jsHeapTotalBytes": -23093248,
"scriptDurationMs": 890.72,
"eventListeners": -23957,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-pan",
"durationMs": 14223.138000000063,
"styleRecalcs": 67,
"styleRecalcDurationMs": 16.59700000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14201.477999999997,
"heapDeltaBytes": -45356536,
"heapUsedBytes": 168615236,
"domNodes": -9850,
"jsHeapTotalBytes": -20733952,
"scriptDurationMs": 906.227,
"eventListeners": -23955,
"totalBlockingTimeMs": 22,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 463.6810000000082,
"styleRecalcs": 19,
"styleRecalcDurationMs": 27.736000000000004,
"layouts": 6,
"layoutDurationMs": 1.8139999999999996,
"taskDurationMs": 138.51900000000003,
"heapDeltaBytes": 5394756,
"heapUsedBytes": 56734348,
"domNodes": 167,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 29.661000000000005,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.663333333333338,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 456.02900000005775,
"styleRecalcs": 13,
"styleRecalcDurationMs": 18.837999999999997,
"layouts": 5,
"layoutDurationMs": 1.192,
"taskDurationMs": 109.09299999999996,
"heapDeltaBytes": 4952576,
"heapUsedBytes": 50618796,
"domNodes": 150,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 23.423999999999996,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "workflow-execution",
"durationMs": 462.8889999999046,
"styleRecalcs": 17,
"styleRecalcDurationMs": 23.454,
"layouts": 5,
"layoutDurationMs": 1.2459999999999998,
"taskDurationMs": 128.029,
"heapDeltaBytes": 5108888,
"heapUsedBytes": 50333124,
"domNodes": 156,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 28.506000000000004,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000273
}
]
} |
Codecov Report❌ Patch coverage is @@ Coverage Diff @@
## main #11719 +/- ##
===========================================
- Coverage 69.30% 51.51% -17.79%
===========================================
Files 1483 1384 -99
Lines 83853 70391 -13462
Branches 23134 19576 -3558
===========================================
- Hits 58114 36263 -21851
- Misses 24794 33527 +8733
+ Partials 945 601 -344
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1002 files with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
src/components/ui/dialog/DialogPortal.vue (1)
5-10: PreferuseForwardPropshere to match the Reka wrapper convention.Directly binding
propsworks, but this diverges from the standardized forwarding pattern used for these primitives.As per coding guidelines, "Use useForwardProps(restProps) for prop forwarding, or computed() if adding defaults" in
src/components/ui/**/*.vue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/dialog/DialogPortal.vue` around lines 5 - 10, Replace the direct v-bind="props" forwarding with the standardized useForwardProps pattern: import/use useForwardProps, pass the component props (from defineProps<DialogPortalProps>()) into useForwardProps to get a forwardProps object, and change the template to v-bind="forwardProps"; if you need defaults instead of straight forwarding use a computed wrapper around props before calling useForwardProps. Ensure you reference the existing defineProps<DialogPortalProps>() and the DialogPortal component when making this change.src/components/ui/dialog/DialogDescription.vue (1)
8-16: UseuseForwardPropsfor forwarded props here as well.This keeps the wrapper consistent with the expected Reka primitive pattern and avoids drift between dialog subcomponents.
As per coding guidelines, "Use useForwardProps(restProps) for prop forwarding, or computed() if adding defaults" in
src/components/ui/**/*.vue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/dialog/DialogDescription.vue` around lines 8 - 16, The wrapper should forward props using useForwardProps instead of manually spreading delegated; keep the customClass default from defineProps but pass the remaining props into useForwardProps so DialogDescription receives the forwarded props. Locate the defineProps destructuring (symbols: defineProps, customClass, delegated) and replace the delegated spread with delegated = useForwardProps(restProps) (or call useForwardProps on the rest object returned from defineProps) and continue using :class="cn('text-sm text-muted-foreground', customClass)" when binding to DialogDescription.src/stores/dialogStore.ts (1)
23-28: Consider removing this new prose block and relying on self-documenting type names.This context already exists in ADR/planning docs, so keeping the type section lean would better match repo conventions.
As per coding guidelines, "Avoid new usage of code comments; do not add or retain redundant comments" and "Write code that is expressive and self-documenting to minimize need for code comments."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/stores/dialogStore.ts` around lines 23 - 28, The new explanatory comment block above the dialog renderer type is redundant — remove the prose comment so the code relies on self-documenting type names ('primevue' and 'reka') and existing ADR docs; specifically delete the multi-line comment that mentions GlobalDialog, 'primevue', 'reka', and the migration note (and any reference to src/components/ui/dialog/) in src/stores/dialogStore.ts so the type declaration stands alone and remains clear.src/components/ui/dialog/DialogOverlay.vue (1)
8-16: Align prop forwarding withuseForwardPropsin this Reka wrapper.Please switch from direct
v-bind="delegated"to forwarded props to keep wrapper behavior consistent across the dialog primitives.As per coding guidelines, "Use useForwardProps(restProps) for prop forwarding, or computed() if adding defaults" in
src/components/ui/**/*.vue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/dialog/DialogOverlay.vue` around lines 8 - 16, The wrapper currently forwards props via the local delegated object (const { class: customClass = '', ...delegated } = defineProps(...)) and uses v-bind="delegated"; change this to use the shared helper by creating a forwardedProps constant: const forwardedProps = useForwardProps(delegated) (import/use useForwardProps in the <script setup>), then update the template to v-bind="forwardedProps" on the <DialogOverlay> (keep :class binding/ customClass handling as needed). This aligns prop forwarding with useForwardProps while preserving the existing customClass handling and DialogOverlay usage.src/components/ui/dialog/Dialog.stories.ts (1)
21-27: Consider removing deprecateddefaultValuefrom argTypes.In Storybook 7+,
defaultValueinargTypesis deprecated. The default is already correctly set inargsat line 29. ThedefaultValueat line 25 can be removed.♻️ Suggested cleanup
argTypes: { size: { control: { type: 'select' }, - options: sizes, - defaultValue: 'md' + options: sizes } },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/ui/dialog/Dialog.stories.ts` around lines 21 - 27, Remove the deprecated defaultValue from the argTypes entry for size: in the Dialog.stories.ts story, locate the argTypes object (the size property that uses control: { type: 'select' }, options: sizes) and delete the defaultValue: 'md' key so the story relies on the existing default in args; leave the control and options intact and ensure args still sets the default size.src/components/dialog/GlobalDialog.test.ts (1)
48-49: Consider usingfindByqueries instead of doublenextTick.The double
await nextTick()pattern can be fragile if rendering takes additional ticks. Testing Library'sfindByRolequeries (orwaitFor) automatically wait for elements to appear and are more resilient to timing variations.♻️ Suggested improvement
- await nextTick() - await nextTick() - - const dialogs = screen.queryAllByRole('dialog') + const dialogs = await screen.findAllByRole('dialog')Also applies to: 65-66
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/dialog/GlobalDialog.test.ts` around lines 48 - 49, Replace the fragile double "await nextTick()" usage in GlobalDialog.test.ts with Testing Library async queries: remove the two nextTick calls (the occurrences currently surrounding the assertions) and use a findBy* query (e.g., screen.findByRole('dialog') or screen.findByText(...)) or wrap assertions in waitFor so the test waits for the DOM change reliably; update both occurrences (around the two nextTick calls at lines shown) to use screen.findByRole/findByText or waitFor and then assert on the returned element.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/ui/dialog/dialog.variants.ts`:
- Around line 4-18: The Tailwind class in dialogContentVariants' base string
uses an invalid token "z-1700"; update the cva base value to use Tailwind's
arbitrary value syntax "z-[1700]" instead (locate the dialogContentVariants
constant and its cva({ base: '...'} ) call and replace z-1700 with z-[1700]).
Ensure the change is applied inside the base string without altering other
classes or variants.
In `@src/components/ui/dialog/DialogTitle.vue`:
- Around line 8-16: The wrapper currently manually extracts props via
defineProps (const { class: customClass = '', ...delegated } =
defineProps<DialogTitleProps & { class?: HTMLAttributes['class'] }>() ) and
binds delegated to <DialogTitle>, which deviates from the Reka pattern; replace
this with the useForwardProps helper to collect and forward props
(useForwardProps<DialogTitleProps>() or the project-specific generic) and use
its returned forwarded props instead of delegated, keep class extraction only
for customClass and pass classes into cn('text-base font-semibold
text-base-foreground', customClass), and apply the same change to
DialogOverlay.vue, DialogDescription.vue, and DialogContent.vue so all dialog
wrappers use useForwardProps for prop forwarding.
---
Nitpick comments:
In `@src/components/dialog/GlobalDialog.test.ts`:
- Around line 48-49: Replace the fragile double "await nextTick()" usage in
GlobalDialog.test.ts with Testing Library async queries: remove the two nextTick
calls (the occurrences currently surrounding the assertions) and use a findBy*
query (e.g., screen.findByRole('dialog') or screen.findByText(...)) or wrap
assertions in waitFor so the test waits for the DOM change reliably; update both
occurrences (around the two nextTick calls at lines shown) to use
screen.findByRole/findByText or waitFor and then assert on the returned element.
In `@src/components/ui/dialog/Dialog.stories.ts`:
- Around line 21-27: Remove the deprecated defaultValue from the argTypes entry
for size: in the Dialog.stories.ts story, locate the argTypes object (the size
property that uses control: { type: 'select' }, options: sizes) and delete the
defaultValue: 'md' key so the story relies on the existing default in args;
leave the control and options intact and ensure args still sets the default
size.
In `@src/components/ui/dialog/DialogDescription.vue`:
- Around line 8-16: The wrapper should forward props using useForwardProps
instead of manually spreading delegated; keep the customClass default from
defineProps but pass the remaining props into useForwardProps so
DialogDescription receives the forwarded props. Locate the defineProps
destructuring (symbols: defineProps, customClass, delegated) and replace the
delegated spread with delegated = useForwardProps(restProps) (or call
useForwardProps on the rest object returned from defineProps) and continue using
:class="cn('text-sm text-muted-foreground', customClass)" when binding to
DialogDescription.
In `@src/components/ui/dialog/DialogOverlay.vue`:
- Around line 8-16: The wrapper currently forwards props via the local delegated
object (const { class: customClass = '', ...delegated } = defineProps(...)) and
uses v-bind="delegated"; change this to use the shared helper by creating a
forwardedProps constant: const forwardedProps = useForwardProps(delegated)
(import/use useForwardProps in the <script setup>), then update the template to
v-bind="forwardedProps" on the <DialogOverlay> (keep :class binding/ customClass
handling as needed). This aligns prop forwarding with useForwardProps while
preserving the existing customClass handling and DialogOverlay usage.
In `@src/components/ui/dialog/DialogPortal.vue`:
- Around line 5-10: Replace the direct v-bind="props" forwarding with the
standardized useForwardProps pattern: import/use useForwardProps, pass the
component props (from defineProps<DialogPortalProps>()) into useForwardProps to
get a forwardProps object, and change the template to v-bind="forwardProps"; if
you need defaults instead of straight forwarding use a computed wrapper around
props before calling useForwardProps. Ensure you reference the existing
defineProps<DialogPortalProps>() and the DialogPortal component when making this
change.
In `@src/stores/dialogStore.ts`:
- Around line 23-28: The new explanatory comment block above the dialog renderer
type is redundant — remove the prose comment so the code relies on
self-documenting type names ('primevue' and 'reka') and existing ADR docs;
specifically delete the multi-line comment that mentions GlobalDialog,
'primevue', 'reka', and the migration note (and any reference to
src/components/ui/dialog/) in src/stores/dialogStore.ts so the type declaration
stands alone and remains clear.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 06c9d703-e98b-4a6f-b6a5-f749bd8083b7
📒 Files selected for processing (14)
src/components/dialog/GlobalDialog.test.tssrc/components/dialog/GlobalDialog.vuesrc/components/ui/dialog/Dialog.stories.tssrc/components/ui/dialog/Dialog.vuesrc/components/ui/dialog/DialogClose.vuesrc/components/ui/dialog/DialogContent.vuesrc/components/ui/dialog/DialogDescription.vuesrc/components/ui/dialog/DialogFooter.vuesrc/components/ui/dialog/DialogHeader.vuesrc/components/ui/dialog/DialogOverlay.vuesrc/components/ui/dialog/DialogPortal.vuesrc/components/ui/dialog/DialogTitle.vuesrc/components/ui/dialog/dialog.variants.tssrc/stores/dialogStore.ts
| export const dialogContentVariants = cva({ | ||
| base: 'data-[state=open]:animate-contentShow fixed top-1/2 left-1/2 z-1700 flex max-h-[85vh] w-[calc(100vw-1rem)] -translate-x-1/2 -translate-y-1/2 flex-col rounded-lg border border-border-subtle bg-base-background shadow-lg outline-none', | ||
| variants: { | ||
| size: { | ||
| sm: 'sm:max-w-sm', | ||
| md: 'sm:max-w-xl', | ||
| lg: 'sm:max-w-3xl', | ||
| xl: 'sm:max-w-5xl', | ||
| full: 'sm:max-w-[calc(100vw-1rem)]' | ||
| } | ||
| }, | ||
| defaultVariants: { | ||
| size: 'md' | ||
| } | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for z-1700 definition in tailwind config or CSS
rg -n 'z-1700|1700' --type=css --type=ts -g '*.config.*' -g 'style.css' -g 'tailwind*'Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Find tailwind config files
find . -name "tailwind.config.*" -o -name "tailwind.*.config.*" 2>/dev/null | head -20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Search for z-index definitions more broadly
rg -i 'z-index|zindex|z:\s*\{' --type=js --type=ts --type=json -g '*config*' -g '*tailwind*' -A 5 | head -100Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Check CSS files for z-1700 or z-index definitions
find . -name "*.css" -o -name "*.scss" | xargs grep -l "1700\|z-1700" 2>/dev/nullRepository: Comfy-Org/ComfyUI_frontend
Length of output: 221
🏁 Script executed:
# Check if tailwind config is in package.json
cat package.json | head -100Repository: Comfy-Org/ComfyUI_frontend
Length of output: 5011
🏁 Script executed:
# Look for postcss config
find . -maxdepth 2 -name "postcss.config.*" -o -name "tailwind.config.*" 2>/dev/nullRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Check the actual file to verify it exists and see full content
cat src/components/ui/dialog/dialog.variants.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 881
🏁 Script executed:
# Find the tailwind-utils package location
find . -type d -name "tailwind-utils" 2>/dev/nullRepository: Comfy-Org/ComfyUI_frontend
Length of output: 96
🏁 Script executed:
# Look for tailwind config in packages directory
find packages -name "tailwind.config.*" 2>/dev/nullRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Search for z-index definitions more broadly
rg -i "z-1700|1700" --type=ts --type=js --type=json -g "packages/*" | head -50Repository: Comfy-Org/ComfyUI_frontend
Length of output: 219
🏁 Script executed:
# Explore tailwind-utils package structure
ls -la packages/tailwind-utils/Repository: Comfy-Org/ComfyUI_frontend
Length of output: 413
🏁 Script executed:
# Find all files in tailwind-utils
find packages/tailwind-utils -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | head -30Repository: Comfy-Org/ComfyUI_frontend
Length of output: 182
🏁 Script executed:
# Search for z-1700 or 1700 in tailwind-utils
rg -i "z-1700|1700" packages/tailwind-utils/Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Search for z-index definitions in tailwind-utils
rg -i "z-index|zindex|z:" packages/tailwind-utils/ -A 3Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Read the tailwind-utils index file
cat packages/tailwind-utils/src/index.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 436
🏁 Script executed:
# Search for any tailwind.config file anywhere in the repo
find . -name "tailwind.config.*" 2>/dev/nullRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
# Check if there's a vite or postcss config with tailwind theme
find . -maxdepth 3 -name "vite.config.*" -o -name "postcss.config.*" 2>/dev/null | grep -v node_modulesRepository: Comfy-Org/ComfyUI_frontend
Length of output: 122
Use z-[1700] with arbitrary value syntax instead of z-1700.
Standard Tailwind z-index utilities only support z-0 through z-50. To use custom z-index values, use the arbitrary value syntax z-[1700]. The current z-1700 class is not a valid Tailwind utility and will be ignored at runtime.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/ui/dialog/dialog.variants.ts` around lines 4 - 18, The
Tailwind class in dialogContentVariants' base string uses an invalid token
"z-1700"; update the cva base value to use Tailwind's arbitrary value syntax
"z-[1700]" instead (locate the dialogContentVariants constant and its cva({
base: '...'} ) call and replace z-1700 with z-[1700]). Ensure the change is
applied inside the base string without altering other classes or variants.
| const { class: customClass = '', ...delegated } = defineProps< | ||
| DialogTitleProps & { class?: HTMLAttributes['class'] } | ||
| >() | ||
| </script> | ||
|
|
||
| <template> | ||
| <DialogTitle | ||
| v-bind="delegated" | ||
| :class="cn('text-base font-semibold text-base-foreground', customClass)" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify forwarding pattern in dialog wrappers
rg -n "useForwardProps|v-bind=\"(delegated|props|restProps|forwarded)\"" src/components/ui/dialog/*.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 544
🏁 Script executed:
# Search for actual useForwardProps usage in codebase
rg "useForwardProps" src/Repository: Comfy-Org/ComfyUI_frontend
Length of output: 2389
🏁 Script executed:
# Check what's being imported from reka-ui across the codebase
rg "from 'reka-ui'" src/ -A 2 | head -100Repository: Comfy-Org/ComfyUI_frontend
Length of output: 6790
🏁 Script executed:
# Look at one of the other UI wrapper components to see the pattern
cat -n src/components/ui/button/Button.vue | head -30Repository: Comfy-Org/ComfyUI_frontend
Length of output: 946
🏁 Script executed:
cat -n src/components/ui/dialog/DialogTitle.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 718
Use useForwardProps for Reka prop forwarding in this wrapper.
This dialog wrapper deviates from the established pattern used across other Reka UI components (ButtonGroup, TagsInput, ToggleGroup, etc.). Align it with the codebase convention.
Proposed refactor
<script setup lang="ts">
import type { DialogTitleProps } from 'reka-ui'
-import { DialogTitle } from 'reka-ui'
+import { DialogTitle, useForwardProps } from 'reka-ui'
import type { HTMLAttributes } from 'vue'
import { cn } from '@comfyorg/tailwind-utils'
-const { class: customClass = '', ...delegated } = defineProps<
+const { class: customClass = '', ...restProps } = defineProps<
DialogTitleProps & { class?: HTMLAttributes['class'] }
>()
+const forwarded = useForwardProps(restProps)
</script>
<template>
<DialogTitle
- v-bind="delegated"
+ v-bind="forwarded"
:class="cn('text-base font-semibold text-base-foreground', customClass)"
>Note: DialogOverlay.vue, DialogDescription.vue, and DialogContent.vue use the same pattern and should be updated similarly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/ui/dialog/DialogTitle.vue` around lines 8 - 16, The wrapper
currently manually extracts props via defineProps (const { class: customClass =
'', ...delegated } = defineProps<DialogTitleProps & { class?:
HTMLAttributes['class'] }>() ) and binds delegated to <DialogTitle>, which
deviates from the Reka pattern; replace this with the useForwardProps helper to
collect and forward props (useForwardProps<DialogTitleProps>() or the
project-specific generic) and use its returned forwarded props instead of
delegated, keep class extraction only for customClass and pass classes into
cn('text-base font-semibold text-base-foreground', customClass), and apply the
same change to DialogOverlay.vue, DialogDescription.vue, and DialogContent.vue
so all dialog wrappers use useForwardProps for prop forwarding.
|
Phase 0 looks clean, the opt-in branch is well-scoped and the PrimeVue path is genuinely unchanged, so no concerns there. The thing I want to flag explicitly now, before Phase 1 lands, is that the public behavioral contract of The minimum behavioral contract that must hold after Phase 1 migrates // This pattern is already live in third-party extensions and must keep working:
const confirmed = await app.extensionManager.dialog.confirm({
title: "Delete pose?",
message: "This cannot be undone.",
});
// confirmed must be boolean-like (true = OK, false/null = cancel/escape)
const name = await app.extensionManager.dialog.prompt({
title: "Save pose",
message: "Enter a name:",
defaultValue: "my_pose",
});
// name must be a non-empty string on confirm, or null on cancel/escape
// it must NEVER leave the caller's await hanging (unresolved promise)Specifically: if the user dismisses via Escape, clicking the overlay, or the close button, the Promise must resolve (to |
Summary
Lands the renderer infrastructure for migrating ComfyUI Frontend's central dialog system from PrimeVue to Reka-UI. Phase 0 of a phased migration. No production dialog migrates in this PR — every existing dialog continues to render through PrimeVue exactly as before.
Motivation
GitHub issue #11688 surfaced a PrimeVue Dialog
max-widthdesign limitation that is awkward to address through PrimeVue's pass-through styling. ADR 0004 (Rejected, 2025-08-27) explicitly endorses selective component replacement with shadcn/Reka-UI as the path forward for problematic PrimeVue components, andAGENTS.mdalready directs contributors to "Avoid new usage of PrimeVue components." The dialog system is a strong first candidate: clean public API boundary (useDialogService/dialogStore), bounded surface (~12 dialogs), and Reka-UI is already in use elsewhere in the codebase. The #11688 fix arrives naturally in Phase 1 onceprompt/confirmmigrate to the new primitive'smddefault (max-width: 36rem).Phased migration plan
This PR is Phase 0 only. Each subsequent phase is shipped as its own PR.
src/components/ui/dialog/+ opt-in renderer branch inGlobalDialog.vue+ tests + StorybookPromptDialogContent+ConfirmationDialogContent; closes #11688ErrorDialogContent,NodeSearchBox(Popover),SecretFormDialog,VideoHelpDialog,CustomizationDialogConfirmDialogcallers (SecretsPanel,BaseWorkflowsSidebarTab)Full plan in
temp/plans/dialog-migration-phase-0.mdand ADR draft attemp/plans/adr-0009-dialog-reka-migration-DRAFT.md(will move todocs/adr/after team review).Changes
src/components/ui/dialog/wrapping Reka-UI'sDialog*components:Dialog,DialogPortal,DialogOverlay,DialogContent,DialogHeader,DialogFooter,DialogTitle,DialogDescription,DialogClose. Variants viacvawith sizessm | md | lg | xl | full.dialogStore.CustomDialogComponentPropsgains opt-inrenderer?: 'primevue' | 'reka'(default'primevue') andsize?: 'sm' | 'md' | 'lg' | 'xl' | 'full'.GlobalDialog.vuebranches the per-stack-item template based on therendererflag. PrimeVue path is byte-identical to before.Default,LongContent,Headless,AllSizes.primevueand no production dialog opts in.Review Focus
useDialogService/dialogStorepublic API is unchanged. Custom-node extensions callingapp.extensionManager.dialog.*continue to work.GlobalDialog.vue—escape-key-down/pointer-down-outsidemap tocloseOnEscape/dismissableMask;mousedowncallsdialogStore.riseDialogto mirror the PrimeVue PT-based behavior.mdsize = 36rem max-width (chosen to resolve Native ComfyUI prompt dialogs should have a max-width set #11688 in Phase 1);full=calc(100vw - 1rem)escape hatch for Settings/Manager later.renderer: 'reka'in this PR.Quality gates
pnpm typecheck— cleanpnpm lint— clean (1 pre-existing warning unrelated to this PR)pnpm test:unit— 48 dialog-adjacent tests pass including 3 new tests inGlobalDialog.test.tspnpm format— appliedknip pre-push noise (unused deps in workspace packages, unused
types.gen.ts) is pre-existing onmainand not introduced by this PR.Out of scope (deferred)
ComfyDialog(src/scripts/ui/dialog.ts) — separate cleanupDialogue.vue/ImageLightbox.vueagainst the new primitives — separate cleanupRefs #11688
┆Issue is synchronized with this Notion page by Unito