react#FocusEventHandler TypeScript Examples
The following examples show how to use
react#FocusEventHandler.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useSlate.ts From ui-schema with MIT License | 7 votes |
useSlate = (schema: WidgetProps['schema'], value: SlateImmutableType | undefined) => {
const [focused, setFocus] = React.useState(false)
const onBlur: FocusEventHandler = React.useCallback(() => {
setFocus(false)
}, [setFocus])
const onFocus: FocusEventHandler = React.useCallback(() => {
setFocus(true)
}, [setFocus])
const dense = schema.getIn(['view', 'dense'])
const empty = isSlateEmpty(value)
return {
focused, setFocus,
onFocus, onBlur,
dense, empty,
}
}
Example #2
Source File: aria.ts From pybricks-code with MIT License | 5 votes |
/**
* React hook for creating toolbar item element props for focus management.
*
* Using this hook requires the current element to be inside of an
* {@link ToolbarStateContext} and to be inside of a {@link FocusScope}.
*/
export function useToolbarItemFocus(props: { id: string }): ToolbarItemFocusAria {
const { id } = props;
const state = useContext(ToolbarStateContext);
const focusManager = useFocusManager();
const onKeyDown = useCallback<KeyboardEventHandler<HTMLElement>>(
(e) => {
switch (e.key) {
case 'ArrowLeft':
focusManager.focusPrevious({ wrap: true });
break;
case 'ArrowRight':
focusManager.focusNext({ wrap: true });
break;
case 'Home':
focusManager.focusFirst();
break;
case 'End':
focusManager.focusLast();
break;
default:
return;
}
},
[focusManager],
);
const onFocus = useCallback<FocusEventHandler<HTMLElement>>(
(e) => {
state.setLastFocusedItem(e.target.id);
},
[state.setLastFocusedItem],
);
const excludeFromTabOrder = id !== state.lastFocusedItem;
return { toolbarItemFocusProps: { onKeyDown, onFocus }, excludeFromTabOrder };
}
Example #3
Source File: App.tsx From pybricks-code with MIT License | 4 votes |
App: React.VFC = () => {
const { isDarkMode } = useTernaryDarkMode();
const { isSettingShowDocsEnabled } = useSettingIsShowDocsEnabled();
const [isDragging, setIsDragging] = useState(false);
const [docsSplit, setDocsSplit] = useLocalStorage('app-docs-split', 30);
const [terminalSplit, setTerminalSplit] = useLocalStorage('app-terminal-split', 30);
// Classes.DARK has to be applied to body element, otherwise it won't
// affect portals
useEffect(() => {
if (!isDarkMode) {
// no class for light mode, so nothing to do
return;
}
document.body.classList.add(Classes.DARK);
return () => document.body.classList.remove(Classes.DARK);
}, [isDarkMode]);
useEffect(() => {
const listener = (e: KeyboardEvent) => {
// prevent default browser keyboard shortcuts that we use
// NB: some of these like 'n' and 'w' cannot be prevented when
// running "in the browser"
if (e.ctrlKey && ['d', 'n', 's', 'w'].includes(e.key)) {
e.preventDefault();
}
};
addEventListener('keydown', listener);
return () => removeEventListener('keydown', listener);
}, []);
// keep track of last focused element in the activities area and restore
// focus to that element if any non-interactive area is clicked
const [lastActivitiesFocusChild, setLastActivitiesFocusChild] =
useState<HTMLElement | null>(null);
const handleFocus = useCallback<FocusEventHandler>(
(e) => {
if (e.target instanceof HTMLElement) {
setLastActivitiesFocusChild(e.target);
}
},
[setLastActivitiesFocusChild],
);
const handleActivitiesMouseDown = useCallback<MouseEventHandler<HTMLDivElement>>(
(e) => {
if (
lastActivitiesFocusChild &&
e.currentTarget.contains(lastActivitiesFocusChild)
) {
// if the last focused child exists and it is still inside of
// the activities area, focus it
lastActivitiesFocusChild.focus();
} else {
// otherwise, focus the first focusable element
const walker = getFocusableTreeWalker(e.currentTarget);
const first = walker.nextNode();
if (first instanceof HTMLElement) {
first.focus();
}
}
// prevent document body from getting focus
e.stopPropagation();
e.preventDefault();
},
[lastActivitiesFocusChild],
);
return (
<div className="pb-app" onContextMenu={(e) => e.preventDefault()}>
<div className="pb-app-body">
<div
className="pb-app-activities"
onFocus={handleFocus}
onMouseDown={handleActivitiesMouseDown}
>
<Activities />
</div>
{/* need a container with position: relative; for SplitterLayout since it uses position: absolute; */}
<div className="pb-app-main" style={{ position: 'relative' }}>
<SplitterLayout
customClassName={
isSettingShowDocsEnabled ? 'pb-show-docs' : 'pb-hide-docs'
}
onDragStart={(): void => setIsDragging(true)}
onDragEnd={(): void => setIsDragging(false)}
percentage={true}
secondaryInitialSize={docsSplit}
onSecondaryPaneSizeChange={setDocsSplit}
>
<SplitterLayout
vertical={true}
percentage={true}
secondaryInitialSize={terminalSplit}
onSecondaryPaneSizeChange={setTerminalSplit}
>
<div className="pb-app-editor">
<Toolbar />
<Editor />
</div>
<div className="pb-app-terminal">
<Terminal />
</div>
</SplitterLayout>
<div className="pb-app-docs">
{isDragging && <div className="pb-app-docs-drag-helper" />}
<Docs />
</div>
</SplitterLayout>
</div>
</div>
<StatusBar />
</div>
);
}
Example #4
Source File: SlateRenderer.tsx From ui-schema with MIT License | 4 votes |
SlateRenderer: React.ComponentType<SlateRendererProps & WidgetProps & WithValue & {
ElementMapper: ElementMapperType
onFocus: FocusEventHandler
onBlur: FocusEventHandler
className?: string
onlyInline?: boolean
withPlugins: withPluginsType
plugins: EditablePluginsProps['plugins']
renderLeaf?: RenderLeaf[]
}> = (
{
value,
internalValue,
onChange,
storeKeys,
required,
schema,
onFocus,
onBlur,
ElementMapper,
className,
onlyInline = false,
plugins,
renderLeaf,
}
) => {
const enableOnly = schema.getIn(['editor', 'enableOnly']) as editorEnableOnly
const renderElements = React.useMemo(() => {
return [
({children, ...props}: RenderElementProps): JSX.Element =>
<ElementMapper {...props} enableOnly={enableOnly}>
{children}
</ElementMapper>,
]
}, [enableOnly])
const valueRef = React.useRef(value)
const handledInitial = React.useRef(false)
const valueIsSameOrInitialised = handledInitial.current && valueRef.current?.equals(value)
React.useEffect(() => {
if (!valueIsSameOrInitialised) {
const handledInitialTemp = handledInitial.current
handledInitial.current = true
onChange({
storeKeys,
scopes: ['internal', 'value'],
type: 'update',
updater: ({internal: currentInternal = Map(), value: storeValue}) => {
if (storeValue && storeValue.size) {
// handling setting internal value for keyword `default`
// must check for really non empty, e.g. when used in root level `value` and `internal` will be an empty list
valueRef.current = storeValue
} else {
valueRef.current = !handledInitialTemp && schema.get('default') ? schema.get('default') as List<any> : List()
}
if (valueRef.current.size) {
currentInternal = currentInternal.set('value', valueRef.current.toJS())
} else {
const initial = [...initialValue]
initial[0] = {...initial[0]}
if (schema.getIn(['editor', 'initialRoot'])) {
initial[0].type = schema.getIn(['editor', 'initialRoot']) as string
} else if (onlyInline) {
initial[0].type = 'span'
}
currentInternal = currentInternal.set('value', initial)
}
return {
internal: currentInternal,
value: valueRef.current,
}
},
schema,
required,
})
}
}, [valueIsSameOrInitialised, handledInitial, valueRef, schema, required, onChange, onlyInline, storeKeys])
// @ts-ignore
const editor: ReactEditor = React.useMemo(
() => pipe(createEditor() as ReactEditor, withReact, withHistory, ...withPlugins({enableOnly, onlyInline})),
[withPlugins, enableOnly, onlyInline]
)
const onChangeHandler = React.useCallback((editorValue) => {
onChange({
storeKeys,
scopes: ['value', 'internal'],
type: 'update',
updater: ({internal: currentInternal = Map()}) => {
let newValue = fromJS(editorValue) as List<any>
if (isSlateEmpty(newValue)) {
newValue = List()
}
valueRef.current = newValue
return {
value: newValue,
internal: currentInternal.set('value', editorValue),
}
},
schema,
required,
})
}, [valueRef, onChange, storeKeys, schema, required])
return internalValue.get('value') ? <Slate editor={editor} value={internalValue.get('value') || initialValue} onChange={onChangeHandler}>
{!schema.getIn(['editor', 'hideToolbar']) ?
<SlateToolbarHead
enableOnly={enableOnly}
onlyInline={onlyInline}
onFocus={onFocus}
onBlur={onBlur}
/> : null}
{!schema.getIn(['editor', 'hideBalloon']) ?
<SlateToolbarBalloon
enableOnly={enableOnly}
/> : null}
<Editable
renderElement={renderElements}
renderLeaf={renderLeaf}
plugins={plugins}
onFocus={onFocus}
onBlur={onBlur}
placeholder={schema.getIn(['editor', 'placeholder']) as string | undefined}
spellCheck={schema.getIn(['editor', 'spellCheck']) as boolean}
autoFocus={schema.getIn(['editor', 'autoFocus']) as boolean}
className={className}
/>
</Slate> : null
}
Example #5
Source File: SlateToolbarHead.tsx From ui-schema with MIT License | 4 votes |
SlateToolbarHead: React.ComponentType<{
enableOnly?: editorEnableOnly
onlyInline?: boolean
onFocus: FocusEventHandler
onBlur: FocusEventHandler
}> = (
{
enableOnly,
onlyInline,
onBlur,
onFocus,
}
) => {
return <HeadingToolbar>
{!onlyInline && editorIsEnabled(enableOnly, pluginOptions.ul.type) &&
<ToolbarList
{...pluginOptions}
type={pluginOptions.ul.type}
icon={<IcListBulleted/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{!onlyInline && editorIsEnabled(enableOnly, pluginOptions.ol.type) &&
<ToolbarList
{...pluginOptions}
type={pluginOptions.ol.type}
icon={<IcListNumbered/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{!onlyInline && editorIsEnabled(enableOnly, pluginOptions.todo_li.type) &&
<ToolbarElement
type={pluginOptions.todo_li.type}
icon={<IcListTodo/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{!onlyInline && editorIsEnabled(enableOnly, pluginOptions.blockquote.type) &&
<ToolbarElement
type={pluginOptions.blockquote.type}
icon={<IcQuote/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{!onlyInline && editorIsEnabled(enableOnly, pluginOptions.code_block.type) &&
<ToolbarCodeBlock
type={pluginOptions.code_block.type}
icon={<IcCode/>}
options={pluginOptions}
onFocus={onFocus}
onBlur={onBlur}
/>}
{editorIsEnabled(enableOnly, pluginOptions.align_center.type) ||
editorIsEnabled(enableOnly, pluginOptions.align_right.type) ||
editorIsEnabled(enableOnly, pluginOptions.align_justify.type) ?
<ToolbarAlign
icon={<IcAlignLeft/>}
type={''}
onFocus={onFocus}
onBlur={onBlur}
/> : null}
{editorIsEnabled(enableOnly, pluginOptions.align_center.type) &&
<ToolbarAlign
type={pluginOptions.align_center.type}
icon={<IcAlignCenter/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{editorIsEnabled(enableOnly, pluginOptions.align_right.type) &&
<ToolbarAlign
type={pluginOptions.align_right.type}
icon={<IcAlignRight/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
{editorIsEnabled(enableOnly, pluginOptions.align_justify.type) &&
<ToolbarAlign
type={pluginOptions.align_justify.type}
icon={<IcAlignJustify/>}
onFocus={onFocus}
onBlur={onBlur}
/>}
</HeadingToolbar>
}