Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: UX improvements for arguments passing #44

Merged
merged 4 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 67 additions & 5 deletions components/Editor/EditorControls.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useRef } from 'react'
import { useRef, useState } from 'react'

import { RiLinksLine } from '@remixicon/react'
import { RiLinksLine, RiQuestionLine } from '@remixicon/react'
import cn from 'classnames'

import { Button, Input } from 'components/ui'
import { Button, Input, Modal } from 'components/ui'

type EditorControlsProps = {
isCompileDisabled: boolean
Expand All @@ -23,6 +23,68 @@ const EditorControls = ({
onProgramArgumentsUpdate,
}: EditorControlsProps) => {
const inputRef = useRef<HTMLInputElement>(null)
const [showArgumentsHelper, setShowArgumentsHelper] = useState(false)

const argumentHelperModal = (
<Modal
title="Program arguments helper"
visible={showArgumentsHelper}
setVisible={setShowArgumentsHelper}
>
<div
className="text-sm md:text-md lg:text-lg text-gray-900 dark:text-gray-900"
role="button"
tabIndex={0}
onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
>
<p className="my-2">
This input field accepts a list of program arguments separated by a{' '}
<span className="font-semibold">whitespace</span>.
</p>
<p className="my-2">Each argument could be:</p>
<ul className="list-disc ml-4">
<li>
a <span className="font-semibold">single</span>
<code className="mx-1 text-orange-600">felt252</code>,
</li>
<li>
an <span className="font-semibold">array</span> of
<code className="mx-1 text-orange-600">felt252</code> where items
are also separated by a{' '}
<span className="font-semibold">whitespace</span>.
</li>
</ul>
<p className="mt-2 italic">
Note that only decimal values are supported for{' '}
<code className="mx-1 text-orange-600">felt252</code>. That means
neither hexadecimal value nor short string are supported yet.
</p>
<p className="mt-4">
Of course, the signature of your{' '}
<code className="mx-1 text-orange-600">main()</code> function must be
adapted accordingly.
</p>
<p className="mt-6">
For example,{' '}
<code className="px-1 bg-gray-200 text-orange-600">1 [3 4 5] 9</code>{' '}
contains 3 arguments and the corresponding main function should be{' '}
<code className="mx-1 text-orange-600">
main(x: felt252, y: Array&lt;felt252&gt;, z: felt252)
</code>
.
</p>
</div>
</Modal>
)
const argumentHelperIcon = (
<>
<button onClick={() => setShowArgumentsHelper(true)}>
<RiQuestionLine size={20} className="text-gray-400" />
</button>
{showArgumentsHelper && argumentHelperModal}
</>
)

return (
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-x-4 px-4 py-4 md:py-2 md:border-r border-gray-200 dark:border-black-500">
Expand All @@ -42,12 +104,13 @@ const EditorControls = ({

<Input
ref={inputRef}
rightIcon={argumentHelperIcon}
onChange={(e) => {
onProgramArgumentsUpdate(e.target.value)
}}
readOnly={isCompileDisabled}
value={programArguments}
placeholder={`Enter program parameters...`}
placeholder={`Enter program arguments...`}
className={cn('grow border bg-gray-200 dark:bg-gray-800', {
'dark:border-gray-800 border-gray-200': areProgramArgumentsValid,
'border-red-500': !areProgramArgumentsValid,
Expand All @@ -56,7 +119,6 @@ const EditorControls = ({
'text-red-500': !areProgramArgumentsValid,
})}
/>

<div>
<Button
onClick={onCompileRun}
Expand Down
3 changes: 2 additions & 1 deletion components/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ const Editor = ({ readOnly = false }: Props) => {
} else if (isCompiling === CompilationState.Error) {
handleLogs(logs)
}
}, [isCompiling, log, serializedOutput])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isCompiling, log, serializedOutput, logs])

const handleCairoCodeChange = (value: string) => {
setCairoCode(value)
Expand Down
9 changes: 3 additions & 6 deletions components/ui/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import cn from 'classnames'
type Props = {
searchable?: boolean
ref?: ForwardedRef<HTMLInputElement>
rightIcon?: JSX.Element
className?: string
inputClassName?: string
readOnly?: boolean
Expand All @@ -14,6 +15,7 @@ export const Input: React.FC<Props> = forwardRef(
(
{
searchable = false,
rightIcon = null,
onFocus,
onBlur,
className,
Expand All @@ -23,18 +25,15 @@ export const Input: React.FC<Props> = forwardRef(
},
ref: ForwardedRef<HTMLInputElement>,
) => {
const [isFocused, setIsFocused] = useState(false)
const [isInputEmpty, setIsInputEmpty] = useState(true)

const handleFocus = (e: any) => {
setIsFocused(true)
if (onFocus) {
onFocus(e)
}
}

const handleBlur = (e: any) => {
setIsFocused(false)
if (onBlur && e) {
onBlur(e)
}
Expand All @@ -52,9 +51,6 @@ export const Input: React.FC<Props> = forwardRef(
<div
className={cn(
'flex items-center rounded px-3 py-2 text-sm relative',
{
shadow: isFocused,
},
className,
)}
>
Expand All @@ -74,6 +70,7 @@ export const Input: React.FC<Props> = forwardRef(
)}
</>
)}
{rightIcon && rightIcon}
</div>
)
},
Expand Down
43 changes: 43 additions & 0 deletions components/ui/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { RiCloseLine } from '@remixicon/react'

export type ModalProps = {
title: string
visible: boolean
setVisible: (_visible: boolean) => void
children: React.ReactNode
}

export const Modal = ({
title,
visible,
setVisible,
children,
}: ModalProps): JSX.Element => {
const closeModal = () => setVisible(false)

return visible ? (
<div
className="flex fixed top-0 left-0 z-80 w-screen h-screen bg-gray-800/30 dark:bg-gray-800/50 justify-center items-center"
role="button"
tabIndex={0}
onClick={closeModal}
onKeyDown={closeModal}
>
<div className="fixed inset-0 z-50 overflow-auto bg-black/80 flex">
<div className="max-w-lg lg:max-w-3xl relative p-4 bg-white w-full m-auto flex-col flex rounded-lg">
<div className="flex flex-row justify-between pb-2 border-b border-slate-300 mb-4">
<h2 className="text-sm md:text-md lg:text-lg text-gray-900 dark:text-gray-900 font-semibold">
{title}
</h2>
<button onClick={closeModal} aria-label="Close modal">
<RiCloseLine size={24} />
</button>
</div>
{children}
</div>
</div>
</div>
) : (
<></>
)
}
1 change: 1 addition & 0 deletions components/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './Message'
export * from './Radio'
export * from './RelativeLink'
export * from './StackBox'
export * from './Modal'
2 changes: 0 additions & 2 deletions types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { LogType } from '../components/Editor/types'

declare global {
interface Window {
EvmCodes: any
Expand Down
Loading