CLARITY®
Overview
News
Analysis
72%
72%
Passing Probability
Passing Probability
+1.2
+1.2
Sentiment Delta
Sentiment Delta
68% Pos
68% Pos
Public Sentiment
Public Sentiment
The CLARITY Act aims to set clear rules for digital assets in the United States, giving users and innovators certainty.
The CLARITY Act aims to set clear rules for digital assets in the United States, giving users and innovators certainty.
With bipartisan support, the Act offers fair rules and market transparency for all.
With bipartisan support, the Act offers fair rules and market transparency for all.
Latest News
Latest News
Top updates and press
Live Social Feed
See the latest thoughts and Twitter commentary about the CLARITY Act, updated in real-time from policy experts, lawmakers, and the #CLARITYAct community.
import * as React from "react" import { addPropertyControls, ControlType } from "framer" type Tweet = { id: string text: string created_at: string url: string author: { name: string username: string profile_image_url?: string } public_metrics?: { like_count?: number repost_count?: number reply_count?: number quote_count?: number } } type Props = { endpoint: string title: string maxItems: number refreshHours: number cardRadius: number gap: number background: string cardBackground: string textColor: string mutedColor: string borderColor: string } function timeAgo(dateString: string) { const then = new Date(dateString).getTime() const now = Date.now() const diff = Math.max(0, now - then) const minute = 60 * 1000 const hour = 60 * minute const day = 24 * hour if (diff < hour) return `${Math.floor(diff / minute) || 1}m ago` if (diff < day) return `${Math.floor(diff / hour)}h ago` return `${Math.floor(diff / day)}d ago` } export default function ClarityXFeed(props: Props) { const { endpoint, title, maxItems, refreshHours, cardRadius, gap, background, cardBackground, textColor, mutedColor, borderColor, } = props const [tweets, setTweets] = React.useState<Tweet[]>([]) const [loading, setLoading] = React.useState(true) const [error, setError] = React.useState<string | null>(null) const fetchTweets = React.useCallback(async () => { if (!endpoint) { setError("Missing API endpoint.") setLoading(false) return } try { setLoading(true) setError(null) const url = new URL(endpoint) url.searchParams.set("limit", String(maxItems)) const res = await fetch(url.toString(), { method: "GET", headers: { Accept: "application/json" }, cache: "no-store", }) if (!res.ok) { throw new Error(`Request failed: ${res.status}`) } const data = await res.json() setTweets(Array.isArray(data?.tweets) ? data.tweets : []) } catch (err: any) { setError(err?.message || "Failed to load posts.") } finally { setLoading(false) } }, [endpoint, maxItems]) React.useEffect(() => { fetchTweets() const intervalMs = Math.max(1, refreshHours) * 60 * 60 * 1000 const id = window.setInterval(fetchTweets, intervalMs) return () => window.clearInterval(id) }, [fetchTweets, refreshHours]) return ( <div style={{ width: "100%", height: "100%", overflow: "auto", background, color: textColor, fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif', padding: 16, boxSizing: "border-box", }} > <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12, }} > <div style={{ fontSize: 18, fontWeight: 700, lineHeight: 1.2, }} > {title} </div> <div style={{ fontSize: 12, color: mutedColor, }} > Refreshes every {refreshHours}h </div> </div> {loading && ( <div style={{ fontSize: 14, color: mutedColor, padding: 12, }} > Loading latest posts… </div> )} {error && !loading && ( <div style={{ fontSize: 14, color: "#b91c1c", background: "#fef2f2", border: "1px solid #fecaca", borderRadius: 12, padding: 12, }} > {error} </div> )} {!loading && !error && tweets.length === 0 && ( <div style={{ fontSize: 14, color: mutedColor, padding: 12, }} > No matching posts found. </div> )} <div style={{ display: "grid", gap, }} > {tweets.map((tweet) => ( <a key={tweet.id} href={tweet.url} target="_blank" rel="noreferrer" style={{ textDecoration: "none", color: "inherit", }} > <div style={{ background: cardBackground, border: `1px solid ${borderColor}`, borderRadius: cardRadius, padding: 14, display: "grid", gap: 10, boxShadow: "0 1px 2px rgba(0,0,0,0.04)", }} > <div style={{ display: "flex", alignItems: "center", gap: 10, }} > {tweet.author.profile_image_url ? ( <img src={tweet.author.profile_image_url} alt={tweet.author.name} style={{ width: 40, height: 40, borderRadius: "999px", objectFit: "cover", flexShrink: 0, }} /> ) : ( <div style={{ width: 40, height: 40, borderRadius: "999px", background: "#e5e7eb", flexShrink: 0, }} /> )} <div style={{ minWidth: 0 }}> <div style={{ fontSize: 14, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", }} > {tweet.author.name} </div> <div style={{ fontSize: 12, color: mutedColor, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", }} > @{tweet.author.username} · {timeAgo(tweet.created_at)} </div> </div> </div> <div style={{ fontSize: 14, lineHeight: 1.5, whiteSpace: "pre-wrap", overflowWrap: "anywhere", }} > {tweet.text} </div> <div style={{ display: "flex", gap: 14, flexWrap: "wrap", fontSize: 12, color: mutedColor, }} > <span>❤️ {tweet.public_metrics?.like_count ?? 0}</span> <span>🔁 {tweet.public_metrics?.repost_count ?? 0}</span> <span>💬 {tweet.public_metrics?.reply_count ?? 0}</span> <span>↗ {tweet.public_metrics?.quote_count ?? 0}</span> </div> </div> </a> ))} </div> </div> ) } ClarityXFeed.defaultProps = { title: "Latest X Posts on CLARITY", endpoint: "https://YOUR-DOMAIN.com/api/clarity-posts", maxItems: 8, refreshHours: 12, cardRadius: 16, gap: 12, background: "#ffffff", cardBackground: "#ffffff", textColor: "#111827", mutedColor: "#6b7280", borderColor: "#e5e7eb", } addPropertyControls(ClarityXFeed, { endpoint: { type: ControlType.String, title: "Endpoint" }, title: { type: ControlType.String, title: "Title" }, maxItems: { type: ControlType.Number, title: "Items", min: 1, max: 20, step: 1, }, refreshHours: { type: ControlType.Number, title: "Refresh", min: 1, max: 24, step: 1, }, cardRadius: { type: ControlType.Number, title: "Radius", min: 0, max: 40, step: 1, }, gap: { type: ControlType.Number, title: "Gap", min: 0, max: 40, step: 1, }, background: { type: ControlType.Color, title: "BG" }, cardBackground: { type: ControlType.Color, title: "Card BG" }, textColor: { type: ControlType.Color, title: "Text" }, mutedColor: { type: ControlType.Color, title: "Muted" }, borderColor: { type: ControlType.Color, title: "Border" }, })
