@bento/listbox 0.2.1 → 0.2.2

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.
package/dist/index.cjs CHANGED
@@ -1,380 +1,744 @@
1
- 'use strict';
2
-
3
- var React4 = require('react');
4
- var collections = require('@react-aria/collections');
5
- var useProps = require('@bento/use-props');
6
- var slots = require('@bento/slots');
7
- var reactAria = require('react-aria');
8
- var useDataAttributes = require('@bento/use-data-attributes');
9
- var reactStately = require('react-stately');
10
- var reactAriaComponents = require('react-aria-components');
11
-
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
-
14
- var React4__default = /*#__PURE__*/_interopDefault(React4);
15
-
16
- // src/header.tsx
17
- var HeaderContext = React4.createContext({});
18
- var BentoHeaderImpl = slots.withSlots(
19
- "BentoHeader",
20
- function BentoHeader(props, ref) {
21
- const { props: processedProps, apply } = useProps.useProps(props);
22
- const contextProps = React4.useContext(HeaderContext);
23
- const appliedUserProps = apply(processedProps);
24
- const composed = {
25
- ...contextProps,
26
- ...appliedUserProps
27
- // User props take precedence over context
28
- };
29
- return /* @__PURE__ */ React4__default.default.createElement("header", { ...composed, ref: contextProps.ref || ref }, processedProps.children);
30
- }
31
- );
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let react = require("react");
25
+ react = __toESM(react, 1);
26
+ let _react_aria_collections = require("@react-aria/collections");
27
+ let _bento_use_props = require("@bento/use-props");
28
+ let _bento_slots = require("@bento/slots");
29
+ let react_jsx_runtime = require("react/jsx-runtime");
30
+ let react_aria = require("react-aria");
31
+ let _bento_use_data_attributes = require("@bento/use-data-attributes");
32
+ let react_stately = require("react-stately");
33
+ let react_aria_components = require("react-aria-components");
34
+ //#region src/header.tsx
35
+ /**
36
+ * React context for providing header-related attributes and refs to Header components.
37
+ * Used internally by ListBoxSection to pass heading props to Header elements.
38
+ * @public
39
+ */
40
+ const HeaderContext = (0, react.createContext)({});
41
+ /**
42
+ * Internal implementation of the BentoHeader component with slots support.
43
+ * This component handles prop processing and context integration.
44
+ * It merges props from useProps and HeaderContext while preserving styling props.
45
+ *
46
+ * @internal
47
+ */
48
+ const BentoHeaderImpl = (0, _bento_slots.withSlots)("BentoHeader", function BentoHeader(...args) {
49
+ const [props, ref] = args;
50
+ const { props: processedProps, apply } = (0, _bento_use_props.useProps)(props);
51
+ const contextProps = (0, react.useContext)(HeaderContext);
52
+ const appliedUserProps = apply(processedProps);
53
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
54
+ ...contextProps,
55
+ ...appliedUserProps,
56
+ ref: contextProps.ref || ref,
57
+ children: processedProps.children
58
+ });
59
+ });
60
+ /**
61
+ * Wrapper component that connects the BentoHeaderImpl to React Aria's collection system.
62
+ * This function serves as an adapter between the createLeafComponent system and
63
+ * the internal BentoHeaderImpl component, ensuring proper prop forwarding and ref handling.
64
+ *
65
+ * @param {HeaderProps} props - Header component props
66
+ * @param {React.ReactNode} [props.children] - React children to render inside the header
67
+ * @param {React.ForwardedRef<HTMLElement>} ref - Forwarded ref to the header element
68
+ * @returns {React.ReactElement} The BentoHeaderImpl component with forwarded props and ref
69
+ * @internal
70
+ */
32
71
  function HeaderWrapper(props, ref) {
33
- return /* @__PURE__ */ React4__default.default.createElement(BentoHeaderImpl, { ...props, ref });
72
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BentoHeaderImpl, {
73
+ ...props,
74
+ ref
75
+ });
34
76
  }
35
- var HeaderBase = collections.createLeafComponent("header", HeaderWrapper);
36
- var Header = HeaderBase;
37
- var BentoListBoxSectionImpl = slots.withSlots("BentoListBoxSection", function BentoListBoxSectionImpl2({ __node, children, title: titleProp, ...rest }, ref) {
38
- const { props, apply } = useProps.useProps(rest);
39
- const data = useDataAttributes.useDataAttributes({ level: __node?.level });
40
- const headingRef = React4.useRef(null);
41
- const title = titleProp ?? props.title ?? __node?.rendered;
42
- const { groupProps, headingProps } = reactAria.useListBoxSection({
43
- heading: title,
44
- "aria-label": props["aria-label"]
45
- });
46
- const composed = reactAria.mergeProps(apply({ ...data, ...props }, ["children", "title", "slot"]), groupProps);
47
- const sectionContent = children || props.children;
48
- return /* @__PURE__ */ React4__default.default.createElement("section", { ...composed, ref }, /* @__PURE__ */ React4__default.default.createElement(HeaderContext.Provider, { value: { ...headingProps, ref: headingRef } }, title && /* @__PURE__ */ React4__default.default.createElement("div", { ...headingProps }, title), sectionContent));
77
+ /**
78
+ * A Header component for section headings within a ListBox.
79
+ * Provides semantic header structure with proper accessibility attributes
80
+ * and integrates with React Aria's collection system for automatic handling.
81
+ *
82
+ * This is the main public interface for creating headers in ListBox sections.
83
+ * It automatically receives heading props from the parent ListBoxSection via HeaderContext.
84
+ *
85
+ * @component
86
+ * @example
87
+ * ```tsx
88
+ * <ListBoxSection>
89
+ * <Header>Fruits</Header>
90
+ * <ListBoxItem>Apple</ListBoxItem>
91
+ * <ListBoxItem>Banana</ListBoxItem>
92
+ * </ListBoxSection>
93
+ * ```
94
+ * @public
95
+ */
96
+ const Header = (0, _react_aria_collections.createLeafComponent)("header", HeaderWrapper);
97
+ //#endregion
98
+ //#region src/listbox-section.tsx
99
+ /**
100
+ * Internal implementation of the BentoListBoxSection component with slots support.
101
+ * This component handles the core logic for rendering a section within a ListBox,
102
+ * including title rendering, accessibility attributes, and child content management.
103
+ * It integrates with React Aria's useListBoxSection hook for proper ARIA compliance.
104
+ *
105
+ * @internal
106
+ */
107
+ const BentoListBoxSectionImpl = (0, _bento_slots.withSlots)("BentoListBoxSection", function BentoListBoxSectionImpl(...restArgs) {
108
+ const [{ __node, children, title: titleProp, ...rest }, ref] = restArgs;
109
+ const { props, apply } = (0, _bento_use_props.useProps)(rest);
110
+ const data = (0, _bento_use_data_attributes.useDataAttributes)({ level: __node?.level });
111
+ const headingRef = (0, react.useRef)(null);
112
+ const title = titleProp ?? props.title ?? __node?.rendered;
113
+ const { groupProps, headingProps } = (0, react_aria.useListBoxSection)({
114
+ heading: title,
115
+ "aria-label": props["aria-label"]
116
+ });
117
+ const composed = (0, react_aria.mergeProps)(apply({
118
+ ...data,
119
+ ...props
120
+ }, [
121
+ "children",
122
+ "title",
123
+ "slot"
124
+ ]), groupProps);
125
+ const sectionContent = children || props.children;
126
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
127
+ ...composed,
128
+ ref,
129
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HeaderContext.Provider, {
130
+ value: {
131
+ ...headingProps,
132
+ ref: headingRef
133
+ },
134
+ children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
135
+ ...headingProps,
136
+ children: title
137
+ }), sectionContent]
138
+ })
139
+ });
49
140
  });
