@d34dman/flowdrop 0.0.20 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +8 -0
  2. package/dist/components/App.svelte +172 -417
  3. package/dist/components/ConfigForm.svelte +707 -241
  4. package/dist/components/ConfigForm.svelte.d.ts +9 -2
  5. package/dist/components/ConfigPanel.svelte +160 -0
  6. package/dist/components/ConfigPanel.svelte.d.ts +32 -0
  7. package/dist/components/Navbar.svelte +2 -1
  8. package/dist/components/NodeStatusOverlay.svelte +1 -0
  9. package/dist/components/NodeStatusOverlay.svelte.d.ts +1 -0
  10. package/dist/components/ReadOnlyDetails.svelte +168 -0
  11. package/dist/components/ReadOnlyDetails.svelte.d.ts +25 -0
  12. package/dist/components/WorkflowEditor.svelte +34 -26
  13. package/dist/components/layouts/MainLayout.svelte +513 -0
  14. package/dist/components/layouts/MainLayout.svelte.d.ts +50 -0
  15. package/dist/components/{GatewayNode.svelte → nodes/GatewayNode.svelte} +3 -3
  16. package/dist/components/{GatewayNode.svelte.d.ts → nodes/GatewayNode.svelte.d.ts} +1 -1
  17. package/dist/components/nodes/NotesNode.svelte +348 -0
  18. package/dist/components/nodes/NotesNode.svelte.d.ts +24 -0
  19. package/dist/components/{SimpleNode.svelte → nodes/SimpleNode.svelte} +2 -2
  20. package/dist/components/{SimpleNode.svelte.d.ts → nodes/SimpleNode.svelte.d.ts} +1 -1
  21. package/dist/components/{SquareNode.svelte → nodes/SquareNode.svelte} +2 -2
  22. package/dist/components/{SquareNode.svelte.d.ts → nodes/SquareNode.svelte.d.ts} +1 -1
  23. package/dist/components/{TerminalNode.svelte → nodes/TerminalNode.svelte} +2 -2
  24. package/dist/components/{TerminalNode.svelte.d.ts → nodes/TerminalNode.svelte.d.ts} +1 -1
  25. package/dist/components/{ToolNode.svelte → nodes/ToolNode.svelte} +2 -2
  26. package/dist/components/{ToolNode.svelte.d.ts → nodes/ToolNode.svelte.d.ts} +1 -1
  27. package/dist/components/{WorkflowNode.svelte → nodes/WorkflowNode.svelte} +3 -3
  28. package/dist/components/{WorkflowNode.svelte.d.ts → nodes/WorkflowNode.svelte.d.ts} +1 -1
  29. package/dist/index.d.ts +8 -7
  30. package/dist/index.js +8 -7
  31. package/dist/registry/builtinNodes.js +7 -7
  32. package/dist/styles/base.css +15 -1
  33. package/package.json +1 -1
  34. package/dist/components/ConfigSidebar.svelte +0 -934
  35. package/dist/components/ConfigSidebar.svelte.d.ts +0 -51
  36. package/dist/components/NotesNode.svelte +0 -566
  37. package/dist/components/NotesNode.svelte.d.ts +0 -43
package/README.md CHANGED
@@ -4,6 +4,14 @@
4
4
 
5
5
  <h1 align="center">FlowDrop</h1>
6
6
 
7
+ <p align="center">
8
+ <img src="https://img.shields.io/github/actions/workflow/status/d34dman/flowdrop/docker-publish.yml?style=flat-square&label=Build" alt="GitHub pages build status" />
9
+ <a href="https://www.npmjs.com/package/@d34dman/flowdrop"><img src="https://img.shields.io/npm/v/@d34dman/flowdrop?style=flat-square" alt="npm" /></a>
10
+ <img src="https://img.shields.io/npm/unpacked-size/%40d34dman%2Fflowdrop?style=flat-square" alt="NPM Unpacked Size" />
11
+ <img src="https://img.shields.io/npm/types/@d34dman/flowdrop?style=flat-square" alt="npm type definitions" />
12
+ <a href="http://npmjs.com/package/@d34dman/flowdrop"><img src="https://img.shields.io/npm/dt/@d34dman/flowdrop.svg?maxAge=2592000&style=flat-square" alt="npm downloads" /></a>
13
+ </p>
14
+
7
15
  <p align="center">
