softr-vibe-coding 1.11.0 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/package.json +1 -1
- package/references/native-block-filters.md +24 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,9 @@ All notable changes to this skill are documented here. Versions follow [Semantic
|
|
|
4
4
|
|
|
5
5
|
Entries from 1.3.1 onward are generated automatically from git commit subjects between version bumps (see `.github/workflows/publish.yml`). Entries before 1.3.1 were backfilled by hand from the existing commit history.
|
|
6
6
|
|
|
7
|
+
## [1.11.1] - 2026-06-12
|
|
8
|
+
- Document the tabbed-list visibility gotcha in native-block-filters.md — Softr renders tabs with Radix and keeps the INACTIVE tab's blocks in the DOM (display:none, not unmounted), so a data-block-id lookup on a tabbed page matches BOTH tabs' lists; injecting a custom control into the hidden one makes it 'disappear' on tab switch. Add §4d: require the matched block to be visible (offsetParent !== null) and home into whichever tab is active so one control follows all tabs (each tab-list keeps its own conditional filter; ~250ms interval for snappier flips), plus a Gotchas bullet. Bump to 1.11.1
|
|
9
|
+
|
|
7
10
|
## [1.11.0] - 2026-06-12
|
|
8
11
|
- Add references/native-block-filters.md — dynamic date / URL-param filters and custom filter controls on native Softr List/Grid blocks. Covers driving a native block's conditional filter from a Custom Code Static block via {URL_PARAM:…}, the empty-param 'match nothing' wide-range sentinel that otherwise empties the list on load, injecting the control into the block's filter row scoped by data-block-id (a page-wide text search wrongly matches the nav 'Clients' link), resolving the row by filter-label-text + lowest-common-ancestor instead of hashed chip classes, and the key gotcha that Softr re-renders its List/Grid block and discards injected nodes so the control must be re-homed on a short interval rather than relocated once. Includes a full worked date-range picker (wide-range sentinel + wait-for-both + Clear + relocation + re-render survival) and a DevTools how-to for finding data-block-id and the filter row. Wire into the SKILL.md reference table and README structure listing; bump to 1.11.0
|
|
9
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "softr-vibe-coding",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "Claude Code skill for generating production-ready Softr Vibe Coding blocks (JSX). Installs into ~/.claude/skills/ and auto-updates on each Claude Code session.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"softr-vibe-coding": "./bin/cli.js"
|
|
@@ -172,6 +172,29 @@ setInterval(ensureHomed, 500); // and re-home after every Softr re-render
|
|
|
172
172
|
|
|
173
173
|
`ensureHomed` is idempotent (it only re-appends when the control is *not* already in the row), so the interval is cheap and can't loop.
|
|
174
174
|
|
|
175
|
+
### 4d. Tabbed pages — home into the VISIBLE tab's list ⚠️
|
|
176
|
+
**Softr renders tabs with Radix, and the *inactive* tab's blocks stay in the DOM — just `display:none`, not unmounted.** So on a tabbed page (e.g. a worker "Pending / All" view) *both* tabs' list blocks match a `data-block-id` lookup. Grab the hidden one and your control gets injected into the invisible panel — it looks like it "vanished" the moment the user switches tabs.
|
|
177
|
+
|
|
178
|
+
Two rules:
|
|
179
|
+
1. **Require the matched block to be visible** — `el.offsetParent !== null` (it's `null` when the element or an ancestor tab panel is `display:none`). Skip hidden matches.
|
|
180
|
+
2. **One control can serve every tab** — list all the tab-lists' block-ids and home into whichever is visible; the re-home interval then makes the control *follow the active tab*.
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
// Both tab lists. Softr keeps the INACTIVE tab's list in the DOM (hidden), so an id-only
|
|
184
|
+
// match could grab the wrong one — only the VISIBLE tab's block should win.
|
|
185
|
+
var LIST_BLOCK_IDS = ["<pending-tab-list-id>", "<all-tab-list-id>"];
|
|
186
|
+
|
|
187
|
+
function activeListBlock() {
|
|
188
|
+
for (var i = 0; i < LIST_BLOCK_IDS.length; i++) {
|
|
189
|
+
var el = document.querySelector('[data-block-id="' + LIST_BLOCK_IDS[i] + '"]');
|
|
190
|
+
if (el && el.offsetParent !== null) return el; // offsetParent === null → in a hidden tab
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Use `activeListBlock()` in place of the single-id lookup inside `findFilterRow()`. Each tab-list still needs its OWN copy of the conditional filter (the control only sets the URL params; every list reads them independently). A ~250ms interval feels snappier than 500ms when the user flips tabs.
|
|
197
|
+
|
|
175
198
|
---
|
|
176
199
|
|
|
177
200
|
## 5. Full worked example — date-range picker that joins the filter row
|
|
@@ -280,6 +303,7 @@ A complete Custom Code Static block: range picker with the wide-range sentinel,
|
|
|
280
303
|
|
|
281
304
|
- **Empty `{URL_PARAM}` = match NOTHING.** A blank/missing param empties a filtered list. Seed a wide sentinel range (and map it back to blank inputs) so "no selection" shows all. §2.
|
|
282
305
|
- **Softr re-renders its list block and discards injected nodes.** One-shot relocation vanishes on the first interaction. Re-home on an interval/observer. §4c.
|
|
306
|
+
- **Tabbed pages keep the inactive tab's list in the DOM (`display:none`).** A `data-block-id` match can grab the hidden tab's copy → the injected control "disappears" on tab switch. Require `offsetParent !== null` and home into the visible list; one control can follow all tabs. §4d.
|
|
283
307
|
- **Page-wide DOM searches hit the native chrome.** Matching by text "Client" also matches a "Clients" nav link → control lands in the sidebar. Always scope to the block's `data-block-id`. §4a.
|
|
284
308
|
- **Filter chips have only hashed classes** (`a0e85ef_…`) that change on deploys. Anchor on your **filter label text + lowest common ancestor**; keep the hash as a fallback only. §4b.
|
|
285
309
|
- **`window.location.reload()` is how Softr re-reads the param.** `replaceState` alone updates the URL but won't re-run the conditional filter — you must reload.
|