Skip to content

Commit

Permalink
Use common SearchBox
Browse files Browse the repository at this point in the history
  • Loading branch information
ryyppy committed Dec 30, 2020
1 parent faf0f9a commit 61cb9e7
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 393 deletions.
112 changes: 112 additions & 0 deletions components/SearchBox.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions components/SearchBox.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* This SearchBox is used for fuzzy-find search scenarios, such as the syntax widget tool or
* the package index
*/

@bs.send external focus: Dom.element => unit = "focus"

type state =
| Active
| Inactive

@react.component
let make = (
~completionValues: array<string>=[], // set of possible values
~value: string,
~onClear: unit => unit,
~placeholder: string="",
~onValueChange: string => unit,
) => {
let (state, setState) = React.useState(_ => Inactive)
let textInput = React.useRef(Js.Nullable.null)

let onMouseDownClear = evt => {
ReactEvent.Mouse.preventDefault(evt)
onClear()
}

let focusInput = () =>
textInput.current->Js.Nullable.toOption->Belt.Option.forEach(el => el->focus)

let onAreaFocus = evt => {
let el = ReactEvent.Focus.target(evt)
let isDiv = Js.Null_undefined.isNullable(el["type"])

if isDiv && state === Inactive {
focusInput()
}
}

let onFocus = _ => {
setState(_ => Active)
}

let onBlur = _ => {
setState(_ => Inactive)
}

let onKeyDown = evt => {
let key = ReactEvent.Keyboard.key(evt)
let ctrlKey = ReactEvent.Keyboard.ctrlKey(evt)

let full = (ctrlKey ? "CTRL+" : "") ++ key

switch full {
| "Escape" => onClear()
| "Tab" =>
if Js.Array.length(completionValues) === 1 {
let targetValue = Belt.Array.getExn(completionValues, 0)

if targetValue !== value {
ReactEvent.Keyboard.preventDefault(evt)
onValueChange(targetValue)
} else {
()
}
}
| _ => ()
}
}

let onChange = evt => {
ReactEvent.Form.preventDefault(evt)
let value = ReactEvent.Form.target(evt)["value"]
onValueChange(value)
}

<div
tabIndex={-1}
onFocus=onAreaFocus
onBlur
className={(
state === Active ? "border-fire" : "border-fire-40"
) ++ " flex items-center border rounded-lg py-4 px-5"}>
<Icon.MagnifierGlass
className={(state === Active ? "text-fire" : "text-fire-80") ++ " w-4 h-4"}
/>
<input
value
ref={ReactDOM.Ref.domRef(textInput)}
onFocus
onKeyDown
onChange={onChange}
placeholder
className="text-16 outline-none ml-4 w-full"
type_="text"
/>
<button onFocus className={value === "" ? "hidden" : "block"} onMouseDown=onMouseDownClear>
<Icon.Close className="w-4 h-4 text-fire" />
</button>
</div>
}
99 changes: 3 additions & 96 deletions components/SyntaxLookupWidget.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 61cb9e7

Please sign in to comment.