8
16
  <strong>Build beautiful workflow editors in minutes, not months.</strong>
9
17
  </p>
@@ -7,10 +7,11 @@
7
7
  <script lang="ts">
8
8
  import { onMount, tick } from 'svelte';
9
9
  import { page } from '$app/stores';
10
+ import MainLayout from './layouts/MainLayout.svelte';
10
11
  import WorkflowEditor from './WorkflowEditor.svelte';
11
12
  import NodeSidebar from './NodeSidebar.svelte';
12
- import ConfigSidebar from './ConfigSidebar.svelte';
13
13
  import ConfigForm from './ConfigForm.svelte';
14
+ import ConfigPanel from './ConfigPanel.svelte';
14
15
  import Navbar from './Navbar.svelte';
15
16
  import { api, setEndpointConfig } from '../services/api.js';
16
17
  import type { NodeMetadata, Workflow, WorkflowNode, ConfigSchema } from '../types/index.js';
@@ -137,6 +138,7 @@
137
138
  type: 'string',
138
139
  title: 'Description',
139
140
  description: 'A description of the workflow',
141
+ format: 'multiline',
140
142
  default: ''
141
143
  }
142
144
  },
@@ -563,15 +565,25 @@
563
565
  <meta name="description" content="A modern drag-and-drop workflow editor for LLM applications" />
564
566
  </svelte:head>
565
567
 
566
- <div
567
- class="flowdrop-app"
568
- style="height: {typeof height === 'number' ? `${height}px` : height}; width: {typeof width ===
569
- 'number'
570
- ? `${width}px`
571
- : width};"
568
+ <!-- MainLayout wrapper for workflow editor -->
569
+ <MainLayout
570
+ showHeader={showNavbar && !$page.url.pathname.includes('/edit')}
571
+ showLeftSidebar={!disableSidebar}
572
+ showRightSidebar={!disableSidebar && (isWorkflowSettingsOpen || !!selectedNodeForConfig())}
573
+ showFooter={false}
574
+ headerHeight={60}
575
+ leftSidebarWidth={320}
576
+ rightSidebarWidth={400}
577
+ leftSidebarMinWidth={280}
578
+ leftSidebarMaxWidth={450}
579
+ rightSidebarMinWidth={320}
580
+ rightSidebarMaxWidth={550}
581
+ enableLeftSplitPane={false}
582
+ enableRightSplitPane={true}
583
+ class="flowdrop-app-layout"
572
584
  >
