diff --git a/biome.json b/biome.json index 9f2044a..a1804f6 100644 --- a/biome.json +++ b/biome.json @@ -38,7 +38,8 @@ "noSvgWithoutTitle": "off", "useButtonType": "off", "useFocusableInteractive": "off", - "useKeyWithClickEvents": "off" + "useKeyWithClickEvents": "off", + "noAutofocus": "off" }, "suspicious": { "noArrayIndexKey": "off", diff --git a/registry.json b/registry.json index 0c939c8..0adac32 100644 --- a/registry.json +++ b/registry.json @@ -345,7 +345,8 @@ "@nteract/isolated-frame", "@nteract/widget-store", "@nteract/markdown-output", - "@nteract/error-boundary" + "@nteract/error-boundary", + "@nteract/highlight-text" ], "files": [ { @@ -948,6 +949,19 @@ } ] }, + { + "name": "highlight-text", + "type": "registry:lib", + "title": "Highlight Text", + "description": "DOM utility for highlighting search matches in text content with customizable styling.", + "files": [ + { + "path": "registry/lib/highlight-text.ts", + "type": "registry:lib", + "target": "lib/highlight-text.ts" + } + ] + }, { "name": "isolated-renderer", "type": "registry:component", diff --git a/registry/cell/CellContainer.tsx b/registry/cell/CellContainer.tsx index d55e144..d453bc8 100644 --- a/registry/cell/CellContainer.tsx +++ b/registry/cell/CellContainer.tsx @@ -94,7 +94,7 @@ export const CellContainer = forwardRef( ribbonColor, )} /> -
{codeContent}
+
{codeContent}
{/* Output row - ribbon + content together */} {hasOutput && ( @@ -107,7 +107,7 @@ export const CellContainer = forwardRef( />
@@ -125,7 +125,7 @@ export const CellContainer = forwardRef( ribbonColor, )} /> -
{children}
+
{children}
)} {/* Right margin - pt-3 aligns with left gutter, appears on hover/focus */} diff --git a/registry/cell/CellTypeSelector.tsx b/registry/cell/CellTypeSelector.tsx index 6301305..88fb923 100644 --- a/registry/cell/CellTypeSelector.tsx +++ b/registry/cell/CellTypeSelector.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Bot, ChevronDown, Code, Database, FileText } from "lucide-react"; import { Button } from "@/components/ui/button"; import { diff --git a/registry/cell/CollaboratorAvatars.tsx b/registry/cell/CollaboratorAvatars.tsx index 54de622..6914c0a 100644 --- a/registry/cell/CollaboratorAvatars.tsx +++ b/registry/cell/CollaboratorAvatars.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as React from "react"; import { Avatar, diff --git a/registry/cell/CompactExecutionButton.tsx b/registry/cell/CompactExecutionButton.tsx index 3d5071f..0339c89 100644 --- a/registry/cell/CompactExecutionButton.tsx +++ b/registry/cell/CompactExecutionButton.tsx @@ -38,7 +38,6 @@ export function CompactExecutionButton({ return ( @@ -480,34 +528,37 @@ export function OutputArea({ )} {/* In-DOM outputs (when not using isolation) */} - {!shouldIsolate && - outputs.map((output, index) => ( -
- ( - - )} - onError={(error, errorInfo) => { - console.error( - `[OutputArea] Error rendering output ${index}:`, - error, - errorInfo.componentStack, - ); - }} + {!shouldIsolate && ( +
+ {outputs.map((output, index) => ( +
- {renderOutput(output, index, renderers, priority)} - -
- ))} + ( + + )} + onError={(error, errorInfo) => { + console.error( + `[OutputArea] Error rendering output ${index}:`, + error, + errorInfo.componentStack, + ); + }} + > + {renderOutput(output, index, renderers, priority)} + +
+ ))} +
+ )} )} diff --git a/registry/cell/PresenceBookmarks.tsx b/registry/cell/PresenceBookmarks.tsx index 7c6a907..1aa0366 100644 --- a/registry/cell/PresenceBookmarks.tsx +++ b/registry/cell/PresenceBookmarks.tsx @@ -1,5 +1,3 @@ -"use client"; - import type * as React from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { diff --git a/registry/editor/extensions.ts b/registry/editor/extensions.ts index 86b8059..2f251cf 100644 --- a/registry/editor/extensions.ts +++ b/registry/editor/extensions.ts @@ -34,6 +34,11 @@ export const notebookEditorTheme = EditorView.theme({ "&.cm-focused": { outline: "none", }, + // Reset line padding so code aligns with output areas + // (CodeMirror's base theme adds "padding: 0 2px 0 6px" to .cm-line) + ".cm-line": { + paddingLeft: "0", + }, // Mobile-friendly padding "@media (max-width: 640px)": { ".cm-content": { diff --git a/registry/lib/highlight-text.ts b/registry/lib/highlight-text.ts new file mode 100644 index 0000000..870747c --- /dev/null +++ b/registry/lib/highlight-text.ts @@ -0,0 +1,66 @@ +/** + * Highlight all occurrences of a search query within a DOM container. + * + * Walks text nodes using TreeWalker, wraps matches in elements. + * Returns a cleanup function that removes all marks and restores text nodes. + */ +export function highlightTextInDom( + container: HTMLElement, + query: string, +): () => void { + if (!query) return () => {}; + + const marks: HTMLElement[] = []; + const walker = document.createTreeWalker( + container, + NodeFilter.SHOW_TEXT, + null, + ); + const lowerQuery = query.toLowerCase(); + + // Collect matches first (to avoid mutating DOM while walking) + const matches: { node: Text; offset: number; length: number }[] = []; + let node = walker.nextNode(); + while (node) { + const text = node.nodeValue || ""; + const lowerText = text.toLowerCase(); + let pos = lowerText.indexOf(lowerQuery, 0); + while (pos !== -1) { + matches.push({ node: node as Text, offset: pos, length: query.length }); + pos = lowerText.indexOf(lowerQuery, pos + query.length); + } + node = walker.nextNode(); + } + + // Apply highlights in reverse order to preserve offsets + for (let i = matches.length - 1; i >= 0; i--) { + const m = matches[i]; + try { + const range = document.createRange(); + range.setStart(m.node, m.offset); + range.setEnd(m.node, m.offset + m.length); + const mark = document.createElement("mark"); + mark.className = "global-find-match"; + mark.style.cssText = + "background: #fbbf24; color: #000; border-radius: 2px; padding: 0;"; + range.surroundContents(mark); + marks.unshift(mark); + } catch { + // surroundContents can fail if range crosses element boundaries + } + } + + // Return cleanup function + return () => { + for (const mark of marks) { + const parent = mark.parentNode; + if (parent) { + while (mark.firstChild) { + parent.insertBefore(mark.firstChild, mark); + } + parent.removeChild(mark); + parent.normalize(); + } + } + }; +} diff --git a/registry/lib/widget-error-fallback.tsx b/registry/lib/widget-error-fallback.tsx index 7c4464c..ee7efe6 100644 --- a/registry/lib/widget-error-fallback.tsx +++ b/registry/lib/widget-error-fallback.tsx @@ -1,5 +1,3 @@ -"use client"; - import { cn } from "@/lib/utils"; export interface WidgetErrorFallbackProps { diff --git a/registry/outputs/isolated/__tests__/comm-bridge-manager.test.ts b/registry/outputs/isolated/__tests__/comm-bridge-manager.test.ts index 992e092..1e645bb 100644 --- a/registry/outputs/isolated/__tests__/comm-bridge-manager.test.ts +++ b/registry/outputs/isolated/__tests__/comm-bridge-manager.test.ts @@ -90,6 +90,8 @@ function createMockFrame(): { eval: vi.fn(), setTheme: vi.fn(), clear: vi.fn(), + search: vi.fn(), + searchNavigate: vi.fn(), isReady: true, isIframeReady: true, }; diff --git a/registry/outputs/isolated/comm-bridge-manager.ts b/registry/outputs/isolated/comm-bridge-manager.ts index efb5332..45d534a 100644 --- a/registry/outputs/isolated/comm-bridge-manager.ts +++ b/registry/outputs/isolated/comm-bridge-manager.ts @@ -370,9 +370,11 @@ export class CommBridgeManager { const unsubscribe = this.store.subscribeToCustomMessage( commId, - (content, buffers) => { + (content: Record, buffers?: DataView[]) => { // Convert DataView[] to ArrayBuffer[] for postMessage - const arrayBuffers = buffers?.map((dv) => dv.buffer as ArrayBuffer); + const arrayBuffers = buffers?.map( + (dv: DataView) => dv.buffer as ArrayBuffer, + ); // Forward custom message to iframe this.sendCommMsg(commId, "custom", content, arrayBuffers); }, diff --git a/registry/outputs/isolated/frame-bridge.ts b/registry/outputs/isolated/frame-bridge.ts index 5952489..3cfa119 100644 --- a/registry/outputs/isolated/frame-bridge.ts +++ b/registry/outputs/isolated/frame-bridge.ts @@ -168,6 +168,33 @@ export interface BridgeReadyMessage { type: "bridge_ready"; } +// --- Global Find: Parent → Iframe --- + +/** + * Search for text within the iframe's rendered content. + * The iframe should highlight all matches and report the count. + */ +export interface SearchMessage { + type: "search"; + payload: { + /** The search query string (empty string clears search) */ + query: string; + /** Whether the search should be case-sensitive */ + caseSensitive?: boolean; + }; +} + +/** + * Navigate to a specific match in the iframe's search results. + */ +export interface SearchNavigateMessage { + type: "search_navigate"; + payload: { + /** The index of the match to navigate to (0-based) */ + matchIndex: number; + }; +} + /** * All message types that can be sent from parent to iframe. */ @@ -182,7 +209,9 @@ export type ParentToIframeMessage = | CommMsgMessage | CommCloseMessage | CommSyncMessage - | BridgeReadyMessage; + | BridgeReadyMessage + | SearchMessage + | SearchNavigateMessage; // --- Message Types: Iframe → Parent --- @@ -337,6 +366,20 @@ export interface WidgetCommCloseMessage { }; } +// --- Global Find: Iframe → Parent --- + +/** + * Report search results from the iframe. + * Sent after processing a search message. + */ +export interface SearchResultsMessage { + type: "search_results"; + payload: { + /** Number of matches found */ + count: number; + }; +} + /** * All message types that can be sent from iframe to parent. */ @@ -353,7 +396,8 @@ export type IframeToParentMessage = | RendererReadyMessage | WidgetReadyMessage | WidgetCommMsgMessage - | WidgetCommCloseMessage; + | WidgetCommCloseMessage + | SearchResultsMessage; // --- Utility Types --- @@ -389,6 +433,7 @@ export function isIframeMessage(data: unknown): data is IframeToParentMessage { "widget_ready", "widget_comm_msg", "widget_comm_close", + "search_results", ].includes(msg.type) ); } diff --git a/registry/outputs/isolated/frame-html.ts b/registry/outputs/isolated/frame-html.ts index 50cb1a6..4e9aa8d 100644 --- a/registry/outputs/isolated/frame-html.ts +++ b/registry/outputs/isolated/frame-html.ts @@ -69,16 +69,11 @@ export function generateFrameHtml(options: FrameHtmlOptions = {}): string { margin: 0; padding: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - font-size: 14px; line-height: 1.5; background: transparent; color: var(--text-primary); } - body { - padding: 8px; - } - /* Output container */ #root { min-height: 1px; @@ -200,6 +195,14 @@ export function generateFrameHtml(options: FrameHtmlOptions = {}): string { handleWidgetState(payload); break; + case 'search': + handleSearch(payload); + break; + + case 'search_navigate': + handleSearchNavigate(payload); + break; + // Comm bridge messages - handled by React widget system, ignore here case 'bridge_ready': case 'comm_open': @@ -393,6 +396,85 @@ export function generateFrameHtml(options: FrameHtmlOptions = {}): string { window.dispatchEvent(new CustomEvent('widget_state', { detail: payload })); } + // --- Search --- + var searchMarks = []; + var currentSearchIndex = -1; + + function handleSearch(payload) { + var query = (payload && payload.query) || ''; + var caseSensitive = payload && payload.caseSensitive; + clearSearchMarks(); + if (!query) { + send('search_results', { count: 0 }); + return; + } + var marks = []; + var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null); + var node; + var compareQuery = caseSensitive ? query : query.toLowerCase(); + // Collect all text nodes and their match positions + var matches = []; + while ((node = walker.nextNode())) { + var text = node.nodeValue || ''; + var compareText = caseSensitive ? text : text.toLowerCase(); + var pos = 0; + while ((pos = compareText.indexOf(compareQuery, pos)) !== -1) { + matches.push({ node: node, offset: pos, length: query.length }); + pos += query.length; + } + } + // Highlight matches in reverse order to preserve offsets + for (var i = matches.length - 1; i >= 0; i--) { + var m = matches[i]; + try { + var range = document.createRange(); + range.setStart(m.node, m.offset); + range.setEnd(m.node, m.offset + m.length); + var mark = document.createElement('mark'); + mark.className = 'global-find-match'; + mark.style.cssText = 'background: #fbbf24; color: #000; border-radius: 2px; padding: 0;'; + range.surroundContents(mark); + marks.unshift(mark); + } catch (e) { + // surroundContents can fail if range crosses element boundaries + } + } + searchMarks = marks; + currentSearchIndex = -1; + send('search_results', { count: marks.length }); + } + + function handleSearchNavigate(payload) { + var matchIndex = (payload && payload.matchIndex) || 0; + if (searchMarks.length === 0) return; + // Clear previous active highlight + if (currentSearchIndex >= 0 && currentSearchIndex < searchMarks.length) { + searchMarks[currentSearchIndex].style.cssText = 'background: #fbbf24; color: #000; border-radius: 2px; padding: 0;'; + } + currentSearchIndex = matchIndex; + if (currentSearchIndex >= 0 && currentSearchIndex < searchMarks.length) { + var active = searchMarks[currentSearchIndex]; + active.style.cssText = 'background: #f97316; color: #000; border-radius: 2px; padding: 0;'; + active.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); + } + } + + function clearSearchMarks() { + for (var i = 0; i < searchMarks.length; i++) { + var mark = searchMarks[i]; + var parent = mark.parentNode; + if (parent) { + while (mark.firstChild) { + parent.insertBefore(mark.firstChild, mark); + } + parent.removeChild(mark); + parent.normalize(); + } + } + searchMarks = []; + currentSearchIndex = -1; + } + // --- Utilities --- function send(type, payload) { diff --git a/registry/outputs/isolated/index.ts b/registry/outputs/isolated/index.ts index 495db33..8f3e9b8 100644 --- a/registry/outputs/isolated/index.ts +++ b/registry/outputs/isolated/index.ts @@ -1,6 +1,3 @@ -// Production components - -// Widget comm bridge for isolated frames export { CommBridgeManager, createCommBridgeManager, diff --git a/registry/outputs/isolated/isolated-frame.tsx b/registry/outputs/isolated/isolated-frame.tsx index 2caf17b..54b669e 100644 --- a/registry/outputs/isolated/isolated-frame.tsx +++ b/registry/outputs/isolated/isolated-frame.tsx @@ -112,6 +112,17 @@ export interface IsolatedFrameHandle { */ clear: () => void; + /** + * Search for text within the iframe's rendered content. + * Pass empty string to clear search highlights. + */ + search: (query: string, caseSensitive?: boolean) => void; + + /** + * Navigate to a specific search match by index. + */ + searchNavigate: (matchIndex: number) => void; + /** * Whether the iframe is ready to receive messages. * True after the React renderer bundle is initialized. @@ -431,6 +442,24 @@ export const IsolatedFrame = forwardRef< setTheme: (isDark: boolean) => send({ type: "theme", payload: { isDark } }), clear: () => send({ type: "clear" }), + search: (query: string, caseSensitive?: boolean) => { + // Search handler is in bootstrap HTML, so send directly when iframe is loaded + // (bypasses the isReady queue which waits for the React renderer) + if (iframeRef.current?.contentWindow) { + iframeRef.current.contentWindow.postMessage( + { type: "search", payload: { query, caseSensitive } }, + "*", + ); + } + }, + searchNavigate: (matchIndex: number) => { + if (iframeRef.current?.contentWindow) { + iframeRef.current.contentWindow.postMessage( + { type: "search_navigate", payload: { matchIndex } }, + "*", + ); + } + }, isReady, isIframeReady, }), diff --git a/registry/outputs/media-router.tsx b/registry/outputs/media-router.tsx index 6d309a6..c9da0a6 100644 --- a/registry/outputs/media-router.tsx +++ b/registry/outputs/media-router.tsx @@ -1,5 +1,3 @@ -"use client"; - import { lazy, type ReactNode, Suspense } from "react"; import { useMediaContext } from "./media-provider"; @@ -346,6 +344,19 @@ export function MediaRouter({ return {String(content)}; } + // Widget view JSON - when rendered in-DOM without a widget renderer, + // show a helpful message instead of raw JSON. This typically happens + // when a widget is displayed inside an Output widget. + if (mimeType === "application/vnd.jupyter.widget-view+json") { + return ( +
+ Nested widget + · + Widgets inside Output widgets are not yet supported +
+ ); + } + // Unknown +json types without custom renderer - show as JSON if (mimeType.includes("+json")) { return ( diff --git a/registry/widgets/controls/accordion-widget.tsx b/registry/widgets/controls/accordion-widget.tsx index 6f71125..ea5dd9e 100644 --- a/registry/widgets/controls/accordion-widget.tsx +++ b/registry/widgets/controls/accordion-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Accordion widget - collapsible panel container. * diff --git a/registry/widgets/controls/audio-widget.tsx b/registry/widgets/controls/audio-widget.tsx index e5a8ad4..6bf2265 100644 --- a/registry/widgets/controls/audio-widget.tsx +++ b/registry/widgets/controls/audio-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Audio widget - plays audio from the kernel. * diff --git a/registry/widgets/controls/box-widget.tsx b/registry/widgets/controls/box-widget.tsx index 7de0aab..42ac3dd 100644 --- a/registry/widgets/controls/box-widget.tsx +++ b/registry/widgets/controls/box-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Box widget - generic flex container. * diff --git a/registry/widgets/controls/button-widget.tsx b/registry/widgets/controls/button-widget.tsx index 1f9832e..fadf225 100644 --- a/registry/widgets/controls/button-widget.tsx +++ b/registry/widgets/controls/button-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Button widget - renders a clickable button. * diff --git a/registry/widgets/controls/checkbox-widget.tsx b/registry/widgets/controls/checkbox-widget.tsx index 61dcdd3..9beadf6 100644 --- a/registry/widgets/controls/checkbox-widget.tsx +++ b/registry/widgets/controls/checkbox-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Checkbox widget - renders a checkbox input. * diff --git a/registry/widgets/controls/color-picker.tsx b/registry/widgets/controls/color-picker.tsx index 4f00606..b543c03 100644 --- a/registry/widgets/controls/color-picker.tsx +++ b/registry/widgets/controls/color-picker.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * ColorPicker widget - renders a color selection input. * diff --git a/registry/widgets/controls/controller-axis-widget.tsx b/registry/widgets/controls/controller-axis-widget.tsx index a085465..ba219b0 100644 --- a/registry/widgets/controls/controller-axis-widget.tsx +++ b/registry/widgets/controls/controller-axis-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * ControllerAxis widget - displays a gamepad axis value. * diff --git a/registry/widgets/controls/controller-button-widget.tsx b/registry/widgets/controls/controller-button-widget.tsx index a2c95b7..e664a81 100644 --- a/registry/widgets/controls/controller-button-widget.tsx +++ b/registry/widgets/controls/controller-button-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * ControllerButton widget - displays a gamepad button state. * diff --git a/registry/widgets/controls/dropdown-widget.tsx b/registry/widgets/controls/dropdown-widget.tsx index e788363..788d364 100644 --- a/registry/widgets/controls/dropdown-widget.tsx +++ b/registry/widgets/controls/dropdown-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Dropdown widget - renders a native select dropdown. * diff --git a/registry/widgets/controls/float-log-slider.tsx b/registry/widgets/controls/float-log-slider.tsx index 2e88492..08d617c 100644 --- a/registry/widgets/controls/float-log-slider.tsx +++ b/registry/widgets/controls/float-log-slider.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * FloatLogSlider widget - renders a logarithmic scale slider. * diff --git a/registry/widgets/controls/float-progress.tsx b/registry/widgets/controls/float-progress.tsx index ce1d681..6a4b8c3 100644 --- a/registry/widgets/controls/float-progress.tsx +++ b/registry/widgets/controls/float-progress.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * FloatProgress widget - renders a floating point progress bar. * diff --git a/registry/widgets/controls/float-range-slider.tsx b/registry/widgets/controls/float-range-slider.tsx index 7ab5456..ecdda79 100644 --- a/registry/widgets/controls/float-range-slider.tsx +++ b/registry/widgets/controls/float-range-slider.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * FloatRangeSlider widget - renders a dual-handle range slider for floats. * diff --git a/registry/widgets/controls/float-slider.tsx b/registry/widgets/controls/float-slider.tsx index 0d89356..5a3de2b 100644 --- a/registry/widgets/controls/float-slider.tsx +++ b/registry/widgets/controls/float-slider.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * FloatSlider widget - renders a floating point slider. * diff --git a/registry/widgets/controls/gridbox-widget.tsx b/registry/widgets/controls/gridbox-widget.tsx index 71d414d..f6a4cbe 100644 --- a/registry/widgets/controls/gridbox-widget.tsx +++ b/registry/widgets/controls/gridbox-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * GridBox widget - CSS grid container. * diff --git a/registry/widgets/controls/hbox-widget.tsx b/registry/widgets/controls/hbox-widget.tsx index cca35ad..7a7e2d2 100644 --- a/registry/widgets/controls/hbox-widget.tsx +++ b/registry/widgets/controls/hbox-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * HBox widget - horizontal flex container. * diff --git a/registry/widgets/controls/html-math-widget.tsx b/registry/widgets/controls/html-math-widget.tsx index a642563..349710b 100644 --- a/registry/widgets/controls/html-math-widget.tsx +++ b/registry/widgets/controls/html-math-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * HTMLMath widget - renders HTML content with LaTeX math support. * diff --git a/registry/widgets/controls/html-widget.tsx b/registry/widgets/controls/html-widget.tsx index 0abcb21..f56e917 100644 --- a/registry/widgets/controls/html-widget.tsx +++ b/registry/widgets/controls/html-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * HTML widget - renders arbitrary HTML content. * diff --git a/registry/widgets/controls/image-widget.tsx b/registry/widgets/controls/image-widget.tsx index f4767c0..269d121 100644 --- a/registry/widgets/controls/image-widget.tsx +++ b/registry/widgets/controls/image-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Image widget - displays images from the kernel. * diff --git a/registry/widgets/controls/int-progress.tsx b/registry/widgets/controls/int-progress.tsx index 7edc0b4..a0e4f0b 100644 --- a/registry/widgets/controls/int-progress.tsx +++ b/registry/widgets/controls/int-progress.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * IntProgress widget - renders an integer progress bar. * diff --git a/registry/widgets/controls/int-range-slider.tsx b/registry/widgets/controls/int-range-slider.tsx index a6122f3..36a9913 100644 --- a/registry/widgets/controls/int-range-slider.tsx +++ b/registry/widgets/controls/int-range-slider.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * IntRangeSlider widget - renders a dual-handle range slider for integers. * diff --git a/registry/widgets/controls/int-slider.tsx b/registry/widgets/controls/int-slider.tsx index de28597..cf73b82 100644 --- a/registry/widgets/controls/int-slider.tsx +++ b/registry/widgets/controls/int-slider.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * IntSlider widget - renders an integer slider. * diff --git a/registry/widgets/controls/label-widget.tsx b/registry/widgets/controls/label-widget.tsx index 8155aa4..509a6c6 100644 --- a/registry/widgets/controls/label-widget.tsx +++ b/registry/widgets/controls/label-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Label widget - renders plain text content. * diff --git a/registry/widgets/controls/link-widget.tsx b/registry/widgets/controls/link-widget.tsx index ddba0df..b36d1dc 100644 --- a/registry/widgets/controls/link-widget.tsx +++ b/registry/widgets/controls/link-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Link widgets — frontend-only property synchronization. * diff --git a/registry/widgets/controls/radio-buttons-widget.tsx b/registry/widgets/controls/radio-buttons-widget.tsx index 20c1743..9c4b6f5 100644 --- a/registry/widgets/controls/radio-buttons-widget.tsx +++ b/registry/widgets/controls/radio-buttons-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * RadioButtons widget - renders a group of radio buttons. * diff --git a/registry/widgets/controls/select-multiple-widget.tsx b/registry/widgets/controls/select-multiple-widget.tsx index 22ada8e..bcfbd4d 100644 --- a/registry/widgets/controls/select-multiple-widget.tsx +++ b/registry/widgets/controls/select-multiple-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * SelectMultiple widget - renders a multi-select listbox. * diff --git a/registry/widgets/controls/select-widget.tsx b/registry/widgets/controls/select-widget.tsx index 7153185..5cbe168 100644 --- a/registry/widgets/controls/select-widget.tsx +++ b/registry/widgets/controls/select-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Select widget - renders a single-selection listbox. * diff --git a/registry/widgets/controls/selection-range-slider-widget.tsx b/registry/widgets/controls/selection-range-slider-widget.tsx index da6a609..f0a2ff1 100644 --- a/registry/widgets/controls/selection-range-slider-widget.tsx +++ b/registry/widgets/controls/selection-range-slider-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * SelectionRangeSlider widget - range slider that selects from discrete options. * diff --git a/registry/widgets/controls/selection-slider-widget.tsx b/registry/widgets/controls/selection-slider-widget.tsx index a5e42fc..3048494 100644 --- a/registry/widgets/controls/selection-slider-widget.tsx +++ b/registry/widgets/controls/selection-slider-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * SelectionSlider widget - slider that selects from discrete options. * diff --git a/registry/widgets/controls/stack-widget.tsx b/registry/widgets/controls/stack-widget.tsx index c10b229..ec401ec 100644 --- a/registry/widgets/controls/stack-widget.tsx +++ b/registry/widgets/controls/stack-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Stack widget - single-child container showing one child at a time. * diff --git a/registry/widgets/controls/tab-widget.tsx b/registry/widgets/controls/tab-widget.tsx index 6789a62..967d3a7 100644 --- a/registry/widgets/controls/tab-widget.tsx +++ b/registry/widgets/controls/tab-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Tab widget - tabbed panel container. * diff --git a/registry/widgets/controls/toggle-button-widget.tsx b/registry/widgets/controls/toggle-button-widget.tsx index 2659567..28a665f 100644 --- a/registry/widgets/controls/toggle-button-widget.tsx +++ b/registry/widgets/controls/toggle-button-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * ToggleButton widget - renders a single toggle button. * diff --git a/registry/widgets/controls/toggle-buttons-widget.tsx b/registry/widgets/controls/toggle-buttons-widget.tsx index 0a4e567..edec4ab 100644 --- a/registry/widgets/controls/toggle-buttons-widget.tsx +++ b/registry/widgets/controls/toggle-buttons-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * ToggleButtons widget - renders a group of toggle buttons (single selection). * diff --git a/registry/widgets/controls/valid-widget.tsx b/registry/widgets/controls/valid-widget.tsx index 70fafd5..af0a584 100644 --- a/registry/widgets/controls/valid-widget.tsx +++ b/registry/widgets/controls/valid-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Valid widget - displays a validation indicator (checkmark or X). * diff --git a/registry/widgets/controls/vbox-widget.tsx b/registry/widgets/controls/vbox-widget.tsx index 879a837..ea1239d 100644 --- a/registry/widgets/controls/vbox-widget.tsx +++ b/registry/widgets/controls/vbox-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * VBox widget - vertical flex container. * diff --git a/registry/widgets/controls/video-widget.tsx b/registry/widgets/controls/video-widget.tsx index 37599e3..206f11c 100644 --- a/registry/widgets/controls/video-widget.tsx +++ b/registry/widgets/controls/video-widget.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Video widget - plays video from the kernel. * diff --git a/registry/widgets/ipycanvas/index.ts b/registry/widgets/ipycanvas/index.ts index 89297db..74167d5 100644 --- a/registry/widgets/ipycanvas/index.ts +++ b/registry/widgets/ipycanvas/index.ts @@ -1,10 +1,3 @@ -/** - * ipycanvas widget registration. - * - * Registers CanvasModel and CanvasManagerModel with the widget registry. - * Import this module to enable rendering of ipycanvas widgets. - */ - import { registerWidget } from "../widget-registry"; import { CanvasManagerWidget, CanvasWidget } from "./canvas-widget"; diff --git a/registry/widgets/use-comm-router.ts b/registry/widgets/use-comm-router.ts index 2f87c17..21ee3ca 100644 --- a/registry/widgets/use-comm-router.ts +++ b/registry/widgets/use-comm-router.ts @@ -1,5 +1,3 @@ -"use client"; - /** * Comm Protocol Router Hook * diff --git a/registry/widgets/use-layout-styles.ts b/registry/widgets/use-layout-styles.ts index f7656e9..5de2a84 100644 --- a/registry/widgets/use-layout-styles.ts +++ b/registry/widgets/use-layout-styles.ts @@ -1,5 +1,3 @@ -"use client"; - import type { CSSProperties } from "react"; import { useMemo } from "react"; import { diff --git a/registry/widgets/widget-view.tsx b/registry/widgets/widget-view.tsx index 9092401..1d65489 100644 --- a/registry/widgets/widget-view.tsx +++ b/registry/widgets/widget-view.tsx @@ -1,5 +1,3 @@ -"use client"; - /** * Universal widget view component. *