@plexui/ui 0.20.8 → 0.20.10

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.
Files changed (44) hide show
  1. package/dist/es/components/Checkbox/Checkbox.js +1 -1
  2. package/dist/es/components/Checkbox/Checkbox.js.map +1 -1
  3. package/dist/es/components/DateRangePicker/Calendar.js +18 -19
  4. package/dist/es/components/DateRangePicker/Calendar.js.map +1 -1
  5. package/dist/es/components/DateRangePicker/DateRangePicker.js +3 -1
  6. package/dist/es/components/DateRangePicker/DateRangePicker.js.map +1 -1
  7. package/dist/es/components/DateRangePicker/context.js.map +1 -1
  8. package/dist/es/components/DateRangePicker/index.js.map +1 -1
  9. package/dist/es/components/DateRangePicker/types.js.map +1 -1
  10. package/dist/es/components/Dialog/Dialog.js +8 -2
  11. package/dist/es/components/Dialog/Dialog.js.map +1 -1
  12. package/dist/es/components/Field/Field.js +6 -3
  13. package/dist/es/components/Field/Field.js.map +1 -1
  14. package/dist/es/components/InputGroup/InputGroup.js +1 -1
  15. package/dist/es/components/InputGroup/InputGroup.js.map +1 -1
  16. package/dist/es/components/Menu/Menu.js +8 -3
  17. package/dist/es/components/Menu/Menu.js.map +1 -1
  18. package/dist/es/components/Popover/Popover.js +16 -8
  19. package/dist/es/components/Popover/Popover.js.map +1 -1
  20. package/dist/es/components/Select/Select.js +17 -9
  21. package/dist/es/components/Select/Select.js.map +1 -1
  22. package/dist/es/components/SelectControl/SelectControl.js +6 -5
  23. package/dist/es/components/SelectControl/SelectControl.js.map +1 -1
  24. package/dist/es/components/Transition/TransitionGroup.js +7 -6
  25. package/dist/es/components/Transition/TransitionGroup.js.map +1 -1
  26. package/dist/es/components/Transition/shared.js +30 -0
  27. package/dist/es/components/Transition/shared.js.map +1 -1
  28. package/dist/es/lib/dateUtils.js +5 -0
  29. package/dist/es/lib/dateUtils.js.map +1 -1
  30. package/dist/es/lib/helpers.js +30 -0
  31. package/dist/es/lib/helpers.js.map +1 -1
  32. package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +6 -1
  33. package/dist/types/components/DateRangePicker/context.d.ts +2 -1
  34. package/dist/types/components/DateRangePicker/index.d.ts +1 -1
  35. package/dist/types/components/DateRangePicker/types.d.ts +2 -0
  36. package/dist/types/components/Field/Field.d.ts +4 -2
  37. package/dist/types/components/Popover/Popover.d.ts +2 -0
  38. package/dist/types/components/Select/Select.d.ts +5 -0
  39. package/dist/types/components/SelectControl/SelectControl.d.ts +7 -1
  40. package/dist/types/components/Transition/TransitionGroup.d.ts +5 -0
  41. package/dist/types/components/Transition/shared.d.ts +23 -0
  42. package/dist/types/lib/dateUtils.d.ts +5 -0
  43. package/dist/types/lib/helpers.d.ts +14 -1
  44. package/package.json +1 -1
@@ -8,7 +8,7 @@ import { Button } from "../Button/index.js";
8
8
  import { ChevronDown, Dropdown, X } from "../Icon/index.js";
9
9
  import { LoadingIndicator } from "../Indicator/index.js";
10
10
  import s from "@plexui/styles/components/SelectControl/SelectControl.module.css";
