Skip to content

Commit 5c1e800

Browse files
committed
fix style issues in new ai chat ui
1 parent f1b382d commit 5c1e800

File tree

7 files changed

+211
-151
lines changed

7 files changed

+211
-151
lines changed

apps/remix-ide/src/app/plugins/remix-ai-assistant.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { EventEmitter } from 'events'
88
const profile = {
99
name: 'remixaiassistant',
1010
displayName: 'Remix AI Assistant',
11-
icon: 'assets/img/remixai-logoDefault.webp',
11+
icon: 'assets/img/remixai-logoAI.webp',
1212
description: 'AI code assistant for Remix IDE',
1313
kind: 'remixaiassistant',
1414
location: 'sidePanel',

libs/remix-ui/remix-ai-assistant/src/components/chat.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import React from 'react'
66

77
const DEFAULT_SUGGESTIONS = [
88
'Explain what a modifier is',
9-
'Explain what a UniSwap hook is',
9+
'What is a UniSwap hook?',
1010
'What is a ZKP?'
1111
]
1212

@@ -29,24 +29,23 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
2929
return (
3030
<div
3131
ref={historyRef}
32-
className="ai-chat-history"
33-
style={{ flexGrow: 1, overflowY: 'auto' }}
32+
className="d-flex flex-column flex-grow-1 overflow-y-auto"
3433
>
3534
{messages.length === 0 ? (
3635
<div className="assistant-landing d-flex flex-column align-items-center justify-content-center text-center px-3 h-100">
3736
<img src={assistantAvatar} alt="RemixAI logo" style={{ width: '120px' }} className="mb-3" />
3837
<h5 className="mb-2">RemixAI</h5>
39-
<p className="mb-4" style={{ maxWidth: '220px' }}>
38+
<p className="mb-4" style={{ fontSize: '1.1rem' }}>
4039
RemixAI provides you personalized guidance as you build. It can break down concepts,
4140
answer questions about blockchain technology and assist you with your smart contracts.
4241
</p>
4342
{DEFAULT_SUGGESTIONS.map(s => (
4443
<button
4544
key={s}
46-
className="btn btn-secondary mb-2 w-100"
45+
className="btn btn-secondary mb-2 w-100 text-left"
4746
onClick={() => sendPrompt(s)}
4847
>
49-
<i className="fa fa-user-robot-xmarks mr-2"></i>{s}
48+
<i className="fa-kit fa-remixai mr-2"></i>{s}
5049
</button>
5150
))}
5251
</div>
@@ -67,7 +66,7 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
6766
)}
6867

6968
{/* Bubble */}
70-
<div className="flex-grow-1">
69+
<div data-region="chat-bubble-section" className="flex-grow-1 w-25 mr-1">
7170
<div className={`chat-bubble p-2 rounded ${bubbleClass}`}>
7271
{msg.role === 'user' && (
7372
<small className="text-uppercase fw-bold text-secondary d-block mb-1">
@@ -93,7 +92,7 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
9392

9493
return (
9594
<div
96-
className="code-block position-relative"
95+
className="code-block p-2 border border-text d-flex align-items-center"
9796
>
9897
<button
9998
type="button"

libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx

Lines changed: 135 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,15 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
4444
dispatchActivity
4545
}) => {
4646
return (
47-
<div
48-
className="prompt-area d-flex flex-column gap-2 p-2 mx-2"
49-
style={{
50-
background: 'rgba(255,255,255,0.04)', // same dark tone as input row
51-
borderRadius: '4px'
52-
}}
53-
>
47+
<>
5448
{showContextOptions && (
5549
<div
56-
className="rounded p-3 mb-2"
50+
className=" w-100 bg-dark p-2 border border-text border-bottom-0 rounded"
5751
>
58-
<h6 className="text-uppercase small mb-3">Add Context Files</h6>
59-
<div className="form-check mb-2">
52+
<div className="text-uppercase ml-2 mb-2">Add Context Files</div>
53+
<div className="d-flex ml-2 custom-control custom-radio">
6054
<input
61-
className="form-check-input"
55+
className="custom-control-input"
6256
type="radio"
6357
id="ctx-none"
6458
checked={contextChoice === 'none'}
@@ -68,13 +62,13 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
6862
setShowContextOptions(false)
6963
}}
7064
/>
71-
<label className="form-check-label" htmlFor="ctx-none">
65+
<label className="form-check-label custom-control-label" htmlFor="ctx-none">
7266
None
7367
</label>
7468
</div>
75-
<div className="form-check mb-2">
69+
<div className="d-flex ml-2 custom-control custom-radio">
7670
<input
77-
className="form-check-input"
71+
className="custom-control-input"
7872
type="radio"
7973
id="ctx-current"
8074
data-id="currentFile-context-option"
@@ -84,13 +78,13 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
8478
setShowContextOptions(false)
8579
}}
8680
/>
87-
<label className="form-check-label" htmlFor="ctx-current">
81+
<label className="form-check-label custom-control-label" htmlFor="ctx-current">
8882
Current file
8983
</label>
9084
</div>
91-
<div className="form-check mb-2">
85+
<div className="d-flex ml-2 custom-control custom-radio">
9286
<input
93-
className="form-check-input"
87+
className="custom-control-input"
9488
type="radio"
9589
id="ctx-opened"
9690
data-id="allOpenedFiles-context-option"
@@ -100,13 +94,13 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
10094
setShowContextOptions(false)
10195
}}
10296
/>
103-
<label className="form-check-label" htmlFor="ctx-opened">
97+
<label className="form-check-label custom-control-label" htmlFor="ctx-opened">
10498
All opened files
10599
</label>
106100
</div>
107-
<div className="form-check">
101+
<div className="d-flex ml-2 custom-control custom-radio">
108102
<input
109-
className="form-check-input"
103+
className="custom-control-input"
110104
type="radio"
111105
id="ctx-workspace"
112106
data-id="workspace-context-option"
@@ -116,110 +110,140 @@ export const PromptArea: React.FC<PromptAreaProps> = ({
116110
setShowContextOptions(false)
117111
}}
118112
/>
119-
<label className="form-check-label" htmlFor="ctx-workspace">
113+
<label className="form-check-label custom-control-label" htmlFor="ctx-workspace">
120114
Workspace
121115
</label>
122116
</div>
123117
</div>
124118
)}
125-
{showAssistantOptions && (
126-
<div
127-
className="rounded p-3 mb-2"
128-
>
129-
<h6 className="text-uppercase small mb-3">Choose Assistant Model</h6>
130119

131-
{['openai', 'mistralai', 'anthropic'].map(val => (
132-
<div className="form-check mb-2" key={val}>
133-
<input
134-
className="form-check-input"
135-
type="radio"
136-
id={`assistant-${val}`}
137-
checked={assistantChoice === val}
138-
onChange={() => {
139-
setAssistantChoice(val as any)
140-
setShowAssistantOptions(false)
141-
}}
142-
/>
143-
<label className="form-check-label" htmlFor={`assistant-${val}`}>
144-
{val}
145-
</label>
146-
</div>
147-
))}
148-
</div>
149-
)}
150-
<div className="d-flex gap-2 mb-2">
151-
<button
152-
onClick={handleAddContext}
153-
data-id="composer-ai-add-context"
154-
className={`btn mr-2 ${showContextOptions ? 'btn-dark' : 'btn-text'}`}
155-
>
120+
<div
121+
className="prompt-area d-flex flex-column gap-2 w-100 p-3"
122+
>
123+
<div className="d-flex justify-content-between mb-2">
124+
<button
125+
onClick={handleAddContext}
126+
data-id="composer-ai-add-context"
127+
className="btn btn-dark btn-sm text-secondary"
128+
>
156129
Add context&nbsp;
157-
{/* <i className={`fa fa-caret-${showContextOptions ? 'down' : 'up'}`}></i> */}
158-
</button>
130+
</button>
159131

