import { useThemeName, BraidPortal } from "../../TooltipRenderer/TooltipRenderer.mjs";
import { useBraidTheme, useLinkComponent } from "../../../../../side-effects/lib/components/BraidProvider/BraidProvider.mjs";
import { useResponsiveValue, FieldButtonIcon, ClearField } from "../../Autosuggest/Autosuggest.mjs";
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
import { useMemo, forwardRef, Children, useRef, useCallback, useContext, useState, Fragment as Fragment$1, createContext, useEffect, useReducer } from "react";
import { ActionsContext, Bleed, ButtonContainer, useButtonStyles, ButtonOverlays, ButtonText } from "../../Button/Button.mjs";
import { Inline, Text, TextContext, useDisclosure, DefaultTextPropsProvider, IconPositive, IconInfo, IconPromote, IconCritical, IconVisibility, flattenChildren } from "../../Accordion/AccordionItem.mjs";
import assert from "assert";
import matchHighlights from "autosuggest-highlight/match/index.js";
import { Box, PublicBox } from "../../Box/Box.mjs";
import { buildDataAttributes } from "../../Accordion/Accordion.mjs";
import clsx from "clsx";
import { BackgroundProvider, useBackgroundLightness } from "../../Box/BackgroundContext.mjs";
import { atoms } from "../../../css/atoms/atoms.mjs";
import { useColoredBoxClasses } from "../../Box/ColoredBox.mjs";
import dedent from "dedent";
import { optimizeResponsiveArray, Column } from "../../Column/Column.mjs";
import { resolveResponsiveRangeProps } from "../../Hidden/Hidden.mjs";
import { Keyline } from "../Keyline/Keyline.mjs";
import { InlineField } from "../InlineField/InlineField.mjs";
import { StyledInput } from "../InlineField/StyledInput.mjs";
import { Modal } from "../Modal/Modal.mjs";
import { useLinkStyles, TextLinkContent } from "../../TextLink/TextLink.mjs";
import { AvoidWidowIcon } from "../AvoidWidowIcon/AvoidWidowIcon.mjs";
import { HeadingContext } from "../../Heading/Heading.mjs";
import { IconChevron } from "../../icons/IconChevron/IconChevron.mjs";
import { useMenuItem } from "../../MenuItem/useMenuItem.mjs";
import { Link } from "../../Pagination/Pagination.mjs";
import { Columns } from "../../Columns/Columns.mjs";
import { Field } from "../Field/Field.mjs";
import { FieldGroup } from "../../MonthPicker/MonthPicker.mjs";
import { Stack } from "../../Stack/Stack.mjs";
import { TabsContext, TAB_PANELS_UPDATED } from "../../Tabs/Tab.mjs";
import { TabPanelsContext } from "../../Tabs/TabPanel.mjs";
import { getCharacterLimitStatus } from "../../Textarea/Textarea.mjs";
import { ToastComponent } from "../../useToast/Toast.mjs";
import { useIsomorphicLayoutEffect } from "../../Tabs/Tabs.mjs";
import { lightTheme, darkTheme, box, label, line } from "./Placeholder.css.mjs";
import { wireframe } from "../../../themes/wireframe/wireframeTheme.css.mjs";
const ThemeNameConsumer = ({ children }) => children(useThemeName());
const useColor = () => useBraidTheme().color;
const useBreakpoint = () => {
  if (process.env.NODE_ENV !== "production") {
    console.warn(
      `'useBreakpoint' has been deprecated. Use 'useResponsiveValue' instead: https://seek-oss.github.io/braid-design-system/components/useResponsiveValue`
    );
  }
  return useResponsiveValue()({
    mobile: "mobile",
    tablet: "tablet",
    desktop: "desktop"
  });
};
const Actions = ({ size, data, children }) => {
  const contextValue = useMemo(() => ({ size }), [size]);
  return /* @__PURE__ */ jsx(ActionsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Inline, { collapseBelow: "tablet", space: "xsmall", data, children }) });
};
function matchSuggestion(suggestion, query) {
  const groupMatches = matchHighlights(
    suggestion.label ?? suggestion.text,
    query
  );
  return !groupMatches.length ? null : {
    ...suggestion,
    highlights: groupMatches.map(([start, end]) => ({ start, end }))
  };
}
function filterSuggestions(...args) {
  assert(
    [1, 2].includes(args.length),
    `Invalid number of arguments passed to "filterSuggestions". Expected 1 or 2, got ${args.length}`
  );
  if (args.length === 1) {
    return (inputValue) => filter(args[0], inputValue);
  } else if (args.length === 2) {
    return filter(args[0], args[1]);
  }
  function filter(suggestions, inputValue) {
    assert(
      typeof inputValue === "string" || typeof inputValue === "object" && inputValue !== null && "text" in inputValue,
      'The second argument to "filterSuggestions" must be a string or an Autosuggest value object, e.g. { text: "Hello world" }'
    );
    const query = (typeof inputValue === "string" ? inputValue : inputValue.text).trim();
    if (query === "") {
      return suggestions;
    }
    const filteredSuggestions = [];
    suggestions.forEach((suggestion) => {
      if ("suggestions" in suggestion) {
        const filteredGroupSuggestions = [];
        suggestion.suggestions.forEach((groupSuggestion) => {
          const filteredSuggestion = matchSuggestion(groupSuggestion, query);
          if (filteredSuggestion) {
            filteredGroupSuggestions.push(filteredSuggestion);
          }
        });
        if (filteredGroupSuggestions.length) {
          filteredSuggestions.push({
            ...suggestion,
            suggestions: filteredGroupSuggestions
          });
        }
      } else {
        const filteredSuggestion = matchSuggestion(suggestion, query);
        if (filteredSuggestion) {
          filteredSuggestions.push(filteredSuggestion);
        }
      }
    });
    return filteredSuggestions;
  }
}
const validTones = [
  "promote",
  "info",
  "neutral",
  "positive",
  "caution",
  "critical"
];
const lightModeBackgroundForTone = {
  positive: "positiveLight",
  critical: "criticalLight",
  info: "infoLight",
  promote: "promoteLight",
  neutral: "neutralLight",
  caution: "cautionLight"
};
const verticalPadding = "xxsmall";
const Badge = forwardRef(
  ({
    tone = "info",
    weight = "regular",
    bleedY = false,
    title,
    children,
    id,
    data,
    tabIndex,
    "aria-describedby": ariaDescribedBy,
    ...restProps
  }, ref) => {
    assert(
      validTones.indexOf(tone) >= 0,
      `Badge tone of "${tone}" is not valid.`
    );
    assert(
      Children.toArray(children).every(
        (child) => ["string", "number"].includes(typeof child)
      ),
      "Badge may only contain strings or numbers"
    );
    const content = /* @__PURE__ */ jsx(
      Box,
      {
        component: "span",
        display: "flex",
        cursor: "default",
        ...buildDataAttributes({ data, validateRestProps: restProps }),
        children: /* @__PURE__ */ jsx(
          Box,
          {
            component: "span",
            id,
            ref,
            tabIndex,
            "aria-describedby": ariaDescribedBy,
            title: title ?? (!ariaDescribedBy ? children : void 0),
            background: weight === "strong" ? tone : lightModeBackgroundForTone[tone],
            paddingY: verticalPadding,
            paddingX: "xsmall",
            borderRadius: "standard",
            overflow: "hidden",
            children: /* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "medium", maxLines: 1, children })
          }
        )
      }
    );
    return bleedY ? /* @__PURE__ */ jsx(Bleed, { component: "span", vertical: verticalPadding, children: content }) : content;
  }
);
Badge.displayName = "Badge";
Badge.__isBadge__ = true;
const ColoredBoxRenderer = ({
  background,
  boxShadow,
  children,
  className
}) => {
  const { backgroundContext, classList } = useColoredBoxClasses({
    background,
    boxShadow
  });
  const element = children(clsx(className, classList));
  return backgroundContext ? /* @__PURE__ */ jsx(BackgroundProvider, { value: backgroundContext, children: element }) : element;
};
const BoxRenderer = ({
  children,
  component = "div",
  className,
  background,
  boxShadow,
  ...props
}) => {
  const classes = clsx(className, atoms({ reset: component, ...props }));
  return background || boxShadow ? /* @__PURE__ */ jsx(
    ColoredBoxRenderer,
    {
      background,
      boxShadow,
      className: classes,
      children
    }
  ) : children(classes);
};
const ButtonLink = forwardRef(
  ({
    children,
    size,
    tone,
    variant,
    bleedY,
    bleed,
    icon,
    iconPosition,
    loading,
    data,
    ...restProps
  }, ref) => {
    const LinkComponent = useLinkComponent(ref);
    if (process.env.NODE_ENV !== "production") {
      if (typeof bleedY !== "undefined") {
        console.warn(
          dedent`
            The "bleedY" prop has been deprecated and will be removed in a future version. Use "bleed" instead.
               <Button
              %c-   bleedY
              %c+   bleed
               %c/>
          `,
          "color: red",
          "color: green",
          "color: inherit"
        );
      }
    }
    return /* @__PURE__ */ jsx(ButtonContainer, { bleed, variant, children: /* @__PURE__ */ jsxs(
      Box,
      {
        component: LinkComponent,
        ref,
        ...restProps,
        ...buildDataAttributes({ data, validateRestProps: false }),
        ...useButtonStyles({
          variant,
          tone,
          size,
          bleed: bleed || bleedY,
          loading
        }),
        children: [
          /* @__PURE__ */ jsx(ButtonOverlays, { variant, tone }),
          /* @__PURE__ */ jsx(
            ButtonText,
            {
              variant,
              tone,
              size,
              loading,
              icon,
              iconPosition,
              bleed,
              children
            }
          )
        ]
      }
    ) });
  }
);
ButtonLink.displayName = "ButtonLink";
const validCardComponents = [
  "div",
  "article",
  "aside",
  "details",
  "main",
  "section"
];
const borderRadius = "large";
const Card = ({
  children,
  component = "div",
  tone,
  data,
  height,
  ...restProps
}) => {
  assert(
    validCardComponents.includes(component),
    `Invalid Card component: '${component}'. Should be one of [${validCardComponents.map((c) => `'${c}'`).join(", ")}]`
  );
  const isLegacyTheme = useBraidTheme().legacy;
  let resolvedRounding;
  if ("rounded" in restProps) {
    resolvedRounding = borderRadius;
  } else if ("roundedAbove" in restProps) {
    const [roundedOnMobile, roundedOnTablet, roundedOnDesktop, roundedOnWide] = resolveResponsiveRangeProps({ above: restProps.roundedAbove });
    resolvedRounding = optimizeResponsiveArray([
      roundedOnMobile ? borderRadius : "none",
      roundedOnTablet ? borderRadius : "none",
      roundedOnDesktop ? borderRadius : "none",
      roundedOnWide ? borderRadius : "none"
    ]);
  }
  const roundingForTheme = !isLegacyTheme ? borderRadius : resolvedRounding;
  return /* @__PURE__ */ jsxs(
    Box,
    {
      component,
      position: "relative",
      background: "surface",
      padding: "gutter",
      borderRadius: roundingForTheme,
      boxShadow: !isLegacyTheme ? "borderNeutralLight" : void 0,
      height: height === "full" ? height : void 0,
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: [
        tone ? /* @__PURE__ */ jsx(Keyline, { tone, borderRadius: roundingForTheme }) : null,
        children
      ]
    }
  );
};
const resolveCheckedGroup = (values) => values.some((value) => value !== values[0]) ? "mixed" : values[0] ?? false;
const Checkbox = forwardRef(
  ({ checked, ...restProps }, ref) => {
    const calculatedChecked = Array.isArray(checked) ? resolveCheckedGroup(checked) : checked;
    return /* @__PURE__ */ jsx(
      InlineField,
      {
        ...restProps,
        checked: calculatedChecked,
        type: "checkbox",
        ref
      }
    );
  }
);
Checkbox.displayName = "Checkbox";
const CheckboxStandalone = forwardRef(({ checked, ...restProps }, ref) => {
  const calculatedChecked = Array.isArray(checked) ? resolveCheckedGroup(checked) : checked;
  return /* @__PURE__ */ jsx(Box, { position: "relative", children: /* @__PURE__ */ jsx(TextContext.Provider, { value: null, children: /* @__PURE__ */ jsx(
    StyledInput,
    {
      ...restProps,
      checked: calculatedChecked,
      type: "checkbox",
      ref
    }
  ) }) });
});
const defaultWidth$1 = "small";
const modalStyle$1 = {
  position: "center",
  headingLevel: "3"
};
const Dialog = ({ width = defaultWidth$1, ...restProps }) => /* @__PURE__ */ jsx(Modal, { width, ...restProps, ...modalStyle$1 });
const noop = () => {
};
const TextLinkButton = ({
  weight,
  hitArea,
  id,
  onClick = noop,
  data,
  children,
  "aria-controls": ariaControls,
  "aria-expanded": ariaExpanded,
  "aria-describedby": ariaDescribedBy,
  "aria-label": ariaLabel,
  tabIndex,
  icon,
  iconPosition,
  ...restProps
}) => {
  const buttonRef = useRef(null);
  const classes = useLinkStyles({
    reset: false,
    weight,
    hitArea
  });
  const handleKeyboard = useCallback(
    (event) => {
      var _a;
      if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        (_a = buttonRef.current) == null ? void 0 : _a.click();
      }
    },
    [buttonRef]
  );
  return /* @__PURE__ */ jsx(
    Box,
    {
      ref: buttonRef,
      role: "button",
      tabIndex: tabIndex ?? 0,
      component: "span",
      onClick,
      onKeyDown: handleKeyboard,
      "aria-controls": ariaControls,
      "aria-expanded": ariaExpanded,
      "aria-describedby": ariaDescribedBy,
      "aria-label": ariaLabel,
      id,
      className: classes,
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: /* @__PURE__ */ jsx(TextLinkContent, { icon, iconPosition, children })
    }
  );
};
const Disclosure = ({
  id,
  expandLabel,
  collapseLabel = expandLabel,
  space = "medium",
  children,
  data,
  weight,
  ...restProps
}) => {
  assert(
    typeof expandLabel === "undefined" || typeof expandLabel === "string",
    "'expandLabel' must be a string"
  );
  assert(
    typeof collapseLabel === "undefined" || typeof collapseLabel === "string",
    "'collapseLabel' must be a string"
  );
  const textContext = useContext(TextContext);
  const headingContext = useContext(HeadingContext);
  const isInline = Boolean(textContext || headingContext);
  const { expanded, buttonProps, contentProps } = useDisclosure({
    id,
    ...restProps.expanded !== void 0 ? {
      onToggle: restProps.onToggle,
      expanded: restProps.expanded
    } : {
      onToggle: restProps.onToggle
    }
  });
  const trigger = /* @__PURE__ */ jsxs(TextLinkButton, { hitArea: "large", weight, ...buttonProps, children: [
    expanded ? collapseLabel : expandLabel,
    /* @__PURE__ */ jsx(AvoidWidowIcon, { iconPosition: "trailing", children: /* @__PURE__ */ jsx(IconChevron, { direction: expanded ? "up" : "down", alignY: "lowercase" }) })
  ] });
  const component = isInline ? "span" : "div";
  return /* @__PURE__ */ jsxs(
    Box,
    {
      component,
      display: isInline ? "inline" : void 0,
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: [
        /* @__PURE__ */ jsx(
          Box,
          {
            component,
            display: isInline ? "inline" : void 0,
            userSelect: "none",
            children: isInline ? /* @__PURE__ */ jsxs(Fragment, { children: [
              " ",
              trigger
            ] }) : /* @__PURE__ */ jsx(Text, { children: trigger })
          }
        ),
        /* @__PURE__ */ jsx(
          Box,
          {
            component,
            paddingTop: space,
            display: expanded ? "block" : "none",
            ...contentProps,
            children
          }
        )
      ]
    }
  );
};
const validWidths = ["small", "medium", "large"];
const validPositions = ["left", "right"];
const defaultWidth = "medium";
const defaultPosition = "right";
const modalStyle = {
  headingLevel: "2",
  illustration: void 0
};
const Drawer = ({
  width = defaultWidth,
  position = defaultPosition,
  ...restProps
}) => {
  assert(validWidths.indexOf(width) >= 0, `Invalid width: ${width}`);
  assert(
    validPositions.indexOf(position) >= 0,
    `Invalid position: ${position}`
  );
  return /* @__PURE__ */ jsx(Modal, { width, position, ...restProps, ...modalStyle });
};
const MenuItem = ({
  children,
  onClick,
  data,
  tone,
  badge,
  icon,
  id
}) => {
  const { menuItemProps, MenuItemChildren } = useMenuItem({
    tone,
    onClick,
    data,
    id
  });
  return /* @__PURE__ */ jsx(Box, { ...menuItemProps, component: "button", type: "button", children: /* @__PURE__ */ jsx(MenuItemChildren, { tone, icon, badge, children }) });
};
MenuItem.__isMenuItem__ = true;
const MenuItemLink = ({
  href,
  target,
  rel,
  onClick,
  tone,
  data,
  children,
  badge,
  icon,
  id
}) => {
  const { menuItemProps, MenuItemChildren } = useMenuItem({
    displayName: "MenuItemLink",
    onClick,
    tone,
    data,
    id
  });
  return /* @__PURE__ */ jsx(
    Box,
    {
      component: Link,
      ...menuItemProps,
      href,
      target,
      rel,
      children: /* @__PURE__ */ jsx(MenuItemChildren, { tone, icon, badge, children })
    }
  );
};
MenuItemLink.__isMenuItem__ = true;
const icons = {
  positive: IconPositive,
  info: IconInfo,
  promote: IconPromote,
  critical: IconCritical
};
const Notice = ({
  tone = "info",
  data,
  children,
  ...restProps
}) => {
  const Icon = icons[tone];
  return /* @__PURE__ */ jsx(
    Box,
    {
      role: "alert",
      "aria-live": "polite",
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: /* @__PURE__ */ jsx(DefaultTextPropsProvider, { tone, children: /* @__PURE__ */ jsxs(Columns, { space: "xsmall", children: [
        /* @__PURE__ */ jsx(Column, { width: "content", children: /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx(Icon, {}) }) }),
        /* @__PURE__ */ jsx(Column, { children })
      ] }) })
    }
  );
};
const PasswordField = forwardRef(
  ({
    value,
    onChange,
    onBlur,
    onFocus,
    placeholder,
    disabled,
    onVisibilityToggle,
    visibilityToggleLabel = "Toggle password visibility",
    id,
    ...restProps
  }, forwardedRef) => {
    const defaultRef = useRef(null);
    const inputRef = forwardedRef || defaultRef;
    const [visible, setVisibile] = useState(false);
    const visibilityHandler = useCallback(
      (event) => {
        if (event.button !== 0) {
          return;
        }
        const newState = !visible;
        setVisibile(newState);
        if (typeof onVisibilityToggle === "function") {
          onVisibilityToggle(newState);
        }
        if (inputRef && typeof inputRef === "object" && inputRef.current) {
          inputRef.current.focus();
        }
      },
      [visible, onVisibilityToggle, inputRef]
    );
    return /* @__PURE__ */ jsx(
      Field,
      {
        ...restProps,
        id,
        value,
        icon: void 0,
        prefix: void 0,
        disabled,
        secondaryMessage: null,
        alwaysShowSecondaryIcon: !disabled,
        secondaryIcon: disabled ? null : /* @__PURE__ */ jsx(
          FieldButtonIcon,
          {
            id: `${id}-toggle`,
            label: visibilityToggleLabel,
            onMouseDown: visibilityHandler,
            icon: /* @__PURE__ */ jsx(IconVisibility, { hidden: visible })
          }
        ),
        children: (overlays, fieldProps, _, secondaryIcon) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
          /* @__PURE__ */ jsx(
            Box,
            {
              component: "input",
              type: visible ? "text" : "password",
              value,
              onChange,
              onFocus,
              onBlur,
              placeholder: !disabled ? placeholder : void 0,
              ...fieldProps,
              ref: inputRef
            }
          ),
          overlays,
          secondaryIcon
        ] })
      }
    );
  }
);
PasswordField.displayName = "PasswordField";
const RadioGroupContext = createContext(
  null
);
const RadioItemContext = createContext(null);
const Radio = forwardRef((props, ref) => {
  const radioGroupContext = useContext(RadioGroupContext);
  assert(
    radioGroupContext === null,
    'The "Radio" component has been deprecated. Use a "RadioItem" instead.'
  );
  if (process.env.NODE_ENV !== "production") {
    console.warn(
      dedent`
        The "Radio" component has been deprecated and will be removed in a future version. Use "RadioGroup" with "RadioItem" instead.
        %c
        - <Radio name="count" label="One" value="1" onChange={...} />
        - <Radio name="count" label="Two" value="2" onChange={...} checked />
        - <Radio name="count" label="Three" value="3" onChange={...}  />
        %c
        + <RadioGroup name="count" value="2" onChange={...}>
        +   <RadioItem label="One" value="1" />
        +   <RadioItem label="Two" value="2" />
        +   <RadioItem label="Three" value="3" />
        + </RadioGroup>
      `,
      "color: red",
      "color: green"
    );
  }
  return /* @__PURE__ */ jsx(
    InlineField,
    {
      ...props,
      inList: false,
      type: "radio",
      message: null,
      reserveMessageSpace: false,
      required: void 0,
      size: void 0,
      ref
    }
  );
});
Radio.displayName = "Radio";
const RadioItem = forwardRef(
  (props, ref) => {
    const radioGroupContext = useContext(RadioGroupContext);
    const radioItemContext = useContext(RadioItemContext);
    assert(
      radioGroupContext !== null && radioItemContext !== null,
      "All `RadioItem` buttons must be within a `RadioGroup`."
    );
    assert(
      typeof props.value !== "undefined" && props.value !== "",
      "All `RadioItem` buttons must have an associated `value`"
    );
    const checked = radioGroupContext.value === props.value;
    const isFirstRadioWithNoCheckedValueInGroup = radioItemContext === 0 && !Boolean(radioGroupContext.value);
    const tababble = checked || isFirstRadioWithNoCheckedValueInGroup;
    return /* @__PURE__ */ jsx(
      InlineField,
      {
        ...props,
        id: `${radioGroupContext.id}_${radioItemContext}`,
        name: radioGroupContext.name,
        checked,
        onChange: radioGroupContext.onChange,
        tone: radioGroupContext.tone === "critical" || radioGroupContext.tone === "neutral" ? radioGroupContext.tone : void 0,
        size: radioGroupContext.size,
        disabled: radioGroupContext.disabled || props.disabled,
        "aria-describedby": radioGroupContext["aria-describedby"],
        tabIndex: tababble ? 0 : -1,
        inList: true,
        type: "radio",
        message: null,
        reserveMessageSpace: false,
        required: void 0,
        ref
      }
    );
  }
);
RadioItem.displayName = "RadioItem";
const stackSpaceForSize = {
  small: "small",
  standard: "medium"
};
const RadioGroup = ({
  children,
  id,
  value,
  name,
  onChange,
  disabled,
  tone,
  size,
  ...props
}) => {
  const items = flattenChildren(children);
  const labelSpace = props.description ? "xxsmall" : "xsmall";
  assert(
    items.every(
      (item) => typeof item === "object" && "type" in item && item.type === RadioItem
    ),
    "All child nodes within a RadioGroup must be a RadioItem: https://seek-oss.github.io/braid-design-system/components/RadioGroup"
  );
  return /* @__PURE__ */ jsx(
    FieldGroup,
    {
      id,
      ...props,
      disabled,
      tone,
      space: "small",
      role: "radiogroup",
      children: (fieldGroupProps) => /* @__PURE__ */ jsx(
        RadioGroupContext.Provider,
        {
          value: {
            id,
            value,
            name: name || id,
            onChange,
            disabled,
            tone,
            size,
            ...fieldGroupProps
          },
          children: /* @__PURE__ */ jsx(
            Box,
            {
              paddingTop: "label" in props ? labelSpace : void 0,
              paddingBottom: props.message || props.reserveMessageSpace ? "xsmall" : void 0,
              children: /* @__PURE__ */ jsx(Stack, { space: stackSpaceForSize[size || "standard"], children: items.map((item, i) => /* @__PURE__ */ jsx(RadioItemContext.Provider, { value: i, children: item }, i)) })
            }
          )
        }
      )
    }
  );
};
RadioGroup.displayName = "RadioGroup";
const TabPanels = ({
  renderInactivePanels = false,
  children
}) => {
  const tabsContext = useContext(TabsContext);
  if (!tabsContext) {
    throw new Error("TabPanels rendered outside TabsProvider context");
  }
  const { dispatch } = tabsContext;
  const panelItems = [];
  const panels = flattenChildren(children).map((panel, index) => {
    assert(
      // @ts-expect-error
      typeof panel === "object" && panel.type.__isTabPanel__,
      "Only TabPanel elements can be direct children of a TabPanels"
    );
    panelItems.push(index);
    return /* @__PURE__ */ jsx(
      TabPanelsContext.Provider,
      {
        value: {
          renderInactive: renderInactivePanels,
          panelIndex: index
        },
        children: panel
      },
      index
    );
  });
  useEffect(() => {
    dispatch({ type: TAB_PANELS_UPDATED, panels: panelItems });
  }, [panelItems.join(), dispatch]);
  return /* @__PURE__ */ jsx(Fragment$1, { children: panels });
};
const validTypes = {
  text: "text",
  password: "password",
  email: "email",
  search: "search",
  number: "number",
  tel: "tel",
  url: "url"
};
const defaultInputModesForType = {
  text: "text",
  password: "text",
  email: "email",
  search: "search",
  number: "numeric",
  tel: "tel",
  url: "url"
};
const TextField = forwardRef(
  ({
    value,
    type = "text",
    onChange,
    onBlur,
    onFocus,
    onClear,
    placeholder,
    characterLimit,
    id,
    clearLabel,
    inputMode,
    step,
    ...restProps
  }, forwardedRef) => {
    const defaultRef = useRef(null);
    const inputRef = forwardedRef || defaultRef;
    const clearable = Boolean(
      typeof onClear !== "undefined" && !restProps.disabled && typeof value === "string" && value.length > 0
    );
    return /* @__PURE__ */ jsx(
      Field,
      {
        ...restProps,
        id,
        value,
        secondaryMessage: characterLimit ? getCharacterLimitStatus({
          value,
          characterLimit
        }) : null,
        secondaryIcon: onClear ? /* @__PURE__ */ jsx(
          ClearField,
          {
            id: `${id}-clear`,
            hide: !clearable,
            onClear,
            label: clearLabel,
            inputRef
          }
        ) : null,
        children: (overlays, fieldProps, icon, secondaryIcon, prefix) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
          icon,
          prefix,
          /* @__PURE__ */ jsx(
            Box,
            {
              component: "input",
              type: validTypes[type],
              value,
              onChange,
              onFocus,
              onBlur,
              placeholder: !restProps.disabled ? placeholder : void 0,
              ...fieldProps,
              inputMode: inputMode || defaultInputModesForType[type],
              step,
              ref: inputRef
            }
          ),
          overlays,
          secondaryIcon
        ] })
      }
    );
  }
);
TextField.displayName = "TextField";
const animationTimeout = 300;
const entranceTransition = "transform 0.2s ease, opacity 0.2s ease";
const exitTransition = "opacity 0.1s ease";
const animate = (element, transforms, transition, done) => {
  const fallbackTimeout = setTimeout(() => {
    if (done) {
      done();
    }
  }, animationTimeout);
  transforms.forEach(({ property, from = "" }) => {
    element.style.setProperty(property, from);
  });
  element.style.setProperty("transition", "");
  const transitionEndHandler = (ev) => {
    if (ev.target !== element) {
      return;
    }
    element.style.setProperty("transition", "");
    if (done) {
      done();
    }
    element.removeEventListener("transitionend", transitionEndHandler);
    clearTimeout(fallbackTimeout);
  };
  element.addEventListener("transitionend", transitionEndHandler);
  window.requestAnimationFrame(() => {
    window.requestAnimationFrame(() => {
      element.style.setProperty("transition", transition);
      transforms.forEach(({ property, to = "" }) => {
        element.style.setProperty(property, to);
      });
    });
  });
};
const useFlipList = () => {
  const refs = useMemo(() => /* @__PURE__ */ new Map(), []);
  const positions = useMemo(() => /* @__PURE__ */ new Map(), []);
  useIsomorphicLayoutEffect(() => {
    const animations = [];
    Array.from(refs.entries()).forEach(([id, element]) => {
      if (element) {
        const prevTop = positions.get(id);
        const { top, height } = element.getBoundingClientRect();
        if (typeof prevTop === "number" && prevTop !== top) {
          animations.push({
            element,
            transition: entranceTransition,
            transforms: [
              {
                property: "transform",
                from: `translateY(${prevTop - top}px)`
              }
            ]
          });
        } else if (typeof prevTop !== "number") {
          animations.push({
            element,
            transition: entranceTransition,
            transforms: [
              {
                property: "transform",
                from: `translateY(${height}px)`
              },
              {
                property: "opacity",
                from: "0"
              }
            ]
          });
        }
        positions.set(id, element.getBoundingClientRect().top);
      } else {
        refs.delete(id);
      }
    });
    animations.forEach(({ element, transforms, transition }) => {
      animate(element, transforms, transition);
    });
  });
  const remove = useCallback(
    (id, cb) => {
      const element = refs.get(id);
      if (element) {
        animate(
          element,
          [
            {
              property: "opacity",
              to: "0"
            }
          ],
          exitTransition,
          cb
        );
      }
    },
    [refs]
  );
  const itemRef = useCallback(
    (id) => (ref) => {
      refs.set(id, ref);
    },
    [refs]
  );
  return {
    itemRef,
    remove
  };
};
const Toaster = ({ toasts, removeToast }) => {
  const { itemRef, remove } = useFlipList();
  const onClose = useCallback(
    (dedupeKey, id) => {
      remove(id, () => {
        removeToast(dedupeKey);
      });
    },
    [remove, removeToast]
  );
  return /* @__PURE__ */ jsx(
    Box,
    {
      position: "fixed",
      zIndex: "notification",
      width: "full",
      pointerEvents: "none",
      paddingX: "gutter",
      bottom: 0,
      children: toasts.map(({ id, ...rest }) => /* @__PURE__ */ jsx(Box, { paddingBottom: "small", children: /* @__PURE__ */ jsx(
        ToastComponent,
        {
          ref: itemRef(id),
          id,
          onClose,
          ...rest
        }
      ) }, id))
    }
  );
};
let toastCounter = 0;
const ToastControllerContext = createContext(null);
const QUEUE_TOAST = 0;
const REMOVE_TOAST = 1;
function reducer(state, action) {
  switch (action.type) {
    case QUEUE_TOAST: {
      const { toast } = action;
      const hasExistingToast = state.toasts.some(
        (t) => t.dedupeKey === toast.dedupeKey
      );
      if (hasExistingToast) {
        return {
          toasts: state.toasts.map((t) => {
            if (t.dedupeKey === toast.dedupeKey) {
              return {
                ...t,
                shouldRemove: true
              };
            }
            return t;
          }),
          queuedToasts: {
            ...state.queuedToasts,
            [toast.dedupeKey]: toast
          }
        };
      }
      return {
        ...state,
        toasts: [...state.toasts, action.toast]
      };
    }
    case REMOVE_TOAST: {
      const toasts = state.toasts.filter(
        ({ dedupeKey }) => dedupeKey !== action.dedupeKey
      );
      const queuedToast = state.queuedToasts[action.dedupeKey];
      if (queuedToast) {
        return {
          queuedToasts: {
            ...state.queuedToasts,
            [action.dedupeKey]: void 0
          },
          toasts: [...toasts, queuedToast]
        };
      }
      return {
        ...state,
        toasts
      };
    }
  }
}
const InternalToastProvider = ({ children }) => {
  const [{ toasts }, dispatch] = useReducer(reducer, {
    toasts: [],
    queuedToasts: {}
  });
  const addToast = useCallback(
    (toast) => dispatch({ type: QUEUE_TOAST, toast }),
    []
  );
  const removeToast = useCallback(
    (dedupeKey) => dispatch({ type: REMOVE_TOAST, dedupeKey }),
    []
  );
  return /* @__PURE__ */ jsxs(ToastControllerContext.Provider, { value: addToast, children: [
    children,
    /* @__PURE__ */ jsx(ToastPortal, { children: /* @__PURE__ */ jsx(Toaster, { toasts, removeToast }) })
  ] });
};
const ToastProvider = ({ children }) => {
  const currentContext = useContext(ToastControllerContext);
  if (currentContext !== null) {
    return /* @__PURE__ */ jsx(Fragment$1, { children });
  }
  return /* @__PURE__ */ jsx(InternalToastProvider, { children });
};
const ToastPortal = ({ children }) => {
  const [toastElement, setElement] = useState(null);
  useEffect(() => {
    const toastContainerId = "braid-toast-container";
    let element = document.getElementById(toastContainerId);
    if (!element) {
      element = document.createElement("div");
      element.setAttribute("id", toastContainerId);
      element.setAttribute("class", "");
      document.body.appendChild(element);
    }
    setElement(element);
  }, []);
  if (!toastElement) {
    return null;
  }
  return /* @__PURE__ */ jsx(BraidPortal, { container: toastElement, children });
};
const useToast = () => {
  const { vanillaTheme } = useBraidTheme();
  const addToast = useContext(ToastControllerContext);
  if (addToast === null) {
    throw new Error('No "ToastProvider" configured');
  }
  return useCallback(
    (toast) => {
      const id = `${toastCounter++}`;
      const dedupeKey = toast.key ?? id;
      addToast({
        ...toast,
        vanillaTheme,
        id,
        dedupeKey,
        shouldRemove: false
      });
    },
    [vanillaTheme, addToast]
  );
};
const resolveToPxIfUnitless = (value) => typeof value === "string" && /[0-9]$/.test(value) ? `${value}px` : value;
const PlaceholderContent = ({
  label: label$1,
  image
}) => {
  if (image) {
    return null;
  }
  if (label$1) {
    return /* @__PURE__ */ jsx(PublicBox, { paddingX: "xsmall", paddingY: "xxsmall", children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "strong", align: "center", baseline: false, children: /* @__PURE__ */ jsx(PublicBox, { className: label, children: label$1 }) }) });
  }
  return /* @__PURE__ */ jsxs(
    "svg",
    {
      xmlns: "http://www.w3.org/2000/svg",
      className: atoms({
        reset: "svg",
        position: "absolute",
        width: "full",
        height: "full"
      }),
      children: [
        /* @__PURE__ */ jsx("line", { className: line, x1: 0, y1: 0, x2: "100%", y2: "100%" }),
        /* @__PURE__ */ jsx("line", { className: line, x1: "100%", y1: 0, x2: 0, y2: "100%" })
      ]
    }
  );
};
const Placeholder = ({
  label: label2,
  width = "auto",
  height = 120,
  shape = "rectangle",
  image,
  imageSize = "cover"
}) => {
  const lightness = useBackgroundLightness();
  return /* @__PURE__ */ jsx(
    PublicBox,
    {
      position: "relative",
      overflow: "hidden",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      borderRadius: shape === "round" ? "full" : void 0,
      className: [
        wireframe.vanillaTheme,
        lightTheme[lightness.lightMode],
        darkTheme[lightness.darkMode],
        !image ? box : void 0
      ],
      style: {
        width: resolveToPxIfUnitless(width),
        height: resolveToPxIfUnitless(height),
        background: image ? `url(${image}) no-repeat center center` : void 0,
        backgroundSize: imageSize
      },
      children: /* @__PURE__ */ jsx(PlaceholderContent, { label: label2, image })
    }
  );
};
export {
  Actions,
  Badge,
  BoxRenderer,
  ButtonLink,
  Card,
  Checkbox,
  CheckboxStandalone,
  Dialog,
  Disclosure,
  Drawer,
  MenuItem,
  MenuItemLink,
  Notice,
  PasswordField,
  Placeholder,
  Radio,
  RadioGroup,
  RadioItem,
  TabPanels,
  TextField,
  TextLinkButton,
  ThemeNameConsumer,
  ToastProvider,
  filterSuggestions,
  useBreakpoint,
  useColor,
  useToast,
  validCardComponents
};