141
+ /**
142
+ * Wrapper component that connects BentoListBoxSectionImpl to React Aria's collection system.
143
+ * This function serves as an adapter between createBranchComponent and the internal
144
+ * BentoListBoxSectionImpl, ensuring proper prop forwarding and node injection for sections.
145
+ *
146
+ * @template T - The type of the section node data
147
+ * @param {ListBoxSectionProps} props - ListBoxSection component props
148
+ * @param {string} [props.slot] - Slot name for Bento's slot system
149
+ * @param {React.ReactNode} [props.title] - Title for the section
150
+ * @param {React.ReactNode} [props.children] - Children to render in the section
151
+ * @param {string} [props.aria-label] - ARIA label for accessibility
152
+ * @param {React.ForwardedRef<HTMLElement>} ref - Ref forwarded from the collection system
153
+ * @param {Node<T>} section - React Aria node containing section metadata and collection info
154
+ * @returns {React.ReactElement} The BentoListBoxSectionImpl component with proper node and ref wiring
155
+ * @internal
156
+ */
157
+ /* v8 ignore start */
50
158
  function ListBoxSectionWrapper(props, ref, section) {
51
- return /* @__PURE__ */ React4__default.default.createElement(BentoListBoxSectionImpl, { ...props, __node: section, ref });
159
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BentoListBoxSectionImpl, {
160
+ ...props,
161
+ __node: section,
162
+ ref
163
+ });
52
164
  }
53
- var ListBoxSectionBase = collections.createBranchComponent("section", ListBoxSectionWrapper);
54
- var ListBoxSectionInner = function ListBoxSectionInner2({ section }) {
55
- const state = React4.useContext(ListStateContext);
56
- const { CollectionBranch } = React4.useContext(reactAriaComponents.CollectionRendererContext);
57
- return /* @__PURE__ */ React4__default.default.createElement(BentoListBoxSectionImpl, { ...section.props, __node: section }, CollectionBranch && state?.collection ? /* @__PURE__ */ React4__default.default.createElement(CollectionBranch, { collection: state.collection, parent: section }) : null);
165
+ /* v8 ignore stop */
166
+ /**
167
+ * Base ListBoxSection component created through React Aria's collection system.
168
+ * This handles the connection to the parent ListBox's collection state and
169
+ * manages the branch structure for nested items.
170
+ * @internal
171
+ */
172
+ const ListBoxSectionBase = (0, _react_aria_collections.createBranchComponent)("section", ListBoxSectionWrapper);
173
+ /**
174
+ * Internal component for rendering dynamic collection sections.
175
+ * This component is used specifically for sections that are part of a dynamic collection,
176
+ * connecting to the ListStateContext and CollectionRendererContext to properly render
177
+ * nested items through React Aria's collection system.
178
+ *
179
+ * @component
180
+ * @param {object} props - The component props containing the section node
181
+ * @param {Node<unknown>} props.section - The React Aria node representing this section in the collection
182
+ * @throws {BentoError} Throws an error if used outside of a ListBox context
183
+ * @returns {React.ReactElement} JSX element representing a dynamically rendered listbox section
184
+ * @internal
185
+ */
186
+ const ListBoxSectionInner = function ListBoxSectionInner({ section }) {
187
+ const state = (0, react.useContext)(ListStateContext);
188
+ const { CollectionBranch } = (0, react.useContext)(react_aria_components.CollectionRendererContext);
189
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BentoListBoxSectionImpl, {
190
+ ...section.props,
191
+ __node: section,
192
+ children: CollectionBranch && state?.collection ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollectionBranch, {
193
+ collection: state.collection,
194
+ parent: section
195
+ }) : null
196
+ });
58
197
  };
