Skip to content

Commit

Permalink
feat: suite config modal
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad Afonin committed Sep 11, 2022
1 parent 0eae3ba commit e147702
Show file tree
Hide file tree
Showing 18 changed files with 255 additions and 215 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build"
"build": "vite build",
"tsc": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "^18.7.13",
Expand Down
2 changes: 1 addition & 1 deletion src/App.module.styl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

* {
*, ::before, ::after {
box-sizing: border-box
-webkit-tap-highlight-color: transparent
}
Expand Down
4 changes: 2 additions & 2 deletions src/declare.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare module '*.styl'
declare module '*.css'
declare module '*.module.styl'
declare module '*.module.css'

declare module 'monaco-editor/*'

Expand Down
16 changes: 14 additions & 2 deletions src/layout/Suite/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { runAllTests, stopAllTests, suite } from 'model/suite'
import { Modal } from 'ui/Modal'

import { $header, $logo, $title, $controls } from './Header.module.styl'
import { SettingsModal } from './SettingsModal'

export const Header: FC = () => {
const [title, author, running] = useFilter(
Expand All @@ -24,6 +25,7 @@ export const Header: FC = () => {
'running',
)
const [shareModalVisible, setShareModalVisible] = useState(false)
const [configModalVisible, setConfigModalVisible] = useState(false)
const shareModalTimerRef = useRef<NodeJS.Timeout | string | number>()

const handleShare = useCallback(async () => {
Expand All @@ -46,6 +48,10 @@ export const Header: FC = () => {
}, 1000)
}, [])

const handleConfig = useCallback(() => {
setConfigModalVisible(true)
}, [])

return (
<header className={$header}>
<Link href="/">
Expand All @@ -60,7 +66,7 @@ export const Header: FC = () => {

<ClotGroup className={$controls}>
<Button icon={Share} onClick={handleShare} />
<Button icon={Settings} />
<Button icon={Settings} onClick={handleConfig} />
{running ? (
<Button icon={Stop} type="primary" onClick={stopAllTests}>
stop
Expand All @@ -72,7 +78,13 @@ export const Header: FC = () => {
)}
</ClotGroup>

<Modal title="Copied!" name="share" visible={shareModalVisible} />
<SettingsModal
visible={configModalVisible}
onDismiss={setConfigModalVisible}
/>
<Modal name="suite_share" visible={shareModalVisible}>
<Title size="small">Copied!</Title>
</Modal>
</header>
)
}
26 changes: 26 additions & 0 deletions src/layout/Suite/Header/SettingsModal.module.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

.surface {
background: var(--theme-bg-fill)
border-radius: 12px
padding: 16px
display: flex
flex-direction: column
gap: 16px
border: 2px solid var(--theme-bg-text)
}

.title {
display: flex
justify-content: center
}

.content {
display: flex
flex-direction: column
gap: 12px
}

.controls {
display: flex
justify-content: flex-end
}
51 changes: 51 additions & 0 deletions src/layout/Suite/Header/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useSelector } from 'lib/sotore'
import { suite } from 'model/suite'
import { FC } from 'react'
import { Button } from 'ui/Button'
import { Form, TextField } from 'ui/Form'
import { Modal } from 'ui/Modal'
import { Title } from 'ui/Text'

import {
$title,
$surface,
$content,
$controls,
} from './SettingsModal.module.styl'

type Props = {
visible: boolean
onDismiss(value: boolean): void
}

export const SettingsModal: FC<Props> = (props) => {
const { visible, onDismiss } = props

const config = useSelector(suite, ({ title, author }) => ({ title, author }))

const handleApply = (values: Record<string, any>) => {
suite.lay(values)
onDismiss(false)
}

return (
<Modal name="suite_config" visible={visible} onDismiss={onDismiss}>
<Form onSubmit={handleApply} values={config} className={$surface}>
<header className={$title}>
<Title size="small">Suite config</Title>
</header>

<main className={$content}>
<TextField name="title" placeholder="Title" />
<TextField name="author" placeholder="Author" />
</main>

<nav className={$controls}>
<Button size="small" type="primary">
Apply
</Button>
</nav>
</Form>
</Modal>
)
}
156 changes: 0 additions & 156 deletions src/lib/benchmark/legacy.ts

This file was deleted.

4 changes: 4 additions & 0 deletions src/ui/Form/Context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Sotore } from 'lib/sotore'
import { createContext } from 'react'

export const Context = createContext<Sotore<Record<string, any>>>(null!)
27 changes: 27 additions & 0 deletions src/ui/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { sotore } from 'lib/sotore'
import { FC, FormEventHandler, ReactNode, useMemo } from 'react'
import { Context } from './Context'

type Props = {
className?: string
children: ReactNode
values?: Record<string, any>
onSubmit(values: Record<string, any>): void
}

export const Form: FC<Props> = (props) => {
const { className, children, values, onSubmit } = props

const store = useMemo(() => sotore(values ?? {}), [values])

const handleSubmit: FormEventHandler = (e) => {
e.preventDefault()
onSubmit(store.get())
}

return (
<form onSubmit={handleSubmit} className={className}>
<Context.Provider value={store}>{children}</Context.Provider>
</form>
)
}
6 changes: 6 additions & 0 deletions src/ui/Form/FormTextField.module.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

.text-field {
display: flex
flex-direction: column
gap: 8px
}
35 changes: 35 additions & 0 deletions src/ui/Form/FormTextField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useFilter } from 'lib/sotore'
import { FC, useCallback, useContext } from 'react'
import { Text } from 'ui/Text'
import { TextField } from 'ui/TextField'
import { Context } from './Context'

import { $text_field } from './FormTextField.module.styl'

type Props = {
name: string
placeholder: string
}

export const FormTextField: FC<Props> = (props) => {
const { name, placeholder } = props

const store = useContext(Context)
const [value] = useFilter(store, name)

const handleChange = useCallback(
(value: string) => {
store.lay({ [name]: value })
},
[store],
)

return (
<div className={$text_field}>
<Text>{placeholder}</Text>
<TextField onChange={handleChange} placeholder={placeholder}>
{value}
</TextField>
</div>
)
}
2 changes: 2 additions & 0 deletions src/ui/Form/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Form } from './Form'
export { FormTextField as TextField } from './FormTextField'
Loading

0 comments on commit e147702

Please sign in to comment.