Skip to content

Commit e9ade3a

Browse files
committed
refactor(to-sc): EndpointPopup
1 parent 0792431 commit e9ade3a

File tree

3 files changed

+111
-67
lines changed

3 files changed

+111
-67
lines changed

packages/graphql-playground-react/src/components/App.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import MiddlewareApp from './MiddlewareApp'
55
import 'isomorphic-fetch'
66
import EndpointPopup from './EndpointPopup'
77
import Loading from './Loading'
8+
import { ThemeProvider, theme as styledTheme } from '../styled'
89

910
const store = createStore()
1011

@@ -104,17 +105,22 @@ export default class App extends React.Component<Props, State> {
104105
.justifyCenter;
105106
}
106107
`}</style>
108+
107109
{this.state.loading ? (
108-
<Loading />
110+
<ThemeProvider theme={styledTheme}>
111+
<Loading />
112+
</ThemeProvider>
109113
) : !this.state.endpoint || this.state.endpoint.length === 0 ? (
110-
<EndpointPopup
111-
onRequestClose={this.handleChangeEndpoint}
112-
endpoint={
113-
this.state.endpoint ||
114-
localStorage.getItem('last-endpoint') ||
115-
''
116-
}
117-
/>
114+
<ThemeProvider theme={styledTheme}>
115+
<EndpointPopup
116+
onRequestClose={this.handleChangeEndpoint}
117+
endpoint={
118+
this.state.endpoint ||
119+
localStorage.getItem('last-endpoint') ||
120+
''
121+
}
122+
/>
123+
</ThemeProvider>
118124
) : (
119125
<MiddlewareApp
120126
endpoint={endpoint}

packages/graphql-playground-react/src/components/EndpointPopup.tsx

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import * as React from 'react'
22
import * as fetch from 'isomorphic-fetch'
33
import Popup from './Popup'
44
import { throttle } from 'lodash'
5-
import * as cn from 'classnames'
65
import { Button } from './Button'
6+
import { styled, css, withProps } from '../styled'
77

88
export interface Props {
99
onRequestClose: (endpoint: string) => void
@@ -16,8 +16,7 @@ export interface State {
1616
}
1717

1818
export default class EndpointPopup extends React.Component<Props, State> {
19-
// TODO remove `as any` once typescript 2.7 is released
20-
checkEndpoint = (throttle as any)(() => {
19+
checkEndpoint = throttle(() => {
2120
if (this.state.endpoint.match(/^https?:\/\/\w+(\.\w+)*(:[0-9]+)?\/?.*$/)) {
2221
fetch(this.state.endpoint, {
2322
method: 'post',
@@ -41,7 +40,7 @@ export default class EndpointPopup extends React.Component<Props, State> {
4140
this.setState({ valid: false })
4241
})
4342
}
44-
}, 500)
43+
}, 500) as any
4544

4645
constructor(props) {
4746
super(props)
@@ -58,67 +57,27 @@ export default class EndpointPopup extends React.Component<Props, State> {
5857
const { valid } = this.state
5958
return (
6059
<Popup onRequestClose={this.close} darkBg={true}>
61-
<div className="content">
62-
<style jsx={true}>{`
63-
.content {
64-
@p: .bbox;
65-
}
66-
form {
67-
@p: .flex, .flexAuto, .w100;
68-
}
69-
input {
70-
@p: .bgWhite10, .br2, .pv16, .ph25, .fw6, .white, .f16, .db, .w100,
71-
.tc, .flexAuto, .flex;
72-
transition: 0.25s color;
73-
}
74-
input.valid {
75-
@p: .green;
76-
}
77-
input.invalid {
78-
@p: .red;
79-
}
80-
.content :global(.button) {
81-
@p: .ph16;
82-
background: #da1b7f;
83-
}
84-
.content :global(.button:hover) {
85-
@p: .ph16, .bgPurple;
86-
}
87-
h1 {
88-
@p: .white80, .fw4, .ml38;
89-
}
90-
.logo-wrapper {
91-
@p: .flex, .justifyCenter, .itemsCenter;
92-
}
93-
.logo {
94-
@p: .flex, .itemsCenter, .mb60, .justifyBetween;
95-
}
96-
.logo img {
97-
width: 78px;
98-
height: 78px;
99-
}
100-
`}</style>
101-
<div className="logo-wrapper">
102-
<div className="logo">
60+
<Wrapper>
61+
<LogoWrapper>
62+
<Logo>
10363
<img src={require('../assets/logo.png')} alt="" />
104-
<h1>GraphQL Playground</h1>
105-
</div>
106-
</div>
107-
<form action="" onSubmit={this.submit}>
108-
<input
64+
<Heading>GraphQL Playground</Heading>
65+
</Logo>
66+
</LogoWrapper>
67+
<Form action="" onSubmit={this.submit}>
68+
<Input
10969
type="text"
11070
placeholder="Enter an endpoint url..."
11171
value={this.state.endpoint}
11272
onChange={this.onChangeEndpoint}
113-
className={cn({
114-
valid: typeof valid === 'boolean' && valid,
115-
invalid: typeof valid === 'boolean' && !valid,
116-
})}
73+
valid={typeof valid === 'boolean' && valid}
74+
invalid={typeof valid === 'boolean' && !valid}
11775
autoFocus={true}
11876
/>
77+
11978
{valid && <Button onClick={this.close}>Use Endpoint</Button>}
120-
</form>
121-
</div>
79+
</Form>
80+
</Wrapper>
12281
</Popup>
12382
)
12483
}
@@ -138,3 +97,79 @@ export default class EndpointPopup extends React.Component<Props, State> {
13897
}
13998
}
14099
}
100+
101+
const Wrapper = styled.div`
102+
box-sizing: border-box;
103+
`
104+
105+
const Form = styled.form`
106+
width: 100%;
107+
display: flex;
108+
flex: 1 1 auto;
109+
110+
.button.button {
111+
padding-right: ${p => p.theme.sizes.small16};
112+
padding-left: ${p => p.theme.sizes.small16};
113+
background: #da1b7f;
114+
115+
&:hover {
116+
background: ${p => p.theme.colours.purple};
117+
}
118+
}
119+
`
120+
121+
interface InputProps {
122+
valid: boolean
123+
invalid: boolean
124+
}
125+
126+
// prettier-ignore
127+
const Input = withProps<InputProps>()(styled.input)`
128+
background: ${p => p.theme.colours.white10};
129+
border-radius: ${p => p.theme.sizes.smallRadius};
130+
padding: ${p => p.theme.sizes.small16} ${p => p.theme.sizes.medium25};
131+
font-weight: ${p => p.theme.sizes.fontSemiBold};
132+
color: white;
133+
font-size: 16px;
134+
display: block;
135+
width: 100%;
136+
text-align: center;
137+
flex: 1 1 auto;
138+
display: flex;
139+
140+
transition: 250ms color;
141+
142+
${(p: any) =>
143+
p.valid ? css`
144+
color: ${k => k.theme.colours.green};
145+
`
146+
: p.invalid ? css`
147+
color: ${k => k.theme.colours.red};
148+
`
149+
: ``
150+
}
151+
`
152+
153+
const Heading = styled.h1`
154+
margin-left: 38px;
155+
font-weight: 400;
156+
color: ${p => p.theme.colours.white80};
157+
`
158+
159+
const LogoWrapper = styled.div`
160+
display: flex;
161+
justify-content: center;
162+
align-items: center;
163+
`
164+
165+
const Logo = styled.div`
166+
display: flex;
167+
justify-content: space-between;
168+
align-items: center;
169+
margin-bottom: 60px;
170+
171+
img {
172+
width: 78px;
173+
height: 78px;
174+
}
175+
`

packages/graphql-playground-react/src/styled/theme.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface Colours {
99
darkBlue10: string
1010
darkerBlue: string
1111
darkestBlue: string
12+
white80: string
1213
white70: string
1314
white60: string
1415
white30: string
@@ -19,6 +20,7 @@ export interface Colours {
1920
paleText: string
2021
paleGrey: string
2122
red: string
23+
purple: string
2224
}
2325

2426
export const colours: Colours = {
@@ -37,9 +39,11 @@ export const colours: Colours = {
3739
white30: 'rgba(255, 255, 255, 0.3)',
3840
white60: 'rgba(255, 255, 255, 0.6)',
3941
white70: 'rgba(255, 255, 255, 0.7)',
42+
white80: 'rgba(255, 255, 255, 0.8)',
4043
white: 'rgba(255, 255, 255, 1)',
4144
black40: 'rgba(0, 0, 0, 0.4)',
4245
red: '#f25c54',
46+
purple: 'rgb(164, 3, 111)',
4347

4448
paleText: 'rgba(0, 0, 0, 0.5)',
4549
paleGrey: '#f3f4f4', // use for bgs, borders, etc
@@ -64,7 +68,6 @@ export const sizes: Sizes = {
6468
small10: '10px',
6569
small12: '12px',
6670
small16: '16px',
67-
6871
medium25: '25px',
6972

7073
// font weights

0 commit comments

Comments
 (0)