@uxf/core

UXF Core

Usage no npm install needed!

<script type="module">
  import uxfCore from 'https://cdn.skypack.dev/@uxf/core';
</script>

README

UXF Core

Constants

  • common modifier classnames for interactive elements (eg. CLASSES.IS_HOVERABLE for is-hoverable classname)
    • focus-visible
    • is-active
    • is-busy
    • is-disabled
    • is-focused
    • is-hovered
    • is-hoverable
    • is-invalid
    • is-readonly
    • is-selected
    • is-not-hoverable

Cookie

  • Cookie options
    • secure?: boolean;
    • httpOnly?: boolean;
    • path?: string;
import { Cookie } from "@uxf/core/cookie";

// on client
const cookie = Cookie.create();

// in getInitialProps
const cookie = Cookie.create(ctx);

cookie.has("cookie-name");
cookie.get("cookie-name");
cookie.set("cookie-name", "value", /* ttl in seconds (optional) */, /* options (optional) */)
cookie.delete("cookie-name", /* options (optional) */);

Hooks

import { useBodyScrollLock } from "@uxf/core/hooks/useBodyScrollLock";
import { useState } from "react";

const innerRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState<boolean>();

const clearAllOnclose = false;

useBodyScrollLock<HTMLDivElement>(innerRef, isOpen, {
  allowTouchMove: undefined, // https://github.com/willmcpo/body-scroll-lock#allowtouchmove
  clearAllOnClose: false, // optionally call clearAllBodyScrollLocks method on unmount
  reserveScrollBarGap: undefined, // https://github.com/willmcpo/body-scroll-lock#reservescrollbargap
});

<div ref={innerRef}>Element which activates scroll lock on its parent elements.</div>
import { useIsMounted } from "@uxf/core/hooks/useIsMounted";

const isMounted = useIsMounted();
import { useIsomorphicLayoutEffect } from "@uxf/core/hooks/useIsomorphicLayoutEffect";

useIsomorphicLayoutEffect(() => {/* code */}, [/* deps */]);
import { useKey } from "@uxf/core/hooks/useKey";
import { useRef } from "react";

const targetRef = useRef<HTMLDivElement>(null);
const disabled = false; // eg. for passing disabled state

useKey<HTMLDivElement>("Enter", () => console.log("callback"), {
  disabled,
  targetRef, // if not provided, then `document` will be used
  type: "keydown"
});

<div ref={targetRef} tabIndex={0}>Element with callback triggerable by enter key.</div>
import { useMinWindowWidth } from "@uxf/core/hooks/useMinWindowWidth";

const isDesktop = useMinWindowWidth(1200);

const example = isDesktop ? "desktop" : "tablet";
import { usePagination } from "@uxf/core/hooks/usePagination";

const paginationItems = usePagination({ page: 1, count: 10 })
import { useRafState } from "@uxf/core/hooks/useRafState";

const [state, setState] = useRafState<boolean>(false);
import { useUnmount } from "@uxf/core/hooks/useUnmount";

const exampleCallback = () => {};

useUnmount(exampleCallback());
import { useUpdateEffect } from "@uxf/core/hooks/useUpdateEffect";

useUpdateEffect(() => {/* code */}, [/* deps */]);
import { useWindowScroll } from "@uxf/core/hooks/useWindowScroll";

const windowScroll = useWindowScroll();

const example = windowScroll && windowScroll.y > 100 ? "scroled" : "on top";
import { useWindowSize } from "@uxf/core/hooks/useWindowSize";

const windowSize = useWindowSize();

const example = windowSize && windowSize.width > 1200 ? "desktop" : "tablet";
import { useFocusTrap } from "@uxf/core/hooks/useFocusTrap";
import { useState } from "react";

const [active, setActive] = useState<boolean>();

const focusTrapRef = useFocusTrap(active);

<div ref={focusTrapRef}>Element which trap focus inside if `active` is truthy.</div>
import { useFocusReturn } from "@uxf/core/hooks/useFocusReturn";
import { useState } from "react";

const [active, setActive] = useState<boolean>();

// Returns focus to last active element, e.g. in Modal or Popover
useFocusReturn(active);
import { useAnchorProps } from "@uxf/core/hooks/useAnchorProps";
import { AnchorHTMLAttributes } from "react";

// extends <a /> by `analyticsCallback`, `disabled`, `loading`, `submit` props
const anchorProps = useAnchorProps<AnchorHTMLAttributes<HTMLAnchorElement>>({
  analyticsCallback: () => console.log("analytics"),
  disabled: false,
  href: "https://www.google.com/",
  loading: false,
  onClick: () => console.log("success"),
  submit: true, // simulate <button type="submit" /> function
});

