@bareboard/react-native 0.0.0-stage → 0.1.0

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.
Files changed (127) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +24 -2
  3. package/dist/components/button/button.d.ts +12 -0
  4. package/dist/components/button/button.js +10 -0
  5. package/dist/components/checkbox/checkbox.d.ts +5 -0
  6. package/dist/components/checkbox/checkbox.js +7 -0
  7. package/dist/components/close-button/close-button.d.ts +5 -0
  8. package/dist/components/close-button/close-button.js +14 -0
  9. package/dist/components/combobox/combobox-machine-glue.d.ts +6 -0
  10. package/dist/components/combobox/combobox-machine-glue.js +16 -0
  11. package/dist/components/combobox/combobox-machine.d.ts +143 -0
  12. package/dist/components/combobox/combobox-machine.js +377 -0
  13. package/dist/components/combobox/combobox.d.ts +66 -0
  14. package/dist/components/combobox/combobox.js +199 -0
  15. package/dist/components/data-interactive/data-interactive.d.ts +4 -0
  16. package/dist/components/data-interactive/data-interactive.js +8 -0
  17. package/dist/components/description/description.d.ts +4 -0
  18. package/dist/components/description/description.js +6 -0
  19. package/dist/components/dialog/dialog.d.ts +22 -0
  20. package/dist/components/dialog/dialog.js +27 -0
  21. package/dist/components/disclosure/disclosure.d.ts +35 -0
  22. package/dist/components/disclosure/disclosure.js +35 -0
  23. package/dist/components/field/field.d.ts +6 -0
  24. package/dist/components/field/field.js +9 -0
  25. package/dist/components/fieldset/fieldset.d.ts +3 -0
  26. package/dist/components/fieldset/fieldset.js +3 -0
  27. package/dist/components/focus-trap/focus-trap.d.ts +5 -0
  28. package/dist/components/focus-trap/focus-trap.js +5 -0
  29. package/dist/components/input/input.d.ts +6 -0
  30. package/dist/components/input/input.js +9 -0
  31. package/dist/components/label/label.d.ts +6 -0
  32. package/dist/components/label/label.js +9 -0
  33. package/dist/components/legend/legend.d.ts +6 -0
  34. package/dist/components/legend/legend.js +9 -0
  35. package/dist/components/listbox/listbox-machine-glue.d.ts +6 -0
  36. package/dist/components/listbox/listbox-machine-glue.js +16 -0
  37. package/dist/components/listbox/listbox-machine.d.ts +140 -0
  38. package/dist/components/listbox/listbox-machine.js +347 -0
  39. package/dist/components/listbox/listbox.d.ts +53 -0
  40. package/dist/components/listbox/listbox.js +91 -0
  41. package/dist/components/listbox-label/listbox-label.d.ts +2 -0
  42. package/dist/components/listbox-label/listbox-label.js +2 -0
  43. package/dist/components/listbox-selected-option/listbox-selected-option.d.ts +7 -0
  44. package/dist/components/listbox-selected-option/listbox-selected-option.js +16 -0
  45. package/dist/components/menu/menu-machine-glue.d.ts +6 -0
  46. package/dist/components/menu/menu-machine-glue.js +16 -0
  47. package/dist/components/menu/menu-machine.d.ts +109 -0
  48. package/dist/components/menu/menu-machine.js +238 -0
  49. package/dist/components/menu/menu.d.ts +34 -0
  50. package/dist/components/menu/menu.js +60 -0
  51. package/dist/components/menu-heading/menu-heading.d.ts +4 -0
  52. package/dist/components/menu-heading/menu-heading.js +6 -0
  53. package/dist/components/menu-section/menu-section.d.ts +4 -0
  54. package/dist/components/menu-section/menu-section.js +6 -0
  55. package/dist/components/menu-separator/menu-separator.d.ts +4 -0
  56. package/dist/components/menu-separator/menu-separator.js +6 -0
  57. package/dist/components/popover/popover-machine-glue.d.ts +6 -0
  58. package/dist/components/popover/popover-machine-glue.js +16 -0
  59. package/dist/components/popover/popover-machine.d.ts +30 -0
  60. package/dist/components/popover/popover-machine.js +49 -0
  61. package/dist/components/popover/popover.d.ts +25 -0
  62. package/dist/components/popover/popover.js +37 -0
  63. package/dist/components/popover-backdrop/popover-backdrop.d.ts +6 -0
  64. package/dist/components/popover-backdrop/popover-backdrop.js +14 -0
  65. package/dist/components/popover-group/popover-group.d.ts +4 -0
  66. package/dist/components/popover-group/popover-group.js +6 -0
  67. package/dist/components/popover-overlay/popover-overlay.d.ts +4 -0
  68. package/dist/components/popover-overlay/popover-overlay.js +6 -0
  69. package/dist/components/portal/portal.d.ts +9 -0
  70. package/dist/components/portal/portal.js +8 -0
  71. package/dist/components/radio-group/radio-group.d.ts +29 -0
  72. package/dist/components/radio-group/radio-group.js +36 -0
  73. package/dist/components/select/select.d.ts +7 -0
  74. package/dist/components/select/select.js +10 -0
  75. package/dist/components/switch/switch.d.ts +20 -0
  76. package/dist/components/switch/switch.js +24 -0
  77. package/dist/components/tab-panels/tab-panels.d.ts +4 -0
  78. package/dist/components/tab-panels/tab-panels.js +6 -0
  79. package/dist/components/tabs/tabs.d.ts +29 -0
  80. package/dist/components/tabs/tabs.js +40 -0
  81. package/dist/components/textarea/textarea.d.ts +5 -0
  82. package/dist/components/textarea/textarea.js +7 -0
  83. package/dist/components/transition/transition.d.ts +21 -0
  84. package/dist/components/transition/transition.js +34 -0
  85. package/dist/hooks/use-controllable.d.ts +1 -0
  86. package/dist/hooks/use-controllable.js +34 -0
  87. package/dist/hooks/use-event.d.ts +1 -0
  88. package/dist/hooks/use-event.js +8 -0
  89. package/dist/hooks/use-iso-morphic-effect.d.ts +2 -0
  90. package/dist/hooks/use-iso-morphic-effect.js +3 -0
  91. package/dist/hooks/use-latest-value.d.ts +1 -0
  92. package/dist/hooks/use-latest-value.js +9 -0
  93. package/dist/hooks/use-on-unmount.d.ts +1 -0
  94. package/dist/hooks/use-on-unmount.js +18 -0
  95. package/dist/index.d.ts +33 -0
  96. package/dist/index.js +33 -0
  97. package/dist/internal/close-provider.d.ts +6 -0
  98. package/dist/internal/close-provider.js +9 -0
  99. package/dist/internal/disabled.d.ts +5 -0
  100. package/dist/internal/disabled.js +9 -0
  101. package/dist/internal/toggle.d.ts +17 -0
  102. package/dist/internal/toggle.js +17 -0
  103. package/dist/machine.d.ts +33 -0
  104. package/dist/machine.js +107 -0
  105. package/dist/machines/stack-machine.d.ts +32 -0
  106. package/dist/machines/stack-machine.js +51 -0
  107. package/dist/react-glue.d.ts +2 -0
  108. package/dist/react-glue.js +9 -0
  109. package/dist/utils/calculate-active-index.d.ts +25 -0
  110. package/dist/utils/calculate-active-index.js +74 -0
  111. package/dist/utils/default-map.d.ts +5 -0
  112. package/dist/utils/default-map.js +15 -0
  113. package/dist/utils/disposables.d.ts +31 -0
  114. package/dist/utils/disposables.js +68 -0
  115. package/dist/utils/find-active-index.d.ts +3 -0
  116. package/dist/utils/find-active-index.js +12 -0
  117. package/dist/utils/match.d.ts +1 -0
  118. package/dist/utils/match.js +12 -0
  119. package/dist/utils/micro-task.d.ts +1 -0
  120. package/dist/utils/micro-task.js +13 -0
  121. package/dist/utils/render.d.ts +3 -0
  122. package/dist/utils/render.js +4 -0
  123. package/dist/utils/sort-by-order.d.ts +16 -0
  124. package/dist/utils/sort-by-order.js +33 -0
  125. package/dist/utils/typeahead.d.ts +1 -0
  126. package/dist/utils/typeahead.js +11 -0
  127. package/package.json +43 -3
