Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02a046321f | ||
|
|
6a5a8d318e | ||
|
|
a19e5f4500 | ||
|
|
c43bff0488 |
@@ -1,3 +1,17 @@
|
||||
## 🎉 Wildcard Pipeline 2.3.1
|
||||
|
||||
📖 [Docs (wiki)](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/wiki) · 💬 [Discord](https://discord.gg/BFYR9WQdVR) · 📦 [Install via ComfyUI Manager](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/wiki/Quick-Start) · 🐛 [Issues](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/issues)
|
||||
|
||||
<details>
|
||||
<summary><b>📋 Full changelog</b> — click to expand the per-commit list</summary>
|
||||
|
||||
|
||||
* Merge pull request #3 from DumiFlex/fix/instance-modal-scroll ([6a5a8d3](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/commit/6a5a8d3)), closes [#3](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/issues/3)
|
||||
* Merge remote-tracking branch 'origin/main' into fix/instance-modal-scroll ([a19e5f4](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/commit/a19e5f4))
|
||||
* fix(extension): scroll instance edit modals with pinned header + footer ([c43bff0](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/commit/c43bff0))
|
||||
|
||||
</details>
|
||||
|
||||
## 🎉 Wildcard Pipeline 2.3.0
|
||||
|
||||
📖 [Docs (wiki)](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/wiki) · 💬 [Discord](https://discord.gg/BFYR9WQdVR) · 📦 [Install via ComfyUI Manager](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/wiki/Quick-Start) · 🐛 [Issues](https://github.com/DumiFlex/ComfyUI-Wildcard-Pipeline/issues)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "comfyui-wildcard-pipeline",
|
||||
"version": "2.3.0",
|
||||
"version": "2.3.1",
|
||||
"private": true,
|
||||
"description": "Modular procedural prompt generation for ComfyUI",
|
||||
"author": "DumiFlex",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "comfyui-wildcard-pipeline"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
description = "Modular procedural prompt generation for ComfyUI — wildcards, constraints, derivations, and context pipelines."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
@@ -157,13 +157,14 @@ const ENTRY_LIMIT = 30 * 1024; // 30 KB
|
||||
// parity test) now; the upcoming reach/constraint-matrix UI phases need the
|
||||
// total budget headroom in the lazy ContextWidget chunk. Approved alongside
|
||||
// the SP3 constraint feature.
|
||||
// Bumped 430 -> 431 KB on 2026-06-18 for the editor robustness pass:
|
||||
// RichTextInput's scoped renderEpoch rebuild (nested-ref picker crash fix)
|
||||
// + useEditorDraft flush-on-unmount/unload + ErrorBoundary copy, plus the
|
||||
// clipboard-shield wired into _shared.ts + main.ts (Ctrl-A/C/V/X guard on
|
||||
// editable widget inputs). ~0.3 KB net gzip across the extension entry +
|
||||
// shared chunks. Landed on the bulk-editor branch (the bulk UI itself is
|
||||
// manager-only and adds nothing to js/).
|
||||
// Bumped 430 -> 431 KB on 2026-06-18 — two same-day landings share the
|
||||
// ceiling (both CSS/glue; the manager-only bulk UI adds nothing to js/):
|
||||
// - editor robustness: RichTextInput renderEpoch crash fix + useEditorDraft
|
||||
// flush-on-unmount/unload + ErrorBoundary copy + clipboard-shield wired
|
||||
// into _shared.ts / main.ts (Ctrl-A/C/V/X guard on editable inputs).
|
||||
// - instance-modal scroll/sticky: sticky header + runtime/footer dock +
|
||||
// own-scrollbar inner lists (options/values/rules/exceptions) + compact
|
||||
// exceptions trash, across all 6 edit modals.
|
||||
const TOTAL_LIMIT = 431 * 1024; // 431 KB
|
||||
|
||||
function gzipSize(path) {
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
.wp-wcm__head { --modal-accent: var(--wp-kind-wildcard); }
|
||||
|
||||
.wp-cbm__head, .wp-cnm__head, .wp-dvm__head, .wp-fvm__head, .wp-wcm__head {
|
||||
/* Pinned to the top of the scrolling modal body so the title + close
|
||||
* stay visible while the content scrolls. Opaque (gradient bottoms out
|
||||
* at --wp-bg2) so scrolled content doesn't bleed through. */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
@@ -102,6 +102,7 @@ const headerName = computed(() => props.bundle.name || props.libraryName || "Bun
|
||||
:library-color="libraryColor"
|
||||
@update="(patch) => emit('update', patch)"
|
||||
/>
|
||||
<div class="wp-bdm__dock">
|
||||
<RuntimeSection
|
||||
:lock-state="lockState"
|
||||
:internal-state="internalState"
|
||||
@@ -157,12 +158,13 @@ const headerName = computed(() => props.bundle.name || props.libraryName || "Bun
|
||||
Save
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.wp-bdm { background: var(--wp-bg2); border: 1px solid var(--wp-border); border-radius: var(--wp-radius); width: 720px; max-width: 100%; max-height: 80vh; display: flex; flex-direction: column; overflow: hidden; font-family: var(--wp-font-sans, sans-serif); font-size: 12px; color: var(--wp-text); }
|
||||
.wp-bdm__head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: linear-gradient(180deg, color-mix(in srgb, var(--modal-accent, var(--wp-accent)) 18%, var(--wp-bg2)) 0%, var(--wp-bg2) 100%); border-bottom: 1px solid var(--wp-border); }
|
||||
.wp-bdm { background: var(--wp-bg2); border: 1px solid var(--wp-border); border-radius: var(--wp-radius); width: 720px; max-width: 100%; max-height: 80vh; display: flex; flex-direction: column; overflow-y: auto; font-family: var(--wp-font-sans, sans-serif); font-size: 12px; color: var(--wp-text); }
|
||||
.wp-bdm__head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 10px; padding: 12px 14px; background: linear-gradient(180deg, color-mix(in srgb, var(--modal-accent, var(--wp-accent)) 18%, var(--wp-bg2)) 0%, var(--wp-bg2) 100%); border-bottom: 1px solid var(--wp-border); }
|
||||
.wp-bdm__head-icon { color: var(--modal-accent, var(--wp-accent)); font-size: 18px; width: 24px; text-align: center; }
|
||||
.wp-bdm__title-block { flex: 1; min-width: 0; }
|
||||
.wp-bdm__title-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
@@ -175,6 +177,7 @@ const headerName = computed(() => props.bundle.name || props.libraryName || "Bun
|
||||
.wp-bdm__close { background: transparent; border: 0; color: var(--wp-text-dim, var(--wp-text3)); cursor: pointer; padding: 4px; }
|
||||
.wp-bdm__close:hover { color: var(--wp-text); }
|
||||
.wp-bdm__close .pi { font-size: 12px; }
|
||||
.wp-bdm__dock { position: sticky; bottom: 0; z-index: 2; background: var(--wp-bg2); }
|
||||
.wp-bdm__foot { display: flex; align-items: center; gap: 12px; padding: 10px 14px; background: var(--wp-bg3); border-top: 1px solid var(--wp-border); }
|
||||
.wp-bdm__spa-link { display: inline-flex; align-items: center; gap: 5px; font: 10px var(--wp-font-sans); color: var(--wp-text-muted, var(--wp-text2)); text-decoration: none; }
|
||||
.wp-bdm__spa-link:hover { color: var(--wp-accent-text, var(--wp-text)); }
|
||||
|
||||
@@ -109,6 +109,7 @@ function onSpaClick(): void {
|
||||
:sibling-vars="siblingVars"
|
||||
@update="onUpdate"
|
||||
/>
|
||||
<div class="wp-cbm__dock">
|
||||
<RuntimeSection :module="module" @update="onUpdate" />
|
||||
|
||||
<footer class="wp-cbm__foot">
|
||||
@@ -147,6 +148,7 @@ function onSpaClick(): void {
|
||||
<button type="button" class="wp-cbm__btn" data-test="cbm-cancel" @click="emit('cancel')">Cancel</button>
|
||||
<button type="button" class="wp-cbm__btn wp-cbm__btn--primary" data-test="cbm-save" @click="emit('save')">Save</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -160,7 +162,7 @@ function onSpaClick(): void {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: var(--wp-font-sans, sans-serif);
|
||||
font-size: 12px;
|
||||
color: var(--wp-text);
|
||||
@@ -168,6 +170,12 @@ function onSpaClick(): void {
|
||||
/* Head styling lives in src/components/context/editors/_modal-head.css
|
||||
* (imported once by ContextWidget). Every modal in this family shares
|
||||
* the same accent-tinted gradient + chip + close button. */
|
||||
.wp-cbm__dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--wp-bg2);
|
||||
}
|
||||
.wp-cbm__foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -691,14 +691,6 @@ function onSpaClick(): void {
|
||||
:stranded="hasDangling"
|
||||
@update="onUpdate"
|
||||
/>
|
||||
<TargetReachSection
|
||||
:model-value="targetSelect"
|
||||
:chain-modules="chainModules"
|
||||
:constraint-uid="constraintUid"
|
||||
:target-wildcard-id="targetWildcardId"
|
||||
:target-name="targetName"
|
||||
@update:model-value="onTargetSelect"
|
||||
/>
|
||||
<ExceptionsSection
|
||||
:module="module"
|
||||
:source-values="sourceValues"
|
||||
@@ -712,6 +704,15 @@ function onSpaClick(): void {
|
||||
@update="onUpdate"
|
||||
/>
|
||||
|
||||
<div class="wp-cnm__dock">
|
||||
<TargetReachSection
|
||||
:model-value="targetSelect"
|
||||
:chain-modules="chainModules"
|
||||
:constraint-uid="constraintUid"
|
||||
:target-wildcard-id="targetWildcardId"
|
||||
:target-name="targetName"
|
||||
@update:model-value="onTargetSelect"
|
||||
/>
|
||||
<footer class="wp-cnm__foot">
|
||||
<a
|
||||
v-if="isLibraryTracked"
|
||||
@@ -748,6 +749,7 @@ function onSpaClick(): void {
|
||||
<button type="button" class="wp-cnm__btn" data-test="cnm-cancel" @click="emit('cancel')">Cancel</button>
|
||||
<button type="button" class="wp-cnm__btn wp-cnm__btn--primary" data-test="cnm-save" @click="emit('save')">Save</button>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- Feature 2: confirm pulling the missing dependency (+ its closure)
|
||||
from the community before any network/install side effect. -->
|
||||
@@ -772,13 +774,19 @@ function onSpaClick(): void {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: var(--wp-font-sans, sans-serif);
|
||||
font-size: 12px;
|
||||
color: var(--wp-text);
|
||||
}
|
||||
/* Head styling lives in src/components/context/editors/_modal-head.css
|
||||
* (imported once by ContextWidget). */
|
||||
.wp-cnm__dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--wp-bg2);
|
||||
}
|
||||
.wp-cnm__foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -304,6 +304,7 @@ function bumpExtraFactor(idx: number, dir: 1 | -1): void {
|
||||
<section class="ex" data-test="ex-section">
|
||||
<div class="ex__label">Exceptions</div>
|
||||
|
||||
<div class="ex__list">
|
||||
<div
|
||||
v-for="(exc, i) in libraryExceptions"
|
||||
:key="libKey(exc)"
|
||||
@@ -551,6 +552,7 @@ function bumpExtraFactor(idx: number, dir: 1 | -1): void {
|
||||
><i class="pi pi-trash" /></button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
v-if="!stranded"
|
||||
@@ -581,11 +583,18 @@ function bumpExtraFactor(idx: number, dir: 1 | -1): void {
|
||||
color: var(--wp-text-dim, var(--wp-text3));
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ex__list {
|
||||
/* Long exception lists scroll in place; the label + add button stay put. */
|
||||
max-height: 34vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.ex__row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px 0;
|
||||
/* right padding keeps the trash off the section edge + the list
|
||||
* scrollbar when the exceptions list scrolls. */
|
||||
padding: 4px 8px 4px 0;
|
||||
font: 11px var(--wp-font-mono);
|
||||
border-bottom: 1px dashed var(--wp-border-soft, var(--wp-border));
|
||||
}
|
||||
@@ -801,17 +810,17 @@ function bumpExtraFactor(idx: number, dir: 1 | -1): void {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
background: color-mix(in srgb, var(--wp-text) 3%, transparent);
|
||||
border: 1px solid var(--wp-border);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
color: var(--wp-text-dim, var(--wp-text3));
|
||||
cursor: pointer;
|
||||
font-size: 11px;
|
||||
flex-shrink: 0;
|
||||
transition: background 0.12s, border-color 0.12s, color 0.12s;
|
||||
transition: background 0.12s, color 0.12s;
|
||||
}
|
||||
.ex__trash:hover {
|
||||
background: color-mix(in srgb, var(--wp-danger, #e05252) 18%, transparent);
|
||||
|
||||
@@ -160,6 +160,7 @@ function onSpaClick(): void {
|
||||
:via-option-pairs="viaOptionPairs"
|
||||
@update="onUpdate"
|
||||
/>
|
||||
<div class="wp-dvm__dock">
|
||||
<RuntimeSection :module="module" @update="onUpdate" />
|
||||
|
||||
<footer class="wp-dvm__foot">
|
||||
@@ -198,6 +199,7 @@ function onSpaClick(): void {
|
||||
<button type="button" class="wp-dvm__btn" data-test="dvm-cancel" @click="emit('cancel')">Cancel</button>
|
||||
<button type="button" class="wp-dvm__btn wp-dvm__btn--primary" data-test="dvm-save" @click="emit('save')">Save</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -211,13 +213,19 @@ function onSpaClick(): void {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: var(--wp-font-sans, sans-serif);
|
||||
font-size: 12px;
|
||||
color: var(--wp-text);
|
||||
}
|
||||
/* Head styling lives in src/components/context/editors/_modal-head.css
|
||||
* (imported once by ContextWidget). */
|
||||
.wp-dvm__dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--wp-bg2);
|
||||
}
|
||||
.wp-dvm__foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -693,6 +693,9 @@ function opUsesValue(op: string | undefined): boolean {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
/* Long rule lists scroll in place so identity / footer stay visible. */
|
||||
max-height: 44vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Rule card */
|
||||
|
||||
@@ -66,6 +66,7 @@ function onSpaClick(): void {
|
||||
|
||||
<IdentitySection :module="module" @update="onUpdate" />
|
||||
<ValuesSection :module="module" @update="onUpdate" />
|
||||
<div class="wp-fvm__dock">
|
||||
<RuntimeSection :module="module" @update="onUpdate" />
|
||||
|
||||
<footer class="wp-fvm__foot">
|
||||
@@ -105,6 +106,7 @@ function onSpaClick(): void {
|
||||
<button type="button" class="wp-fvm__btn" data-test="fvm-cancel" @click="emit('cancel')">Cancel</button>
|
||||
<button type="button" class="wp-fvm__btn wp-fvm__btn--primary" data-test="fvm-save" @click="emit('save')">Save</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -118,13 +120,19 @@ function onSpaClick(): void {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: var(--wp-font-sans, sans-serif);
|
||||
font-size: 12px;
|
||||
color: var(--wp-text);
|
||||
}
|
||||
/* Head styling lives in src/components/context/editors/_modal-head.css
|
||||
* (imported once by ContextWidget). */
|
||||
.wp-fvm__dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--wp-bg2);
|
||||
}
|
||||
.wp-fvm__foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -183,9 +183,14 @@ const addedCount = computed(() => draftRows.value.filter((r) => r.libraryId ===
|
||||
background: var(--wp-bg-deep, var(--wp-bg));
|
||||
border: 1px solid var(--wp-border);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
/* Long value lists scroll in place; the header row stays pinned. */
|
||||
max-height: 42vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.vals__head {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 22px 180px 1fr 28px 28px;
|
||||
gap: 10px;
|
||||
|
||||
@@ -101,6 +101,7 @@ function onSpaClick(): void {
|
||||
@update="onUpdate"
|
||||
/>
|
||||
<PoolSection :module="module" :via-option-pairs="viaOptionPairs" @update="onUpdate" />
|
||||
<div class="wp-wcm__dock">
|
||||
<RuntimeSection :module="module" @update="onUpdate" />
|
||||
|
||||
<footer class="wp-wcm__foot">
|
||||
@@ -150,6 +151,7 @@ function onSpaClick(): void {
|
||||
Save
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -163,7 +165,7 @@ function onSpaClick(): void {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: var(--wp-font-sans, sans-serif);
|
||||
font-size: 12px;
|
||||
color: var(--wp-text);
|
||||
@@ -171,6 +173,12 @@ function onSpaClick(): void {
|
||||
/* Head styling lives in src/components/context/editors/_modal-head.css
|
||||
* (imported once by ContextWidget). Adopted from InjectorBindingModal
|
||||
* so every per-instance edit modal reads as one design family. */
|
||||
.wp-wcm__dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
background: var(--wp-bg2);
|
||||
}
|
||||
.wp-wcm__foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -903,9 +903,15 @@ const skewedTowards = computed(() => {
|
||||
background: var(--wp-bg-deep, var(--wp-bg));
|
||||
border: 1px solid var(--wp-border);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
/* Long option lists scroll in place so the axes / pick / footer stay
|
||||
* visible; the column-header row below stays pinned via sticky. */
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.pool__opt-head {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
/* Match OptionRow column widths so cell alignment stays in lockstep. */
|
||||
grid-template-columns: 22px 1fr 110px 64px 96px;
|
||||
|
||||
Reference in New Issue
Block a user