docs: enhance widget documentation with playground examples and JSON structures#474
docs: enhance widget documentation with playground examples and JSON structures#474divyanshub024 merged 6 commits intodevfrom
Conversation
…structures - Added playground examples and JSON structures for various widgets including AlertDialog, Align, AppBar, AspectRatio, AutoComplete, BackdropFilter, Badge, BottomNavigationBar, Card, CarouselView, Center, CheckBox, Chip, CircleAvatar, CircularProgressIndicator, ClipOval, ClipRRect, and ColoredBox. - Updated documentation format to include tabs for Dart code, JSON representation, and live preview.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughReplaced many widget examples’ single CodeGroup with Tabs (Dart / JSON / Preview), added PLAYGROUND_BASE_URL, and for each widget exported Changes
Sequence Diagram(s)sequenceDiagram
participant Docs as Docs Page (MDX)
participant Iframe as Playground Iframe
participant Playground as Playground Origin
rect rgba(160,220,255,0.5)
Docs->>Iframe: render <iframe src="{PLAYGROUND_BASE_URL}/embed">
Iframe-->>Docs: load event
loop up to 12 attempts (250ms)
Docs->>Iframe.contentWindow: postMessage({type:"stac-preview-json", payload: PREVIEW_JSON}, targetOrigin=PLAYGROUND_BASE_URL)
Iframe->>Playground: receive postMessage → apply preview
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 10
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (7)
docs/widgets/switch.mdx (1)
50-120:⚠️ Potential issue | 🟡 MinorInconsistent: only Example 1 was migrated to Tabs/Preview.
Example 1 (Cupertino) now uses
<Tabs>+ Preview, but Example 2 (Adaptive, line 105) and Example 3 (Material, line 124) still use the old<CodeGroup>. The page reads as half-migrated. Either:
- Convert Examples 2 and 3 to the same
Tabslayout (each will need its own*PreviewJson/*PreviewSrcexports or — better — a shared component that takespreviewJsonas a prop), or- Defer the migration so all three examples switch together.
Also worth noting: Example 2 and 3 don't really need their own iframe
srcconstants — only the JSON differs — which is another argument for extracting a shared<PlaygroundPreview json={...} />component before scaling this pattern.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/switch.mdx` around lines 50 - 120, The page is half-migrated: Example 1 uses <Tabs> with a Preview while Example 2 ("Adaptive") and Example 3 ("Material") still use <CodeGroup>; unify them by replacing the CodeGroup blocks for the adaptive and material examples with the same Tabs/Preview pattern (Tab titles "Dart", "JSON", "Preview") and wire their iframe messaging the same way as the first example (see switchPreviewSrc and switchPreviewJson usage around the iframe id="stac"), or roll Example 1 back to CodeGroup if you prefer deferring the migration. Preferably extract a small shared PlaygroundPreview component (props: previewJson, previewSrc) that encapsulates the iframe, onLoad postMessage loop and constants (attempts/maxAttempts) and reuse it in the three examples to pass different JSON payloads (adaptive/material/cupertino) so only the JSON differs between previews.docs/widgets/image.mdx (1)
101-181:⚠️ Potential issue | 🟡 MinorInconsistent: only the
StacImage.assetsection was converted to Tabs/Preview.The remaining sections —
StacImage.network(line 107),StacImage.file(line 135), and the defaultStacImage(line 161) — still use the old<CodeGroup>. This leaves the page with a mixed look-and-feel and means three of four constructors have no preview. Either convert the rest to the newTabslayout (network is a particularly good candidate for an actually-working preview) or drop the partial migration to keep the page consistent for now.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/image.mdx` around lines 101 - 181, The page is inconsistent: only StacImage.asset was migrated to the new Tabs/Preview pattern while StacImage.network, StacImage.file, and the default StacImage still use <CodeGroup>; either convert those three <CodeGroup> sections to the same Tabs + Preview structure used by StacImage.asset (preserving the Dart and JSON examples and adding a live preview for network using a stable URL) or revert the asset section back to <CodeGroup> so all constructors match; update the StacImage.network, StacImage.file, and StacImage (default) sections accordingly and ensure the preview uses the same component names and props as in the asset example.docs/widgets/alert_dialog.mdx (1)
100-128:⚠️ Potential issue | 🟡 MinorFix JSON key name for text alignment to match Dart property.
Line 147 uses
"align": "center"but the StacText parser expects"textAlign"(matching the Dart property at line 111). Update the JSON to use"textAlign": "center"so the documented JSON example renders identically to the Dart example.Incorrect JSON at line 147
"align": "center",Should be:
"textAlign": "center",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/alert_dialog.mdx` around lines 100 - 128, The JSON example uses the wrong key "align" for text alignment; update the JSON to use "textAlign" so it matches the Dart property and the StacText parser expectations (ensure the JSON example that corresponds to the StacText widget uses "textAlign": "center" instead of "align": "center").docs/widgets/spacer.mdx (1)
18-20:⚠️ Potential issue | 🟡 MinorBroken Properties table — stray
choretoken in the separator row.The separator row contains
|--chore-----|, which breaks the markdown table rendering for the Type column. This looks like a stray edit/merge artifact.🛠️ Proposed fix
| Property | Type | Description | -|----------|--chore-----|---------------------------------------------------------| +|----------|-------|---------------------------------------------------------| | flex | `int` | The flex factor to use for the spacer. Defaults to `1`. |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/spacer.mdx` around lines 18 - 20, The markdown table's separator row contains a stray token `chore` which breaks rendering; locate the table with header "Property | Type | Description" and the separator row containing "`|--chore-----|`" and replace it with a proper Markdown separator (e.g., "`|---|---|---|`" or matching dashes for three columns) so the "flex" property row (`flex | \`int\` | The flex factor...`) renders correctly.docs/widgets/divider.mdx (1)
88-148:⚠️ Potential issue | 🟡 MinorInconsistent: second example still uses the old
<CodeGroup>with no Preview tab.The top-level example was migrated to the new
Tabs+Previewlayout, but the "Divider in a List" section below still uses the legacy<CodeGroup>pattern and has no playground preview. Readers will see an inconsistent experience on the same page. Either migrate this section to the tabbed layout with its owndividerInListPreviewJson, or intentionally keep it as code-only and add a short note explaining why.Same inconsistency exists in
docs/widgets/limited_box.mdxfor "Example 2".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/divider.mdx` around lines 88 - 148, The "Divider in a List" section still uses the legacy <CodeGroup> and lacks a Preview tab, causing inconsistency with other examples that use the new Tabs+Preview pattern; update this section (the block showing StacColumn/StacListTile/StacDivider) to the tabbed layout by replacing <CodeGroup> with the Tabs + Preview structure and add a matching preview JSON entry (e.g., dividerInListPreviewJson) so the example renders in the playground, or alternatively keep the CodeGroup but add a short explanatory note; also apply the same migration or explanatory-note change to the "Example 2" in docs/widgets/limited_box.mdx to keep both pages consistent.docs/widgets/visibility.mdx (1)
97-124:⚠️ Potential issue | 🟡 MinorExample 2 was not converted — inconsistent with Example 1.
Example 1 ("Basic Visibility") was migrated to the new
<Tabs>layout with a Preview tab, but Example 2 ("Hidden with Replacement") is still using the old<CodeGroup>block and has no Preview. Readers will see two examples with different UX in the same page, and the more interesting case (visible: falsewith areplacement) loses its live demo.🔧 Suggested approach
Add a
visibilityHiddenPreviewJsonexport alongside the existing one, then convert Example 2 to the same Tabs/Preview structure (re-usingPLAYGROUND_BASE_URLalready declared at the top):export const visibilityPreviewSrc = `${PLAYGROUND_BASE_URL}/embed?showTopBar=false&showEditor=false`; +export const visibilityHiddenPreviewJson = { + "type": "visibility", + "child": { "type": "text", "data": "I am hidden!" }, + "replacement": { "type": "container", "color": "#FF5733", "width": 50, "height": 50 }, + "visible": false +};…then replace the
<CodeGroup>at lines 99–124 with the same<Tabs>/<Tab title="Preview">pattern used in Example 1, passingvisibilityHiddenPreviewJsonas the payload.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/visibility.mdx` around lines 97 - 124, Add a new export named visibilityHiddenPreviewJson (next to the existing preview JSON export) containing the Example 2 JSON payload, then replace the <CodeGroup> block for "Hidden with Replacement" with the same <Tabs>/<Tab title="Preview"> pattern used in Example 1 and wire the Preview to the playground using PLAYGROUND_BASE_URL and visibilityHiddenPreviewJson as the payload; ensure the StacVisibility example keeps the replacement (StacContainer) and visible:false fields in the exported payload so the live demo shows the hidden-with-replacement behavior.docs/widgets/badge.mdx (1)
46-271:⚠️ Potential issue | 🟡 MinorInconsistent: only the first Badge example gets a Preview tab; the other five still use
<CodeGroup>.Within the same page, "Basic Badge with Label" (lines 46–111) is now
<Tabs>with a Preview tab, while the remaining five examples — "Badge with Count", "Badge with Count Exceeding MaxCount", "Small Badge (No Label)", "Badge on IconButton", and "Badge with Custom Styling" (lines 112–271) — still use<CodeGroup>and have no preview. This is jarring UX-wise and hides the visually most interesting variants (count overflow, custom styling, badge on icon button) from the live preview.Either convert the remaining examples to the same Tabs/Preview structure (ideally via the shared component suggested on
docs/widgets/padding.mdx), or — if intentional for this PR's scope — add a brief note here and a follow-up issue to cover the rest.Want me to draft the converted markup for the remaining four examples, or open a follow-up issue?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/badge.mdx` around lines 46 - 271, The page is inconsistent: "Basic Badge with Label" uses a Tabs/Preview setup while the other examples ("Badge with Count", "Badge with Count Exceeding MaxCount", "Small Badge (No Label)", "Badge on IconButton", "Badge with Custom Styling") remain as CodeGroup; update those examples to the same Tabs (Dart/JSON/Preview) pattern used in the "Basic Badge with Label" example by replacing each <CodeGroup> block with a <Tabs sync={false}> containing <Tab title="Dart"> (the Dart snippet), <Tab title="JSON"> (the JSON snippet) and a <Tab title="Preview"> with the same iframe + onLoad postMessage logic (using their respective preview JSON payloads like badgeCountPreviewJson, badgeOverflowPreviewJson, smallBadgePreviewJson, iconButtonBadgePreviewJson, customBadgePreviewJson) so each example shows a live preview; alternatively factor this into the shared preview component used in docs/widgets/padding.mdx and reuse it for each badge variant to avoid duplicating the iframe/postMessage logic.
🟡 Minor comments (27)
docs/widgets/hero.mdx-10-13 (1)
10-13:⚠️ Potential issue | 🟡 MinorPreview will show a broken image (
https://example.com/avatar.pngis not a real asset).
example.comreturns an HTML page, not an image, so theStacImagein the preview iframe will fail to load and users will see whatever broken-image state the playground renders. Point this at a real asset (e.g. a small image hosted on the Stac docs/assets CDN, or a known placeholder likehttps://picsum.photos/200/https://placehold.co/200) so the preview actually demonstrates the hero.The Dart/JSON sample blocks lower in the file can keep
example.comsince they're just illustrative code, but the live preview payload needs a resolvable URL.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/hero.mdx` around lines 10 - 13, The preview payload in docs/widgets/hero.mdx uses a broken image URL ("child" object with "type": "image" and "network" set to https://example.com/avatar.png) which causes StacImage in the preview iframe to fail; update that "network" value to a real, resolvable image (for example a small CDN asset on the Stac docs/assets CDN or a placeholder like https://picsum.photos/200 or https://placehold.co/200) so the live preview renders correctly, while leaving the illustrative Dart/JSON sample blocks that use example.com unchanged.docs/widgets/gesture_detector.mdx-95-120 (1)
95-120:⚠️ Potential issue | 🟡 Minor
setIntervalcan leak / stack up on repeatedonLoad.The interval handle is local to this
onLoadcallback and only cleared aftermaxAttemptsis reached. There are two realistic cases where it is never cleared (or stacks):
- The iframe is removed from the DOM (tab switch re-renders, route change, Fast Refresh) before 12 ticks have run — the interval keeps firing
postMessageon a detachedcontentWindowforever.onLoadfires more than once on the same iframe (e.g. navigation inside the playground, BFCache restore, or asrcchange). Each invocation starts a new interval; the previous ones are still alive, so you now have N overlapping posters.Since this pattern was replicated across ~85 docs files, the leak multiplies. Consider caching the handle on the element and clearing any prior one, and also stopping on unload:
🛠️ Suggested hardening
onLoad={(event) => { const iframe = event.currentTarget; + // Clear any prior interval on re-load of the same iframe + if (iframe.__stacPreviewInterval) { + clearInterval(iframe.__stacPreviewInterval); + } const targetOrigin = PLAYGROUND_BASE_URL; const message = { type: "stac-preview-json", payload: gestureDetectorPreviewJson }; let attempts = 0; const maxAttempts = 12; - const interval = setInterval(() => { + const interval = setInterval(() => { + if (!iframe.isConnected) { + clearInterval(interval); + return; + } iframe.contentWindow?.postMessage(message, targetOrigin); attempts += 1; if (attempts >= maxAttempts) { clearInterval(interval); } }, 250); + iframe.__stacPreviewInterval = interval; }}A cleaner long-term fix is a ready-handshake: have the playground post
{ type: "stac-preview-ready" }on load, and only then send the JSON once (listener removed after use). That also eliminates the blind 12× 250 ms spam.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/gesture_detector.mdx` around lines 95 - 120, The onLoad callback for the iframe (id "stac") creates a local setInterval (variables attempts, maxAttempts, interval) that can leak or stack across removals and repeated onLoad calls; change it to first clear any existing interval stored on the iframe element (e.g., iframe._stacInterval or iframe.dataset.stacInterval) before creating a new one, assign the new interval handle to that property, and ensure you clear it both when attempts >= maxAttempts and on iframe unload/removal (add a one-time "beforeunload"/"unload" or MutationObserver cleanup to clear iframe._stacInterval); alternatively implement a ready-handshake where the playground posts { type: "stac-preview-ready" } and you send gestureDetectorPreviewJson once (then remove the message listener) to avoid polling entirely (use PLAYGROUND_BASE_URL and gestureDetectorPreviewJson in the handshake).docs/widgets/text.mdx-7-14 (1)
7-14:⚠️ Potential issue | 🟡 MinorPreview text will likely be invisible (white on white).
color: "#FFFFFF"on the top-leveltextpayload means the preview renders white text. If the playground's default background is white (or even a light neutral), readers will just see an empty iframe and assume the preview is broken. Use a dark color, or wrap the text in a contrastingcontainer:🛠️ Suggested fix
export const textPreviewJson = { - "type": "text", - "data": "Hello, World!", - "style": { - "color": "#FFFFFF", - "fontSize": 24 - } + "type": "container", + "padding": 16, + "color": "#FF1E88E5", + "child": { + "type": "text", + "data": "Hello, World!", + "style": { + "color": "#FFFFFFFF", + "fontSize": 24 + } + } };Note: the Dart/JSON tabs can keep the original snippet — this change only affects the live preview payload.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/text.mdx` around lines 7 - 14, The preview payload textPreviewJson uses color: "#FFFFFF" which will render white-on-white and appear invisible; update the payload so the preview is visible by either changing textPreviewJson.data.style.color to a dark/contrasting value (e.g., "#000000" or a dark gray) or wrap the text node in a contrasting container (add a container node with a dark background and place the text inside) so the live preview is readable; modify the textPreviewJson object accordingly (adjust the "style.color" or structure to include a container) used by the preview renderer.docs/widgets/image.mdx-7-15 (1)
7-15:⚠️ Potential issue | 🟡 MinorPreview won't be able to load
assets/logo.pngfrom the playground.
imagePreviewJsonreferencesassets/logo.pngwithimageType: "asset", but the embedded playground atplayground.stac.devhas no way to resolve assets bundled in a consumer's app. The preview tab will most likely render a broken/placeholder image, which is worse than no preview. Consider switching the preview payload to anetworkimage with a stable public URL (you can keep the Dart/JSON snippets showing the asset usage as the documented example), so the playground can actually display something meaningful.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/image.mdx` around lines 7 - 15, The preview payload imagePreviewJson currently points to a local asset ("assets/logo.png") with imageType: "asset", which the embedded playground cannot resolve; update imagePreviewJson so imageType is "network" and src is a stable public URL (e.g., a CDN-hosted PNG) so the playground can render the preview, while leaving the Dart/JSON examples in the docs that show asset usage unchanged; ensure you update the src and imageType fields in imagePreviewJson (and keep imagePreviewSrc as-is).docs/widgets/switch.mdx-102-103 (1)
102-103:⚠️ Potential issue | 🟡 MinorMissing blank line between the closing
</Tabs>and the next H3.Line 102's
</Tabs>is immediately followed by### Example 2: Adaptive Switchon line 103 with no blank line. In MDX this can occasionally cause the heading to be parsed as part of the preceding JSX block. Add a blank line to be safe:Proposed fix
</Tabs> + ### Example 2: Adaptive Switch🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/switch.mdx` around lines 102 - 103, There is no blank line between the closing JSX tag </Tabs> and the subsequent markdown heading "### Example 2: Adaptive Switch", which can cause the heading to be parsed as part of the JSX; add a single blank line immediately after the </Tabs> tag so the H3 is separated from the JSX block (locate the closing </Tabs> and insert one empty line before "### Example 2: Adaptive Switch").docs/widgets/outlined_button.mdx-7-23 (1)
7-23:⚠️ Potential issue | 🟡 MinorFix empty action objects — missing required
actionTypefield.The action handlers (
onPressed,onLongPress,onHover,onFocusChange) are set to empty objects{}, which are invalid. The Stac framework requires anactionTypefield on all action objects (throwsFormatExceptionif missing). The Dart example usesStacNoneAction(); replace the empty objects with{"actionType": "none"}in both the exportedoutlinedButtonPreviewJson(lines 7–23) and the JSON tab example (lines 66–69).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/outlined_button.mdx` around lines 7 - 23, The action handler objects in outlinedButtonPreviewJson (fields onPressed, onLongPress, onHover, onFocusChange) are empty and must include an actionType; replace each `{}` with `{"actionType": "none"}` (matching StacNoneAction) in the exported outlinedButtonPreviewJson and also update the JSON tab example where those handlers appear so every action object contains an actionType field.docs/widgets/clip_rrect.mdx-87-88 (1)
87-88:⚠️ Potential issue | 🟡 MinorMissing blank line between
</Tabs>and the next heading.In MDX, a heading immediately following a JSX closing tag without a blank line can be parsed as part of the JSX block / inline content rather than a new markdown section. Add a blank line before
## Propertiesto keep the heading rendering reliable.🛠️ Proposed fix
</Tabs> + ## Properties🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/clip_rrect.mdx` around lines 87 - 88, Add a blank line after the JSX closing tag "</Tabs>" so the "## Properties" heading is separated from the JSX block; ensure the file contains an empty line between the "</Tabs>" token and the "## Properties" heading to prevent MDX from parsing the heading as part of the JSX block.docs/widgets/circle_avatar.mdx-11-11 (1)
11-11:⚠️ Potential issue | 🟡 MinorPreview image uses a mutable
refs/heads/devURL.
https://raw.githubusercontent.com/StacDev/stac/refs/heads/dev/assets/companies/bettrdo.jpgresolves against whateverdevpoints to at request time. If that asset is renamed, moved, or deleted, this documentation preview silently breaks (and cache-busting onraw.githubusercontent.comis inconsistent). Consider pinning to a stable ref — either a tagged release (e.g.refs/tags/v…) or a specific commit SHA — or hosting the image alongside the docs.The same URL is used on line 47 in the Dart example.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/circle_avatar.mdx` at line 11, The preview image URL uses the mutable ref "refs/heads/dev" (seen in the "backgroundImage" property) which can break when dev moves; update the URL to a stable ref by replacing "refs/heads/dev" with either a released tag (refs/tags/vX.Y.Z) or a specific commit SHA, or alternatively host the image alongside the docs and point "backgroundImage" to that stable path; make the same change to the Dart example occurrence mentioned (line ~47) so both references are pinned to the stable ref.docs/widgets/opacity.mdx-35-35 (1)
35-35:⚠️ Potential issue | 🟡 MinorCopy error: description references the wrong widget.
This is the Opacity documentation, but the sentence says "the Slider widget in Flutter". The link target is correct (
Opacity-class.html), only the prose is wrong.✏️ Proposed fix
-To know more about the Slider widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/Opacity-class.html). +To know more about the Opacity widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/Opacity-class.html).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/opacity.mdx` at line 35, The sentence incorrectly references the "Slider widget" in the Opacity docs; update the prose in the string "To know more about the Slider widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/Opacity-class.html)." to mention the Opacity widget instead (e.g., "To know more about the Opacity widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/Opacity-class.html)."), keeping the existing Opacity-class.html link intact.docs/widgets/sized_box.mdx-7-11 (1)
7-11:⚠️ Potential issue | 🟡 Minor640 px preview frame for a 25 px
SizedBoxwill render as empty space.The iframe is fixed at
h-[640px](standardized across the PR), but this widget's payload is a 25 px tall spacer with no visible content. Readers will see a large empty Playground chrome and likely assume the preview is broken.Options:
- Use a more illustrative payload (e.g. a colored
containerseparated by thesizedBox) so the preview demonstrates the spacing effect.- Make the frame height a prop on the shared preview component proposed on
dynamic_view.mdxand pick a smaller value here.Also applies to: 45-72
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sized_box.mdx` around lines 7 - 11, The preview uses sizedBoxPreviewJson (type: "sizedBox", height: 25) which renders as an empty 25px spacer inside a 640px iframe (sizedBoxPreviewSrc), making the playground look broken; update sizedBoxPreviewJson to a more illustrative payload—e.g., wrap the SizedBox between two colored containers or add a visible child so the spacing effect is visible—or change the shared preview component (referenced in dynamic_view.mdx) to accept a frameHeight prop and set a smaller height for this preview; modify either sizedBoxPreviewJson or the shared preview usage accordingly and keep the PLAYGROUND_BASE_URL embed URL unchanged.docs/widgets/dynamic_view.mdx-88-107 (1)
88-107:⚠️ Potential issue | 🟡 MinorRetry loop has no cleanup and no success signal — replace with a handshake.
Two minor but real issues with the
onLoadblock that will be inherited by every widget doc using this pattern:
- No teardown on navigation.
setIntervalself-clears only after 12 attempts (~3s). If a reader navigates away, reloads the iframe, or the tab unmounts during that window, the interval keeps firingpostMessageagainst a detachedcontentWindow. It recovers quickly, but it's avoidable noise and can surface as "postMessage after unload" warnings in DevTools.- Blind retries. The page posts 12 times regardless of whether the iframe already rendered the payload. A one-line
message-event handshake (iframe posts{ type: "stac-preview-ready" }on mount; host stops retrying on receipt) is cheaper and more reliable, and makes the max-attempt fallback a real safety net rather than the primary mechanism.Since this code is about to be duplicated across ~85 files, fixing it here (or, better, in the shared snippet suggested above) has outsized value.
♻️ Sketch of a handshake-based version
onLoad={(event) => { const iframe = event.currentTarget; const targetOrigin = PLAYGROUND_BASE_URL; const message = { type: "stac-preview-json", payload: dynamicViewPreviewJson }; let attempts = 0; const maxAttempts = 12; const onReady = (e) => { if (e.origin !== targetOrigin) return; if (e.data?.type === "stac-preview-ready") { iframe.contentWindow?.postMessage(message, targetOrigin); cleanup(); } }; const interval = setInterval(() => { iframe.contentWindow?.postMessage(message, targetOrigin); if (++attempts >= maxAttempts) cleanup(); }, 250); const cleanup = () => { clearInterval(interval); window.removeEventListener("message", onReady); iframe.removeEventListener("unload", cleanup); }; window.addEventListener("message", onReady); iframe.addEventListener("unload", cleanup, { once: true }); }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/dynamic_view.mdx` around lines 88 - 107, The onLoad handler currently blasts postMessage in an untracked interval (using PLAYGROUND_BASE_URL and dynamicViewPreviewJson) without teardown or success detection; replace it with a handshake: add a window "message" listener (e.g., onReady) that checks e.origin === PLAYGROUND_BASE_URL and e.data.type === "stac-preview-ready", send the {type: "stac-preview-json", payload: dynamicViewPreviewJson} once onReady and then call cleanup; keep the existing interval/maxAttempts fallback but have cleanup clearInterval(interval), removeEventListener("message", onReady) and remove any iframe unload/unmount listener (attach iframe.addEventListener("unload", cleanup, { once: true }) or equivalent) so retries stop on success or when the iframe/navigation unmounts.docs/widgets/conditional.mdx-92-94 (1)
92-94:⚠️ Potential issue | 🟡 MinorAdd a blank line between
</Tabs>and the next markdown heading.Same issue as in
set_value.mdx: the## Conditional with Complex Widgetsheading directly follows the closing</Tabs>tag with no blank line, which can cause MDX to swallow the heading into the JSX block.📝 Proposed fix
</Tabs> + ## Conditional with Complex Widgets🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/conditional.mdx` around lines 92 - 94, Insert a blank line after the closing JSX tag </Tabs> so the Markdown heading "## Conditional with Complex Widgets" is separated from the JSX block; locate the sequence containing the </Tabs> tag in the docs/widgets/conditional.mdx content and add one empty line before the "## Conditional with Complex Widgets" heading to prevent MDX from treating the heading as part of the JSX.docs/widgets/set_value.mdx-107-109 (1)
107-109:⚠️ Potential issue | 🟡 MinorAdd a blank line between
</Tabs>and the next markdown heading.Without a blank line separating the closing JSX tag from
## Initializing State on Screen Load, many MDX renderers will treat the##line as a continuation of the JSX block and fail to render it as a heading.📝 Proposed fix
</Tabs> + ## Initializing State on Screen Load🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/set_value.mdx` around lines 107 - 109, Add a single blank line after the closing JSX tag </Tabs> so the following markdown heading "## Initializing State on Screen Load" is separated; update the snippet around the closing </Tabs> tag to insert one empty line before the "## Initializing State on Screen Load" heading to ensure MDX renders the heading correctly.docs/widgets/tab_bar.mdx-20-33 (1)
20-33:⚠️ Potential issue | 🟡 MinorAll three tab labels are "Red" — likely a copy/paste typo.
Tabs 2 and 3 are also titled
"Red", both in thistabBarPreviewJsonand in the Dart/JSON example blocks (lines 141–143 and 178–187). This makes the preview confusing — tapping tabs appears to do nothing because the labels never change. Suggest distinct labels (e.g."Tab 1","Tab 2","Tab 3", or names matching the container colors).📝 Proposed fix (apply to all three duplicated locations)
- { "type": "tab", "text": "Red" }, - { "type": "tab", "text": "Red" }, - { "type": "tab", "text": "Red" } + { "type": "tab", "text": "Tab 1" }, + { "type": "tab", "text": "Tab 2" }, + { "type": "tab", "text": "Tab 3" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/tab_bar.mdx` around lines 20 - 33, The tab labels in the tabBarPreviewJson "tabs" array are duplicated ("Red" x3); update the "text" values in the JSON examples (the "tabs" array used in tabBarPreviewJson and the Dart/JSON example blocks) so each tab has a distinct label (e.g., "Tab 1", "Tab 2", "Tab 3" or names matching their container colors). Locate the arrays named or referenced as tabBarPreviewJson and the two example blocks and replace the repeated "Red" strings with unique labels in all three duplicated locations.docs/widgets/filled_button.mdx-7-23 (1)
7-23:⚠️ Potential issue | 🟡 MinorEmpty
{}action objects are invalid and inconsistent with the Dart example.The JSON examples use
"onPressed": {}(and three other empty handler objects), but this pattern lacks theactionTypediscriminator required by the schema. Thetool_tip.mdxfile demonstrates the correct pattern:{ "actionType": "none" }for no-op actions. More importantly, the Dart sample in the same file showsStacNoneAction()foronPressedonly—the other three handlers are omitted. The JSON should match this by removing all four empty handler keys.📝 Suggested cleanup
export const filledButtonPreviewJson = { "type": "filledButton", - "onPressed": {}, - "onLongPress": {}, - "onHover": {}, - "onFocusChange": {}, "style": { "backgroundColor": "#FFC107", "foregroundColor": "#000000" },Apply the same change to the JSON code block at lines 64–80.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/filled_button.mdx` around lines 7 - 23, The JSON example object filledButtonPreviewJson currently contains invalid empty handler objects ("onPressed", "onLongPress", "onHover", "onFocusChange"); remove those four keys entirely from filledButtonPreviewJson so the JSON matches the Dart sample (which only uses StacNoneAction for onPressed and omits the other handlers), and apply the same removal to the other JSON example block in this file to replace the empty {} handlers with neither keys nor empty objects.docs/widgets/radio_group.mdx-222-247 (1)
222-247:⚠️ Potential issue | 🟡 MinorDuplicate iframe
id="stac"across all preview blocks.Every widget doc uses
id="stac"on its iframe. HTMLidmust be unique per document. Mintlify pages tend to be self-contained, so this is fine today, but if any landing page or aggregated route ever inlines two preview iframes,document.getElementById("stac")and CSS rules will silently target only the first, and accessibility tooling will flag the duplicate. Either drop theid(theonLoadhandler already capturesevent.currentTarget) or make it widget-specific.🔧 Suggested change
<iframe - id="stac" src={radioGroupPreviewSrc}The same change should be applied to the iframes in
sliver_list.mdx,carousel_view.mdx,circular_progress_indicator.mdx,grid_view.mdx,safe_area.mdx,visibility.mdx,center.mdx, and (per the AI summary) the other ~85 widget docs touched by this PR.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/radio_group.mdx` around lines 222 - 247, The iframe uses a hardcoded id="stac" which creates duplicate HTML ids across widget docs; remove the id attribute (or generate a widget-specific id) and rely on the existing onLoad handler's event.currentTarget (and iframe.contentWindow) to post the preview message; update all affected preview iframes (the element with id="stac" and its onLoad handler in each widget doc such as radio_group.mdx, sliver_list.mdx, carousel_view.mdx, circular_progress_indicator.mdx, grid_view.mdx, safe_area.mdx, visibility.mdx, center.mdx, etc.) to drop the id or make it unique so CSS/document.getElementById and accessibility tooling no longer encounter duplicate ids.docs/widgets/sliver_grid.mdx-253-271 (1)
253-271:⚠️ Potential issue | 🟡 MinorReplace the blind 12×250ms postMessage polling with a ready handshake, and clear the interval on unmount.
Two concerns with the current preview handler (present in every file in this PR):
- The handler fires
postMessageup to 12 times regardless of whether the iframe has already consumed it. A cleaner pattern is for the embedded playground to post a{ type: "stac-preview-ready" }message back towindow.opener/parent, and for the parent to send the payload exactly once in response. This removes the 3-second racy loop and works reliably regardless of iframe warm-up time.setIntervalis only cleared aftermaxAttempts. If the user switches tabs or navigates away within ~3s, the interval keeps firing against a detached iframe. Since this is a ReactonLoad, you can't return a cleanup, but you can at least guard withif (!iframe.isConnected) { clearInterval(interval); return; }inside the tick, or attach a one-shotmessagelistener for the ready event instead.Since this same handler ships in ~85 files, fixing it inside the shared component suggested above will fix it everywhere.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_grid.mdx` around lines 253 - 271, The onLoad handler currently spams postMessage up to 12 times via setInterval (variables attempts, maxAttempts, interval) and never reliably stops when the iframe is detached; replace this polling with a handshake: in the onLoad callback (where iframe, targetOrigin and the message {type: "stac-preview-json", payload: sliverGridPreviewJson} are defined) register a one-time window.addEventListener('message') handler that listens for {type: "stac-preview-ready"} from the iframe and, when seen, calls iframe.contentWindow.postMessage(message, targetOrigin) exactly once and then removes the listener; additionally, remove the setInterval code and/or if you keep a fallback interval, add a guard inside its tick to clearInterval(interval) and return if !iframe.isConnected, and ensure any event listener is cleaned up after firing (use { once: true } or explicitly removeEventListener).docs/widgets/custom_scroll_view.mdx-23-23 (1)
23-23:⚠️ Potential issue | 🟡 MinorRemove empty action objects or use explicit no-op action in documentation examples.
An empty object
{}creates a validStacActioninstance but has noactionTypeand won't function if invoked. In documentation examples at lines 23, 62, and 90, use a no-op action (with appropriateactionType) or omit the field entirely to clarify the behavior. This prevents confusion when developers reference these examples.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/custom_scroll_view.mdx` at line 23, The examples in docs/widgets/custom_scroll_view.mdx use empty action objects for the onPressed field which yield invalid StacAction instances; replace each empty onPressed object with an explicit no-op action that includes the required actionType (use your project’s designated no-op actionType) or simply remove the onPressed field from those examples so they don’t imply a callable action (update all occurrences of onPressed that currently have {}).docs/widgets/sliver_padding.mdx-9-9 (1)
9-9:⚠️ Potential issue | 🟡 MinorCorrect the Properties table type annotation for
padding.The Properties table documents
paddingasMap<String, dynamic>, but the actual type isStacEdgeInsets. The code already supports the scalar format shown in your JSON examples ("padding": 16) viaStacEdgeInsets.fromJson(), which accepts numeric input and expands it uniformly to all edges. Update the Properties table to reflect the correct type.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_padding.mdx` at line 9, The Properties table incorrectly lists the type of the padding property as Map<String, dynamic>; change it to StacEdgeInsets to match the actual implementation and behaviors (e.g., StacEdgeInsets.fromJson supports scalar inputs like "padding": 16). Update the documentation entry for the padding field to use StacEdgeInsets and optionally mention that StacEdgeInsets.fromJson accepts numeric/scalar formats which expand uniformly to all edges.docs/widgets/backdrop_filter.mdx-219-220 (1)
219-220:⚠️ Potential issue | 🟡 MinorAdd a blank line between
</Tabs>and the next heading.Same issue as in
tool_tip.mdx: the### Example 2: Dilate Filter Effectheading directly follows</Tabs>with no blank line, which can confuse MDX parsers. Add a blank line before the heading.📝 Proposed fix
</Tabs> + ### Example 2: Dilate Filter Effect🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/backdrop_filter.mdx` around lines 219 - 220, The MDX has no blank line between the closing </Tabs> tag and the next heading "### Example 2: Dilate Filter Effect", which can break MDX parsing; open the docs file and insert a single blank line immediately after the </Tabs> token so the heading is separated (same fix as applied in tool_tip.mdx), ensuring there's a newline between </Tabs> and the "### Example 2: Dilate Filter Effect" heading.docs/widgets/tool_tip.mdx-108-109 (1)
108-109:⚠️ Potential issue | 🟡 MinorAdd a blank line between
</Tabs>and the next markdown heading.Mintlify MDX requires a blank line between closing JSX tags and markdown headings to prevent parsing errors. Every other section in this file follows this pattern (lines 22, 49, 154, 189, 228 all have blank lines before their headings), but
#### Styled Tooltipat line 109 is missing this blank line.📝 Proposed fix
</Tabs> + #### Styled Tooltip🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/tool_tip.mdx` around lines 108 - 109, Add a blank line between the closing JSX tag "</Tabs>" and the markdown heading "#### Styled Tooltip" so the file has an empty line separating the JSX block and the heading (i.e., ensure there's one newline after "</Tabs>" before "#### Styled Tooltip") to match the other sections and satisfy Mintlify MDX parsing.docs/widgets/tool_tip.mdx-78-108 (1)
78-108:⚠️ Potential issue | 🟡 MinorTooltip preview won't display the tooltip — only the icon will be visible.
By default,
StacTooltiprequires a long-press gesture to reveal the message. In an embedded iframe, long-press events cannot be reliably triggered, so readers will see only the info icon with no indication a tooltip exists.Two options:
- Configure the preview with
triggerMode: "manual"(or"tap") and pair with JavaScript to programmatically trigger visibility, or set a very shortwaitDurationto simulate hover behavior.- Remove the Preview tab for this widget and keep the Dart/JSON tabs only until the playground supports interactive tooltip triggering.
Also confirm that
triggerModedefaults are appropriate in iframe contexts where pointer events may be unavailable.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/tool_tip.mdx` around lines 78 - 108, The Preview iframe shows only the icon because StacTooltip requires a long-press to open and iframe embedding prevents reliable long-press; update the preview payload (toolTipPreviewJson) or the preview configuration to set StacTooltip.triggerMode to "manual" or "tap" and/or reduce waitDuration so the tooltip will become visible in the iframe, then programmatically postMessage from the parent (the existing onLoad handler) to trigger visibility; alternatively remove the Preview Tab entirely if you prefer not to simulate interaction. Ensure you reference StacTooltip, triggerMode, waitDuration, toolTipPreviewJson (or toolTipPreviewSrc) when making the change and verify defaults are suitable for iframe contexts.docs/widgets/network_widget.mdx-7-16 (1)
7-16:⚠️ Potential issue | 🟡 MinorPreview will fail because api.example.com/data returns invalid widget payload.
The playground receives the preview JSON via postMessage and attempts to fetch from
https://api.example.com/data. This endpoint returns a 404 or generic documentation page, not a valid widget definition—the preview tab will display an error or parse failure.Consider using a real test API (e.g.,
dummyjson.comlike form.mdx does) or a network-less widget variant to demonstrate functionality.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/network_widget.mdx` around lines 7 - 16, The preview JSON in networkWidgetPreviewJson points to an invalid endpoint (request.url = "https://api.example.com/data") which causes the playground fetch to fail; update networkWidgetPreviewJson to use a real test API (e.g., a dummyjson.com endpoint) or convert it to a network-less example by removing the request field so the preview does not perform an external fetch—modify the request.url value or the request object inside networkWidgetPreviewJson accordingly.docs/widgets/expanded.mdx-7-14 (1)
7-14:⚠️ Potential issue | 🟡 MinorWrap
Expandedin aRow,Column, orFlexcontainer.
Expandedis aParentDataWidgetrequiring aFlexparent (Row, Column, or Flex). The current preview puts it at root level, which will throwIncorrect use of ParentDataWidgetat render time. The framework does not auto-wrap root widgets.🛠️ Suggested payload
export const expandedPreviewJson = { - "type": "expanded", - "flex": 2, - "child": { - "type": "text", - "data": "Hello, World!" - } + "type": "row", + "children": [ + { + "type": "expanded", + "flex": 2, + "child": { "type": "text", "data": "Hello, World!" } + } + ] };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/expanded.mdx` around lines 7 - 14, The preview JSON places an Expanded widget at the root (expandedPreviewJson with "type":"expanded"), which will throw an Incorrect use of ParentDataWidget error; fix by wrapping the Expanded node in a Flex parent (e.g., change expandedPreviewJson so the top-level "type" is "row" or "column" or "flex" and move the existing expanded object into that parent's "children"/"child" property), ensuring the Expanded remains a descendant of a Flex (Row/Column/Flex) rather than the root.docs/widgets/auto_complete.mdx-14-17 (1)
14-17:⚠️ Potential issue | 🟡 Minor
onSelectedreferences a callback that the embedded playground likely can't resolve.The preview payload sends
{"type": "callback", "name": "onOptionSelected"}, but the embedded playground iframe is launched withshowEditor=falseand has no way for a doc reader to registeronOptionSelected. Selecting an option in the preview will probably no-op or throw. For preview-only payloads, consider omittingonSelected(or pointing it at a built-in noop action if Stac has one) so the preview is self-contained. The Dart/JSON snippets above can keep the callback to demonstrate the API.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/auto_complete.mdx` around lines 14 - 17, The preview payload includes an onSelected callback referencing "onOptionSelected" which the embedded playground (launched with showEditor=false) cannot resolve; remove the onSelected entry from the preview payload or replace its value with a built-in no-op action (e.g., a Stac-provided noop) so the iframe preview remains self-contained—update the JSON used for the live preview (the object containing "onSelected": {"type":"callback","name":"onOptionSelected"}) to either omit "onSelected" or point it to the noop action.docs/widgets/icon_button.mdx-24-24 (1)
24-24:⚠️ Potential issue | 🟡 Minor
"onPressed": {}is not a valid Stac action shape.An empty object will fail action parsing. The source documentation for
stac_icon_button.dartshows the expected pattern is{"action": "navigate", "route": "/next"}. Alternatively, the function action pattern{"type": "function", "name": "..."}is also valid (as used inscaffold.mdx).🔧 Suggested change
- "onPressed": {}, + "onPressed": { + "action": "navigate", + "route": "/next" + },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/icon_button.mdx` at line 24, Replace the invalid empty action object for "onPressed" with a valid Stac action shape; update the example in docs/widgets/icon_button.mdx so "onPressed" uses either the navigation pattern (e.g., {"action":"navigate","route":"/next"}) or the function pattern used elsewhere ({"type":"function","name":"..."}) to match the expected parser in stac_icon_button.dart and the scaffold.mdx examples.docs/widgets/sliver_visibility.mdx-104-122 (1)
104-122:⚠️ Potential issue | 🟡 MinorAdd cleanup handler to prevent setInterval firing on detached iframe after tab navigation.
The interval will continue firing for up to 3 seconds if the user navigates away or closes the Preview tab before the 12 retry attempts complete. Once the iframe unmounts,
postMessagecalls fire on a detachedcontentWindow.Two remedies:
- Listen for an ack
messageevent from the playground andclearIntervalimmediately on first successful receipt, rather than relying on a timer.- Wrap the iframe in a component that returns cleanup from a
useEffect, capturing the interval reference.Minor note: The
targetOrigin = PLAYGROUND_BASE_URLis correct (not"*"); verify the playground validatesevent.originto reject spoofed messages.This pattern is duplicated across multiple widget docs; consolidating into a shared component would fix it everywhere.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_visibility.mdx` around lines 104 - 122, The onLoad inline handler starts a setInterval that can continue posting to a detached iframe; replace this pattern by moving the logic into a React component (e.g., a SliverVisibilityPreview component) that in a useEffect creates the message, starts the retry interval (using the existing variables attempts/maxAttempts/interval), adds a window "message" listener that checks event.origin === PLAYGROUND_BASE_URL and the expected ack payload and immediately clears the interval on first valid ack, and returns a cleanup that clears the interval and removes the message listener on unmount; keep using PLAYGROUND_BASE_URL and the same message shape (type: "stac-preview-json", payload: sliverVisibilityPreviewJson) so the playground can validate origin and respond.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 868a9343-45f4-4222-bdeb-daacfddd1b52
📒 Files selected for processing (87)
docs/widgets/alert_dialog.mdxdocs/widgets/align.mdxdocs/widgets/app_bar.mdxdocs/widgets/aspect_ratio.mdxdocs/widgets/auto_complete.mdxdocs/widgets/backdrop_filter.mdxdocs/widgets/badge.mdxdocs/widgets/bottom_navigation_bar.mdxdocs/widgets/card.mdxdocs/widgets/carousel_view.mdxdocs/widgets/center.mdxdocs/widgets/check_box.mdxdocs/widgets/chip.mdxdocs/widgets/circle_avatar.mdxdocs/widgets/circular_progress_indicator.mdxdocs/widgets/clip_oval.mdxdocs/widgets/clip_rrect.mdxdocs/widgets/colored_box.mdxdocs/widgets/column.mdxdocs/widgets/conditional.mdxdocs/widgets/container.mdxdocs/widgets/custom_scroll_view.mdxdocs/widgets/divider.mdxdocs/widgets/drawer.mdxdocs/widgets/dropdown_menu.mdxdocs/widgets/dynamic_view.mdxdocs/widgets/elevated_button.mdxdocs/widgets/expanded.mdxdocs/widgets/filled_button.mdxdocs/widgets/fitted_box.mdxdocs/widgets/flexible.mdxdocs/widgets/floating_action_button.mdxdocs/widgets/form.mdxdocs/widgets/fractionally_sized_box.mdxdocs/widgets/gesture_detector.mdxdocs/widgets/grid_view.mdxdocs/widgets/hero.mdxdocs/widgets/icon.mdxdocs/widgets/icon_button.mdxdocs/widgets/image.mdxdocs/widgets/ink_well.mdxdocs/widgets/limited_box.mdxdocs/widgets/linear_progress_indicator.mdxdocs/widgets/list_tile.mdxdocs/widgets/listview.mdxdocs/widgets/network_widget.mdxdocs/widgets/opacity.mdxdocs/widgets/outlined_button.mdxdocs/widgets/padding.mdxdocs/widgets/page_view.mdxdocs/widgets/placeholder.mdxdocs/widgets/positioned.mdxdocs/widgets/radio_group.mdxdocs/widgets/refresh_indicator.mdxdocs/widgets/row.mdxdocs/widgets/safe_area.mdxdocs/widgets/scaffold.mdxdocs/widgets/selectable_text.mdxdocs/widgets/set_value.mdxdocs/widgets/single_child_scroll_view.mdxdocs/widgets/sized_box.mdxdocs/widgets/slider.mdxdocs/widgets/sliver_app_bar.mdxdocs/widgets/sliver_fill_remaining.mdxdocs/widgets/sliver_grid.mdxdocs/widgets/sliver_list.mdxdocs/widgets/sliver_opacity.mdxdocs/widgets/sliver_padding.mdxdocs/widgets/sliver_safe_area.mdxdocs/widgets/sliver_to_box_adapter.mdxdocs/widgets/sliver_visibility.mdxdocs/widgets/spacer.mdxdocs/widgets/stack.mdxdocs/widgets/switch.mdxdocs/widgets/tab_bar.mdxdocs/widgets/table.mdxdocs/widgets/table_cell.mdxdocs/widgets/table_row.mdxdocs/widgets/text.mdxdocs/widgets/text_button.mdxdocs/widgets/text_field.mdxdocs/widgets/text_form_field.mdxdocs/widgets/tool_tip.mdxdocs/widgets/vertical_divider.mdxdocs/widgets/visibility.mdxdocs/widgets/webview.mdxdocs/widgets/wrap.mdx
- Refactored widget documentation to include structured JSON representations and playground examples for DropdownMenu, Positioned, RefreshIndicator, SliverAppBar, SliverFillRemaining, SliverGrid, SliverOpacity, SliverPadding, SliverSafeArea, and SliverVisibility. - Enhanced clarity and usability of widget examples for better developer experience.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/widgets/sliver_safe_area.mdx (1)
60-72:⚠️ Potential issue | 🟡 MinorJSON tab still shows a bare root-level sliver, inconsistent with the Preview payload.
The Preview payload (lines 7–25) correctly wraps
sliverSafeAreainsidescaffold > customScrollView > slivers, but the JSON example here shows the sliver at the root. A user copy-pasting this JSON will hit the same render-time failure the Preview fix was addressing. Consider aligning this snippet with the preview payload (or at least noting the requiredCustomScrollViewparent) for consistency across both tabs.✍️ Proposed fix
```json { - "type": "sliverSafeArea", - "top": true, - "sliver": { - "type": "sliverToBoxAdapter", - "child": { - "type": "text", - "data": "Hello World" + "type": "scaffold", + "body": { + "type": "customScrollView", + "slivers": [ + { + "type": "sliverSafeArea", + "top": true, + "sliver": { + "type": "sliverToBoxAdapter", + "child": { + "type": "text", + "data": "Hello World" + } + } + } + ] } }</details> The same discrepancy likely exists in the other sliver docs touched by this PR (`sliver_grid.mdx`, `sliver_opacity.mdx`, `sliver_padding.mdx`, `sliver_visibility.mdx`, `sliver_fill_remaining.mdx`, `sliver_app_bar.mdx`) — worth a sweep. <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@docs/widgets/sliver_safe_area.mdxaround lines 60 - 72, The JSON example
currently shows a root-level "sliverSafeArea" which is inconsistent with the
Preview payload; update the example to wrap the "sliverSafeArea" inside a
"scaffold" -> "body": { "type":"customScrollView", "slivers":[ ... ] } structure
(preserving the inner "sliverToBoxAdapter" and "text" child), or add a clear
note that "sliverSafeArea" requires a CustomScrollView parent; also sweep the
other sliver docs (sliver_grid.mdx, sliver_opacity.mdx, sliver_padding.mdx,
sliver_visibility.mdx, sliver_fill_remaining.mdx, sliver_app_bar.mdx) and make
the same fix so examples consistently include the "customScrollView" ->
"slivers" wrapper.</details> </blockquote></details> </blockquote></details>♻️ Duplicate comments (1)
docs/widgets/dropdown_menu.mdx (1)
165-183:⚠️ Potential issue | 🟡 MinorOverlapping intervals on repeated iframe
onLoad.
onLoadcan fire more than once for a single iframe (e.g., if the playground performs a client-side navigation or the tab is toggled and the iframe reloads). Each invocation starts a freshsetIntervalwithout cancelling the previous one, so multiple 250ms timers run concurrently, each blasting up to 12postMessagecalls at the playground. Track the active interval and clear it before starting a new one.🛠️ Proposed fix
onLoad={(event) => { const iframe = event.currentTarget; const targetOrigin = PLAYGROUND_BASE_URL; const message = { type: "stac-preview-json", payload: dropdownMenuPreviewJson }; + if (iframe.__stacPreviewInterval) { + clearInterval(iframe.__stacPreviewInterval); + } let attempts = 0; const maxAttempts = 12; const interval = setInterval(() => { iframe.contentWindow?.postMessage(message, targetOrigin); attempts += 1; if (attempts >= maxAttempts) { clearInterval(interval); + iframe.__stacPreviewInterval = null; } }, 250); + iframe.__stacPreviewInterval = interval; }}A cleaner alternative is a one-shot handshake: have the playground
postMessage({type:"stac-preview-ready"})to its parent once mounted, and send the payload from a singlewindow.addEventListener("message", …)handler. That also lets you drop the retry loop entirely.Note: this pattern appears to be replicated across all the widget docs touched in this PR, so a fix should be applied consistently.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/dropdown_menu.mdx` around lines 165 - 183, The onLoad handler for the iframe creates overlapping setInterval timers (variables attempts, maxAttempts, interval) and should clear any prior interval before starting a new one or, better, replace the retry loop with a one-shot handshake; update the onLoad logic (the inline onLoad handler that posts message {type:"stac-preview-json", payload: dropdownMenuPreviewJson} to PLAYGROUND_BASE_URL) to either track and clear an existing interval variable before calling setInterval or remove the interval entirely and implement a single message listener pattern where the playground sends back {type:"stac-preview-ready"} and the parent (using window.addEventListener("message", …)) sends the payload once—apply the same change consistently across all widget docs that use this pattern.🧹 Nitpick comments (3)
docs/widgets/sliver_fill_remaining.mdx (1)
91-109: Consider handshake-based messaging instead of fixed-attempt polling.The current approach blindly posts the payload 12 times at 250ms intervals regardless of whether the playground has already received it. A ready-signal handshake (playground posts
stac-preview-readyback, parent responds once) would be more reliable and eliminate redundant messages. Also note the interval is not cleared if the component unmounts or the iframe reloads mid-retry — minor since it self-terminates within ~3s, but worth addressing if this pattern is extracted into a shared component (which would be worthwhile given it is duplicated across many widget docs in this PR).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_fill_remaining.mdx` around lines 91 - 109, Replace the blind polling in the onLoad handler with a handshake: listen for window "message" events from PLAYGROUND_BASE_URL and when you receive type "stac-preview-ready" post the "stac-preview-json" payload once to event.currentTarget.contentWindow and remove the listener and any retry interval; if you keep a fallback polling retry (attempts/interval), ensure you clear the interval and remove the message listener on success, on iframe reload, and on component unmount to avoid leaks. Verify origin === PLAYGROUND_BASE_URL before trusting messages, reference the existing onLoad handler, the posted message type "stac-preview-json", the expected reply "stac-preview-ready", and the interval/attempts logic when implementing the cleanup and handshake.docs/widgets/sliver_safe_area.mdx (1)
83-101: Retry loop fires 12 postMessages unconditionally — consider stopping on ack.The interval posts the payload 12 times regardless of whether the playground has already received/processed it, and there's no handshake (e.g., listening for a
ready/ackmessage from the iframe) to short-circuit. For a single iframe this is harmless, but it's noisy in DevTools and wastes work. If/when the playground can emit a readiness message, wiring amessagelistener toclearIntervalearly would be cleaner. Non-blocking.Also note this same block (plus
PLAYGROUND_BASE_URLand the embed URL) is duplicated verbatim across every widget MDX added in this PR — a small shared MDX component/hook (e.g.,<StacPreview json={...} />) would eliminate the copy-paste and make future tweaks (origin change, retry tuning) a one-line edit.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_safe_area.mdx` around lines 83 - 101, The retry loop in the onLoad handler posts "stac-preview-json" up to 12 times unconditionally (iframe.contentWindow?.postMessage with PLAYGROUND_BASE_URL and sliverSafeAreaPreviewJson); change it to stop early by adding a window.addEventListener('message') handler that verifies event.origin === PLAYGROUND_BASE_URL and event.data.type === 'stac-preview-ack' (or 'ready') and then clears the interval and removes the listener; also refactor this duplicated logic into a shared MDX/React component or hook (e.g., <StacPreview json={...}> or useStacPreview) so the PLAYGROUND_BASE_URL, retry tuning and handshake live in one place for all widgets.docs/widgets/dropdown_menu.mdx (1)
118-154: JSON block duplicatesdropdownMenuPreviewJson— drift risk.The JSON shown in the “JSON” tab (lines 119–153) is a hand-written copy of the
dropdownMenuPreviewJsonconstant (lines 7–41). Any future edit that updates one but not the other will cause the documented JSON to disagree with what the live Preview actually renders — which is exactly the kind of discrepancy users will file bugs on. Consider rendering the JSON tab from the same constant (e.g., via a small JSON fenced-code helper or a shared MDX component) so there is a single source of truth, or at minimum add a short comment in both places noting they must stay in sync. Since this pattern is repeated across many widget docs in this PR, a shared helper would pay off quickly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/dropdown_menu.mdx` around lines 118 - 154, The JSON block in the "JSON" tab is a duplicated, hand-edited copy of the dropdownMenuPreviewJson constant which creates a drift risk; instead of a static fenced JSON snippet, import or reference the existing dropdownMenuPreviewJson value and render it (e.g., stringify and inject into the JSON code block via a small MDX helper or shared component) so the preview and docs share one source of truth, or if a shared renderer is not feasible immediately, add a clear inline comment next to dropdownMenuPreviewJson and the JSON tab noting they must remain in sync and link to the single canonical constant name (dropdownMenuPreviewJson) to reduce future divergence.🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed. Outside diff comments: In `@docs/widgets/sliver_safe_area.mdx`: - Around line 60-72: The JSON example currently shows a root-level "sliverSafeArea" which is inconsistent with the Preview payload; update the example to wrap the "sliverSafeArea" inside a "scaffold" -> "body": { "type":"customScrollView", "slivers":[ ... ] } structure (preserving the inner "sliverToBoxAdapter" and "text" child), or add a clear note that "sliverSafeArea" requires a CustomScrollView parent; also sweep the other sliver docs (sliver_grid.mdx, sliver_opacity.mdx, sliver_padding.mdx, sliver_visibility.mdx, sliver_fill_remaining.mdx, sliver_app_bar.mdx) and make the same fix so examples consistently include the "customScrollView" -> "slivers" wrapper. --- Duplicate comments: In `@docs/widgets/dropdown_menu.mdx`: - Around line 165-183: The onLoad handler for the iframe creates overlapping setInterval timers (variables attempts, maxAttempts, interval) and should clear any prior interval before starting a new one or, better, replace the retry loop with a one-shot handshake; update the onLoad logic (the inline onLoad handler that posts message {type:"stac-preview-json", payload: dropdownMenuPreviewJson} to PLAYGROUND_BASE_URL) to either track and clear an existing interval variable before calling setInterval or remove the interval entirely and implement a single message listener pattern where the playground sends back {type:"stac-preview-ready"} and the parent (using window.addEventListener("message", …)) sends the payload once—apply the same change consistently across all widget docs that use this pattern. --- Nitpick comments: In `@docs/widgets/dropdown_menu.mdx`: - Around line 118-154: The JSON block in the "JSON" tab is a duplicated, hand-edited copy of the dropdownMenuPreviewJson constant which creates a drift risk; instead of a static fenced JSON snippet, import or reference the existing dropdownMenuPreviewJson value and render it (e.g., stringify and inject into the JSON code block via a small MDX helper or shared component) so the preview and docs share one source of truth, or if a shared renderer is not feasible immediately, add a clear inline comment next to dropdownMenuPreviewJson and the JSON tab noting they must remain in sync and link to the single canonical constant name (dropdownMenuPreviewJson) to reduce future divergence. In `@docs/widgets/sliver_fill_remaining.mdx`: - Around line 91-109: Replace the blind polling in the onLoad handler with a handshake: listen for window "message" events from PLAYGROUND_BASE_URL and when you receive type "stac-preview-ready" post the "stac-preview-json" payload once to event.currentTarget.contentWindow and remove the listener and any retry interval; if you keep a fallback polling retry (attempts/interval), ensure you clear the interval and remove the message listener on success, on iframe reload, and on component unmount to avoid leaks. Verify origin === PLAYGROUND_BASE_URL before trusting messages, reference the existing onLoad handler, the posted message type "stac-preview-json", the expected reply "stac-preview-ready", and the interval/attempts logic when implementing the cleanup and handshake. In `@docs/widgets/sliver_safe_area.mdx`: - Around line 83-101: The retry loop in the onLoad handler posts "stac-preview-json" up to 12 times unconditionally (iframe.contentWindow?.postMessage with PLAYGROUND_BASE_URL and sliverSafeAreaPreviewJson); change it to stop early by adding a window.addEventListener('message') handler that verifies event.origin === PLAYGROUND_BASE_URL and event.data.type === 'stac-preview-ack' (or 'ready') and then clears the interval and removes the listener; also refactor this duplicated logic into a shared MDX/React component or hook (e.g., <StacPreview json={...}> or useStacPreview) so the PLAYGROUND_BASE_URL, retry tuning and handshake live in one place for all widgets.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID:
5bf7382e-680a-4c5a-bdcf-0c0dd3db2fe1📒 Files selected for processing (10)
docs/widgets/dropdown_menu.mdxdocs/widgets/positioned.mdxdocs/widgets/refresh_indicator.mdxdocs/widgets/sliver_app_bar.mdxdocs/widgets/sliver_fill_remaining.mdxdocs/widgets/sliver_grid.mdxdocs/widgets/sliver_opacity.mdxdocs/widgets/sliver_padding.mdxdocs/widgets/sliver_safe_area.mdxdocs/widgets/sliver_visibility.mdx✅ Files skipped from review due to trivial changes (1)
- docs/widgets/sliver_opacity.mdx
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/widgets/refresh_indicator.mdx
- docs/widgets/sliver_visibility.mdx
- docs/widgets/sliver_grid.mdx
- docs/widgets/sliver_app_bar.mdx
- docs/widgets/positioned.mdx
- docs/widgets/sliver_padding.mdx
- Updated multiple widget documentation files to import the PLAYGROUND_BASE_URL from a centralized snippet for consistency. - Simplified the preview source URL for each widget by removing unnecessary query parameters. - Adjusted iframe styling to maintain a consistent height across all widget previews.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/widgets/sliver_app_bar.mdx (1)
110-141:⚠️ Potential issue | 🟠 MajorJSON tab is out of sync with the Preview payload.
sliverAppBarPreviewJson(lines 8–43) correctly wraps thesliverAppBarinsidescaffold → customScrollView → sliversso the preview renders. But the JSON tab here still shows a bare top-levelsliverAppBar, which is exactly the payload that prompted the earlier "slivers need a sliver-aware parent" feedback. Users copying the JSON tab will not reproduce what they see in the Preview, and the shown payload will fail to render on its own.Please align the JSON tab with the exported preview payload.
🛠️ Suggested fix
```json { - "type": "sliverAppBar", - "title": { - "type": "text", - "data": "SliverAppBar" - }, - "leading": { - "type": "iconButton", - "icon": { - "type": "icon", - "iconType": "material", - "icon": "menu" - }, - "onPressed": {} - }, - "backgroundColor": "primary", - "actions": [ - { - "type": "iconButton", - "icon": { - "type": "icon", - "iconType": "cupertino", - "icon": "heart_solid" - }, - "onPressed": {} - } - ] + "type": "scaffold", + "body": { + "type": "customScrollView", + "slivers": [ + { + "type": "sliverAppBar", + "title": { "type": "text", "data": "SliverAppBar" }, + "leading": { + "type": "iconButton", + "icon": { "type": "icon", "iconType": "material", "icon": "menu" }, + "onPressed": {} + }, + "backgroundColor": "primary", + "actions": [ + { + "type": "iconButton", + "icon": { "type": "icon", "iconType": "cupertino", "icon": "heart_solid" }, + "onPressed": {} + } + ] + } + ] + } }Consider applying the same wrapping to the Dart tab so all three tabs tell the same story. </details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@docs/widgets/sliver_app_bar.mdxaround lines 110 - 141, The JSON tab shows a
top-level "sliverAppBar" that won't render standalone and is out of sync with
sliverAppBarPreviewJson; update the JSON payload to wrap the sliverAppBar inside
a scaffold -> customScrollView -> slivers array (matching
sliverAppBarPreviewJson) so users can copy a working payload; also mirror this
same scaffold/customScrollView/slivers wrapping in the Dart tab if present to
keep all tabs consistent.</details> </blockquote></details> <details> <summary>docs/widgets/limited_box.mdx (1)</summary><blockquote> `97-126`: _⚠️ Potential issue_ | _🟡 Minor_ **Example 2 was left on the old `<CodeGroup>` pattern.** Example 1 was migrated to `<Tabs>` with a Preview tab, but Example 2 still uses `<CodeGroup>` and unnormalized float literals (`200.0`, `300.0`). This leaves the page visually inconsistent and Example 2 without a live preview. Consider migrating it for parity (or drop Example 2 if a preview isn't planned). <details> <summary>♻️ Sketch of the migration</summary> ```diff -<CodeGroup> -```dart Dart -StacLimitedBox( - maxHeight: 200.0, - maxWidth: 300.0, - child: StacText( - data: 'Hello, World! from Limited Box', - style: StacTextStyle(fontSize: 16, color: StacColors.black), - ), -) -``` - -```json JSON -{ - "type": "limitedBox", - "maxHeight": 200.0, - "maxWidth": 300.0, - "child": { - "type": "text", - "data": "Hello, World! from Limited Box", - "style": { - "fontSize": 16, - "color": "#000000" - } - } -} -``` -</CodeGroup> +<Tabs sync={false}> + <Tab title="Dart"> + ```dart + StacLimitedBox( + maxHeight: 200.0, + maxWidth: 300.0, + child: StacText( + data: 'Hello, World! from Limited Box', + style: StacTextStyle(fontSize: 16, color: StacColors.black), + ), + ) + ``` + </Tab> + <Tab title="JSON"> + ```json + { + "type": "limitedBox", + "maxHeight": 200, + "maxWidth": 300, + "child": { + "type": "text", + "data": "Hello, World! from Limited Box", + "style": { "fontSize": 16, "color": "#000000" } + } + } + ``` + </Tab> + {/* Optionally add a Preview tab, following the Example 1 pattern. */} +</Tabs>Also worth adding the trailing newline back at EOF for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/limited_box.mdx` around lines 97 - 126, Example 2 in docs/widgets/limited_box.mdx still uses the old <CodeGroup> pattern and unnormalized float literals (e.g., 200.0, 300.0) causing visual inconsistency and no live preview; replace the <CodeGroup> block for Example 2 with a <Tabs sync={false}> containing <Tab title="Dart"> and <Tab title="JSON"> (optionally add a Preview tab like Example 1), move the StacLimitedBox Dart snippet into the Dart tab, convert JSON numeric fields ("maxHeight", "maxWidth") to integers (200, 300) in the JSON tab, and ensure the file ends with a trailing newline; refer to the existing Example 1 Tabs/Preview usage as the migration model.
♻️ Duplicate comments (1)
docs/widgets/positioned.mdx (1)
55-80:⚠️ Potential issue | 🟡 MinorKeep the code tabs aligned with the fixed preview payload.
The Preview tab now uses a
stack, but the Dart/JSON tabs still showPositionedas a standalone root. Wrap the examples too so copied examples match the preview and remain valid as a complete widget tree.Suggested update
-StacPositioned( - left: 10, - top: 20, - right: 30, - bottom: 40, - child: StacText(data: 'Hello, World!'), +StacStack( + children: [ + StacPositioned( + left: 10, + top: 20, + right: 30, + bottom: 40, + child: StacText(data: 'Hello, World!'), + ), + ], ){ - "type": "positioned", - "left": 10, - "top": 20, - "right": 30, - "bottom": 40, - "child": { - "type": "text", - "data": "Hello, World!" - } + "type": "stack", + "children": [ + { + "type": "positioned", + "left": 10, + "top": 20, + "right": 30, + "bottom": 40, + "child": { + "type": "text", + "data": "Hello, World!" + } + } + ] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/positioned.mdx` around lines 55 - 80, The Dart and JSON examples show StacPositioned as the root but the preview uses a stack; update both examples so they are wrapped in a Stack/root "stack" node so copied snippets form a complete widget tree: in the Dart tab wrap StacPositioned (and its StacText child) inside the same Stack construct used by the preview (e.g., a Stack containing StacPositioned), and in the JSON tab make the top-level object type "stack" with a children array that contains the positioned object (keep "type": "positioned", left/top/right/bottom and the nested text node intact).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/widgets/align.mdx`:
- Around line 11-28: The JSON preview payload for the Align example is missing
the clipBehavior property, causing it to differ from the Dart example; update
the alignPreviewJson payload in docs/widgets/align.mdx to include
"clipBehavior": "hardEdge" on the relevant align/container object so the Preview
tab renders the same documented payload as the Dart example and keeps JSON and
Preview consistent.
In `@docs/widgets/dynamic_view.mdx`:
- Around line 8-18: Update the dynamicView preview object dynamicViewPreviewJson
so it uses a reachable, deterministic endpoint and the correct template field:
change request.url to "https://dummyjson.com/users/1" and update template.data
to reference the returned user property by replacing "{{name}}" with
"{{firstName}}"; ensure the template.type ("text") and the
dynamicViewPreviewJson export remain unchanged.
In `@docs/widgets/sized_box.mdx`:
- Around line 8-12: sizedBoxPreviewJson currently specifies only
"type":"sizedBox" and "height":25 which renders blank; update
sizedBoxPreviewJson to include a simple child (e.g., a small container/box or
text element with a background color) so the Preview tab shows visible output,
and make the analogous change to the other sizedBox preview definitions
referenced (lines 30-41) so they also include a visible child; retain
sizedBoxPreviewSrc/PLAYGROUND_BASE_URL as-is.
In `@docs/widgets/sliver_to_box_adapter.mdx`:
- Around line 8-30: The preview JSON for sliverToBoxAdapter is not wrapped in a
CustomScrollView scaffold context; update sliverToBoxAdapterPreviewJson so its
root follows the same structure as other sliver docs by nesting the current
payload under the path scaffold > body > customScrollView > slivers (i.e., move
the existing sliverPadding/sliverToBoxAdapter object into a slivers array inside
a customScrollView body of a scaffold) so the sliver has the proper viewport
context for rendering.
---
Outside diff comments:
In `@docs/widgets/limited_box.mdx`:
- Around line 97-126: Example 2 in docs/widgets/limited_box.mdx still uses the
old <CodeGroup> pattern and unnormalized float literals (e.g., 200.0, 300.0)
causing visual inconsistency and no live preview; replace the <CodeGroup> block
for Example 2 with a <Tabs sync={false}> containing <Tab title="Dart"> and <Tab
title="JSON"> (optionally add a Preview tab like Example 1), move the
StacLimitedBox Dart snippet into the Dart tab, convert JSON numeric fields
("maxHeight", "maxWidth") to integers (200, 300) in the JSON tab, and ensure the
file ends with a trailing newline; refer to the existing Example 1 Tabs/Preview
usage as the migration model.
In `@docs/widgets/sliver_app_bar.mdx`:
- Around line 110-141: The JSON tab shows a top-level "sliverAppBar" that won't
render standalone and is out of sync with sliverAppBarPreviewJson; update the
JSON payload to wrap the sliverAppBar inside a scaffold -> customScrollView ->
slivers array (matching sliverAppBarPreviewJson) so users can copy a working
payload; also mirror this same scaffold/customScrollView/slivers wrapping in the
Dart tab if present to keep all tabs consistent.
---
Duplicate comments:
In `@docs/widgets/positioned.mdx`:
- Around line 55-80: The Dart and JSON examples show StacPositioned as the root
but the preview uses a stack; update both examples so they are wrapped in a
Stack/root "stack" node so copied snippets form a complete widget tree: in the
Dart tab wrap StacPositioned (and its StacText child) inside the same Stack
construct used by the preview (e.g., a Stack containing StacPositioned), and in
the JSON tab make the top-level object type "stack" with a children array that
contains the positioned object (keep "type": "positioned", left/top/right/bottom
and the nested text node intact).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: fc72eaf3-6577-47e7-b80d-0f203268c2a4
⛔ Files ignored due to path filters (4)
examples/counter_example/pubspec.lockis excluded by!**/*.lockexamples/movie_app/pubspec.lockis excluded by!**/*.lockexamples/stac_gallery/pubspec.lockis excluded by!**/*.lockpackages/stac_cli/pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (88)
docs/snippets/playground_base.mdxdocs/widgets/alert_dialog.mdxdocs/widgets/align.mdxdocs/widgets/app_bar.mdxdocs/widgets/aspect_ratio.mdxdocs/widgets/auto_complete.mdxdocs/widgets/backdrop_filter.mdxdocs/widgets/badge.mdxdocs/widgets/bottom_navigation_bar.mdxdocs/widgets/card.mdxdocs/widgets/carousel_view.mdxdocs/widgets/center.mdxdocs/widgets/check_box.mdxdocs/widgets/chip.mdxdocs/widgets/circle_avatar.mdxdocs/widgets/circular_progress_indicator.mdxdocs/widgets/clip_oval.mdxdocs/widgets/clip_rrect.mdxdocs/widgets/colored_box.mdxdocs/widgets/column.mdxdocs/widgets/conditional.mdxdocs/widgets/container.mdxdocs/widgets/custom_scroll_view.mdxdocs/widgets/divider.mdxdocs/widgets/drawer.mdxdocs/widgets/dropdown_menu.mdxdocs/widgets/dynamic_view.mdxdocs/widgets/elevated_button.mdxdocs/widgets/expanded.mdxdocs/widgets/filled_button.mdxdocs/widgets/fitted_box.mdxdocs/widgets/flexible.mdxdocs/widgets/floating_action_button.mdxdocs/widgets/form.mdxdocs/widgets/fractionally_sized_box.mdxdocs/widgets/gesture_detector.mdxdocs/widgets/grid_view.mdxdocs/widgets/hero.mdxdocs/widgets/icon.mdxdocs/widgets/icon_button.mdxdocs/widgets/image.mdxdocs/widgets/ink_well.mdxdocs/widgets/limited_box.mdxdocs/widgets/linear_progress_indicator.mdxdocs/widgets/list_tile.mdxdocs/widgets/listview.mdxdocs/widgets/network_widget.mdxdocs/widgets/opacity.mdxdocs/widgets/outlined_button.mdxdocs/widgets/padding.mdxdocs/widgets/page_view.mdxdocs/widgets/placeholder.mdxdocs/widgets/positioned.mdxdocs/widgets/radio_group.mdxdocs/widgets/refresh_indicator.mdxdocs/widgets/row.mdxdocs/widgets/safe_area.mdxdocs/widgets/scaffold.mdxdocs/widgets/selectable_text.mdxdocs/widgets/set_value.mdxdocs/widgets/single_child_scroll_view.mdxdocs/widgets/sized_box.mdxdocs/widgets/slider.mdxdocs/widgets/sliver_app_bar.mdxdocs/widgets/sliver_fill_remaining.mdxdocs/widgets/sliver_grid.mdxdocs/widgets/sliver_list.mdxdocs/widgets/sliver_opacity.mdxdocs/widgets/sliver_padding.mdxdocs/widgets/sliver_safe_area.mdxdocs/widgets/sliver_to_box_adapter.mdxdocs/widgets/sliver_visibility.mdxdocs/widgets/spacer.mdxdocs/widgets/stack.mdxdocs/widgets/switch.mdxdocs/widgets/tab_bar.mdxdocs/widgets/table.mdxdocs/widgets/table_cell.mdxdocs/widgets/table_row.mdxdocs/widgets/text.mdxdocs/widgets/text_button.mdxdocs/widgets/text_field.mdxdocs/widgets/text_form_field.mdxdocs/widgets/tool_tip.mdxdocs/widgets/vertical_divider.mdxdocs/widgets/visibility.mdxdocs/widgets/webview.mdxdocs/widgets/wrap.mdx
✅ Files skipped from review due to trivial changes (6)
- docs/snippets/playground_base.mdx
- docs/widgets/conditional.mdx
- docs/widgets/text_field.mdx
- docs/widgets/clip_rrect.mdx
- docs/widgets/sliver_fill_remaining.mdx
- docs/widgets/sliver_opacity.mdx
🚧 Files skipped from review as they are similar to previous changes (46)
- docs/widgets/app_bar.mdx
- docs/widgets/alert_dialog.mdx
- docs/widgets/linear_progress_indicator.mdx
- docs/widgets/safe_area.mdx
- docs/widgets/container.mdx
- docs/widgets/tool_tip.mdx
- docs/widgets/badge.mdx
- docs/widgets/form.mdx
- docs/widgets/visibility.mdx
- docs/widgets/webview.mdx
- docs/widgets/flexible.mdx
- docs/widgets/row.mdx
- docs/widgets/column.mdx
- docs/widgets/hero.mdx
- docs/widgets/tab_bar.mdx
- docs/widgets/network_widget.mdx
- docs/widgets/floating_action_button.mdx
- docs/widgets/vertical_divider.mdx
- docs/widgets/divider.mdx
- docs/widgets/center.mdx
- docs/widgets/drawer.mdx
- docs/widgets/carousel_view.mdx
- docs/widgets/refresh_indicator.mdx
- docs/widgets/fractionally_sized_box.mdx
- docs/widgets/selectable_text.mdx
- docs/widgets/scaffold.mdx
- docs/widgets/listview.mdx
- docs/widgets/circular_progress_indicator.mdx
- docs/widgets/image.mdx
- docs/widgets/expanded.mdx
- docs/widgets/stack.mdx
- docs/widgets/filled_button.mdx
- docs/widgets/spacer.mdx
- docs/widgets/table_cell.mdx
- docs/widgets/fitted_box.mdx
- docs/widgets/clip_oval.mdx
- docs/widgets/custom_scroll_view.mdx
- docs/widgets/sliver_safe_area.mdx
- docs/widgets/table_row.mdx
- docs/widgets/sliver_list.mdx
- docs/widgets/switch.mdx
- docs/widgets/slider.mdx
- docs/widgets/icon_button.mdx
- docs/widgets/elevated_button.mdx
- docs/widgets/sliver_grid.mdx
- docs/widgets/text.mdx
| export const dynamicViewPreviewJson = { | ||
| "type": "dynamicView", | ||
| "request": { | ||
| "url": "https://api.example.com/user/1", | ||
| "method": "get" | ||
| }, | ||
| "template": { | ||
| "type": "text", | ||
| "data": "Hello, {{name}}!" | ||
| } | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Confirm whether the preview URL returns JSON compatible with the template.
# Expected: A 2xx JSON response containing the fields used by the template.
python - <<'PY'
import urllib.request
url = "https://api.example.com/user/1"
try:
req = urllib.request.Request(url, headers={"Accept": "application/json"})
with urllib.request.urlopen(req, timeout=5) as response:
print("status:", response.status)
print("content-type:", response.headers.get("content-type"))
print("body-prefix:", response.read(200).decode("utf-8", errors="replace"))
except Exception as exc:
print(type(exc).__name__ + ":", exc)
PYRepository: StacDev/stac
Length of output: 118
🏁 Script executed:
# First, locate and read the file to confirm content
fd -t f "dynamic_view.mdx" --exec head -120 {}Repository: StacDev/stac
Length of output: 4127
🏁 Script executed:
# Test the suggested endpoint to confirm it returns compatible JSON
python - <<'PY'
import urllib.request
import json
url = "https://dummyjson.com/users/1"
try:
req = urllib.request.Request(url, headers={"Accept": "application/json"})
with urllib.request.urlopen(req, timeout=5) as response:
print("status:", response.status)
print("content-type:", response.headers.get("content-type"))
body = response.read().decode("utf-8")
data = json.loads(body)
print("response-keys:", list(data.keys()))
# Check for the fields mentioned in review
if "firstName" in data:
print("firstName:", data["firstName"])
if "name" in data:
print("name:", data["name"])
except Exception as exc:
print(type(exc).__name__ + ":", exc)
PYRepository: StacDev/stac
Length of output: 193
🏁 Script executed:
# Try with curl and disable SSL verification (for sandbox testing)
curl -s "https://dummyjson.com/users/1" 2>/dev/null | python - <<'PY'
import sys
import json
data = json.load(sys.stdin)
print("Available fields:", list(data.keys()))
print("\nRelevant fields:")
if "firstName" in data:
print(f" firstName: {data['firstName']}")
if "lastName" in data:
print(f" lastName: {data['lastName']}")
if "name" in data:
print(f" name: {data['name']}")
PYRepository: StacDev/stac
Length of output: 776
🌐 Web query:
dummyjson API users endpoint response structure firstName
💡 Result:
The DummyJSON API users endpoint (https://dummyjson.com/users) returns a JSON object with a "users" array containing user objects. Each user object includes a "firstName" field as a string property, such as "Emily" or "Terry". Example structure from official docs: { "users": [ { "id": 1, "firstName": "Emily", "lastName": "Johnson", ... }, ... ], "total": 208, "skip": 0, "limit": 30 }
Citations:
Make the DynamicView preview deterministic.
This live preview posts a network-backed dynamicView payload up to 12 times at 250ms intervals, and the URL is a placeholder endpoint that cannot be reached. If the playground applies each message, the preview repeatedly issues failing API requests instead of rendering a stable example.
Replace the placeholder endpoint with a real working endpoint and update the template field name accordingly. Use https://dummyjson.com/users/1 (which returns a user object with firstName), and update the template to use {{firstName}} instead of {{name}}.
🛠️ Corrected preview payload
export const dynamicViewPreviewJson = {
"type": "dynamicView",
"request": {
- "url": "https://api.example.com/user/1",
+ "url": "https://dummyjson.com/users/1",
"method": "get"
},
"template": {
"type": "text",
- "data": "Hello, {{name}}!"
+ "data": "Hello, {{firstName}}!"
}
};🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/widgets/dynamic_view.mdx` around lines 8 - 18, Update the dynamicView
preview object dynamicViewPreviewJson so it uses a reachable, deterministic
endpoint and the correct template field: change request.url to
"https://dummyjson.com/users/1" and update template.data to reference the
returned user property by replacing "{{name}}" with "{{firstName}}"; ensure the
template.type ("text") and the dynamicViewPreviewJson export remain unchanged.
| export const sizedBoxPreviewJson = { | ||
| "type": "sizedBox", | ||
| "height": 25 | ||
| }; | ||
| export const sizedBoxPreviewSrc = `${PLAYGROUND_BASE_URL}/embed`; |
There was a problem hiding this comment.
Make the SizedBox preview visibly render something.
A SizedBox with only height and no child/background produces a blank Preview tab, which can look broken. Add a small child so the live preview has visible output.
Suggested update
export const sizedBoxPreviewJson = {
"type": "sizedBox",
- "height": 25
+ "width": 160,
+ "height": 40,
+ "child": {
+ "type": "center",
+ "child": {
+ "type": "text",
+ "data": "SizedBox"
+ }
+ }
};-StacSizedBox(height: 25)
+StacSizedBox(
+ width: 160,
+ height: 40,
+ child: StacCenter(
+ child: StacText(data: 'SizedBox'),
+ ),
+) {
"type": "sizedBox",
- "height": 25
+ "width": 160,
+ "height": 40,
+ "child": {
+ "type": "center",
+ "child": {
+ "type": "text",
+ "data": "SizedBox"
+ }
+ }
}Also applies to: 30-41
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/widgets/sized_box.mdx` around lines 8 - 12, sizedBoxPreviewJson
currently specifies only "type":"sizedBox" and "height":25 which renders blank;
update sizedBoxPreviewJson to include a simple child (e.g., a small
container/box or text element with a background color) so the Preview tab shows
visible output, and make the analogous change to the other sizedBox preview
definitions referenced (lines 30-41) so they also include a visible child;
retain sizedBoxPreviewSrc/PLAYGROUND_BASE_URL as-is.
| export const sliverToBoxAdapterPreviewJson = { | ||
| "type": "sliverPadding", | ||
| "padding": 16, | ||
| "sliver": { | ||
| "type": "sliverToBoxAdapter", | ||
| "child": { | ||
| "type": "container", | ||
| "height": 150, | ||
| "color": "#4CAF50", | ||
| "child": { | ||
| "type": "center", | ||
| "child": { | ||
| "type": "text", | ||
| "data": "I am a Box inside a SliverToBoxAdapter!", | ||
| "style": { | ||
| "color": "#FFFFFF", | ||
| "fontWeight": "bold" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check whether the preview renderer already wraps root sliver payloads in a viewport.
# Expected: If no automatic sliver-root wrapper exists, sliver preview payloads should be wrapped in the MDX preview JSON.
rg -n -C3 'stac-preview-json|CustomScrollView|customScrollView|sliverToBoxAdapter|SliverToBoxAdapter'Repository: StacDev/stac
Length of output: 50371
🏁 Script executed:
#!/bin/bash
# Check other sliver widget docs to see if they wrap slivers
fd -e mdx docs/widgets/sliver | head -20Repository: StacDev/stac
Length of output: 38
🏁 Script executed:
#!/bin/bash
# Look for playground renderer or iframe postMessage handler
rg -l 'postMessage|iframe|stac-preview-json' docs/ --type mdx | head -10Repository: StacDev/stac
Length of output: 83
🏁 Script executed:
#!/bin/bash
# Check how sliver_visibility and sliver_padding docs handle preview JSON
for file in docs/widgets/sliver_*.mdx; do
echo "=== $file ==="
head -35 "$file" | grep -A 30 'export const'
doneRepository: StacDev/stac
Length of output: 7101
Wrap the preview payload in customScrollView to match other sliver widget docs.
All other sliver widget documentation (sliver_padding.mdx, sliver_opacity.mdx, sliver_safe_area.mdx, sliver_visibility.mdx, etc.) wrap their preview JSON in scaffold > body > customScrollView > slivers. The sliverToBoxAdapterPreviewJson should follow the same pattern since slivers require a viewport context to render.
🛠️ Proposed fix
export const sliverToBoxAdapterPreviewJson = {
+ "type": "scaffold",
+ "body": {
+ "type": "customScrollView",
+ "slivers": [
+ {
- "type": "sliverPadding",
- "padding": 16,
- "sliver": {
- "type": "sliverToBoxAdapter",
+ "type": "sliverPadding",
+ "padding": 16,
+ "sliver": {
+ "type": "sliverToBoxAdapter",
- "child": {
- "type": "container",
- "height": 150,
- "color": "#4CAF50",
- "child": {
- "type": "center",
- "child": {
- "type": "text",
- "data": "I am a Box inside a SliverToBoxAdapter!",
- "style": {
- "color": "#FFFFFF",
- "fontWeight": "bold"
+ "child": {
+ "type": "container",
+ "height": 150,
+ "color": "#4CAF50",
+ "child": {
+ "type": "center",
+ "child": {
+ "type": "text",
+ "data": "I am a Box inside a SliverToBoxAdapter!",
+ "style": {
+ "color": "#FFFFFF",
+ "fontWeight": "bold"
+ }
+ }
+ }
}
}
}
- }
- }
+ }
+ ]
+ }
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const sliverToBoxAdapterPreviewJson = { | |
| "type": "sliverPadding", | |
| "padding": 16, | |
| "sliver": { | |
| "type": "sliverToBoxAdapter", | |
| "child": { | |
| "type": "container", | |
| "height": 150, | |
| "color": "#4CAF50", | |
| "child": { | |
| "type": "center", | |
| "child": { | |
| "type": "text", | |
| "data": "I am a Box inside a SliverToBoxAdapter!", | |
| "style": { | |
| "color": "#FFFFFF", | |
| "fontWeight": "bold" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| export const sliverToBoxAdapterPreviewJson = { | |
| "type": "scaffold", | |
| "body": { | |
| "type": "customScrollView", | |
| "slivers": [ | |
| { | |
| "type": "sliverPadding", | |
| "padding": 16, | |
| "sliver": { | |
| "type": "sliverToBoxAdapter", | |
| "child": { | |
| "type": "container", | |
| "height": 150, | |
| "color": "#4CAF50", | |
| "child": { | |
| "type": "center", | |
| "child": { | |
| "type": "text", | |
| "data": "I am a Box inside a SliverToBoxAdapter!", | |
| "style": { | |
| "color": "#FFFFFF", | |
| "fontWeight": "bold" | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/widgets/sliver_to_box_adapter.mdx` around lines 8 - 30, The preview JSON
for sliverToBoxAdapter is not wrapped in a CustomScrollView scaffold context;
update sliverToBoxAdapterPreviewJson so its root follows the same structure as
other sliver docs by nesting the current payload under the path scaffold > body
> customScrollView > slivers (i.e., move the existing
sliverPadding/sliverToBoxAdapter object into a slivers array inside a
customScrollView body of a scaffold) so the sliver has the proper viewport
context for rendering.
- Refactored multiple widget documentation files to adopt a consistent scaffold structure for JSON representations. - Updated examples for Align, Positioned, SliverAppBar, SliverFillRemaining, SliverGrid, SliverOpacity, SliverPadding, SliverSafeArea, and SliverVisibility to enhance clarity and usability. - Adjusted the PLAYGROUND_BASE_URL for better accessibility in examples.
- Updated the JSON representation of the Align widget to include a Scaffold wrapper for better layout context. - Adjusted the Dart code examples to reflect the new structure and improved alignment properties. - Enhanced the documentation to clarify the usage of StacAlignmentDirectional for child alignment.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/widgets/sliver_grid.mdx (1)
119-176:⚠️ Potential issue | 🟡 MinorWrap the Dart example in scroll-view context to match the documented constraint.
Line 110 says
sliverGridmust be insidecustomScrollView, but the Dart snippet on Lines 120-175 showsStacSliverGridstandalone. This makes the copy/paste example inconsistent with the JSON/Preview payloads.🛠️ Suggested documentation fix
-const StacSliverGrid( - crossAxisCount: 2, - mainAxisSpacing: 16, - crossAxisSpacing: 16, - childAspectRatio: 1, - children: [ - ... - ], -) +StacScaffold( + body: StacCustomScrollView( + slivers: [ + const StacSliverGrid( + crossAxisCount: 2, + mainAxisSpacing: 16, + crossAxisSpacing: 16, + childAspectRatio: 1, + children: [ + ... + ], + ), + ], + ), +)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/sliver_grid.mdx` around lines 119 - 176, The example shows StacSliverGrid used standalone but must be nested inside a customScrollView per the docs; update the snippet so StacSliverGrid is wrapped by the customScrollView widget (e.g., place StacSliverGrid inside the children/slivers of customScrollView) so the example matches the documented constraint and the JSON/Preview payloads; keep the existing StacSliverGrid, children, and spacing values unchanged—only add the surrounding customScrollView wrapper.
♻️ Duplicate comments (1)
docs/widgets/align.mdx (1)
8-33:⚠️ Potential issue | 🟡 MinorKeep
alignPreviewJsonsynchronized with the Dart/JSON examples.
alignPreviewJsoncurrently diverges from the examples: Line 12 adds outer"alignment": "topEnd"that the tabs don’t show, and the preview payload omits theappBarpresent on Lines 87-93. This makes the Preview tab demonstrate a different configuration.🛠️ Suggested consistency patch
export const alignPreviewJson = { "type": "scaffold", + "appBar": { + "type": "appBar", + "title": { + "type": "text", + "data": "Align" + } + }, "body": { "type": "align", - "alignment": "topEnd", "child": { "type": "container", "color": "#FC5632",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/align.mdx` around lines 8 - 33, alignPreviewJson diverges from the Dart/JSON examples: remove the extra outer "alignment": "topEnd" from the top-level body and add the same appBar object used in the examples to the preview payload's body so the Preview tab matches the Dart/JSON tabs; update the alignPreviewJson object (and keep alignPreviewSrc as-is) to mirror the examples' structure exactly, referencing the alignPreviewJson symbol to locate the change.
🧹 Nitpick comments (1)
docs/widgets/ink_well.mdx (1)
146-163: Consider extracting the iframe postMessage retry block into a helper.The retry/onLoad block is repeated across widget docs; a small shared helper (or local function) would reduce drift and simplify future updates.
♻️ Example local extraction (same file)
+const postPreviewJsonToIframe = (iframe, payload) => { + const targetOrigin = PLAYGROUND_BASE_URL; + const message = { type: "stac-preview-json", payload }; + let attempts = 0; + const maxAttempts = 12; + const interval = setInterval(() => { + iframe.contentWindow?.postMessage(message, targetOrigin); + attempts += 1; + if (attempts >= maxAttempts) clearInterval(interval); + }, 250); +}; ... - onLoad={(event) => { - const iframe = event.currentTarget; - const targetOrigin = PLAYGROUND_BASE_URL; - const message = { - type: "stac-preview-json", - payload: inkWellPreviewJson - }; - - let attempts = 0; - const maxAttempts = 12; - const interval = setInterval(() => { - iframe.contentWindow?.postMessage(message, targetOrigin); - attempts += 1; - - if (attempts >= maxAttempts) { - clearInterval(interval); - } - }, 250); - }} + onLoad={(event) => { + postPreviewJsonToIframe(event.currentTarget, inkWellPreviewJson); + }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/widgets/ink_well.mdx` around lines 146 - 163, Extract the repeated postMessage retry logic into a reusable helper function (e.g., sendPostMessageWithRetries) that accepts the iframe element (or its contentWindow), the message object, targetOrigin, maxAttempts (default 12) and delayMs (default 250); implement the same behavior (postMessage, increment attempts, clearInterval when reaching max) and replace the inline onLoad block in ink_well.mdx by calling this helper from the onLoad handler so the file only constructs message/targetOrigin and invokes sendPostMessageWithRetries(iframe, message, targetOrigin).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@docs/widgets/sliver_grid.mdx`:
- Around line 119-176: The example shows StacSliverGrid used standalone but must
be nested inside a customScrollView per the docs; update the snippet so
StacSliverGrid is wrapped by the customScrollView widget (e.g., place
StacSliverGrid inside the children/slivers of customScrollView) so the example
matches the documented constraint and the JSON/Preview payloads; keep the
existing StacSliverGrid, children, and spacing values unchanged—only add the
surrounding customScrollView wrapper.
---
Duplicate comments:
In `@docs/widgets/align.mdx`:
- Around line 8-33: alignPreviewJson diverges from the Dart/JSON examples:
remove the extra outer "alignment": "topEnd" from the top-level body and add the
same appBar object used in the examples to the preview payload's body so the
Preview tab matches the Dart/JSON tabs; update the alignPreviewJson object (and
keep alignPreviewSrc as-is) to mirror the examples' structure exactly,
referencing the alignPreviewJson symbol to locate the change.
---
Nitpick comments:
In `@docs/widgets/ink_well.mdx`:
- Around line 146-163: Extract the repeated postMessage retry logic into a
reusable helper function (e.g., sendPostMessageWithRetries) that accepts the
iframe element (or its contentWindow), the message object, targetOrigin,
maxAttempts (default 12) and delayMs (default 250); implement the same behavior
(postMessage, increment attempts, clearInterval when reaching max) and replace
the inline onLoad block in ink_well.mdx by calling this helper from the onLoad
handler so the file only constructs message/targetOrigin and invokes
sendPostMessageWithRetries(iframe, message, targetOrigin).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e000bd22-4136-4d98-9521-1e7c2255d796
📒 Files selected for processing (11)
docs/snippets/playground_base.mdxdocs/widgets/align.mdxdocs/widgets/ink_well.mdxdocs/widgets/positioned.mdxdocs/widgets/sliver_app_bar.mdxdocs/widgets/sliver_fill_remaining.mdxdocs/widgets/sliver_grid.mdxdocs/widgets/sliver_opacity.mdxdocs/widgets/sliver_padding.mdxdocs/widgets/sliver_safe_area.mdxdocs/widgets/sliver_visibility.mdx
🚧 Files skipped from review as they are similar to previous changes (7)
- docs/snippets/playground_base.mdx
- docs/widgets/positioned.mdx
- docs/widgets/sliver_fill_remaining.mdx
- docs/widgets/sliver_padding.mdx
- docs/widgets/sliver_safe_area.mdx
- docs/widgets/sliver_visibility.mdx
- docs/widgets/sliver_opacity.mdx
- Updated the SliverGrid documentation to adopt a consistent structure, including a customScrollView wrapper. - Simplified the JSON representation and Dart code examples for both SliverGrid and Align widgets. - Enhanced clarity in the documentation to improve usability and understanding of widget properties.
Description
Type of Change
Summary by CodeRabbit