573
- <!-- Navbar (conditionally rendered) - hide on workflow edit pages -->
574
- {#if showNavbar && !$page.url.pathname.includes('/edit')}
585
+ <!-- Header: Navbar -->
586
+ {#snippet header()}
575
587
  <Navbar
576
588
  title={breadcrumbTitle()}
577
589
  primaryActions={navbarActions.length > 0
@@ -610,231 +622,161 @@
610
622
  ]}
611
623
  showStatus={true}
612
624
  />
613
- {/if}
614
-
615
- <!-- Main Content -->
616
- <main class="flowdrop-main">
617
- <!-- Status Display -->
618
- {#if error}
619
- <div class="flowdrop-status flowdrop-status--error">
620
- <div class="flowdrop-status__content">
621
- <div class="flowdrop-flex flowdrop-gap--3">
622
- <div class="flowdrop-status__indicator flowdrop-status__indicator--error"></div>
623
- <span class="flowdrop-text--sm flowdrop-font--medium">Error: {error}</span>
624
- </div>
625
- <div class="flowdrop-flex flowdrop-gap--2">
626
- <button
627
- class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
628
- onclick={retryLoad}
629
- type="button"
630
- >
631
- Retry
632
- </button>
633
- <button
634
- class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--primary"
635
- onclick={() => {
636
- nodes = sampleNodes;
637
- error = null;
638
- }}
639
- type="button"
640
- >
641
- Use Sample Data
642
- </button>
643
- <button
644
- class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
645
- onclick={() => {
646
- const defaultUrl = '/api/flowdrop';
647
- const newUrl = prompt('Enter Backend API URL:', defaultUrl);
648
- if (newUrl) {
649
- const endpointConfig = createEndpointConfig(newUrl);
650
- setEndpointConfig(endpointConfig);
651
- fetchNodeTypes();
652
- }
653
- }}
654
- type="button"
655
- >
656
- Set API URL
657
- </button>
658
- <button
659
- class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
660
- onclick={testApiConnection}
661
- type="button"
662
- >
663
- Test API
664
- </button>
665
- <button
666
- class="flowdrop-btn flowdrop-btn--ghost flowdrop-btn--sm"
667
- onclick={() => (error = null)}
668
- type="button"
669
- >
670
-
671
- </button>
672
- </div>
673
- </div>
674
- </div>
675
- {/if}
676
-
677
- <!-- Workflow Editor with Sidebars -->
678
- <div class="flowdrop-editor-container">
679
- <!-- Left Sidebar - Node Components (conditionally rendered) -->
680
- {#if !disableSidebar}
681
- <div class="flowdrop-sidebar flowdrop-sidebar--left">
682
- <NodeSidebar {nodes} />
683
- </div>
684
- {/if}
685
-
686
- <!-- Main Editor Area -->
687
- <div
688
- class="flowdrop-editor-main"
689
- class:pipeline-view={!!pipelineId}
690
- onclick={handleCanvasClick}
691
- onkeydown={(e) => e.key === 'Escape' && closeConfigSidebar()}
692
- role="button"
693
- tabindex="0"
694
- aria-label="Workflow canvas - click to close sidebar"
625
+ {/snippet}
626
+
627
+ <!-- Left Sidebar: Node Components -->
628
+ {#snippet leftSidebar()}
629
+ <NodeSidebar {nodes} />
630
+ {/snippet}
631
+
632
+ <!-- Right Sidebar: Configuration or Workflow Settings -->
633
+ {#snippet rightSidebar()}
634
+ {#if isWorkflowSettingsOpen}
635
+ <ConfigPanel
636
+ title="Workflow Settings"
637
+ id={$workflowStore?.id}
638
+ details={[
639
+ { label: 'Nodes', value: String($workflowStore?.nodes?.length ?? 0) },
640
+ { label: 'Connections', value: String($workflowStore?.edges?.length ?? 0) }
641
+ ]}
642
+ configTitle="Settings"
643
+ onClose={() => (isWorkflowSettingsOpen = false)}
695
644
  >
696
- <WorkflowEditor
697
- bind:this={workflowEditorRef}
698
- {nodes}
699
- {height}
700
- {width}
701
- {endpointConfig}
702
- {isConfigSidebarOpen}
703
- selectedNodeForConfig={selectedNodeForConfig()}
704
- {openConfigSidebar}
705
- {closeConfigSidebar}
706
- {lockWorkflow}
707
- {readOnly}
708
- {nodeStatuses}
709
- {pipelineId}
645
+ <ConfigForm
646
+ schema={workflowConfigSchema}
647
+ values={workflowConfigValues}
648
+ onSave={handleWorkflowSave}
649
+ onCancel={() => (isWorkflowSettingsOpen = false)}
710
650
  />
711
- </div>
651
+ </ConfigPanel>
652
+ {:else if selectedNodeForConfig()}
653
+ {@const currentNode = selectedNodeForConfig()}
654
+ <ConfigPanel
655
+ title={currentNode.data.label}
656
+ id={currentNode.id}
657
+ description={currentNode.data.metadata?.description || 'Node configuration'}
658
+ details={[
659
+ { label: 'Type', value: currentNode.data.metadata?.type || currentNode.type },
660
+ { label: 'Category', value: currentNode.data.metadata?.category || 'general' }
661
+ ]}
662
+ onClose={closeConfigSidebar}
663
+ >
664
+ <ConfigForm
665
+ node={currentNode}
666
+ onSave={(updatedConfig) => {
667
+ if (selectedNodeId && currentNode) {
668
+ // Handle nodeType switching if nodeType is in the config
669
+ let nodeUpdates: Record<string, unknown> = {
670
+ data: {
671
+ ...currentNode.data,
672
+ config: updatedConfig
673
+ }
674
+ };
712
675
 
713
- <!-- Right Sidebar - Configuration or Workflow Settings (conditionally rendered) -->
714
- {#if !disableSidebar && isWorkflowSettingsOpen}
715
- <ConfigSidebar
716
- isOpen={isWorkflowSettingsOpen}
717
- title="Workflow Settings"
718
- configSchema={workflowConfigSchema}
719
- configValues={workflowConfigValues}
720
- onSave={handleWorkflowSave}
721
- onClose={() => (isWorkflowSettingsOpen = false)}
676
+ // NOTE: We do NOT change the node's type field anymore
677
+ // All nodes use 'universalNode' and UniversalNode handles internal switching
678
+ workflowActions.updateNode(selectedNodeId, nodeUpdates);
679
+ }
680
+
681
+ closeConfigSidebar();
682
+ }}
683
+ onCancel={closeConfigSidebar}
722
684
  />
723
- {:else if !disableSidebar && selectedNodeForConfig()}
724
- <div class="flowdrop-sidebar flowdrop-sidebar--right">
725
- <div class="flowdrop-config-sidebar">
726
- <!-- Header -->
727
- <div class="flowdrop-config-sidebar__header">
728
- <h2 class="flowdrop-config-sidebar__title">{selectedNodeForConfig().data.label}</h2>
729
- <button
730
- class="flowdrop-config-sidebar__close"
731
- onclick={closeConfigSidebar}
732
- aria-label="Close configuration sidebar"
733
- >
734
- ×
735
- </button>
736
- </div>
737
-
738
- <!-- Content -->
739
- <div class="flowdrop-config-sidebar__content">
740
- <!-- Node Details -->
741
- <div class="flowdrop-config-sidebar__section">
742
- <h3 class="flowdrop-config-sidebar__section-title">Node Details</h3>
743
- <div class="flowdrop-config-sidebar__details">
744
- <div class="flowdrop-config-sidebar__detail">
745
- <span class="flowdrop-config-sidebar__detail-label">Node ID:</span>
746
- <div class="flowdrop-config-sidebar__detail-value-with-copy">
747
- <span
748
- class="flowdrop-config-sidebar__detail-value"
749
- style="font-family: monospace;"
750
- >
751
- {selectedNodeForConfig().id}
752
- </span>
753
- <button
754
- class="flowdrop-config-sidebar__copy-btn"
755
- onclick={() => {
756
- navigator.clipboard.writeText(selectedNodeForConfig().id);
757
- }}
758
- title="Copy Node ID"
759
- aria-label="Copy node ID to clipboard"
760
- >
761
- 📋
762
- </button>
763
- </div>
764
- </div>
765
- <div class="flowdrop-config-sidebar__detail">
766
- <span class="flowdrop-config-sidebar__detail-label">Type:</span>
767
- <span class="flowdrop-config-sidebar__detail-value"
768
- >{selectedNodeForConfig().data.metadata?.type ||
769
- selectedNodeForConfig().type}</span
770
- >
771
- </div>
772
- <div class="flowdrop-config-sidebar__detail">
773
- <span class="flowdrop-config-sidebar__detail-label">Category:</span>
774
- <span class="flowdrop-config-sidebar__detail-value"
775
- >{selectedNodeForConfig().data.metadata?.category || 'general'}</span
776
- >
777
- </div>
778
- <div class="flowdrop-config-sidebar__detail">
779
- <span class="flowdrop-config-sidebar__detail-label">Description:</span>
780
- <p class="flowdrop-config-sidebar__detail-description">
781
- {selectedNodeForConfig().data.metadata?.description || 'Node configuration'}
782
- </p>
783
- </div>
784
- </div>
785
- </div>
786
-
787
- <!-- Configuration Form -->
788
- <div class="flowdrop-config-sidebar__section">
789
- <h3 class="flowdrop-config-sidebar__section-title">Configuration</h3>
790
- <ConfigForm
791
- node={selectedNodeForConfig()}
792
- onSave={(updatedConfig) => {
793
- const currentNode = selectedNodeForConfig();
794
- if (selectedNodeId && currentNode) {
795
- // Handle nodeType switching if nodeType is in the config
796
- let nodeUpdates: Record<string, unknown> = {
797
- data: {
798
- ...currentNode.data,
799
- config: updatedConfig
800
- }
801
- };
802
-
803
- // NOTE: We do NOT change the node's type field anymore
804
- // All nodes use 'universalNode' and UniversalNode handles internal switching
805
- workflowActions.updateNode(selectedNodeId, nodeUpdates);
806
- }
807
-
808
- closeConfigSidebar();
809
- }}
810
- onCancel={closeConfigSidebar}
811
- />
812
- </div>
813
- </div>
814
- </div>
685
+ </ConfigPanel>
686
+ {/if}
687
+ {/snippet}
688
+
689
+ <!-- Main Content: Workflow Editor with Error Status -->
690
+ <!-- Status Display -->
691
+ {#if error}
692
+ <div class="flowdrop-status flowdrop-status--error">
693
+ <div class="flowdrop-status__content">
694
+ <div class="flowdrop-flex flowdrop-gap--3">
695
+ <div class="flowdrop-status__indicator flowdrop-status__indicator--error"></div>
696
+ <span class="flowdrop-text--sm flowdrop-font--medium">Error: {error}</span>
815
697
  </div>
816
- {/if}
698
+ <div class="flowdrop-flex flowdrop-gap--2">
699
+ <button
700
+ class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
701
+ onclick={retryLoad}
702
+ type="button"
703
+ >
704
+ Retry
705
+ </button>
706
+ <button
707
+ class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--primary"
708
+ onclick={() => {
709
+ nodes = sampleNodes;
710
+ error = null;
711
+ }}
712
+ type="button"
713
+ >
714
+ Use Sample Data
715
+ </button>
716
+ <button
717
+ class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
718
+ onclick={() => {
719
+ const defaultUrl = '/api/flowdrop';
720
+ const newUrl = prompt('Enter Backend API URL:', defaultUrl);
721
+ if (newUrl) {
722
+ const endpointConfig = createEndpointConfig(newUrl);
723
+ setEndpointConfig(endpointConfig);
724
+ fetchNodeTypes();
725
+ }
726
+ }}
727
+ type="button"
728
+ >
729
+ Set API URL
730
+ </button>
731
+ <button
732
+ class="flowdrop-btn flowdrop-btn--sm flowdrop-btn--outline"
733
+ onclick={testApiConnection}
734
+ type="button"
735
+ >
736
+ Test API
737
+ </button>
738
+ <button
739
+ class="flowdrop-btn flowdrop-btn--ghost flowdrop-btn--sm"
740
+ onclick={() => (error = null)}
741
+ type="button"
742
+ >
743
+
744
+ </button>
745
+ </div>
746
+ </div>
817
747
  </div>
818
- </main>
819
- </div>
820
-
821
- <style>
822
- .flowdrop-app {
823
- background: linear-gradient(135deg, #f9fafb 0%, #e0e7ff 50%, #c7d2fe 100%);
824
- display: flex;
825
- flex-direction: column;
826
- overflow: hidden;
827
- }
748
+ {/if}
828
749
 
829
- .flowdrop-main {
830
- flex: 1;
831
- position: relative;
832
- display: flex;
833
- flex-direction: column;
834
- min-height: 0;
835
- overflow: hidden;
836
- }
750
+ <!-- Main Editor Area -->
751
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
752
+ <div
753
+ class="flowdrop-editor-main"
754
+ class:pipeline-view={!!pipelineId}
755
+ onclick={handleCanvasClick}
756
+ onkeydown={(e) => e.key === 'Escape' && closeConfigSidebar()}
757
+ role="region"
758
+ aria-label="Workflow canvas"
759
+ >
760
+ <WorkflowEditor
761
+ bind:this={workflowEditorRef}
762
+ {nodes}
763
+ {height}
764
+ {width}
765
+ {endpointConfig}
766
+ {isConfigSidebarOpen}
767
+ selectedNodeForConfig={selectedNodeForConfig()}
768
+ {openConfigSidebar}
769
+ {closeConfigSidebar}
770
+ {lockWorkflow}
771
+ {readOnly}
772
+ {nodeStatuses}
773
+ {pipelineId}
774
+ />
775
+ </div>
776
+ </MainLayout>
837
777
 
778
+ <style>
779
+ /* Status bar styles */
838
780
  .flowdrop-status {
839
781
  background-color: #eff6ff;
840
782
  border-bottom: 1px solid #bfdbfe;
@@ -864,6 +806,7 @@
864
806
  background-color: #ef4444;
865
807
  }
866
808
 
809
+ /* Button styles */
867
810
  .flowdrop-btn {
868
811
  padding: 0.375rem 0.75rem;
869
812
  border-radius: 0.375rem;
@@ -912,6 +855,7 @@
912
855
  color: #374151;
913
856
  }
914
857
 
858
+ /* Utility classes */
915
859
  .flowdrop-flex {
916
860
  display: flex;
917
861
  }
@@ -933,202 +877,13 @@
933
877
  font-weight: 500;
934
878
  }
935
879
 
936
- @keyframes spin {
937
- 0% {
938
- transform: rotate(0deg);
939
- }
940
- 100% {
941
- transform: rotate(360deg);
942
- }
943
- }
944
-
945
- .flowdrop-editor-container {
946
- flex: 1;
947
- position: relative;
948
- min-height: 0;
949
- overflow: hidden;
950
- display: flex;
951
- }
952
-
953
- .flowdrop-sidebar {
954
- background-color: #ffffff;
955
- border: 1px solid #e5e7eb;
956
- overflow-y: auto;
957
- overflow-x: hidden;
958
- height: 100%;
959
- display: flex;
960
- flex-direction: column;
961
- /* Custom scrollbar styling */
962
- scrollbar-width: thin;
963
- scrollbar-color: #cbd5e1 #f1f5f9;
964
- }
965
-
966
- .flowdrop-sidebar::-webkit-scrollbar {
967
- width: 8px;
968
- }
969
-
970
- .flowdrop-sidebar::-webkit-scrollbar-track {
971
- background: #f1f5f9;
972
- border-radius: 4px;
973
- }
974
-
975
- .flowdrop-sidebar::-webkit-scrollbar-thumb {
976
- background: #cbd5e1;
977
- border-radius: 4px;
978
- }
979
-
980
- .flowdrop-sidebar::-webkit-scrollbar-thumb:hover {
981
- background: #94a3b8;
982
- }
983
-
984
- .flowdrop-sidebar--left {
985
- width: 320px;
986
- min-width: 320px;
987
- border-right: 1px solid #e5e7eb;
988
- box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1);
989
- display: flex;
990
- flex-direction: column;
991
- }
992
-
993
- .flowdrop-sidebar--right {
994
- border-left: 1px solid #e5e7eb;
995
- box-shadow: -2px 0 4px rgba(0, 0, 0, 0.1);
996
- }
997
-
880
+ /* Main editor area */
998
881
  .flowdrop-editor-main {
999
882
  flex: 1;
1000
883
  position: relative;
1001
884
  min-width: 0;
885
+ height: 100%;
1002
886
  overflow: hidden;
1003
887
  background-color: #1f2937;
1004
888
  }
1005
-
1006
- /* Configuration Sidebar Styles */
1007
- .flowdrop-config-sidebar {
1008
- height: 100%;
1009
- display: flex;
1010
- flex-direction: column;
1011
- background-color: #ffffff;
1012
- }
1013
-
1014
- .flowdrop-config-sidebar__header {
1015
- display: flex;
1016
- justify-content: space-between;
1017
- align-items: center;
1018
- padding: 1rem;
1019
- border-bottom: 1px solid #e5e7eb;
1020
- background-color: #f9fafb;
1021
- }
1022
-
1023
- .flowdrop-config-sidebar__title {
1024
- margin: 0;
1025
- font-size: 1.125rem;
1026
- font-weight: 600;
1027
- color: #111827;
1028
- }
1029
-
1030
- .flowdrop-config-sidebar__close {
1031
- background: none;
1032
- border: none;
1033
- font-size: 1.5rem;
1034
- cursor: pointer;
1035
- color: #6b7280;
1036
- padding: 0.25rem;
1037
- border-radius: 0.25rem;
1038
- transition: color 0.2s;
1039
- }
1040
-
1041
- .flowdrop-config-sidebar__close:hover {
1042
- color: #374151;
1043
- background-color: #f3f4f6;
1044
- }
1045
-
1046
- .flowdrop-config-sidebar__content {
1047
- flex: 1;
1048
- overflow-y: auto;
1049
- padding: 1rem;
1050
- }
1051
-
1052
- .flowdrop-config-sidebar__section {
1053
- margin-bottom: 1.5rem;
1054
- }
1055
-
1056
- .flowdrop-config-sidebar__section-title {
1057
- margin: 0 0 0.75rem 0;
1058
- font-size: 0.875rem;
1059
- font-weight: 600;
1060
- color: #374151;
1061
- text-transform: uppercase;
1062
- letter-spacing: 0.05em;
1063
- }
1064
-
1065
- .flowdrop-config-sidebar__details {
1066
- display: flex;
1067
- flex-direction: column;
1068
- gap: 0.5rem;
1069
- }
1070
-
1071
- .flowdrop-config-sidebar__detail {
1072
- display: flex;
1073
- flex-direction: column;
1074
- gap: 0.25rem;
1075
- }
1076
-
1077
- .flowdrop-config-sidebar__detail-label {
1078
- font-size: 0.75rem;
1079
- font-weight: 500;
1080
- color: #6b7280;
1081
- text-transform: uppercase;
1082
- letter-spacing: 0.05em;
1083
- }
1084
-
1085
- .flowdrop-config-sidebar__detail-value {
1086
- font-size: 0.875rem;
1087
- color: #111827;
1088
- font-weight: 500;
1089
- }
1090
-
1091
- .flowdrop-config-sidebar__detail-value-with-copy {
1092
- display: flex;
1093
- align-items: center;
1094
- gap: 0.5rem;
1095
- background-color: #f3f4f6;
1096
- padding: 0.5rem;
1097
- border-radius: 0.375rem;
1098
- border: 1px solid #e5e7eb;
1099
- }
1100
-
1101
- .flowdrop-config-sidebar__detail-value-with-copy .flowdrop-config-sidebar__detail-value {
1102
- flex: 1;
1103
- font-size: 0.8125rem;
1104
- word-break: break-all;
1105
- }
1106
-
1107
- .flowdrop-config-sidebar__copy-btn {
1108
- background: white;
1109
- border: 1px solid #d1d5db;
1110
- border-radius: 0.25rem;
1111
- padding: 0.25rem 0.5rem;
1112
- cursor: pointer;
1113
- font-size: 1rem;
1114
- transition: all 0.2s;
1115
- flex-shrink: 0;
1116
- }
1117
-
1118
- .flowdrop-config-sidebar__copy-btn:hover {
1119
- background-color: #f9fafb;
1120
- border-color: #9ca3af;
1121
- transform: scale(1.05);
1122
- }
1123
-
1124
- .flowdrop-config-sidebar__copy-btn:active {
1125
- transform: scale(0.95);
1126
- }
1127
-
1128
- .flowdrop-config-sidebar__detail-description {
1129
- margin: 0;
1130
- font-size: 0.875rem;
1131
- color: #6b7280;
1132
- line-height: 1.4;
1133
- }
1134
889
  </style>