@adamjanicki/ui 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ type Props = Omit<BoxProps, "children"> & {
4
4
  /**
5
5
  * Drawers to render as accordion sections
6
6
  */
7
- drawers: Drawer[];
7
+ drawers: UncontrolledDrawer[] | ControlledDrawer[];
8
8
  /**
9
9
  * Duration of the drawer animation (in seconds)
10
10
  */
@@ -16,7 +16,7 @@ type Props = Omit<BoxProps, "children"> & {
16
16
  hideDividers?: boolean;
17
17
  };
18
18
  declare const Accordion: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
19
- type Drawer = {
19
+ type UncontrolledDrawer = {
20
20
  /**
21
21
  * Label for the accordion drawer
22
22
  */
@@ -26,12 +26,14 @@ type Drawer = {
26
26
  */
27
27
  content: React.ReactNode;
28
28
  };
29
- type DrawerProps = {
29
+ type ControlledDrawer = UncontrolledDrawer & {
30
+ /**
31
+ * Whether the drawer is open
32
+ */
30
33
  open: boolean;
34
+ /**
35
+ * Callback that fires when the open state changes for this drawer
36
+ */
31
37
  onOpenChange: (open: boolean) => void;
32
- item: Drawer;
33
- duration?: number;
34
- showDivider: boolean;
35
38
  };
36
- declare const Drawer: ({ item, open, onOpenChange, duration, showDivider, }: DrawerProps) => import("react/jsx-runtime").JSX.Element;
37
39
  export default Accordion;
@@ -30,24 +30,24 @@ import { classNames } from "../../functions";
30
30
  var Accordion = React.forwardRef(function (_a, ref) {
31
31
  var drawers = _a.drawers, className = _a.className, duration = _a.duration, hideDividers = _a.hideDividers, layout = _a.layout, rest = __rest(_a, ["drawers", "className", "duration", "hideDividers", "layout"]);
32
32
  var _b = useState(new Set()), openIndices = _b[0], setOpenIndices = _b[1];
33
- return (_jsx(Box, __assign({ layout: __assign({ axis: "y" }, layout) }, rest, { className: classNames("aui-accordion aui-corners--rounded", className), ref: ref, children: drawers.map(function (item, i) { return (_jsx(Drawer, { item: item, open: openIndices.has(i), onOpenChange: function (open) {
34
- return setOpenIndices(function (prev) {
35
- var next = new Set(prev);
36
- if (open) {
37
- next.add(i);
38
- }
39
- else {
40
- next.delete(i);
41
- }
42
- return next;
43
- });
44
- }, duration: duration, showDivider: !hideDividers && i < drawers.length - 1 }, i)); }) })));
33
+ return (_jsx(Box, __assign({ layout: __assign({ axis: "y" }, layout) }, rest, { className: classNames("aui-accordion aui-corners--rounded", className), ref: ref, children: drawers.map(function (item, i) { return (_jsx(Drawer, { item: __assign({ open: openIndices.has(i), onOpenChange: function (open) {
34
+ return setOpenIndices(function (prev) {
35
+ var next = new Set(prev);
36
+ if (open) {
37
+ next.add(i);
38
+ }
39
+ else {
40
+ next.delete(i);
41
+ }
42
+ return next;
43
+ });
44
+ } }, item), duration: duration, showDivider: !hideDividers && i < drawers.length - 1 }, i)); }) })));
45
45
  });
46
46
  var Drawer = function (_a) {
47
- var item = _a.item, open = _a.open, onOpenChange = _a.onOpenChange, duration = _a.duration, showDivider = _a.showDivider;
47
+ var item = _a.item, duration = _a.duration, showDivider = _a.showDivider;
48
48
  var boxRef = useRef(null);
49
49
  var _b = useState(), height = _b[0], setHeight = _b[1];
50
- var children = item.content;
50
+ var children = item.content, open = item.open, onOpenChange = item.onOpenChange;
51
51
  useEffect(function () {
52
52
  if (open && children && boxRef.current) {
53
53
  setHeight(boxRef.current.offsetHeight);
@@ -55,7 +55,7 @@ var Drawer = function (_a) {
55
55
  }, [open, children]);
56
56
  // TODO: change this to use calc-size when supported
57
57
  // https://developer.mozilla.org/en-US/docs/Web/CSS/calc-size#browser_compatibility
58
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { layout: { axis: "y" }, children: [_jsx(UnstyledButton, { onClick: function () { return onOpenChange(!open); }, children: _jsxs(Box, { layout: { axis: "x", align: "center", gap: "s", padding: "m" }, children: [_jsx(Icon, { size: "xs", icon: open ? "chevron-down" : "chevron-right", className: "aui-accordion-arrow" }), _jsx("span", { className: "aui-accordion-label", children: item.label })] }) }), _jsx(Animated, { style: { overflow: "hidden" }, keepMounted: true, duration: duration, animated: open, animateFrom: {
58
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { layout: { axis: "y" }, children: [_jsx(UnstyledButton, { onClick: function () { return onOpenChange(!open); }, children: _jsxs(Box, { layout: { axis: "x", align: "center", gap: "s", padding: "m" }, children: [_jsx(Icon, { size: "xs", icon: open ? "chevron-down" : "chevron-right", className: "aui-accordion-arrow" }), _jsx("span", { className: "aui-accordion-label", children: item.label })] }) }), _jsx(Animated, { style: { overflow: "hidden" }, keepMounted: true, duration: duration, visible: open, animateFrom: {
59
59
  style: {
60
60
  visibility: "hidden",
61
61
  height: 0,
@@ -3,15 +3,24 @@ import type { Style } from "../../utils/types";
3
3
  import { type BoxProps } from "../Box/Box";
4
4
  type Props = BoxProps & {
5
5
  /**
6
- * Whether to begin the animation.
6
+ * Whether to begin the animation and render the component.
7
7
  * Set to true to start animation, false to start the exit animation.
8
8
  */
9
- animated: boolean;
9
+ visible: boolean;
10
10
  /**
11
11
  * Duration of the animation in seconds
12
12
  * @default 0.25
13
13
  */
14
- duration?: number;
14
+ duration?: number | {
15
+ /**
16
+ * Length of the forward direction
17
+ */
18
+ forward: number;
19
+ /**
20
+ * Length of the reverse direction
21
+ */
22
+ reverse: number;
23
+ };
15
24
  /**
16
25
  * Whether to keep the component mounted when it is not animated
17
26
  * @default false
@@ -40,6 +49,11 @@ type Props = BoxProps & {
40
49
  */
41
50
  style?: Style;
42
51
  };
52
+ /**
53
+ * The properties to apply a transition
54
+ * @default ['all']
55
+ */
56
+ transitionProperties?: string[];
43
57
  };
44
58
  declare const Animated: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
45
59
  export default Animated;
@@ -25,9 +25,12 @@ import React, { useState, useEffect, useRef } from "react";
25
25
  import classNames from "../../functions/classNames";
26
26
  import Box from "../Box/Box";
27
27
  var Animated = React.forwardRef(function (props, ref) {
28
- var animated = props.animated, _a = props.duration, duration = _a === void 0 ? 0.25 : _a, _b = props.keepMounted, keepMounted = _b === void 0 ? false : _b, animateTo = props.animateTo, animateFrom = props.animateFrom, className = props.className, style = props.style, rest = __rest(props, ["animated", "duration", "keepMounted", "animateTo", "animateFrom", "className", "style"]);
29
- var _c = useState(animated || keepMounted), shouldRender = _c[0], setShouldRender = _c[1];
30
- var _d = useState(false), isAnimatingForward = _d[0], setIsAnimatingForward = _d[1];
28
+ var visible = props.visible, _a = props.duration, duration = _a === void 0 ? 0.25 : _a, _b = props.keepMounted, keepMounted = _b === void 0 ? false : _b, _c = props.transitionProperties, transitionProperties = _c === void 0 ? ["all"] : _c, animateTo = props.animateTo, animateFrom = props.animateFrom, className = props.className, style = props.style, rest = __rest(props, ["visible", "duration", "keepMounted", "transitionProperties", "animateTo", "animateFrom", "className", "style"]);
29
+ var forwardDuration = typeof duration === "number" ? duration : duration.forward;
30
+ var reverseDuration = typeof duration === "number" ? duration : duration.reverse;
31
+ var instantForward = forwardDuration <= 0;
32
+ var instantReverse = reverseDuration <= 0;
33
+ var _d = useState("from"), phase = _d[0], setPhase = _d[1];
31
34
  var timeoutRef = useRef(null);
32
35
  var animationFrameRef = useRef(null);
33
36
  var clearRefs = function () {
@@ -41,35 +44,51 @@ var Animated = React.forwardRef(function (props, ref) {
41
44
  }
42
45
  };
43
46
  useEffect(function () {
44
- // initiate forward animation
45
- if (animated && shouldRender) {
46
- clearRefs();
47
- animationFrameRef.current = requestAnimationFrame(function () {
48
- return setIsAnimatingForward(true);
49
- });
50
- }
51
- return clearRefs;
52
- }, [animated, shouldRender]);
53
- useEffect(function () {
54
- // make container element appear on DOM
55
- if (animated) {
56
- setShouldRender(true);
57
- }
58
- // initiate reverse animation
59
- else {
60
- clearRefs();
61
- setIsAnimatingForward(false);
62
- timeoutRef.current = window.setTimeout(function () {
63
- if (!keepMounted) {
64
- setShouldRender(false);
47
+ clearRefs();
48
+ if (visible) {
49
+ if (phase !== "forward") {
50
+ if (instantForward) {
51
+ setPhase("forward");
65
52
  }
66
- }, duration * 1000);
53
+ else {
54
+ animationFrameRef.current = requestAnimationFrame(function () {
55
+ return setPhase("forward");
56
+ });
57
+ }
58
+ }
59
+ }
60
+ else if (phase !== "from") {
61
+ if (instantReverse) {
62
+ setPhase("from");
63
+ }
64
+ else if (phase !== "reverse") {
65
+ setPhase("reverse");
66
+ }
67
+ else if (phase === "reverse") {
68
+ timeoutRef.current = window.setTimeout(function () { return setPhase("from"); }, reverseDuration * 1000);
69
+ }
67
70
  }
68
71
  return clearRefs;
69
- }, [animated, duration, keepMounted]);
70
- if (!shouldRender)
72
+ }, [visible, phase, instantForward, instantReverse, reverseDuration]);
73
+ if (phase === "from" && !keepMounted && !visible)
71
74
  return null;
72
- var currentAnimation = isAnimatingForward ? animateTo : animateFrom;
73
- return (_jsx(Box, __assign({ className: classNames(className, currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.className), style: __assign(__assign({ transition: "all ".concat(duration, "s ease-in-out") }, style), currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.style) }, rest, { ref: ref })));
75
+ var currentAnimation = phase === "forward" || (visible && instantForward)
76
+ ? animateTo
77
+ : animateFrom;
78
+ var transition = undefined;
79
+ if (phase === "forward" && !instantForward) {
80
+ transition = makeTransition(transitionProperties, forwardDuration);
81
+ }
82
+ else if (phase === "reverse" && !instantReverse) {
83
+ transition = makeTransition(transitionProperties, reverseDuration);
84
+ }
85
+ return (_jsx(Box, __assign({ className: classNames(className, currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.className), style: __assign(__assign({ transition: transition }, style), currentAnimation === null || currentAnimation === void 0 ? void 0 : currentAnimation.style) }, rest, { ref: ref })));
74
86
  });
87
+ var makeTransition = function (transitionProperties, duration) {
88
+ return transitionProperties.length > 0
89
+ ? transitionProperties
90
+ .map(function (prop) { return "".concat(prop, " ").concat(duration, "s ease-in-out"); })
91
+ .join(", ")
92
+ : undefined;
93
+ };
75
94
  export default Animated;
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import type { CornerType, SizeToken } from "../../utils/types";
3
+ import { type BoxProps } from "../Box/Box";
4
+ type Props = Omit<BoxProps, "children"> & {
5
+ /**
6
+ * How to treat the border radius of the avatar
7
+ * @default "rounded"
8
+ */
9
+ corners?: CornerType;
10
+ /**
11
+ * Size of the avatar
12
+ * @default "s"
13
+ */
14
+ size?: SizeToken | number;
15
+ /**
16
+ * Image to be used in the background
17
+ */
18
+ backgroundImage?: string;
19
+ /**
20
+ * Username to render the first char of,
21
+ * or as a fallback if there's a 404 getting the backgroundImage url
22
+ */
23
+ username: string;
24
+ };
25
+ declare const Avatar: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
26
+ export default Avatar;
@@ -0,0 +1,56 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ import { jsx as _jsx } from "react/jsx-runtime";
24
+ import React, { useState } from "react";
25
+ import Box from "../Box/Box";
26
+ import { classNames } from "../../functions";
27
+ var Avatar = React.forwardRef(function (_a, ref) {
28
+ var _b = _a.size, size = _b === void 0 ? "s" : _b, backgroundImage = _a.backgroundImage, className = _a.className, style = _a.style, _c = _a.corners, corners = _c === void 0 ? "rounded" : _c, username = _a.username, rest = __rest(_a, ["size", "backgroundImage", "className", "style", "corners", "username"]);
29
+ var _d = useState(false), imageError = _d[0], setImageError = _d[1];
30
+ var useFallback = imageError || !backgroundImage;
31
+ var color = chooseColor(username);
32
+ var avatarClassName = "aui-avatar aui-corners--".concat(corners);
33
+ if (useFallback) {
34
+ avatarClassName = classNames(avatarClassName, "aui-avatar-".concat(color));
35
+ }
36
+ var imageClassName = undefined;
37
+ var avatarStyle = {};
38
+ var imageStyle = undefined;
39
+ if (typeof size === "number") {
40
+ avatarStyle = { width: size, height: size, fontSize: 0.8 * size };
41
+ imageStyle = { width: size, height: size };
42
+ }
43
+ else {
44
+ avatarClassName = classNames(avatarClassName, "aui-avatar-".concat(size));
45
+ imageClassName = "aui-avatar-".concat(size);
46
+ }
47
+ var fallbackCharacter = username[0];
48
+ return (_jsx(Box, __assign({ className: classNames(avatarClassName, className), style: __assign(__assign({}, avatarStyle), style) }, rest, { ref: ref, children: !useFallback ? (_jsx("img", { src: backgroundImage, alt: "", className: imageClassName, onError: function () { return setImageError(true); }, style: imageStyle })) : (fallbackCharacter) })));
49
+ });
50
+ var colorOptions = ["red", "yellow", "green", "blue", "purple"];
51
+ // simple deterministic "hash" to get a background color
52
+ function chooseColor(username) {
53
+ return colorOptions[username.split("").reduce(function (sum, char) { return sum + char.charCodeAt(0); }, 0) %
54
+ colorOptions.length];
55
+ }
56
+ export default Avatar;
@@ -0,0 +1,2 @@
1
+ import Avatar from "./Avatar";
2
+ export default Avatar;
@@ -0,0 +1,2 @@
1
+ import Avatar from "./Avatar";
2
+ export default Avatar;
@@ -1,6 +1,8 @@
1
1
  import React from "react";
2
2
  import type { CornerType, Layout } from "../../utils/types";
3
- type DefaultButtonProps = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
3
+ import { Props as IconProps } from "../Icon/Icon";
4
+ type BaseButtonProps = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
5
+ type DefaultButtonProps = BaseButtonProps & {
4
6
  /**
5
7
  * Additional styles to apply to the layout that are transformed to classNames to be easier to override if needed
6
8
  */
@@ -25,6 +27,26 @@ export type VisualButtonProps = {
25
27
  };
26
28
  type ButtonProps = DefaultButtonProps & VisualButtonProps;
27
29
  export declare const UnstyledButton: React.ForwardRefExoticComponent<Omit<DefaultButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
30
+ type IconButtonProps = Omit<BaseButtonProps, "children"> & {
31
+ /**
32
+ * The hover effect to play when the user hovers over the button
33
+ * @default "dim"
34
+ */
35
+ variant?: "dim" | "undim";
36
+ /**
37
+ * Which icon to render in the button
38
+ */
39
+ icon: IconProps["icon"];
40
+ /**
41
+ * The size of the icon
42
+ */
43
+ size?: IconProps["size"];
44
+ /**
45
+ * Other props to pass to the icon element
46
+ */
47
+ iconProps?: Omit<IconProps, "icon" | "size">;
48
+ };
49
+ export declare const IconButton: React.ForwardRefExoticComponent<Omit<IconButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
28
50
  declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
29
51
  export declare const getButtonClassName: ({ variant, corners, size, }: VisualButtonProps) => string;
30
52
  export default Button;
@@ -24,10 +24,15 @@ import { jsx as _jsx } from "react/jsx-runtime";
24
24
  import React from "react";
25
25
  import classNames from "../../functions/classNames";
26
26
  import transformLayout from "../../utils/transformLayout";
27
+ import Icon from "../Icon/Icon";
27
28
  export var UnstyledButton = React.forwardRef(function (_a, ref) {
28
29
  var className = _a.className, layout = _a.layout, props = __rest(_a, ["className", "layout"]);
29
30
  return (_jsx("button", __assign({}, props, { className: classNames("aui-action aui-button", transformLayout(layout), className), ref: ref })));
30
31
  });
32
+ export var IconButton = React.forwardRef(function (_a, ref) {
33
+ var icon = _a.icon, size = _a.size, iconProps = _a.iconProps, _b = _a.variant, variant = _b === void 0 ? "dim" : _b, className = _a.className, rest = __rest(_a, ["icon", "size", "iconProps", "variant", "className"]);
34
+ return (_jsx(UnstyledButton, __assign({}, rest, { layout: { axis: "x", align: "center", justify: "center" }, className: classNames("aui-".concat(variant), className), ref: ref, children: _jsx(Icon, __assign({ icon: icon, size: size }, iconProps)) })));
35
+ });
31
36
  var Button = React.forwardRef(function (_a, ref) {
32
37
  var variant = _a.variant, layout = _a.layout, corners = _a.corners, className = _a.className, size = _a.size, rest = __rest(_a, ["variant", "layout", "corners", "className", "size"]);
33
38
  return (_jsx(UnstyledButton, __assign({}, rest, { className: classNames(getButtonClassName({ variant: variant, corners: corners, size: size }), transformLayout(layout), className), ref: ref })));
@@ -1,3 +1,3 @@
1
- import Button, { UnstyledButton } from "./Button";
2
- export { UnstyledButton };
1
+ import Button, { UnstyledButton, IconButton } from "./Button";
2
+ export { UnstyledButton, IconButton };
3
3
  export default Button;
@@ -1,3 +1,3 @@
1
- import Button, { UnstyledButton } from "./Button";
2
- export { UnstyledButton };
1
+ import Button, { UnstyledButton, IconButton } from "./Button";
2
+ export { UnstyledButton, IconButton };
3
3
  export default Button;
@@ -1,4 +1,9 @@
1
1
  import React from "react";
2
+ declare const mouseEvents: {
3
+ readonly click: "onClick";
4
+ readonly mousedown: "onMouseDown";
5
+ readonly mouseup: "onMouseUp";
6
+ };
2
7
  type Props = {
3
8
  /**
4
9
  * The children to render.
@@ -11,6 +16,11 @@ type Props = {
11
16
  * @param event - The mouse event object
12
17
  */
13
18
  onClickOutside: (event: MouseEvent) => void;
19
+ /**
20
+ * The mouse event to trigger on
21
+ * @default "click"
22
+ */
23
+ mouseEvent?: keyof typeof mouseEvents;
14
24
  };
15
- declare const ClickOutside: ({ children, onClickOutside, }: Props) => React.JSX.Element;
25
+ declare const ClickOutside: ({ children, onClickOutside, mouseEvent, }: Props) => React.JSX.Element;
16
26
  export default ClickOutside;
@@ -1,6 +1,13 @@
1
1
  import { cloneElement, useCallback, useEffect, useRef } from "react";
2
+ import useMergeRefs from "../../hooks/useMergeRefs";
3
+ var mouseEvents = {
4
+ click: "onClick",
5
+ mousedown: "onMouseDown",
6
+ mouseup: "onMouseUp",
7
+ };
2
8
  var ClickOutside = function (_a) {
3
- var children = _a.children, onClickOutside = _a.onClickOutside;
9
+ var _b;
10
+ var children = _a.children, onClickOutside = _a.onClickOutside, _c = _a.mouseEvent, mouseEvent = _c === void 0 ? "click" : _c;
4
11
  var ref = useRef(null);
5
12
  var clickWithinChildRef = useRef(false);
6
13
  var startedRef = useRef(false);
@@ -14,27 +21,35 @@ var ClickOutside = function (_a) {
14
21
  };
15
22
  }, []);
16
23
  var handleClickOutside = useCallback(function (event) {
24
+ var _a;
17
25
  var clickedWithinChild = clickWithinChildRef.current;
18
26
  clickWithinChildRef.current = false;
19
- if (!startedRef.current || !ref.current || clickedWithinChild)
27
+ var childElement = ref.current;
28
+ if (!startedRef.current || !childElement || clickedWithinChild)
20
29
  return;
21
- if (!event.composedPath().includes(ref.current)) {
30
+ var path = ((_a = event.composedPath) === null || _a === void 0 ? void 0 : _a.call(event)) || [];
31
+ var isInside = path.includes(childElement) ||
32
+ childElement.contains(event.target);
33
+ if (!isInside) {
22
34
  onClickOutside(event);
23
35
  }
24
36
  }, [onClickOutside]);
25
37
  useEffect(function () {
26
- document.addEventListener("click", handleClickOutside);
27
- return function () { return document.removeEventListener("click", handleClickOutside); };
28
- }, [handleClickOutside]);
29
- return cloneElement(children, {
30
- ref: ref,
31
- onClick: function (event) {
38
+ document.addEventListener(mouseEvent, handleClickOutside);
39
+ return function () { return document.removeEventListener(mouseEvent, handleClickOutside); };
40
+ }, [handleClickOutside, mouseEvent]);
41
+ var mergedRef = useMergeRefs(ref, children.props.ref);
42
+ var mouseEventPropName = mouseEvents[mouseEvent];
43
+ return cloneElement(children, (_b = {
44
+ ref: mergedRef
45
+ },
46
+ _b[mouseEventPropName] = function (event) {
32
47
  var _a, _b;
33
48
  // point of this is to let us know that click originated
34
49
  // from the child element, so we can ignore it
35
50
  clickWithinChildRef.current = true;
36
- (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
51
+ (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a[mouseEventPropName]) === null || _b === void 0 ? void 0 : _b.call(_a, event);
37
52
  },
38
- });
53
+ _b));
39
54
  };
40
55
  export default ClickOutside;
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { type IconType } from "./icons";
3
+ import type { SizeToken } from "../../utils/types";
3
4
  export type Props = Omit<React.DetailedHTMLProps<React.SVGAttributes<SVGSVGElement>, SVGSVGElement>, "children" | "viewBox"> & {
4
5
  /**
5
6
  * The version of icon to render
@@ -9,7 +10,7 @@ export type Props = Omit<React.DetailedHTMLProps<React.SVGAttributes<SVGSVGEleme
9
10
  * Size of the icon; will control both width and height
10
11
  * @default "s"
11
12
  */
12
- size?: "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
13
+ size?: SizeToken;
13
14
  };
14
15
  declare const Icon: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<SVGSVGElement>>;
15
16
  export default Icon;
@@ -10,11 +10,6 @@ type Props = Omit<BoxProps, "children"> & {
10
10
  * IMPORTANT: the child must be able to accept a ref
11
11
  */
12
12
  children: React.ReactElement<any>;
13
- /**
14
- * [Optional] Whether to disable the escape key to close the layer
15
- * @default false
16
- */
17
- disableEscape?: boolean;
18
13
  /**
19
14
  * [Optional] Whether to return focus to the element that triggered the layer
20
15
  * @default false
@@ -25,14 +25,13 @@ import React, { useEffect } from "react";
25
25
  import { useFocusTrap, useScrollLock } from "../../hooks";
26
26
  import classNames from "../../functions/classNames";
27
27
  import Box from "../Box/Box";
28
+ import useMergeRefs from "../../hooks/useMergeRefs";
28
29
  var Layer = React.forwardRef(function (_a, ref) {
29
- var returnFocusOnEscape = _a.returnFocusOnEscape, disableScrollLock = _a.disableScrollLock, onClose = _a.onClose, children = _a.children, className = _a.className, _b = _a.disableEscape, disableEscape = _b === void 0 ? false : _b, onMouseDown = _a.onMouseDown, layout = _a.layout, rest = __rest(_a, ["returnFocusOnEscape", "disableScrollLock", "onClose", "children", "className", "disableEscape", "onMouseDown", "layout"]);
30
+ var returnFocusOnEscape = _a.returnFocusOnEscape, disableScrollLock = _a.disableScrollLock, onClose = _a.onClose, children = _a.children, className = _a.className, onMouseDown = _a.onMouseDown, layout = _a.layout, rest = __rest(_a, ["returnFocusOnEscape", "disableScrollLock", "onClose", "children", "className", "onMouseDown", "layout"]);
30
31
  var focusRef = useFocusTrap(true);
31
32
  // Lock and unlock on mount and unmount
32
33
  useScrollLock(!disableScrollLock);
33
34
  useEffect(function () {
34
- if (disableEscape)
35
- return;
36
35
  var handleEscape = function (event) {
37
36
  var _a;
38
37
  if (event.key === "Escape") {
@@ -47,12 +46,13 @@ var Layer = React.forwardRef(function (_a, ref) {
47
46
  return function () {
48
47
  document.removeEventListener("keydown", handleEscape);
49
48
  };
50
- }, [onClose, disableEscape, returnFocusOnEscape]);
49
+ }, [onClose, returnFocusOnEscape]);
50
+ var mergedRef = useMergeRefs(focusRef, children.props.ref);
51
51
  return (_jsx(Box, __assign({ layout: __assign({ axis: "y", align: "center", justify: "center" }, layout) }, rest, { className: classNames("aui-layer-backdrop", className), onMouseDown: function (e) {
52
52
  onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(e);
53
53
  onClose === null || onClose === void 0 ? void 0 : onClose();
54
54
  }, ref: ref, children: React.cloneElement(children, {
55
- ref: focusRef,
55
+ ref: mergedRef,
56
56
  onMouseDown: function (e) {
57
57
  var _a, _b;
58
58
  e.stopPropagation();
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { type BoxProps } from "../Box/Box";
3
+ type Props = BoxProps & {
4
+ /**
5
+ * Callback that fires when the user clicks the Ok button in the modal
6
+ */
7
+ onConfirm: () => void;
8
+ /**
9
+ * Label rendered in the ok/confirm button
10
+ * @default "Ok"
11
+ */
12
+ confirmLabel?: React.ReactNode;
13
+ /**
14
+ * Label rendered in the cancel button
15
+ * @default "Cancel"
16
+ */
17
+ cancelLabel?: React.ReactNode;
18
+ /**
19
+ * Whether the modal is open or not
20
+ */
21
+ open: boolean;
22
+ /**
23
+ * Callback that fires when the user closes the modal
24
+ */
25
+ onClose: () => void;
26
+ /**
27
+ * [Optional] Whether to return focus to the element that triggered the modal
28
+ * @default false
29
+ */
30
+ returnFocusOnEscape?: boolean;
31
+ };
32
+ declare const Modal: React.ForwardRefExoticComponent<Omit<Props, "ref"> & React.RefAttributes<HTMLDivElement>>;
33
+ export default Modal;
@@ -0,0 +1,47 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
+ import React from "react";
25
+ import Box from "../Box/Box";
26
+ import Layer from "../Layer";
27
+ import Button, { IconButton } from "../Button";
28
+ import Animated from "../Animated";
29
+ var Modal = React.forwardRef(function (_a, ref) {
30
+ var open = _a.open, onClose = _a.onClose, onConfirm = _a.onConfirm, _b = _a.confirmLabel, confirmLabel = _b === void 0 ? "Ok" : _b, _c = _a.cancelLabel, cancelLabel = _c === void 0 ? "Cancel" : _c, returnFocusOnEscape = _a.returnFocusOnEscape, rest = __rest(_a, ["open", "onClose", "onConfirm", "confirmLabel", "cancelLabel", "returnFocusOnEscape"]);
31
+ return (_jsx(Animated, { className: "aui-modal-backdrop", visible: open, animateTo: { style: { opacity: 1 } }, animateFrom: { style: { opacity: 0 } }, children: _jsx(Layer, { onClose: onClose, returnFocusOnEscape: returnFocusOnEscape, children: _jsxs(Box, { role: "dialog", "aria-modal": "true", className: "aui-modal aui-corners--rounded", layout: { axis: "y", padding: "m", gap: "m" }, children: [_jsx(Box, { layout: {
32
+ axis: "x",
33
+ align: "center",
34
+ justify: "end",
35
+ width: "full",
36
+ }, children: _jsx(IconButton, { icon: "x", onClick: onClose }) }), _jsx(Box, __assign({}, rest, { ref: ref })), _jsxs(Box, { layout: {
37
+ axis: "x",
38
+ align: "center",
39
+ justify: "end",
40
+ width: "full",
41
+ gap: "m",
42
+ }, children: [_jsx(Button, { variant: "secondary", onClick: onClose, children: cancelLabel }), _jsx(Button, { onClick: function () {
43
+ onConfirm();
44
+ onClose();
45
+ }, children: confirmLabel })] })] }) }) }));
46
+ });
47
+ export default Modal;
@@ -0,0 +1,2 @@
1
+ import Modal from "./Modal";
2
+ export default Modal;
@@ -0,0 +1,2 @@
1
+ import Modal from "./Modal";
2
+ export default Modal;
package/hooks/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export { default as useScroll } from "./useScroll";
4
4
  export { default as useFocusTrap } from "./useFocusTrap";
5
5
  export { default as useScrollToHash } from "./useScrollToHash";
6
6
  export { default as useWindowResize } from "./useWindowResize";
7
+ export { default as useMergeRefs } from "./useMergeRefs";
package/hooks/index.js CHANGED
@@ -4,3 +4,4 @@ export { default as useScroll } from "./useScroll";
4
4
  export { default as useFocusTrap } from "./useFocusTrap";
5
5
  export { default as useScrollToHash } from "./useScrollToHash";
6
6
  export { default as useWindowResize } from "./useWindowResize";
7
+ export { default as useMergeRefs } from "./useMergeRefs";
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ /**
3
+ * Simple hook that merges N refs into one callback
4
+ *
5
+ * @param refs all the refs you want to merge
6
+ * @returns one combined ref
7
+ */
8
+ declare const useMergeRefs: <T>(...refs: (React.Ref<T> | null | undefined)[]) => React.Ref<T>;
9
+ export default useMergeRefs;
@@ -0,0 +1,24 @@
1
+ import { useCallback } from "react";
2
+ /**
3
+ * Simple hook that merges N refs into one callback
4
+ *
5
+ * @param refs all the refs you want to merge
6
+ * @returns one combined ref
7
+ */
8
+ var useMergeRefs = function () {
9
+ var refs = [];
10
+ for (var _i = 0; _i < arguments.length; _i++) {
11
+ refs[_i] = arguments[_i];
12
+ }
13
+ return useCallback(function (node) {
14
+ refs.forEach(function (ref) {
15
+ if (typeof ref === "function") {
16
+ ref(node);
17
+ }
18
+ else if (ref && typeof ref === "object") {
19
+ ref.current = node;
20
+ }
21
+ });
22
+ }, [refs]);
23
+ };
24
+ export default useMergeRefs;
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { default as Accordion } from "./components/Accordion";
2
2
  export { default as Alert } from "./components/Alert";
3
3
  export { default as Animated } from "./components/Animated";
4
+ export { default as Avatar } from "./components/Avatar";
4
5
  export { default as Badge } from "./components/Badge";
5
6
  export { default as Banner } from "./components/Banner";
6
7
  export { default as Box } from "./components/Box";
@@ -16,6 +17,7 @@ export * from "./components/Input";
16
17
  export { default as Layer } from "./components/Layer";
17
18
  export { default as Link } from "./components/Link";
18
19
  export * from "./components/Link";
20
+ export { default as Modal } from "./components/Modal";
19
21
  export { default as Select } from "./components/Select";
20
22
  export { default as Spinner } from "./components/Spinner";
21
23
  export * from "./hooks";
package/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  export { default as Accordion } from "./components/Accordion";
3
3
  export { default as Alert } from "./components/Alert";
4
4
  export { default as Animated } from "./components/Animated";
5
+ export { default as Avatar } from "./components/Avatar";
5
6
  export { default as Badge } from "./components/Badge";
6
7
  export { default as Banner } from "./components/Banner";
7
8
  export { default as Box } from "./components/Box";
@@ -17,6 +18,7 @@ export * from "./components/Input";
17
18
  export { default as Layer } from "./components/Layer";
18
19
  export { default as Link } from "./components/Link";
19
20
  export * from "./components/Link";
21
+ export { default as Modal } from "./components/Modal";
20
22
  export { default as Select } from "./components/Select";
21
23
  export { default as Spinner } from "./components/Spinner";
22
24
  // Hooks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamjanicki/ui",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Basic UI components and hooks for React in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./index.js",
package/style.css CHANGED
@@ -1 +1 @@
1
- :root{--aui-xxs: 2px;--aui-xs: 4px;--aui-s: 8px;--aui-m: 16px;--aui-l: 24px;--aui-xl: 32px;--aui-xxl: 64px;--aui-moon-gray: #ccc;--aui-dark-gray: #555;--aui-darkest-gray: #333;--aui-obsidian: #121212;--aui-focus-ring-color: #b2dbfa;--aui-default-text-color: black;--aui-default-background: white;--aui-default-border: var(--aui-moon-gray);--aui-disabled-opacity: 0.5;--aui-default-transition: 0.25s ease-in-out;--aui-default-opacity-dim: 0.75;--aui-container-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);--aui-sharp-radius: 0;--aui-rounded-radius: 8px;--aui-pill-radius: 9999px;--aui-button-primary-background: black;--aui-button-primary-color: white;--aui-button-secondary-border-hover: var(--aui-darkest-gray);--aui-subtle-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.16);--aui-button-primary-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.36);--aui-success-background: #dff2e1;--aui-success-color: #1b5e20;--aui-success-border: #b2dfb1;--aui-warning-background: #fceeb6;--aui-warning-color: #b23904;--aui-warning-border: #e6d5a2;--aui-error-background: #fdecea;--aui-error-color: #b71c1c;--aui-error-border: #f5b7b7;--aui-info-background: #e3f2fd;--aui-info-color: #0d47a1;--aui-info-border: #90caf9;--aui-static-background: #e8e8e8;--aui-layer-backdrop-background: rgba(200, 200, 200, 0.7);--aui-link-color: #0070ff;--aui-select-icon: var(--aui-dark-gray)}[data-theme=dark]{--aui-focus-ring-color: #6699cc;--aui-default-text-color: white;--aui-default-background: var(--aui-obsidian);--aui-default-border: var(--aui-dark-gray);--aui-container-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.36);--aui-button-primary-background: white;--aui-button-primary-color: var(--aui-obsidian);--aui-button-secondary-border-hover: var(--aui-moon-gray);--aui-subtle-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);--aui-button-primary-box-shadow: 0 1px 2px rgba(64, 64, 64, 0.8);--aui-success-background: #2a5733;--aui-success-color: #d9efd8;--aui-success-border: #439e4a;--aui-warning-background: #736230;--aui-warning-color: #fff6d1;--aui-warning-border: #927a3b;--aui-error-background: #663232;--aui-error-color: #f9dadc;--aui-error-border: #8d2a2a;--aui-info-background: #335f72;--aui-info-color: #d4f1f5;--aui-info-border: #1d8ea4;--aui-static-background: var(--aui-darkest-gray);--aui-layer-backdrop-background: rgba(55, 55, 55, 0.7);--aui-link-color: #33bfff;--aui-select-icon: var(--aui-moon-gray)}.aui-corners--rounded{border-radius:var(--aui-rounded-radius)}.aui-corners--pill{border-radius:var(--aui-pill-radius)}.aui-corners--sharp{border-radius:var(--aui-sharp-radius)}.aui-content--success{background-color:var(--aui-success-background);color:var(--aui-success-color);border-color:var(--aui-success-border)}.aui-content--warning{background-color:var(--aui-warning-background);color:var(--aui-warning-color);border-color:var(--aui-warning-border)}.aui-content--error{background-color:var(--aui-error-background);color:var(--aui-error-color);border-color:var(--aui-error-border)}.aui-content--info{background-color:var(--aui-info-background);color:var(--aui-info-color);border-color:var(--aui-info-border)}.aui-content--static{background-color:var(--aui-static-background);color:var(--aui-default-text-color);border-color:var(--aui-default-border)}.aui-accordion{background-color:var(--aui-default-background);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-container-box-shadow)}.aui-accordion-label{font-weight:600}.aui-accordion-hr{border:none;height:1px;background-color:var(--aui-default-border);width:100%;margin:0}.aui-accordion-arrow{color:var(--aui-select-icon)}.aui-alert{padding:var(--aui-m);border-style:solid;border-width:1px;font-weight:400}.aui-badge{padding:var(--aui-xxs) var(--aui-xs);border-style:solid;border-width:1px;font-weight:500;font-size:14px;width:fit-content}.aui-banner{padding:var(--aui-l) var(--aui-xl);border:none;font-weight:400;width:100%}.aui-action{color:inherit;text-decoration:none;cursor:pointer;outline-color:var(--aui-link-color)}.aui-action:focus:not(:focus-visible){outline:none}.aui-button{background:none;border:none;padding:0}.aui-button-size--regular{padding:var(--aui-s);font-weight:600}.aui-button-size--small{padding:var(--aui-xs);font-size:12px;font-weight:600}.aui-button:disabled{cursor:default !important;opacity:var(--aui-disabled-opacity)}.aui-button--primary{background-color:var(--aui-button-primary-background);color:var(--aui-button-primary-color);box-shadow:var(--aui-button-primary-box-shadow);transition:opacity var(--aui-default-transition)}.aui-button--secondary{color:var(--aui-default-text-color);background-color:var(--aui-default-background);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);transition:box-shadow var(--aui-default-transition)}.aui-link{font-weight:600;color:var(--aui-link-color);transition:opacity var(--aui-default-transition)}@media(hover: hover){.aui-button--primary:not([disabled]):hover,.aui-link:hover{opacity:var(--aui-default-opacity-dim)}.aui-button--secondary:not([disabled]):hover{box-shadow:0 0 0 1px var(--aui-button-secondary-border-hover) inset,var(--aui-subtle-box-shadow)}}.aui-input-base{outline:none;border:none;background-color:inherit;color:inherit;padding:var(--aui-s);font-weight:400}.aui-input-base::selection{background-color:var(--aui-focus-ring-color)}.aui-icon-input{overflow:scroll}.aui-icon-input input{background-color:rgba(0,0,0,0);width:100%}.aui-input{transition:box-shadow var(--aui-default-transition);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);background-color:var(--aui-default-background)}.aui-input:disabled{opacity:var(--aui-disabled-opacity);cursor:default}.aui-input:not([disabled]):focus-within,.aui-select-container:not([disabled]):focus-within{box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow),0 0 0 3px var(--aui-focus-ring-color)}.aui-select-container{position:relative;padding:0;width:fit-content;transition:box-shadow var(--aui-default-transition);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);background-color:var(--aui-default-background)}.aui-select{width:100%;color:inherit;border:none;outline:none;box-shadow:none;cursor:pointer;background-color:rgba(0,0,0,0);padding:var(--aui-s) 28px var(--aui-s) var(--aui-s);font-weight:600;appearance:none;-webkit-appearance:none;-moz-appearance:none}.aui-select-disabled *{opacity:var(--aui-disabled-opacity);cursor:default}.aui-layer-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:10000;background:var(--aui-layer-backdrop-background)}.aui-icon *{color:currentColor;fill:currentColor}.aui-spinner{animation:aui-spinner-animation 1s linear infinite;transform-origin:center;height:var(--aui-l)}@keyframes aui-spinner-animation{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.aui-carousel{max-width:100%;position:relative;overflow:hidden;min-height:var(--aui-xxl);min-width:var(--aui-xxl);width:fit-content}.aui-carousel-item{flex:0 0 100%;width:100%;height:100%}.aui-carousel-arrow{position:absolute;top:50%;transform:translateY(-50%);width:var(--aui-l);height:var(--aui-l);padding:0}.aui-carousel-dots{position:absolute;bottom:var(--aui-s);transform:translateX(-50%);left:50%}.aui-carousel-dot{width:var(--aui-m);height:var(--aui-s);padding:0}.aui-flex-x,.aui-flex-y,.aui-flex--x,.aui-flex--y{display:flex}.aui-flex-x{flex-direction:row}.aui-flex-y{flex-direction:column}.aui-flex--x{flex-direction:row-reverse}.aui-flex--y{flex-direction:column-reverse}.aui-flex-wrap{flex-wrap:wrap}.aui-align-start{align-items:flex-start}.aui-align-center{align-items:center}.aui-align-end{align-items:flex-end}.aui-justify-start{justify-content:flex-start}.aui-justify-center{justify-content:center}.aui-justify-between{justify-content:space-between}.aui-justify-around{justify-content:space-around}.aui-justify-end{justify-content:flex-end}.aui-icon-xxs{width:8px;height:8px}.aui-icon-xs{width:12px;height:12px}.aui-icon-s{width:16px;height:16px}.aui-icon-m{width:24px;height:24px}.aui-icon-l{width:32px;height:32px}.aui-icon-xl{width:48px;height:48px}.aui-icon-xxl{width:64px;height:64px}.aui-gap-none{gap:0}.aui-gap-xxs{gap:var(--aui-xxs)}.aui-gap-xs{gap:var(--aui-xs)}.aui-gap-s{gap:var(--aui-s)}.aui-gap-m{gap:var(--aui-m)}.aui-gap-l{gap:var(--aui-l)}.aui-gap-xl{gap:var(--aui-xl)}.aui-gap-xxl{gap:var(--aui-xxl)}.aui-pa-none{padding:0}.aui-pa-xxs{padding:var(--aui-xxs)}.aui-pa-xs{padding:var(--aui-xs)}.aui-pa-s{padding:var(--aui-s)}.aui-pa-m{padding:var(--aui-m)}.aui-pa-l{padding:var(--aui-l)}.aui-pa-xl{padding:var(--aui-xl)}.aui-pa-xxl{padding:var(--aui-xxl)}.aui-pt-none{padding-top:0}.aui-pt-xxs{padding-top:var(--aui-xxs)}.aui-pt-xs{padding-top:var(--aui-xs)}.aui-pt-s{padding-top:var(--aui-s)}.aui-pt-m{padding-top:var(--aui-m)}.aui-pt-l{padding-top:var(--aui-l)}.aui-pt-xl{padding-top:var(--aui-xl)}.aui-pt-xxl{padding-top:var(--aui-xxl)}.aui-pb-none{padding-bottom:0}.aui-pb-xxs{padding-bottom:var(--aui-xxs)}.aui-pb-xs{padding-bottom:var(--aui-xs)}.aui-pb-s{padding-bottom:var(--aui-s)}.aui-pb-m{padding-bottom:var(--aui-m)}.aui-pb-l{padding-bottom:var(--aui-l)}.aui-pb-xl{padding-bottom:var(--aui-xl)}.aui-pb-xxl{padding-bottom:var(--aui-xxl)}.aui-pl-none{padding-left:0}.aui-pl-xxs{padding-left:var(--aui-xxs)}.aui-pl-xs{padding-left:var(--aui-xs)}.aui-pl-s{padding-left:var(--aui-s)}.aui-pl-m{padding-left:var(--aui-m)}.aui-pl-l{padding-left:var(--aui-l)}.aui-pl-xl{padding-left:var(--aui-xl)}.aui-pl-xxl{padding-left:var(--aui-xxl)}.aui-pr-none{padding-right:0}.aui-pr-xxs{padding-right:var(--aui-xxs)}.aui-pr-xs{padding-right:var(--aui-xs)}.aui-pr-s{padding-right:var(--aui-s)}.aui-pr-m{padding-right:var(--aui-m)}.aui-pr-l{padding-right:var(--aui-l)}.aui-pr-xl{padding-right:var(--aui-xl)}.aui-pr-xxl{padding-right:var(--aui-xxl)}.aui-ma-auto{margin:auto}.aui-mt-auto{margin-top:auto}.aui-mb-auto{margin-bottom:auto}.aui-ml-auto{margin-left:auto}.aui-mr-auto{margin-right:auto}.aui-ma-none{margin:0}.aui-ma-xxs{margin:var(--aui-xxs)}.aui-ma-xs{margin:var(--aui-xs)}.aui-ma-s{margin:var(--aui-s)}.aui-ma-m{margin:var(--aui-m)}.aui-ma-l{margin:var(--aui-l)}.aui-ma-xl{margin:var(--aui-xl)}.aui-ma-xxl{margin:var(--aui-xxl)}.aui-mt-none{margin-top:0}.aui-mt-xxs{margin-top:var(--aui-xxs)}.aui-mt-xs{margin-top:var(--aui-xs)}.aui-mt-s{margin-top:var(--aui-s)}.aui-mt-m{margin-top:var(--aui-m)}.aui-mt-l{margin-top:var(--aui-l)}.aui-mt-xl{margin-top:var(--aui-xl)}.aui-mt-xxl{margin-top:var(--aui-xxl)}.aui-mb-none{margin-bottom:0}.aui-mb-xxs{margin-bottom:var(--aui-xxs)}.aui-mb-xs{margin-bottom:var(--aui-xs)}.aui-mb-s{margin-bottom:var(--aui-s)}.aui-mb-m{margin-bottom:var(--aui-m)}.aui-mb-l{margin-bottom:var(--aui-l)}.aui-mb-xl{margin-bottom:var(--aui-xl)}.aui-mb-xxl{margin-bottom:var(--aui-xxl)}.aui-ml-none{margin-left:0}.aui-ml-xxs{margin-left:var(--aui-xxs)}.aui-ml-xs{margin-left:var(--aui-xs)}.aui-ml-s{margin-left:var(--aui-s)}.aui-ml-m{margin-left:var(--aui-m)}.aui-ml-l{margin-left:var(--aui-l)}.aui-ml-xl{margin-left:var(--aui-xl)}.aui-ml-xxl{margin-left:var(--aui-xxl)}.aui-mr-none{margin-right:0}.aui-mr-xxs{margin-right:var(--aui-xxs)}.aui-mr-xs{margin-right:var(--aui-xs)}.aui-mr-s{margin-right:var(--aui-s)}.aui-mr-m{margin-right:var(--aui-m)}.aui-mr-l{margin-right:var(--aui-l)}.aui-mr-xl{margin-right:var(--aui-xl)}.aui-mr-xxl{margin-right:var(--aui-xxl)}.aui-w-full{width:100%}.aui-w-fit{width:fit-content}.aui-w-min{width:min-content}.aui-w-max{width:max-content}.aui-mw-full{max-width:100%}.aui-mw-fit{max-width:fit-content}.aui-mw-min{max-width:min-content}.aui-mw-max{max-width:max-content}.aui-h-full{height:100%}.aui-h-fit{height:fit-content}.aui-h-min{height:min-content}.aui-h-max{height:max-content}.aui-mh-full{max-height:100%}.aui-mh-fit{max-height:fit-content}.aui-mh-min{max-height:min-content}.aui-mh-max{max-height:max-content}.aui-select-icon{--size: 10px;color:var(--aui-select-icon);width:var(--size);height:var(--size);position:absolute;top:calc(50% + 1px);transform:translateY(-50%);right:var(--size);pointer-events:none}
1
+ :root{--aui-xxs: 2px;--aui-xs: 4px;--aui-s: 8px;--aui-m: 16px;--aui-l: 24px;--aui-xl: 32px;--aui-xxl: 64px;--aui-moon-gray: #ccc;--aui-dark-gray: #555;--aui-darkest-gray: #333;--aui-obsidian: #121212;--aui-focus-ring-color: #b2dbfa;--aui-default-text-color: black;--aui-default-background: white;--aui-default-border: var(--aui-moon-gray);--aui-disabled-opacity: 0.5;--aui-default-transition: 0.25s ease-in-out;--aui-default-opacity-dim: 0.75;--aui-floating-box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);--aui-sharp-radius: 0;--aui-rounded-radius: 8px;--aui-pill-radius: 9999px;--aui-button-primary-background: black;--aui-button-primary-color: white;--aui-button-secondary-border-hover: var(--aui-darkest-gray);--aui-subtle-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.16);--aui-button-primary-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.36);--aui-success-background: #dff2e1;--aui-success-color: #1b5e20;--aui-success-border: #b2dfb1;--aui-warning-background: #fceeb6;--aui-warning-color: #b23904;--aui-warning-border: #e6d5a2;--aui-error-background: #fdecea;--aui-error-color: #b71c1c;--aui-error-border: #f5b7b7;--aui-info-background: #e3f2fd;--aui-info-color: #0d47a1;--aui-info-border: #90caf9;--aui-avatar-purple: #bc54d6;--aui-avatar-blue: #618bdc;--aui-avatar-red: #ee6060;--aui-avatar-green: #add386;--aui-avatar-yellow: #f5c76d;--aui-static-background: #e8e8e8;--aui-layer-backdrop-background: rgba(200, 200, 200, 0.6);--aui-link-color: #0070ff;--aui-select-icon: var(--aui-dark-gray)}[data-theme=dark]{--aui-focus-ring-color: #6699cc;--aui-default-text-color: white;--aui-default-background: var(--aui-obsidian);--aui-default-border: var(--aui-dark-gray);--aui-floating-box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);--aui-button-primary-background: white;--aui-button-primary-color: var(--aui-obsidian);--aui-button-secondary-border-hover: var(--aui-moon-gray);--aui-subtle-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);--aui-button-primary-box-shadow: 0 1px 2px rgba(64, 64, 64, 0.8);--aui-success-background: #2a5733;--aui-success-color: #d9efd8;--aui-success-border: #439e4a;--aui-warning-background: #736230;--aui-warning-color: #fff6d1;--aui-warning-border: #927a3b;--aui-error-background: #663232;--aui-error-color: #f9dadc;--aui-error-border: #8d2a2a;--aui-info-background: #335f72;--aui-info-color: #d4f1f5;--aui-info-border: #1d8ea4;--aui-avatar-purple: #771199;--aui-avatar-blue: #0b4cce;--aui-avatar-red: #bb1111;--aui-avatar-green: #307040;--aui-avatar-yellow: #bb8822;--aui-static-background: var(--aui-darkest-gray);--aui-layer-backdrop-background: rgba(55, 55, 55, 0.7);--aui-link-color: #33bfff;--aui-select-icon: var(--aui-moon-gray)}.aui-corners--rounded{border-radius:var(--aui-rounded-radius)}.aui-corners--pill{border-radius:var(--aui-pill-radius)}.aui-corners--sharp{border-radius:var(--aui-sharp-radius)}.aui-content--success{background-color:var(--aui-success-background);color:var(--aui-success-color);border-color:var(--aui-success-border)}.aui-content--warning{background-color:var(--aui-warning-background);color:var(--aui-warning-color);border-color:var(--aui-warning-border)}.aui-content--error{background-color:var(--aui-error-background);color:var(--aui-error-color);border-color:var(--aui-error-border)}.aui-content--info{background-color:var(--aui-info-background);color:var(--aui-info-color);border-color:var(--aui-info-border)}.aui-content--static{background-color:var(--aui-static-background);color:var(--aui-default-text-color);border-color:var(--aui-default-border)}.aui-modal{color:var(--aui-default-text-color);background-color:var(--aui-default-background);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-floating-box-shadow);border-radius:var(--aui-rounded-radius);min-width:40%;max-width:100%}.aui-accordion{background-color:var(--aui-default-background);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow)}.aui-accordion-label{font-weight:600}.aui-accordion-hr{border:none;height:1px;background-color:var(--aui-default-border);width:100%;margin:0}.aui-accordion-arrow{color:var(--aui-select-icon)}.aui-alert{padding:var(--aui-m);border-style:solid;border-width:1px;font-weight:400}.aui-avatar{overflow:hidden;text-align:center;font-weight:600}.aui-badge{padding:var(--aui-xxs) var(--aui-xs);border-style:solid;border-width:1px;font-weight:500;font-size:14px;width:fit-content}.aui-banner{padding:var(--aui-l) var(--aui-xl);border:none;font-weight:400;width:100%}.aui-action{color:inherit;text-decoration:none;cursor:pointer;outline-color:var(--aui-link-color)}.aui-action:focus:not(:focus-visible){outline:none}.aui-button{background:none;border:none;padding:0}.aui-button-size--regular{padding:var(--aui-s);font-weight:600}.aui-button-size--small{padding:var(--aui-xs);font-size:12px;font-weight:600}.aui-button:disabled{cursor:default !important;opacity:var(--aui-disabled-opacity)}.aui-button--primary{background-color:var(--aui-button-primary-background);color:var(--aui-button-primary-color);box-shadow:var(--aui-button-primary-box-shadow);transition:opacity var(--aui-default-transition)}.aui-button--secondary{color:var(--aui-default-text-color);background-color:var(--aui-default-background);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);transition:box-shadow var(--aui-default-transition)}.aui-dim,.aui-undim{transition:opacity var(--aui-default-transition)}.aui-dim{opacity:1}.aui-undim{opacity:var(--aui-default-opacity-dim)}.aui-link{font-weight:600;color:var(--aui-link-color);transition:opacity var(--aui-default-transition)}@media(hover: hover){.aui-button--primary:not([disabled]):hover,.aui-dim:not([disabled]):hover,.aui-link:hover{opacity:var(--aui-default-opacity-dim)}.aui-button--secondary:not([disabled]):hover{box-shadow:0 0 0 1px var(--aui-button-secondary-border-hover) inset,var(--aui-subtle-box-shadow)}.aui-undim:not([disabled]):hover{opacity:1}}.aui-input-base{outline:none;border:none;background-color:inherit;color:inherit;padding:var(--aui-s);font-weight:400}.aui-input-base::selection{background-color:var(--aui-focus-ring-color)}.aui-icon-input{overflow:scroll}.aui-icon-input input{background-color:rgba(0,0,0,0);width:100%}.aui-input{transition:box-shadow var(--aui-default-transition);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);background-color:var(--aui-default-background)}.aui-input:disabled{opacity:var(--aui-disabled-opacity);cursor:default}.aui-input:not([disabled]):focus-within,.aui-select-container:not([disabled]):focus-within{box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow),0 0 0 3px var(--aui-focus-ring-color)}.aui-select-container{position:relative;padding:0;width:fit-content;transition:box-shadow var(--aui-default-transition);box-shadow:0 0 0 1px var(--aui-default-border) inset,var(--aui-subtle-box-shadow);background-color:var(--aui-default-background)}.aui-select{width:100%;color:inherit;border:none;outline:none;box-shadow:none;cursor:pointer;background-color:rgba(0,0,0,0);padding:var(--aui-s) 28px var(--aui-s) var(--aui-s);font-weight:600;appearance:none;-webkit-appearance:none;-moz-appearance:none}.aui-select-disabled *{opacity:var(--aui-disabled-opacity);cursor:default}.aui-modal-backdrop,.aui-layer-backdrop{z-index:10000}.aui-layer-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;background:var(--aui-layer-backdrop-background)}.aui-icon *{color:currentColor;fill:currentColor}.aui-spinner{animation:aui-spinner-animation 1s linear infinite;transform-origin:center;height:var(--aui-l)}@keyframes aui-spinner-animation{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.aui-carousel{max-width:100%;position:relative;overflow:hidden;min-height:var(--aui-xxl);min-width:var(--aui-xxl);width:fit-content}.aui-carousel-item{flex:0 0 100%;width:100%;height:100%}.aui-carousel-arrow{position:absolute;top:50%;transform:translateY(-50%);width:var(--aui-l);height:var(--aui-l);padding:0}.aui-carousel-dots{position:absolute;bottom:var(--aui-s);transform:translateX(-50%);left:50%}.aui-carousel-dot{width:var(--aui-m);height:var(--aui-s);padding:0}.aui-flex-x,.aui-flex-y,.aui-flex--x,.aui-flex--y{display:flex}.aui-flex-x{flex-direction:row}.aui-flex-y{flex-direction:column}.aui-flex--x{flex-direction:row-reverse}.aui-flex--y{flex-direction:column-reverse}.aui-flex-wrap{flex-wrap:wrap}.aui-align-start{align-items:flex-start}.aui-align-center{align-items:center}.aui-align-end{align-items:flex-end}.aui-justify-start{justify-content:flex-start}.aui-justify-center{justify-content:center}.aui-justify-between{justify-content:space-between}.aui-justify-around{justify-content:space-around}.aui-justify-end{justify-content:flex-end}.aui-avatar-red{background-color:var(--aui-avatar-red)}.aui-avatar-yellow{background-color:var(--aui-avatar-yellow)}.aui-avatar-green{background-color:var(--aui-avatar-green)}.aui-avatar-blue{background-color:var(--aui-avatar-blue)}.aui-avatar-purple{background-color:var(--aui-avatar-purple)}.aui-avatar-xxs{width:12px;height:12px;line-height:12px;font-size:9.6px}.aui-avatar-xs{width:16px;height:16px;line-height:16px;font-size:12.8px}.aui-avatar-s{width:24px;height:24px;line-height:24px;font-size:19.2px}.aui-avatar-m{width:32px;height:32px;line-height:32px;font-size:25.6px}.aui-avatar-l{width:48px;height:48px;line-height:48px;font-size:38.4px}.aui-avatar-xl{width:64px;height:64px;line-height:64px;font-size:51.2px}.aui-avatar-xxl{width:128px;height:128px;line-height:128px;font-size:102.4px}.aui-icon-xxs{width:8px;height:8px}.aui-icon-xs{width:12px;height:12px}.aui-icon-s{width:16px;height:16px}.aui-icon-m{width:24px;height:24px}.aui-icon-l{width:32px;height:32px}.aui-icon-xl{width:48px;height:48px}.aui-icon-xxl{width:64px;height:64px}.aui-gap-none{gap:0}.aui-gap-xxs{gap:var(--aui-xxs)}.aui-gap-xs{gap:var(--aui-xs)}.aui-gap-s{gap:var(--aui-s)}.aui-gap-m{gap:var(--aui-m)}.aui-gap-l{gap:var(--aui-l)}.aui-gap-xl{gap:var(--aui-xl)}.aui-gap-xxl{gap:var(--aui-xxl)}.aui-pa-none{padding:0}.aui-pa-xxs{padding:var(--aui-xxs)}.aui-pa-xs{padding:var(--aui-xs)}.aui-pa-s{padding:var(--aui-s)}.aui-pa-m{padding:var(--aui-m)}.aui-pa-l{padding:var(--aui-l)}.aui-pa-xl{padding:var(--aui-xl)}.aui-pa-xxl{padding:var(--aui-xxl)}.aui-pt-none{padding-top:0}.aui-pt-xxs{padding-top:var(--aui-xxs)}.aui-pt-xs{padding-top:var(--aui-xs)}.aui-pt-s{padding-top:var(--aui-s)}.aui-pt-m{padding-top:var(--aui-m)}.aui-pt-l{padding-top:var(--aui-l)}.aui-pt-xl{padding-top:var(--aui-xl)}.aui-pt-xxl{padding-top:var(--aui-xxl)}.aui-pb-none{padding-bottom:0}.aui-pb-xxs{padding-bottom:var(--aui-xxs)}.aui-pb-xs{padding-bottom:var(--aui-xs)}.aui-pb-s{padding-bottom:var(--aui-s)}.aui-pb-m{padding-bottom:var(--aui-m)}.aui-pb-l{padding-bottom:var(--aui-l)}.aui-pb-xl{padding-bottom:var(--aui-xl)}.aui-pb-xxl{padding-bottom:var(--aui-xxl)}.aui-pl-none{padding-left:0}.aui-pl-xxs{padding-left:var(--aui-xxs)}.aui-pl-xs{padding-left:var(--aui-xs)}.aui-pl-s{padding-left:var(--aui-s)}.aui-pl-m{padding-left:var(--aui-m)}.aui-pl-l{padding-left:var(--aui-l)}.aui-pl-xl{padding-left:var(--aui-xl)}.aui-pl-xxl{padding-left:var(--aui-xxl)}.aui-pr-none{padding-right:0}.aui-pr-xxs{padding-right:var(--aui-xxs)}.aui-pr-xs{padding-right:var(--aui-xs)}.aui-pr-s{padding-right:var(--aui-s)}.aui-pr-m{padding-right:var(--aui-m)}.aui-pr-l{padding-right:var(--aui-l)}.aui-pr-xl{padding-right:var(--aui-xl)}.aui-pr-xxl{padding-right:var(--aui-xxl)}.aui-ma-auto{margin:auto}.aui-mt-auto{margin-top:auto}.aui-mb-auto{margin-bottom:auto}.aui-ml-auto{margin-left:auto}.aui-mr-auto{margin-right:auto}.aui-ma-none{margin:0}.aui-ma-xxs{margin:var(--aui-xxs)}.aui-ma-xs{margin:var(--aui-xs)}.aui-ma-s{margin:var(--aui-s)}.aui-ma-m{margin:var(--aui-m)}.aui-ma-l{margin:var(--aui-l)}.aui-ma-xl{margin:var(--aui-xl)}.aui-ma-xxl{margin:var(--aui-xxl)}.aui-mt-none{margin-top:0}.aui-mt-xxs{margin-top:var(--aui-xxs)}.aui-mt-xs{margin-top:var(--aui-xs)}.aui-mt-s{margin-top:var(--aui-s)}.aui-mt-m{margin-top:var(--aui-m)}.aui-mt-l{margin-top:var(--aui-l)}.aui-mt-xl{margin-top:var(--aui-xl)}.aui-mt-xxl{margin-top:var(--aui-xxl)}.aui-mb-none{margin-bottom:0}.aui-mb-xxs{margin-bottom:var(--aui-xxs)}.aui-mb-xs{margin-bottom:var(--aui-xs)}.aui-mb-s{margin-bottom:var(--aui-s)}.aui-mb-m{margin-bottom:var(--aui-m)}.aui-mb-l{margin-bottom:var(--aui-l)}.aui-mb-xl{margin-bottom:var(--aui-xl)}.aui-mb-xxl{margin-bottom:var(--aui-xxl)}.aui-ml-none{margin-left:0}.aui-ml-xxs{margin-left:var(--aui-xxs)}.aui-ml-xs{margin-left:var(--aui-xs)}.aui-ml-s{margin-left:var(--aui-s)}.aui-ml-m{margin-left:var(--aui-m)}.aui-ml-l{margin-left:var(--aui-l)}.aui-ml-xl{margin-left:var(--aui-xl)}.aui-ml-xxl{margin-left:var(--aui-xxl)}.aui-mr-none{margin-right:0}.aui-mr-xxs{margin-right:var(--aui-xxs)}.aui-mr-xs{margin-right:var(--aui-xs)}.aui-mr-s{margin-right:var(--aui-s)}.aui-mr-m{margin-right:var(--aui-m)}.aui-mr-l{margin-right:var(--aui-l)}.aui-mr-xl{margin-right:var(--aui-xl)}.aui-mr-xxl{margin-right:var(--aui-xxl)}.aui-w-full{width:100%}.aui-w-fit{width:fit-content}.aui-w-min{width:min-content}.aui-w-max{width:max-content}.aui-mw-full{max-width:100%}.aui-mw-fit{max-width:fit-content}.aui-mw-min{max-width:min-content}.aui-mw-max{max-width:max-content}.aui-h-full{height:100%}.aui-h-fit{height:fit-content}.aui-h-min{height:min-content}.aui-h-max{height:max-content}.aui-mh-full{max-height:100%}.aui-mh-fit{max-height:fit-content}.aui-mh-min{max-height:min-content}.aui-mh-max{max-height:max-content}.aui-select-icon{--size: 10px;color:var(--aui-select-icon);width:var(--size);height:var(--size);position:absolute;top:calc(50% + 1px);transform:translateY(-50%);right:var(--size);pointer-events:none}
package/utils/types.d.ts CHANGED
@@ -22,17 +22,21 @@ export type SizeDimension = "full" | "fit" | "min" | "max";
22
22
  /**
23
23
  * Size variants used for CSS.
24
24
  */
25
- type SizeToken = "none" | "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
25
+ export type SizeToken = "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
26
+ /**
27
+ * Size variants used for padding & margin
28
+ */
29
+ type SpacingSize = "none" | "xxs" | "xs" | "s" | "m" | "l" | "xl" | "xxl";
26
30
  /**
27
31
  * Used for margin
28
32
  */
29
- type AutoSize = SizeToken | "auto";
33
+ type AutoSize = SpacingSize | "auto";
30
34
  /** Layout props for a component */
31
35
  export type Layout = {
32
36
  /** Direction the layout spans; along the x-axis or y-axis (Equivalent to flex-direction) */
33
37
  axis?: "x" | "y" | "-x" | "-y";
34
38
  /** Spacing between children of the layout */
35
- gap?: SizeToken;
39
+ gap?: SpacingSize;
36
40
  /** Alignment orthogonal to the selected axis (Equivalent to align-items) */
37
41
  align?: "start" | "center" | "end";
38
42
  /** How to layout the children (Equivalent to justify-content) */
@@ -40,19 +44,19 @@ export type Layout = {
40
44
  /** Whether to allow wrapping of layout children */
41
45
  wrap?: boolean;
42
46
  /** Padding inside the layout */
43
- padding?: SizeToken;
47
+ padding?: SpacingSize;
44
48
  /** Horizontal padding inside the layout */
45
- paddingX?: SizeToken;
49
+ paddingX?: SpacingSize;
46
50
  /** Vertical padding inside the layout */
47
- paddingY?: SizeToken;
51
+ paddingY?: SpacingSize;
48
52
  /** Top padding inside the layout */
49
- paddingTop?: SizeToken;
53
+ paddingTop?: SpacingSize;
50
54
  /** Bottom padding inside the layout */
51
- paddingBottom?: SizeToken;
55
+ paddingBottom?: SpacingSize;
52
56
  /** Left padding inside the layout */
53
- paddingLeft?: SizeToken;
57
+ paddingLeft?: SpacingSize;
54
58
  /** Right padding inside the layout */
55
- paddingRight?: SizeToken;
59
+ paddingRight?: SpacingSize;
56
60
  /** Margin outside the layout */
57
61
  margin?: AutoSize;
58
62
  /** Horizontal margin outside the layout */