11
- export const SelectControl = ({ ref, onPointerDown, onKeyDown, onPointerEnter, onInteract, invalid, disabled, children, className, variant = "outline", size = "md", block, opticallyAlign, pill = false, loading, onClearClick, selected = false, StartIcon, dropdownIconType = "dropdown", ...restProps }) => {
11
+ export const SelectControl = ({ ref, onPointerDown, onKeyDown, onPointerEnter, onInteract, interactOnEnter = false, invalid, disabled, children, className, variant = "outline", size = "md", block, opticallyAlign, pill = false, loading, onClearClick, selected = false, StartIcon, dropdownIconType = "dropdown", ...restProps }) => {
12
12
  const controlRef = useRef(null);
13
13
  const clearable = !!onClearClick;
14
14
  const showClearAction = clearable && selected && !loading && !disabled;
@@ -23,10 +23,14 @@ export const SelectControl = ({ ref, onPointerDown, onKeyDown, onPointerEnter, o
23
23
  return;
24
24
  }
25
25
  switch (evt.key) {
26
- // NOTE: "Enter" does not open selects, as it may be an attempt to submit a form
26
+ case "Enter":
27
27
  case "ArrowDown":
28
28
  case "ArrowUp":
29
29
  case " ":
30
+ // NOTE: "Enter" may be an attempt to submit a form
31
+ if (evt.key === "Enter" && !interactOnEnter) {
32
+ break;
33
+ }
30
34
  evt.stopPropagation();
31
35
  evt.preventDefault();
32
36
  if (onInteract) {
@@ -41,9 +45,6 @@ export const SelectControl = ({ ref, onPointerDown, onKeyDown, onPointerEnter, o
41
45
  }));
42
46
  }
43
47
  break;
44
- case "Enter":
45
- // NOTE: "Enter" does not open selects, as it may be an attempt to submit a form
46
- break;
47
48
  default:
48
49
  // Allow all other key presses through
49
50
  onKeyDown?.(evt);
@@ -1 +1 @@
1
- {"version":3,"file":"SelectControl.js","sourceRoot":"","sources":["../../../../src/components/SelectControl/SelectControl.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { useRef, type ReactNode } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport type { ControlSize, Variants } from \"../../types\"\nimport { Button } from \"../Button\"\nimport { ChevronDown, Dropdown, X } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport s from \"@plexui/styles/components/SelectControl/SelectControl.module.css\"\n\nexport type DropdownIconType = \"chevronDown\" | \"dropdown\" | \"none\"\n\nexport type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"onClick\"> & {\n /**\n * Style variant for the Button\n * @default fill\n */\n variant?: Variants<\"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the control should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Extends the control to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the control\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Disables the control visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Visually indicates that the control is in an invalid state\n * @default false\n */\n invalid?: boolean\n /**\n * Indicates that the control is selected. An unselected state will display placeholder styles.\n * @default false\n */\n selected?: boolean\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n onClearClick?: () => void\n /**\n * Primary handler for when the control is selected with pointer or keyboard events\n */\n onInteract?: () => void\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: DropdownIconType\n /** Icon displayed at the start of the control */\n StartIcon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the control element */\n className?: string\n /** Content rendered for the control */\n children: ReactNode\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const SelectControl = ({\n ref,\n onPointerDown,\n onKeyDown,\n onPointerEnter,\n onInteract,\n invalid,\n disabled,\n children,\n className,\n variant = \"outline\",\n size = \"md\",\n block,\n opticallyAlign,\n pill = false,\n loading,\n onClearClick,\n selected = false,\n StartIcon,\n dropdownIconType = \"dropdown\",\n ...restProps\n}: SelectControlProps) => {\n const controlRef = useRef<HTMLSpanElement>(null)\n const clearable = !!onClearClick\n const showClearAction = clearable && selected && !loading && !disabled\n const hasDropdownIcon = dropdownIconType && dropdownIconType !== \"none\" && !loading\n const hasAnyTertiaryIndicator = showClearAction || loading || hasDropdownIcon\n const isInteractive = !loading && !disabled\n\n // Act like a <button> and fire the click handler on keyboard actions\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLSpanElement>) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) {\n return\n }\n switch (evt.key) {\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n evt.stopPropagation()\n evt.preventDefault()\n\n if (onInteract) {\n onInteract()\n } else {\n // Otherwise, send a synthetic trigger event to Radix (presumably)\n controlRef.current?.dispatchEvent(\n new PointerEvent(\"pointerdown\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\", // mimic mouse interaction\n }),\n )\n }\n break\n case \"Enter\":\n // NOTE: \"Enter\" does not open selects, as it may be an attempt to submit a form\n break\n default:\n // Allow all other key presses through\n onKeyDown?.(evt)\n }\n }\n\n const handlePointerDown = (evt: React.PointerEvent<HTMLSpanElement>) => {\n // Don't trigger on right clicks\n if (evt.button === 2) {\n return\n }\n\n // Prevent focus from entering the click target of the select\n // so that focus correctly moves into the menu.\n evt.stopPropagation()\n\n if (onInteract) {\n evt.preventDefault()\n onInteract()\n } else {\n // NOTE: cannot preventDefault() here, for radix\n onPointerDown?.(evt)\n // @ts-expect-error -- `onClick` can only be present if Radix is trying to spread it.\n // An example would be `<Popover>`, but we specifically open this component on `onPointerDown`.\n // Trigger the handler, assuming that `onPointerDown` is not going to be responsible for opening.\n restProps.onClick?.(evt)\n }\n }\n\n return (\n // Intentionally not using <button> and rebuilding the semantics\n <span\n ref={mergeRefs([controlRef, ref])}\n className={clsx(s.SelectControl, className)}\n // Recreate <button> semantics\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onPointerEnter={(evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n }}\n onPointerDown={isInteractive ? handlePointerDown : undefined}\n onKeyDown={isInteractive ? handleKeyDown : undefined}\n data-variant={variant}\n data-block={block ? \"\" : undefined}\n data-pill={pill ? \"\" : undefined}\n data-size={size}\n data-optically-align={opticallyAlign}\n aria-busy={loading ? \"true\" : undefined}\n data-selected={selected}\n data-loading={loading ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-disabled={disabled}\n {...restProps}\n // Ignore onClick handler from Radix, because we use onPointerDown to mimic a native select\n onClick={undefined}\n >\n {StartIcon && <StartIcon className={s.StartIcon} />}\n <span className={s.TriggerText}>{children}</span>\n {hasAnyTertiaryIndicator && (\n <div className={s.IndicatorWrapper}>\n {showClearAction && (\n <Button\n aria-label=\"Clear current value\"\n className={s.Clear}\n onPointerDown={(evt: React.PointerEvent<HTMLButtonElement>) => {\n // Prevent pointerDown on trigger from being captured\n evt.stopPropagation()\n }}\n onClick={(evt) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick()\n }}\n color=\"secondary\"\n variant={hasDropdownIcon ? \"ghost\" : \"solid\"}\n // Mostly custom sizing through variables\n size=\"3xs\"\n uniform\n pill={pill}\n data-only-child={!hasDropdownIcon ? \"\" : undefined}\n >\n <X />\n </Button>\n )}\n {loading && <LoadingIndicator className={s.LoadingIndicator} />}\n {/* Using raw SVG canvases (opposed to fixed icon canvases) led to less pixelation. */}\n {hasDropdownIcon && <DropdownIcon iconType={dropdownIconType} />}\n </div>\n )}\n </span>\n )\n}\n\ntype DropdownIconProps = {\n iconType: Omit<DropdownIconType, \"none\">\n}\n\nexport const DropdownIcon = ({ iconType }: DropdownIconProps) => {\n return iconType === \"chevronDown\" ? (\n <ChevronDown className={clsx(s.DropdownIcon, s.DropdownIconChevron)} />\n ) : (\n <Dropdown className={s.DropdownIcon} />\n )\n}\n"]}
1
+ {"version":3,"file":"SelectControl.js","sourceRoot":"","sources":["../../../../src/components/SelectControl/SelectControl.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { useRef, type ReactNode } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport type { ControlSize, Variants } from \"../../types\"\nimport { Button } from \"../Button\"\nimport { ChevronDown, Dropdown, X } from \"../Icon\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport s from \"@plexui/styles/components/SelectControl/SelectControl.module.css\"\n\nexport type DropdownIconType = \"chevronDown\" | \"dropdown\" | \"none\"\n\nexport type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"onClick\"> & {\n /**\n * Style variant for the Button\n * @default fill\n */\n variant?: Variants<\"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the control should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Extends the control to 100% of available width.\n * @default true\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the control\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Disables the control visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Visually indicates that the control is in an invalid state\n * @default false\n */\n invalid?: boolean\n /**\n * Indicates that the control is selected. An unselected state will display placeholder styles.\n * @default false\n */\n selected?: boolean\n /**\n * Display a clear action that allows the select to be unset.\n * @default false\n */\n onClearClick?: () => void\n /**\n * Primary handler for when the control is selected with pointer or keyboard events\n */\n onInteract?: () => void\n /**\n * Enter interacts too, as on a combobox button. Off by default, as Enter\n * may be an attempt to submit a form.\n * @default false\n */\n interactOnEnter?: boolean\n /**\n * Determines size of the size and spacing of the control.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Icon displayed in the far right of the select trigger\n * @default dropdown\n */\n dropdownIconType?: DropdownIconType\n /** Icon displayed at the start of the control */\n StartIcon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Custom class applied to the control element */\n className?: string\n /** Content rendered for the control */\n children: ReactNode\n ref?: React.Ref<HTMLSpanElement | null>\n}\n\nexport const SelectControl = ({\n ref,\n onPointerDown,\n onKeyDown,\n onPointerEnter,\n onInteract,\n interactOnEnter = false,\n invalid,\n disabled,\n children,\n className,\n variant = \"outline\",\n size = \"md\",\n block,\n opticallyAlign,\n pill = false,\n loading,\n onClearClick,\n selected = false,\n StartIcon,\n dropdownIconType = \"dropdown\",\n ...restProps\n}: SelectControlProps) => {\n const controlRef = useRef<HTMLSpanElement>(null)\n const clearable = !!onClearClick\n const showClearAction = clearable && selected && !loading && !disabled\n const hasDropdownIcon = dropdownIconType && dropdownIconType !== \"none\" && !loading\n const hasAnyTertiaryIndicator = showClearAction || loading || hasDropdownIcon\n const isInteractive = !loading && !disabled\n\n // Act like a <button> and fire the click handler on keyboard actions\n const handleKeyDown = (evt: React.KeyboardEvent<HTMLSpanElement>) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) {\n return\n }\n switch (evt.key) {\n case \"Enter\":\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n // NOTE: \"Enter\" may be an attempt to submit a form\n if (evt.key === \"Enter\" && !interactOnEnter) {\n break\n }\n\n evt.stopPropagation()\n evt.preventDefault()\n\n if (onInteract) {\n onInteract()\n } else {\n // Otherwise, send a synthetic trigger event to Radix (presumably)\n controlRef.current?.dispatchEvent(\n new PointerEvent(\"pointerdown\", {\n bubbles: true,\n cancelable: true,\n pointerType: \"mouse\", // mimic mouse interaction\n }),\n )\n }\n break\n default:\n // Allow all other key presses through\n onKeyDown?.(evt)\n }\n }\n\n const handlePointerDown = (evt: React.PointerEvent<HTMLSpanElement>) => {\n // Don't trigger on right clicks\n if (evt.button === 2) {\n return\n }\n\n // Prevent focus from entering the click target of the select\n // so that focus correctly moves into the menu.\n evt.stopPropagation()\n\n if (onInteract) {\n evt.preventDefault()\n onInteract()\n } else {\n // NOTE: cannot preventDefault() here, for radix\n onPointerDown?.(evt)\n // @ts-expect-error -- `onClick` can only be present if Radix is trying to spread it.\n // An example would be `<Popover>`, but we specifically open this component on `onPointerDown`.\n // Trigger the handler, assuming that `onPointerDown` is not going to be responsible for opening.\n restProps.onClick?.(evt)\n }\n }\n\n return (\n // Intentionally not using <button> and rebuilding the semantics\n <span\n ref={mergeRefs([controlRef, ref])}\n className={clsx(s.SelectControl, className)}\n // Recreate <button> semantics\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onPointerEnter={(evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n }}\n onPointerDown={isInteractive ? handlePointerDown : undefined}\n onKeyDown={isInteractive ? handleKeyDown : undefined}\n data-variant={variant}\n data-block={block ? \"\" : undefined}\n data-pill={pill ? \"\" : undefined}\n data-size={size}\n data-optically-align={opticallyAlign}\n aria-busy={loading ? \"true\" : undefined}\n data-selected={selected}\n data-loading={loading ? \"\" : undefined}\n data-invalid={invalid ? \"\" : undefined}\n data-disabled={disabled ? \"\" : undefined}\n aria-disabled={disabled}\n {...restProps}\n // Ignore onClick handler from Radix, because we use onPointerDown to mimic a native select\n onClick={undefined}\n >\n {StartIcon && <StartIcon className={s.StartIcon} />}\n <span className={s.TriggerText}>{children}</span>\n {hasAnyTertiaryIndicator && (\n <div className={s.IndicatorWrapper}>\n {showClearAction && (\n <Button\n aria-label=\"Clear current value\"\n className={s.Clear}\n onPointerDown={(evt: React.PointerEvent<HTMLButtonElement>) => {\n // Prevent pointerDown on trigger from being captured\n evt.stopPropagation()\n }}\n onClick={(evt) => {\n evt.stopPropagation()\n evt.preventDefault()\n onClearClick()\n }}\n color=\"secondary\"\n variant={hasDropdownIcon ? \"ghost\" : \"solid\"}\n // Mostly custom sizing through variables\n size=\"3xs\"\n uniform\n pill={pill}\n data-only-child={!hasDropdownIcon ? \"\" : undefined}\n >\n <X />\n </Button>\n )}\n {loading && <LoadingIndicator className={s.LoadingIndicator} />}\n {/* Using raw SVG canvases (opposed to fixed icon canvases) led to less pixelation. */}\n {hasDropdownIcon && <DropdownIcon iconType={dropdownIconType} />}\n </div>\n )}\n </span>\n )\n}\n\ntype DropdownIconProps = {\n iconType: Omit<DropdownIconType, \"none\">\n}\n\nexport const DropdownIcon = ({ iconType }: DropdownIconProps) => {\n return iconType === \"chevronDown\" ? (\n <ChevronDown className={clsx(s.DropdownIcon, s.DropdownIconChevron)} />\n ) : (\n <Dropdown className={s.DropdownIcon} />\n )\n}\n"]}
@@ -2,14 +2,14 @@
2
2
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import React, { Children, useCallback, useEffect, useLayoutEffect, useReducer, useRef, useState, } from "react";
4
4
  import { mergeRefs } from "react-merge-refs";
5
- import { waitForAnimationFrame } from "../../lib/helpers.js";
5
+ import { prefersReducedMotion, waitForAnimationFrame } from "../../lib/helpers.js";
6
6
  import clsx from "clsx";
7
7
  import { useTimeout } from "usehooks-ts";
8
8
  import getDisableAnimations from "./getDisableAnimations.js";
9
9
  import { assertSingleChildWhenRef, ChildrenWithKeys, computeNextRenderChildren, noop, useChildCallback, } from "./shared.js";
10
10
  import s from "@plexui/styles/components/Transition/TransitionGroup.module.css";
11
11
  import { getInitialTransitionState, transitionReducer } from "./transitionReducer.js";
12
- const TransitionGroupChildInner = ({ ref: forwardedRef, as: TagName, children, className, transitionId, style, preventMountTransition, shouldRender, enterDuration, exitDuration, removeChild, onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete, }) => {
12
+ const TransitionGroupChildInner = ({ ref: forwardedRef, as: TagName, children, className, transitionId, style, preventMountTransition, shouldRender, enterDuration, exitDuration, overlay, removeChild, onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete, }) => {
13
13
  const [state, dispatch] = useReducer(transitionReducer, getInitialTransitionState(preventMountTransition || false));
14
14
  // Allow a child to prevent mount transition, but still experience
15
15
  // future enter transition events, when applicable.
@@ -63,7 +63,7 @@ const TransitionGroupChildInner = ({ ref: forwardedRef, as: TagName, children, c
63
63
  exitTimeout = window.setTimeout(() => {
64
64
  triggerCallback("exit-complete");
65
65
  removeChild();
66
- }, exitDurationRef.current);
66
+ }, overlay && prefersReducedMotion() ? 0 : exitDurationRef.current);
67
67
  });
68
68
  return () => {
69
69
  cancelAnimationFrame();
@@ -98,6 +98,7 @@ const TransitionGroupChildInner = ({ ref: forwardedRef, as: TagName, children, c
98
98
  shouldRender,
99
99
  // This value is immutable after <TransitionGroup> is created, and does not change on re-renders.
100
100
  preventMountTransition,
101
+ overlay,
101
102
  removeChild,
102
103
  triggerCallback,
103
104
  ]);
@@ -108,7 +109,7 @@ const TransitionGroupChildInner = ({ ref: forwardedRef, as: TagName, children, c
108
109
  preventedMountTransition.current = false;
109
110
  };
110
111
  }, []);
111
- return (_jsx(TagName, { ref: mergeRefs([elementRef, forwardedRef]), className: clsx(className, s.TransitionGroupChild), "data-transition-id": transitionId, style: style, "data-entering": state.enter ? "" : undefined, "data-entering-active": state.enterActive ? "" : undefined, "data-exiting": state.exit ? "" : undefined, "data-exiting-active": state.exitActive ? "" : undefined, "data-interrupted": state.interrupted ? "" : undefined, children: children }));
112
+ return (_jsx(TagName, { ref: mergeRefs([elementRef, forwardedRef]), className: clsx(className, s.TransitionGroupChild), "data-transition-id": transitionId, style: style, "data-entering": state.enter ? "" : undefined, "data-entering-active": state.enterActive ? "" : undefined, "data-exiting": state.exit ? "" : undefined, "data-exiting-active": state.exitActive ? "" : undefined, "data-interrupted": state.interrupted ? "" : undefined, inert: overlay && state.exit ? true : undefined, children: children }));
112
113
  };
113
114
  const TransitionGroupChild = (props) => {
114
115
  // Don't spread these out of props - pass all props to inner child
@@ -121,7 +122,7 @@ const TransitionGroupChild = (props) => {
121
122
  return mounted ? _jsx(TransitionGroupChildInner, { ...props }) : null;
122
123
  };
123
124
  export const TransitionGroup = (props) => {
124
- const { ref: forwardedRef, as: TagName = "span", children, className, transitionId, style, enterDuration = 0, exitDuration = 0, preventInitialTransition = true, enterMountDelay, insertMethod = "append", disableAnimations = getDisableAnimations(), } = props;
125
+ const { ref: forwardedRef, as: TagName = "span", children, className, transitionId, style, enterDuration = 0, exitDuration = 0, preventInitialTransition = true, enterMountDelay, insertMethod = "append", disableAnimations = getDisableAnimations(), overlay, } = props;
125
126
  // Create stable, mutable references for all callbacks
126
127
  const onEnter = useChildCallback(props.onEnter ?? noop);
127
128
  const onEnterActive = useChildCallback(props.onEnterActive ?? noop);
@@ -173,6 +174,6 @@ export const TransitionGroup = (props) => {
173
174
  // @ts-expect-error -- TS is not happy about this forwardedRef, but it's fine.
174
175
  ref: forwardedRef, className: className, style: style, "data-transition-id": transitionId, children: child }))) }));
