Skip to content

Commit 9ebf079

Browse files
cleaning up react hooks and moving banner out
1 parent b4220c4 commit 9ebf079

11 files changed

Lines changed: 855 additions & 523 deletions

File tree

playground/internal/page/banner.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package page
2+
3+
import (
4+
"github.com/gopherjs/gopherjs.github.io/playground/internal/react"
5+
"github.com/gopherjs/gopherjs/compiler"
6+
"github.com/gopherjs/gopherjs/js"
7+
)
8+
9+
func Banner(runButtonRef react.Ref, urlHash string, onRun, onFormat, onShare, onSnippetSelected react.Func) *react.Element {
10+
return react.CreateElement(bannerComponent, react.Props{
11+
`runButtonRef`: runButtonRef,
12+
`onRun`: onRun,
13+
`onFormat`: onFormat,
14+
`urlHash`: urlHash,
15+
`onShare`: onShare,
16+
`onSnippetSelected`: onSnippetSelected,
17+
})
18+
}
19+
20+
func bannerComponent(props react.Props) *react.Element {
21+
var (
22+
runButtonRef = props.GetRef(`runButtonRef`)
23+
onRun = props.GetFunc(`onRun`)
24+
onFormat = props.GetFunc(`onFormat`)
25+
urlHash = props.GetString(`urlHash`)
26+
onShare = props.GetFunc(`onShare`)
27+
onSnippetSelected = props.GetFunc(`onSnippetSelected`)
28+
lightTheme, setLightTheme = react.UseStateLazy(getDefaultToLightTheme)
29+
fmtImports, setFmtImports = react.UseState(true)
30+
)
31+
32+
react.UseEffect(func() {
33+
setDataTheme(lightTheme)
34+
}, []any{lightTheme})
35+
36+
onFormatClick := react.UseCallback(func() {
37+
onFormat.Invoke(fmtImports)
38+
}, []any{fmtImports})
39+
40+
return react.Div(react.Props{
41+
`id`: `banner`,
42+
},
43+
BannerTitle(compiler.Version),
44+
react.Span(react.Props{
45+
`id`: `controls`,
46+
},
47+
react.Button(`run-button`, `Run`, react.Props{`ref`: runButtonRef}, onRun),
48+
react.Button(`format-button`, `Format`, nil, onFormatClick),
49+
ToggleBox(`format-imports`, `Rewrite imports on Format`, `Imports`, fmtImports, setFmtImports),
50+
ShareUrlControl(urlHash, onShare, onSnippetSelected),
51+
ToggleBox(`color-theme`, `Change color-theme`, ``, lightTheme, setLightTheme),
52+
),
53+
)
54+
}
55+
56+
func getDefaultToLightTheme() bool {
57+
return js.Global.Get(`window`).Call(`matchMedia`, `(prefers-color-scheme: light)`).Get(`matches`).Bool()
58+
}
59+
60+
func setDataTheme(lightTheme bool) {
61+
theme := `dark`
62+
if lightTheme {
63+
theme = `light`
64+
}
65+
js.Global.Get(`document`).Get(`documentElement`).Call(`setAttribute`, `data-theme`, theme)
66+
}

playground/internal/page/codeBox.go

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/gopherjs/gopherjs.github.io/playground/internal/react"
1212
)
1313

