@@ -43,137 +43,72 @@ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e)
4343
4444initTheme ( ) ;
4545
46- // Examples data
47- const exampleCases = [
48- {
49- id : 'math' ,
50- title : 'Mathematical Expression' ,
51- description : 'Basic math operations with variables' ,
52- expression : '(x + y) * multiplier + sqrt(16)' ,
53- context : {
54- x : 10 ,
55- y : 5 ,
56- multiplier : 3
57- }
58- } ,
59- {
60- id : 'arrays' ,
61- title : 'Working with Arrays' ,
62- description : 'Array functions like sum, min, max' ,
63- expression : 'sum(numbers) + max(numbers) - min(numbers)' ,
64- context : {
65- numbers : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ,
66- values : [ 15 , 25 , 35 ]
67- }
68- } ,
69- {
70- id : 'objects' ,
71- title : 'Object Manipulation' ,
72- description : 'Access nested object properties' ,
73- expression : 'user.profile.score * level.multiplier + bonus.points' ,
74- context : {
75- user : {
76- name : "Alice" ,
77- profile : {
78- score : 85 ,
79- rank : "Gold"
80- }
81- } ,
82- level : {
83- current : 5 ,
84- multiplier : 1.5
85- } ,
86- bonus : {
87- points : 100 ,
88- active : true
89- }
90- }
91- } ,
92- {
93- id : 'map-filter' ,
94- title : 'Map and Filter Functions' ,
95- description : 'Transform and filter data with callbacks' ,
96- expression : 'sum(map(filter(items, item => item > 3), x => x * 2))' ,
97- context : {
98- items : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ,
99- threshold : 3
100- }
101- } ,
102- {
103- id : 'complex' ,
104- title : 'Complex Objects' ,
105- description : 'Work with deeply nested data structures' ,
106- expression : 'company.departments[0].employees.length * company.settings.bonusRate + sum(map(company.departments, d => d.budget))' ,
107- context : {
108- company : {
109- name : "TechCorp" ,
110- departments : [
111- {
112- name : "Engineering" ,
113- budget : 500000 ,
114- employees : [ "John" , "Jane" , "Bob" ]
115- } ,
116- {
117- name : "Marketing" ,
118- budget : 200000 ,
119- employees : [ "Alice" , "Carol" ]
120- }
121- ] ,
122- settings : {
123- bonusRate : 0.15 ,
124- fiscalYear : 2024
125- }
126- }
127- }
128- } ,
129- {
130- id : 'data-transform' ,
131- title : 'Data Transformation' ,
132- description : 'Flatten nested objects and transform rows' ,
133- expression : "map(f(row) = {_id: row.rowId} + flatten(row.data, ''), $event)" ,
134- context : {
135- "$event" : [
136- { "rowId" : 1 , "state" : "saved" , "data" : { "InventoryId" : 1256 , "Description" : "Bal" , "Weight" : { "Unit" : "g" , "Amount" : 120 } } } ,
137- { "rowId" : 2 , "state" : "new" , "data" : { "InventoryId" : 2344 , "Description" : "Basket" , "Weight" : { "Unit" : "g" , "Amount" : 300 } } } ,
138- { "rowId" : 3 , "state" : "unchanged" , "data" : { "InventoryId" : 9362 , "Description" : "Wood" , "Weight" : { "Unit" : "kg" , "Amount" : 18 } } }
139- ]
140- }
141- }
142- ] ;
46+ // Copy example link to clipboard
47+ function copyExampleLink ( exampleId , button ) {
48+ const url = new URL ( window . location . href ) ;
49+ url . search = '' ;
50+ url . searchParams . set ( 'example' , exampleId ) ;
51+ navigator . clipboard . writeText ( url . toString ( ) ) . then ( ( ) => {
52+ // Show checkmark briefly
53+ const icon = button . querySelector ( 'svg' ) ;
54+ const originalPath = icon . innerHTML ;
55+ icon . innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />' ;
56+ button . classList . add ( 'text-green-500' , 'dark:text-green-400' ) ;
57+ setTimeout ( ( ) => {
58+ icon . innerHTML = originalPath ;
59+ button . classList . remove ( 'text-green-500' , 'dark:text-green-400' ) ;
60+ } , 1500 ) ;
61+ } ) ;
62+ }
14363
14464// Render examples sidebar
14565function renderExamplesSidebar ( ) {
14666 const examplesList = document . getElementById ( 'examplesList' ) ;
14767 if ( ! examplesList ) return ;
14868
14969 examplesList . innerHTML = exampleCases . map ( example => `
150- <button
151- class="example-item w-full text-left p-3 rounded-lg transition-all duration-200
152- hover:bg-white dark:hover:bg-[#2d2d2d]
153- hover:shadow-sm hover:border-indigo-200 dark:hover:border-[#3c3c3c]
154- border border-transparent
155- group"
156- data-example-id="${ example . id } "
157- >
158- <div class="flex items-start gap-2">
159- <div class="flex-shrink-0 w-6 h-6 rounded bg-indigo-100 dark:bg-[#3c3c3c] flex items-center justify-center mt-0.5">
160- <svg class="w-3.5 h-3.5 text-indigo-600 dark:text-[#569cd6]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
161- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
162- </svg>
70+ <div class="example-container relative group/container">
71+ <button
72+ class="example-item w-full text-left p-3 rounded-lg transition-all duration-200
73+ hover:bg-white dark:hover:bg-[#2d2d2d]
74+ hover:shadow-sm hover:border-indigo-200 dark:hover:border-[#3c3c3c]
75+ border border-transparent
76+ group"
77+ data-example-id="${ example . id } "
78+ >
79+ <div class="flex items-start gap-2">
80+ <div class="flex-shrink-0 w-6 h-6 rounded bg-indigo-100 dark:bg-[#3c3c3c] flex items-center justify-center mt-0.5">
81+ <svg class="w-3.5 h-3.5 text-indigo-600 dark:text-[#569cd6]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
82+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
83+ </svg>
84+ </div>
85+ <div class="flex-1 min-w-0">
86+ <p class="text-sm font-medium text-gray-800 dark:text-[#cccccc] truncate group-hover:text-indigo-600 dark:group-hover:text-[#569cd6]">
87+ ${ example . title }
88+ </p>
89+ <p class="text-xs text-gray-500 dark:text-[#808080] mt-0.5 line-clamp-2">
90+ ${ example . description }
91+ </p>
92+ </div>
16393 </div>
164- <div class="flex-1 min-w-0">
165- <p class="text-sm font-medium text-gray-800 dark:text-[#cccccc] truncate group-hover:text-indigo-600 dark:group-hover:text-[#569cd6]">
166- ${ example . title }
167- </p>
168- <p class="text-xs text-gray-500 dark:text-[#808080] mt-0.5 line-clamp-2">
169- ${ example . description }
170- </p>
171- </div>
172- </div>
173- </button>
94+ </button>
95+ <button
96+ class="copy-link-btn absolute top-2 right-2 p-1.5 rounded-md
97+ opacity-0 group-hover/container:opacity-100
98+ bg-gray-100 dark:bg-[#3c3c3c] hover:bg-gray-200 dark:hover:bg-[#4c4c4c]
99+ text-gray-500 dark:text-[#808080] hover:text-indigo-600 dark:hover:text-[#569cd6]
100+ transition-all duration-200"
101+ data-example-id="${ example . id } "
102+ title="Copy link to example"
103+ >
104+ <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
105+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
106+ </svg>
107+ </button>
108+ </div>
174109 ` ) . join ( '' ) ;
175110
176- // Add click handlers
111+ // Add click handlers for loading examples
177112 examplesList . querySelectorAll ( '.example-item' ) . forEach ( button => {
178113 button . addEventListener ( 'click' , ( ) => {
179114 const exampleId = button . dataset . exampleId ;
@@ -183,6 +118,15 @@ function renderExamplesSidebar() {
183118 }
184119 } ) ;
185120 } ) ;
121+
122+ // Add click handlers for copy link buttons
123+ examplesList . querySelectorAll ( '.copy-link-btn' ) . forEach ( button => {
124+ button . addEventListener ( 'click' , ( e ) => {
125+ e . stopPropagation ( ) ;
126+ const exampleId = button . dataset . exampleId ;
127+ copyExampleLink ( exampleId , button ) ;
128+ } ) ;
129+ } ) ;
186130}
187131
188132// Load example into editors
0 commit comments