{"mappings":"AC2DoB;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAiDD;;;;EAAA;;;;EAQY;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAkEK;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;;;EAAA;;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAwBV;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;EAAA;;;;;AAnJN;EA2HgB;;;;;AA3HhB;EAAA;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;;;AA2HgB;EAAA;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;IAAA;;;;;;AAwBV;EAAA;IAAA","sources":["b68c88297d49b771","packages/@react-spectrum/s2/src/NumberField.tsx"],"sourcesContent":["@import \"86e54c0ad46f69c2\";\n@import \"81d36b1860c8fc73\";\n@import \"22edbea9646800a7\";\n@import \"c17a88ce1f4f53da\";\n@import \"e6f6c2ace019f265\";\n","/*\n * Copyright 2024 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport Add from '../ui-icons/Add';\nimport {\n  ButtonProps as AriaButtonProps,\n  NumberField as AriaNumberField,\n  NumberFieldProps as AriaNumberFieldProps,\n  ButtonContext,\n  ButtonRenderProps,\n  ContextValue,\n  InputContext,\n  Text,\n  useContextProps\n} from 'react-aria-components';\nimport {baseColor, space, style} from '../style' with {type: 'macro'};\nimport {controlBorderRadius, field, fieldInput, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'};\nimport {createContext, CSSProperties, ForwardedRef, forwardRef, ReactNode, Ref, useContext, useImperativeHandle, useMemo, useRef} from 'react';\nimport {createFocusableRef} from '@react-spectrum/utils';\nimport Dash from '../ui-icons/Dash';\nimport {FieldErrorIcon, FieldGroup, FieldLabel, HelpText, Input} from './Field';\nimport {filterDOMProps, mergeProps, mergeRefs} from '@react-aria/utils';\nimport {FormContext} from './Form';\nimport {HelpTextProps, SpectrumLabelableProps} from '@react-types/shared';\nimport {pressScale} from './pressScale';\nimport {TextFieldRef} from '@react-types/textfield';\nimport {useButton, useFocusRing, useHover} from 'react-aria';\nimport {useSpectrumContextProps} from './useSpectrumContextProps';\n\n\nexport interface NumberFieldProps extends\n  Omit<AriaNumberFieldProps, 'children' | 'className' | 'style'>,\n  StyleProps,\n  SpectrumLabelableProps,\n  HelpTextProps {\n  /**\n   * Whether to hide the increment and decrement buttons.\n   * @default false\n   */\n  hideStepper?: boolean,\n  /**\n   * The size of the NumberField.\n   *\n   * @default 'M'\n   */\n  size?: 'S' | 'M' | 'L' | 'XL'\n}\n\nexport const NumberFieldContext = createContext<ContextValue<Partial<NumberFieldProps>, TextFieldRef>>(null);\n\nconst inputButton = style<ButtonRenderProps & {size: 'S' | 'M' | 'L' | 'XL', type: 'decrement' | 'increment'}>({\n  ...controlBorderRadius('sm'),\n  display: 'flex',\n  outlineStyle: 'none',\n  textAlign: 'center',\n  borderStyle: 'none',\n  alignItems: 'center',\n  justifyContent: 'center',\n  width: {\n    size: {\n      S: 16,\n      M: 20,\n      L: 24,\n      XL: 32\n    }\n  },\n  height: 'auto',\n  marginStart: {\n    default: 'text-to-control',\n    type: {\n      increment: 0\n    }\n  },\n  aspectRatio: 'square',\n  flexShrink: 0,\n  minHeight: 0,\n  transition: {\n    default: 'default',\n    forcedColors: 'none'\n  },\n  backgroundColor: {\n    default: baseColor('gray-100'),\n    isDisabled: 'disabled',\n    forcedColors: {\n      default: 'ButtonText',\n      isHovered: 'Highlight',\n      isDisabled: 'GrayText'\n    }\n  },\n  color: {\n    default: baseColor('neutral'),\n    isDisabled: 'disabled',\n    forcedColors: {\n      default: 'ButtonFace'\n    }\n  },\n  cursor: 'default'\n});\n\nconst iconStyles = style({\n  flexShrink: 0,\n  '--iconPrimary': {\n    type: 'fill',\n    value: 'currentColor'\n  }\n});\n\nconst stepperContainerStyles = style({\n  display: 'flex',\n  flexDirection: 'row',\n  gap: {\n    size: {\n      S: 8,\n      M: 4,\n      L: 8,\n      XL: 8\n    }\n  },\n  marginEnd: {\n    size: {\n      S: 2,\n      M: 4,\n      L: space(6),\n      XL: space(6)\n    }\n  }\n});\n\n/**\n * NumberFields allow users to input number values with a keyboard or increment/decrement with step buttons.\n */\nexport const NumberField = forwardRef(function NumberField(props: NumberFieldProps, ref: Ref<TextFieldRef>) {\n  [props, ref] = useSpectrumContextProps(props, ref, NumberFieldContext);\n  let {\n    label,\n    contextualHelp,\n    description: descriptionMessage,\n    errorMessage,\n    hideStepper,\n    isRequired,\n    size = 'M',\n    labelPosition = 'top',\n    necessityIndicator,\n    labelAlign = 'start',\n    UNSAFE_className = '',\n    UNSAFE_style,\n    ...numberFieldProps\n  } = props;\n  let formContext = useContext(FormContext);\n  let domRef = useRef<HTMLDivElement | null>(null);\n  let inputRef = useRef<HTMLInputElement | null>(null);\n  let decrementButtonRef = useRef<HTMLDivElement | null>(null);\n  let incrementButtonRef = useRef<HTMLDivElement | null>(null);\n\n  // Expose imperative interface for ref\n  useImperativeHandle(ref, () => ({\n    ...createFocusableRef(domRef, inputRef),\n    select() {\n      if (inputRef.current) {\n        inputRef.current.select();\n      }\n    },\n    getInputElement() {\n      return inputRef.current;\n    }\n  }));\n\n\n  return (\n    <AriaNumberField\n      isRequired={isRequired}\n      {...numberFieldProps}\n      style={UNSAFE_style}\n      className={UNSAFE_className + style(field(), getAllowedOverrides())({\n        isInForm: !!formContext,\n        labelPosition,\n        size\n      }, props.styles)}>\n      {\n          ({isDisabled, isInvalid}) => {\n            return  (\n              <>\n                <FieldLabel\n                  isDisabled={isDisabled}\n                  isRequired={isRequired}\n                  size={size}\n                  labelPosition={labelPosition}\n                  labelAlign={labelAlign}\n                  necessityIndicator={necessityIndicator}\n                  contextualHelp={contextualHelp}>\n                  {label}\n                </FieldLabel>\n                <FieldGroup\n                  role=\"presentation\"\n                  isDisabled={isDisabled}\n                  isInvalid={isInvalid}\n                  size={size}\n                  styles={style({\n                    ...fieldInput(),\n                    paddingStart: 'edge-to-text',\n                    paddingEnd: {\n                      default: 0,\n                      isStepperHidden: 'edge-to-text'\n                    }\n                  })({size, isStepperHidden: hideStepper})}>\n                  <InputContext.Consumer>\n                    {ctx => (\n                      <InputContext.Provider value={{...ctx, ref: mergeRefs((ctx as any)?.ref, inputRef)}}>\n                        <Input />\n                      </InputContext.Provider>\n                    )}\n                  </InputContext.Consumer>\n                  {isInvalid && <FieldErrorIcon isDisabled={isDisabled} />}\n                  {!hideStepper && <div className={stepperContainerStyles({size})}>\n                    <StepButton\n                      ref={decrementButtonRef}\n                      slot=\"decrement\"\n                      style={renderProps => pressScale(decrementButtonRef)(renderProps)}\n                      className={renderProps => inputButton({\n                        ...renderProps,\n                        type: 'decrement',\n                        size\n                      })}>\n                      <Dash size={size} className={iconStyles} />\n                    </StepButton>\n                    <StepButton\n                      ref={incrementButtonRef}\n                      slot=\"increment\"\n                      style={renderProps => pressScale(incrementButtonRef)(renderProps)}\n                      className={renderProps => inputButton({\n                        ...renderProps,\n                        type: 'increment',\n                        size\n                      })}>\n                      <Add size={size} className={iconStyles} />\n                    </StepButton>\n                  </div>}\n                </FieldGroup>\n                {descriptionMessage && <Text slot=\"description\">{descriptionMessage}</Text>}\n                <HelpText\n                  size={size}\n                  isDisabled={isDisabled}\n                  isInvalid={isInvalid}\n                  description={descriptionMessage}>\n                  {errorMessage}\n                </HelpText>\n              </>\n            );\n          }\n        }\n    </AriaNumberField>\n  );\n});\n\ninterface StepButtonProps extends AriaButtonProps {\n}\n\nconst additionalButtonHTMLAttributes = new Set(['form', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget', 'name', 'value']);\n\nlet StepButton = forwardRef((props: StepButtonProps, ref: ForwardedRef<HTMLDivElement>) => {\n  [props, ref] = useContextProps(props, ref, ButtonContext as any);\n  let ctx = props as any;\n  /**\n   * Must use div for now because Safari pointer event bugs on disabled form elements.\n   * Link https://bugs.webkit.org/show_bug.cgi?id=219188.\n   */\n  let {buttonProps, isPressed} = useButton({...props, elementType: 'div'}, ref);\n  let {focusProps, isFocused, isFocusVisible} = useFocusRing(props);\n  let {hoverProps, isHovered} = useHover(props);\n  let renderProps = useRenderProps({\n    ...props,\n    values: {isHovered, isPressed, isFocused, isFocusVisible, isDisabled: props.isDisabled || false},\n    defaultClassName: 'react-aria-Button'\n  });\n  return (\n    <div\n      {...filterDOMProps(props, {propNames: additionalButtonHTMLAttributes})}\n      {...mergeProps(buttonProps, focusProps, hoverProps)}\n      {...renderProps}\n      ref={ref}\n      slot={props.slot || undefined}\n      data-disabled={props.isDisabled || undefined}\n      data-pressed={ctx.isPressed || isPressed || undefined}\n      data-hovered={isHovered || undefined}\n      data-focused={isFocused || undefined}\n      data-focus-visible={isFocusVisible || undefined} />\n  );\n});\n\n// replace from RAC\nfunction useRenderProps(props: any) {\n  let {\n    className,\n    style,\n    children,\n    defaultClassName = undefined,\n    defaultChildren = undefined,\n    defaultStyle,\n    values\n  } = props;\n\n  return useMemo(() => {\n    let computedClassName: string | undefined;\n    let computedStyle: CSSProperties | undefined;\n    let computedChildren: ReactNode | undefined;\n\n    if (typeof className === 'function') {\n      computedClassName = className({...values, defaultClassName});\n    } else {\n      computedClassName = className;\n    }\n\n    if (typeof style === 'function') {\n      computedStyle = style({...values, defaultStyle: defaultStyle || {}});\n    } else {\n      computedStyle = style;\n    }\n\n    if (typeof children === 'function') {\n      computedChildren = children({...values, defaultChildren});\n    } else if (children == null) {\n      computedChildren = defaultChildren;\n    } else {\n      computedChildren = children;\n    }\n\n    return {\n      className: computedClassName ?? defaultClassName,\n      style: (computedStyle || defaultStyle) ? {...defaultStyle, ...computedStyle} : undefined,\n      children: computedChildren ?? defaultChildren,\n      'data-rac': ''\n    };\n  }, [className, style, children, defaultClassName, defaultChildren, defaultStyle, values]);\n}\n"],"names":[],"version":3,"file":"NumberField.css.map"}