175
176
  }
176
- return (_jsx(_Fragment, { children: renderChildren.map(({ component, ...restProps }) => (_jsx(TransitionGroupChild, { ...restProps, as: TagName, className: className, transitionId: transitionId, enterDuration: enterDuration, exitDuration: exitDuration, enterMountDelay: enterMountDelay, style: style, ref: forwardedRef, children: component }, component.key))) }));
177
+ return (_jsx(_Fragment, { children: renderChildren.map(({ component, ...restProps }) => (_jsx(TransitionGroupChild, { ...restProps, as: TagName, className: className, transitionId: transitionId, enterDuration: enterDuration, exitDuration: exitDuration, enterMountDelay: enterMountDelay, overlay: overlay, style: style, ref: forwardedRef, children: component }, component.key))) }));
177
178
  };
178
179
  //# sourceMappingURL=TransitionGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TransitionGroup.js","sourceRoot":"","sources":["../../../../src/components/Transition/TransitionGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport React, {\n Children,\n useCallback,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { waitForAnimationFrame } from \"../../lib/helpers\"\n\nimport clsx from \"clsx\"\nimport { useTimeout } from \"usehooks-ts\"\nimport getDisableAnimations from \"./getDisableAnimations\"\nimport {\n assertSingleChildWhenRef,\n ChildrenWithKeys,\n computeNextRenderChildren,\n noop,\n useChildCallback,\n type CallbackType,\n type ReactElementWithKey,\n type TransitionGroupChildCallbacks,\n} from \"./shared\"\nimport s from \"@plexui/styles/components/Transition/TransitionGroup.module.css\"\nimport { getInitialTransitionState, transitionReducer } from \"./transitionReducer\"\n\ntype TransitionGroupChildProps = {\n as: \"div\" | \"span\"\n children: React.ReactNode\n className?: string\n transitionId?: string\n style?: CSSProperties\n preventMountTransition?: boolean\n shouldRender: boolean\n enterDuration: number\n exitDuration: number\n enterMountDelay?: number\n removeChild: () => void\n ref?: React.Ref<unknown>\n} & TransitionGroupChildCallbacks\n\nconst TransitionGroupChildInner = ({\n ref: forwardedRef,\n as: TagName,\n children,\n className,\n transitionId,\n style,\n preventMountTransition,\n shouldRender,\n enterDuration,\n exitDuration,\n removeChild,\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n}: TransitionGroupChildProps) => {\n const [state, dispatch] = useReducer(\n transitionReducer,\n getInitialTransitionState(preventMountTransition || false),\n )\n // Allow a child to prevent mount transition, but still experience\n // future enter transition events, when applicable.\n const preventedMountTransition = useRef<boolean>(false)\n const elementRef = useRef<HTMLDivElement | null>(null)\n // Duration values should not affect hook re-renders, so we create refs for them\n const enterDurationRef = useRef<number>(enterDuration)\n enterDurationRef.current = enterDuration\n const exitDurationRef = useRef<number>(exitDuration)\n exitDurationRef.current = exitDuration\n\n const lastCallbackRef = useRef<CallbackType>(null)\n const triggerCallback = useCallback(\n (callbackType: CallbackType) => {\n const element = elementRef.current\n\n if (!element || callbackType === lastCallbackRef.current) {\n return\n }\n\n lastCallbackRef.current = callbackType\n\n switch (callbackType) {\n case \"enter\":\n onEnter(element)\n break\n case \"enter-active\":\n onEnterActive(element)\n break\n case \"enter-complete\":\n onEnterComplete(element)\n break\n case \"exit\":\n onExit(element)\n break\n case \"exit-active\":\n onExitActive(element)\n break\n case \"exit-complete\":\n onExitComplete(element)\n break\n default:\n callbackType satisfies never\n break\n }\n },\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n React.useLayoutEffect(() => {\n // Exit transition\n if (!shouldRender) {\n let exitTimeout: number | undefined\n\n dispatch({ type: \"exit-before\" })\n triggerCallback(\"exit\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"exit-active\" })\n triggerCallback(\"exit-active\")\n\n exitTimeout = window.setTimeout(() => {\n triggerCallback(\"exit-complete\")\n removeChild()\n }, exitDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (exitTimeout !== undefined) clearTimeout(exitTimeout)\n }\n }\n\n // Enter transition\n\n // Check if we need to prevent this specific entering cycle\n if (preventMountTransition && !preventedMountTransition.current) {\n // Mark initial transition as prevented and short-circuit.\n preventedMountTransition.current = true\n return\n }\n\n let enterTimeout: number | undefined\n\n dispatch({ type: \"enter-before\" })\n triggerCallback(\"enter\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"enter-active\" })\n triggerCallback(\"enter-active\")\n\n enterTimeout = window.setTimeout(() => {\n dispatch({ type: \"done\" })\n triggerCallback(\"enter-complete\")\n }, enterDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (enterTimeout !== undefined) clearTimeout(enterTimeout)\n }\n }, [\n shouldRender,\n // This value is immutable after <TransitionGroup> is created, and does not change on re-renders.\n preventMountTransition,\n removeChild,\n triggerCallback,\n ])\n\n useEffect(() => {\n // Required for <StrictMode>, because we need to unset this token\n // when the hooks are re-run. It's an imperative effect that we need to manage.\n return () => {\n preventedMountTransition.current = false\n }\n }, [])\n\n return (\n <TagName\n ref={mergeRefs([elementRef, forwardedRef])}\n className={clsx(className, s.TransitionGroupChild)}\n data-transition-id={transitionId}\n style={style}\n data-entering={state.enter ? \"\" : undefined}\n data-entering-active={state.enterActive ? \"\" : undefined}\n data-exiting={state.exit ? \"\" : undefined}\n data-exiting-active={state.exitActive ? \"\" : undefined}\n data-interrupted={state.interrupted ? \"\" : undefined}\n >\n {children}\n </TagName>\n )\n}\n\nconst TransitionGroupChild = (props: TransitionGroupChildProps) => {\n // Don't spread these out of props - pass all props to inner child\n const { enterMountDelay, preventMountTransition } = props\n // Mount gating occurs when enterMountDelay exists, and isn't initial mount\n // Otherwise, this flag is a no-op and the TransitionChild mounts normally.\n const mountDelay = !preventMountTransition && enterMountDelay != null ? enterMountDelay : null\n const [mounted, setMounted] = useState(mountDelay == null)\n useTimeout(() => setMounted(true), mounted ? null : mountDelay)\n\n return mounted ? <TransitionGroupChildInner {...props} /> : null\n}\n\nexport type TransitionGroupProps = {\n /** Components controlled by TransitionGroup rendering */\n children: React.ReactNode\n /** Determines the tag used by wrapping elements */\n as?: \"div\" | \"span\"\n /** Class passed to wrapping elements */\n className?: string\n /** Identifier passed to wrapping elements as `[data-transition-id]` */\n transitionId?: string\n /** Determines the amount of time that the enter state is applied during mounting */\n enterDuration?: number\n /** Determines the amount of time that the exit state is applied before unmounting */\n exitDuration?: number\n /**\n * Determines if children should have an enter transition applied during mounting of the TransitionGroup.\n * @default true\n */\n preventInitialTransition?: boolean\n /** Delay in MS to wait before mounting a child. `null` for no delay (default). */\n enterMountDelay?: number\n /** Render children changes immediately, bypassing transition timings */\n disableAnimations?: boolean\n /** Determines how new children are added to the children array */\n insertMethod?: \"append\" | \"prepend\"\n /** Styles applied to wrapping elements */\n style?: CSSProperties\n /** Ref for the TransitionGroup */\n ref?: React.Ref<unknown>\n} & Partial<TransitionGroupChildCallbacks>\n\ntype RenderChild = {\n component: ReactElementWithKey\n shouldRender: boolean\n preventMountTransition?: boolean\n removeChild: () => void\n} & TransitionGroupChildCallbacks\n\nexport const TransitionGroup = (props: TransitionGroupProps) => {\n const {\n ref: forwardedRef,\n as: TagName = \"span\",\n children,\n className,\n transitionId,\n style,\n enterDuration = 0,\n exitDuration = 0,\n preventInitialTransition = true,\n enterMountDelay,\n insertMethod = \"append\",\n disableAnimations = getDisableAnimations(),\n } = props\n // Create stable, mutable references for all callbacks\n const onEnter = useChildCallback(props.onEnter ?? noop)\n const onEnterActive = useChildCallback(props.onEnterActive ?? noop)\n const onEnterComplete = useChildCallback(props.onEnterComplete ?? noop)\n const onExit = useChildCallback(props.onExit ?? noop)\n const onExitActive = useChildCallback(props.onExitActive ?? noop)\n const onExitComplete = useChildCallback(props.onExitComplete ?? noop)\n\n // Ensure all children are provided with keys.\n // Cannot reliably use Children.toArray() because `key` is processed: https://reactjs.org/docs/react-api.html#reactchildrentoarray\n Children.forEach(children, (child) => {\n // @ts-expect-error - We know `key` might not exist on certain types, that's why we're checking\n if (child && !child.key) {\n throw new Error(\"Child elements of <TransitionGroup /> must include a `key`\")\n }\n })\n\n const createDefaultRenderChildProps = useCallback(\n (child: ReactElementWithKey): RenderChild => ({\n component: child,\n shouldRender: true,\n removeChild: () => {\n setRenderChildren((currentRenderChildren) =>\n currentRenderChildren.filter((c) => child.key !== c.component.key),\n )\n },\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n }),\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n const [renderChildren, setRenderChildren] = useState<RenderChild[]>((): RenderChild[] => {\n return ChildrenWithKeys(children).map((child) => ({\n ...createDefaultRenderChildProps(child),\n // Lock this value to whatever the value was on initial render of the TransitionGroup.\n // It doesn't make sense to change this once it is mounted.\n preventMountTransition: preventInitialTransition,\n }))\n })\n\n useLayoutEffect(() => {\n setRenderChildren((currentRenderChildren): RenderChild[] => {\n const propChildrenArray = ChildrenWithKeys(children)\n return computeNextRenderChildren(\n propChildrenArray,\n currentRenderChildren,\n createDefaultRenderChildProps,\n insertMethod,\n )\n })\n }, [children, insertMethod, createDefaultRenderChildProps])\n\n // Prevent mistakes with forwardRef() by ensuring single child usage within the group.\n assertSingleChildWhenRef(\"TransitionGroup\", forwardedRef, Children.count(children))\n\n if (disableAnimations) {\n return (\n <>\n {Children.map(children, (child) => (\n <TagName\n // @ts-expect-error -- TS is not happy about this forwardedRef, but it's fine.\n ref={forwardedRef}\n className={className}\n style={style}\n data-transition-id={transitionId}\n >\n {child}\n </TagName>\n ))}\n </>\n )\n }\n\n return (\n <>\n {renderChildren.map(({ component, ...restProps }) => (\n <TransitionGroupChild\n key={component.key}\n {...restProps}\n as={TagName}\n className={className}\n transitionId={transitionId}\n enterDuration={enterDuration}\n exitDuration={exitDuration}\n enterMountDelay={enterMountDelay}\n style={style}\n ref={forwardedRef}\n >\n {component}\n </TransitionGroupChild>\n ))}\n </>\n )\n}\n"]}
