@design-systems/utils
Helper utilities for developing react components.
Installation
npm i @design-systems/utils
yarn add @design-systems/utils
import Utils from '@design-systems/utils';
Usage
arrayify
(function)
Normalize a value to an array.
Parameters:
- value (
T | T[]
) - The value to potentially convert to an array
arrayify('a');
arrayify(['a']);
fromEntries
(function)
Object.fromEntries ponyfill while we wait for better babel support.
Parameters:
- entries (
[string, any][]
) - Array of object entries.
fromEntries([['key', 'value']]);
Omit
(type)
Omit keys from a type.
Omit<{foo: string, bar: string}, 'foo'>
omit
(function)
Omit keys from an object.
Parameters:
- obj (
Props
) - The object to omit props from - keys (
Prop[]
) - A list of keys to omit
Here is a simple example
const result = omit({ foo: 'a', bar: 'b' }, 'foo');
Here is a another example
const result = omit({ baz: 'a', bar: 'b' }, 'baz');
getProp
(function)
Attempt to retrieve a prop from a react node.
Parameters:
- el (
ReactNode
) - The react node to get props from - prop (
string
) - The name of the prop to get
getProp(child, 'id');
DisplayNamed
(interface)
Members:
- displayName (
string
) - The name various dev tools should use to display the component
displayName
(function)
Set a displayName on a component. This name is used in various dev tools.
Parameters:
- comp (
T
) - The component to set the display name on - name (
string
) - The display name for the component
displayName(Component, 'MyCoolComponent');
isReactInstanceOf
(function)
Determine whether a HTML element is an instance of a React component.
Parameters:
- element - Element to check the instance of
- component (
Renderable<Props>
) - The component to check for - // IDK how to get rid of this any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
element (
any
)
returns: boolean
isReactInstanceOf(child, MyComponent);
WINDOW_RESIZE_DELAY
(variable)
debounce
(function)
Only call a function once every 'wait" seconds.
Parameters:
- func (
Base
) - the callback to debounce - wait (
number
) - how long to wait until to run the callback - immediate (
boolean
) - run the callback immediately
returns: Base
const onClick = debounce(() => console.log('I was clicked'), 1000);
logger
(variable)
Logger
A logging utility which maps to console in development but
is a no-op in production.
Require
(type)
Mark some keys of an interface as required
Properties:
- T - interface to augment
- K - keys to convert to required
type Example = { foo?: string; bar?: string };
type WithFooRequired = Require<Example, 'foo'>;
Element
(type)
Get all of the props for an HTML element. Used to easily type
the rest props of a component.
Properties:
interface CardProps extends Element<'div'> {
isRound?: boolean;
}
const Card: React.FC<CardProps> = ({ isRound, children, ...html }) => (
<div {...html} style={{ borderRadius: isRound ? '4px' : 0 }}>
{children}
</div>
);
const Card: React.FC<Element<'div'>> = ({ children, ...html }) => (
<div {...html}>{children}</div>
);
Never
(type)
Create an interface that has all the properties of the input
interface set to 'never'.
Properties:
type A = { a: string };
type B = { b: string };
type C = A & Never<B>;
const test: C = {
a: 'foo',
b: 'bar'
};
OneOf
(type)
Create an interface that only accepts one of the two provided interface
type A = { a: string };
type B = { b: string };
type C = OneOf<A, B>;
const test: C = {
a: 'foo',
b: 'bar'
};
OneOf3
(type)
Create an interface that only accepts one of the three provided interface
type A = { a: string };
type B = { b: string };
type C = { c: string };
type D = OneOf<A, B, C>;
const test: D = {
a: 'foo',
c: 'bar'
};
createInstanceIfDefined
(function)
Create an instance of the component only if the element is defined.
Parameters:
- node (
ReactNode
) - The node to check if it's defined - Component (
ComponentType<{}>
) - The component to wrap the node in
const child = 'Foo';
createInstanceIfDefined(child, Wrapper);
const other = null;
createInstanceIfDefined(other, Wrapper);
SLOT_KEY
(variable)
getSlotToken
(function)
Gets the token to represent the slot on an element
Parameters:
- child (
any
) - The React component or element you want to get the slot token from
returns: any
isSlotOf
(function)
Check to see if a child component is an instance of the given slot
Parameters:
- child (
any
) - The React child component instance to test - identifier (
symbol | ComponentClass<any, any> | FunctionComponent<any>
) - The React Component or Slot ID (Symbol) to test against
returns: boolean
forwardWithSlots
(function)
Forward a ref and make the returned component slottable.
Parameters:
- Component (
ForwardRefRenderFunction<RefType, PropType>
) - Same props you give to React.forwardRef
export const SlottedComponentWithRef = forwardWithSlots<
HTMLDivElement,
ContentCardProps,
SubComponents
>((props, ref) => null);
createSlots
(function)
Chunk child elements into buckets based on React components.
Will also return the rest of the props.
Parameters:
- props (
InputProps
) - The props to find the slots in. Either in props or children - componentMapping (
ComponentMap
) - A map of slot names to slot components - omit (
(string | keyof InputProps)[]
) - A list of props to omit from the final returned props
returns: InputProps
const Example = props => {
const { header, body, footer, ...html } = createSlots(props, {
header: Header,
body: Body,
footer: Footer
});
return (
<div>
{header}
{body}
{footer}
</div>
);
};
const Usage = () => (
<Example>
<Footer>by me!</Footer>
<Body>Some Text</Body>
<Header>Title</Header>
</Example>
);
const Usage = () => (
<Example>
<Footer>by me!</Footer>
<Body>Some Text</Body>
<Header>Title</Header>
</Example>
);
FocusLock
(variable)
Lock focus withing an area of the app
Portal
(variable)
Render an element inside of a portal.
const Example = () => <Portal>{'I am rendered at the end of the dom'}</Portal>;
DocGen
(interface)
Members:
- __docgenInfo (
{ description: string; }
) - The generated docs for the react component
Slotted
(interface)
Members:
- SLOT (
symbol
) - The slot the styled element should render in
styled
(function)
Create a react element with a className attached. The generated element accepts
all the same props as the element prop.
Parameters:
- element (
T | [T, ...((props: any) => ReactNode)[]] | ((props: any) => ReactNode)
) - The html dom element to create a Component for - options (
string | WrappedComponent
) - The class an metadata to attach to the Component
returns: DocGen & Slotted & WithRef
const Wrapper = styled('div', {
class: styles.fancy,
description: 'A fancy component',
name: 'FancyWrapper'
});
const Example = ({ children, ...html }) => {
<Wrapper {...html}>{children}</Wrapper>;
};