59
- var ListBoxSection = ListBoxSectionBase;
198
+ /**
199
+ * A section component for organizing related items within a ListBox.
200
+ *
201
+ * @component
202
+ * @example
203
+ * ```tsx
204
+ * <ListBoxSection title="Fruits">
205
+ * <ListBoxItem>Apple</ListBoxItem>
206
+ * <ListBoxItem>Banana</ListBoxItem>
207
+ * </ListBoxSection>
208
+ * ```
209
+ * @public
210
+ */
211
+ const ListBoxSection = ListBoxSectionBase;
212
+ //#endregion
213
+ //#region src/utils.ts
214
+ /* v8 ignore next */
215
+ /**
216
+ * NOTE: This utility will be moved to the new use-collection package.
217
+ * Safe wrapper for React Aria's useObjectRef that handles test environments where refs are not extensible.
218
+ *
219
+ * **Critical for Vitest Browser Mode Testing**: When running tests in Vitest's browser mode with Playwright,
220
+ * the test environment can freeze or make objects non-extensible. React Aria's `useObjectRef` attempts to
221
+ * dynamically add properties to ref objects, which fails with "Cannot add property current, object is not extensible"
222
+ * in these constrained test environments.
223
+ *
224
+ * **Technical Details:**
225
+ * - Vitest browser mode uses Playwright's Chrome DevTools Protocol for test execution
226
+ * - The V8 engine's security model can freeze objects during test isolation
227
+ * - React Aria's useObjectRef uses `Object.defineProperty()` to add reactive properties to refs
228
+ * - This conflicts with frozen objects in browser testing scenarios
229
+ *
230
+ * **Why This Solution Works:**
231
+ * - Creates an internal ref that's always mutable (created in our controlled environment)
232
+ * - Safely forwards values to the external ref using try/catch for frozen object scenarios
233
+ * - Maintains the same ref forwarding behavior as React Aria's useObjectRef in normal environments
234
+ * - Gracefully degrades in test environments without breaking functionality
235
+ *
236
+ * **Production Impact**: Zero. Object freezing only occurs in specific test configurations.
237
+ * In production and development, this behaves identically to React Aria's useObjectRef.
238
+ *
239
+ * @template T - The type of the ref element
240
+ * @param {React.ForwardedRef<T>} ref - The forwarded ref to handle safely
241
+ * @returns {React.RefObject<T>} A safe ref object that works in all environments including frozen test contexts
242
+ * @public
243
+ */
60
244
  function useSafeObjectRef(ref) {
61
- const internalRef = React4.useRef(null);
62
- React4.useEffect(function updateForwardedRef() {
63
- const current = internalRef.current;
64
- if (typeof ref === "function") {
65
- ref(current);
66
- } else if (ref && "current" in ref) {
67
- try {
68
- ref.current = current;
69
- } catch {
70
- }
71
- }
72
- });
73
- return internalRef;
245
+ const internalRef = (0, react.useRef)(null);
246
+ (0, react.useEffect)(function updateForwardedRef() {
247
+ const current = internalRef.current;
248
+ if (typeof ref === "function") ref(current);
249
+ else if (ref && "current" in ref) try {
250
+ ref.current = current;
251
+ } catch {}
252
+ });
253
+ return internalRef;
74
254
  }
75
-
76
- // src/listbox.tsx
77
- var ListStateContext = React4.createContext(null);
255
+ //#endregion
256
+ //#region src/listbox.tsx
257
+ /**
258
+ * React context for sharing ListBox state across components.
259
+ * This context provides the ListBox state to child components like ListBoxItem and ListBoxSection,
260
+ * enabling them to access selection state, collection data, and other shared functionality.
261
+ *
262
+ * @context
263
+ * @internal
264
+ */
265
+ const ListStateContext = (0, react.createContext)(null);
266
+ /**
267
+ * Custom hook to manage ListBox state creation and context handling.
268
+ * This hook either uses an existing state from context or creates a new one.
269
+ * It's designed to work both as a standalone component and within a parent component
270
+ * that provides ListBox state through context.
271
+ *
272
+ * @param {Record<string, unknown>} props - Configuration object for the ListBox state
273
+ * @returns {object} An object containing the state instance and context state flag
274
+ * @returns {ListState<unknown>} returns.state - The ListBox state instance
275
+ * @returns {ListState<unknown> | null} returns.contextState - Existing context state, if any
276
+ * @internal
277
+ */
78
278
  function useListBoxState(props) {
79
- const contextState = React4.useContext(ListStateContext);
80
- const stateProps = {
81
- ...props,
82
- children: void 0,
83
- items: void 0
84
- };
85
- const state = contextState ?? reactStately.useListState(stateProps);
86
- return { state, contextState };
279
+ const contextState = (0, react.useContext)(ListStateContext);
280
+ const stateProps = {
281
+ ...props,
282
+ children: void 0,
283
+ items: void 0
284
+ };
285
+ return {
286
+ state: contextState ?? (0, react_stately.useListState)(stateProps),
287
+ contextState
288
+ };
87
289
  }
290
+ /**
291
+ * Renders content with optional context provider wrapper.
292
+ * If no context state exists, wraps the content in a ListStateContext.Provider.
293
+ * This allows the ListBox to work both standalone and as part of a larger component tree.
294
+ *
295
+ * @param {React.ReactNode} content - The React content to render
296
+ * @param {ListState<unknown>} state - The ListBox state to provide via context
297
+ * @param {ListState<unknown> | null} contextState - Existing context state, if any
298
+ * @returns {React.ReactNode} The content, optionally wrapped in a context provider
299
+ * @internal
300
+ */
88
301
  function renderWithOptionalContext(content, state, contextState) {
89
- return contextState ? content : /* @__PURE__ */ React4__default.default.createElement(ListStateContext.Provider, { value: state }, content);
302
+ /* v8 ignore next */
303
+ return contextState ? content : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListStateContext.Provider, {
304
+ value: state,
305
+ children: content
306
+ });
90
307
  }