1
+ {"version":3,"file":"TransitionGroup.js","sourceRoot":"","sources":["../../../../src/components/Transition/TransitionGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport React, {\n Children,\n useCallback,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\n\nimport { prefersReducedMotion, waitForAnimationFrame } from \"../../lib/helpers\"\n\nimport clsx from \"clsx\"\nimport { useTimeout } from \"usehooks-ts\"\nimport getDisableAnimations from \"./getDisableAnimations\"\nimport {\n assertSingleChildWhenRef,\n ChildrenWithKeys,\n computeNextRenderChildren,\n noop,\n useChildCallback,\n type CallbackType,\n type ReactElementWithKey,\n type TransitionGroupChildCallbacks,\n} from \"./shared\"\nimport s from \"@plexui/styles/components/Transition/TransitionGroup.module.css\"\nimport { getInitialTransitionState, transitionReducer } from \"./transitionReducer\"\n\ntype TransitionGroupChildProps = {\n as: \"div\" | \"span\"\n children: React.ReactNode\n className?: string\n transitionId?: string\n style?: CSSProperties\n preventMountTransition?: boolean\n shouldRender: boolean\n enterDuration: number\n exitDuration: number\n enterMountDelay?: number\n overlay?: boolean\n removeChild: () => void\n ref?: React.Ref<unknown>\n} & TransitionGroupChildCallbacks\n\nconst TransitionGroupChildInner = ({\n ref: forwardedRef,\n as: TagName,\n children,\n className,\n transitionId,\n style,\n preventMountTransition,\n shouldRender,\n enterDuration,\n exitDuration,\n overlay,\n removeChild,\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n}: TransitionGroupChildProps) => {\n const [state, dispatch] = useReducer(\n transitionReducer,\n getInitialTransitionState(preventMountTransition || false),\n )\n // Allow a child to prevent mount transition, but still experience\n // future enter transition events, when applicable.\n const preventedMountTransition = useRef<boolean>(false)\n const elementRef = useRef<HTMLDivElement | null>(null)\n // Duration values should not affect hook re-renders, so we create refs for them\n const enterDurationRef = useRef<number>(enterDuration)\n enterDurationRef.current = enterDuration\n const exitDurationRef = useRef<number>(exitDuration)\n exitDurationRef.current = exitDuration\n\n const lastCallbackRef = useRef<CallbackType>(null)\n const triggerCallback = useCallback(\n (callbackType: CallbackType) => {\n const element = elementRef.current\n\n if (!element || callbackType === lastCallbackRef.current) {\n return\n }\n\n lastCallbackRef.current = callbackType\n\n switch (callbackType) {\n case \"enter\":\n onEnter(element)\n break\n case \"enter-active\":\n onEnterActive(element)\n break\n case \"enter-complete\":\n onEnterComplete(element)\n break\n case \"exit\":\n onExit(element)\n break\n case \"exit-active\":\n onExitActive(element)\n break\n case \"exit-complete\":\n onExitComplete(element)\n break\n default:\n callbackType satisfies never\n break\n }\n },\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n React.useLayoutEffect(() => {\n // Exit transition\n if (!shouldRender) {\n let exitTimeout: number | undefined\n\n dispatch({ type: \"exit-before\" })\n triggerCallback(\"exit\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"exit-active\" })\n triggerCallback(\"exit-active\")\n\n exitTimeout = window.setTimeout(\n () => {\n triggerCallback(\"exit-complete\")\n removeChild()\n },\n overlay && prefersReducedMotion() ? 0 : exitDurationRef.current,\n )\n })\n\n return () => {\n cancelAnimationFrame()\n if (exitTimeout !== undefined) clearTimeout(exitTimeout)\n }\n }\n\n // Enter transition\n\n // Check if we need to prevent this specific entering cycle\n if (preventMountTransition && !preventedMountTransition.current) {\n // Mark initial transition as prevented and short-circuit.\n preventedMountTransition.current = true\n return\n }\n\n let enterTimeout: number | undefined\n\n dispatch({ type: \"enter-before\" })\n triggerCallback(\"enter\")\n\n const cancelAnimationFrame = waitForAnimationFrame(() => {\n dispatch({ type: \"enter-active\" })\n triggerCallback(\"enter-active\")\n\n enterTimeout = window.setTimeout(() => {\n dispatch({ type: \"done\" })\n triggerCallback(\"enter-complete\")\n }, enterDurationRef.current)\n })\n\n return () => {\n cancelAnimationFrame()\n if (enterTimeout !== undefined) clearTimeout(enterTimeout)\n }\n }, [\n shouldRender,\n // This value is immutable after <TransitionGroup> is created, and does not change on re-renders.\n preventMountTransition,\n overlay,\n removeChild,\n triggerCallback,\n ])\n\n useEffect(() => {\n // Required for <StrictMode>, because we need to unset this token\n // when the hooks are re-run. It's an imperative effect that we need to manage.\n return () => {\n preventedMountTransition.current = false\n }\n }, [])\n\n return (\n <TagName\n ref={mergeRefs([elementRef, forwardedRef])}\n className={clsx(className, s.TransitionGroupChild)}\n data-transition-id={transitionId}\n style={style}\n data-entering={state.enter ? \"\" : undefined}\n data-entering-active={state.enterActive ? \"\" : undefined}\n data-exiting={state.exit ? \"\" : undefined}\n data-exiting-active={state.exitActive ? \"\" : undefined}\n data-interrupted={state.interrupted ? \"\" : undefined}\n inert={overlay && state.exit ? true : undefined}\n >\n {children}\n </TagName>\n )\n}\n\nconst TransitionGroupChild = (props: TransitionGroupChildProps) => {\n // Don't spread these out of props - pass all props to inner child\n const { enterMountDelay, preventMountTransition } = props\n // Mount gating occurs when enterMountDelay exists, and isn't initial mount\n // Otherwise, this flag is a no-op and the TransitionChild mounts normally.\n const mountDelay = !preventMountTransition && enterMountDelay != null ? enterMountDelay : null\n const [mounted, setMounted] = useState(mountDelay == null)\n useTimeout(() => setMounted(true), mounted ? null : mountDelay)\n\n return mounted ? <TransitionGroupChildInner {...props} /> : null\n}\n\nexport type TransitionGroupProps = {\n /** Components controlled by TransitionGroup rendering */\n children: React.ReactNode\n /** Determines the tag used by wrapping elements */\n as?: \"div\" | \"span\"\n /** Class passed to wrapping elements */\n className?: string\n /** Identifier passed to wrapping elements as `[data-transition-id]` */\n transitionId?: string\n /** Determines the amount of time that the enter state is applied during mounting */\n enterDuration?: number\n /** Determines the amount of time that the exit state is applied before unmounting */\n exitDuration?: number\n /**\n * Determines if children should have an enter transition applied during mounting of the TransitionGroup.\n * @default true\n */\n preventInitialTransition?: boolean\n /** Delay in MS to wait before mounting a child. `null` for no delay (default). */\n enterMountDelay?: number\n /** Render children changes immediately, bypassing transition timings */\n disableAnimations?: boolean\n /**\n * For overlays: an exiting child is `inert`, out of the tab order and of hit\n * testing, and with reduced motion it leaves without waiting for `exitDuration`.\n */\n overlay?: boolean\n /** Determines how new children are added to the children array */\n insertMethod?: \"append\" | \"prepend\"\n /** Styles applied to wrapping elements */\n style?: CSSProperties\n /** Ref for the TransitionGroup */\n ref?: React.Ref<unknown>\n} & Partial<TransitionGroupChildCallbacks>\n\ntype RenderChild = {\n component: ReactElementWithKey\n shouldRender: boolean\n preventMountTransition?: boolean\n removeChild: () => void\n} & TransitionGroupChildCallbacks\n\nexport const TransitionGroup = (props: TransitionGroupProps) => {\n const {\n ref: forwardedRef,\n as: TagName = \"span\",\n children,\n className,\n transitionId,\n style,\n enterDuration = 0,\n exitDuration = 0,\n preventInitialTransition = true,\n enterMountDelay,\n insertMethod = \"append\",\n disableAnimations = getDisableAnimations(),\n overlay,\n } = props\n // Create stable, mutable references for all callbacks\n const onEnter = useChildCallback(props.onEnter ?? noop)\n const onEnterActive = useChildCallback(props.onEnterActive ?? noop)\n const onEnterComplete = useChildCallback(props.onEnterComplete ?? noop)\n const onExit = useChildCallback(props.onExit ?? noop)\n const onExitActive = useChildCallback(props.onExitActive ?? noop)\n const onExitComplete = useChildCallback(props.onExitComplete ?? noop)\n\n // Ensure all children are provided with keys.\n // Cannot reliably use Children.toArray() because `key` is processed: https://reactjs.org/docs/react-api.html#reactchildrentoarray\n Children.forEach(children, (child) => {\n // @ts-expect-error - We know `key` might not exist on certain types, that's why we're checking\n if (child && !child.key) {\n throw new Error(\"Child elements of <TransitionGroup /> must include a `key`\")\n }\n })\n\n const createDefaultRenderChildProps = useCallback(\n (child: ReactElementWithKey): RenderChild => ({\n component: child,\n shouldRender: true,\n removeChild: () => {\n setRenderChildren((currentRenderChildren) =>\n currentRenderChildren.filter((c) => child.key !== c.component.key),\n )\n },\n onEnter,\n onEnterActive,\n onEnterComplete,\n onExit,\n onExitActive,\n onExitComplete,\n }),\n [onEnter, onEnterActive, onEnterComplete, onExit, onExitActive, onExitComplete],\n )\n\n const [renderChildren, setRenderChildren] = useState<RenderChild[]>((): RenderChild[] => {\n return ChildrenWithKeys(children).map((child) => ({\n ...createDefaultRenderChildProps(child),\n // Lock this value to whatever the value was on initial render of the TransitionGroup.\n // It doesn't make sense to change this once it is mounted.\n preventMountTransition: preventInitialTransition,\n }))\n })\n\n useLayoutEffect(() => {\n setRenderChildren((currentRenderChildren): RenderChild[] => {\n const propChildrenArray = ChildrenWithKeys(children)\n return computeNextRenderChildren(\n propChildrenArray,\n currentRenderChildren,\n createDefaultRenderChildProps,\n insertMethod,\n )\n })\n }, [children, insertMethod, createDefaultRenderChildProps])\n\n // Prevent mistakes with forwardRef() by ensuring single child usage within the group.\n assertSingleChildWhenRef(\"TransitionGroup\", forwardedRef, Children.count(children))\n\n if (disableAnimations) {\n return (\n <>\n {Children.map(children, (child) => (\n <TagName\n // @ts-expect-error -- TS is not happy about this forwardedRef, but it's fine.\n ref={forwardedRef}\n className={className}\n style={style}\n data-transition-id={transitionId}\n >\n {child}\n </TagName>\n ))}\n </>\n )\n }\n\n return (\n <>\n {renderChildren.map(({ component, ...restProps }) => (\n <TransitionGroupChild\n key={component.key}\n {...restProps}\n as={TagName}\n className={className}\n transitionId={transitionId}\n enterDuration={enterDuration}\n exitDuration={exitDuration}\n enterMountDelay={enterMountDelay}\n overlay={overlay}\n style={style}\n ref={forwardedRef}\n >\n {component}\n </TransitionGroupChild>\n ))}\n </>\n )\n}\n"]}
@@ -15,6 +15,36 @@ export const ChildrenWithKeys = (children, shouldThrow = false, componentName =
15
15
  return validChildren;
16
16
  };