@@ -0,0 +1,66 @@
1
+ import type { ForwardRefExoticComponent, RefAttributes } from 'react';
2
+ import { type ReactNode } from 'react';
3
+ import { type PressableProps, type ViewProps, type ViewInstance, type TextInputInstance } from 'react-native';
4
+ import { type RenderChildren } from '../../utils/render';
5
+ import { type InputProps } from '../input/input';
6
+ import { Label } from '../label/label';
7
+ type ComboboxBaseProps<TValue> = {
8
+ by?: (a: TValue, b: TValue) => boolean;
9
+ displayValue?: (value: TValue) => string;
10
+ immediate?: boolean;
11
+ virtual?: {
12
+ options: TValue[];
13
+ disabled?: (value: TValue) => boolean;
14
+ } | null;
15
+ disabled?: boolean;
16
+ children?: ReactNode;
17
+ };
18
+ type ComboboxSingleProps<TValue> = {
19
+ multiple?: false;
20
+ value?: TValue;
21
+ defaultValue?: TValue;
22
+ onChange?: (value: TValue) => void;
23
+ };
24
+ type ComboboxMultipleProps<TValue> = {
25
+ multiple: true;
26
+ value?: TValue[];
27
+ defaultValue?: TValue[];
28
+ onChange?: (value: TValue[]) => void;
29
+ };
30
+ export type ComboboxProps<TValue> = (ComboboxSingleProps<TValue> | ComboboxMultipleProps<TValue>) & ComboboxBaseProps<TValue>;
31
+ export declare function Combobox<TValue>({ value: controlledValue, defaultValue, onChange, multiple, by, displayValue, immediate, virtual, disabled, children, }: ComboboxProps<TValue>): import("react").JSX.Element;
32
+ export type ComboboxInputProps = InputProps;
33
+ export declare const ComboboxInput: ForwardRefExoticComponent<ComboboxInputProps & RefAttributes<TextInputInstance>>;
34
+ export type ComboboxButtonRenderPropArg = {
35
+ open: boolean;
36
+ disabled: boolean;
37
+ active: boolean;
38
+ };
39
+ export type ComboboxButtonProps = Omit<PressableProps, 'children' | 'disabled'> & {
40
+ disabled?: boolean;
41
+ children?: RenderChildren<ComboboxButtonRenderPropArg>;
42
+ };
43
+ export declare const ComboboxButton: ForwardRefExoticComponent<ComboboxButtonProps & RefAttributes<ViewInstance>>;
44
+ export type ComboboxOptionsRenderPropArg = {
45
+ option: unknown;
46
+ index: number;
47
+ };
48
+ export type ComboboxOptionsProps = Omit<ViewProps, 'children'> & {
49
+ children?: ReactNode | ((bag: ComboboxOptionsRenderPropArg) => ReactNode);
50
+ itemHeight?: number;
51
+ };
52
+ export declare const ComboboxOptions: ForwardRefExoticComponent<ComboboxOptionsProps & RefAttributes<ViewInstance>>;
53
+ export type ComboboxOptionRenderPropArg = {
54
+ selected: boolean;
55
+ disabled: boolean;
56
+ active: boolean;
57
+ };
58
+ export type ComboboxOptionProps<TValue> = Omit<PressableProps, 'children' | 'disabled'> & {
59
+ value: TValue;
60
+ disabled?: boolean;
61
+ order?: number;
62
+ children?: RenderChildren<ComboboxOptionRenderPropArg>;
63
+ };
64
+ export declare function ComboboxOption<TValue>({ value, disabled: optionDisabled, order, children, onPress, onLayout, ...theirProps }: ComboboxOptionProps<TValue>): import("react").JSX.Element;
65
+ export declare const ComboboxLabel: typeof Label;
66
+ export {};
@@ -0,0 +1,199 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createContext, forwardRef, useCallback, useContext, useEffect, useId, useRef, useState, } from 'react';
3
+ import { FlatList, Pressable, View, } from 'react-native';
4
+ import { useControllable } from '../../hooks/use-controllable';
5
+ import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect';
6
+ import { useLatestValue } from '../../hooks/use-latest-value';
7
+ import { useSlice } from '../../react-glue';
8
+ import { Focus } from '../../utils/calculate-active-index';
9
+ import { resolveChildren } from '../../utils/render';
10
+ import { Input } from '../input/input';
11
+ import { Label } from '../label/label';
12
+ import { ActionTypes, ComboboxState, ValueMode } from './combobox-machine';
13
+ import { ComboboxContext, useComboboxMachine, useComboboxMachineContext, } from './combobox-machine-glue';
14
+ let ComboboxValueContext = createContext(null);
15
+ function useComboboxValueContext(componentName) {
16
+ let context = useContext(ComboboxValueContext);
17
+ if (context === null) {
18
+ throw new Error(`<${componentName} /> must be rendered inside a <Combobox /> component.`);
19
+ }
20
+ return context;
21
+ }
22
+ function defaultDisplayValue(value) {
23
+ return value == null ? '' : String(value);
24
+ }
25
+ // The list is not filtered here: like the web Combobox, the consumer filters the options it renders
26
+ // from `query`, which is updated by `ComboboxInput` as the user types.
27
+ export function Combobox({ value: controlledValue, defaultValue, onChange, multiple = false, by, displayValue = defaultDisplayValue, immediate = false, virtual = null, disabled = false, children, }) {
28
+ let id = useId();
29
+ let machine = useComboboxMachine({ id });
30
+ let [query, setQuery] = useState(null);
31
+ // The controllable value is either a single value or an array, depending on `multiple`.
32
+ let [value, select] = useControllable(controlledValue, onChange, defaultValue ?? (multiple ? [] : undefined));
33
+ let compare = (a, b) => (by ? by(a, b) : a === b);
34
+ let isSelected = (candidate) => multiple
35
+ ? value.some((item) => compare(item, candidate))
36
+ : value !== undefined && compare(value, candidate);
37
+ useIsoMorphicEffect(() => {
38
+ machine.state.dataRef.current = {
39
+ value,
40
+ defaultValue,
41
+ disabled,
42
+ mode: multiple ? ValueMode.Multi : ValueMode.Single,
43
+ onChange: (next) => select(next),
44
+ onClose: () => setQuery(null),
45
+ compare,
46
+ isSelected,
47
+ virtual: virtual,
48
+ calculateIndex: (candidate) => virtual
49
+ ? virtual.options.findIndex((option) => compare(option, candidate))
50
+ : machine.state.options.findIndex((option) => compare(option.dataRef.current.value, candidate)),
51
+ };
52
+ });
53
+ // The machine needs the virtual options to move the active option through them.
54
+ useIsoMorphicEffect(() => {
55
+ if (!virtual)
56
+ return;
57
+ machine.send({
58
+ type: ActionTypes.UpdateVirtualConfiguration,
59
+ options: virtual.options,
60
+ disabled: virtual.disabled ?? null,
61
+ });
62
+ }, [virtual?.options, virtual?.disabled]);
63
+ return (_jsx(ComboboxContext.Provider, { value: machine, children: _jsx(ComboboxValueContext.Provider, { value: {
64
+ value,
65
+ multiple,
66
+ disabled,
67
+ query,
68
+ setQuery,
69
+ displayValue: displayValue,
70
+ immediate,
71
+ select,
72
+ isSelected,
73
+ virtual: virtual ? { options: virtual.options } : null,
74
+ }, children: children }) }));
75
+ }
76
+ export const ComboboxInput = forwardRef(function ComboboxInputFn(props, ref) {
77
+ let machine = useComboboxMachineContext('ComboboxInput');
78
+ let combobox = useComboboxValueContext('ComboboxInput');
79
+ let { disabled = false, onChangeText, onFocus, onKeyPress, onSubmitEditing, ...theirProps } = props;
80
+ let handleFocus = (event) => {
81
+ onFocus?.(event);
82
+ if (combobox.immediate)
83
+ machine.actions.openCombobox();
84
+ };
85
+ let handleChangeText = (text) => {
86
+ onChangeText?.(text);
87
+ combobox.setQuery(text);
88
+ // Like the web default, clearing the input clears the value of a single combobox.
89
+ if (text === '' && !combobox.multiple)
90
+ combobox.select(null);
91
+ machine.actions.setIsTyping(true);
92
+ machine.actions.openCombobox();
93
+ };
94
+ // Arrow keys and Escape need a hardware keyboard, which is the case on a web build of the app.
95
+ let handleKeyPress = (event) => {
96
+ onKeyPress?.(event);
97
+ switch (event.nativeEvent.key) {
98
+ // Like on the web, an arrow key opens a closed combobox. This does nothing when it is open.
99
+ case 'ArrowDown':
100
+ machine.actions.openCombobox();
101
+ machine.actions.goToOption({ focus: Focus.Next });
102
+ break;
103
+ case 'ArrowUp':
104
+ machine.actions.openCombobox();
105
+ machine.actions.goToOption({ focus: Focus.Previous });
106
+ break;
107
+ case 'Escape':
108
+ machine.actions.closeCombobox();
109
+ break;
110
+ }
111
+ };
112
+ let handleSubmitEditing = (event) => {
113
+ onSubmitEditing?.(event);
114
+ machine.actions.selectActiveOption();
115
+ if (!combobox.multiple)
116
+ machine.actions.closeCombobox();
117
+ };
118
+ return (_jsx(Input, { ...theirProps, ref: ref, disabled: combobox.disabled || disabled, value: combobox.query ?? (combobox.multiple ? '' : combobox.displayValue(combobox.value)), onChangeText: handleChangeText, onKeyPress: handleKeyPress, onSubmitEditing: handleSubmitEditing, onFocus: handleFocus }));
119
+ });
120
+ export const ComboboxButton = forwardRef(function ComboboxButtonFn(props, ref) {
121
+ let machine = useComboboxMachineContext('ComboboxButton');
122
+ let combobox = useComboboxValueContext('ComboboxButton');
123
+ let open = useSlice(machine, (state) => state.comboboxState === ComboboxState.Open);
124
+ let { disabled: buttonDisabled = false, children, onPress, ...theirProps } = props;
125
+ let disabled = combobox.disabled || buttonDisabled;
126
+ let handlePress = (event) => {
127
+ onPress?.(event);
128
+ if (open) {
129
+ machine.actions.closeCombobox();
130
+ }
131
+ else {
132
+ machine.actions.openCombobox();
133
+ }
134
+ };
135
+ return (_jsx(Pressable, { ...theirProps, ref: ref, disabled: disabled, accessibilityRole: "button", accessibilityState: { ...theirProps.accessibilityState, expanded: open, disabled }, onPress: handlePress, children: ({ pressed }) => resolveChildren(children, { open, disabled, active: pressed }) }));
136
+ });
137
+ export const ComboboxOptions = forwardRef(function ComboboxOptionsFn({ children, itemHeight, ...theirProps }, ref) {
138
+ let machine = useComboboxMachineContext('ComboboxOptions');
139
+ let combobox = useComboboxValueContext('ComboboxOptions');
140
+ let open = useSlice(machine, (state) => state.comboboxState === ComboboxState.Open);
141
+ if (!open)
142
+ return null;
143
+ if (combobox.virtual) {
144
+ return (_jsx(VirtualComboboxOptions, { ...theirProps, forwardedRef: ref, options: combobox.virtual.options, itemHeight: itemHeight, render: children }));
145
+ }
146
+ return (_jsx(View, { ...theirProps, ref: ref, children: children }));
147
+ });
148
+ // Renders only the visible options, and keeps the active one scrolled into view.
149
+ function VirtualComboboxOptions({ forwardedRef, options, itemHeight, render, ...theirProps }) {
150
+ let machine = useComboboxMachineContext('ComboboxOptions');
151
+ let listRef = useRef(null);
152
+ let activeOptionIndex = useSlice(machine, (state) => machine.selectors.activeOptionIndex(state));
153
+ // The list is kept for scrolling, and is also handed to the ref of `ComboboxOptions`.
154
+ let setListRef = useCallback((list) => {
155
+ listRef.current = list;
156
+ if (typeof forwardedRef === 'function')
157
+ forwardedRef(list);
158
+ else if (forwardedRef)
159
+ forwardedRef.current = list;
160
+ }, [forwardedRef]);
161
+ useEffect(() => {
162
+ // The machine learns about new `options` after this render. Until then the active index still
163
+ // points into the previous list, so skip it: the machine re-renders with the corrected index.
164
+ if (activeOptionIndex === null || activeOptionIndex >= options.length)
165
+ return;
166
+ listRef.current?.scrollToIndex({ index: activeOptionIndex, animated: false });
167
+ }, [activeOptionIndex, options.length]);
168
+ return (_jsx(FlatList, { ...theirProps, ref: setListRef, data: options, keyExtractor: (_, index) => String(index), getItemLayout: itemHeight
169
+ ? (_, index) => ({ length: itemHeight, offset: itemHeight * index, index })
170
+ : undefined, onScrollToIndexFailed: ({ index }) => {
171
+ if (__DEV__) {
172
+ console.warn(`ComboboxOptions could not scroll to option ${index}. Pass \`itemHeight\`.`);
173
+ }
174
+ }, renderItem: ({ item, index }) => _jsx(_Fragment, { children: render({ option: item, index }) }) }));
175
+ }
176
+ export function ComboboxOption({ value, disabled: optionDisabled = false, order, children, onPress, onLayout, ...theirProps }) {
177
+ let machine = useComboboxMachineContext('ComboboxOption');
178
+ let combobox = useComboboxValueContext('ComboboxOption');
179
+ let id = useId();
180
+ let disabled = combobox.disabled || optionDisabled;
181
+ let dataRef = useLatestValue({ disabled, value, order });
182
+ useIsoMorphicEffect(() => machine.actions.registerOption(id, dataRef), [id, machine]);
183
+ let active = useSlice(machine, (state) => machine.selectors.isActive(state, value, id));
184
+ let selected = combobox.isSelected(value);
185
+ let handlePress = (event) => {
186
+ onPress?.(event);
187
+ if (disabled)
188
+ return;
189
+ machine.actions.onChange(value);
190
+ if (!combobox.multiple)
191
+ machine.actions.closeCombobox();
192
+ };
193
+ let handleLayout = (event) => {
194
+ onLayout?.(event);
195
+ machine.actions.setOptionTop(id, event.nativeEvent.layout.y);
196
+ };
197
+ return (_jsx(Pressable, { ...theirProps, disabled: disabled, accessibilityRole: "button", accessibilityState: { ...theirProps.accessibilityState, selected, disabled }, onPress: handlePress, onLayout: handleLayout, children: ({ pressed }) => resolveChildren(children, { selected, disabled, active: active || pressed }) }));
198
+ }
199
+ export const ComboboxLabel = Label;
@@ -0,0 +1,4 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type ViewProps, type ViewInstance } from 'react-native';
3
+ export type DataInteractiveProps = ViewProps;
4
+ export declare const DataInteractive: ForwardRefExoticComponent<DataInteractiveProps & RefAttributes<ViewInstance>>;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { View } from 'react-native';
4
+ // On the web this marks an element so that outside-click handlers ignore it. React Native has no
5
+ // outside-click handling, so it only renders its children.
6
+ export const DataInteractive = forwardRef(function DataInteractiveFn(props, ref) {
7
+ return _jsx(View, { ...props, ref: ref });
8
+ });
@@ -0,0 +1,4 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type TextProps, type TextInstance } from 'react-native';
3
+ export type DescriptionProps = TextProps;
4
+ export declare const Description: ForwardRefExoticComponent<DescriptionProps & RefAttributes<TextInstance>>;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { Text } from 'react-native';
4
+ export const Description = forwardRef(function DescriptionFn(props, ref) {
5
+ return _jsx(Text, { ...props, ref: ref });
6
+ });
@@ -0,0 +1,22 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type ModalProps, type PressableProps, type StyleProp, type ViewProps, type ViewStyle, type ViewInstance } from 'react-native';
3
+ import { type RenderChildren } from '../../utils/render';
4
+ import { Description } from '../description/description';
5
+ import { Label } from '../label/label';
6
+ export type DialogRenderPropArg = {
7
+ open: boolean;
8
+ close: () => void;
9
+ };
10
+ export type DialogProps = Omit<ModalProps, 'visible' | 'children' | 'onRequestClose'> & {
11
+ open: boolean;
12
+ onClose: () => void;
13
+ children?: RenderChildren<DialogRenderPropArg>;
14
+ };
15
+ export declare function Dialog({ open, onClose, children, animationType, ...theirProps }: DialogProps): import("react").JSX.Element;
16
+ export declare const DialogPanel: ForwardRefExoticComponent<ViewProps & RefAttributes<ViewInstance>>;
17
+ export type DialogBackdropProps = Omit<PressableProps, 'children' | 'style'> & {
18
+ style?: StyleProp<ViewStyle>;
19
+ };
20
+ export declare const DialogBackdrop: ForwardRefExoticComponent<DialogBackdropProps & RefAttributes<ViewInstance>>;
21
+ export declare const DialogTitle: typeof Label;
22
+ export declare const DialogDescription: typeof Description;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { Modal, Pressable, StyleSheet, View, } from 'react-native';
4
+ import { CloseProvider, useClose } from '../../internal/close-provider';
5
+ import { resolveChildren } from '../../utils/render';
6
+ import { Description } from '../description/description';
7
+ import { Label } from '../label/label';
8
+ // `Modal` replaces the web portal: it is rendered on top of the app, and pressing the hardware back
9
+ // button calls `onClose`.
10
+ export function Dialog({ open, onClose, children, animationType = 'fade', ...theirProps }) {
11
+ return (_jsx(Modal, { ...theirProps, visible: open, animationType: animationType, onRequestClose: onClose, children: _jsx(CloseProvider, { value: onClose, children: resolveChildren(children, { open, close: onClose }) }) }));
12
+ }
13
+ export const DialogPanel = forwardRef(function DialogPanelFn(props, ref) {
14
+ return _jsx(View, { ...props, ref: ref, accessibilityViewIsModal: true });
15
+ });
16
+ // A press outside the panel closes the dialog, as the web Dialog does on an outside click.
17
+ export const DialogBackdrop = forwardRef(function DialogBackdropFn(props, ref) {
18
+ let close = useClose();
19
+ let { onPress, style, ...theirProps } = props;
20
+ let handlePress = (event) => {
21
+ onPress?.(event);
22
+ close();
23
+ };
24
+ return (_jsx(Pressable, { ...theirProps, ref: ref, accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: [StyleSheet.absoluteFill, style], onPress: handlePress }));
25
+ });
26
+ export const DialogTitle = Label;
27
+ export const DialogDescription = Description;
@@ -0,0 +1,35 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type PressableProps, type ViewProps, type ViewInstance } from 'react-native';
3
+ import { type RenderChildren } from '../../utils/render';
4
+ export type DisclosureRenderPropArg = {
5
+ open: boolean;
6
+ close: () => void;
7
+ };
8
+ export type DisclosureProps = {
9
+ open?: boolean;
10
+ defaultOpen?: boolean;
11
+ onChange?: (open: boolean) => void;
12
+ children?: RenderChildren<DisclosureRenderPropArg>;
13
+ };
14
+ type DisclosureContextValue = {
15
+ open: boolean;
16
+ toggle: () => void;
17
+ close: () => void;
18
+ };
19
+ export declare function useDisclosure(componentName: string): DisclosureContextValue;
20
+ export declare function Disclosure({ open: controlledOpen, defaultOpen, onChange, children, }: DisclosureProps): import("react").JSX.Element;
21
+ export type DisclosureButtonRenderPropArg = {
22
+ open: boolean;
23
+ disabled: boolean;
24
+ active: boolean;
25
+ };
26
+ export type DisclosureButtonProps = Omit<PressableProps, 'children' | 'disabled'> & {
27
+ disabled?: boolean;
28
+ children?: RenderChildren<DisclosureButtonRenderPropArg>;
29
+ };
30
+ export declare const DisclosureButton: ForwardRefExoticComponent<DisclosureButtonProps & RefAttributes<ViewInstance>>;
31
+ export type DisclosurePanelProps = ViewProps & {
32
+ unmount?: boolean;
33
+ };
34
+ export declare const DisclosurePanel: ForwardRefExoticComponent<DisclosurePanelProps & RefAttributes<ViewInstance>>;
35
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, forwardRef, useContext, } from 'react';
3
+ import { Pressable, View, } from 'react-native';
4
+ import { useControllable } from '../../hooks/use-controllable';
5
+ import { useEvent } from '../../hooks/use-event';
6
+ import { resolveChildren } from '../../utils/render';
7
+ let DisclosureContext = createContext(null);
8
+ export function useDisclosure(componentName) {
9
+ let context = useContext(DisclosureContext);
10
+ if (context === null) {
11
+ throw new Error(`<${componentName} /> must be rendered inside a <Disclosure /> component.`);
12
+ }
13
+ return context;
14
+ }
15
+ export function Disclosure({ open: controlledOpen, defaultOpen, onChange, children, }) {
16
+ let [open, setOpen] = useControllable(controlledOpen, onChange, defaultOpen ?? false);
17
+ let close = useEvent(() => setOpen(false));
18
+ let toggle = useEvent(() => setOpen(!open));
19
+ return (_jsx(DisclosureContext.Provider, { value: { open, toggle, close }, children: resolveChildren(children, { open, close }) }));
20
+ }
21
+ export const DisclosureButton = forwardRef(function DisclosureButtonFn(props, ref) {
22
+ let { open, toggle } = useDisclosure('DisclosureButton');
23
+ let { disabled = false, children, onPress, ...theirProps } = props;
24
+ let handlePress = useEvent((event) => {
25
+ onPress?.(event);
26
+ toggle();
27
+ });
28
+ return (_jsx(Pressable, { ...theirProps, ref: ref, disabled: disabled, accessibilityRole: "button", accessibilityState: { ...theirProps.accessibilityState, expanded: open, disabled }, onPress: handlePress, children: ({ pressed }) => resolveChildren(children, { open, disabled, active: pressed }) }));
29
+ });
30
+ export const DisclosurePanel = forwardRef(function DisclosurePanelFn({ unmount = true, ...theirProps }, ref) {
31
+ let { open } = useDisclosure('DisclosurePanel');
32
+ if (!open && unmount)
33
+ return null;
34
+ return _jsx(View, { ...theirProps, ref: ref, style: [theirProps.style, !open && { display: 'none' }] });
35
+ });
@@ -0,0 +1,6 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type ViewProps, type ViewInstance } from 'react-native';
3
+ export type FieldProps = ViewProps & {
4
+ disabled?: boolean;
5
+ };
6
+ export declare const Field: ForwardRefExoticComponent<FieldProps & RefAttributes<ViewInstance>>;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { View } from 'react-native';
4
+ import { DisabledProvider, useDisabled } from '../../internal/disabled';
5
+ export const Field = forwardRef(function FieldFn({ disabled, ...theirProps }, ref) {
6
+ let providedDisabled = useDisabled();
7
+ let isDisabled = disabled ?? providedDisabled ?? false;
8
+ return (_jsx(DisabledProvider, { value: isDisabled, children: _jsx(View, { ...theirProps, ref: ref }) }));
9
+ });
@@ -0,0 +1,3 @@
1
+ import { Field, type FieldProps } from '../field/field';
2
+ export type FieldsetProps = FieldProps;
3
+ export declare const Fieldset: typeof Field;
@@ -0,0 +1,3 @@
1
+ import { Field } from '../field/field';
2
+ // A fieldset groups related fields. In React Native it is a Field, which propagates `disabled`.
3
+ export const Fieldset = Field;
@@ -0,0 +1,5 @@
1
+ import { type ReactNode } from 'react';
2
+ export type FocusTrapProps = {
3
+ children?: ReactNode;
4
+ };
5
+ export declare function FocusTrap({ children }: FocusTrapProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import {} from 'react';
3
+ export function FocusTrap({ children }) {
4
+ return _jsx(_Fragment, { children: children });
5
+ }
@@ -0,0 +1,6 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type TextInputProps, type TextInputInstance } from 'react-native';
3
+ export type InputProps = Omit<TextInputProps, 'editable'> & {
4
+ disabled?: boolean;
5
+ };
6
+ export declare const Input: ForwardRefExoticComponent<InputProps & RefAttributes<TextInputInstance>>;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { TextInput } from 'react-native';
4
+ import { useDisabled } from '../../internal/disabled';
5
+ export const Input = forwardRef(function InputFn(props, ref) {
6
+ let providedDisabled = useDisabled();
7
+ let { disabled = providedDisabled || false, ...theirProps } = props;
8
+ return (_jsx(TextInput, { ...theirProps, ref: ref, editable: !disabled, accessibilityState: { ...theirProps.accessibilityState, disabled } }));
9
+ });
@@ -0,0 +1,6 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type TextProps, type TextInstance } from 'react-native';
3
+ export type LabelProps = TextProps & {
4
+ disabled?: boolean;
5
+ };
6
+ export declare const Label: ForwardRefExoticComponent<LabelProps & RefAttributes<TextInstance>>;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { Text } from 'react-native';
4
+ import { useDisabled } from '../../internal/disabled';
5
+ export const Label = forwardRef(function LabelFn(props, ref) {
6
+ let providedDisabled = useDisabled();
7
+ let { disabled = providedDisabled || false, ...theirProps } = props;
8
+ return (_jsx(Text, { ...theirProps, ref: ref, accessibilityState: { ...theirProps.accessibilityState, disabled } }));
9
+ });
@@ -0,0 +1,6 @@
1
+ import { type ForwardRefExoticComponent, type RefAttributes } from 'react';
2
+ import { type TextProps, type TextInstance } from 'react-native';
3
+ export type LegendProps = TextProps & {
4
+ disabled?: boolean;
5
+ };
6
+ export declare const Legend: ForwardRefExoticComponent<LegendProps & RefAttributes<TextInstance>>;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { Text } from 'react-native';
4
+ import { useDisabled } from '../../internal/disabled';
5
+ export const Legend = forwardRef(function LegendFn(props, ref) {
6
+ let providedDisabled = useDisabled();
7
+ let { disabled = providedDisabled || false, ...theirProps } = props;
8
+ return (_jsx(Text, { ...theirProps, ref: ref, accessibilityState: { ...theirProps.accessibilityState, disabled } }));
9
+ });
@@ -0,0 +1,6 @@
1
+ import { ListboxMachine } from './listbox-machine';
2
+ export declare const ListboxContext: import("react").Context<ListboxMachine<unknown> | null>;
3
+ export declare function useListboxMachineContext<T>(component: string): ListboxMachine<T>;
4
+ export declare function useListboxMachine({ id }: {
5
+ id: string;
6
+ }): ListboxMachine<unknown>;
@@ -0,0 +1,16 @@
1
+ import { createContext, useContext, useMemo } from 'react';
2
+ import { useOnUnmount } from '../../hooks/use-on-unmount';
3
+ import { ListboxMachine } from './listbox-machine';
4
+ export const ListboxContext = createContext(null);
5
+ export function useListboxMachineContext(component) {
6
+ let context = useContext(ListboxContext);
7
+ if (context === null) {
8
+ throw new Error(`<${component} /> is missing a parent <Listbox /> component.`);
9
+ }
10
+ return context;
11
+ }
12
+ export function useListboxMachine({ id }) {
13
+ let machine = useMemo(() => ListboxMachine.new({ id }), []);
14
+ useOnUnmount(() => machine.dispose());
15
+ return machine;
16
+ }