91
- function useKeyboardDelegate({
92
- collection,
93
- collator,
94
- listBoxRef,
95
- selectionManager,
96
- layout,
97
- orientation,
98
- direction,
99
- keyboardDelegate: providedDelegate
100
- }) {
101
- const { disabledBehavior, disabledKeys } = selectionManager;
102
- return React4.useMemo(
103
- function createKeyboardDelegate() {
104
- return providedDelegate || new reactAria.ListKeyboardDelegate({
105
- collection,
106
- collator,
107
- ref: listBoxRef,
108
- disabledKeys,
109
- disabledBehavior,
110
- layout,
111
- orientation,
112
- direction
113
- });
114
- },
115
- [collection, collator, listBoxRef, selectionManager, orientation, direction, layout, providedDelegate]
116
- );
308
+ /**
309
+ * Creates and memoizes a keyboard delegate for the ListBox.
310
+ * The keyboard delegate handles keyboard navigation logic, including
311
+ * arrow key navigation, home/end keys, and type-ahead functionality.
312
+ *
313
+ * @param {object} config - Configuration object for the keyboard delegate
314
+ * @param {ListState<unknown>['collection']} config.collection - The collection of items in the ListBox
315
+ * @param {Intl.Collator} config.collator - Intl collator for string comparison in type-ahead
316
+ * @param {React.RefObject<HTMLDivElement>} config.listBoxRef - Reference to the ListBox DOM element
317
+ * @param {ListState<unknown>['selectionManager']} config.selectionManager - Selection manager from the state
318
+ * @param {'stack' | 'grid'} [config.layout] - Layout mode (stack or grid)
319
+ * @param {Orientation} [config.orientation] - Primary orientation of the items
320
+ * @param {'ltr' | 'rtl'} config.direction - Text direction (ltr or rtl)
321
+ * @param {ListKeyboardDelegate<unknown>} [config.keyboardDelegate] - Custom keyboard delegate to use instead of default
322
+ * @returns {ListKeyboardDelegate<unknown>} A keyboard delegate instance for handling keyboard interactions
323
+ * @internal
324
+ */
325
+ function useKeyboardDelegate({ collection, collator, listBoxRef, selectionManager, layout, orientation, direction, keyboardDelegate: providedDelegate }) {
326
+ const { disabledBehavior, disabledKeys } = selectionManager;
327
+ return (0, react.useMemo)(function createKeyboardDelegate() {
328
+ return providedDelegate || new react_aria.ListKeyboardDelegate({
329
+ collection,
330
+ collator,
331
+ ref: listBoxRef,
332
+ disabledKeys,
333
+ disabledBehavior,
334
+ layout,
335
+ orientation,
336
+ direction
337
+ });
338
+ }, [
339
+ collection,
340
+ collator,
341
+ listBoxRef,
342
+ selectionManager,
343
+ orientation,
344
+ direction,
345
+ layout,
346
+ providedDelegate
347
+ ]);
117
348
  }
118
- function useListBoxDataAttributes({
119
- isEmpty,
120
- isFocused,
121
- isFocusVisible,
122
- layout,
123
- orientation,
124
- selectionManager,
125
- allowsTabNavigation,
126
- shouldFocusWrap,
127
- originalSelectionBehavior
128
- }) {
129
- return useDataAttributes.useDataAttributes({
130
- empty: isEmpty,
131
- focused: isFocused,
132
- "focus-visible": isFocusVisible,
133
- layout,
134
- orientation,
135
- "selection-mode": selectionManager.selectionMode !== "none" ? selectionManager.selectionMode : void 0,
136
- "selection-behavior": originalSelectionBehavior !== void 0 ? selectionManager.selectionBehavior : void 0,
137
- "allows-tab-navigation": allowsTabNavigation,
138
- "focus-wrap": shouldFocusWrap
139
- });
349
+ /**
350
+ * Generates data attributes for the ListBox element based on its current state.
351
+ * These attributes are used for styling selectors and accessibility indicators.
352
+ *
353
+ * @param {object} config - Configuration object containing ListBox state flags
354
+ * @param {boolean} config.isEmpty - Whether the listbox has no items
355
+ * @param {boolean} config.isFocused - Whether the listbox is currently focused
356
+ * @param {boolean} config.isFocusVisible - Whether focus should be visually indicated
357
+ * @param {'stack' | 'grid'} [config.layout] - Layout mode (stack or grid)
358
+ * @param {Orientation} [config.orientation] - Primary orientation of the items
359
+ * @param {ListState<unknown>['selectionManager']} config.selectionManager - Selection manager containing selection state
360
+ * @param {boolean} [config.allowsTabNavigation] - Whether tab navigation is enabled
361
+ * @param {boolean} [config.shouldFocusWrap] - Whether focus wraps at boundaries
362
+ * @param {SelectionBehavior} [config.originalSelectionBehavior] - Original selection behavior setting
363
+ * @returns {Record<string, unknown>} Object with data attributes for the ListBox element
364
+ * @internal
365
+ */
366
+ function useListBoxDataAttributes({ isEmpty, isFocused, isFocusVisible, layout, orientation, selectionManager, allowsTabNavigation, shouldFocusWrap, originalSelectionBehavior }) {
367
+ return (0, _bento_use_data_attributes.useDataAttributes)({
368
+ empty: isEmpty,
369
+ focused: isFocused,
370
+ "focus-visible": isFocusVisible,
371
+ layout,
372
+ orientation,
373
+ "selection-mode": selectionManager.selectionMode !== "none" ? selectionManager.selectionMode : void 0,
374
+ "selection-behavior": originalSelectionBehavior !== void 0 ? selectionManager.selectionBehavior : void 0,
375
+ "allows-tab-navigation": allowsTabNavigation,
376
+ "focus-wrap": shouldFocusWrap
377
+ });
140
378
  }
141
- function useComposedProps({
142
- otherProps,
143
- renderValues,
144
- listBoxProps,
145
- focusProps,
146
- dataAttributes,
147
- selectionManager,
148
- listBoxRef
149
- }) {
150
- const { apply } = useProps.useProps(otherProps, renderValues);
151
- const propsToExclude = [
152
- "renderEmptyState",
153
- "selectionMode",
154
- "defaultSelectedKeys",
155
- "disabledKeys",
156
- "disallowEmptySelection",
157
- "shouldFocusWrap",
158
- "items",
159
- "children",
160
- "selectionBehavior",
161
- "keyboardDelegate"
162
- ];
163
- const appliedUserProps = apply(otherProps, propsToExclude);
164
- const baseProps = {
165
- ...reactAria.mergeProps(listBoxProps, focusProps),
166
- ...dataAttributes,
167
- ...selectionManager.selectionMode !== "none" && {
168
- "aria-multiselectable": selectionManager.selectionMode === "multiple"
169
- }
170
- };
171
- const finalProps = {
172
- ...baseProps,
173
- ...appliedUserProps,
174
- ref: listBoxRef
175
- // Set ref directly to avoid extensibility issues
176
- };
177
- return finalProps;
379
+ /**
380
+ * Composes all props for the ListBox element including DOM props, ARIA props,
381
+ * focus props, and data attributes. Handles prop application through useProps
382
+ * and manages ref assignment to avoid proxy extensibility issues.
383
+ *
384
+ * @param {object} config - Configuration object containing all props to compose
385
+ * @param {Record<string, unknown>} config.otherProps - Additional props from the component
386
+ * @param {ListBoxRenderProps} config.renderValues - Values available to render functions
387
+ * @param {Record<string, unknown>} config.listBoxProps - Props from useListBox hook
388
+ * @param {Record<string, unknown>} config.focusProps - Props from useFocusRing hook
389
+ * @param {Record<string, unknown>} config.dataAttributes - Data attributes for styling/selectors
390
+ * @param {ListState<unknown>['selectionManager']} config.selectionManager - Selection manager for ARIA attributes
391
+ * @param {React.RefObject<HTMLDivElement>} config.listBoxRef - Reference to attach to the final element
392
+ * @returns {Record<string, unknown>} Composed props object ready for the ListBox element
393
+ * @internal
394
+ */
395
+ function useComposedProps({ otherProps, renderValues, listBoxProps, focusProps, dataAttributes, selectionManager, listBoxRef }) {
396
+ const { apply } = (0, _bento_use_props.useProps)(otherProps, renderValues);
397
+ const appliedUserProps = apply(otherProps, [
398
+ "renderEmptyState",
399
+ "selectionMode",
400
+ "defaultSelectedKeys",
401
+ "disabledKeys",
402
+ "disallowEmptySelection",
403
+ "shouldFocusWrap",
404
+ "items",
405
+ "children",
406
+ "selectionBehavior",
407
+ "keyboardDelegate"
408
+ ]);
409
+ return {
410
+ ...(0, react_aria.mergeProps)(listBoxProps, focusProps),
411
+ ...dataAttributes,
412
+ ...selectionManager.selectionMode !== "none" && { "aria-multiselectable": selectionManager.selectionMode === "multiple" },
413
+ ...appliedUserProps,
414
+ ref: listBoxRef
415
+ };
178
416
  }
417
+ /**
418
+ * Renders the empty state content for the ListBox when no items are present.
419
+ * Handles both function-based render props and direct JSX elements.
420
+ * If a function is provided, calls it with render values; otherwise returns as-is.
421
+ *
422
+ * @param {(props: ListBoxRenderProps) => React.ReactNode} renderEmptyStateFn - Function or JSX element to render for empty state
423
+ * @param {ListBoxRenderProps} renderValues - Current render values to pass to render function
424
+ * @returns {React.ReactNode} Rendered empty state content
425
+ * @internal
426
+ */
179
427
  function renderEmptyState(renderEmptyStateFn, renderValues) {
180
- if (typeof renderEmptyStateFn === "function") {
181
- return renderEmptyStateFn(renderValues);
182
- }
183
- return renderEmptyStateFn;
428
+ if (typeof renderEmptyStateFn === "function") return renderEmptyStateFn(renderValues);
429
+ return renderEmptyStateFn;
184
430
  }
431
+ /**
432
+ * Renders all items in the collection as React elements.
433
+ * Handles both regular items and section items, using the appropriate
434
+ * components (ListBoxItemImpl for items, ListBoxSectionInner for sections).
435
+ *
436
+ * @param {ListState<unknown>['collection']} collection - The collection of items to render
437
+ * @returns {React.ReactElement[]} Array of rendered React elements for all collection items
438
+ * @internal
439
+ */
185
440
  function renderCollectionItems(collection) {
186
- return [...collection].map(function renderCollectionItem(item) {
187
- return item.type === "section" ? /* @__PURE__ */ React4__default.default.createElement(ListBoxSectionInner, { key: item.key, section: item }) : /* @__PURE__ */ React4__default.default.createElement(ListBoxItemImpl, { key: item.key, __node: item }, item.rendered);
188
- });
441
+ return [...collection].map(function renderCollectionItem(item) {
442
+ return item.type === "section" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListBoxSectionInner, { section: item }, item.key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListBoxItemImpl, {
443
+ __node: item,
444
+ children: item.rendered
445
+ }, item.key);
446
+ });
189
447
  }
190
- function renderListBoxContent({
191
- children,
192
- items,
193
- isEmpty,
194
- renderEmptyStateProp,
195
- renderValues,
196
- collection
197
- }) {
198
- const hasRenderChildren = typeof children === "function" && !items;
199
- if (hasRenderChildren) {
200
- return children(renderValues);
201
- }
202
- if (isEmpty && renderEmptyStateProp) {
203
- return renderEmptyState(renderEmptyStateProp, renderValues);
204
- }
205
- return renderCollectionItems(collection);
448
+ /**
449
+ * Determines what content to render inside the ListBox based on its configuration.
450
+ * Handles three cases:
451
+ * 1. Function children without items (Bento render prop pattern with full render props)
452
+ * 2. Empty state when no items and renderEmptyState is provided
453
+ * 3. Normal collection rendering (including items with children functions for React Aria compatibility)
454
+ *
455
+ * @param {object} config - Configuration object for rendering
456
+ * @param {React.ReactNode | ((item: unknown) => React.ReactNode) | ((props: ListBoxRenderProps) => React.ReactNode)} [config.children] - Children prop (static, item render function, or ListBox render prop)
457
+ * @param {Iterable<unknown>} [config.items] - Items array for dynamic collections
458
+ * @param {boolean} config.isEmpty - Whether the collection is empty
459
+ * @param {(props: ListBoxRenderProps) => React.ReactNode} [config.renderEmptyStateProp] - Function to render empty state
460
+ * @param {ListBoxRenderProps} config.renderValues - Current render values for render functions
461
+ * @param {ListState<unknown>['collection']} config.collection - The collection state to render
462
+ * @returns {React.ReactNode} The appropriate content to render inside the ListBox
463
+ * @internal
464
+ */
465
+ function renderListBoxContent({ children, items, isEmpty, renderEmptyStateProp, renderValues, collection }) {
466
+ /* v8 ignore next 3 */
467
+ if (typeof children === "function" && !items) return children(renderValues);
468
+ if (isEmpty && renderEmptyStateProp) return renderEmptyState(renderEmptyStateProp, renderValues);
469
+ return renderCollectionItems(collection);
206
470
  }
207
- var ListBoxInner = function ListBoxInner2({
208
- state,
209
- renderEmptyState: renderEmptyStateProp,
210
- children,
211
- items,
212
- listBoxRef,
213
- ...otherProps
214
- }) {
215
- const { layout = "stack", orientation = "vertical", shouldSelectOnPressUp, selectionBehavior } = otherProps;
216
- const { collection, selectionManager } = state;
217
- const { direction } = reactAria.useLocale();
218
- const collator = reactAria.useCollator({ usage: "search", sensitivity: "base" });
219
- const keyboardDelegate = useKeyboardDelegate({
220
- collection,
221
- collator,
222
- listBoxRef,
223
- selectionManager,
224
- layout,
225
- orientation,
226
- direction,
227
- keyboardDelegate: otherProps.keyboardDelegate
228
- });
229
- const { listBoxProps } = reactAria.useListBox(
230
- {
231
- ...otherProps,
232
- shouldSelectOnPressUp,
233
- keyboardDelegate
234
- },
235
- state,
236
- listBoxRef
237
- );
238
- const { focusProps, isFocused, isFocusVisible } = reactAria.useFocusRing();
239
- const isEmpty = state.collection.size === 0;
240
- const renderValues = {
241
- isEmpty,
242
- isFocused,
243
- isFocusVisible,
244
- isDropTarget: false,
245
- layout,
246
- state,
247
- items
248
- };
249
- const dataAttributes = useListBoxDataAttributes({
250
- isEmpty,
251
- isFocused,
252
- isFocusVisible,
253
- layout,
254
- orientation,
255
- selectionManager,
256
- allowsTabNavigation: otherProps.allowsTabNavigation,
257
- shouldFocusWrap: otherProps.shouldFocusWrap,
258
- originalSelectionBehavior: selectionBehavior
259
- });
260
- const composedProps = useComposedProps({
261
- otherProps,
262
- renderValues,
263
- listBoxProps,
264
- focusProps,
265
- dataAttributes,
266
- selectionManager,
267
- listBoxRef
268
- });
269
- return /* @__PURE__ */ React4__default.default.createElement(reactAria.FocusScope, null, /* @__PURE__ */ React4__default.default.createElement("div", { ...composedProps }, renderListBoxContent({
270
- children,
271
- items,
272
- isEmpty,
273
- renderEmptyStateProp,
274
- renderValues,
275
- collection
276
- })));
471
+ /**
472
+ * Internal ListBox component that handles the core rendering logic.
473
+ * This component manages all the hooks, state, and prop composition needed
474
+ * for a fully functional ListBox. It's wrapped by the main ListBox component
475
+ * which handles collection building.
476
+ *
477
+ * @param {object} props - Component props
478
+ * @param {ListState<unknown>} props.state - The ListBox state instance
479
+ * @param {(props: ListBoxRenderProps) => React.ReactNode} [props.renderEmptyState] - Function to render when no items are present
480
+ * @param {React.ReactNode | ((item: unknown) => React.ReactNode) | ((props: ListBoxRenderProps) => React.ReactNode)} [props.children] - Static children, item render function, or ListBox render function
481
+ * @param {Iterable<unknown>} [props.items] - Items array for dynamic collections
482
+ * @param {React.RefObject<HTMLDivElement>} props.listBoxRef - Reference to the ListBox DOM element
483
+ * @param {'stack'} [props.layout] - Layout mode (stack or grid)
484
+ * @param {Orientation} [props.orientation] - Primary orientation of the items
485
+ * @param {boolean} [props.shouldSelectOnPressUp] - Whether selection occurs on pointer up
486
+ * @param {ListKeyboardDelegate<unknown>} [props.keyboardDelegate] - Custom keyboard navigation delegate
487
+ * @param {boolean} [props.allowsTabNavigation] - Whether tab key navigates between items
488
+ * @param {boolean} [props.shouldFocusWrap] - Whether focus wraps at boundaries
489
+ * @param {'none' | 'single' | 'multiple'} [props.selectionMode] - Selection mode (none, single, multiple)
490
+ * @param {SelectionBehavior} [props.selectionBehavior] - Selection behavior (toggle, replace)
491
+ * @returns {React.ReactElement} A fully functional ListBox element with focus scope
492
+ * @internal
493
+ */
494
+ const ListBoxInner = function ListBoxInner({ state, renderEmptyState: renderEmptyStateProp, children, items, listBoxRef, ...otherProps }) {
495
+ const { layout = "stack", orientation = "vertical", shouldSelectOnPressUp, selectionBehavior } = otherProps;
496
+ const { collection, selectionManager } = state;
497
+ const { direction } = (0, react_aria.useLocale)();
498
+ const keyboardDelegate = useKeyboardDelegate({
499
+ collection,
500
+ collator: (0, react_aria.useCollator)({
501
+ usage: "search",
502
+ sensitivity: "base"
503
+ }),
504
+ listBoxRef,
505
+ selectionManager,
506
+ layout,
507
+ orientation,
508
+ direction,
509
+ keyboardDelegate: otherProps.keyboardDelegate
510
+ });
511
+ const { listBoxProps } = (0, react_aria.useListBox)({
512
+ ...otherProps,
513
+ shouldSelectOnPressUp,
514
+ keyboardDelegate
515
+ }, state, listBoxRef);
516
+ const { focusProps, isFocused, isFocusVisible } = (0, react_aria.useFocusRing)();
517
+ const isEmpty = state.collection.size === 0;
518
+ const renderValues = {
519
+ isEmpty,
520
+ isFocused,
521
+ isFocusVisible,
522
+ isDropTarget: false,
523
+ layout,
524
+ state,
525
+ items
526
+ };
527
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_aria.FocusScope, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
528
+ ...useComposedProps({
529
+ otherProps,
530
+ renderValues,
531
+ listBoxProps,
532
+ focusProps,
533
+ dataAttributes: useListBoxDataAttributes({
534
+ isEmpty,
535
+ isFocused,
536
+ isFocusVisible,
537
+ layout,
538
+ orientation,
539
+ selectionManager,
540
+ allowsTabNavigation: otherProps.allowsTabNavigation,
541
+ shouldFocusWrap: otherProps.shouldFocusWrap,
542
+ originalSelectionBehavior: selectionBehavior
543
+ }),
544
+ selectionManager,
545
+ listBoxRef
546
+ }),
547
+ children: renderListBoxContent({
548
+ children,
549
+ items,
550
+ isEmpty,
551
+ renderEmptyStateProp,
552
+ renderValues,
553
+ collection
554
+ })
555
+ }) });
277
556
  };