17
17
  export const noop = () => { };
18
+ // Overlay timers, in step with the `--motion-*` tokens
19
+ export const overlayTiming = { enterDuration: 250, exitDuration: 150 };
20
+ /** A panel that crosses the screen: a sheet or a side panel */
21
+ export const overlayTimingLarge = { enterDuration: 300, exitDuration: 200 };
22
+ /**
23
+ * An overlay stays a dismissable layer through its exit. A press on its trigger
24
+ * turns it around, and the layer must not count that press as outside and
25
+ * close it again: pass `transition` to the TransitionGroup and
26
+ * `onInteractOutside` to the layer.
27
+ */
28
+ export const createExitGuard = () => {
29
+ let exiting = false;
30
+ return {
31
+ transition: {
32
+ onExit: () => {
33
+ exiting = true;
34
+ },
35
+ onEnterActive: () => {
36
+ exiting = false;
37
+ },
38
+ onExitComplete: () => {
39
+ exiting = false;
40
+ },
41
+ },
42
+ onInteractOutside: (event) => {
43
+ if (exiting)
44
+ event.preventDefault();
45
+ },
46
+ };
47
+ };
18
48
  export const useChildCallback = (cb) => {
19
49
  const ref = useRef(cb);
20
50
  ref.current = cb;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/components/Transition/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import React, { Children, useCallback, useRef } from \"react\"\nimport { isDev, isTest } from \"../../lib/constants\"\n\nexport type TransitionDefinition = {\n opacity?: number\n /** The horizontal translation value in pixels */\n x?: number\n /** The horizontal vertical value in pixels */\n y?: number\n /** The opacity value ranging from 0 to 1. */\n scale?: number\n rotate?: number | string\n skewX?: number | string\n skewY?: number | string\n blur?: number\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type InitialTransitionDefinition = Omit<\n TransitionDefinition,\n \"duration\" | \"delay\" | \"timingFunction\"\n>\n\nexport type LayoutTransitionDefinition = {\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type CallbackType =\n | \"enter\"\n | \"enter-active\"\n | \"enter-complete\"\n | \"exit\"\n | \"exit-active\"\n | \"exit-complete\"\n\n// Transition callbacks and types shared across implementations\nexport type TransitionGroupChildCallback = (element: HTMLDivElement) => void\n\nexport type TransitionGroupChildCallbacks = {\n /** Callback fired when an enter animation is staged (e.g., component mounted to the DOM) */\n onEnter: TransitionGroupChildCallback\n /** Callback fired when an enter animation starts */\n onEnterActive: TransitionGroupChildCallback\n /** Callback fired when an enter animation completes */\n onEnterComplete: TransitionGroupChildCallback\n /** Callback fired when an exit animation is staged */\n onExit: TransitionGroupChildCallback\n /** Callback fired when an exit animation starts */\n onExitActive: TransitionGroupChildCallback\n /** Callback fired when an exit animation completes (e.g., component unmounted from the DOM) */\n onExitComplete: TransitionGroupChildCallback\n}\n\nexport const NonNullChildren = (children: React.ReactNode) =>\n Children.toArray(children).filter((child) => child !== null && child !== undefined)\n\n// Shared keyed-children and transition helpers\nexport interface ReactElementWithKey extends React.ReactElement {\n key: string\n}\n\nexport const ChildrenWithKeys = (\n children: React.ReactNode,\n shouldThrow: boolean = false,\n componentName: string = \"TransitionGroup\",\n): ReactElementWithKey[] => {\n const validChildren: ReactElementWithKey[] = []\n Children.forEach(children, (child) => {\n if (child && typeof child === \"object\" && \"key\" in child && !!child.key) {\n // @ts-expect-error -- The above conditional is enough coercion that the component is valid\n validChildren.push(child)\n } else if (shouldThrow) {\n throw new Error(`Child elements of <${componentName} /> must include a \\`key\\``)\n }\n })\n return validChildren\n}\n\nexport const noop = () => {}\n\nexport const useChildCallback = (cb: (el: HTMLDivElement) => void) => {\n const ref = useRef(cb)\n ref.current = cb\n return useCallback<(el: HTMLDivElement) => void>((element) => ref.current(element), [])\n}\n\nexport type InsertMethod = \"append\" | \"prepend\"\n\nexport function computeNextRenderChildren<\n RenderChild extends { component: ReactElementWithKey; shouldRender: boolean },\n>(\n propChildrenArray: ReactElementWithKey[],\n currentRenderChildren: RenderChild[],\n createDefaultRenderChildProps: (child: ReactElementWithKey) => RenderChild,\n insertMethod: InsertMethod,\n): RenderChild[] {\n // Sets, not plain objects: a key such as \"constructor\" must not match an\n // inherited Object property\n const propChildKeys = new Set(propChildrenArray.map((child) => child.key))\n const currentRenderChildKeys = new Set(currentRenderChildren.map((child) => child.component.key))\n\n const newRenderChildren: RenderChild[] = propChildrenArray\n .filter((propChild) => !currentRenderChildKeys.has(propChild.key))\n .map(createDefaultRenderChildProps)\n\n const updatedCurrentChildren: RenderChild[] = currentRenderChildren.map((childProps) => ({\n ...childProps,\n component:\n propChildrenArray.find(({ key }) => key === childProps.component.key) || childProps.component,\n shouldRender: propChildKeys.has(childProps.component.key),\n }))\n\n return insertMethod === \"append\"\n ? updatedCurrentChildren.concat(newRenderChildren)\n : newRenderChildren.concat(updatedCurrentChildren)\n}\n\nexport function assertSingleChildWhenRef(\n componentName: string,\n ref: React.Ref<unknown> | undefined,\n childrenCount: number,\n): void {\n if ((isTest || isDev) && ref && childrenCount > 1) {\n throw new Error(`Cannot use forwardRef with multiple children in <${componentName} />`)\n }\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/components/Transition/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAwDnD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAyB,EAAE,EAAE,CAC3D,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAA;AAOrF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,QAAyB,EACzB,cAAuB,KAAK,EAC5B,gBAAwB,iBAAiB,EAClB,EAAE;IACzB,MAAM,aAAa,GAA0B,EAAE,CAAA;IAC/C,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;QACnC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACxE,2FAA2F;YAC3F,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,sBAAsB,aAAa,4BAA4B,CAAC,CAAA;QAClF,CAAC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;AAE5B,uDAAuD;AACvD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAA;AACtE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAA;AAE3E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,OAAO;QACL,UAAU,EAAE;YACV,MAAM,EAAE,GAAG,EAAE;gBACX,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;YACD,aAAa,EAAE,GAAG,EAAE;gBAClB,OAAO,GAAG,KAAK,CAAA;YACjB,CAAC;YACD,cAAc,EAAE,GAAG,EAAE;gBACnB,OAAO,GAAG,KAAK,CAAA;YACjB,CAAC;SACF;QACD,iBAAiB,EAAE,CAAC,KAAY,EAAE,EAAE;YAClC,IAAI,OAAO;gBAAE,KAAK,CAAC,cAAc,EAAE,CAAA;QACrC,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAgC,EAAE,EAAE;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;IACtB,GAAG,CAAC,OAAO,GAAG,EAAE,CAAA;IAChB,OAAO,WAAW,CAA+B,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;AACzF,CAAC,CAAA;AAID,MAAM,UAAU,yBAAyB,CAGvC,iBAAwC,EACxC,qBAAoC,EACpC,6BAA0E,EAC1E,YAA0B;IAE1B,yEAAyE;IACzE,4BAA4B;IAC5B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1E,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAEjG,MAAM,iBAAiB,GAAkB,iBAAiB;SACvD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;SACjE,GAAG,CAAC,6BAA6B,CAAC,CAAA;IAErC,MAAM,sBAAsB,GAAkB,qBAAqB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACvF,GAAG,UAAU;QACb,SAAS,EACP,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,SAAS;QAC/F,YAAY,EAAE,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC;KAC1D,CAAC,CAAC,CAAA;IAEH,OAAO,YAAY,KAAK,QAAQ;QAC9B,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAClD,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,aAAqB,EACrB,GAAmC,EACnC,aAAqB;IAErB,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,oDAAoD,aAAa,KAAK,CAAC,CAAA;IACzF,CAAC;AACH,CAAC","sourcesContent":["import React, { Children, useCallback, useRef } from \"react\"\nimport { isDev, isTest } from \"../../lib/constants\"\n\nexport type TransitionDefinition = {\n opacity?: number\n /** The horizontal translation value in pixels */\n x?: number\n /** The horizontal vertical value in pixels */\n y?: number\n /** The opacity value ranging from 0 to 1. */\n scale?: number\n rotate?: number | string\n skewX?: number | string\n skewY?: number | string\n blur?: number\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type InitialTransitionDefinition = Omit<\n TransitionDefinition,\n \"duration\" | \"delay\" | \"timingFunction\"\n>\n\nexport type LayoutTransitionDefinition = {\n duration?: number\n delay?: number\n timingFunction?: string\n}\n\nexport type CallbackType =\n | \"enter\"\n | \"enter-active\"\n | \"enter-complete\"\n | \"exit\"\n | \"exit-active\"\n | \"exit-complete\"\n\n// Transition callbacks and types shared across implementations\nexport type TransitionGroupChildCallback = (element: HTMLDivElement) => void\n\nexport type TransitionGroupChildCallbacks = {\n /** Callback fired when an enter animation is staged (e.g., component mounted to the DOM) */\n onEnter: TransitionGroupChildCallback\n /** Callback fired when an enter animation starts */\n onEnterActive: TransitionGroupChildCallback\n /** Callback fired when an enter animation completes */\n onEnterComplete: TransitionGroupChildCallback\n /** Callback fired when an exit animation is staged */\n onExit: TransitionGroupChildCallback\n /** Callback fired when an exit animation starts */\n onExitActive: TransitionGroupChildCallback\n /** Callback fired when an exit animation completes (e.g., component unmounted from the DOM) */\n onExitComplete: TransitionGroupChildCallback\n}\n\nexport const NonNullChildren = (children: React.ReactNode) =>\n Children.toArray(children).filter((child) => child !== null && child !== undefined)\n\n// Shared keyed-children and transition helpers\nexport interface ReactElementWithKey extends React.ReactElement {\n key: string\n}\n\nexport const ChildrenWithKeys = (\n children: React.ReactNode,\n shouldThrow: boolean = false,\n componentName: string = \"TransitionGroup\",\n): ReactElementWithKey[] => {\n const validChildren: ReactElementWithKey[] = []\n Children.forEach(children, (child) => {\n if (child && typeof child === \"object\" && \"key\" in child && !!child.key) {\n // @ts-expect-error -- The above conditional is enough coercion that the component is valid\n validChildren.push(child)\n } else if (shouldThrow) {\n throw new Error(`Child elements of <${componentName} /> must include a \\`key\\``)\n }\n })\n return validChildren\n}\n\nexport const noop = () => {}\n\n// Overlay timers, in step with the `--motion-*` tokens\nexport const overlayTiming = { enterDuration: 250, exitDuration: 150 }\n/** A panel that crosses the screen: a sheet or a side panel */\nexport const overlayTimingLarge = { enterDuration: 300, exitDuration: 200 }\n\n/**\n * An overlay stays a dismissable layer through its exit. A press on its trigger\n * turns it around, and the layer must not count that press as outside and\n * close it again: pass `transition` to the TransitionGroup and\n * `onInteractOutside` to the layer.\n */\nexport const createExitGuard = () => {\n let exiting = false\n return {\n transition: {\n onExit: () => {\n exiting = true\n },\n onEnterActive: () => {\n exiting = false\n },\n onExitComplete: () => {\n exiting = false\n },\n },\n onInteractOutside: (event: Event) => {\n if (exiting) event.preventDefault()\n },\n }\n}\n\nexport const useChildCallback = (cb: (el: HTMLDivElement) => void) => {\n const ref = useRef(cb)\n ref.current = cb\n return useCallback<(el: HTMLDivElement) => void>((element) => ref.current(element), [])\n}\n\nexport type InsertMethod = \"append\" | \"prepend\"\n\nexport function computeNextRenderChildren<\n RenderChild extends { component: ReactElementWithKey; shouldRender: boolean },\n>(\n propChildrenArray: ReactElementWithKey[],\n currentRenderChildren: RenderChild[],\n createDefaultRenderChildProps: (child: ReactElementWithKey) => RenderChild,\n insertMethod: InsertMethod,\n): RenderChild[] {\n // Sets, not plain objects: a key such as \"constructor\" must not match an\n // inherited Object property\n const propChildKeys = new Set(propChildrenArray.map((child) => child.key))\n const currentRenderChildKeys = new Set(currentRenderChildren.map((child) => child.component.key))\n\n const newRenderChildren: RenderChild[] = propChildrenArray\n .filter((propChild) => !currentRenderChildKeys.has(propChild.key))\n .map(createDefaultRenderChildProps)\n\n const updatedCurrentChildren: RenderChild[] = currentRenderChildren.map((childProps) => ({\n ...childProps,\n component:\n propChildrenArray.find(({ key }) => key === childProps.component.key) || childProps.component,\n shouldRender: propChildKeys.has(childProps.component.key),\n }))\n\n return insertMethod === \"append\"\n ? updatedCurrentChildren.concat(newRenderChildren)\n : newRenderChildren.concat(updatedCurrentChildren)\n}\n\nexport function assertSingleChildWhenRef(\n componentName: string,\n ref: React.Ref<unknown> | undefined,\n childrenCount: number,\n): void {\n if ((isTest || isDev) && ref && childrenCount > 1) {\n throw new Error(`Cannot use forwardRef with multiple children in <${componentName} />`)\n }\n}\n"]}