14-
func CodeBox(code string, setCode react.Setter, onSave react.Setter, onEscape react.Setter) *react.Element {
14+
func CodeBox(code string, setCode, onSave, onEscape react.Func) *react.Element {
1515
return react.CreateElement(codeBoxComponent, react.Props{
1616
`curCode`: code,
1717
`setCode`: setCode,
@@ -34,7 +34,7 @@ func codeBoxComponent(props react.Props) *react.Element {
3434
newCode := e.Get(`target`).Get(`value`).String()
3535
sel := getSelection(textAreaRef)
3636
globals.UndoRedo().RecordCodeChange(sel, curCode, newCode)
37-
setCode(newCode)
37+
setCode.Invoke(newCode)
3838
}, []any{curCode, setCode, textAreaRef})
3939

4040
onKeyDown := react.UseCallback(func(e *js.Object) {
@@ -80,29 +80,33 @@ func codeBoxComponent(props react.Props) *react.Element {
8080
}, []any{lineCount})
8181

8282
return react.Div(react.Props{
83-
`id`: `code-box`,
83+
`id`: `code-box-container`,
8484
},
85-
react.TextArea(react.Props{
86-
`id`: `line-nums`,
87-
`ref`: lineNumsRef,
88-
`value`: lineNumbers,
89-
`readOnly`: true,
90-
`disable`: `true`,
91-
}),
92-
react.TextArea(react.Props{
93-
`id`: `code`,
94-
`ref`: textAreaRef,
95-
`value`: curCode,
96-
`onInput`: onInput,
97-
`onKeyDown`: onKeyDown,
98-
`onScroll`: onScroll,
99-
`onSelect`: onSelect,
100-
`autoFocus`: true,
101-
`autoCorrect`: `off`,
102-
`autoComplete`: `off`,
103-
`autoCapitalize`: `off`,
104-
`spellCheck`: false,
105-
}),
85+
react.Div(react.Props{
86+
`id`: `code-box`,
87+
},
88+
react.TextArea(react.Props{
89+
`id`: `line-nums`,
90+
`ref`: lineNumsRef,
91+
`value`: lineNumbers,
92+
`readOnly`: true,
93+
`disable`: `true`,
94+
}),
95+
react.TextArea(react.Props{
96+
`id`: `code`,
97+
`ref`: textAreaRef,
98+
`value`: curCode,
99+
`onInput`: onInput,
100+
`onKeyDown`: onKeyDown,
101+
`onScroll`: onScroll,
102+
`onSelect`: onSelect,
103+
`autoFocus`: true,
104+
`autoCorrect`: `off`,
105+
`autoComplete`: `off`,
106+
`autoCapitalize`: `off`,
107+
`spellCheck`: false,
108+
}),
109+
),
106110
)
107111
}
108112

@@ -111,7 +115,7 @@ type codeBoxAssistant struct {
111115
setCode react.Func
112116
onSave react.Func
113117
onEscape react.Func
114-
textAreaRef *react.Ref
118+
textAreaRef react.Ref
115119
}
116120

117121
var _ common.CodeBoxWrapper = (*codeBoxAssistant)(nil)
@@ -121,9 +125,9 @@ func (cba *codeBoxAssistant) Code() string { return cba.curCode }
121125
func (cba *codeBoxAssistant) EmitEvent(event common.Event) {
122126
switch event {
123127
case common.SaveEvent:
124-
cba.onSave()
128+
cba.onSave.Invoke()
125129
case common.EscapeEvent:
126-
cba.onEscape()
130+
cba.onEscape.Invoke()
127131
case common.UndoEvent:
128132
globals.UndoRedo().PerformUndo(cba)
129133
case common.RedoEvent:
@@ -148,7 +152,7 @@ func (cba *codeBoxAssistant) SetCode(sel common.Selection, code string) {
148152
globals.UndoRedo().AddBreak()
149153

150154
// Update the code state for react.
151-
cba.setCode(code)
155+
cba.setCode.Invoke(code)
152156

153157
// Pre-update the textarea value so that the caret and scroll can be set
154158
// correctly before the next render so that the next render doesn't reset them.
@@ -167,7 +171,7 @@ func (cba *codeBoxAssistant) SetCode(sel common.Selection, code string) {
167171
horizontallyAutoScroll(cba.textAreaRef, sel.End, code)
168172
}
169173

170-
func verticallyAutoScroll(textAreaRef *react.Ref, caret int, code string) {
174+
func verticallyAutoScroll(textAreaRef react.Ref, caret int, code string) {
171175
textArea := textAreaRef.Current()
172176
totalHeight := textArea.Get(`scrollHeight`).Int()
173177
visibleHeight := textArea.Get(`clientHeight`).Int()
@@ -187,7 +191,7 @@ func verticallyAutoScroll(textAreaRef *react.Ref, caret int, code string) {
187191
}
188192
}
189193

190-
func horizontallyAutoScroll(textAreaRef *react.Ref, caret int, code string) {
194+
func horizontallyAutoScroll(textAreaRef react.Ref, caret int, code string) {
191195
textArea := textAreaRef.Current()
192196
totalWidth := textArea.Get(`scrollWidth`).Int()
193197
visibleWidth := textArea.Get(`clientWidth`).Int()
@@ -208,15 +212,15 @@ func horizontallyAutoScroll(textAreaRef *react.Ref, caret int, code string) {
208212
}
209213
}
210214

211-
func getSelection(textAreaRef *react.Ref) common.Selection {
215+
func getSelection(textAreaRef react.Ref) common.Selection {
212216
textArea := textAreaRef.Current()
213217
start := textArea.Get(`selectionStart`).Int()
214218
end := textArea.Get(`selectionEnd`).Int()
215219
return common.Selection{Start: start, End: end}
216220
}
217221

218222
// setSelection sets the selection on the given textarea ref.
219-
func setSelection(textAreaRef *react.Ref, sel common.Selection) {
223+
func setSelection(textAreaRef react.Ref, sel common.Selection) {
220224
textArea := textAreaRef.Current()
221225
textArea.Set(`selectionStart`, sel.Start)
222226
textArea.Set(`selectionEnd`, sel.End)

playground/internal/page/dropDown.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"github.com/gopherjs/gopherjs.github.io/playground/internal/react"
99
)
1010

11-
func DropDown(id, className string, items []any, selected any, onSelect react.Setter) *react.Element {
11+
func DropDown(id, className string, items []any, selected any, onSelect react.Func) *react.Element {
1212
return react.CreateElement(dropDownComponent, react.Props{
1313
`id`: id,
1414
`className`: className,
@@ -28,15 +28,17 @@ func dropDownComponent(props react.Props) *react.Element {
2828
)
2929

3030
onChange := react.UseCallback(func(e *js.Object) {
31-
onSelect(e.Get(`target`).Get(`value`).String())
31+
selected := e.Get(`target`).Get(`value`).String()
32+
onSelect.Invoke(selected)
3233
}, []any{onSelect})
3334

3435
options := make([]react.Node, len(items))
3536
for i, item := range items {
37+
value := item.(string)
3638
options[i] = react.CreateElement(`option`, react.Props{
37-
`key`: fmt.Sprintf("%s-%v", id, item),
38-
`value`: item,
39-
}, item)
39+
`key`: fmt.Sprintf("%s-%v", id, value),
40+
`value`: value,
41+
}, value)
4042
}
4143

4244
return react.CreateElement(`select`, react.Props{

playground/internal/page/outputBox.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ const (
1515
contextKey = `context`
1616
)
1717

18-
func Output(setOutput react.Setter) common.Output {
18+
func Output(setOutput react.Func) common.Output {
1919
return &outputImpl{setOutput: setOutput}
2020
}
2121

22-
type outputImpl struct{ setOutput react.Setter }
22+
type outputImpl struct{ setOutput react.Func }
2323

2424
func (o *outputImpl) Clear() {
2525
o.setOutput.Invoke([]any{})

0 commit comments

Comments
 (0)