278
- function ListBoxComponent(args, ref) {
279
- return /* @__PURE__ */ React4__default.default.createElement(collections.CollectionBuilder, { content: /* @__PURE__ */ React4__default.default.createElement(collections.Collection, { ...args }) }, function buildCollection(collection) {
280
- return /* @__PURE__ */ React4__default.default.createElement(StandaloneListBox, { props: args, listBoxRef: ref, collection });
281
- });
557
+ /**
558
+ * A complete ListBox component providing accessible selection lists with keyboard navigation.
559
+ * Supports both static children and dynamic collections, with single/multiple selection modes.
560
+ * Built on React Aria with full ARIA compliance and keyboard accessibility.
561
+ *
562
+ * @component
563
+ * @template T The type of items in the collection
564
+ * @param {ListBoxProps<T>} args - The properties passed to the ListBox component
565
+ * @param {React.ForwardedRef<HTMLDivElement>} ref - The ref to the listbox container
566
+ * @returns {React.ReactElement} A ListBox component
567
+ *
568
+ * @example
569
+ * ```tsx
570
+ * <ListBox aria-label="Fruits" selectionMode="single">
571
+ * <ListBoxItem id="apple" textValue="Apple">Apple</ListBoxItem>
572
+ * <ListBoxItem id="banana" textValue="Banana">Banana</ListBoxItem>
573
+ * </ListBox>
574
+ * ```
575
+ * @public
576
+ */
577
+ function ListBoxComponent(...args) {
578
+ const [_args, ref] = args;
579
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_aria_collections.CollectionBuilder, {
580
+ content: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_aria_collections.Collection, { ..._args }),
581
+ children: function buildCollection(collection) {
582
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StandaloneListBox, {
583
+ props: _args,
584
+ listBoxRef: ref,
585
+ collection
586
+ });
587
+ }
588
+ });
282
589
  }
