@react-spectrum/s2
Version:
Spectrum 2 UI components in React
1 lines • 12.4 kB
Source Map (JSON)
{"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"}