UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

194 lines (192 loc) 7.23 kB
"use strict"; 'use client'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectRoot = void 0; var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _useSelectRoot = require("./useSelectRoot"); var _SelectRootContext = require("./SelectRootContext"); var _SelectIndexContext = require("./SelectIndexContext"); var _FieldRootContext = require("../../field/root/FieldRootContext"); var _visuallyHidden = require("../../utils/visuallyHidden"); var _PortalContext = require("../../portal/PortalContext"); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const inertStyle = ` [data-floating-ui-inert] { pointer-events: none !important; } `; /** * Groups all parts of the select. * Doesn’t render its own HTML element. * * Documentation: [Base UI Select](https://base-ui.com/react/components/select) */ const SelectRoot = exports.SelectRoot = function SelectRoot(props) { const { value: valueProp, defaultValue = null, onValueChange, open, defaultOpen = false, onOpenChange, alignItemToTrigger = true, name, disabled = false, readOnly = false, required = false, modal = true } = props; const selectRoot = (0, _useSelectRoot.useSelectRoot)({ value: valueProp, defaultValue, onValueChange, open, defaultOpen, onOpenChange, alignItemToTrigger, name, disabled, readOnly, required, modal }); const { setDirty, validityData } = (0, _FieldRootContext.useFieldRootContext)(); const { rootContext } = selectRoot; const value = rootContext.value; const serializedValue = React.useMemo(() => { if (value == null) { return ''; // avoid uncontrolled -> controlled error } if (typeof value === 'string') { return value; } return JSON.stringify(value); }, [value]); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectRootContext.SelectRootContext.Provider, { value: selectRoot.rootContext, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_SelectIndexContext.SelectIndexContext.Provider, { value: selectRoot.indexContext, children: [selectRoot.rootContext.open && modal && /*#__PURE__*/ /* eslint-disable-next-line react/no-danger */ (0, _jsxRuntime.jsx)("style", { dangerouslySetInnerHTML: { __html: inertStyle } }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_PortalContext.PortalContext.Provider, { value: rootContext.mounted, children: props.children }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", { ...rootContext.fieldControlValidation.getInputValidationProps({ onFocus() { // Move focus to the trigger element when the hidden input is focused. rootContext.triggerElement?.focus(); }, // Handle browser autofill. onChange(event) { // Workaround for https://github.com/facebook/react/issues/9023 if (event.nativeEvent.defaultPrevented) { return; } const nextValue = event.target.value; const exactValue = rootContext.valuesRef.current.find(v => v === nextValue || typeof value === 'string' && nextValue.toLowerCase() === v.toLowerCase()); if (exactValue != null) { setDirty(exactValue !== validityData.initialValue); rootContext.setValue?.(exactValue, event.nativeEvent); } }, id: rootContext.id, name: rootContext.name, disabled: rootContext.disabled, required: rootContext.required, readOnly: rootContext.readOnly, value: serializedValue, ref: rootContext.fieldControlValidation.inputRef, style: _visuallyHidden.visuallyHidden, tabIndex: -1, 'aria-hidden': true }) })] }) }); }; process.env.NODE_ENV !== "production" ? SelectRoot.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │ // └─────────────────────────────────────────────────────────────────────┘ /** * Determines if the selected item inside the popup should align to the trigger element. * @default true */ alignItemToTrigger: _propTypes.default.bool, /** * @ignore */ children: _propTypes.default.node, /** * Whether the select menu is initially open. * * To render a controlled select menu, use the `open` prop instead. * @default false */ defaultOpen: _propTypes.default.bool, /** * The uncontrolled value of the select when it’s initially rendered. * * To render a controlled select, use the `value` prop instead. * @default null */ defaultValue: _propTypes.default.any, /** * Whether the component should ignore user interaction. * @default false */ disabled: _propTypes.default.bool, /** * Whether the select should prevent outside clicks and lock page scroll when open. * @default true */ modal: _propTypes.default.bool, /** * Identifies the field when a form is submitted. */ name: _propTypes.default.string, /** * Event handler called when the select menu is opened or closed. */ onOpenChange: _propTypes.default.func, /** * Callback fired when the value of the select changes. Use when controlled. */ onValueChange: _propTypes.default.func, /** * Whether the select menu is currently open. */ open: _propTypes.default.bool, /** * Whether the user should be unable to choose a different option from the select menu. * @default false */ readOnly: _propTypes.default.bool, /** * Whether the user must choose a value before submitting a form. * @default false */ required: _propTypes.default.bool, /** * The value of the select. */ value: _propTypes.default.any } : void 0;