1+ <!-- Context Creation Modal -->
2+ < div id ="context-modal-overlay " class ="fixed inset-0 bg-black bg-opacity-50 z-50 hidden ">
3+ < div class ="flex items-center justify-center min-h-screen p-4 " onclick ="closeContextModal() ">
4+ < div id ="context-modal " class ="bg-white border-2 border-black shadow-[8px_8px_0px_0px_rgba(0,0,0,1)] p-6 max-w-md w-full " onclick ="event.stopPropagation() ">
5+ <!-- Modal Header -->
6+ < h2 class ="text-xl font-black text-black mb-4 "> Create new context</ h2 >
7+
8+ <!-- Modal Body -->
9+ < div class ="mb-6 ">
10+ < label for ="context-name-input " class ="block text-sm font-bold text-black mb-2 "> Context name</ label >
11+ < input
12+ type ="text "
13+ id ="context-name-input "
14+ class ="w-full px-3 py-2 border-2 border-black focus:outline-none "
15+ placeholder ="e.g. My Project "
16+ autocomplete ="off "
17+ />
18+ < div id ="context-modal-error " class ="text-red-600 text-sm mt-2 hidden "> </ div >
19+ </ div >
20+
21+ <!-- Modal Actions -->
22+ < div class ="flex gap-2 justify-end ">
23+ < button
24+ onclick ="closeContextModal() "
25+ class ="px-4 py-2 bg-gray-200 border-2 border-black text-black font-bold shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] hover:shadow-[3px_3px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-1px] hover:translate-y-[-1px] active:shadow-[1px_1px_0px_0px_rgba(0,0,0,1)] active:translate-x-[1px] active:translate-y-[1px] transition-all ">
26+ Cancel
27+ </ button >
28+ < button
29+ onclick ="submitContextModal() "
30+ class ="px-4 py-2 bg-pink-400 border-2 border-black text-black font-bold shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] hover:shadow-[3px_3px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[-1px] hover:translate-y-[-1px] active:shadow-[1px_1px_0px_0px_rgba(0,0,0,1)] active:translate-x-[1px] active:translate-y-[1px] transition-all ">
31+ Create
32+ </ button >
33+ </ div >
34+ </ div >
35+ </ div >
36+ </ div >
37+
38+ < script >
39+ let contextModalCallback = null ;
40+ let previousContextFocusElement = null ;
41+
42+ function openContextModal ( ) {
43+ const modal = document . getElementById ( 'context-modal-overlay' ) ;
44+ const input = document . getElementById ( 'context-name-input' ) ;
45+ const error = document . getElementById ( 'context-modal-error' ) ;
46+
47+ // Reset any previous callback
48+ if ( contextModalCallback ) {
49+ contextModalCallback ( null ) ;
50+ contextModalCallback = null ;
51+ }
52+
53+ // Store the currently focused element
54+ previousContextFocusElement = document . activeElement ;
55+
56+ // Reset and show modal
57+ modal . classList . remove ( 'hidden' ) ;
58+ error . classList . add ( 'hidden' ) ;
59+ error . textContent = '' ;
60+ input . value = '' ;
61+
62+ // Focus input
63+ setTimeout ( ( ) => {
64+ input . focus ( ) ;
65+ } , 50 ) ;
66+
67+ // Remove any existing event listeners
68+ input . onkeydown = null ;
69+
70+ // Handle Enter and Escape keys
71+ input . addEventListener ( 'keydown' , ( e ) => {
72+ if ( e . key === 'Enter' ) {
73+ e . preventDefault ( ) ;
74+ submitContextModal ( ) ;
75+ } else if ( e . key === 'Escape' ) {
76+ e . preventDefault ( ) ;
77+ closeContextModal ( ) ;
78+ }
79+ } ) ;
80+
81+ return new Promise ( ( resolve ) => {
82+ contextModalCallback = resolve ;
83+ } ) ;
84+ }
85+
86+ function closeContextModal ( ) {
87+ const modal = document . getElementById ( 'context-modal-overlay' ) ;
88+ modal . classList . add ( 'hidden' ) ;
89+
90+ // Restore focus
91+ if ( previousContextFocusElement ) {
92+ previousContextFocusElement . focus ( ) ;
93+ }
94+
95+ if ( contextModalCallback ) {
96+ contextModalCallback ( null ) ;
97+ contextModalCallback = null ;
98+ }
99+ }
100+
101+ function submitContextModal ( ) {
102+ const input = document . getElementById ( 'context-name-input' ) ;
103+ const error = document . getElementById ( 'context-modal-error' ) ;
104+ const contextName = input . value . trim ( ) ;
105+
106+ // Validation
107+ if ( ! contextName ) {
108+ error . textContent = 'Please enter a context name' ;
109+ error . classList . remove ( 'hidden' ) ;
110+ return ;
111+ }
112+
113+ // Check for invalid characters (very permissive for context names)
114+ if ( contextName . length > 100 ) {
115+ error . textContent = 'Context name is too long (max 100 characters)' ;
116+ error . classList . remove ( 'hidden' ) ;
117+ return ;
118+ }
119+
120+ // Close modal and return result
121+ const modal = document . getElementById ( 'context-modal-overlay' ) ;
122+ modal . classList . add ( 'hidden' ) ;
123+
124+ // Restore focus
125+ if ( previousContextFocusElement ) {
126+ previousContextFocusElement . focus ( ) ;
127+ }
128+
129+ if ( contextModalCallback ) {
130+ contextModalCallback ( contextName ) ;
131+ contextModalCallback = null ;
132+ }
133+ }
134+
135+ // Export for global use
136+ window . openContextModal = openContextModal ;
137+ window . closeContextModal = closeContextModal ;
138+ window . submitContextModal = submitContextModal ;
139+ </ script >
0 commit comments