<a {...anchorProps}>Click me</a>

// example with generics
import { UseAnchorProps, useAnchorProps } from "@uxf/core/hooks/useAnchorProps";
import { AnchorHTMLAttributes } from "react";

interface Props extends UseAnchorProps, AnchorHTMLAttributes<HTMLAnchorElement> {
  customProp?: boolean;
}

const anchorProps = useAnchorProps<Props>({
  customProp: true,
  loading: false,
  href: "https://www.google.com/",
});

<a {...anchorProps}>Click me</a>

import { useButtonProps } from "@uxf/core/hooks/useButtonProps";
import { ButtonHTMLAttributes } from "react";

// extends <button /> by `analyticsCallback` and `loading` props
const buttonProps = useButtonProps<ButtonHTMLAttributes<HTMLButtonElement>>({
  analyticsCallback: () => console.log("analytics"),
  disabled: false,
  loading: false,
  onClick: () => console.log("success"),
  type: "submit",
});

<button {...buttonProps}>Click me</button>

// example with generics
import { UseButtonProps, useButtonProps } from "@uxf/core/hooks/useButtonProps";
import { ButtonHTMLAttributes } from "react";

interface Props extends UseButtonProps, ButtonHTMLAttributes<HTMLButtonElement> {
  customProp?: boolean;
}

const buttonProps = useButtonProps<Props>({
  customProp: true,
  loading: false,
  type: "submit",
});

<button {...buttonProps}>Click me</button>
import { useClickableProps } from "@uxf/core/hooks/useClickableProps";
import { HTMLAttributes } from "react";

// extends any HTML element by `analyticsCallback`, `disabled`, `loading`, `submit` props
const clickableProps = useClickableProps<HTMLAttributes<HTMLDivElement>>({
  analyticsCallback: () => console.log("analytics"),
  disabled: false,
  loading: false,
  onClick: () => console.log("success"),
  submit: true, // simulate <button type="submit" /> function
});

<div {...clickableProps}>Click me</div>

// example with generics
import { UseClickableProps, useClickableProps } from "@uxf/core/hooks/useClickableProps";
import { HTMLAttributes } from "react";

interface Props extends UseClickableProps, HTMLAttributes<HTMLDivElement> {
  customProp?: boolean;
}

const buttonProps = useClickableProps<Props>({
  customProp: true,
  hidden: false,
  loading: false,
});

<button {...buttonProps}>Click me</button>
import { useMouseDragToScroll } from "@uxf/core/hooks/useMouseDragToScroll";

const targetRef = useRef<HTMLDivElement>(null);

const style = useMouseDragToScroll(scrollRef);

<div style={style}>Drag to scroll</div>
import { useInputFocus } from "@uxf/core/hooks/useInputFocus";

const focusRef = useRef<HTMLInputElement>(null); // or HTMLTextAreaElement
const { onBlur, onFocus } = props;

const input = useInputFocus(focusRef, onBlur, onFocus);

<div>Input is {input.focused}</div>
<button onClick={input.focus}>Focus input</button>
<input onBlur={input.onBlur} onFocus={input.onFocus} ref={focusRef} />

Next

import { queryParamToString, queryParamToNumber } from "@uxf/core/next";

queryParamToNumber(ctx.query.id);
queryParamToString(ctx.query.name);

Utils

import { cameCaseToDash } from "@uxf/core/utils/cameCaseToDash";

const example = cameCaseToDash("fooBar") /* returns "foo-bar" */
import { composeRefs } from "@uxf/core/utils/composeRefs";

const firstRef = useRef<HTMLDivElement>(null);
const secondRef = useRef<HTMLDivElement>(null);

const example = <div ref={composeRefs(firstRef, secondRef)} />;
import { cx } from "@uxf/core/utils/cx";

/* fork of https://github.com/lukeed/clsx */
const example = cx("foo", true && "bar", "baz", false && "bam", undefined) /* returns "foo bar baz" */
import { isBrowser } from "@uxf/core/utils/isBrowser";
import { isServer } from "@uxf/core/utils/isServer";

const browserExample = isBrowser; /* returns true if DOM is available */
const serverExample = isServer; /* returns true if DOM is NOT available */
import { slugify } from "@uxf/core/utils/slugify";

const example = slugify("Jak se dnes máte?") /* returns "jak-se-dnes-mate" */
import { trimTrailingZeros } from "@uxf/core/utils/trimTrailingZeros";

const example = trimTrailingZeros("120,450") /* returns "120,45" */

Validators

import { Validator } from "@uxf/core";

Validator.isEmail("...");
Validator.isPhone("...");