@@ -28,6 +28,11 @@ export const isSameDay = (targetDate, compareDate) => targetDate.hasSame(compare
28
28
  * Check if a date is today
29
29
  */
30
30
  export const isToday = (dateTime) => isSameDay(dateTime, DateTime.local());
31
+ /**
32
+ * Where a date sits in a week row that starts on `weekStartsOn`, 0 (Sunday) to
33
+ * 6 (Saturday). Luxon's weekday runs from 1 (Monday) to 7 (Sunday).
34
+ */
35
+ export const weekPosition = (date, weekStartsOn) => (date.weekday - weekStartsOn + 7) % 7;
31
36
  /**
32
37
  * Split an array of days into weeks (arrays of 7 days each)
33
38
  */
@@ -1 +1 @@
1
- {"version":3,"file":"dateUtils.js","sourceRoot":"","sources":["../../../src/lib/dateUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAc,EAAc,EAAE;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,EAAE,CAAA,CAAC,mCAAmC;IACtF,MAAM,IAAI,GAAG,EAAE,CAAA;IAEf,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC/D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAC/E,UAAU,CAAC,QAAQ,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAC9E,UAAU,CAAC,QAAQ,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAChF,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;AAExC;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAkB,EAAW,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;AAE7F;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAuB,EAAE,IAAI,GAAG,CAAC,EAAgB,EAAE;IAChF,MAAM,KAAK,GAAG,EAAE,CAAA;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,IAAc,EACd,EAAE,GAAG,EAAE,GAAG,KAAyC,EAAE,EAC/B,EAAE;IACxB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEtC,OAAO;QACL,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY;QACpD,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU;KACjD,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { DateTime } from \"luxon\"\n\n/**\n * Get all days in a given month as DateTime objects\n */\nexport const getDaysOfMonth = (date: DateTime): DateTime[] => {\n const startOfMonth = date.startOf(\"month\")\n const daysInMonth = startOfMonth.daysInMonth ?? 31 // fallback to 31 days if undefined\n const days = []\n\n for (let day = 0; day < daysInMonth; day++) {\n const dayDate = startOfMonth.plus({ days: day }).startOf(\"day\")\n days.push(dayDate)\n }\n\n return days\n}\n\n/**\n * Check if the first date is before the second date\n */\nexport const isBefore = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.toMillis() < compareDate?.toMillis()\n\n/**\n * Check if the first date is after the second date\n */\nexport const isAfter = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.toMillis() > compareDate?.toMillis()\n\n/**\n * Check if two dates are the same day (ignoring time)\n */\nexport const isSameDay = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.hasSame(compareDate, \"day\")\n\n/**\n * Check if a date is today\n */\nexport const isToday = (dateTime: DateTime): boolean => isSameDay(dateTime, DateTime.local())\n\n/**\n * Split an array of days into weeks (arrays of 7 days each)\n */\nexport const chunkIntoWeeks = (daysInMonth: DateTime[], size = 7): DateTime[][] => {\n const weeks = []\n for (let i = 0; i < daysInMonth.length; i += size) {\n weeks.push(daysInMonth.slice(i, i + size))\n }\n return weeks\n}\n\n/**\n * Get the start and end date of the month the provided date is in, with optional min and max limits.\n */\nexport const getMonthStartAndEnd = (\n date: DateTime,\n { min, max }: { min?: DateTime; max?: DateTime } = {},\n): [DateTime, DateTime] => {\n const startOfMonth = date.startOf(\"month\")\n const endOfMonth = date.endOf(\"month\")\n\n return [\n min ? DateTime.max(min, startOfMonth) : startOfMonth,\n max ? DateTime.min(max, endOfMonth) : endOfMonth,\n ]\n}\n"]}
1
+ {"version":3,"file":"dateUtils.js","sourceRoot":"","sources":["../../../src/lib/dateUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAc,EAAc,EAAE;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,EAAE,CAAA,CAAC,mCAAmC;IACtF,MAAM,IAAI,GAAG,EAAE,CAAA;IAEf,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC/D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAC/E,UAAU,CAAC,QAAQ,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAC9E,UAAU,CAAC,QAAQ,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAoB,EAAE,WAAqB,EAAW,EAAE,CAChF,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;AAExC;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAkB,EAAW,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAc,EAAE,YAAoB,EAAU,EAAE,CAC3E,CAAC,IAAI,CAAC,OAAO,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;AAEvC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAuB,EAAE,IAAI,GAAG,CAAC,EAAgB,EAAE;IAChF,MAAM,KAAK,GAAG,EAAE,CAAA;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IAC5C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,IAAc,EACd,EAAE,GAAG,EAAE,GAAG,KAAyC,EAAE,EAC/B,EAAE;IACxB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAEtC,OAAO;QACL,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY;QACpD,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU;KACjD,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { DateTime } from \"luxon\"\n\n/**\n * Get all days in a given month as DateTime objects\n */\nexport const getDaysOfMonth = (date: DateTime): DateTime[] => {\n const startOfMonth = date.startOf(\"month\")\n const daysInMonth = startOfMonth.daysInMonth ?? 31 // fallback to 31 days if undefined\n const days = []\n\n for (let day = 0; day < daysInMonth; day++) {\n const dayDate = startOfMonth.plus({ days: day }).startOf(\"day\")\n days.push(dayDate)\n }\n\n return days\n}\n\n/**\n * Check if the first date is before the second date\n */\nexport const isBefore = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.toMillis() < compareDate?.toMillis()\n\n/**\n * Check if the first date is after the second date\n */\nexport const isAfter = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.toMillis() > compareDate?.toMillis()\n\n/**\n * Check if two dates are the same day (ignoring time)\n */\nexport const isSameDay = (targetDate: DateTime, compareDate: DateTime): boolean =>\n targetDate.hasSame(compareDate, \"day\")\n\n/**\n * Check if a date is today\n */\nexport const isToday = (dateTime: DateTime): boolean => isSameDay(dateTime, DateTime.local())\n\n/**\n * Where a date sits in a week row that starts on `weekStartsOn`, 0 (Sunday) to\n * 6 (Saturday). Luxon's weekday runs from 1 (Monday) to 7 (Sunday).\n */\nexport const weekPosition = (date: DateTime, weekStartsOn: number): number =>\n (date.weekday - weekStartsOn + 7) % 7\n\n/**\n * Split an array of days into weeks (arrays of 7 days each)\n */\nexport const chunkIntoWeeks = (daysInMonth: DateTime[], size = 7): DateTime[][] => {\n const weeks = []\n for (let i = 0; i < daysInMonth.length; i += size) {\n weeks.push(daysInMonth.slice(i, i + size))\n }\n return weeks\n}\n\n/**\n * Get the start and end date of the month the provided date is in, with optional min and max limits.\n */\nexport const getMonthStartAndEnd = (\n date: DateTime,\n { min, max }: { min?: DateTime; max?: DateTime } = {},\n): [DateTime, DateTime] => {\n const startOfMonth = date.startOf(\"month\")\n const endOfMonth = date.endOf(\"month\")\n\n return [\n min ? DateTime.max(min, startOfMonth) : startOfMonth,\n max ? DateTime.min(max, endOfMonth) : endOfMonth,\n ]\n}\n"]}
@@ -93,9 +93,39 @@ export const toFilterProperty = ({ blur } = {}) => {
93
93
  const filters = [blur == null ? null : `blur(${blur}px)`].filter(Boolean);
94
94
  return filters.length ? filters.join(" ") : "none";
95
95
  };
96
+ /** The `data-*` attributes among a component's props, to pass on to its element. */
97
+ export const dataAttributes = (props) => Object.fromEntries(Object.entries(props).filter(([key]) => key.startsWith("data-")));
96
98
  export const preventDefaultHandler = (evt) => {
97
99
  evt.preventDefault();
98
100
  };
101
+ /**
102
+ * For an overlay's close auto focus: focus that moved on to something else
103
+ * while the overlay left stays there instead of going back to the trigger.
104
+ */
105
+ export const keepMovedFocus = (evt) => {
106
+ const active = document.activeElement;
107
+ const movedOut = !!active && active !== document.body && !evt.target?.contains(active);
108
+ if (movedOut)
109
+ evt.preventDefault();
110
+ };
111
+ /*
112
+ * For a row that acts on pointerup, where a press can start on the trigger and
113
+ * end on the row. A touch acts on its click: the click comes last, and a row
114
+ * that closed its list at pointerup would send it to what lies behind the list.
115
+ */
116
+ let touchPressed = false;
117
+ export const pressHandlers = (action) => ({
118
+ onPointerUp: (evt) => {
119
+ touchPressed = evt.pointerType === "touch" || evt.pointerType === "pen";
120
+ if (!touchPressed)
121
+ action();
122
+ },
123
+ onClick: () => {
124
+ if (touchPressed)
125
+ action();
126
+ touchPressed = false;
127
+ },
128
+ });
99
129
  /*
100
130
  * Intentionally simple selector string. Purposeful exclusions: (for now)
101
131
  * - select, because our selects are better recognized as button
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/lib/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { type CSSProperties } from \"react\"\nimport { canUseDOM, hasDocument, hasWindow } from \"./environment\"\nimport type { Pretty } from \"./utilityTypes\"\n\nexport const prefersReducedMotion = () => {\n if (!hasWindow || typeof window.matchMedia !== \"function\") {\n return false\n }\n\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n}\n\nexport const handlePressableMouseEnter = (evt: React.MouseEvent) => {\n const target = evt.currentTarget\n\n // Safely coerce type to HTMLElement so TS is peaceful with `evt.target`\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n const elementWidth = target.offsetWidth\n\n let scale = 0.985\n\n if (elementWidth <= 80) {\n scale = 0.96\n } else if (elementWidth <= 150) {\n scale = 0.97\n } else if (elementWidth <= 220) {\n scale = 0.98\n } else if (elementWidth > 600) {\n scale = 0.995\n }\n\n target.style.setProperty(\"--scale\", scale.toString())\n}\n\ninterface CancelAnimationFrame {\n (): void\n}\n\nexport const waitForAnimationFrame = (\n cb: () => void,\n options?: { frames: number },\n): CancelAnimationFrame => {\n const runAfterTick = () => {\n const id = setTimeout(cb)\n return () => {\n clearTimeout(id)\n }\n }\n\n if (!canUseDOM || typeof window.requestAnimationFrame !== \"function\") {\n return runAfterTick()\n }\n\n const visibilityHidden = hasDocument && document.visibilityState === \"hidden\"\n if (visibilityHidden) {\n return runAfterTick()\n }\n\n let frames = options?.frames ?? 2\n let animationFrame = window.requestAnimationFrame(function recurse() {\n frames -= 1\n if (frames === 0) {\n cb()\n } else {\n animationFrame = window.requestAnimationFrame(recurse)\n }\n })\n\n return () => {\n if (typeof window.cancelAnimationFrame === \"function\") {\n window.cancelAnimationFrame(animationFrame)\n }\n }\n}\n\nexport const toCssVariables = (\n variables: Record<string, string | number | undefined>,\n): CSSProperties => {\n const formattedVariables = Object.keys(variables).reduce(\n (acc, variable) => {\n // Ensure value is truthy\n const value = variables[variable]\n // Accept 0 as a valid value\n if (value || value === 0) {\n // Add the prefix if it wasn't already provided\n const prefix = variable.startsWith(\"--\") ? \"\" : \"--\"\n const formattedValue = typeof value === \"number\" ? `${value}px` : value\n\n acc[`${prefix}${variable}`] = formattedValue\n }\n\n return acc\n },\n {} as Record<string, string>,\n )\n\n // Safe casting because we know we've formatted an object of CSS Variable strings\n return formattedVariables as CSSProperties\n}\n\nexport const toAngle = (value: number | string): string =>\n typeof value === \"number\" ? `${value}deg` : value\n\nexport const toOpacityProperty = (opacity: number): string => String(opacity)\n\nexport const toMsDurationProperty = (duration: number): string => `${duration}ms`\n\nexport const toTransformProperty = ({\n x,\n y,\n scale,\n rotate,\n skewX,\n skewY,\n}: {\n x?: number\n y?: number\n scale?: number\n rotate?: number | string\n skewX?: number | string\n skewY?: number | string\n} = {}): string => {\n const transforms = [\n x == null ? null : `translateX(${x}px)`,\n y == null ? null : `translateY(${y}px)`,\n scale == null ? null : `scale(${scale})`,\n rotate == null ? null : `rotate(${toAngle(rotate)})`,\n skewX == null ? null : `skewX(${toAngle(skewX)})`,\n skewY == null ? null : `skewY(${toAngle(skewY)})`,\n ].filter(Boolean)\n\n return transforms.length ? transforms.join(\" \") : \"none\"\n}\n\nexport const toFilterProperty = ({ blur }: { blur?: number | undefined } = {}) => {\n // Maybe add more support in the future\n const filters = [blur == null ? null : `blur(${blur}px)`].filter(Boolean)\n\n return filters.length ? filters.join(\" \") : \"none\"\n}\n\nexport const preventDefaultHandler = (evt: Event) => {\n evt.preventDefault()\n}\n\n/*\n * Intentionally simple selector string. Purposeful exclusions: (for now)\n * - select, because our selects are better recognized as button\n * - unused selectors like iframe, object, .etc.\n * - states like [inert]\n */\nexport const focusableElements = (element: HTMLElement) =>\n element.querySelectorAll<HTMLElement>(\n 'a[href], input:not([disabled]):not([type=\"hidden\"]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex^=\"-\"]), [contenteditable]',\n )\n\nexport const sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms))\n\n/**\n * Group an array of objects by a property, preserving the *first-seen* order\n * of each group.\n *\n * @example\n * groupByOrdered(people, \"team\")\n * // => [ { team: \"infra\", items:[...] }, { team:\"design\", items:[...] }, ... ]\n */\nexport function groupByProperty<T extends object, K extends keyof T, F = T[K]>(\n items: T[],\n key: K,\n format: (raw: T[K], item: T) => F = (raw) => raw as F,\n // Explicit: the inferred `Pretty<...>` is expanded in the published\n // declaration into a form consumers' type checks reject (TS2536)\n): ({ [P in K]: F } & { items: T[] })[] {\n const groups: Pretty<{ [P in K]: F } & { items: T[] }>[] = []\n const indexMap = new Map<unknown, number>() // maps group value -> index in groups array\n\n for (const item of items) {\n const value = format(item[key], item)\n\n // Add to existing group\n const existing = indexMap.get(value)\n if (existing !== undefined) {\n groups[existing].items.push(item)\n continue\n }\n\n // Create new group\n const group = { [key]: value, items: [item] } as { [P in K]: F } & { items: T[] }\n indexMap.set(value, groups.length)\n groups.push(group)\n }\n\n return groups\n}\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/lib/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { type CSSProperties, type PointerEvent as ReactPointerEvent } from \"react\"\nimport { canUseDOM, hasDocument, hasWindow } from \"./environment\"\nimport type { Pretty } from \"./utilityTypes\"\n\nexport const prefersReducedMotion = () => {\n if (!hasWindow || typeof window.matchMedia !== \"function\") {\n return false\n }\n\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n}\n\nexport const handlePressableMouseEnter = (evt: React.MouseEvent) => {\n const target = evt.currentTarget\n\n // Safely coerce type to HTMLElement so TS is peaceful with `evt.target`\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n const elementWidth = target.offsetWidth\n\n let scale = 0.985\n\n if (elementWidth <= 80) {\n scale = 0.96\n } else if (elementWidth <= 150) {\n scale = 0.97\n } else if (elementWidth <= 220) {\n scale = 0.98\n } else if (elementWidth > 600) {\n scale = 0.995\n }\n\n target.style.setProperty(\"--scale\", scale.toString())\n}\n\ninterface CancelAnimationFrame {\n (): void\n}\n\nexport const waitForAnimationFrame = (\n cb: () => void,\n options?: { frames: number },\n): CancelAnimationFrame => {\n const runAfterTick = () => {\n const id = setTimeout(cb)\n return () => {\n clearTimeout(id)\n }\n }\n\n if (!canUseDOM || typeof window.requestAnimationFrame !== \"function\") {\n return runAfterTick()\n }\n\n const visibilityHidden = hasDocument && document.visibilityState === \"hidden\"\n if (visibilityHidden) {\n return runAfterTick()\n }\n\n let frames = options?.frames ?? 2\n let animationFrame = window.requestAnimationFrame(function recurse() {\n frames -= 1\n if (frames === 0) {\n cb()\n } else {\n animationFrame = window.requestAnimationFrame(recurse)\n }\n })\n\n return () => {\n if (typeof window.cancelAnimationFrame === \"function\") {\n window.cancelAnimationFrame(animationFrame)\n }\n }\n}\n\nexport const toCssVariables = (\n variables: Record<string, string | number | undefined>,\n): CSSProperties => {\n const formattedVariables = Object.keys(variables).reduce(\n (acc, variable) => {\n // Ensure value is truthy\n const value = variables[variable]\n // Accept 0 as a valid value\n if (value || value === 0) {\n // Add the prefix if it wasn't already provided\n const prefix = variable.startsWith(\"--\") ? \"\" : \"--\"\n const formattedValue = typeof value === \"number\" ? `${value}px` : value\n\n acc[`${prefix}${variable}`] = formattedValue\n }\n\n return acc\n },\n {} as Record<string, string>,\n )\n\n // Safe casting because we know we've formatted an object of CSS Variable strings\n return formattedVariables as CSSProperties\n}\n\nexport const toAngle = (value: number | string): string =>\n typeof value === \"number\" ? `${value}deg` : value\n\nexport const toOpacityProperty = (opacity: number): string => String(opacity)\n\nexport const toMsDurationProperty = (duration: number): string => `${duration}ms`\n\nexport const toTransformProperty = ({\n x,\n y,\n scale,\n rotate,\n skewX,\n skewY,\n}: {\n x?: number\n y?: number\n scale?: number\n rotate?: number | string\n skewX?: number | string\n skewY?: number | string\n} = {}): string => {\n const transforms = [\n x == null ? null : `translateX(${x}px)`,\n y == null ? null : `translateY(${y}px)`,\n scale == null ? null : `scale(${scale})`,\n rotate == null ? null : `rotate(${toAngle(rotate)})`,\n skewX == null ? null : `skewX(${toAngle(skewX)})`,\n skewY == null ? null : `skewY(${toAngle(skewY)})`,\n ].filter(Boolean)\n\n return transforms.length ? transforms.join(\" \") : \"none\"\n}\n\nexport const toFilterProperty = ({ blur }: { blur?: number | undefined } = {}) => {\n // Maybe add more support in the future\n const filters = [blur == null ? null : `blur(${blur}px)`].filter(Boolean)\n\n return filters.length ? filters.join(\" \") : \"none\"\n}\n\n/** The `data-*` attributes among a component's props, to pass on to its element. */\nexport const dataAttributes = (props: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(props).filter(([key]) => key.startsWith(\"data-\")))\n\nexport const preventDefaultHandler = (evt: Event) => {\n evt.preventDefault()\n}\n\n/**\n * For an overlay's close auto focus: focus that moved on to something else\n * while the overlay left stays there instead of going back to the trigger.\n */\nexport const keepMovedFocus = (evt: Event) => {\n const active = document.activeElement\n const movedOut = !!active && active !== document.body && !(evt.target as Node | null)?.contains(active)\n if (movedOut) evt.preventDefault()\n}\n\n/*\n * For a row that acts on pointerup, where a press can start on the trigger and\n * end on the row. A touch acts on its click: the click comes last, and a row\n * that closed its list at pointerup would send it to what lies behind the list.\n */\nlet touchPressed = false\n\nexport const pressHandlers = (action: () => void) => ({\n onPointerUp: (evt: ReactPointerEvent) => {\n touchPressed = evt.pointerType === \"touch\" || evt.pointerType === \"pen\"\n if (!touchPressed) action()\n },\n onClick: () => {\n if (touchPressed) action()\n touchPressed = false\n },\n})\n\n/*\n * Intentionally simple selector string. Purposeful exclusions: (for now)\n * - select, because our selects are better recognized as button\n * - unused selectors like iframe, object, .etc.\n * - states like [inert]\n */\nexport const focusableElements = (element: HTMLElement) =>\n element.querySelectorAll<HTMLElement>(\n 'a[href], input:not([disabled]):not([type=\"hidden\"]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex^=\"-\"]), [contenteditable]',\n )\n\nexport const sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms))\n\n/**\n * Group an array of objects by a property, preserving the *first-seen* order\n * of each group.\n *\n * @example\n * groupByOrdered(people, \"team\")\n * // => [ { team: \"infra\", items:[...] }, { team:\"design\", items:[...] }, ... ]\n */\nexport function groupByProperty<T extends object, K extends keyof T, F = T[K]>(\n items: T[],\n key: K,\n format: (raw: T[K], item: T) => F = (raw) => raw as F,\n // Explicit: the inferred `Pretty<...>` is expanded in the published\n // declaration into a form consumers' type checks reject (TS2536)\n): ({ [P in K]: F } & { items: T[] })[] {\n const groups: Pretty<{ [P in K]: F } & { items: T[] }>[] = []\n const indexMap = new Map<unknown, number>() // maps group value -> index in groups array\n\n for (const item of items) {\n const value = format(item[key], item)\n\n // Add to existing group\n const existing = indexMap.get(value)\n if (existing !== undefined) {\n groups[existing].items.push(item)\n continue\n }\n\n // Create new group\n const group = { [key]: value, items: [item] } as { [P in K]: F } & { items: T[] }\n indexMap.set(value, groups.length)\n groups.push(group)\n }\n\n return groups\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { DateTime } from "luxon";
2
2
  import { type PopoverContentProps } from "../Popover/index.js";
3
3
  import type { SelectControlProps } from "../SelectControl/index.js";
4
- import { type DateRange, type DateRangeShortcut } from "./types.js";
4
+ import { type DateRange, type DateRangeShortcut, type WeekStart } from "./types.js";
5
5
  export type DateRangePickerProps = {
6
6
  /**
7
7
  * The selected date range value.
@@ -24,6 +24,11 @@ export type DateRangePickerProps = {
24
24
  * When set, the end date cannot be more than this many days after the start date.
25
25
  */
26
26
  maxRangeDays?: number;
27
+ /**
28
+ * The day each week starts on, from 0 (Sunday) to 6 (Saturday).
29
+ * @default 0
30
+ */
31
+ weekStartsOn?: WeekStart;
27
32
  /**
28
33
  * List of date range shortcuts displayed for quick selection, shown to the left of the calendar.
29
34
  */
@@ -1,11 +1,12 @@
1
1
  import { DateTime } from "luxon";
2
2
  import type { SelectControlProps } from "../SelectControl/index.js";
3
- import type { DateRange, DateRangeShortcut } from "./types.js";
3
+ import type { DateRange, DateRangeShortcut, WeekStart } from "./types.js";
4
4
  export type DateRangeContextValue = {
5
5
  value: DateRange | null;
6
6
  min?: DateTime;
7
7
  max?: DateTime;
8
8
  maxRangeDays?: number;
9
+ weekStartsOn: WeekStart;
9
10
  triggerStepperUnit?: "month";
10
11
  triggerClassName?: string;
11
12
  triggerShowIcon?: boolean;
@@ -1,2 +1,2 @@
1
1
  export { DateRangePicker, type DateRangePickerProps } from "./DateRangePicker.js";
2
- export { type DateRange, type DateRangeShortcut } from "./types.js";
2
+ export { type DateRange, type DateRangeShortcut, type WeekStart } from "./types.js";
@@ -1,5 +1,7 @@
1
1
  import { type DateTime } from "luxon";
2
2
  export type DateRange = [DateTime, DateTime];
3
+ /** The day a week starts on: 0 is Sunday, 6 is Saturday. */
4
+ export type WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;
3
5
  export type DateRangeShortcut = {
4
6
  label: string;
5
7
  getDateRange: () => DateRange;
@@ -49,7 +49,8 @@ export type FieldProps = {
49
49
  orientation?: "vertical" | "horizontal";
50
50
  /**
51
51
  * Allows overriding the auto-generated `id`. When provided, this becomes
52
- * the id set on the child control and the `htmlFor` on the label.
52
+ * the id set on the child control and the `htmlFor` on the label. A child's
53
+ * own `id` wins over both: it stays, and the label's `htmlFor` follows it.
53
54
  */
54
55
  id?: string;
55
56
  /**
@@ -64,7 +65,8 @@ export type FieldProps = {
64
65
  className?: string;
65
66
  /**
66
67
  * The form control(s) to render.
67
- * - If a single ReactElement, Field clones it with { id, aria-describedby, aria-invalid }.
68
+ * - If a single ReactElement, Field clones it with { id, aria-describedby, aria-invalid },
69
+ * keeping an `id` the child already has.
68
70
  * A child without its own `aria-label`, `aria-labelledby` or `label` also gets
69
71
  * `aria-labelledby` pointing at the label, which names controls the label's
70
72
  * `for` cannot reach, such as the Select and DatePicker triggers.
@@ -75,4 +75,6 @@ export type PopoverContentProps = {
75
75
  * @default true
76
76
  */
77
77
  autoFocus?: boolean;
78
+ /** `data-*` attributes land on the popover */
79
+ [dataAttribute: `data-${string}`]: unknown;
78
80
  };
@@ -118,6 +118,11 @@ export type SelectProps<T extends Option> = (SingleSelectProps<T> | MultiSelectP
118
118
  * @default false
119
119
  */
120
120
  pill?: boolean;
121
+ /**
122
+ * Text of a `multiple` trigger when every option is selected
123
+ * @default All selected
124
+ */
125
+ allSelectedLabel?: string;
121
126
  /**
122
127
  * Controls size of the select trigger, and several other aspects of trigger styling.
123
128
  *
@@ -46,6 +46,12 @@ export type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "on
46
46
  * Primary handler for when the control is selected with pointer or keyboard events
47
47
  */
48
48
  onInteract?: () => void;
49
+ /**
50
+ * Enter interacts too, as on a combobox button. Off by default, as Enter
51
+ * may be an attempt to submit a form.
52
+ * @default false
53
+ */
54
+ interactOnEnter?: boolean;
49
55
  /**
50
56
  * Determines size of the size and spacing of the control.
51
57
  *
@@ -73,7 +79,7 @@ export type SelectControlProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "on
73
79
  children: ReactNode;
74
80
  ref?: React.Ref<HTMLSpanElement | null>;
75
81
  };
76
- export declare const SelectControl: ({ ref, onPointerDown, onKeyDown, onPointerEnter, onInteract, invalid, disabled, children, className, variant, size, block, opticallyAlign, pill, loading, onClearClick, selected, StartIcon, dropdownIconType, ...restProps }: SelectControlProps) => import("react/jsx-runtime").JSX.Element;
82
+ export declare const SelectControl: ({ ref, onPointerDown, onKeyDown, onPointerEnter, onInteract, interactOnEnter, invalid, disabled, children, className, variant, size, block, opticallyAlign, pill, loading, onClearClick, selected, StartIcon, dropdownIconType, ...restProps }: SelectControlProps) => import("react/jsx-runtime").JSX.Element;
77
83
  type DropdownIconProps = {
78
84
  iconType: Omit<DropdownIconType, "none">;
79
85
  };
@@ -22,6 +22,11 @@ export type TransitionGroupProps = {
22
22
  enterMountDelay?: number;
23
23
  /** Render children changes immediately, bypassing transition timings */
24
24
  disableAnimations?: boolean;
25
+ /**
26
+ * For overlays: an exiting child is `inert`, out of the tab order and of hit
27
+ * testing, and with reduced motion it leaves without waiting for `exitDuration`.
28
+ */
29
+ overlay?: boolean;
25
30
  /** Determines how new children are added to the children array */
26
31
  insertMethod?: "append" | "prepend";
27
32
  /** Styles applied to wrapping elements */