Feature Interactive Api Curl Builder
blockfeatureInteractive API cURL builder and live payload testing sandbox with multi-language code export.
Installation
$pnpm dlx uipkge-ng@latest add feature-interactive-api-curl-builder$npx uipkge-ng@latest add feature-interactive-api-curl-builder$yarn dlx uipkge-ng@latest add feature-interactive-api-curl-builder$bunx uipkge-ng@latest add feature-interactive-api-curl-builderManifest:
https://uipkge.dev/r/angular/feature-interactive-api-curl-builder.jsonInstalls to:src/app/components/blocks/feature-interactive-api-curl-builder/Variants
Loading interactive previews…
Loading interactive previews…
Schema
Type aliases exported from this item's source. Use these to shape the data you pass in.
CurlExecutionDatainterface CurlExecutionData {
bundleId: string
name: string
frameworks: string[]
astCompiled: boolean
sizeBytes: number
oklchTokensInlined: number
edgeDeliveryTime: string
}CurlExecutionResultinterface CurlExecutionResult {
status: number
latencyMs: number
data: CurlExecutionData
}npm dependencies
Files installed (2)
src/app/components/blocks/feature-interactive-api-curl-builder/feature-interactive-api-curl-builder.component.ts13.7 kB
// Interactive edge API console: endpoint + payload flag config on the left, live multi-language // snippet generation (cURL / Fetch / Python / Go) with copy on the right, and a simulated HTTP // response payload. Port of the React block 1:1. import { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core' import { ArrowRight, Check, Copy, Globe, LucideAngularModule, Play, Terminal } from 'lucide-angular' import { cn } from '@/lib/utils' import { UiBadgeComponent } from '@/ui/badge/badge.component' import { UiButtonComponent } from '@/ui/button/button.component' import { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component' export type CurlHttpMethod = 'GET' | 'POST' export type CurlLanguage = 'curl' | 'javascript' | 'python' | 'go' export interface CurlExecutionData { bundleId: string name: string frameworks: string[] astCompiled: boolean sizeBytes: number oklchTokensInlined: number edgeDeliveryTime: string } export interface CurlExecutionResult { status: number latencyMs: number data: CurlExecutionData } export const CURL_ENDPOINTS = ['/v1/components/bundle', '/v1/tokens/compile'] as const export const CURL_LANGUAGES: { id: CurlLanguage; label: string }[] = [ { id: 'curl', label: 'cURL' }, { id: 'javascript', label: 'Fetch' }, { id: 'python', label: 'Python' }, { id: 'go', label: 'Go' }, ] @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-feature-interactive-api-curl-builder, [ui-feature-interactive-api-curl-builder]', standalone: true, // React renders the root <section> itself: the host stays out of layout and `class` goes to the root. host: { '[attr.class]': '"contents"' }, imports: [LucideAngularModule, UiBadgeComponent, UiButtonComponent, UiCardComponent, UiCardContentComponent], template: ` <section data-slot="feature-interactive-api-curl-builder" [class]="rootClass"> <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> <!-- Section Header --> <div class="mx-auto max-w-3xl space-y-4 text-center"> <a href="#api-builder" class="group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors" > <lucide-icon [img]="Globe" class="text-primary size-3.5" /> <span>Interactive Edge API Console</span> <lucide-icon [img]="ArrowRight" class="text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5" /> </a> <h2 class="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">{{ title }}</h2> <p class="text-muted-foreground text-base sm:text-lg">{{ description }}</p> </div> <!-- API Builder Workbench --> <div class="mt-12 grid grid-cols-1 gap-6 lg:grid-cols-12"> <!-- Left Config Parameters (5 cols) --> <div class="space-y-4 lg:col-span-5"> <div ui-card class="border-border bg-card shadow-xs"> <div ui-card-content class="space-y-5 p-6"> <div class="border-border flex items-center justify-between border-b pb-3"> <span class="text-muted-foreground text-xs font-bold tracking-wider uppercase" >Request Parameters</span > <span ui-badge variant="outline" class="border-success/30 bg-success/10 text-success font-mono text-xs" > Edge v1 </span> </div> <!-- Endpoint Selector --> <div class="space-y-2"> <label class="text-foreground text-xs font-bold">Endpoint Path</label> <div class="border-border bg-muted/40 flex rounded-lg border p-1"> @for (ep of endpoints; track ep) { <button type="button" [class]="endpointClass(ep)" class="flex-1 rounded-md py-1 font-mono text-xs transition-colors" (click)="selectEndpoint(ep)" > {{ ep }} </button> } </div> </div> <!-- Payload Toggles --> <div class="space-y-2.5 pt-2"> <label class="text-foreground text-xs font-bold">Payload Flags</label> <div class="space-y-2"> <label class="border-border/80 bg-background hover:bg-muted/20 flex cursor-pointer items-center justify-between rounded-lg border p-3 text-xs" > <span class="text-muted-foreground">Emit AST Syntax Tree</span> <input type="checkbox" [checked]="enableAstTree()" (change)="enableAstTree.set($any($event.target).checked)" class="accent-primary size-4 cursor-pointer" /> </label> <label class="border-border/80 bg-background hover:bg-muted/20 flex cursor-pointer items-center justify-between rounded-lg border p-3 text-xs" > <span class="text-muted-foreground">Inline OKLCH CSS Tokens</span> <input type="checkbox" [checked]="enableOklchTokens()" (change)="enableOklchTokens.set($any($event.target).checked)" class="accent-primary size-4 cursor-pointer" /> </label> </div> </div> <button ui-button class="w-full gap-2 shadow-xs" [disabled]="isExecuting()" (click)="executeRequest()"> <lucide-icon [img]="Play" class="fill-primary-foreground size-3.5" /> <span>{{ isExecuting() ? 'Executing Edge Call...' : 'Send Live HTTP Request' }}</span> </button> </div> </div> </div> <!-- Right Code Preview & Simulated Response (7 cols) --> <div class="space-y-4 lg:col-span-7"> <div ui-card class="border-border bg-card overflow-hidden font-mono text-xs shadow-xs"> <!-- Language Selector Tabs --> <div class="border-border bg-muted/40 flex items-center justify-between border-b px-4 py-2"> <div class="flex items-center gap-1"> @for (lang of languages; track lang.id) { <button type="button" [class]="languageClass(lang.id)" class="rounded px-2.5 py-1 text-xs transition-colors" (click)="selectLanguage(lang.id)" > {{ lang.label }} </button> } </div> <button type="button" class="text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors" (click)="copySnippet()" > @if (copiedSnippet()) { <lucide-icon [img]="Check" class="text-success size-3" /> } @else { <lucide-icon [img]="Copy" class="size-3" /> } <span>{{ copiedSnippet() ? 'Copied' : 'Copy' }}</span> </button> </div> <div ui-card-content class="bg-muted/10 p-4"> <pre class="text-foreground overflow-x-auto text-xs leading-relaxed" ><code>{{ generatedCode() }}</code></pre> </div> </div> <!-- Simulated Live HTTP Response --> <div class="border-border bg-muted/30 space-y-2 rounded-xl border p-4 font-mono text-xs"> <div class="border-border/80 flex items-center justify-between border-b pb-2"> <div class="flex items-center gap-2"> <lucide-icon [img]="Terminal" class="text-primary size-3.5" /> <span class="text-foreground font-bold">Response Payload</span> </div> <div class="flex items-center gap-3 text-xs"> <span class="text-success font-bold">HTTP {{ executionResult().status }} OK</span> <span class="text-muted-foreground">{{ executionResult().latencyMs }}ms</span> </div> </div> <pre class="text-muted-foreground overflow-x-auto text-xs leading-relaxed" ><code>{{ responseJson() }}</code></pre> </div> </div> </div> </div> </section> `, }) export class UiFeatureInteractiveApiCurlBuilderComponent { protected readonly ArrowRight = ArrowRight protected readonly Check = Check protected readonly Copy = Copy protected readonly Globe = Globe protected readonly Play = Play protected readonly Terminal = Terminal protected readonly endpoints: readonly string[] = CURL_ENDPOINTS protected readonly languages = CURL_LANGUAGES @Input() title = 'Composable REST APIs designed for programmatic automation.' @Input() description = 'Synthesize type-safe HTTP payloads, test endpoints in real time, and export snippets directly to your production workflow.' @Input('class') className?: string readonly selectedMethod = signal<CurlHttpMethod>('POST') readonly selectedEndpoint = signal<string>('/v1/components/bundle') readonly selectedLanguage = signal<CurlLanguage>('curl') readonly enableAstTree = signal(true) readonly enableOklchTokens = signal(true) readonly copiedSnippet = signal(false) readonly isExecuting = signal(false) readonly executionResult = signal<CurlExecutionResult>({ status: 200, latencyMs: 14, data: { bundleId: 'pkg_9981x2', name: 'button', frameworks: ['vue', 'react'], astCompiled: true, sizeBytes: 1480, oklchTokensInlined: 48, edgeDeliveryTime: '0.8ms', }, }) private copyTimer: ReturnType<typeof setTimeout> | undefined readonly generatedCode = computed(() => { const method = this.selectedMethod() const endpoint = this.selectedEndpoint() const language = this.selectedLanguage() const payload = JSON.stringify( { component: 'button', framework: 'vue', astTree: this.enableAstTree(), inlineTokens: this.enableOklchTokens(), }, null, 2, ) if (language === 'curl') { return `curl -X ${method} https://api.uipkge.dev${endpoint} \\ -H "Authorization: Bearer uipkge_sec_89201" \\ -H "Content-Type: application/json" \\ -d '${payload.replace(/\n/g, '\n ')}'` } if (language === 'javascript') { return `const res = await fetch("https://api.uipkge.dev${endpoint}", { method: "${method}", headers: { "Authorization": "Bearer uipkge_sec_89201", "Content-Type": "application/json" }, body: JSON.stringify(${payload}) }); const data = await res.json();` } if (language === 'python') { return `import requests res = requests.${method.toLowerCase()}( "https://api.uipkge.dev${endpoint}", headers={"Authorization": "Bearer uipkge_sec_89201"}, json=${payload.replace(/true/g, 'True').replace(/false/g, 'False')} ) data = res.json()` } return `// Go HTTP Request req, _ := http.NewRequest("${method}", "https://api.uipkge.dev${endpoint}", payload) req.Header.Set("Authorization", "Bearer uipkge_sec_89201") res, _ := client.Do(req)` }) readonly responseJson = computed(() => JSON.stringify(this.executionResult().data, null, 2)) get rootClass(): string { return cn('bg-background relative overflow-hidden py-16 sm:py-24', this.className) } endpointClass(ep: string): string { return cn( this.selectedEndpoint() === ep ? 'bg-background text-foreground font-bold shadow-2xs' : 'text-muted-foreground hover:text-foreground', ) } languageClass(lang: CurlLanguage): string { return cn( this.selectedLanguage() === lang ? 'bg-background text-foreground font-bold shadow-2xs' : 'text-muted-foreground hover:text-foreground', ) } selectEndpoint(ep: string): void { this.selectedEndpoint.set(ep) } selectLanguage(lang: CurlLanguage): void { this.selectedLanguage.set(lang) } async copySnippet(): Promise<void> { try { await navigator.clipboard.writeText(this.generatedCode()) this.copiedSnippet.set(true) clearTimeout(this.copyTimer) this.copyTimer = setTimeout(() => this.copiedSnippet.set(false), 2000) } catch { // Clipboard unavailable (insecure context / jsdom): leave the label unchanged. } } executeRequest(): void { if (this.isExecuting()) return this.isExecuting.set(true) setTimeout(() => { this.isExecuting.set(false) const endpoint = this.selectedEndpoint() const ast = this.enableAstTree() const tokens = this.enableOklchTokens() this.executionResult.set({ status: 200, latencyMs: Math.floor(Math.random() * 8) + 11, data: { bundleId: `pkg_${Math.random().toString(36).substring(2, 8)}`, name: endpoint.includes('bundle') ? 'button' : 'tokens', frameworks: ['vue', 'react'], astCompiled: ast, sizeBytes: ast ? 1480 : 1120, oklchTokensInlined: tokens ? 48 : 0, edgeDeliveryTime: '0.8ms', }, }) }, 350) } }src/app/components/blocks/feature-interactive-api-curl-builder/index.ts0.2 kB
export { UiFeatureInteractiveApiCurlBuilderComponent, CURL_ENDPOINTS, CURL_LANGUAGES, type CurlHttpMethod, type CurlLanguage, type CurlExecutionData, type CurlExecutionResult, } from './feature-interactive-api-curl-builder.component'
Raw manifest:https://uipkge.dev/r/angular/feature-interactive-api-curl-builder.json