283
- var StandaloneListBox = function StandaloneListBox2({ props, listBoxRef, collection }) {
284
- const originalRenderEmptyState = props.renderEmptyState;
285
- const { props: processedProps } = useProps.useProps(props);
286
- const processedRef = useSafeObjectRef(listBoxRef);
287
- const { state, contextState } = useListBoxState({ ...processedProps, collection });
288
- const { renderEmptyState: _, ...cleanProcessedProps } = processedProps;
289
- const content = /* @__PURE__ */ React4__default.default.createElement(
290
- ListBoxInner,
291
- {
292
- state,
293
- listBoxRef: processedRef,
294
- renderEmptyState: originalRenderEmptyState,
295
- ...cleanProcessedProps
296
- }
297
- );
298
- return renderWithOptionalContext(content, state, contextState);
299
- };
300
- var ListBox = slots.withSlots("BentoListBox", ListBoxComponent);
301
- var TextContext = React4.createContext({ slots: {} });
302
- var ListBoxItemImplComponent = function ListBoxItemImplComponent2({ __node, ...props }, ref) {
303
- const state = React4.useContext(ListStateContext);
304
- const safeRef = useSafeObjectRef(ref);
305
- const { optionProps, labelProps, descriptionProps, ...states } = reactAria.useOption(
306
- {
307
- key: __node.key,
308
- "aria-label": props["aria-label"],
309
- isDisabled: props.isDisabled
310
- },
311
- state,
312
- safeRef
313
- );
314
- const { hoverProps, isHovered } = reactAria.useHover({
315
- isDisabled: states.isDisabled,
316
- onHoverStart: props.onHoverStart,
317
- onHoverChange: props.onHoverChange,
318
- onHoverEnd: props.onHoverEnd
319
- });
320
- const renderValues = {
321
- ...states,
322
- isHovered,
323
- selectionMode: state.selectionManager.selectionMode,
324
- selectionBehavior: state.selectionManager.selectionBehavior
325
- };
326
- const content = typeof props.children === "function" ? props.children(renderValues) : props.children;
327
- const { apply } = useProps.useProps(props, renderValues);
328
- const dataAttributes = useDataAttributes.useDataAttributes({
329
- selected: states.isSelected,
330
- disabled: states.isDisabled,
331
- hovered: isHovered,
332
- focused: states.isFocused,
333
- "focus-visible": states.isFocusVisible,
334
- pressed: states.isPressed,
335
- level: __node.level,
336
- "selection-mode": state.selectionManager.selectionMode,
337
- "selection-behavior": state.selectionManager.selectionBehavior
338
- });
339
- const textContext = React4.useMemo(
340
- function createTextContext() {
341
- return {
342
- slots: {
343
- label: labelProps,
344
- description: descriptionProps
345
- }
346
- };
347
- },
348
- [labelProps, descriptionProps]
349
- );
350
- const ElementType = __node.props.href ? "a" : "div";
351
- const appliedUserProps = apply(__node.props, ["ref"]);
352
- const finalAttributes = {
353
- ...reactAria.mergeProps(optionProps, hoverProps),
354
- // React Aria props
355
- ...dataAttributes,
356
- // Bento data attributes
357
- ...appliedUserProps,
358
- ref: safeRef,
359
- "data-text-value": __node.textValue
360
- };
361
- return /* @__PURE__ */ React4__default.default.createElement(TextContext.Provider, { value: textContext }, React4__default.default.createElement(ElementType, finalAttributes, content));
590
+ /**
591
+ * Standalone ListBox component that manages its own state and collection.
592
+ * This component is used internally by the main ListBox component after
593
+ * collection building is complete. It handles prop processing, state creation,
594
+ * and context management.
595
+ *
596
+ * @param {object} props - Component props
597
+ * @param {ListBoxProps<unknown>} props.props - The original ListBox props
598
+ * @param {React.ForwardedRef<HTMLDivElement>} props.listBoxRef - Reference to forward to the ListBox element
599
+ * @param {unknown} props.collection - Built collection from CollectionBuilder
600
+ * @returns {React.ReactElement} A complete ListBox with state management and optional context wrapping
601
+ * @internal
602
+ */
603
+ const StandaloneListBox = function StandaloneListBox({ props, listBoxRef, collection }) {
604
+ const originalRenderEmptyState = props.renderEmptyState;
605
+ const { props: processedProps } = (0, _bento_use_props.useProps)(props);
606
+ const processedRef = useSafeObjectRef(listBoxRef);
607
+ const { state, contextState } = useListBoxState({
608
+ ...processedProps,
609
+ collection
610
+ });
611
+ const { renderEmptyState: _, ...cleanProcessedProps } = processedProps;
612
+ return renderWithOptionalContext(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListBoxInner, {
613
+ state,
614
+ listBoxRef: processedRef,
615
+ renderEmptyState: originalRenderEmptyState,
616
+ ...cleanProcessedProps
617
+ }), state, contextState);
362
618
  };
