Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
})
}
const getMenuItemById = useCallback(
function (id) {
for (const menuItem of menuItems) {
if (menuItem.__id === id) {
return menuItem
}
}
return null
},
[menuItems]
)
const computeNextId = useCallback(
function (id) {
if (id === INVALID_ID) {
return menuItems[0].__id
}
let foundCurrentMenuItem = false
let index = -1
while (index++ < menuItems.length - 1) {
if (typeof menuItems[index].value !== 'undefined') {
if (foundCurrentMenuItem === true) {
// We've found the item after the current menu item with a `.value`
break
}
if (menuItems[index].__id === id) {
foundCurrentMenuItem = true
}
}
const [ltiLaunchState, setLtiLaunchState] = useState({
...INITIAL_LTI_LAUNCH_STATE,
state: viaUrlCallback ? 'fetching-url' : 'fetched-url',
contentUrl: viaUrl ? viaUrl : null,
});
// Value for the key="" prop to rebuild the sidebar when it needs re-rendering
const [sidebarKey, setSidebarKey] = useState('');
/**
* Fetch the URL of the content to display in the iframe.
*
* This will typically be a PDF URL proxied through Via.
*/
const fetchContentUrl = useCallback(async () => {
if (!viaUrlCallback) {
// If no "callback" URL was supplied for the frontend to use to fetch
// the URL, then the backend must have provided the Via URL in the
// initial request, which we'll just use directly.
return;
}
try {
setLtiLaunchState({
...INITIAL_LTI_LAUNCH_STATE,
state: 'fetching-url',
});
const { via_url: contentUrl } = await apiCall({
authToken,
path: viaUrlCallback,
});
// (in case it is currently "auto"), force a synchronous layout,
// then transition to 0.
//
// These steps are needed because browsers will not animate transitions
// from "auto" => "0" and may not animate "auto" => fixed height => 0
// if the layout tree transitions directly from "auto" => 0.
el.style.height = `${el.scrollHeight}px`;
// Force a sync layout.
el.getBoundingClientRect();
setContainerHeight(0);
}
}, [containerHeight, visible]);
const handleTransitionEnd = useCallback(() => {
if (visible) {
setContainerHeight('auto');
} else {
// When the collapse animation completes, stop rendering the content so
// that the browser has fewer nodes to render and the content is removed
// from keyboard navigation.
setContentVisible(false);
}
}, [setContainerHeight, visible]);
return (
export function Header() {
// TODO: Consider using ontransitionend to improve height transition
const url = location.pathname;
const [open, setOpen] = useOverlayToggle();
const toggle = useCallback(() => setOpen(!open), [open]);
return (
<header open="" class="{cx({">
<div class="{style.inner}">
<nav class="{style.nav}">
<div class="{style.social}">
<a href="https://github.com/preactjs/preact" aria-label="Browse the code on GitHub" class="{style.socialItem}">
<img width="26" alt="GitHub" src="{githubIcon}">
</a>
</div></nav></div></header>
overflowThreshold = 0,
settings = {},
}) {
const [collapsedByInlineControls, setCollapsedByInlineControls] = useState(
true
);
// Container for the excerpt's content.
const contentElement = useRef(null);
// Measured height of `contentElement` in pixels.
const [contentHeight, setContentHeight] = useState(0);
// Update the measured height of the content after the initial render and
// when the size of the content element changes.
const updateContentHeight = useCallback(() => {
const newContentHeight = contentElement.current.clientHeight;
setContentHeight(newContentHeight);
// prettier-ignore
const isCollapsible =
newContentHeight > (collapsedHeight + overflowThreshold);
onCollapsibleChanged({ collapsible: isCollapsible });
}, [collapsedHeight, onCollapsibleChanged, overflowThreshold]);
useLayoutEffect(() => {
const cleanup = observeElementSize(
contentElement.current,
updateContentHeight
);
updateContentHeight();
return cleanup;
export function useForm (
initialState,
{ transform, validate, onClose, onSubmit }
) {
const [state, setState] = useState(
typeof transform === 'function' ? transform(initialState) : initialState
)
const handleSubmit = useCallback(
function (event) {
if (typeof event !== 'undefined') {
event.preventDefault()
}
if (typeof validate !== 'function' || validate(state) === true) {
onSubmit(state)
}
},
[state, onSubmit, validate]
)
const handleChange = useCallback(
function (nextState) {
setState(function (previousState) {
const state = {
...previousState,
...nextState
name,
onChange,
options,
propagateEscapeKeyDown = true,
value,
...rest
}) {
const handleChange = useCallback(
function (event) {
const index = parseInt(event.target.getAttribute('data-index'))
onChange({ [name]: options[index].value })
},
[name, onChange, options]
)
const handleKeyDown = useCallback(
function (event) {
const keyCode = event.keyCode
if (keyCode === ESCAPE_KEY_CODE) {
if (propagateEscapeKeyDown === false) {
event.stopPropagation()
}
event.target.blur()
return
}
if (
keyCode === DOWN_KEY_CODE ||
keyCode === LEFT_KEY_CODE ||
keyCode === RIGHT_KEY_CODE ||
keyCode === UP_KEY_CODE
) {
if (value === null) {
export const Router: FunctionalComponent = props => {
const [path, setPath] = useState(location.pathname)
const update = useCallback(() => {
setPath(location.pathname)
}, [setPath])
useLocation(update)
const navigate = useCallback(
(path: string) => {
history.pushState(null, "", path)
update()
},
[update],
)
const router = useMemo(
() => ({
match: [],
if (ref.current) {
ref.current.setCustomValidity(valid ? "" : "Invalid input");
}
}, [ref.current, valid]);
const onKeyUp = useCallback((e: KeyboardEvent) => {
if (e.key === "Enter") {
store.onConfirm();
} else if (e.key === "ArrowUp") {
store.onIncrement();
} else if (e.key === "ArrowDown") {
store.onDecrement();
}
}, []);
const onInput = useCallback((e: Event) => {
store.onInput((e.target as any).value);
}, []);
return (
<div class="{s.valueWrapper}">
{store.asCheckbox.$ && !focus && (
<input checked="{store.actualValue.$" type="checkbox" class="{s.check}"> {
const value = "" + (e.target as any).checked;
value$.$ = parseValue(value);
onChange(value$.$);
}}
/></div>
export function useMenu ({
getSelectedItemElement,
onChange,
items,
selectedItem
}) {
const handleKeyDown = useCallback(
function (event) {
if (event.keyCode === UP_KEY_CODE || event.keyCode === DOWN_KEY_CODE) {
event.preventDefault()
if (selectedItem === null) {
if (event.keyCode === UP_KEY_CODE) {
onChange(items[items.length - 1])
return
}
onChange(items[0])
return
}
const currentIndex = items.findIndex(function (item) {
return item === selectedItem
})
let nextIndex = currentIndex + (event.keyCode === UP_KEY_CODE ? -1 : 1)
if (nextIndex === -1) {