160-
<button
161-
onClick={handleSetAssistant}
162-
className={`btn mr-2 ${showAssistantOptions ? 'btn-dark' : 'btn-text'}`}
163-
>
164-
@Set assistant&nbsp;
165-
{/* <i className={`fa fa-caret-${showAssistantOptions ? 'down' : 'up'}`}></i> */}
166-
</button>
167-
168-
<button
169-
onClick={handleGenerateWorkspace}
170-
className="btn btn-dark"
171-
data-id="composer-ai-workspace-generate"
172-
>
132+
<button
133+
onClick={handleGenerateWorkspace}
134+
className="btn btn-dark btn-sm text-secondary"
135+
data-id="composer-ai-workspace-generate"
136+
>
173137
@Generate Workspace
174-
</button>
175-
</div>
176-
<div className="ai-chat-input">
177-
<input
178-
style={{ flexGrow: 1 }}
179-
type="text"
180-
className="form-control"
181-
value={input}
182-
disabled={isStreaming}
183-
onFocus={() => {
184-
dispatchActivity('typing', input)
185-
}}
186-
onChange={e => {
187-
dispatchActivity('typing', e.target.value)
188-
setInput(e.target.value)
189-
}}
190-
onKeyDown={e => {
191-
if (e.key === 'Enter' && !isStreaming) handleSend()
192-
}}
193-
placeholder="Ask me anything, use button to add context..."
194-
/>
195-
</div>
196-
{contextChoice !== 'none' && contextFiles.length > 0 && (
197-
<div className="mt-2 d-flex flex-wrap gap-1" style={{ maxHeight: '110px', overflowY: 'auto' }}>
198-
{contextFiles.slice(0, 6).map(f => {
199-
const name = f.split('/').pop()
200-
return (
138+
</button>
139+
</div>
140+
<div className="ai-chat-input d-flex flex-column">
141+
<input
142+
style={{ flexGrow: 1 }}
143+
type="text"
144+
className="form-control bg-light"
145+
value={input}
146+
disabled={isStreaming}
147+
onFocus={() => {
148+
dispatchActivity('typing', input)
149+
}}
150+
onChange={e => {
151+
dispatchActivity('typing', e.target.value)
152+
setInput(e.target.value)
153+
}}
154+
onKeyDown={e => {
155+
if (e.key === 'Enter' && !isStreaming) handleSend()
156+
}}
157+
placeholder="Ask me anything, add workspace files..."
158+
/>
159+
{showAssistantOptions && (
160+
<div
161+
className="p-3 mb-2 z-3 bg-dark border border-text position-absolute"
162+
style={{ top: '79dvh', left: '85dvw', right: '0px', bottom: '15px', height: '125px', width: '220px', borderRadius: '15px' }}
163+
>
164+
<div className="text-uppercase ml-2 mb-2">Choose Assistant Model</div>
165+
<div className="d-flex ml-2 custom-control custom-radio" key={'openai'}>
166+
<input
167+
className="custom-control-input"
168+
type="radio"
169+
id={`assistant-openai`}
170+
checked={assistantChoice === 'openai'}
171+
onChange={() => {
172+
setAssistantChoice('openai')
173+
setShowAssistantOptions(false)
174+
}}
175+
/>
176+
<label className="form-check-label custom-control-label" htmlFor={`assistant-openai`}>
177+
OpenAI
178+
</label>
179+
</div>
180+
<div className="d-flex ml-2 custom-control custom-radio" key={'mistralai'}>
181+
<input
182+
className="custom-control-input"
183+
type="radio"
184+
id={`assistant-mistralai`}
185+
checked={assistantChoice === 'mistralai'}
186+
onChange={() => {
187+
setAssistantChoice('mistralai')
188+
setShowAssistantOptions(false)
189+
}}
190+
/>
191+
<label className="form-check-label custom-control-label" htmlFor={`assistant-mistralai`}>
192+
MistralAI
193+
</label>
194+
</div>
195+
<div className="d-flex ml-2 custom-control custom-radio" key={'anthropic'}>
196+
<input
197+
className="custom-control-input"
198+
type="radio"
199+
id={`assistant-anthropic`}
200+
checked={assistantChoice === 'anthropic'}
201+
onChange={() => {
202+
setAssistantChoice('anthropic')
203+
setShowAssistantOptions(false)
204+
}}
205+
/>
206+
<label className="form-check-label custom-control-label" htmlFor={`assistant-anthropic`}>
207+
Anthropic
208+
</label>
209+
</div>
210+
</div>
211+
)}
212+
<button
213+
onClick={handleSetAssistant}
214+
className="btn btn-dark btn-sm text-secondary mt-2 align-self-end"
215+
>
216+
Set assistant&nbsp;
217+
</button>
218+
</div>
219+
{contextChoice !== 'none' && contextFiles.length > 0 && (
220+
<div className="mt-2 d-flex flex-wrap gap-1 overflow-y-auto" style={{ maxHeight: '110px' }}>
221+
{contextFiles.slice(0, 6).map(f => {
222+
const name = f.split('/').pop()
223+
return (
224+
<span
225+
key={f}
226+
className="badge badge-info mr-1 aiContext-file text-success"
227+
style={{ cursor: 'pointer' }}
228+
onClick={clearContext}
229+
>
230+
{name}
231+
<i className="fa fa-times ms-1 ml-1" style={{ cursor: 'pointer' }}></i>
232+
</span>
233+
)
234+
})}
235+
{contextFiles.length > 6 && (
201236
<span
202-
key={f}
203-
className="badge badge-info mr-1 aiContext-file text-success"
237+
className="badge badge-info"
204238
style={{ cursor: 'pointer' }}
205239
onClick={clearContext}
206240
>
207-
{name}
208-
<i className="fa fa-times ms-1 ml-1" style={{ cursor: 'pointer' }}></i>
209-
</span>
210-
)
211-
})}
212-
{contextFiles.length > 6 && (
213-
<span
214-
className="badge badge-info"
215-
style={{ cursor: 'pointer' }}
216-
onClick={clearContext}
217-
>
218241
{contextFiles.length - 6} more <i className="fa fa-times ms-1" style={{ cursor: 'pointer' }}></i>
219-
</span>
220-
)}
221-
</div>
222-
)}
223-
</div>
242+
</span>
243+
)}
244+
</div>
245+
)}
246+
</div>
247+
</>
224248
)
225249
}

libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
258258
ERC‑20 token with foundry tests
259259
ERC‑721 NFT collection with IPFS metadata
260260
Decentralized voting app with Solidity smart contracts
261-
261+
262262
`,
263263
modalType: ModalTypes.prompt, // single-line text
264264
okLabel: 'Generate',
@@ -295,8 +295,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
295295

296296
return (
297297
<div
298-
className="ai-chat-container"
299-
style={{ display: 'flex', flexDirection: 'column', height: '100%' }}
298+
className="d-flex flex-column h-100 mx-3"
300299
>
301300
<div data-id="remix-ai-assistant-ready"></div>
302301
{/* hidden hook for E2E tests: data-streaming="true|false" */}

0 commit comments

Comments
 (0)