363
- var ListBoxItemImpl = slots.withSlots("BentoListBoxItem", ListBoxItemImplComponent);
619
+ /**
620
+ * A complete ListBox component providing accessible selection lists with keyboard navigation.
621
+ * Supports both static children and dynamic collections, with single/multiple selection modes.
622
+ * Built on React Aria with full ARIA compliance and keyboard accessibility.
623
+ *
624
+ * @component
625
+ * @example
626
+ * ```tsx
627
+ * <ListBox aria-label="Fruits" selectionMode="single">
628
+ * <ListBoxItem id="apple" textValue="Apple">Apple</ListBoxItem>
629
+ * <ListBoxItem id="banana" textValue="Banana">Banana</ListBoxItem>
630
+ * </ListBox>
631
+ * ```
632
+ * @public
633
+ */
634
+ const ListBox = (0, _bento_slots.withSlots)("BentoListBox", ListBoxComponent);
635
+ //#endregion
636
+ //#region src/listbox-item.tsx
637
+ /**
638
+ * Internal context for providing text-related slot attributes to child components.
639
+ * This context allows ListBoxItem to pass label and description attributes
640
+ * to nested components that need them for accessibility.
641
+ * @internal
642
+ */
643
+ const TextContext = (0, react.createContext)({ slots: {} });
644
+ /**
645
+ * Enhanced ListBoxItem implementation with slots support.
646
+ * This wraps the core ListBoxItemImplComponent with Bento's slot system
647
+ * for advanced composition and styling capabilities.
648
+ * @internal
649
+ */
650
+ const ListBoxItemImpl = (0, _bento_slots.withSlots)("BentoListBoxItem", function ListBoxItemImplComponent(...restArgs) {
651
+ const [{ __node, ...props }, ref] = restArgs;
652
+ const state = (0, react.useContext)(ListStateContext);
653
+ const safeRef = useSafeObjectRef(ref);
654
+ const { optionProps, labelProps, descriptionProps, ...states } = (0, react_aria.useOption)({
655
+ key: __node.key,
656
+ "aria-label": props["aria-label"],
657
+ isDisabled: props.isDisabled
658
+ }, state, safeRef);
659
+ const { hoverProps, isHovered } = (0, react_aria.useHover)({
660
+ isDisabled: states.isDisabled,
661
+ onHoverStart: props.onHoverStart,
662
+ onHoverChange: props.onHoverChange,
663
+ onHoverEnd: props.onHoverEnd
664
+ });
665
+ const renderValues = {
666
+ ...states,
667
+ isHovered,
668
+ selectionMode: state.selectionManager.selectionMode,
669
+ selectionBehavior: state.selectionManager.selectionBehavior
670
+ };
671
+ const content = typeof props.children === "function" ? props.children(renderValues) : props.children;
672
+ const { apply } = (0, _bento_use_props.useProps)(props, renderValues);
673
+ const dataAttributes = (0, _bento_use_data_attributes.useDataAttributes)({
674
+ selected: states.isSelected,
675
+ disabled: states.isDisabled,
676
+ hovered: isHovered,
677
+ focused: states.isFocused,
678
+ "focus-visible": states.isFocusVisible,
679
+ pressed: states.isPressed,
680
+ level: __node.level,
681
+ "selection-mode": state.selectionManager.selectionMode,
682
+ "selection-behavior": state.selectionManager.selectionBehavior
683
+ });
684
+ const textContext = (0, react.useMemo)(function createTextContext() {
685
+ return { slots: {
686
+ label: labelProps,
687
+ description: descriptionProps
688
+ } };
689
+ }, [labelProps, descriptionProps]);
690
+ const ElementType = __node.props.href ? "a" : "div";
691
+ const appliedUserProps = apply(__node.props, ["ref"]);
692
+ const finalAttributes = {
693
+ ...(0, react_aria.mergeProps)(optionProps, hoverProps),
694
+ ...dataAttributes,
695
+ ...appliedUserProps,
696
+ ref: safeRef,
697
+ "data-text-value": __node.textValue
698
+ };
699
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TextContext.Provider, {
700
+ value: textContext,
701
+ children: react.default.createElement(ElementType, finalAttributes, content)
702
+ });
703
+ });
704
+ /**
705
+ * Adapter component that connects ListBoxItemImpl to React Aria's collection system.
706
+ * This function serves as a bridge between React Aria's createLeafComponent and
707
+ * the internal ListBoxItemImpl, ensuring proper prop forwarding and node injection.
708
+ *
709
+ * @template T - The type of the item value
710
+ * @param {ListBoxItemProps<T>} props - ListBoxItem component props
711
+ * @param {React.ForwardedRef<HTMLDivElement>} forwardedRef - Ref forwarded from the collection system
712
+ * @param {Node<T>} item - React Aria node containing item metadata and collection info
713
+ * @returns {React.ReactElement} The ListBoxItemImpl component with proper node and ref wiring
714
+ * @internal
715
+ */
364
716
  function ListBoxItemComponent(props, forwardedRef, item) {
365
- return /* @__PURE__ */ React4__default.default.createElement(ListBoxItemImpl, { ...props, ref: forwardedRef, __node: item });
717
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ListBoxItemImpl, {
718
+ ...props,
719
+ ref: forwardedRef,
720
+ __node: item
721
+ });
366
722
  }
367
- var ListBoxItemBase = collections.createLeafComponent("item", ListBoxItemComponent);
368
- var ListBoxItem = ListBoxItemBase;
369
-
370
- Object.defineProperty(exports, "Collection", {
371
- enumerable: true,
372
- get: function () { return collections.Collection; }
373
- });
723
+ /**
724
+ * A single item within a ListBox component.
725
+ * Handles user interactions, accessibility, and state management for individual options.
726
+ *
727
+ * @component
728
+ * @template T The type of the item value
729
+ * @example
730
+ * ```tsx
731
+ * <ListBoxItem>Simple option</ListBoxItem>
732
+ * ```
733
+ * @public
734
+ */
735
+ const ListBoxItem = (0, _react_aria_collections.createLeafComponent)("item", ListBoxItemComponent);
736
+ //#endregion
737
+ exports.Collection = _react_aria_collections.Collection;
374
738
  exports.Header = Header;
375
739
  exports.HeaderContext = HeaderContext;
376
740
  exports.ListBox = ListBox;
377
741
  exports.ListBoxItem = ListBoxItem;
378
742
  exports.ListBoxSection = ListBoxSection;
379
- //# sourceMappingURL=index.cjs.map
743
+
380
744
  //# sourceMappingURL=index.cjs.map