@lmb-it/kitsconcerto-native 0.1.258 → 0.1.260
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/apps/mobile/src/Core/Dropdown/index.cjs +71 -92
- package/apps/mobile/src/Core/Dropdown/index.cjs.map +1 -1
- package/apps/mobile/src/Core/Dropdown/index.js +74 -95
- package/apps/mobile/src/Core/Dropdown/index.js.map +1 -1
- package/apps/mobile/src/Core/MultiSelect/index.cjs +13 -3
- package/apps/mobile/src/Core/MultiSelect/index.cjs.map +1 -1
- package/apps/mobile/src/Core/MultiSelect/index.js +13 -3
- package/apps/mobile/src/Core/MultiSelect/index.js.map +1 -1
- package/apps/mobile/src/Factory/helpers/useKeyboardHeight.cjs +24 -0
- package/apps/mobile/src/Factory/helpers/useKeyboardHeight.cjs.map +1 -0
- package/apps/mobile/src/Factory/helpers/useKeyboardHeight.js +22 -0
- package/apps/mobile/src/Factory/helpers/useKeyboardHeight.js.map +1 -0
- package/form/selects/Dropdown/index.cjs +6 -1
- package/form/selects/Dropdown/index.cjs.map +1 -1
- package/form/selects/Dropdown/index.js +6 -1
- package/form/selects/Dropdown/index.js.map +1 -1
- package/form/selects/MultiSelect/index.cjs +6 -1
- package/form/selects/MultiSelect/index.cjs.map +1 -1
- package/form/selects/MultiSelect/index.js +6 -1
- package/form/selects/MultiSelect/index.js.map +1 -1
- package/form/selects/helpers/SelectPopupOverlay.cjs +200 -0
- package/form/selects/helpers/SelectPopupOverlay.cjs.map +1 -0
- package/form/selects/helpers/SelectPopupOverlay.js +196 -0
- package/form/selects/helpers/SelectPopupOverlay.js.map +1 -0
- package/form-renderer/components/fields/Select/index.cjs +2 -0
- package/form-renderer/components/fields/Select/index.cjs.map +1 -1
- package/form-renderer/components/fields/Select/index.js +2 -0
- package/form-renderer/components/fields/Select/index.js.map +1 -1
- package/index.d.ts +45 -0
- package/package.json +1 -1
|
@@ -65,6 +65,7 @@ require('../../../../../packages/types/src/Theme/shadows.cjs');
|
|
|
65
65
|
require('../../../../../packages/types/src/Theme/defaultTheme.cjs');
|
|
66
66
|
require('../../../../../packages/types/src/Theme/alphaColors.cjs');
|
|
67
67
|
require('../../Factory/helpers/cssVarMap.cjs');
|
|
68
|
+
var useKeyboardHeight = require('../../Factory/helpers/useKeyboardHeight.cjs');
|
|
68
69
|
require('i18next');
|
|
69
70
|
require('react-i18next');
|
|
70
71
|
require('../AutoComplete/index.cjs');
|
|
@@ -145,6 +146,9 @@ function Dropdown({
|
|
|
145
146
|
emptyFilterMessage = "No results found",
|
|
146
147
|
filterPlaceholder = "Search...",
|
|
147
148
|
isRTL = false,
|
|
149
|
+
popup = false,
|
|
150
|
+
renderPopup,
|
|
151
|
+
popupTitle,
|
|
148
152
|
itemTemplate,
|
|
149
153
|
valueTemplate,
|
|
150
154
|
panelFooterTemplate,
|
|
@@ -163,19 +167,7 @@ function Dropdown({
|
|
|
163
167
|
const [filterQuery, setFilterQuery] = React.useState("");
|
|
164
168
|
const [triggerLayout, setTriggerLayout] = React.useState(null);
|
|
165
169
|
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
166
|
-
const
|
|
167
|
-
React.useEffect(() => {
|
|
168
|
-
const showEvent = reactNative.Platform.OS === "ios" ? "keyboardWillChangeFrame" : "keyboardDidShow";
|
|
169
|
-
const hideEvent = reactNative.Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide";
|
|
170
|
-
const onShow = (event) => setKeyboardHeight(event?.endCoordinates?.height ?? 0);
|
|
171
|
-
const onHide = () => setKeyboardHeight(0);
|
|
172
|
-
const showSub = reactNative.Keyboard.addListener(showEvent, onShow);
|
|
173
|
-
const hideSub = reactNative.Keyboard.addListener(hideEvent, onHide);
|
|
174
|
-
return () => {
|
|
175
|
-
showSub.remove();
|
|
176
|
-
hideSub.remove();
|
|
177
|
-
};
|
|
178
|
-
}, []);
|
|
170
|
+
const keyboardHeight = useKeyboardHeight.useKeyboardHeight();
|
|
179
171
|
const { viewStyle: externalViewStyle, textStyle: externalTextStyle } = splitStyle(externalStyle);
|
|
180
172
|
const colors = {
|
|
181
173
|
border: t("border") || t("gray.300"),
|
|
@@ -296,6 +288,46 @@ function Dropdown({
|
|
|
296
288
|
});
|
|
297
289
|
}, [flatData, filter, filterQuery, filterBy, optionLabel]);
|
|
298
290
|
const displayValue = valueTemplate ? valueTemplate(selectedItem) : selectedItem ? getLabel(selectedItem, optionLabel) : "";
|
|
291
|
+
const panelBody = (fill, autoFocusFilter) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
292
|
+
filter && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
293
|
+
reactNative.TextInput,
|
|
294
|
+
{
|
|
295
|
+
value: filterQuery,
|
|
296
|
+
onChangeText: setFilterQuery,
|
|
297
|
+
placeholder: filterPlaceholder,
|
|
298
|
+
placeholderTextColor: colors.placeholder,
|
|
299
|
+
style: [
|
|
300
|
+
styles.filterInput,
|
|
301
|
+
{
|
|
302
|
+
borderColor: colors.filterBorder,
|
|
303
|
+
backgroundColor: colors.filterBg,
|
|
304
|
+
color: colors.filterText
|
|
305
|
+
},
|
|
306
|
+
// Every other input in this library names its own edge and
|
|
307
|
+
// direction from the reader's language. Leaving these unset let the
|
|
308
|
+
// platform decide, so the field followed the process layout
|
|
309
|
+
// direction instead of the person reading it.
|
|
310
|
+
isRTL ? styles.filterRtl : styles.filterLtr
|
|
311
|
+
],
|
|
312
|
+
autoFocus: autoFocusFilter
|
|
313
|
+
}
|
|
314
|
+
) }),
|
|
315
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
316
|
+
reactNative.FlatList,
|
|
317
|
+
{
|
|
318
|
+
style: fill ? styles.listFill : styles.listShrink,
|
|
319
|
+
contentContainerStyle: styles.listContent,
|
|
320
|
+
data: filteredData,
|
|
321
|
+
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
322
|
+
renderItem: ({ item, index }) => renderItem(item, index),
|
|
323
|
+
keyboardShouldPersistTaps: "handled",
|
|
324
|
+
showsHorizontalScrollIndicator: false,
|
|
325
|
+
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
326
|
+
}
|
|
327
|
+
),
|
|
328
|
+
panelFooterTemplate?.()
|
|
329
|
+
] });
|
|
330
|
+
const usePopup = popup && typeof renderPopup === "function";
|
|
299
331
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.container, testID, children: [
|
|
300
332
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
301
333
|
reactNative.Pressable,
|
|
@@ -339,7 +371,7 @@ function Dropdown({
|
|
|
339
371
|
]
|
|
340
372
|
}
|
|
341
373
|
),
|
|
342
|
-
!isModal && /* @__PURE__ */ jsxRuntime.jsx(
|
|
374
|
+
!usePopup && !isModal && /* @__PURE__ */ jsxRuntime.jsx(
|
|
343
375
|
reactNative.Modal,
|
|
344
376
|
{
|
|
345
377
|
visible: open && !!triggerLayout,
|
|
@@ -356,7 +388,7 @@ function Dropdown({
|
|
|
356
388
|
triggerY: triggerLayout.y,
|
|
357
389
|
triggerHeight: triggerLayout.height
|
|
358
390
|
});
|
|
359
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
391
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
360
392
|
reactNative.View,
|
|
361
393
|
{
|
|
362
394
|
style: [
|
|
@@ -371,93 +403,26 @@ function Dropdown({
|
|
|
371
403
|
}
|
|
372
404
|
],
|
|
373
405
|
onStartShouldSetResponder: () => true,
|
|
374
|
-
children:
|
|
375
|
-
filter && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
376
|
-
reactNative.TextInput,
|
|
377
|
-
{
|
|
378
|
-
value: filterQuery,
|
|
379
|
-
onChangeText: setFilterQuery,
|
|
380
|
-
placeholder: filterPlaceholder,
|
|
381
|
-
placeholderTextColor: colors.placeholder,
|
|
382
|
-
style: [
|
|
383
|
-
styles.filterInput,
|
|
384
|
-
{
|
|
385
|
-
borderColor: colors.filterBorder,
|
|
386
|
-
backgroundColor: colors.filterBg,
|
|
387
|
-
color: colors.filterText
|
|
388
|
-
},
|
|
389
|
-
// Every other input in this library names its own edge
|
|
390
|
-
// and direction from the reader's language. Leaving
|
|
391
|
-
// these unset let the platform decide, so the field
|
|
392
|
-
// followed the process layout direction instead of the
|
|
393
|
-
// person reading it.
|
|
394
|
-
isRTL ? styles.filterRtl : styles.filterLtr
|
|
395
|
-
],
|
|
396
|
-
autoFocus: true
|
|
397
|
-
}
|
|
398
|
-
) }),
|
|
399
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
400
|
-
reactNative.FlatList,
|
|
401
|
-
{
|
|
402
|
-
style: { flexGrow: 0, flexShrink: 1 },
|
|
403
|
-
contentContainerStyle: { paddingBottom: 12 },
|
|
404
|
-
data: filteredData,
|
|
405
|
-
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
406
|
-
renderItem: ({ item, index }) => renderItem(item, index),
|
|
407
|
-
keyboardShouldPersistTaps: "handled",
|
|
408
|
-
showsHorizontalScrollIndicator: false,
|
|
409
|
-
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
410
|
-
}
|
|
411
|
-
),
|
|
412
|
-
panelFooterTemplate?.()
|
|
413
|
-
]
|
|
406
|
+
children: panelBody(false, true)
|
|
414
407
|
}
|
|
415
408
|
);
|
|
416
409
|
})() })
|
|
417
410
|
}
|
|
418
411
|
),
|
|
419
|
-
isModal && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible: open, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles.modalOverlay, onPress: close, children: /* @__PURE__ */ jsxRuntime.
|
|
412
|
+
!usePopup && isModal && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Modal, { visible: open, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: styles.modalOverlay, onPress: close, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
420
413
|
reactNative.View,
|
|
421
414
|
{
|
|
422
415
|
style: [styles.modalPanel, { backgroundColor: colors.bg }],
|
|
423
416
|
onStartShouldSetResponder: () => true,
|
|
424
|
-
children:
|
|
425
|
-
filter && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
426
|
-
reactNative.TextInput,
|
|
427
|
-
{
|
|
428
|
-
value: filterQuery,
|
|
429
|
-
onChangeText: setFilterQuery,
|
|
430
|
-
placeholder: filterPlaceholder,
|
|
431
|
-
placeholderTextColor: colors.placeholder,
|
|
432
|
-
style: [
|
|
433
|
-
styles.filterInput,
|
|
434
|
-
{
|
|
435
|
-
borderColor: colors.filterBorder,
|
|
436
|
-
backgroundColor: colors.filterBg,
|
|
437
|
-
color: colors.filterText
|
|
438
|
-
},
|
|
439
|
-
isRTL ? styles.filterRtl : styles.filterLtr
|
|
440
|
-
],
|
|
441
|
-
autoFocus: true
|
|
442
|
-
}
|
|
443
|
-
) }),
|
|
444
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
445
|
-
reactNative.FlatList,
|
|
446
|
-
{
|
|
447
|
-
data: filteredData,
|
|
448
|
-
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
449
|
-
renderItem: ({ item, index }) => renderItem(item, index),
|
|
450
|
-
nestedScrollEnabled: true,
|
|
451
|
-
keyboardShouldPersistTaps: "handled",
|
|
452
|
-
style: { flex: 1 },
|
|
453
|
-
contentContainerStyle: { paddingBottom: 12 },
|
|
454
|
-
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
455
|
-
}
|
|
456
|
-
),
|
|
457
|
-
panelFooterTemplate?.()
|
|
458
|
-
]
|
|
417
|
+
children: panelBody(true, true)
|
|
459
418
|
}
|
|
460
|
-
) }) })
|
|
419
|
+
) }) }),
|
|
420
|
+
usePopup && renderPopup({
|
|
421
|
+
visible: open,
|
|
422
|
+
onClose: close,
|
|
423
|
+
title: popupTitle,
|
|
424
|
+
children: panelBody(true, false)
|
|
425
|
+
})
|
|
461
426
|
] });
|
|
462
427
|
}
|
|
463
428
|
const styles = reactNative.StyleSheet.create({
|
|
@@ -509,6 +474,20 @@ const styles = reactNative.StyleSheet.create({
|
|
|
509
474
|
paddingVertical: 6,
|
|
510
475
|
borderBottomWidth: 1
|
|
511
476
|
},
|
|
477
|
+
listFill: {
|
|
478
|
+
flex: 1
|
|
479
|
+
},
|
|
480
|
+
// The anchored panel is sized by `maxHeight` with no height, so the list has
|
|
481
|
+
// to grow with its content up to that ceiling and then scroll inside it.
|
|
482
|
+
// `flex: 1` sets flexBasis 0, which contributes nothing to a shrink-wrapping
|
|
483
|
+
// parent.
|
|
484
|
+
listShrink: {
|
|
485
|
+
flexGrow: 0,
|
|
486
|
+
flexShrink: 1
|
|
487
|
+
},
|
|
488
|
+
listContent: {
|
|
489
|
+
paddingBottom: 12
|
|
490
|
+
},
|
|
512
491
|
filterInput: {
|
|
513
492
|
fontSize: 14,
|
|
514
493
|
paddingHorizontal: 8,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../../../../../apps/mobile/src/Core/Dropdown/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState, type ChangeEvent } from \"react\";\nimport {\n Dimensions,\n FlatList,\n Keyboard,\n Modal,\n Platform,\n Pressable,\n ScrollView,\n TouchableOpacity,\n View,\n StyleSheet, Text, TextInput\n} from \"react-native\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\nimport { Input, InputField, type VirtualScrollerOptions } from \"../../\";\nimport { resolveThemeTokenForNative } from '../../Factory/helpers/style';\nimport { computePanelGeometry } from './panelGeometry';\n\n/* ---------------------------------------------\n Types (PrimeReact-compatible)\n---------------------------------------------- */\n\nexport interface DropdownChangeEvent<T = any> {\n originalEvent?: any;\n value: T | null;\n}\n\n\nexport interface DropdownProps<T = any> {\n value?: T | null;\n options?: T[];\n\n onChange?: (e: ChangeEvent<T>, item:any) => void;\n\n optionLabel?: string;\n optionValue?: string;\n\n placeholder?: string;\n disabled?: boolean;\n editable?: boolean;\n loading?: boolean;\n showClear?: boolean;\n isModal?: boolean;\n\n checkmark?: boolean;\n highlightOnSelect?: boolean;\n\n filter?: boolean;\n filterBy?: string;\n emptyFilterMessage?: string;\n /**\n * Placeholder for the panel's filter field.\n *\n * ⛔ THIS COMPONENT CANNOT TRANSLATE. It lives in `apps/mobile`, which\n * `packages/ui` imports — the reverse import would be a cycle between the two\n * workspaces. So the sentence is resolved by the KitsConcerto wrapper, which\n * has `useLanguage()`, and arrives here already written, exactly as\n * `emptyFilterMessage` does.\n */\n filterPlaceholder?: string;\n /**\n * Which way the reader reads, from the wrapper's `useLanguage().isRTL`.\n *\n * ⛔ NOT `I18nManager.isRTL`. That is the PROCESS layout direction, which a\n * consumer can force at boot and which does not change when the reader\n * switches language. The filter field follows the interface language, like\n * every other input in this library.\n */\n isRTL?: boolean;\n\n itemTemplate?: (item: T) => React.ReactNode;\n valueTemplate?: (value: T | null) => React.ReactNode;\n panelFooterTemplate?: () => React.ReactNode;\n\n optionGroupLabel?: string;\n optionGroupChildren?: string;\n optionGroupTemplate?: (group: any) => React.ReactNode;\n\n virtualScrollerOptions?: VirtualScrollerOptions;\n\n invalid?: boolean;\n testID?: string;\n style?: import('react-native').ViewStyle;\n}\n\n/* ---------------------------------------------\n Helpers\n---------------------------------------------- */\n\nconst getLabel = (item: any, optionLabel?: string) => {\n if (!item) return \"\";\n if (!optionLabel) return String(item);\n return String(item[optionLabel]);\n};\n\nconst getValue = (item: any, optionValue?: string) => {\n if (!item) return null;\n if (!optionValue) return item;\n return item[optionValue];\n};\n\nconst t = resolveThemeTokenForNative;\n\nconst TEXT_STYLE_KEYS = new Set([\n 'fontSize', 'fontFamily', 'fontWeight', 'fontStyle',\n 'color', 'letterSpacing', 'lineHeight', 'textAlign',\n 'textDecorationLine', 'textTransform',\n]);\n\nfunction splitStyle(combined?: any): { viewStyle?: any; textStyle?: any } {\n if (!combined) return {};\n const view: Record<string, any> = {};\n const text: Record<string, any> = {};\n for (const [k, v] of Object.entries(combined)) {\n if (TEXT_STYLE_KEYS.has(k)) text[k] = v;\n else view[k] = v;\n }\n return {\n viewStyle: Object.keys(view).length ? view : undefined,\n textStyle: Object.keys(text).length ? text : undefined,\n };\n}\n\n/* ---------------------------------------------\n Component\n---------------------------------------------- */\n\nexport default function Dropdown<T = any>({\n value,\n options = [],\n onChange,\n\n optionLabel,\n optionValue,\n\n placeholder,\n disabled,\n editable,\n isModal = false,\n\n checkmark,\n highlightOnSelect = true,\n\n filter,\n filterBy,\n // ⚠️ THESE TWO ENGLISH LITERALS ARE A LAST RESORT, NOT A\n // TRANSLATION. The KitsConcerto wrapper always passes the\n // reader's own sentence; these only apply when this component\n // is used directly from `apps/mobile`, and they exist so a\n // panel can never render a blank search box or an empty\n // \"no results\" line. Recorded as English fallbacks.\n emptyFilterMessage = 'No results found',\n filterPlaceholder = 'Search...',\n isRTL = false,\n\n itemTemplate,\n valueTemplate,\n panelFooterTemplate,\n\n optionGroupLabel,\n optionGroupChildren,\n optionGroupTemplate,\n\n virtualScrollerOptions,\n\n invalid,\n testID,\n style: externalStyle,\n }: DropdownProps<T>) {\n const inputRef = useRef<any>(null);\n const triggerRef = useRef<View>(null);\n const [open, setOpen] = useState(false);\n const [inputText, setInputText] = useState(\"\");\n const [filterQuery, setFilterQuery] = useState(\"\");\n const [triggerLayout, setTriggerLayout] = useState<{\n x: number; y: number; width: number; height: number;\n } | null>(null);\n const insets = useSafeAreaInsets();\n const [keyboardHeight, setKeyboardHeight] = useState(0);\n\n /* The filter field inside the panel carries `autoFocus`, so on a filtered\n dropdown the keyboard is already rising by the time the panel lays out.\n Without this the panel is sized against the raw screen height and hands\n itself space the keyboard is about to take.\n\n iOS reports the frame before the animation so the panel settles in one\n step; Android has no `Will` events and reports after. */\n useEffect(() => {\n const showEvent = Platform.OS === 'ios' ? 'keyboardWillChangeFrame' : 'keyboardDidShow';\n const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';\n\n const onShow = (event: any) => setKeyboardHeight(event?.endCoordinates?.height ?? 0);\n const onHide = () => setKeyboardHeight(0);\n\n const showSub = Keyboard.addListener(showEvent as any, onShow);\n const hideSub = Keyboard.addListener(hideEvent as any, onHide);\n\n return () => {\n showSub.remove();\n hideSub.remove();\n };\n }, []);\n\n const { viewStyle: externalViewStyle, textStyle: externalTextStyle } = splitStyle(externalStyle);\n\n const colors = {\n border: t('border') || t('gray.300'),\n borderInvalid: t('danger') || t('red.500'),\n bg: t('surface-card') || '#fff',\n text: t('text') || t('gray.800'),\n placeholder: t('text-secondary') || t('gray.400'),\n optionSelected: t('highlight-bg') || t('gray.100'),\n groupBg: t('surface-ground') || t('gray.50'),\n filterBorder: t('border') || t('gray.200'),\n filterBg: t('surface-ground') || t('gray.50'),\n filterText: t('text') || t('gray.800'),\n emptyText: t('text-secondary') || t('gray.400'),\n primary: t('primary'),\n };\n\n /* ---------------------------------------------\n Derived\n ---------------------------------------------- */\n\n const selectedItem = useMemo(() => {\n if (value == null) return null;\n // Search through group children when grouped\n if (optionGroupChildren) {\n for (const group of options as any[]) {\n const children = group[optionGroupChildren];\n if (Array.isArray(children)) {\n const found = children.find((c: any) => getValue(c, optionValue) === value);\n if (found) return found;\n }\n }\n return null;\n }\n return options.find(\n (o) => getValue(o, optionValue) === value\n ) ?? null;\n }, [value, options, optionValue, optionGroupChildren]);\n\n /* ---------------------------------------------\n Open / Close\n ---------------------------------------------- */\n\n const toggle = () => {\n if (disabled) return;\n Keyboard.dismiss();\n if (open) {\n setOpen(false);\n return;\n }\n setFilterQuery(\"\");\n // Measure trigger position in window so the popover can be rendered\n // inside a Modal (escaping any parent ScrollView) at the correct anchor.\n triggerRef.current?.measureInWindow((x, y, width, height) => {\n setTriggerLayout({ x, y, width, height });\n setOpen(true);\n });\n };\n\n const close = () => setOpen(false);\n\n /* ---------------------------------------------\n Selection\n ---------------------------------------------- */\n\n const selectItem = (item: T) => {\n const newValue = getValue(item, optionValue);\n\n if (!onChange) return;\n\n const syntheticEvent = {\n target: {\n value: newValue,\n },\n } as React.ChangeEvent<any>;\n\n onChange(syntheticEvent, item);\n\n setOpen(false);\n };\n\n /* ---------------------------------------------\n Render item\n ---------------------------------------------- */\n\n const renderItem = useCallback(\n (item: any, index: number) => {\n if (!item) {\n return null;\n }\n\n // Group header\n if (item.__group) {\n return (\n <Text key={`group-${index}`} style={[styles.groupLabel, { backgroundColor: colors.groupBg }]}>\n {optionGroupLabel ? item.group?.[optionGroupLabel] : \"\"}\n </Text>\n );\n }\n\n const selected =\n value != null &&\n getValue(item, optionValue) === value;\n\n let content: React.ReactElement;\n\n if (itemTemplate) {\n const rendered = itemTemplate(item);\n\n content = React.isValidElement(rendered) ? (\n rendered\n ) : (\n <Text>{String(rendered ?? \"\")}</Text>\n );\n } else {\n content = (\n <Text style={[{ color: colors.text }, externalTextStyle && { fontSize: externalTextStyle.fontSize }]}>\n {getLabel(item, optionLabel)}\n </Text>\n );\n }\n\n return (\n <Pressable\n key={`item-${index}`}\n onPress={() => selectItem(item)}\n style={[\n styles.option,\n selected && highlightOnSelect && { backgroundColor: colors.optionSelected },\n ]}\n >\n {content}\n {checkmark && selected && <Text>✓</Text>}\n </Pressable>\n );\n },\n [\n value,\n optionValue,\n optionLabel,\n itemTemplate,\n optionGroupLabel,\n checkmark,\n highlightOnSelect,\n ]\n );\n\n\n /* ---------------------------------------------\n Group flattening\n ---------------------------------------------- */\n\n const flatData = useMemo(() => {\n if (!optionGroupLabel || !optionGroupChildren) {\n return options;\n }\n\n const out: any[] = [];\n options.forEach((g: any) => {\n out.push({ __group: true, group: g });\n g[optionGroupChildren]?.forEach((c: any) => out.push(c));\n });\n return out;\n }, [options]);\n\n /* ---------------------------------------------\n Filter\n ---------------------------------------------- */\n\n const filteredData = useMemo(() => {\n if (!filter || !filterQuery) return flatData;\n const q = filterQuery.toLowerCase();\n const key = filterBy || optionLabel;\n\n return flatData.filter((entry: any) => {\n // Keep group headers\n if (entry.__group) return true;\n const label = getLabel(entry, key);\n return label.toLowerCase().includes(q);\n });\n }, [flatData, filter, filterQuery, filterBy, optionLabel]);\n\n /* ---------------------------------------------\n Display value\n ---------------------------------------------- */\n\n const displayValue = valueTemplate\n ? valueTemplate(selectedItem)\n : selectedItem\n ? getLabel(selectedItem, optionLabel)\n : \"\";\n\n /* ---------------------------------------------\n Render\n ---------------------------------------------- */\n\n return (\n <View style={styles.container} testID={testID}>\n <Pressable\n ref={triggerRef as any}\n style={[\n styles.control,\n { borderColor: colors.border, backgroundColor: colors.bg },\n invalid && { borderColor: colors.borderInvalid },\n disabled && styles.disabled,\n externalViewStyle,\n ]}\n onPress={toggle}\n >\n {editable ? (\n <Input style={styles.input}>\n <InputField\n ref={inputRef}\n value={inputText}\n onChangeText={setInputText}\n placeholder={placeholder}\n editable={!disabled}\n />\n </Input>\n ) : (\n <Text\n numberOfLines={1}\n style={[\n // Fill the trigger row and left-align the value/placeholder so it\n // doesn't read as centred (the row is justify=space-between, so the\n // arrow stays pinned right).\n { flex: 1, textAlign: \"left\" as const },\n displayValue ? { color: colors.text } : { color: colors.placeholder },\n externalTextStyle,\n !displayValue && { color: colors.placeholder },\n ]}>\n {displayValue || placeholder}\n </Text>\n )}\n\n <Text style={[{ color: colors.text }, externalTextStyle]}>▾</Text>\n </Pressable>\n\n {!isModal && (\n <Modal\n visible={open && !!triggerLayout}\n transparent\n animationType=\"none\"\n onRequestClose={close}\n >\n <Pressable style={styles.popoverOverlay} onPress={close}>\n {triggerLayout && (() => {\n const screen = Dimensions.get('window');\n const { top, maxHeight } = computePanelGeometry({\n screenHeight: screen.height,\n insetTop: insets.top,\n insetBottom: insets.bottom,\n keyboardHeight,\n triggerY: triggerLayout.y,\n triggerHeight: triggerLayout.height,\n });\n\n return (\n <View\n style={[\n styles.popoverPanel,\n {\n top,\n left: triggerLayout.x,\n width: triggerLayout.width,\n maxHeight,\n borderColor: colors.border,\n backgroundColor: colors.bg,\n },\n ]}\n onStartShouldSetResponder={() => true}\n >\n {filter && (\n <View style={[styles.filterContainer, { borderBottomColor: colors.filterBorder }]}>\n <TextInput\n value={filterQuery}\n onChangeText={setFilterQuery}\n placeholder={filterPlaceholder}\n placeholderTextColor={colors.placeholder}\n style={[styles.filterInput, {\n borderColor: colors.filterBorder,\n backgroundColor: colors.filterBg,\n color: colors.filterText,\n },\n // Every other input in this library names its own edge\n // and direction from the reader's language. Leaving\n // these unset let the platform decide, so the field\n // followed the process layout direction instead of the\n // person reading it.\n isRTL ? styles.filterRtl : styles.filterLtr]}\n autoFocus\n />\n </View>\n )}\n {/* `flexShrink` rather than `flex: 1`: the panel is sized by\n `maxHeight`, not a fixed height, so the list has to be\n allowed to grow with its content up to that ceiling and\n then scroll inside it. `flex: 1` sets flexBasis 0, which\n contributes nothing to a shrink-wrapping parent. */}\n <FlatList\n style={{ flexGrow: 0, flexShrink: 1 }}\n contentContainerStyle={{ paddingBottom: 12 }}\n data={filteredData}\n keyExtractor={(item: any, i: number) =>\n item?.__group ? `group-${i}` : `item-${i}`\n }\n renderItem={({ item, index }) => renderItem(item, index)}\n keyboardShouldPersistTaps=\"handled\"\n showsHorizontalScrollIndicator={false}\n ListEmptyComponent={\n filterQuery ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: colors.emptyText }]}>{emptyFilterMessage}</Text>\n </View>\n ) : null\n }\n />\n {panelFooterTemplate?.()}\n </View>\n );\n })()}\n </Pressable>\n </Modal>\n )}\n\n {isModal && (\n <Modal visible={open} transparent animationType=\"fade\">\n <Pressable style={styles.modalOverlay} onPress={close}>\n <View\n style={[styles.modalPanel, { backgroundColor: colors.bg }]}\n onStartShouldSetResponder={() => true}\n >\n {filter && (\n <View style={[styles.filterContainer, { borderBottomColor: colors.filterBorder }]}>\n <TextInput\n value={filterQuery}\n onChangeText={setFilterQuery}\n placeholder={filterPlaceholder}\n placeholderTextColor={colors.placeholder}\n style={[styles.filterInput, {\n borderColor: colors.filterBorder,\n backgroundColor: colors.filterBg,\n color: colors.filterText,\n },\n isRTL ? styles.filterRtl : styles.filterLtr]}\n autoFocus\n />\n </View>\n )}\n <FlatList\n data={filteredData}\n keyExtractor={(item: any, i: number) =>\n item?.__group ? `group-${i}` : `item-${i}`\n }\n renderItem={({ item, index }) => renderItem(item, index)}\n nestedScrollEnabled\n keyboardShouldPersistTaps=\"handled\"\n style={{ flex: 1 }}\n contentContainerStyle={{ paddingBottom: 12 }}\n ListEmptyComponent={\n filterQuery ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: colors.emptyText }]}>{emptyFilterMessage}</Text>\n </View>\n ) : null\n }\n />\n {panelFooterTemplate?.()}\n </View>\n </Pressable>\n </Modal>\n )}\n </View>\n );\n}\n\n/* ---------------------------------------------\n Styles (layout only — colors applied inline via theme tokens)\n---------------------------------------------- */\n\nconst styles = StyleSheet.create({\n container: {\n width: \"100%\",\n position: \"relative\" as const,\n },\n control: {\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"space-between\" as const,\n borderWidth: 1,\n borderRadius: 6,\n paddingHorizontal: 10,\n paddingVertical: 10,\n },\n disabled: {\n opacity: 0.5,\n },\n option: {\n paddingHorizontal: 12,\n paddingVertical: 10,\n flexDirection: \"row\" as const,\n justifyContent: \"space-between\" as const,\n alignItems: \"center\" as const,\n },\n groupLabel: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n fontWeight: \"600\" as const,\n },\n input: {\n flex: 1,\n },\n panel: {\n position: \"absolute\" as const,\n top: \"100%\",\n left: 0,\n right: 0,\n marginTop: 4,\n borderWidth: 1,\n borderRadius: 6,\n maxHeight: 260,\n overflow: \"hidden\" as const,\n zIndex: 9999,\n },\n filterContainer: {\n paddingHorizontal: 8,\n paddingVertical: 6,\n borderBottomWidth: 1,\n },\n filterInput: {\n fontSize: 14,\n paddingHorizontal: 8,\n paddingVertical: 6,\n borderWidth: 1,\n borderRadius: 4,\n },\n filterLtr: {\n textAlign: 'left' as const,\n writingDirection: 'ltr' as const,\n },\n filterRtl: {\n textAlign: 'right' as const,\n writingDirection: 'rtl' as const,\n },\n emptyContainer: {\n padding: 16,\n alignItems: 'center' as const,\n },\n emptyText: {\n fontSize: 14,\n },\n popoverOverlay: {\n flex: 1,\n backgroundColor: 'transparent',\n },\n popoverPanel: {\n position: 'absolute' as const,\n borderWidth: 1,\n borderRadius: 6,\n overflow: 'hidden' as const,\n elevation: 8,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.15,\n shadowRadius: 8,\n },\n modalOverlay: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.4)',\n justifyContent: 'center' as const,\n },\n modalPanel: {\n margin: 24,\n maxHeight: '70%',\n borderRadius: 12,\n overflow: 'hidden' as const,\n },\n});\n"],"names":["resolveThemeTokenForNative","useRef","useState","useSafeAreaInsets","useEffect","Platform","Keyboard","useMemo","useCallback","jsx","Text","jsxs","Pressable","View","Input","InputField","Modal","Dimensions","computePanelGeometry","TextInput","FlatList","StyleSheet"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../../../../../apps/mobile/src/Core/Dropdown/index.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useRef, useState, type ChangeEvent } from \"react\";\nimport {\n Dimensions,\n FlatList,\n Keyboard,\n Modal,\n Pressable,\n ScrollView,\n TouchableOpacity,\n View,\n StyleSheet, Text, TextInput\n} from \"react-native\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\nimport { Input, InputField, type VirtualScrollerOptions } from \"../../\";\nimport { resolveThemeTokenForNative } from '../../Factory/helpers/style';\nimport { useKeyboardHeight } from '../../Factory/helpers/useKeyboardHeight';\nimport { computePanelGeometry } from './panelGeometry';\n\n/* ---------------------------------------------\n Types (PrimeReact-compatible)\n---------------------------------------------- */\n\nexport interface DropdownChangeEvent<T = any> {\n originalEvent?: any;\n value: T | null;\n}\n\n\nexport interface DropdownProps<T = any> {\n value?: T | null;\n options?: T[];\n\n onChange?: (e: ChangeEvent<T>, item:any) => void;\n\n optionLabel?: string;\n optionValue?: string;\n\n placeholder?: string;\n disabled?: boolean;\n editable?: boolean;\n loading?: boolean;\n showClear?: boolean;\n isModal?: boolean;\n\n checkmark?: boolean;\n highlightOnSelect?: boolean;\n\n filter?: boolean;\n filterBy?: string;\n emptyFilterMessage?: string;\n /**\n * Placeholder for the panel's filter field.\n *\n * ⛔ THIS COMPONENT CANNOT TRANSLATE. It lives in `apps/mobile`, which\n * `packages/ui` imports — the reverse import would be a cycle between the two\n * workspaces. So the sentence is resolved by the KitsConcerto wrapper, which\n * has `useLanguage()`, and arrives here already written, exactly as\n * `emptyFilterMessage` does.\n */\n filterPlaceholder?: string;\n /**\n * Open the options in a popup that owns the screen instead of a panel\n * anchored to the trigger.\n *\n * ⛔ THE ANCHOR IS THE PROBLEM THIS ESCAPES. An anchored panel can never be\n * taller than the gap between the trigger and the keyboard, and a field in\n * the middle of a form has ~190pt of gap on a 874pt phone — a search box and\n * four rows. Sizing that gap correctly does not make it big. The popup takes\n * a fixed share of the window instead, so where the field sits stops\n * mattering.\n *\n * Default false: every existing consumer keeps the anchored panel.\n */\n popup?: boolean;\n /**\n * Supplies the popup's container. Injected by the KitsConcerto wrapper\n * because the container is this library's `KitsDialogControlled`, which\n * lives in `packages/ui` — and `packages/ui` imports THIS file, so importing\n * it back would be a cycle between the two workspaces.\n *\n * Without it `popup` falls back to the anchored panel rather than rendering\n * nothing.\n */\n renderPopup?: (args: {\n visible: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n }) => React.ReactNode;\n /** Title for the popup header. The wrapper passes the field's label. */\n popupTitle?: React.ReactNode;\n /**\n * Which way the reader reads, from the wrapper's `useLanguage().isRTL`.\n *\n * ⛔ NOT `I18nManager.isRTL`. That is the PROCESS layout direction, which a\n * consumer can force at boot and which does not change when the reader\n * switches language. The filter field follows the interface language, like\n * every other input in this library.\n */\n isRTL?: boolean;\n\n itemTemplate?: (item: T) => React.ReactNode;\n valueTemplate?: (value: T | null) => React.ReactNode;\n panelFooterTemplate?: () => React.ReactNode;\n\n optionGroupLabel?: string;\n optionGroupChildren?: string;\n optionGroupTemplate?: (group: any) => React.ReactNode;\n\n virtualScrollerOptions?: VirtualScrollerOptions;\n\n invalid?: boolean;\n testID?: string;\n style?: import('react-native').ViewStyle;\n}\n\n/* ---------------------------------------------\n Helpers\n---------------------------------------------- */\n\nconst getLabel = (item: any, optionLabel?: string) => {\n if (!item) return \"\";\n if (!optionLabel) return String(item);\n return String(item[optionLabel]);\n};\n\nconst getValue = (item: any, optionValue?: string) => {\n if (!item) return null;\n if (!optionValue) return item;\n return item[optionValue];\n};\n\nconst t = resolveThemeTokenForNative;\n\nconst TEXT_STYLE_KEYS = new Set([\n 'fontSize', 'fontFamily', 'fontWeight', 'fontStyle',\n 'color', 'letterSpacing', 'lineHeight', 'textAlign',\n 'textDecorationLine', 'textTransform',\n]);\n\nfunction splitStyle(combined?: any): { viewStyle?: any; textStyle?: any } {\n if (!combined) return {};\n const view: Record<string, any> = {};\n const text: Record<string, any> = {};\n for (const [k, v] of Object.entries(combined)) {\n if (TEXT_STYLE_KEYS.has(k)) text[k] = v;\n else view[k] = v;\n }\n return {\n viewStyle: Object.keys(view).length ? view : undefined,\n textStyle: Object.keys(text).length ? text : undefined,\n };\n}\n\n/* ---------------------------------------------\n Component\n---------------------------------------------- */\n\nexport default function Dropdown<T = any>({\n value,\n options = [],\n onChange,\n\n optionLabel,\n optionValue,\n\n placeholder,\n disabled,\n editable,\n isModal = false,\n\n checkmark,\n highlightOnSelect = true,\n\n filter,\n filterBy,\n // ⚠️ THESE TWO ENGLISH LITERALS ARE A LAST RESORT, NOT A\n // TRANSLATION. The KitsConcerto wrapper always passes the\n // reader's own sentence; these only apply when this component\n // is used directly from `apps/mobile`, and they exist so a\n // panel can never render a blank search box or an empty\n // \"no results\" line. Recorded as English fallbacks.\n emptyFilterMessage = 'No results found',\n filterPlaceholder = 'Search...',\n isRTL = false,\n popup = false,\n renderPopup,\n popupTitle,\n\n itemTemplate,\n valueTemplate,\n panelFooterTemplate,\n\n optionGroupLabel,\n optionGroupChildren,\n optionGroupTemplate,\n\n virtualScrollerOptions,\n\n invalid,\n testID,\n style: externalStyle,\n }: DropdownProps<T>) {\n const inputRef = useRef<any>(null);\n const triggerRef = useRef<View>(null);\n const [open, setOpen] = useState(false);\n const [inputText, setInputText] = useState(\"\");\n const [filterQuery, setFilterQuery] = useState(\"\");\n const [triggerLayout, setTriggerLayout] = useState<{\n x: number; y: number; width: number; height: number;\n } | null>(null);\n const insets = useSafeAreaInsets();\n const keyboardHeight = useKeyboardHeight();\n\n const { viewStyle: externalViewStyle, textStyle: externalTextStyle } = splitStyle(externalStyle);\n\n const colors = {\n border: t('border') || t('gray.300'),\n borderInvalid: t('danger') || t('red.500'),\n bg: t('surface-card') || '#fff',\n text: t('text') || t('gray.800'),\n placeholder: t('text-secondary') || t('gray.400'),\n optionSelected: t('highlight-bg') || t('gray.100'),\n groupBg: t('surface-ground') || t('gray.50'),\n filterBorder: t('border') || t('gray.200'),\n filterBg: t('surface-ground') || t('gray.50'),\n filterText: t('text') || t('gray.800'),\n emptyText: t('text-secondary') || t('gray.400'),\n primary: t('primary'),\n };\n\n /* ---------------------------------------------\n Derived\n ---------------------------------------------- */\n\n const selectedItem = useMemo(() => {\n if (value == null) return null;\n // Search through group children when grouped\n if (optionGroupChildren) {\n for (const group of options as any[]) {\n const children = group[optionGroupChildren];\n if (Array.isArray(children)) {\n const found = children.find((c: any) => getValue(c, optionValue) === value);\n if (found) return found;\n }\n }\n return null;\n }\n return options.find(\n (o) => getValue(o, optionValue) === value\n ) ?? null;\n }, [value, options, optionValue, optionGroupChildren]);\n\n /* ---------------------------------------------\n Open / Close\n ---------------------------------------------- */\n\n const toggle = () => {\n if (disabled) return;\n Keyboard.dismiss();\n if (open) {\n setOpen(false);\n return;\n }\n setFilterQuery(\"\");\n // Measure trigger position in window so the popover can be rendered\n // inside a Modal (escaping any parent ScrollView) at the correct anchor.\n triggerRef.current?.measureInWindow((x, y, width, height) => {\n setTriggerLayout({ x, y, width, height });\n setOpen(true);\n });\n };\n\n const close = () => setOpen(false);\n\n /* ---------------------------------------------\n Selection\n ---------------------------------------------- */\n\n const selectItem = (item: T) => {\n const newValue = getValue(item, optionValue);\n\n if (!onChange) return;\n\n const syntheticEvent = {\n target: {\n value: newValue,\n },\n } as React.ChangeEvent<any>;\n\n onChange(syntheticEvent, item);\n\n setOpen(false);\n };\n\n /* ---------------------------------------------\n Render item\n ---------------------------------------------- */\n\n const renderItem = useCallback(\n (item: any, index: number) => {\n if (!item) {\n return null;\n }\n\n // Group header\n if (item.__group) {\n return (\n <Text key={`group-${index}`} style={[styles.groupLabel, { backgroundColor: colors.groupBg }]}>\n {optionGroupLabel ? item.group?.[optionGroupLabel] : \"\"}\n </Text>\n );\n }\n\n const selected =\n value != null &&\n getValue(item, optionValue) === value;\n\n let content: React.ReactElement;\n\n if (itemTemplate) {\n const rendered = itemTemplate(item);\n\n content = React.isValidElement(rendered) ? (\n rendered\n ) : (\n <Text>{String(rendered ?? \"\")}</Text>\n );\n } else {\n content = (\n <Text style={[{ color: colors.text }, externalTextStyle && { fontSize: externalTextStyle.fontSize }]}>\n {getLabel(item, optionLabel)}\n </Text>\n );\n }\n\n return (\n <Pressable\n key={`item-${index}`}\n onPress={() => selectItem(item)}\n style={[\n styles.option,\n selected && highlightOnSelect && { backgroundColor: colors.optionSelected },\n ]}\n >\n {content}\n {checkmark && selected && <Text>✓</Text>}\n </Pressable>\n );\n },\n [\n value,\n optionValue,\n optionLabel,\n itemTemplate,\n optionGroupLabel,\n checkmark,\n highlightOnSelect,\n ]\n );\n\n\n /* ---------------------------------------------\n Group flattening\n ---------------------------------------------- */\n\n const flatData = useMemo(() => {\n if (!optionGroupLabel || !optionGroupChildren) {\n return options;\n }\n\n const out: any[] = [];\n options.forEach((g: any) => {\n out.push({ __group: true, group: g });\n g[optionGroupChildren]?.forEach((c: any) => out.push(c));\n });\n return out;\n }, [options]);\n\n /* ---------------------------------------------\n Filter\n ---------------------------------------------- */\n\n const filteredData = useMemo(() => {\n if (!filter || !filterQuery) return flatData;\n const q = filterQuery.toLowerCase();\n const key = filterBy || optionLabel;\n\n return flatData.filter((entry: any) => {\n // Keep group headers\n if (entry.__group) return true;\n const label = getLabel(entry, key);\n return label.toLowerCase().includes(q);\n });\n }, [flatData, filter, filterQuery, filterBy, optionLabel]);\n\n /* ---------------------------------------------\n Display value\n ---------------------------------------------- */\n\n const displayValue = valueTemplate\n ? valueTemplate(selectedItem)\n : selectedItem\n ? getLabel(selectedItem, optionLabel)\n : \"\";\n\n /* ---------------------------------------------\n Panel body — the search field and the list\n ---------------------------------------------- */\n\n /*\n * ⛔ ONE BODY, THREE CONTAINERS. The anchored panel and the centred modal\n * each carried their own copy of this markup, which is why the hardcoded\n * \"Search...\" had to be found and fixed twice. The popup would have made it\n * three. The containers differ; what is inside them does not.\n *\n * `fill` is the one real difference. In the anchored panel the container has\n * a `maxHeight` and no height, so the list must shrink-wrap its content up\n * to that ceiling (`flexShrink`). In the popup and the centred modal the\n * container has a real height, so the list takes what is left (`flex: 1`).\n */\n const panelBody = (fill: boolean, autoFocusFilter: boolean) => (\n <>\n {filter && (\n <View style={[styles.filterContainer, { borderBottomColor: colors.filterBorder }]}>\n <TextInput\n value={filterQuery}\n onChangeText={setFilterQuery}\n placeholder={filterPlaceholder}\n placeholderTextColor={colors.placeholder}\n style={[styles.filterInput, {\n borderColor: colors.filterBorder,\n backgroundColor: colors.filterBg,\n color: colors.filterText,\n },\n // Every other input in this library names its own edge and\n // direction from the reader's language. Leaving these unset let the\n // platform decide, so the field followed the process layout\n // direction instead of the person reading it.\n isRTL ? styles.filterRtl : styles.filterLtr]}\n /* ⛔ THE ANCHORED PANEL KEEPS ITS AUTOFOCUS — changing it would\n change behaviour for every consumer that has not opted in. In\n the popup the list is already the whole point and is fully\n visible, so the keyboard waits to be asked for: one tap on the\n field raises it, and until then the list has the whole sheet. */\n autoFocus={autoFocusFilter}\n />\n </View>\n )}\n <FlatList\n style={fill ? styles.listFill : styles.listShrink}\n contentContainerStyle={styles.listContent}\n data={filteredData}\n keyExtractor={(item: any, i: number) =>\n item?.__group ? `group-${i}` : `item-${i}`\n }\n renderItem={({ item, index }) => renderItem(item, index)}\n keyboardShouldPersistTaps=\"handled\"\n showsHorizontalScrollIndicator={false}\n ListEmptyComponent={\n filterQuery ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: colors.emptyText }]}>{emptyFilterMessage}</Text>\n </View>\n ) : null\n }\n />\n {panelFooterTemplate?.()}\n </>\n );\n\n /* ---------------------------------------------\n Render\n ---------------------------------------------- */\n\n const usePopup = popup && typeof renderPopup === 'function';\n\n return (\n <View style={styles.container} testID={testID}>\n <Pressable\n ref={triggerRef as any}\n style={[\n styles.control,\n { borderColor: colors.border, backgroundColor: colors.bg },\n invalid && { borderColor: colors.borderInvalid },\n disabled && styles.disabled,\n externalViewStyle,\n ]}\n onPress={toggle}\n >\n {editable ? (\n <Input style={styles.input}>\n <InputField\n ref={inputRef}\n value={inputText}\n onChangeText={setInputText}\n placeholder={placeholder}\n editable={!disabled}\n />\n </Input>\n ) : (\n <Text\n numberOfLines={1}\n style={[\n // Fill the trigger row and left-align the value/placeholder so it\n // doesn't read as centred (the row is justify=space-between, so the\n // arrow stays pinned right).\n { flex: 1, textAlign: \"left\" as const },\n displayValue ? { color: colors.text } : { color: colors.placeholder },\n externalTextStyle,\n !displayValue && { color: colors.placeholder },\n ]}>\n {displayValue || placeholder}\n </Text>\n )}\n\n <Text style={[{ color: colors.text }, externalTextStyle]}>▾</Text>\n </Pressable>\n\n {!usePopup && !isModal && (\n <Modal\n visible={open && !!triggerLayout}\n transparent\n animationType=\"none\"\n onRequestClose={close}\n >\n <Pressable style={styles.popoverOverlay} onPress={close}>\n {triggerLayout && (() => {\n const screen = Dimensions.get('window');\n const { top, maxHeight } = computePanelGeometry({\n screenHeight: screen.height,\n insetTop: insets.top,\n insetBottom: insets.bottom,\n keyboardHeight,\n triggerY: triggerLayout.y,\n triggerHeight: triggerLayout.height,\n });\n\n return (\n <View\n style={[\n styles.popoverPanel,\n {\n top,\n left: triggerLayout.x,\n width: triggerLayout.width,\n maxHeight,\n borderColor: colors.border,\n backgroundColor: colors.bg,\n },\n ]}\n onStartShouldSetResponder={() => true}\n >\n {panelBody(false, true)}\n </View>\n );\n })()}\n </Pressable>\n </Modal>\n )}\n\n {!usePopup && isModal && (\n <Modal visible={open} transparent animationType=\"fade\">\n <Pressable style={styles.modalOverlay} onPress={close}>\n <View\n style={[styles.modalPanel, { backgroundColor: colors.bg }]}\n onStartShouldSetResponder={() => true}\n >\n {panelBody(true, true)}\n </View>\n </Pressable>\n </Modal>\n )}\n\n {/* Popup — the container comes from the wrapper (this library's own\n Dialog in sheet position); everything inside it is the same body the\n other two containers render. */}\n {usePopup && renderPopup!({\n visible: open,\n onClose: close,\n title: popupTitle,\n children: panelBody(true, false),\n })}\n\n </View>\n );\n}\n\n/* ---------------------------------------------\n Styles (layout only — colors applied inline via theme tokens)\n---------------------------------------------- */\n\nconst styles = StyleSheet.create({\n container: {\n width: \"100%\",\n position: \"relative\" as const,\n },\n control: {\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"space-between\" as const,\n borderWidth: 1,\n borderRadius: 6,\n paddingHorizontal: 10,\n paddingVertical: 10,\n },\n disabled: {\n opacity: 0.5,\n },\n option: {\n paddingHorizontal: 12,\n paddingVertical: 10,\n flexDirection: \"row\" as const,\n justifyContent: \"space-between\" as const,\n alignItems: \"center\" as const,\n },\n groupLabel: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n fontWeight: \"600\" as const,\n },\n input: {\n flex: 1,\n },\n panel: {\n position: \"absolute\" as const,\n top: \"100%\",\n left: 0,\n right: 0,\n marginTop: 4,\n borderWidth: 1,\n borderRadius: 6,\n maxHeight: 260,\n overflow: \"hidden\" as const,\n zIndex: 9999,\n },\n filterContainer: {\n paddingHorizontal: 8,\n paddingVertical: 6,\n borderBottomWidth: 1,\n },\n listFill: {\n flex: 1,\n },\n // The anchored panel is sized by `maxHeight` with no height, so the list has\n // to grow with its content up to that ceiling and then scroll inside it.\n // `flex: 1` sets flexBasis 0, which contributes nothing to a shrink-wrapping\n // parent.\n listShrink: {\n flexGrow: 0,\n flexShrink: 1,\n },\n listContent: {\n paddingBottom: 12,\n },\n filterInput: {\n fontSize: 14,\n paddingHorizontal: 8,\n paddingVertical: 6,\n borderWidth: 1,\n borderRadius: 4,\n },\n filterLtr: {\n textAlign: 'left' as const,\n writingDirection: 'ltr' as const,\n },\n filterRtl: {\n textAlign: 'right' as const,\n writingDirection: 'rtl' as const,\n },\n emptyContainer: {\n padding: 16,\n alignItems: 'center' as const,\n },\n emptyText: {\n fontSize: 14,\n },\n popoverOverlay: {\n flex: 1,\n backgroundColor: 'transparent',\n },\n popoverPanel: {\n position: 'absolute' as const,\n borderWidth: 1,\n borderRadius: 6,\n overflow: 'hidden' as const,\n elevation: 8,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.15,\n shadowRadius: 8,\n },\n modalOverlay: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.4)',\n justifyContent: 'center' as const,\n },\n modalPanel: {\n margin: 24,\n maxHeight: '70%',\n borderRadius: 12,\n overflow: 'hidden' as const,\n },\n});\n"],"names":["resolveThemeTokenForNative","useRef","useState","useSafeAreaInsets","useKeyboardHeight","useMemo","Keyboard","useCallback","jsx","Text","jsxs","Pressable","Fragment","View","TextInput","FlatList","Input","InputField","Modal","Dimensions","computePanelGeometry","StyleSheet"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAW,WAAA,KAAyB;AACpD,EAAA,IAAI,CAAC,MAAM,OAAO,EAAA;AAClB,EAAA,IAAI,CAAC,WAAA,EAAa,OAAO,MAAA,CAAO,IAAI,CAAA;AACpC,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,WAAW,CAAC,CAAA;AACjC,CAAA;AAEA,MAAM,QAAA,GAAW,CAAC,IAAA,EAAW,WAAA,KAAyB;AACpD,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AACzB,EAAA,OAAO,KAAK,WAAW,CAAA;AACzB,CAAA;AAEA,MAAM,CAAA,GAAIA,gCAAA;AAEV,MAAM,eAAA,uBAAsB,GAAA,CAAI;AAAA,EAC9B,UAAA;AAAA,EAAY,YAAA;AAAA,EAAc,YAAA;AAAA,EAAc,WAAA;AAAA,EACxC,OAAA;AAAA,EAAS,eAAA;AAAA,EAAiB,YAAA;AAAA,EAAc,WAAA;AAAA,EACxC,oBAAA;AAAA,EAAsB;AACxB,CAAC,CAAA;AAED,SAAS,WAAW,QAAA,EAAsD;AACxE,EAAA,IAAI,CAAC,QAAA,EAAU,OAAO,EAAC;AACvB,EAAA,MAAM,OAA4B,EAAC;AACnC,EAAA,MAAM,OAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC7C,IAAA,IAAI,gBAAgB,GAAA,CAAI,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,SACjC,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,EACjB;AACA,EAAA,OAAO;AAAA,IACL,WAAW,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,IAAA,GAAO,MAAA;AAAA,IAC7C,WAAW,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,IAAA,GAAO;AAAA,GAC/C;AACF;AAMA,SAAwB,QAAA,CAAkB;AAAA,EACN,KAAA;AAAA,EACA,UAAU,EAAC;AAAA,EACX,QAAA;AAAA,EAEA,WAAA;AAAA,EACA,WAAA;AAAA,EAEA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EAEV,SAAA;AAAA,EACA,iBAAA,GAAoB,IAAA;AAAA,EAEpB,MAAA;AAAA,EACA,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAA,GAAqB,kBAAA;AAAA,EACrB,iBAAA,GAAoB,WAAA;AAAA,EACpB,KAAA,GAAQ,KAAA;AAAA,EACR,KAAA,GAAQ,KAAA;AAAA,EACR,WAAA;AAAA,EACA,UAAA;AAAA,EAEA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,mBAAA;AAAA,EAEA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EAEA,sBAAA;AAAA,EAEA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA,EAAO;AACT,CAAA,EAAqB;AACrD,EAAA,MAAM,QAAA,GAAWC,aAAY,IAAI,CAAA;AACjC,EAAA,MAAM,UAAA,GAAaA,aAAa,IAAI,CAAA;AACpC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,eAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,EAAE,CAAA;AACjD,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,eAEhC,IAAI,CAAA;AACd,EAAA,MAAM,SAASC,4CAAA,EAAkB;AACjC,EAAA,MAAM,iBAAiBC,mCAAA,EAAkB;AAEzC,EAAA,MAAM,EAAE,SAAA,EAAW,iBAAA,EAAmB,WAAW,iBAAA,EAAkB,GAAI,WAAW,aAAa,CAAA;AAE/F,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,MAAA,EAAQ,CAAA,CAAE,QAAQ,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IACnC,aAAA,EAAe,CAAA,CAAE,QAAQ,CAAA,IAAK,EAAE,SAAS,CAAA;AAAA,IACzC,EAAA,EAAI,CAAA,CAAE,cAAc,CAAA,IAAK,MAAA;AAAA,IACzB,IAAA,EAAM,CAAA,CAAE,MAAM,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IAC/B,WAAA,EAAa,CAAA,CAAE,gBAAgB,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IAChD,cAAA,EAAgB,CAAA,CAAE,cAAc,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IACjD,OAAA,EAAS,CAAA,CAAE,gBAAgB,CAAA,IAAK,EAAE,SAAS,CAAA;AAAA,IAC3C,YAAA,EAAc,CAAA,CAAE,QAAQ,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IACzC,QAAA,EAAU,CAAA,CAAE,gBAAgB,CAAA,IAAK,EAAE,SAAS,CAAA;AAAA,IAC5C,UAAA,EAAY,CAAA,CAAE,MAAM,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IACrC,SAAA,EAAW,CAAA,CAAE,gBAAgB,CAAA,IAAK,EAAE,UAAU,CAAA;AAAA,IAC9C,OAAA,EAAS,EAAE,SAAS;AAAA,GACtB;AAMA,EAAA,MAAM,YAAA,GAAeC,cAAQ,MAAM;AACjC,IAAA,IAAI,KAAA,IAAS,MAAM,OAAO,IAAA;AAE1B,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,KAAA,MAAW,SAAS,OAAA,EAAkB;AACpC,QAAA,MAAM,QAAA,GAAW,MAAM,mBAAmB,CAAA;AAC1C,QAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC3B,UAAA,MAAM,KAAA,GAAQ,SAAS,IAAA,CAAK,CAAC,MAAW,QAAA,CAAS,CAAA,EAAG,WAAW,CAAA,KAAM,KAAK,CAAA;AAC1E,UAAA,IAAI,OAAO,OAAO,KAAA;AAAA,QACpB;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,OAAA,CAAQ,IAAA;AAAA,MACb,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,EAAG,WAAW,CAAA,KAAM;AAAA,KACtC,IAAK,IAAA;AAAA,EACP,GAAG,CAAC,KAAA,EAAO,OAAA,EAAS,WAAA,EAAa,mBAAmB,CAAC,CAAA;AAMrD,EAAA,MAAM,SAAS,MAAM;AACnB,IAAA,IAAI,QAAA,EAAU;AACd,IAAAC,oBAAA,CAAS,OAAA,EAAQ;AACjB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,EAAE,CAAA;AAGjB,IAAA,UAAA,CAAW,SAAS,eAAA,CAAgB,CAAC,CAAA,EAAG,CAAA,EAAG,OAAO,MAAA,KAAW;AAC3D,MAAA,gBAAA,CAAiB,EAAE,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,QAAQ,CAAA;AACxC,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,KAAK,CAAA;AAMjC,EAAA,MAAM,UAAA,GAAa,CAAC,IAAA,KAAY;AAC9B,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,IAAA,EAAM,WAAW,CAAA;AAE3C,IAAA,IAAI,CAAC,QAAA,EAAU;AAEf,IAAA,MAAM,cAAA,GAAiB;AAAA,MACrB,MAAA,EAAQ;AAAA,QACN,KAAA,EAAO;AAAA;AACT,KACF;AAEA,IAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA;AAE7B,IAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,EACf,CAAA;AAMA,EAAA,MAAM,UAAA,GAAaC,iBAAA;AAAA,IACjB,CAAC,MAAW,KAAA,KAAkB;AAC5B,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,KAAK,OAAA,EAAS;AAChB,QAAA,uBACEC,cAAA,CAACC,oBAA4B,KAAA,EAAO,CAAC,OAAO,UAAA,EAAY,EAAE,iBAAiB,MAAA,CAAO,OAAA,EAAS,CAAA,EACxF,QAAA,EAAA,gBAAA,GAAmB,KAAK,KAAA,GAAQ,gBAAgB,IAAI,EAAA,EAAA,EAD5C,CAAA,MAAA,EAAS,KAAK,CAAA,CAEzB,CAAA;AAAA,MAEJ;AAEA,MAAA,MAAM,WACJ,KAAA,IAAS,IAAA,IACT,QAAA,CAAS,IAAA,EAAM,WAAW,CAAA,KAAM,KAAA;AAElC,MAAA,IAAI,OAAA;AAEJ,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,MAAM,QAAA,GAAW,aAAa,IAAI,CAAA;AAElC,QAAA,OAAA,GAAU,KAAA,CAAM,cAAA,CAAe,QAAQ,CAAA,GACrC,QAAA,kCAECA,gBAAA,EAAA,EAAM,QAAA,EAAA,MAAA,CAAO,QAAA,IAAY,EAAE,CAAA,EAAE,CAAA;AAAA,MAElC,CAAA,MAAO;AACL,QAAA,OAAA,kCACGA,gBAAA,EAAA,EAAK,KAAA,EAAO,CAAC,EAAE,KAAA,EAAO,OAAO,IAAA,EAAK,EAAG,qBAAqB,EAAE,QAAA,EAAU,kBAAkB,QAAA,EAAU,GAChG,QAAA,EAAA,QAAA,CAAS,IAAA,EAAM,WAAW,CAAA,EAC7B,CAAA;AAAA,MAEJ;AAEA,MAAA,uBACEC,eAAA;AAAA,QAACC,qBAAA;AAAA,QAAA;AAAA,UAEC,OAAA,EAAS,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,UAC9B,KAAA,EAAO;AAAA,YACL,MAAA,CAAO,MAAA;AAAA,YACP,QAAA,IAAY,iBAAA,IAAqB,EAAE,eAAA,EAAiB,OAAO,cAAA;AAAe,WAC5E;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,OAAA;AAAA,YACA,SAAA,IAAa,QAAA,oBAAYH,cAAA,CAACC,gBAAA,EAAA,EAAK,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA,SAAA;AAAA,QAR5B,QAAQ,KAAK,CAAA;AAAA,OASpB;AAAA,IAEJ,CAAA;AAAA,IACA;AAAA,MACE,KAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,gBAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA;AACF,GACF;AAOA,EAAA,MAAM,QAAA,GAAWJ,cAAQ,MAAM;AAC7B,IAAA,IAAI,CAAC,gBAAA,IAAoB,CAAC,mBAAA,EAAqB;AAC7C,MAAA,OAAO,OAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAa,EAAC;AACpB,IAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,KAAW;AAC1B,MAAA,GAAA,CAAI,KAAK,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,GAAG,CAAA;AACpC,MAAA,CAAA,CAAE,mBAAmB,GAAG,OAAA,CAAQ,CAAC,MAAW,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IACzD,CAAC,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAMZ,EAAA,MAAM,YAAA,GAAeA,cAAQ,MAAM;AACjC,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,WAAA,EAAa,OAAO,QAAA;AACpC,IAAA,MAAM,CAAA,GAAI,YAAY,WAAA,EAAY;AAClC,IAAA,MAAM,MAAM,QAAA,IAAY,WAAA;AAExB,IAAA,OAAO,QAAA,CAAS,MAAA,CAAO,CAAC,KAAA,KAAe;AAErC,MAAA,IAAI,KAAA,CAAM,SAAS,OAAO,IAAA;AAC1B,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,GAAG,CAAA;AACjC,MAAA,OAAO,KAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,CAAC,CAAA;AAAA,IACvC,CAAC,CAAA;AAAA,EACH,GAAG,CAAC,QAAA,EAAU,QAAQ,WAAA,EAAa,QAAA,EAAU,WAAW,CAAC,CAAA;AAMzD,EAAA,MAAM,YAAA,GAAe,gBACjB,aAAA,CAAc,YAAY,IAC1B,YAAA,GACE,QAAA,CAAS,YAAA,EAAc,WAAW,CAAA,GAClC,EAAA;AAiBN,EAAA,MAAM,SAAA,GAAY,CAAC,IAAA,EAAe,eAAA,qBAChCK,eAAA,CAAAE,mBAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,MAAA,oBACCJ,cAAA,CAACK,gBAAA,EAAA,EAAK,KAAA,EAAO,CAAC,MAAA,CAAO,eAAA,EAAiB,EAAE,iBAAA,EAAmB,MAAA,CAAO,YAAA,EAAc,CAAA,EAC9E,QAAA,kBAAAL,cAAA;AAAA,MAACM,qBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,WAAA;AAAA,QACP,YAAA,EAAc,cAAA;AAAA,QACd,WAAA,EAAa,iBAAA;AAAA,QACb,sBAAsB,MAAA,CAAO,WAAA;AAAA,QAC7B,KAAA,EAAO;AAAA,UAAC,MAAA,CAAO,WAAA;AAAA,UAAa;AAAA,YAC1B,aAAa,MAAA,CAAO,YAAA;AAAA,YACpB,iBAAiB,MAAA,CAAO,QAAA;AAAA,YACxB,OAAO,MAAA,CAAO;AAAA,WAChB;AAAA;AAAA;AAAA;AAAA;AAAA,UAKA,KAAA,GAAQ,MAAA,CAAO,SAAA,GAAY,MAAA,CAAO;AAAA,SAAS;AAAA,QAM3C,SAAA,EAAW;AAAA;AAAA,KACb,EACF,CAAA;AAAA,oBAEFN,cAAA;AAAA,MAACO,oBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,IAAA,GAAO,MAAA,CAAO,QAAA,GAAW,MAAA,CAAO,UAAA;AAAA,QACvC,uBAAuB,MAAA,CAAO,WAAA;AAAA,QAC9B,IAAA,EAAM,YAAA;AAAA,QACN,YAAA,EAAc,CAAC,IAAA,EAAW,CAAA,KACxB,IAAA,EAAM,UAAU,CAAA,MAAA,EAAS,CAAC,CAAA,CAAA,GAAK,CAAA,KAAA,EAAQ,CAAC,CAAA,CAAA;AAAA,QAE1C,UAAA,EAAY,CAAC,EAAE,IAAA,EAAM,OAAM,KAAM,UAAA,CAAW,MAAM,KAAK,CAAA;AAAA,QACvD,yBAAA,EAA0B,SAAA;AAAA,QAC1B,8BAAA,EAAgC,KAAA;AAAA,QAChC,kBAAA,EACE,8BACEP,cAAA,CAACK,gBAAA,EAAA,EAAK,OAAO,MAAA,CAAO,cAAA,EAClB,yCAACJ,gBAAA,EAAA,EAAK,KAAA,EAAO,CAAC,MAAA,CAAO,SAAA,EAAW,EAAE,KAAA,EAAO,MAAA,CAAO,WAAW,CAAA,EAAI,QAAA,EAAA,kBAAA,EAAmB,CAAA,EACpF,CAAA,GACE;AAAA;AAAA,KAER;AAAA,IACC,mBAAA;AAAsB,GAAA,EACzB,CAAA;AAOF,EAAA,MAAM,QAAA,GAAW,KAAA,IAAS,OAAO,WAAA,KAAgB,UAAA;AAEjD,EAAA,uBACEC,eAAA,CAACG,gBAAA,EAAA,EAAK,KAAA,EAAO,MAAA,CAAO,WAAW,MAAA,EAC7B,QAAA,EAAA;AAAA,oBAAAH,eAAA;AAAA,MAACC,qBAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,KAAA,EAAO;AAAA,UACL,MAAA,CAAO,OAAA;AAAA,UACP,EAAE,WAAA,EAAa,MAAA,CAAO,MAAA,EAAQ,eAAA,EAAiB,OAAO,EAAA,EAAG;AAAA,UACzD,OAAA,IAAW,EAAE,WAAA,EAAa,MAAA,CAAO,aAAA,EAAc;AAAA,UAC/C,YAAY,MAAA,CAAO,QAAA;AAAA,UACnB;AAAA,SACF;AAAA,QACA,OAAA,EAAS,MAAA;AAAA,QAER,QAAA,EAAA;AAAA,UAAA,QAAA,mBACCH,cAAA,CAACQ,WAAA,EAAA,EAAM,KAAA,EAAO,MAAA,CAAO,KAAA,EACnB,QAAA,kBAAAR,cAAA;AAAA,YAACS,gBAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,QAAA;AAAA,cACL,KAAA,EAAO,SAAA;AAAA,cACP,YAAA,EAAc,YAAA;AAAA,cACd,WAAA;AAAA,cACA,UAAU,CAAC;AAAA;AAAA,aAEf,CAAA,mBAEAT,cAAA;AAAA,YAACC,gBAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAe,CAAA;AAAA,cACf,KAAA,EAAO;AAAA;AAAA;AAAA;AAAA,gBAIL,EAAE,IAAA,EAAM,CAAA,EAAG,SAAA,EAAW,MAAA,EAAgB;AAAA,gBACtC,YAAA,GAAe,EAAE,KAAA,EAAO,MAAA,CAAO,MAAK,GAAI,EAAE,KAAA,EAAO,MAAA,CAAO,WAAA,EAAY;AAAA,gBACpE,iBAAA;AAAA,gBACA,CAAC,YAAA,IAAgB,EAAE,KAAA,EAAO,OAAO,WAAA;AAAY,eAC/C;AAAA,cACC,QAAA,EAAA,YAAA,IAAgB;AAAA;AAAA,WACnB;AAAA,0BAGFD,cAAA,CAACC,gBAAA,EAAA,EAAK,KAAA,EAAO,CAAC,EAAE,KAAA,EAAO,MAAA,CAAO,IAAA,EAAK,EAAG,iBAAiB,CAAA,EAAG,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA;AAAA,KAC7D;AAAA,IAEC,CAAC,QAAA,IAAY,CAAC,OAAA,oBACbD,cAAA;AAAA,MAACU,iBAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,IAAA,IAAQ,CAAC,CAAC,aAAA;AAAA,QACnB,WAAA,EAAW,IAAA;AAAA,QACX,aAAA,EAAc,MAAA;AAAA,QACd,cAAA,EAAgB,KAAA;AAAA,QAEhB,QAAA,kBAAAV,cAAA,CAACG,yBAAU,KAAA,EAAO,MAAA,CAAO,gBAAgB,OAAA,EAAS,KAAA,EAC/C,4BAAkB,MAAM;AACvB,UAAA,MAAM,MAAA,GAASQ,sBAAA,CAAW,GAAA,CAAI,QAAQ,CAAA;AACtC,UAAA,MAAM,EAAE,GAAA,EAAK,SAAA,EAAU,GAAIC,kCAAA,CAAqB;AAAA,YAC9C,cAAc,MAAA,CAAO,MAAA;AAAA,YACrB,UAAU,MAAA,CAAO,GAAA;AAAA,YACjB,aAAa,MAAA,CAAO,MAAA;AAAA,YACpB,cAAA;AAAA,YACA,UAAU,aAAA,CAAc,CAAA;AAAA,YACxB,eAAe,aAAA,CAAc;AAAA,WAC9B,CAAA;AAED,UAAA,uBACEZ,cAAA;AAAA,YAACK,gBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO;AAAA,gBACL,MAAA,CAAO,YAAA;AAAA,gBACP;AAAA,kBACE,GAAA;AAAA,kBACA,MAAM,aAAA,CAAc,CAAA;AAAA,kBACpB,OAAO,aAAA,CAAc,KAAA;AAAA,kBACrB,SAAA;AAAA,kBACA,aAAa,MAAA,CAAO,MAAA;AAAA,kBACpB,iBAAiB,MAAA,CAAO;AAAA;AAC1B,eACF;AAAA,cACA,2BAA2B,MAAM,IAAA;AAAA,cAEhC,QAAA,EAAA,SAAA,CAAU,OAAO,IAAI;AAAA;AAAA,WACxB;AAAA,QAEJ,IAAG,EACL;AAAA;AAAA,KACF;AAAA,IAGD,CAAC,QAAA,IAAY,OAAA,oBACZL,cAAA,CAACU,iBAAA,EAAA,EAAM,SAAS,IAAA,EAAM,WAAA,EAAW,IAAA,EAAC,aAAA,EAAc,QAC9C,QAAA,kBAAAV,cAAA,CAACG,qBAAA,EAAA,EAAU,OAAO,MAAA,CAAO,YAAA,EAAc,SAAS,KAAA,EAC9C,QAAA,kBAAAH,cAAA;AAAA,MAACK,gBAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAC,MAAA,CAAO,UAAA,EAAY,EAAE,eAAA,EAAiB,MAAA,CAAO,IAAI,CAAA;AAAA,QACzD,2BAA2B,MAAM,IAAA;AAAA,QAEhC,QAAA,EAAA,SAAA,CAAU,MAAM,IAAI;AAAA;AAAA,OAEzB,CAAA,EACF,CAAA;AAAA,IAMD,YAAY,WAAA,CAAa;AAAA,MACxB,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAAS,KAAA;AAAA,MACT,KAAA,EAAO,UAAA;AAAA,MACP,QAAA,EAAU,SAAA,CAAU,IAAA,EAAM,KAAK;AAAA,KAChC;AAAA,GAAA,EAEH,CAAA;AAEJ;AAMA,MAAM,MAAA,GAASQ,uBAAW,MAAA,CAAO;AAAA,EAC/B,SAAA,EAAW;AAAA,IACT,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,aAAA,EAAe,KAAA;AAAA,IACf,UAAA,EAAY,QAAA;AAAA,IACZ,cAAA,EAAgB,eAAA;AAAA,IAChB,WAAA,EAAa,CAAA;AAAA,IACb,YAAA,EAAc,CAAA;AAAA,IACd,iBAAA,EAAmB,EAAA;AAAA,IACnB,eAAA,EAAiB;AAAA,GACnB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAA,EAAS;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,iBAAA,EAAmB,EAAA;AAAA,IACnB,eAAA,EAAiB,EAAA;AAAA,IACjB,aAAA,EAAe,KAAA;AAAA,IACf,cAAA,EAAgB,eAAA;AAAA,IAChB,UAAA,EAAY;AAAA,GACd;AAAA,EACA,UAAA,EAAY;AAAA,IACV,iBAAA,EAAmB,EAAA;AAAA,IACnB,eAAA,EAAiB,CAAA;AAAA,IACjB,UAAA,EAAY;AAAA,GACd;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM;AAAA,GACR;AAAA,EACA,KAAA,EAAO;AAAA,IACL,QAAA,EAAU,UAAA;AAAA,IACV,GAAA,EAAK,MAAA;AAAA,IACL,IAAA,EAAM,CAAA;AAAA,IACN,KAAA,EAAO,CAAA;AAAA,IACP,SAAA,EAAW,CAAA;AAAA,IACX,WAAA,EAAa,CAAA;AAAA,IACb,YAAA,EAAc,CAAA;AAAA,IACd,SAAA,EAAW,GAAA;AAAA,IACX,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,iBAAA,EAAmB,CAAA;AAAA,IACnB,eAAA,EAAiB,CAAA;AAAA,IACjB,iBAAA,EAAmB;AAAA,GACrB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM;AAAA,GACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,EAAY;AAAA,IACV,QAAA,EAAU,CAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA,EACA,WAAA,EAAa;AAAA,IACX,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,QAAA,EAAU,EAAA;AAAA,IACV,iBAAA,EAAmB,CAAA;AAAA,IACnB,eAAA,EAAiB,CAAA;AAAA,IACjB,WAAA,EAAa,CAAA;AAAA,IACb,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,SAAA,EAAW,MAAA;AAAA,IACX,gBAAA,EAAkB;AAAA,GACpB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,SAAA,EAAW,OAAA;AAAA,IACX,gBAAA,EAAkB;AAAA,GACpB;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,OAAA,EAAS,EAAA;AAAA,IACT,UAAA,EAAY;AAAA,GACd;AAAA,EACA,SAAA,EAAW;AAAA,IACT,QAAA,EAAU;AAAA,GACZ;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,IAAA,EAAM,CAAA;AAAA,IACN,eAAA,EAAiB;AAAA,GACnB;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,QAAA,EAAU,UAAA;AAAA,IACV,WAAA,EAAa,CAAA;AAAA,IACb,YAAA,EAAc,CAAA;AAAA,IACd,QAAA,EAAU,QAAA;AAAA,IACV,SAAA,EAAW,CAAA;AAAA,IACX,WAAA,EAAa,MAAA;AAAA,IACb,YAAA,EAAc,EAAE,KAAA,EAAO,CAAA,EAAG,QAAQ,CAAA,EAAE;AAAA,IACpC,aAAA,EAAe,IAAA;AAAA,IACf,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,CAAA;AAAA,IACN,eAAA,EAAiB,iBAAA;AAAA,IACjB,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,UAAA,EAAY;AAAA,IACV,MAAA,EAAQ,EAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,EAAA;AAAA,IACd,QAAA,EAAU;AAAA;AAEd,CAAC,CAAA;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import React, { useRef, useState,
|
|
3
|
-
import {
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import React, { useRef, useState, useMemo, useCallback } from 'react';
|
|
3
|
+
import { Text, Pressable, View, Modal, Dimensions, Keyboard, TextInput, FlatList, StyleSheet } from 'react-native';
|
|
4
4
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
5
|
import '../../ui/accordion/index.js';
|
|
6
6
|
import '../../ui/actionsheet/index.js';
|
|
@@ -61,6 +61,7 @@ import '../../../../../packages/types/src/Theme/shadows.js';
|
|
|
61
61
|
import '../../../../../packages/types/src/Theme/defaultTheme.js';
|
|
62
62
|
import '../../../../../packages/types/src/Theme/alphaColors.js';
|
|
63
63
|
import '../../Factory/helpers/cssVarMap.js';
|
|
64
|
+
import { useKeyboardHeight } from '../../Factory/helpers/useKeyboardHeight.js';
|
|
64
65
|
import 'i18next';
|
|
65
66
|
import 'react-i18next';
|
|
66
67
|
import '../AutoComplete/index.js';
|
|
@@ -141,6 +142,9 @@ function Dropdown({
|
|
|
141
142
|
emptyFilterMessage = "No results found",
|
|
142
143
|
filterPlaceholder = "Search...",
|
|
143
144
|
isRTL = false,
|
|
145
|
+
popup = false,
|
|
146
|
+
renderPopup,
|
|
147
|
+
popupTitle,
|
|
144
148
|
itemTemplate,
|
|
145
149
|
valueTemplate,
|
|
146
150
|
panelFooterTemplate,
|
|
@@ -159,19 +163,7 @@ function Dropdown({
|
|
|
159
163
|
const [filterQuery, setFilterQuery] = useState("");
|
|
160
164
|
const [triggerLayout, setTriggerLayout] = useState(null);
|
|
161
165
|
const insets = useSafeAreaInsets();
|
|
162
|
-
const
|
|
163
|
-
useEffect(() => {
|
|
164
|
-
const showEvent = Platform.OS === "ios" ? "keyboardWillChangeFrame" : "keyboardDidShow";
|
|
165
|
-
const hideEvent = Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide";
|
|
166
|
-
const onShow = (event) => setKeyboardHeight(event?.endCoordinates?.height ?? 0);
|
|
167
|
-
const onHide = () => setKeyboardHeight(0);
|
|
168
|
-
const showSub = Keyboard.addListener(showEvent, onShow);
|
|
169
|
-
const hideSub = Keyboard.addListener(hideEvent, onHide);
|
|
170
|
-
return () => {
|
|
171
|
-
showSub.remove();
|
|
172
|
-
hideSub.remove();
|
|
173
|
-
};
|
|
174
|
-
}, []);
|
|
166
|
+
const keyboardHeight = useKeyboardHeight();
|
|
175
167
|
const { viewStyle: externalViewStyle, textStyle: externalTextStyle } = splitStyle(externalStyle);
|
|
176
168
|
const colors = {
|
|
177
169
|
border: t("border") || t("gray.300"),
|
|
@@ -292,6 +284,46 @@ function Dropdown({
|
|
|
292
284
|
});
|
|
293
285
|
}, [flatData, filter, filterQuery, filterBy, optionLabel]);
|
|
294
286
|
const displayValue = valueTemplate ? valueTemplate(selectedItem) : selectedItem ? getLabel(selectedItem, optionLabel) : "";
|
|
287
|
+
const panelBody = (fill, autoFocusFilter) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
288
|
+
filter && /* @__PURE__ */ jsx(View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsx(
|
|
289
|
+
TextInput,
|
|
290
|
+
{
|
|
291
|
+
value: filterQuery,
|
|
292
|
+
onChangeText: setFilterQuery,
|
|
293
|
+
placeholder: filterPlaceholder,
|
|
294
|
+
placeholderTextColor: colors.placeholder,
|
|
295
|
+
style: [
|
|
296
|
+
styles.filterInput,
|
|
297
|
+
{
|
|
298
|
+
borderColor: colors.filterBorder,
|
|
299
|
+
backgroundColor: colors.filterBg,
|
|
300
|
+
color: colors.filterText
|
|
301
|
+
},
|
|
302
|
+
// Every other input in this library names its own edge and
|
|
303
|
+
// direction from the reader's language. Leaving these unset let the
|
|
304
|
+
// platform decide, so the field followed the process layout
|
|
305
|
+
// direction instead of the person reading it.
|
|
306
|
+
isRTL ? styles.filterRtl : styles.filterLtr
|
|
307
|
+
],
|
|
308
|
+
autoFocus: autoFocusFilter
|
|
309
|
+
}
|
|
310
|
+
) }),
|
|
311
|
+
/* @__PURE__ */ jsx(
|
|
312
|
+
FlatList,
|
|
313
|
+
{
|
|
314
|
+
style: fill ? styles.listFill : styles.listShrink,
|
|
315
|
+
contentContainerStyle: styles.listContent,
|
|
316
|
+
data: filteredData,
|
|
317
|
+
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
318
|
+
renderItem: ({ item, index }) => renderItem(item, index),
|
|
319
|
+
keyboardShouldPersistTaps: "handled",
|
|
320
|
+
showsHorizontalScrollIndicator: false,
|
|
321
|
+
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsx(View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsx(Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
322
|
+
}
|
|
323
|
+
),
|
|
324
|
+
panelFooterTemplate?.()
|
|
325
|
+
] });
|
|
326
|
+
const usePopup = popup && typeof renderPopup === "function";
|
|
295
327
|
return /* @__PURE__ */ jsxs(View, { style: styles.container, testID, children: [
|
|
296
328
|
/* @__PURE__ */ jsxs(
|
|
297
329
|
Pressable,
|
|
@@ -335,7 +367,7 @@ function Dropdown({
|
|
|
335
367
|
]
|
|
336
368
|
}
|
|
337
369
|
),
|
|
338
|
-
!isModal && /* @__PURE__ */ jsx(
|
|
370
|
+
!usePopup && !isModal && /* @__PURE__ */ jsx(
|
|
339
371
|
Modal,
|
|
340
372
|
{
|
|
341
373
|
visible: open && !!triggerLayout,
|
|
@@ -352,7 +384,7 @@ function Dropdown({
|
|
|
352
384
|
triggerY: triggerLayout.y,
|
|
353
385
|
triggerHeight: triggerLayout.height
|
|
354
386
|
});
|
|
355
|
-
return /* @__PURE__ */
|
|
387
|
+
return /* @__PURE__ */ jsx(
|
|
356
388
|
View,
|
|
357
389
|
{
|
|
358
390
|
style: [
|
|
@@ -367,93 +399,26 @@ function Dropdown({
|
|
|
367
399
|
}
|
|
368
400
|
],
|
|
369
401
|
onStartShouldSetResponder: () => true,
|
|
370
|
-
children:
|
|
371
|
-
filter && /* @__PURE__ */ jsx(View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsx(
|
|
372
|
-
TextInput,
|
|
373
|
-
{
|
|
374
|
-
value: filterQuery,
|
|
375
|
-
onChangeText: setFilterQuery,
|
|
376
|
-
placeholder: filterPlaceholder,
|
|
377
|
-
placeholderTextColor: colors.placeholder,
|
|
378
|
-
style: [
|
|
379
|
-
styles.filterInput,
|
|
380
|
-
{
|
|
381
|
-
borderColor: colors.filterBorder,
|
|
382
|
-
backgroundColor: colors.filterBg,
|
|
383
|
-
color: colors.filterText
|
|
384
|
-
},
|
|
385
|
-
// Every other input in this library names its own edge
|
|
386
|
-
// and direction from the reader's language. Leaving
|
|
387
|
-
// these unset let the platform decide, so the field
|
|
388
|
-
// followed the process layout direction instead of the
|
|
389
|
-
// person reading it.
|
|
390
|
-
isRTL ? styles.filterRtl : styles.filterLtr
|
|
391
|
-
],
|
|
392
|
-
autoFocus: true
|
|
393
|
-
}
|
|
394
|
-
) }),
|
|
395
|
-
/* @__PURE__ */ jsx(
|
|
396
|
-
FlatList,
|
|
397
|
-
{
|
|
398
|
-
style: { flexGrow: 0, flexShrink: 1 },
|
|
399
|
-
contentContainerStyle: { paddingBottom: 12 },
|
|
400
|
-
data: filteredData,
|
|
401
|
-
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
402
|
-
renderItem: ({ item, index }) => renderItem(item, index),
|
|
403
|
-
keyboardShouldPersistTaps: "handled",
|
|
404
|
-
showsHorizontalScrollIndicator: false,
|
|
405
|
-
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsx(View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsx(Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
406
|
-
}
|
|
407
|
-
),
|
|
408
|
-
panelFooterTemplate?.()
|
|
409
|
-
]
|
|
402
|
+
children: panelBody(false, true)
|
|
410
403
|
}
|
|
411
404
|
);
|
|
412
405
|
})() })
|
|
413
406
|
}
|
|
414
407
|
),
|
|
415
|
-
isModal && /* @__PURE__ */ jsx(Modal, { visible: open, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsx(Pressable, { style: styles.modalOverlay, onPress: close, children: /* @__PURE__ */
|
|
408
|
+
!usePopup && isModal && /* @__PURE__ */ jsx(Modal, { visible: open, transparent: true, animationType: "fade", children: /* @__PURE__ */ jsx(Pressable, { style: styles.modalOverlay, onPress: close, children: /* @__PURE__ */ jsx(
|
|
416
409
|
View,
|
|
417
410
|
{
|
|
418
411
|
style: [styles.modalPanel, { backgroundColor: colors.bg }],
|
|
419
412
|
onStartShouldSetResponder: () => true,
|
|
420
|
-
children:
|
|
421
|
-
filter && /* @__PURE__ */ jsx(View, { style: [styles.filterContainer, { borderBottomColor: colors.filterBorder }], children: /* @__PURE__ */ jsx(
|
|
422
|
-
TextInput,
|
|
423
|
-
{
|
|
424
|
-
value: filterQuery,
|
|
425
|
-
onChangeText: setFilterQuery,
|
|
426
|
-
placeholder: filterPlaceholder,
|
|
427
|
-
placeholderTextColor: colors.placeholder,
|
|
428
|
-
style: [
|
|
429
|
-
styles.filterInput,
|
|
430
|
-
{
|
|
431
|
-
borderColor: colors.filterBorder,
|
|
432
|
-
backgroundColor: colors.filterBg,
|
|
433
|
-
color: colors.filterText
|
|
434
|
-
},
|
|
435
|
-
isRTL ? styles.filterRtl : styles.filterLtr
|
|
436
|
-
],
|
|
437
|
-
autoFocus: true
|
|
438
|
-
}
|
|
439
|
-
) }),
|
|
440
|
-
/* @__PURE__ */ jsx(
|
|
441
|
-
FlatList,
|
|
442
|
-
{
|
|
443
|
-
data: filteredData,
|
|
444
|
-
keyExtractor: (item, i) => item?.__group ? `group-${i}` : `item-${i}`,
|
|
445
|
-
renderItem: ({ item, index }) => renderItem(item, index),
|
|
446
|
-
nestedScrollEnabled: true,
|
|
447
|
-
keyboardShouldPersistTaps: "handled",
|
|
448
|
-
style: { flex: 1 },
|
|
449
|
-
contentContainerStyle: { paddingBottom: 12 },
|
|
450
|
-
ListEmptyComponent: filterQuery ? /* @__PURE__ */ jsx(View, { style: styles.emptyContainer, children: /* @__PURE__ */ jsx(Text, { style: [styles.emptyText, { color: colors.emptyText }], children: emptyFilterMessage }) }) : null
|
|
451
|
-
}
|
|
452
|
-
),
|
|
453
|
-
panelFooterTemplate?.()
|
|
454
|
-
]
|
|
413
|
+
children: panelBody(true, true)
|
|
455
414
|
}
|
|
456
|
-
) }) })
|
|
415
|
+
) }) }),
|
|
416
|
+
usePopup && renderPopup({
|
|
417
|
+
visible: open,
|
|
418
|
+
onClose: close,
|
|
419
|
+
title: popupTitle,
|
|
420
|
+
children: panelBody(true, false)
|
|
421
|
+
})
|
|
457
422
|
] });
|
|
458
423
|
}
|
|
459
424
|
const styles = StyleSheet.create({
|
|
@@ -505,6 +470,20 @@ const styles = StyleSheet.create({
|
|
|
505
470
|
paddingVertical: 6,
|
|
506
471
|
borderBottomWidth: 1
|
|
507
472
|
},
|
|
473
|
+
listFill: {
|
|
474
|
+
flex: 1
|
|
475
|
+
},
|
|
476
|
+
// The anchored panel is sized by `maxHeight` with no height, so the list has
|
|
477
|
+
// to grow with its content up to that ceiling and then scroll inside it.
|
|
478
|
+
// `flex: 1` sets flexBasis 0, which contributes nothing to a shrink-wrapping
|
|
479
|
+
// parent.
|
|
480
|
+
listShrink: {
|
|
481
|
+
flexGrow: 0,
|
|
482
|
+
flexShrink: 1
|
|
483
|
+
},
|
|
484
|
+
listContent: {
|
|
485
|
+
paddingBottom: 12
|
|
486
|
+
},
|
|
508
487
|
filterInput: {
|
|
509
488
|
fontSize: 14,
|
|
510
489
|
paddingHorizontal: 8,
|