Skip to content

Commit a5da4bb

Browse files
Mobile friendly (big refactor)
1 parent 5d9b7ce commit a5da4bb

File tree

9 files changed

+971
-150
lines changed

9 files changed

+971
-150
lines changed

connect-react-demo/app/components/ConfigAndCodePanel.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,17 @@ export function ConfigAndCodePanel() {
1212
return (
1313
<div className="flex flex-col h-full">
1414
<Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col">
15-
<div className="border-b bg-white px-4 py-2">
16-
<TabsList className="grid w-full grid-cols-2">
17-
<TabsTrigger value="config" className="flex items-center gap-2">
15+
<div className="border-b bg-white px-3 sm:px-4 py-2">
16+
<TabsList className="grid w-full grid-cols-2 h-12">
17+
<TabsTrigger value="config" className="flex items-center gap-2 h-10 text-sm">
1818
<IoSettingsOutline className="h-4 w-4" />
19-
Configuration
19+
<span className="hidden sm:inline">Configuration</span>
20+
<span className="sm:hidden">Config</span>
2021
</TabsTrigger>
21-
<TabsTrigger value="code" className="flex items-center gap-2">
22+
<TabsTrigger value="code" className="flex items-center gap-2 h-10 text-sm">
2223
<IoCodeSlashOutline className="h-4 w-4" />
23-
Code Examples
24+
<span className="hidden sm:inline">Code Examples</span>
25+
<span className="sm:hidden">Code</span>
2426
</TabsTrigger>
2527
</TabsList>
2628
</div>

connect-react-demo/app/components/ConfigPanel.tsx

Lines changed: 113 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
"use client"
22

3-
import { useId } from "react"
3+
import { useId, useState } from "react"
44
import { SelectApp, SelectComponent } from "@pipedream/connect-react"
55
import {
66
Tooltip,
77
TooltipContent,
88
TooltipProvider,
99
TooltipTrigger,
1010
} from "@/components/ui/tooltip"
11+
import {
12+
Collapsible,
13+
CollapsibleContent,
14+
CollapsibleTrigger,
15+
} from "@/components/ui/collapsible"
1116
import { useAppState } from "@/lib/app-state"
1217
import { cn } from "@/lib/utils"
1318
import Select from "react-select"
1419
import { ScrollArea } from "@/components/ui/scroll-area"
1520
import {enableDebugging} from "@/lib/query-params"
16-
import { IoCubeSharp, IoFlashOutline } from "react-icons/io5"
21+
import { IoCubeSharp, IoFlashOutline, IoChevronDown, IoSettingsOutline } from "react-icons/io5"
1722

1823
function getTypeDescription(prop: {
1924
name: string
@@ -114,7 +119,7 @@ const PropertyItem = ({
114119
})
115120

116121
return (
117-
<div className="grid grid-cols-[180px_1fr] gap-4 items-center py-2 pl-4 pr-2 hover:bg-zinc-50/50">
122+
<div className="grid grid-cols-[120px_1fr] gap-3 items-center py-2 pl-4 pr-2 hover:bg-zinc-50/50">
118123
<div className="flex items-center">
119124
<TooltipProvider delayDuration={0}>
120125
<Tooltip>
@@ -227,6 +232,7 @@ export const ConfigPanel = () => {
227232
} = useAppState()
228233
const id1 = useId();
229234
const id2 = useId();
235+
const [showAdvanced, setShowAdvanced] = useState(false);
230236

231237
const isValidWebhookUrl = () => {
232238
if (!webhookUrl) {
@@ -242,7 +248,8 @@ export const ConfigPanel = () => {
242248
}
243249

244250

245-
const formControls = (
251+
// Basic configuration options (always visible)
252+
const basicFormControls = (
246253
<div className="divide-y">
247254
<PropertyItem
248255
name="componentType"
@@ -279,15 +286,36 @@ export const ConfigPanel = () => {
279286
</div>
280287
</PropertyItem>
281288
<PropertyItem
282-
name="userId"
289+
name="app"
283290
type="string"
284-
description="Authenticated user identifier"
291+
description="App to connect to"
285292
required={true}
286293
>
287-
<input
288-
value={userId || ""}
289-
className="w-full px-3 py-1.5 text-sm font-mono border rounded bg-zinc-50/50"
290-
readOnly
294+
<SelectApp
295+
value={selectedApp}
296+
onChange={(app) => {
297+
app
298+
? setSelectedAppSlug(app.name_slug)
299+
: removeSelectedAppSlug()
300+
}}
301+
/>
302+
</PropertyItem>
303+
<PropertyItem
304+
name={selectedComponentType === "action" ? "actionId" : "triggerId"}
305+
type="string"
306+
description={`${selectedComponentType === "action" ? "Action" : "Trigger"} to use`}
307+
required={true}
308+
>
309+
<SelectComponent
310+
app={selectedApp}
311+
componentType={selectedComponentType}
312+
value={selectedComponent}
313+
onChange={(comp) => {
314+
comp
315+
? setSelectedComponentKey(comp.key)
316+
: removeSelectedComponentKey()
317+
318+
}}
291319
/>
292320
</PropertyItem>
293321
{selectedComponentType === "trigger" && (
@@ -307,33 +335,23 @@ export const ConfigPanel = () => {
307335
/>
308336
</PropertyItem>
309337
)}
338+
</div>
339+
)
340+
341+
// Advanced configuration options (collapsible)
342+
const advancedFormControls = (
343+
<div className="divide-y">
310344
<PropertyItem
311-
name="componentKey"
345+
name="userId"
312346
type="string"
313-
description="Unique identifier for the component to be rendered"
347+
description="Authenticated user identifier"
314348
required={true}
315349
>
316-
<div className="grid grid-cols-2 gap-1">
317-
<SelectApp
318-
value={selectedApp}
319-
onChange={(app) => {
320-
app
321-
? setSelectedAppSlug(app.name_slug)
322-
: removeSelectedAppSlug()
323-
}}
324-
/>
325-
<SelectComponent
326-
app={selectedApp}
327-
componentType={selectedComponentType}
328-
value={selectedComponent}
329-
onChange={(comp) => {
330-
comp
331-
? setSelectedComponentKey(comp.key)
332-
: removeSelectedComponentKey()
333-
334-
}}
335-
/>
336-
</div>
350+
<input
351+
value={userId || ""}
352+
className="w-full px-3 py-1.5 text-sm font-mono border rounded bg-zinc-50/50"
353+
readOnly
354+
/>
337355
</PropertyItem>
338356
<PropertyItem
339357
name="hideOptionalProps"
@@ -442,7 +460,6 @@ export const ConfigPanel = () => {
442460
onChange={(v) => {
443461
if (v) {
444462
setCustomizationOption(v)
445-
setFileCode(undefined)
446463
}
447464
}}
448465
getOptionValue={(o) => o.name}
@@ -454,53 +471,79 @@ export const ConfigPanel = () => {
454471
}}
455472
/>
456473
</PropertyItem>
457-
{selectedComponentType === "trigger" && (
458-
<div className="bg-sky-100/50 backdrop-blur-xl border rounded border-neutral-200/50 px-4 py-2 mb-10 m-4 shadow-sm">
459-
<div className="text-sm text-neutral-700 leading-relaxed">
460-
<p className="py-2 flex gap-2">
461-
{/* <BsInfoCircleFill className="h-4 w-4 text-neutral-500 flex-shrink-0 mt-1" /> */}
462-
<span>
463-
When you deploy a trigger via the Pipedream components API, we'll emit events to a{' '}
464-
<code className="font-mono mx-1">webhookUrl</code> that you define. To test your trigger:
465-
</span>
466-
</p>
467-
<ol className="list-decimal list-outside ml-6 space-y-2">
468-
<li className="pl-2">
469-
Configure the trigger and define a <code className="font-mono text-sm">webhookUrl</code> to receive events (use a{' '}
470-
<a
471-
href="https://pipedream.com/new?h=tch_BXfkaA"
472-
target="_blank"
473-
rel="noopener noreferrer"
474-
className="font-medium text-sky-800 hover:text-sky-900 hover:underline transition-colors"
475-
>
476-
RequestBin
477-
</a>
478-
{' '}for example)
479-
</li>
480-
<li className="pl-2">
481-
Click <span className="font-semibold">Submit</span> on the right (may take up to a minute, but can happen asynchronously in your app)
482-
</li>
483-
<li className="pl-2">
484-
Generate some actual events in the relevant app and check your webhook for emitted events.
485-
</li>
486-
</ol>
487-
</div>
488-
</div>
489-
)}
474+
</div>
475+
)
476+
477+
const triggerInfo = selectedComponentType === "trigger" && (
478+
<div className="bg-sky-100/50 backdrop-blur-xl border rounded border-neutral-200/50 px-4 py-2 mb-10 m-4 shadow-sm hidden md:block">
479+
<div className="text-sm text-neutral-700 leading-relaxed">
480+
<p className="py-2 flex gap-2">
481+
{/* <BsInfoCircleFill className="h-4 w-4 text-neutral-500 flex-shrink-0 mt-1" /> */}
482+
<span>
483+
When you deploy a trigger via the Pipedream components API, we'll emit events to a{' '}
484+
<code className="font-mono mx-1">webhookUrl</code> that you define. To test your trigger:
485+
</span>
486+
</p>
487+
<ol className="list-decimal list-outside ml-6 space-y-2">
488+
<li className="pl-2">
489+
Configure the trigger and define a <code className="font-mono text-sm">webhookUrl</code> to receive events (use a{' '}
490+
<a
491+
href="https://pipedream.com/new?h=tch_BXfkaA"
492+
target="_blank"
493+
rel="noopener noreferrer"
494+
className="font-medium text-sky-800 hover:text-sky-900 hover:underline transition-colors"
495+
>
496+
RequestBin
497+
</a>
498+
{' '}for example)
499+
</li>
500+
<li className="pl-2">
501+
Click <span className="font-semibold">Submit</span> on the right (may take up to a minute, but can happen asynchronously in your app)
502+
</li>
503+
<li className="pl-2">
504+
Generate some actual events in the relevant app and check your webhook for emitted events.
505+
</li>
506+
</ol>
507+
</div>
490508
</div>
491509
)
492510

493511
return (
494512
<div className="flex flex-col min-h-0 h-full">
495-
<div className="px-6 py-4 border-b bg-white">
513+
<div className="px-4 md:px-6 py-4 border-b bg-white">
496514
<h2 className="text-lg font-semibold text-gray-900">Demo Configuration</h2>
497515
<p className="text-sm text-gray-500 mt-1">
498516
Configure the component demo settings
499517
</p>
500518
</div>
501519
<ScrollArea className="flex-1 min-h-0">
502-
<div className="px-6 py-4">
503-
{formControls}
520+
<div className="px-4 md:px-6 py-4">
521+
{/* Basic configuration - always visible */}
522+
{basicFormControls}
523+
524+
{/* Advanced configuration - collapsible on mobile */}
525+
<div className="mt-4">
526+
<Collapsible open={showAdvanced} onOpenChange={setShowAdvanced}>
527+
<CollapsibleTrigger className="flex items-center justify-between w-full py-2 px-3 text-xs font-medium text-neutral-500 hover:text-neutral-600 hover:bg-neutral-25 rounded border border-neutral-150 md:hidden">
528+
<div className="flex items-center gap-2">
529+
<IoSettingsOutline className="h-3 w-3" />
530+
Advanced Configuration
531+
</div>
532+
<IoChevronDown className={cn("h-3 w-3 transition-transform", showAdvanced && "rotate-180")} />
533+
</CollapsibleTrigger>
534+
535+
{/* Always show on desktop, collapsible on mobile */}
536+
<div className="hidden md:block">
537+
{advancedFormControls}
538+
</div>
539+
540+
<CollapsibleContent className="md:hidden">
541+
{advancedFormControls}
542+
</CollapsibleContent>
543+
</Collapsible>
544+
</div>
545+
546+
{triggerInfo}
504547
</div>
505548
</ScrollArea>
506549
</div>

0 commit comments

Comments
 (0)