How to use the preact/hooks.useLayoutEffect function in preact

To help you get started, we’ve selected a few preact examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github lydell / LinkHints / src / options / TextInput.js View on Github external
const element = rootRef.current;
    if (element != null) {
      selectionStartRef.current = element.selectionStart;
      selectionEndRef.current = element.selectionEnd;
    }
  }

  function restoreSelection() {
    const element = rootRef.current;
    if (element != null) {
      element.selectionStart = selectionStartRef.current;
      element.selectionEnd = selectionEndRef.current;
    }
  }

  useLayoutEffect(
    () =>
      // Move the default cursor position from the end of the textarea to the start.
      textarea ? restoreSelection() : undefined,
    [textarea]
  );

  useLayoutEffect(() => {
    // When readonly textareas change, move the cursor back to the start.
    if (textarea && readonly) {
      selectionStartRef.current = 0;
      selectionEndRef.current = 0;
      return timeout(0, restoreSelection);
    }
    return undefined;
  }, [textarea, readonly, savedValue]);
github yuanqing / create-figma-plugin / packages / ui / src / components / textbox / textbox-autocomplete / textbox-autocomplete.js View on Github external
})
      if (selectedElement.offsetTop < menuElement.scrollTop) {
        menuElement.scrollTop = selectedElement.offsetTop
        return
      }
      const offsetBottom =
        selectedElement.offsetTop + selectedElement.offsetHeight
      if (offsetBottom > menuElement.scrollTop + menuElement.offsetHeight) {
        menuElement.scrollTop = offsetBottom - menuElement.offsetHeight
      }
    },
    [isMenuVisible, menuItems.length, selectedId]
  )

  // Blur the input and hide the menu if we clicked outside the component
  useLayoutEffect(
    function () {
      function handleWindowMousedown (event) {
        if (
          isMenuVisible === false ||
          rootElementRef.current === event.target ||
          rootElementRef.current.contains(event.target)
        ) {
          // Exit if we clicked on any DOM element that is part of the component
          return
        }
        scrollTopRef.current = menuElementRef.current.scrollTop
        setMenuVisible(false)
      }
      window.addEventListener('mousedown', handleWindowMousedown)
      return function () {
        window.removeEventListener('mousedown', handleWindowMousedown)
github preactjs / preact-www / src / components / store-adapter.js View on Github external
export function useStore(keys = [], actions) {
	const store = useContext(storeCtx);
	let [currentState, setCurrentState] = useState(
		mapStateToProps(keys, store.getState())
	);

	// We can't use `useEffect` here, because the callback will be called to late.
	// This is most noticable when the store was updated when a component has
	// has rendered, but hasn't subscribed to the store yet. In that case it will
	// miss the store update. That's why we need to subscribe immediately.
	useLayoutEffect(() => {
		const update = () => {
			let mapped = mapStateToProps(keys, store.getState());
			for (let i in mapped) {
				if (mapped[i] !== currentState[i]) {
					return setCurrentState(mapped);
				}
			}

			for (let i in currentState) {
				if (!(i in mapped)) {
					return setCurrentState(mapped);
				}
			}
		};

		const dispose = store.subscribe(update);
github yuanqing / create-figma-plugin / packages / ui / src / components / textbox / textbox-autocomplete / textbox-autocomplete.js View on Github external
useLayoutEffect(
    function () {
      if (isMenuVisible === false) {
        inputElementRef.current.blur()
        setCurrentValue(EMPTY_STRING)
        return
      }
      menuElementRef.current.scrollTop = scrollTopRef.current
      inputElementRef.current.focus()
      inputElementRef.current.select()
    },
    [isMenuVisible]
  )

  // Adjust the menu scroll position so that the selected menu item is always visible
  useLayoutEffect(
    function () {
      if (isMenuVisible === false || menuItems.length === 0) {
        return
      }
      const menuElement = menuElementRef.current
      if (selectedId === INVALID_ID) {
        menuElement.scrollTop = 0
        return
      }
      const selectedElement = [].slice
        .call(menuElement.children)
        .find(function (element) {
          return element.getAttribute('data-id') === `${selectedId}`
        })
      if (selectedElement.offsetTop < menuElement.scrollTop) {
        menuElement.scrollTop = selectedElement.offsetTop
github hypothesis / lms / lms / static / scripts / frontend_apps / components / SvgIcon.js View on Github external
export default function SvgIcon({
  name,
  className = '',
  inline = false,
  title = '',
}) {
  if (!iconRegistry[name]) {
    throw new Error(`Icon name "${name}" is not registered`);
  }
  const markup = { __html: iconRegistry[name] };

  const element = /** @type {Ref} */ (useRef());
  useLayoutEffect(() => {
    const svg = element.current.querySelector('svg');

    // The icon should always contain an `<svg>` element, but check here as we
    // don't validate the markup when it is registered.
    if (svg) {
      svg.setAttribute('class', className);
    }
  }, [
    className,
    // `markup` is a dependency of this effect because the SVG is replaced if
    // it changes.
    markup,
  ]);

  const spanProps = {};
  if (title) {</svg>
github hypothesis / client / src / sidebar / components / excerpt.js View on Github external
// 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;
  }, [updateContentHeight]);

  // Render the (possibly truncated) content and controls for
  // expanding/collapsing the content.
  // prettier-ignore
  const isOverflowing = contentHeight > (collapsedHeight + overflowThreshold);
  const isCollapsed = inlineControls ? collapsedByInlineControls : collapse;
  const isExpandable = isOverflowing && isCollapsed;

  const contentStyle = {};
github hypothesis / client / src / sidebar / components / svg-icon.js View on Github external
function SvgIcon({ name, className = '', inline = false }) {
  if (!icons[name]) {
    throw new Error(`Unknown icon ${name}`);
  }
  const markup = { __html: icons[name] };

  const element = useRef();
  useLayoutEffect(() =&gt; {
    const svg = element.current.querySelector('svg');
    svg.setAttribute('class', className);
  }, [
    className,
    // `markup` is a dependency of this effect because the SVG is replaced if
    // it changes.
    markup,
  ]);

  return (
    <span>
  );</span>
github preactjs / preact-devtools / src / view / components / profiler / flamegraph / FlameGraph.tsx View on Github external
export function FlameGraph() {
	const store = useStore();
	const commit = useObserver(() =&gt; {
		return store.profiler2.activeCommit.$ || EMTPY;
	});

	const selected = useObserver(() =&gt; store.profiler2.activeCommitIdx.$);

	const ref2 = useInstance(() =&gt; createFlameGraphStore(store.profiler2));
	const nodes = useObserver(() =&gt; ref2.nodes.$);

	const displayType = useObserver(() =&gt; store.profiler2.flamegraphType.$);
	const [canvasWidth, setWidth] = useState(100);

	const ref = useRef();
	useLayoutEffect(() =&gt; {
		if (ref.current) {
			setWidth(ref.current.clientWidth);
		}
	}, [ref.current, selected, displayType]);

	useEffect(() =&gt; {
		const listener = () =&gt; {
			if (ref.current) {
				setWidth(ref.current.clientWidth);
			}
		};
		window.addEventListener("resize", listener);
		return () =&gt; window.removeEventListener("resize", listener);
	}, []);

	const isRecording = useObserver(() =&gt; store.profiler2.isRecording.$);
github yuanqing / create-figma-plugin / packages / ui / src / components / textbox / textbox.js View on Github external
onChange({ [name]: inputElementRef.current.value })
    },
    [name, onChange]
  )

  function handleKeyDown (event) {
    const keyCode = event.keyCode
    if (keyCode === ESCAPE_KEY_CODE) {
      if (propagateEscapeKeyDown === false) {
        event.stopPropagation()
      }
      inputElementRef.current.blur()
    }
  }

  useLayoutEffect(
    function () {
      if (isFocused === true) {
        handleFocus()
      }
    },
    [isFocused]
  )

  return (
    <div class="{classnames("></div>
github yuanqing / create-figma-plugin / packages / ui / src / components / search-textbox / search-textbox.js View on Github external
)

  const handleKeyDown = useCallback(
    function (event) {
      const keyCode = event.keyCode
      if (keyCode === ESCAPE_KEY_CODE) {
        if (propagateEscapeKeyDown === false) {
          event.stopPropagation()
        }
        inputElementRef.current.blur()
      }
    },
    [propagateEscapeKeyDown]
  )

  useLayoutEffect(
    function () {
      if (isFocused === true) {
        handleFocus()
      }
    },
    [isFocused]
  )

  return (
    <div class="{styles.searchTextbox}">
      </div>