@platform-blocks/ui 0.1.2 → 0.2.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.
- package/README.md +38 -1
- package/lib/cjs/index.js +1403 -321
- package/lib/cjs/index.js.map +1 -1
- package/lib/components/FileInput/types.d.ts +12 -3
- package/lib/components/Highlight/Highlight.d.ts +4 -0
- package/lib/components/Highlight/index.d.ts +3 -0
- package/lib/components/Highlight/types.d.ts +24 -0
- package/lib/components/MenuItemButton/MenuItemButton.d.ts +29 -1
- package/lib/components/Popover/Popover.d.ts +14 -0
- package/lib/components/Popover/index.d.ts +2 -0
- package/lib/components/Popover/styles.d.ts +66 -0
- package/lib/components/Popover/types.d.ts +129 -0
- package/lib/components/ShimmerText/ShimmerText.d.ts +1 -0
- package/lib/components/Spotlight/Spotlight.d.ts +1 -1
- package/lib/components/Spotlight/SpotlightController.d.ts +2 -1
- package/lib/components/Spotlight/types.d.ts +3 -1
- package/lib/components/Toast/types.d.ts +2 -0
- package/lib/components/index.d.ts +4 -0
- package/lib/core/factory/factory.d.ts +3 -3
- package/lib/core/theme/PlatformBlocksProvider.d.ts +2 -1
- package/lib/esm/index.js +1404 -325
- package/lib/esm/index.js.map +1 -1
- package/lib/index.d.ts +4 -0
- package/lib/utils/optionalDependencies.d.ts +13 -0
- package/package.json +37 -40
package/lib/cjs/index.js
CHANGED
|
@@ -5,11 +5,9 @@ var React = require('react');
|
|
|
5
5
|
var reactNative = require('react-native');
|
|
6
6
|
var Animated = require('react-native-reanimated');
|
|
7
7
|
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
8
|
-
var expoLinearGradient = require('expo-linear-gradient');
|
|
9
8
|
var Svg = require('react-native-svg');
|
|
10
9
|
var flashList = require('@shopify/flash-list');
|
|
11
10
|
var MaskedView = require('@react-native-masked-view/masked-view');
|
|
12
|
-
var DocumentPicker = require('expo-document-picker');
|
|
13
11
|
var ReanimatedCarousel = require('react-native-reanimated-carousel');
|
|
14
12
|
|
|
15
13
|
function _interopNamespaceDefault(e) {
|
|
@@ -30,7 +28,6 @@ function _interopNamespaceDefault(e) {
|
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
33
|
-
var DocumentPicker__namespace = /*#__PURE__*/_interopNamespaceDefault(DocumentPicker);
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
33
|
* Design tokens for consistent styling across the UI library
|
|
@@ -679,7 +676,7 @@ const DARK_THEME = {
|
|
|
679
676
|
'#8E8E93',
|
|
680
677
|
'#AEAEB2',
|
|
681
678
|
'#C7C7CC',
|
|
682
|
-
'#
|
|
679
|
+
'#D1D1D6',
|
|
683
680
|
'#E5E5EA'
|
|
684
681
|
],
|
|
685
682
|
success: [
|
|
@@ -3170,6 +3167,21 @@ const convertToWebStyles = (rnStyles) => {
|
|
|
3170
3167
|
});
|
|
3171
3168
|
return webStyles;
|
|
3172
3169
|
};
|
|
3170
|
+
const containsPlatformText = (node) => {
|
|
3171
|
+
return React.Children.toArray(node).some(child => {
|
|
3172
|
+
if (React.isValidElement(child)) {
|
|
3173
|
+
const childType = child.type;
|
|
3174
|
+
if ((childType === null || childType === void 0 ? void 0 : childType.__PLATFORM_BLOCKS_TEXT__) === true) {
|
|
3175
|
+
return true;
|
|
3176
|
+
}
|
|
3177
|
+
const childProps = child.props;
|
|
3178
|
+
if (childProps === null || childProps === void 0 ? void 0 : childProps.children) {
|
|
3179
|
+
return containsPlatformText(childProps.children);
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
return false;
|
|
3183
|
+
});
|
|
3184
|
+
};
|
|
3173
3185
|
const Text = (allProps) => {
|
|
3174
3186
|
const { spacingProps, otherProps } = extractSpacingProps(allProps);
|
|
3175
3187
|
const { children, tx, txParams, variant = 'p', size, weight, align = 'left', color, colorVariant, lineHeight, tracking, uppercase, style, fontFamily, as, selectable = true, onPress, onLayout, value, numberOfLines, ellipsizeMode } = otherProps;
|
|
@@ -3210,6 +3222,10 @@ const Text = (allProps) => {
|
|
|
3210
3222
|
// Switch to div to prevent <h*> inside <p> DOM nesting warning / hydration error
|
|
3211
3223
|
htmlTag = 'div';
|
|
3212
3224
|
}
|
|
3225
|
+
if (htmlTag === 'p' && containsPlatformText(children)) {
|
|
3226
|
+
// Avoid nested paragraphs when Text components are nested
|
|
3227
|
+
htmlTag = 'div';
|
|
3228
|
+
}
|
|
3213
3229
|
}
|
|
3214
3230
|
// Platform-specific rendering
|
|
3215
3231
|
if (reactNative.Platform.OS === 'web' && isHTMLVariant(htmlTag)) {
|
|
@@ -3247,6 +3263,7 @@ const Text = (allProps) => {
|
|
|
3247
3263
|
// Fallback to React Native Text for mobile or non-HTML variants
|
|
3248
3264
|
return (jsxRuntime.jsx(reactNative.Text, { style: [textStyles, spacingStyles, style], selectable: selectable, onPress: onPress, onLayout: onLayout, numberOfLines: numberOfLines, ellipsizeMode: ellipsizeMode, children: content }));
|
|
3249
3265
|
};
|
|
3266
|
+
Text.__PLATFORM_BLOCKS_TEXT__ = true;
|
|
3250
3267
|
// Helper function to check if variant is a valid HTML tag
|
|
3251
3268
|
const isHTMLVariant = (variant) => {
|
|
3252
3269
|
const htmlTags = [
|
|
@@ -4176,6 +4193,12 @@ const actionIcons = {
|
|
|
4176
4193
|
variant: 'outlined',
|
|
4177
4194
|
description: 'Magnifying glass and highlight circle to represent spotlight search.',
|
|
4178
4195
|
},
|
|
4196
|
+
highlight: {
|
|
4197
|
+
content: 'm15.728 3.514 4.758 4.758-7.071 7.071-2.474.353a1 1 0 0 1-1.118-1.118l.353-2.474 7.552-7.03Zm-9.95 8.486 3.222 3.222-3 3H3a1 1 0 0 1-1-1v-2.999l3.778-3.223Z',
|
|
4198
|
+
viewBox: '0 0 24 24',
|
|
4199
|
+
variant: 'outlined',
|
|
4200
|
+
description: 'Highlighter marker illustrating text emphasis.',
|
|
4201
|
+
},
|
|
4179
4202
|
minus: {
|
|
4180
4203
|
content: 'M5 12h14',
|
|
4181
4204
|
viewBox: '0 0 24 24',
|
|
@@ -4662,6 +4685,12 @@ const uiIcons = {
|
|
|
4662
4685
|
variant: 'outlined',
|
|
4663
4686
|
description: 'Tooltip badge with question mark for contextual hints.',
|
|
4664
4687
|
},
|
|
4688
|
+
popover: {
|
|
4689
|
+
content: 'M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-5.17L12 19.17 9.17 16H6a2 2 0 0 1-2-2V6z',
|
|
4690
|
+
viewBox: '0 0 24 24',
|
|
4691
|
+
variant: 'outlined',
|
|
4692
|
+
description: 'Popover surface with speech arrow for contextual overlays.',
|
|
4693
|
+
},
|
|
4665
4694
|
'layer-mask': {
|
|
4666
4695
|
content: 'M5 4h4 M4 5v4 M19 4h-4 M20 5v4 M19 20h-4 M20 19v-4 M5 20h4 M4 19v-4 M9 9h12v10H9z M13 13h4v4h-4z',
|
|
4667
4696
|
viewBox: '0 0 24 24',
|
|
@@ -4669,10 +4698,22 @@ const uiIcons = {
|
|
|
4669
4698
|
description: 'Layered frame with inset window representing an overlay mask.',
|
|
4670
4699
|
},
|
|
4671
4700
|
slider: {
|
|
4672
|
-
content: '
|
|
4701
|
+
content: 'M12 3a1 1 0 0 1 .993 .883l.007 .117v9.171a3.001 3.001 0 0 1 0 5.658v1.171a1 1 0 0 1 -1.993 .117l-.007 -.117v-1.17a3.002 3.002 0 0 1 -1.995 -2.654l-.005 -.176l.005 -.176a3.002 3.002 0 0 1 1.995 -2.654v-9.17a1 1 0 0 1 1 -1z',
|
|
4673
4702
|
viewBox: '0 0 24 24',
|
|
4674
4703
|
variant: 'outlined',
|
|
4675
|
-
description: '
|
|
4704
|
+
description: 'Horizontal slider track with centered thumb knob.',
|
|
4705
|
+
},
|
|
4706
|
+
hook: {
|
|
4707
|
+
content: 'M6 3v7a6 6 0 1 0 12 0v-2M6 6h6M10 13c0 2 1.5 3 3 3s3-1 3-3',
|
|
4708
|
+
viewBox: '0 0 24 24',
|
|
4709
|
+
variant: 'outlined',
|
|
4710
|
+
description: 'Fishing hook silhouette for representing hooks utilities.',
|
|
4711
|
+
},
|
|
4712
|
+
support: {
|
|
4713
|
+
content: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm0 4a6 6 0 1 1 0 12 6 6 0 0 1 0-12Zm-4.95-.95 2.12 2.12-1.06 1.06-2.12-2.12 1.06-1.06Zm9.9 0 1.06 1.06-2.12 2.12-1.06-1.06 2.12-2.12ZM7.05 16.95l-1.06-1.06 2.12-2.12 1.06 1.06-2.12 2.12Zm9.9 0-2.12-2.12 1.06-1.06 2.12 2.12-1.06 1.06Z',
|
|
4714
|
+
viewBox: '0 0 24 24',
|
|
4715
|
+
variant: 'outlined',
|
|
4716
|
+
description: 'Life preserver style icon to represent support resources.',
|
|
4676
4717
|
},
|
|
4677
4718
|
input: {
|
|
4678
4719
|
content: 'M4 6h16v2H4zM4 12h16v6H4z',
|
|
@@ -5618,6 +5659,65 @@ const createAccessibilityProps = (options) => {
|
|
|
5618
5659
|
return accessibilityProps;
|
|
5619
5660
|
};
|
|
5620
5661
|
|
|
5662
|
+
let linearGradientCache;
|
|
5663
|
+
let linearGradientAvailable = false;
|
|
5664
|
+
let warnedLinearGradient = false;
|
|
5665
|
+
const LinearGradientFallback = ({ children, style, colors }) => {
|
|
5666
|
+
if (__DEV__ && !warnedLinearGradient) {
|
|
5667
|
+
console.warn('expo-linear-gradient not installed; gradient-based components fall back to solid colors.');
|
|
5668
|
+
warnedLinearGradient = true;
|
|
5669
|
+
}
|
|
5670
|
+
const styles = [
|
|
5671
|
+
(colors === null || colors === void 0 ? void 0 : colors[0]) ? { backgroundColor: colors[0] } : undefined,
|
|
5672
|
+
...(Array.isArray(style) ? style : style ? [style] : []),
|
|
5673
|
+
].filter(Boolean);
|
|
5674
|
+
return React.createElement(reactNative.View, { style: styles }, children);
|
|
5675
|
+
};
|
|
5676
|
+
function resolveLinearGradient() {
|
|
5677
|
+
var _a, _b;
|
|
5678
|
+
if (linearGradientCache === undefined) {
|
|
5679
|
+
try {
|
|
5680
|
+
const mod = require('expo-linear-gradient');
|
|
5681
|
+
linearGradientCache = (_b = (_a = mod === null || mod === void 0 ? void 0 : mod.LinearGradient) !== null && _a !== void 0 ? _a : mod === null || mod === void 0 ? void 0 : mod.default) !== null && _b !== void 0 ? _b : mod;
|
|
5682
|
+
linearGradientAvailable = !!linearGradientCache;
|
|
5683
|
+
}
|
|
5684
|
+
catch (_c) {
|
|
5685
|
+
linearGradientCache = LinearGradientFallback;
|
|
5686
|
+
linearGradientAvailable = false;
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
if (!linearGradientCache) {
|
|
5690
|
+
linearGradientCache = LinearGradientFallback;
|
|
5691
|
+
linearGradientAvailable = false;
|
|
5692
|
+
}
|
|
5693
|
+
return {
|
|
5694
|
+
LinearGradient: linearGradientCache,
|
|
5695
|
+
hasLinearGradient: linearGradientAvailable,
|
|
5696
|
+
};
|
|
5697
|
+
}
|
|
5698
|
+
let documentPickerCache;
|
|
5699
|
+
let warnedDocumentPicker = false;
|
|
5700
|
+
function resolveDocumentPicker() {
|
|
5701
|
+
if (documentPickerCache === undefined) {
|
|
5702
|
+
try {
|
|
5703
|
+
documentPickerCache = require('expo-document-picker');
|
|
5704
|
+
}
|
|
5705
|
+
catch (_a) {
|
|
5706
|
+
documentPickerCache = null;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
const hasDocumentPicker = !!(documentPickerCache === null || documentPickerCache === void 0 ? void 0 : documentPickerCache.getDocumentAsync);
|
|
5710
|
+
if (!hasDocumentPicker && __DEV__ && !warnedDocumentPicker) {
|
|
5711
|
+
console.warn('expo-document-picker not installed; native file picker support is disabled.');
|
|
5712
|
+
warnedDocumentPicker = true;
|
|
5713
|
+
}
|
|
5714
|
+
return {
|
|
5715
|
+
DocumentPicker: documentPickerCache,
|
|
5716
|
+
hasDocumentPicker,
|
|
5717
|
+
};
|
|
5718
|
+
}
|
|
5719
|
+
|
|
5720
|
+
const { LinearGradient: OptionalLinearGradient$4, hasLinearGradient: hasLinearGradient$3 } = resolveLinearGradient();
|
|
5621
5721
|
const getButtonStyles = (theme, variant = 'filled', size = 'md', disabled = false, loading = false, height, radiusStyles, shadowStyles, customColor, isIconButton = false, fullWidth = false) => {
|
|
5622
5722
|
const sizeConfig = getComponentSize(size);
|
|
5623
5723
|
const horizontalSpacing = isIconButton ? 0 : sizeConfig.padding;
|
|
@@ -5741,6 +5841,7 @@ const Button = (allProps) => {
|
|
|
5741
5841
|
const { title, children, onPress, onPressIn, onPressOut, onHoverIn, onHoverOut, onLongPress, onLayout, variant = 'filled', size = 'md', disabled = false, loading = false, loadingTitle, colorVariant, textColor: textColorProp, icon, startIcon, endIcon, tooltip, tooltipPosition = 'top', radius, style, testID, accessibilityLabel: accessibilityLabelProp, accessibilityHint: accessibilityHintProp, } = otherProps;
|
|
5742
5842
|
// Theme
|
|
5743
5843
|
const theme = useTheme();
|
|
5844
|
+
const effectiveVariant = variant === 'gradient' && !hasLinearGradient$3 ? 'filled' : variant;
|
|
5744
5845
|
// Accessibility hooks
|
|
5745
5846
|
const { getDuration } = useReducedMotion$1();
|
|
5746
5847
|
const { announce } = useAnnouncer();
|
|
@@ -5804,7 +5905,7 @@ const Button = (allProps) => {
|
|
|
5804
5905
|
const height = getHeight(size);
|
|
5805
5906
|
const radiusStyles = createRadiusStyles(radius, height, 'button');
|
|
5806
5907
|
// Handle shadow prop - use default 'sm' for primary/filled/secondary/gradient variants if no shadow specified
|
|
5807
|
-
const effectiveShadow = (_a = shadowProps.shadow) !== null && _a !== void 0 ? _a : ((
|
|
5908
|
+
const effectiveShadow = (_a = shadowProps.shadow) !== null && _a !== void 0 ? _a : ((effectiveVariant === 'filled' || effectiveVariant === 'secondary' || effectiveVariant === 'gradient') ? 'sm' : 'none');
|
|
5808
5909
|
const shadowStyles = getShadowStyles({ shadow: effectiveShadow }, theme, 'button');
|
|
5809
5910
|
const spacingStyles = getSpacingStyles(spacingProps);
|
|
5810
5911
|
const baseLayoutStyles = getLayoutStyles(layoutProps);
|
|
@@ -5839,7 +5940,7 @@ const Button = (allProps) => {
|
|
|
5839
5940
|
return token; // raw css color
|
|
5840
5941
|
};
|
|
5841
5942
|
const resolvedCustomColor = resolveTokenColor(colorVariant);
|
|
5842
|
-
const buttonStyles = getButtonStyles(theme,
|
|
5943
|
+
const buttonStyles = getButtonStyles(theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, resolvedCustomColor, isIconButton, layoutProps.fullWidth || false);
|
|
5843
5944
|
// derive contrasted text color if filled/filled background
|
|
5844
5945
|
const pickContrast = (bg) => {
|
|
5845
5946
|
if (!bg)
|
|
@@ -5858,12 +5959,12 @@ const Button = (allProps) => {
|
|
|
5858
5959
|
if (textColorProp)
|
|
5859
5960
|
return resolveTokenColor(textColorProp) || textColorProp;
|
|
5860
5961
|
if (resolvedCustomColor) {
|
|
5861
|
-
if (
|
|
5962
|
+
if (effectiveVariant === 'filled' || effectiveVariant === 'gradient')
|
|
5862
5963
|
return pickContrast(resolvedCustomColor);
|
|
5863
|
-
if (
|
|
5964
|
+
if (effectiveVariant === 'outline' || effectiveVariant === 'ghost' || effectiveVariant === 'none' || effectiveVariant === 'secondary')
|
|
5864
5965
|
return resolvedCustomColor;
|
|
5865
5966
|
}
|
|
5866
|
-
switch (
|
|
5967
|
+
switch (effectiveVariant) {
|
|
5867
5968
|
case 'filled': return '#FFFFFF';
|
|
5868
5969
|
case 'gradient': return '#FFFFFF';
|
|
5869
5970
|
case 'secondary': return theme.colors.gray[7];
|
|
@@ -5873,7 +5974,7 @@ const Button = (allProps) => {
|
|
|
5873
5974
|
case 'none': return 'currentColor';
|
|
5874
5975
|
default: return '#FFFFFF';
|
|
5875
5976
|
}
|
|
5876
|
-
}, [textColorProp, resolvedCustomColor,
|
|
5977
|
+
}, [textColorProp, resolvedCustomColor, effectiveVariant, theme.colors.gray, theme.colors.primary]);
|
|
5877
5978
|
// Memoize text props
|
|
5878
5979
|
const textProps = React.useMemo(() => ({
|
|
5879
5980
|
size,
|
|
@@ -5889,11 +5990,11 @@ const Button = (allProps) => {
|
|
|
5889
5990
|
// Memoize loader color calculation
|
|
5890
5991
|
const loaderColor = React.useMemo(() => {
|
|
5891
5992
|
if (resolvedCustomColor) {
|
|
5892
|
-
if (
|
|
5993
|
+
if (effectiveVariant === 'filled')
|
|
5893
5994
|
return pickContrast(resolvedCustomColor);
|
|
5894
5995
|
return resolvedCustomColor;
|
|
5895
5996
|
}
|
|
5896
|
-
switch (
|
|
5997
|
+
switch (effectiveVariant) {
|
|
5897
5998
|
case 'filled': return '#FFFFFF';
|
|
5898
5999
|
case 'secondary': return theme.colors.gray[7];
|
|
5899
6000
|
case 'outline': return theme.colors.primary[5];
|
|
@@ -5903,7 +6004,7 @@ const Button = (allProps) => {
|
|
|
5903
6004
|
case 'none': return 'currentColor';
|
|
5904
6005
|
default: return '#FFFFFF';
|
|
5905
6006
|
}
|
|
5906
|
-
}, [resolvedCustomColor,
|
|
6007
|
+
}, [resolvedCustomColor, effectiveVariant, theme.colors.gray, theme.colors.primary]);
|
|
5907
6008
|
// Helper function to inject color into icon components
|
|
5908
6009
|
const renderIconWithColor = (iconElement) => {
|
|
5909
6010
|
if (!iconElement)
|
|
@@ -6004,14 +6105,14 @@ const Button = (allProps) => {
|
|
|
6004
6105
|
},
|
|
6005
6106
|
// subtle visual feedback beyond scale on supported platforms
|
|
6006
6107
|
pressed && !isInteractionDisabled ? {
|
|
6007
|
-
opacity:
|
|
6108
|
+
opacity: effectiveVariant === 'ghost' || effectiveVariant === 'none' ? 0.6 : 0.9,
|
|
6008
6109
|
...(reactNative.Platform.OS !== 'web' ? { transform: [{ translateY: 1 }] } : {})
|
|
6009
6110
|
} : null,
|
|
6010
6111
|
style,
|
|
6011
6112
|
{ minWidth: calculatedMinWidth }
|
|
6012
|
-
], onPress: handleInternalPress, onLayout: onLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && jsxRuntime.jsx(
|
|
6013
|
-
?
|
|
6014
|
-
: [
|
|
6113
|
+
], onPress: handleInternalPress, onLayout: onLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && hasLinearGradient$3 && (jsxRuntime.jsx(OptionalLinearGradient$4, { colors: resolvedCustomColor
|
|
6114
|
+
? [resolvedCustomColor, theme.colors.primary[7]]
|
|
6115
|
+
: [theme.colors.primary[5], theme.colors.primary[7]], style: { position: 'absolute', zIndex: -1, top: 0, left: 0, right: 0, bottom: 0, borderRadius: radiusStyles.borderRadius }, start: { x: 0, y: 0 }, end: { x: 1, y: 0 } })), loading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Loader, { size: size, color: getLoaderColor(), style: !isIconButton ? { marginRight: iconSpacing } : undefined }), !isIconButton && renderButtonContent(displayContent)] })) : isIconButton ? (
|
|
6015
6116
|
// Icon-only button
|
|
6016
6117
|
renderIconWithColor(icon)) : (
|
|
6017
6118
|
// Regular button with text and optional side icons
|
|
@@ -6886,7 +6987,6 @@ const Flex = factory((props, ref) => {
|
|
|
6886
6987
|
* Automatically mirrors to row-reverse in RTL
|
|
6887
6988
|
*/
|
|
6888
6989
|
const Row$1 = React.forwardRef((props, ref) => {
|
|
6889
|
-
// @ts-expect-error - factory components handle refs differently
|
|
6890
6990
|
return jsxRuntime.jsx(Flex, { ...props, direction: "row", ref: ref });
|
|
6891
6991
|
});
|
|
6892
6992
|
Row$1.displayName = 'Row';
|
|
@@ -6895,7 +6995,6 @@ Row$1.displayName = 'Row';
|
|
|
6895
6995
|
* Not affected by RTL (columns are vertical)
|
|
6896
6996
|
*/
|
|
6897
6997
|
const Column$1 = React.forwardRef((props, ref) => {
|
|
6898
|
-
// @ts-expect-error - factory components handle refs differently
|
|
6899
6998
|
return jsxRuntime.jsx(Flex, { ...props, direction: "column", ref: ref });
|
|
6900
6999
|
});
|
|
6901
7000
|
Column$1.displayName = 'Column';
|
|
@@ -6952,6 +7051,280 @@ function useSimpleDialog() {
|
|
|
6952
7051
|
};
|
|
6953
7052
|
}
|
|
6954
7053
|
|
|
7054
|
+
const escapeRegExp$1 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
7055
|
+
const toHighlightArray = (value, trim) => {
|
|
7056
|
+
if (value === undefined || value === null) {
|
|
7057
|
+
return [];
|
|
7058
|
+
}
|
|
7059
|
+
const rawValues = Array.isArray(value) ? value : [value];
|
|
7060
|
+
return rawValues
|
|
7061
|
+
.filter((item) => item !== undefined && item !== null)
|
|
7062
|
+
.map((item) => String(item))
|
|
7063
|
+
.map((item) => (trim ? item.trim() : item))
|
|
7064
|
+
.filter((item) => item.length > 0);
|
|
7065
|
+
};
|
|
7066
|
+
const flattenStyleArray = (style) => {
|
|
7067
|
+
if (!Array.isArray(style)) {
|
|
7068
|
+
return style ? [style] : [];
|
|
7069
|
+
}
|
|
7070
|
+
return style.reduce((acc, item) => {
|
|
7071
|
+
acc.push(...flattenStyleArray(item));
|
|
7072
|
+
return acc;
|
|
7073
|
+
}, []);
|
|
7074
|
+
};
|
|
7075
|
+
const extractColorFromStyle = (style) => {
|
|
7076
|
+
for (const entry of flattenStyleArray(style)) {
|
|
7077
|
+
if (entry && typeof entry === 'object' && typeof entry.color === 'string') {
|
|
7078
|
+
return entry.color;
|
|
7079
|
+
}
|
|
7080
|
+
}
|
|
7081
|
+
return undefined;
|
|
7082
|
+
};
|
|
7083
|
+
const parseColor = (value) => {
|
|
7084
|
+
if (!value || typeof value !== 'string') {
|
|
7085
|
+
return undefined;
|
|
7086
|
+
}
|
|
7087
|
+
const trimmed = value.trim();
|
|
7088
|
+
if (trimmed.startsWith('#')) {
|
|
7089
|
+
let hex = trimmed.slice(1);
|
|
7090
|
+
if (hex.length === 3) {
|
|
7091
|
+
hex = hex.split('').map(char => char + char).join('');
|
|
7092
|
+
}
|
|
7093
|
+
if (hex.length === 6) {
|
|
7094
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
7095
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
7096
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
7097
|
+
if ([r, g, b].every(component => !Number.isNaN(component))) {
|
|
7098
|
+
return { r, g, b };
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
7101
|
+
if (hex.length === 8) {
|
|
7102
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
7103
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
7104
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
7105
|
+
if ([r, g, b].every(component => !Number.isNaN(component))) {
|
|
7106
|
+
return { r, g, b };
|
|
7107
|
+
}
|
|
7108
|
+
}
|
|
7109
|
+
}
|
|
7110
|
+
const rgbMatch = trimmed.match(/^rgba?\(([^)]+)\)$/i);
|
|
7111
|
+
if (rgbMatch) {
|
|
7112
|
+
const parts = rgbMatch[1].split(',').map(part => part.trim()).slice(0, 3);
|
|
7113
|
+
if (parts.length === 3) {
|
|
7114
|
+
const [r, g, b] = parts.map(part => parseFloat(part));
|
|
7115
|
+
if ([r, g, b].every(component => !Number.isNaN(component))) {
|
|
7116
|
+
return { r: Math.round(r), g: Math.round(g), b: Math.round(b) };
|
|
7117
|
+
}
|
|
7118
|
+
}
|
|
7119
|
+
}
|
|
7120
|
+
return undefined;
|
|
7121
|
+
};
|
|
7122
|
+
const getRelativeLuminance = ({ r, g, b }) => {
|
|
7123
|
+
const srgb = [r, g, b].map(channel => {
|
|
7124
|
+
const normalized = channel / 255;
|
|
7125
|
+
return normalized <= 0.03928 ? normalized / 12.92 : Math.pow((normalized + 0.055) / 1.055, 2.4);
|
|
7126
|
+
});
|
|
7127
|
+
return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
|
|
7128
|
+
};
|
|
7129
|
+
const mixRgb = (color, target, weight) => ({
|
|
7130
|
+
r: Math.round(color.r * (1 - weight) + target.r * weight),
|
|
7131
|
+
g: Math.round(color.g * (1 - weight) + target.g * weight),
|
|
7132
|
+
b: Math.round(color.b * (1 - weight) + target.b * weight),
|
|
7133
|
+
});
|
|
7134
|
+
const toRgba$1 = ({ r, g, b }, alpha) => `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
7135
|
+
const resolvePaletteShade = (palette, preferredIndex, fallbackIndex) => {
|
|
7136
|
+
if (!palette || palette.length === 0) {
|
|
7137
|
+
return undefined;
|
|
7138
|
+
}
|
|
7139
|
+
const safePreferred = palette[Math.min(Math.max(preferredIndex, 0), palette.length - 1)];
|
|
7140
|
+
if (safePreferred) {
|
|
7141
|
+
return safePreferred;
|
|
7142
|
+
}
|
|
7143
|
+
return palette[Math.min(Math.max(fallbackIndex, 0), palette.length - 1)];
|
|
7144
|
+
};
|
|
7145
|
+
const createAdaptiveBackground = (baseColor, isTextLight, colorScheme) => {
|
|
7146
|
+
const rgb = parseColor(baseColor);
|
|
7147
|
+
if (!rgb) {
|
|
7148
|
+
return baseColor;
|
|
7149
|
+
}
|
|
7150
|
+
const target = isTextLight ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 };
|
|
7151
|
+
const mixAmount = isTextLight ? (colorScheme === 'dark' ? 0.4 : 0.3) : (colorScheme === 'dark' ? 0.25 : 0.15);
|
|
7152
|
+
const alpha = isTextLight ? (colorScheme === 'dark' ? 0.7 : 0.8) : (colorScheme === 'dark' ? 0.55 : 0.88);
|
|
7153
|
+
const mixed = mixRgb(rgb, target, mixAmount);
|
|
7154
|
+
return toRgba$1(mixed, alpha);
|
|
7155
|
+
};
|
|
7156
|
+
const resolveHighlightBackground = (theme, highlightColor, isTextLight) => {
|
|
7157
|
+
var _a;
|
|
7158
|
+
const themeColors = theme.colors;
|
|
7159
|
+
const paletteFromProp = highlightColor ? themeColors[highlightColor] : undefined;
|
|
7160
|
+
const defaultPalette = theme.colors.highlight || theme.colors.amber || theme.colors.primary;
|
|
7161
|
+
const preferredPalette = paletteFromProp || defaultPalette;
|
|
7162
|
+
const highlightStateColor = (_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightBackground;
|
|
7163
|
+
let baseColor = paletteFromProp
|
|
7164
|
+
? resolvePaletteShade(paletteFromProp, isTextLight ? 8 : 2, isTextLight ? 7 : 3)
|
|
7165
|
+
: undefined;
|
|
7166
|
+
if (!baseColor && highlightColor && !paletteFromProp) {
|
|
7167
|
+
baseColor = highlightColor;
|
|
7168
|
+
}
|
|
7169
|
+
if (!baseColor && highlightStateColor) {
|
|
7170
|
+
baseColor = highlightStateColor;
|
|
7171
|
+
}
|
|
7172
|
+
if (!baseColor && preferredPalette) {
|
|
7173
|
+
baseColor = resolvePaletteShade(preferredPalette, isTextLight ? 8 : 2, isTextLight ? 7 : 3);
|
|
7174
|
+
}
|
|
7175
|
+
if (!baseColor) {
|
|
7176
|
+
baseColor = isTextLight ? '#92400E' : '#FDE68A';
|
|
7177
|
+
}
|
|
7178
|
+
return createAdaptiveBackground(baseColor, isTextLight, theme.colorScheme);
|
|
7179
|
+
};
|
|
7180
|
+
const createBaseHighlightStyle = (theme, backgroundColor, textColor, includeColor) => ({
|
|
7181
|
+
backgroundColor,
|
|
7182
|
+
...(includeColor ? { color: textColor } : {}),
|
|
7183
|
+
borderRadius: 4,
|
|
7184
|
+
paddingHorizontal: 4,
|
|
7185
|
+
paddingVertical: reactNative.Platform.OS === 'web' ? 0 : 2,
|
|
7186
|
+
});
|
|
7187
|
+
const Highlight = ({ children, highlight, highlightStyles, highlightColor, caseSensitive = false, trim = true, highlightProps, variant, ...rest }) => {
|
|
7188
|
+
var _a, _b;
|
|
7189
|
+
const theme = useTheme();
|
|
7190
|
+
const outerVariant = variant !== null && variant !== void 0 ? variant : 'span';
|
|
7191
|
+
const textContent = React.useMemo(() => {
|
|
7192
|
+
if (typeof children === 'string' || typeof children === 'number') {
|
|
7193
|
+
return String(children);
|
|
7194
|
+
}
|
|
7195
|
+
const parts = React.Children.toArray(children);
|
|
7196
|
+
if (parts.length === 0) {
|
|
7197
|
+
return '';
|
|
7198
|
+
}
|
|
7199
|
+
if (parts.every((part) => typeof part === 'string' || typeof part === 'number')) {
|
|
7200
|
+
return parts.map((part) => String(part)).join('');
|
|
7201
|
+
}
|
|
7202
|
+
return null;
|
|
7203
|
+
}, [children]);
|
|
7204
|
+
const highlightValues = React.useMemo(() => toHighlightArray(highlight, trim), [highlight, trim]);
|
|
7205
|
+
const highlightPropsValue = React.useMemo(() => highlightProps !== null && highlightProps !== void 0 ? highlightProps : {}, [highlightProps]);
|
|
7206
|
+
const highlightDerived = React.useMemo(() => {
|
|
7207
|
+
var _a, _b;
|
|
7208
|
+
const { style, as, variant: innerVariant, color: colorProp, ...restProps } = highlightPropsValue;
|
|
7209
|
+
return {
|
|
7210
|
+
style,
|
|
7211
|
+
color: colorProp,
|
|
7212
|
+
as: (_a = as) !== null && _a !== void 0 ? _a : (reactNative.Platform.OS === 'web' ? 'mark' : 'span'),
|
|
7213
|
+
variant: (_b = innerVariant) !== null && _b !== void 0 ? _b : 'span',
|
|
7214
|
+
rest: restProps,
|
|
7215
|
+
};
|
|
7216
|
+
}, [highlightPropsValue]);
|
|
7217
|
+
const outerColor = React.useMemo(() => {
|
|
7218
|
+
const restProps = rest;
|
|
7219
|
+
if ((restProps === null || restProps === void 0 ? void 0 : restProps.color) && typeof restProps.color === 'string') {
|
|
7220
|
+
return restProps.color;
|
|
7221
|
+
}
|
|
7222
|
+
const colorVariantKey = restProps === null || restProps === void 0 ? void 0 : restProps.colorVariant;
|
|
7223
|
+
if (typeof colorVariantKey === 'string') {
|
|
7224
|
+
const fromText = theme.text[colorVariantKey];
|
|
7225
|
+
if (fromText) {
|
|
7226
|
+
return fromText;
|
|
7227
|
+
}
|
|
7228
|
+
const palette = theme.colors[colorVariantKey];
|
|
7229
|
+
const paletteColor = resolvePaletteShade(palette, 6, palette ? palette.length - 1 : 6);
|
|
7230
|
+
if (paletteColor) {
|
|
7231
|
+
return paletteColor;
|
|
7232
|
+
}
|
|
7233
|
+
}
|
|
7234
|
+
return extractColorFromStyle(restProps === null || restProps === void 0 ? void 0 : restProps.style);
|
|
7235
|
+
}, [rest, theme]);
|
|
7236
|
+
const fallbackTextColor = (_b = (_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightText) !== null && _b !== void 0 ? _b : theme.text.primary;
|
|
7237
|
+
const { resolvedTextColor, isTextColorLight } = React.useMemo(() => {
|
|
7238
|
+
var _a, _b;
|
|
7239
|
+
const candidate = (_b = (_a = highlightDerived.color) !== null && _a !== void 0 ? _a : outerColor) !== null && _b !== void 0 ? _b : fallbackTextColor;
|
|
7240
|
+
const parsedCandidate = parseColor(candidate);
|
|
7241
|
+
if (parsedCandidate) {
|
|
7242
|
+
return {
|
|
7243
|
+
resolvedTextColor: candidate,
|
|
7244
|
+
isTextColorLight: getRelativeLuminance(parsedCandidate) > 0.6,
|
|
7245
|
+
};
|
|
7246
|
+
}
|
|
7247
|
+
const parsedFallback = parseColor(fallbackTextColor);
|
|
7248
|
+
if (parsedFallback) {
|
|
7249
|
+
return {
|
|
7250
|
+
resolvedTextColor: fallbackTextColor,
|
|
7251
|
+
isTextColorLight: getRelativeLuminance(parsedFallback) > 0.6,
|
|
7252
|
+
};
|
|
7253
|
+
}
|
|
7254
|
+
return {
|
|
7255
|
+
resolvedTextColor: candidate !== null && candidate !== void 0 ? candidate : fallbackTextColor,
|
|
7256
|
+
isTextColorLight: theme.colorScheme === 'dark',
|
|
7257
|
+
};
|
|
7258
|
+
}, [highlightDerived.color, outerColor, fallbackTextColor, theme.colorScheme]);
|
|
7259
|
+
const highlightBackground = React.useMemo(() => resolveHighlightBackground(theme, highlightColor, isTextColorLight), [theme, highlightColor, isTextColorLight]);
|
|
7260
|
+
const highlightColorProp = highlightDerived.color;
|
|
7261
|
+
const baseHighlightStyle = React.useMemo(() => createBaseHighlightStyle(theme, highlightBackground, resolvedTextColor, !highlightColorProp), [theme, highlightBackground, resolvedTextColor, highlightColorProp]);
|
|
7262
|
+
const overrideHighlightStyle = React.useMemo(() => (typeof highlightStyles === 'function' ? highlightStyles(theme) : highlightStyles), [highlightStyles, theme]);
|
|
7263
|
+
const highlightNodeStyle = React.useMemo(() => reactNative.StyleSheet.flatten([
|
|
7264
|
+
baseHighlightStyle,
|
|
7265
|
+
overrideHighlightStyle,
|
|
7266
|
+
highlightDerived.style,
|
|
7267
|
+
]), [baseHighlightStyle, overrideHighlightStyle, highlightDerived.style]);
|
|
7268
|
+
const highlightVariant = highlightDerived.variant;
|
|
7269
|
+
const highlightAs = highlightDerived.as;
|
|
7270
|
+
const highlightRest = highlightDerived.rest;
|
|
7271
|
+
const highlightRegex = React.useMemo(() => {
|
|
7272
|
+
if (textContent === null || highlightValues.length === 0) {
|
|
7273
|
+
return null;
|
|
7274
|
+
}
|
|
7275
|
+
const escaped = highlightValues
|
|
7276
|
+
.map((value) => escapeRegExp$1(value))
|
|
7277
|
+
.filter((value) => value.length > 0)
|
|
7278
|
+
.sort((a, b) => b.length - a.length);
|
|
7279
|
+
if (escaped.length === 0) {
|
|
7280
|
+
return null;
|
|
7281
|
+
}
|
|
7282
|
+
return new RegExp(`(${escaped.join('|')})`, caseSensitive ? 'g' : 'gi');
|
|
7283
|
+
}, [textContent, highlightValues, caseSensitive]);
|
|
7284
|
+
const highlightNormalizedSet = React.useMemo(() => {
|
|
7285
|
+
if (caseSensitive) {
|
|
7286
|
+
return new Set(highlightValues);
|
|
7287
|
+
}
|
|
7288
|
+
return new Set(highlightValues.map((value) => value.toLowerCase()));
|
|
7289
|
+
}, [highlightValues, caseSensitive]);
|
|
7290
|
+
const renderedChildren = React.useMemo(() => {
|
|
7291
|
+
if (textContent === null) {
|
|
7292
|
+
return children;
|
|
7293
|
+
}
|
|
7294
|
+
if (!highlightRegex || highlightValues.length === 0) {
|
|
7295
|
+
return textContent;
|
|
7296
|
+
}
|
|
7297
|
+
const segments = textContent.split(highlightRegex);
|
|
7298
|
+
if (segments.length <= 1) {
|
|
7299
|
+
return textContent;
|
|
7300
|
+
}
|
|
7301
|
+
return segments.map((segment, index) => {
|
|
7302
|
+
if (!segment) {
|
|
7303
|
+
return null;
|
|
7304
|
+
}
|
|
7305
|
+
const normalizedSegment = caseSensitive ? segment : segment.toLowerCase();
|
|
7306
|
+
if (highlightNormalizedSet.has(normalizedSegment)) {
|
|
7307
|
+
return (jsxRuntime.jsx(Text, { variant: highlightVariant, as: highlightAs, color: highlightColorProp, ...highlightRest, style: highlightNodeStyle, children: segment }, `highlight-${index}`));
|
|
7308
|
+
}
|
|
7309
|
+
return (jsxRuntime.jsx(React.Fragment, { children: segment }, `text-${index}`));
|
|
7310
|
+
}).filter((item) => item !== null);
|
|
7311
|
+
}, [
|
|
7312
|
+
children,
|
|
7313
|
+
textContent,
|
|
7314
|
+
highlightRegex,
|
|
7315
|
+
highlightValues,
|
|
7316
|
+
caseSensitive,
|
|
7317
|
+
highlightNormalizedSet,
|
|
7318
|
+
highlightVariant,
|
|
7319
|
+
highlightAs,
|
|
7320
|
+
highlightRest,
|
|
7321
|
+
highlightNodeStyle,
|
|
7322
|
+
highlightColorProp,
|
|
7323
|
+
]);
|
|
7324
|
+
return (jsxRuntime.jsx(Text, { variant: outerVariant, ...rest, children: renderedChildren }));
|
|
7325
|
+
};
|
|
7326
|
+
Highlight.displayName = 'Highlight';
|
|
7327
|
+
|
|
6955
7328
|
function isAction(item) {
|
|
6956
7329
|
return 'id' in item && 'label' in item;
|
|
6957
7330
|
}
|
|
@@ -7370,7 +7743,7 @@ function SpotlightActionsList({ children, scrollable = true, maxHeight, style, s
|
|
|
7370
7743
|
// Always use ScrollView for consistent behavior
|
|
7371
7744
|
return (jsxRuntime.jsx(reactNative.ScrollView, { ref: scrollRef, style: [containerStyle, { maxHeight: calculatedMaxHeight }], showsVerticalScrollIndicator: true, onScroll: onScrollChange ? (e) => onScrollChange(e.nativeEvent.contentOffset.y) : undefined, scrollEventThrottle: 16, contentContainerStyle: undefined, children: children }));
|
|
7372
7745
|
}
|
|
7373
|
-
function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled = false, selected = false, children, style, innerRef, }) {
|
|
7746
|
+
function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled = false, selected = false, children, style, innerRef, highlightQuery, }) {
|
|
7374
7747
|
const theme = useTheme();
|
|
7375
7748
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
7376
7749
|
// Truncate long descriptions for cleaner list appearance
|
|
@@ -7423,7 +7796,7 @@ function SpotlightAction({ label, description, leftSection, rightSection, onPres
|
|
|
7423
7796
|
!selected && pressed && pressedStyle,
|
|
7424
7797
|
!selected && !pressed && isHovered && hoverStyle,
|
|
7425
7798
|
style,
|
|
7426
|
-
], ...webHoverProps, children: jsxRuntime.jsxs(Block, { direction: "row", align: "center", style: styles$c.actionContent, children: [leftSection && (jsxRuntime.jsx(reactNative.View, { style: styles$c.actionLeftSection, children: leftSection })), jsxRuntime.jsxs(Block, { direction: "column", style: { flex: 1 }, children: [jsxRuntime.jsx(
|
|
7799
|
+
], ...webHoverProps, children: jsxRuntime.jsxs(Block, { direction: "row", align: "center", style: styles$c.actionContent, children: [leftSection && (jsxRuntime.jsx(reactNative.View, { style: styles$c.actionLeftSection, children: leftSection })), jsxRuntime.jsxs(Block, { direction: "column", style: { flex: 1 }, children: [jsxRuntime.jsx(Highlight, { highlight: highlightQuery, style: styles$c.actionLabel, highlightProps: { style: styles$c.actionLabel }, children: label }), truncatedDescription ? (jsxRuntime.jsx(Highlight, { highlight: highlightQuery, style: styles$c.actionDescription, highlightProps: { style: styles$c.actionDescription }, children: truncatedDescription })) : null, children] }), rightSection ? (jsxRuntime.jsx(reactNative.View, { style: styles$c.actionRightSection, children: rightSection })) : null] }) }));
|
|
7427
7800
|
}
|
|
7428
7801
|
function SpotlightActionsGroup({ label, children, style, }) {
|
|
7429
7802
|
const theme = useTheme();
|
|
@@ -7441,7 +7814,7 @@ function SpotlightEmpty({ children, style }) {
|
|
|
7441
7814
|
return (jsxRuntime.jsx(reactNative.View, { style: [styles$c.empty, style], children: jsxRuntime.jsx(Text, { size: "md", color: theme.text.secondary, style: styles$c.emptyText, children: children }) }));
|
|
7442
7815
|
}
|
|
7443
7816
|
// Main Spotlight component
|
|
7444
|
-
function Spotlight({ actions, nothingFound = 'Nothing found...', highlightQuery =
|
|
7817
|
+
function Spotlight({ actions, nothingFound = 'Nothing found...', highlightQuery = true, limit, scrollable = false, maxHeight, // Remove default - let it be calculated dynamically
|
|
7445
7818
|
shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', width = 600, height, }) {
|
|
7446
7819
|
const spotlightStore = useSpotlightStore();
|
|
7447
7820
|
// Set as default store if no custom store provided
|
|
@@ -7462,6 +7835,23 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
|
|
|
7462
7835
|
}, [shouldHandleToggleHotkey, currentStore]);
|
|
7463
7836
|
useGlobalHotkeys('spotlight-toggle', ['mod+k', handleToggleHotkey]);
|
|
7464
7837
|
const filteredActions = filterActions(actions, query, limit);
|
|
7838
|
+
const highlightValue = React.useMemo(() => {
|
|
7839
|
+
if (!highlightQuery) {
|
|
7840
|
+
return undefined;
|
|
7841
|
+
}
|
|
7842
|
+
if (highlightQuery !== true) {
|
|
7843
|
+
return highlightQuery;
|
|
7844
|
+
}
|
|
7845
|
+
const trimmed = query.trim();
|
|
7846
|
+
if (!trimmed) {
|
|
7847
|
+
return undefined;
|
|
7848
|
+
}
|
|
7849
|
+
const parts = trimmed.split(/\s+/).filter(Boolean);
|
|
7850
|
+
if (parts.length === 0) {
|
|
7851
|
+
return undefined;
|
|
7852
|
+
}
|
|
7853
|
+
return parts.length === 1 ? parts[0] : parts;
|
|
7854
|
+
}, [highlightQuery, query]);
|
|
7465
7855
|
// Flatten all actions for keyboard navigation
|
|
7466
7856
|
const flatActions = React.useMemo(() => {
|
|
7467
7857
|
const flat = [];
|
|
@@ -7589,7 +7979,7 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
|
|
|
7589
7979
|
if (isAction(item)) {
|
|
7590
7980
|
const isSelected = flatIndex === selectedIndex;
|
|
7591
7981
|
flatIndex++; // Increment after checking
|
|
7592
|
-
return (jsxRuntime.jsx(SpotlightAction, { label: item.label, description: item.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, leftSection: typeof item.icon === 'string' ? (jsxRuntime.jsx(Icon, { name: item.icon, size: "md", color: "pink" })) : (item.icon), onPress: () => {
|
|
7982
|
+
return (jsxRuntime.jsx(SpotlightAction, { label: item.label, description: item.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, highlightQuery: highlightValue, leftSection: typeof item.icon === 'string' ? (jsxRuntime.jsx(Icon, { name: item.icon, size: "md", color: "pink" })) : (item.icon), onPress: () => {
|
|
7593
7983
|
var _a;
|
|
7594
7984
|
(_a = item.onPress) === null || _a === void 0 ? void 0 : _a.call(item);
|
|
7595
7985
|
currentStore.close();
|
|
@@ -7599,7 +7989,7 @@ shortcut = ['cmd+k', 'ctrl+k'], searchProps = {}, store, variant = 'modal', widt
|
|
|
7599
7989
|
return (jsxRuntime.jsx(SpotlightActionsGroup, { label: item.group, children: item.actions.map((action) => {
|
|
7600
7990
|
const isSelected = flatIndex === selectedIndex;
|
|
7601
7991
|
flatIndex++; // Increment after checking
|
|
7602
|
-
return (jsxRuntime.jsx(SpotlightAction, { label: action.label, description: action.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, leftSection: typeof action.icon === 'string' ? (jsxRuntime.jsx(Icon, { name: action.icon, size: "md" })) : (action.icon), onPress: () => {
|
|
7992
|
+
return (jsxRuntime.jsx(SpotlightAction, { label: action.label, description: action.description, selected: isSelected, innerRef: (el) => { itemRefs.current[flatIndex - 1] = el; }, onLayout: (e) => { itemLayouts.current[flatIndex - 1] = { y: e.nativeEvent.layout.y, height: e.nativeEvent.layout.height }; setLayoutVersion(v => v + 1); }, highlightQuery: highlightValue, leftSection: typeof action.icon === 'string' ? (jsxRuntime.jsx(Icon, { name: action.icon, size: "md" })) : (action.icon), onPress: () => {
|
|
7603
7993
|
var _a;
|
|
7604
7994
|
(_a = action.onPress) === null || _a === void 0 ? void 0 : _a.call(action);
|
|
7605
7995
|
currentStore.close();
|
|
@@ -7749,27 +8139,27 @@ class DirectSpotlightStateManager {
|
|
|
7749
8139
|
return { ...this.state };
|
|
7750
8140
|
}
|
|
7751
8141
|
setState(updates) {
|
|
7752
|
-
console.log('[DirectSpotlightStateManager] Setting state:', updates, 'from:', this.state);
|
|
8142
|
+
// console.log('[DirectSpotlightStateManager] Setting state:', updates, 'from:', this.state);
|
|
7753
8143
|
this.state = { ...this.state, ...updates };
|
|
7754
8144
|
this.notifyListeners();
|
|
7755
8145
|
}
|
|
7756
8146
|
open(query) {
|
|
7757
|
-
console.log('[DirectSpotlightStateManager] Opening spotlight');
|
|
8147
|
+
// console.log('[DirectSpotlightStateManager] Opening spotlight');
|
|
7758
8148
|
this.setState({
|
|
7759
8149
|
opened: true,
|
|
7760
8150
|
...(query !== undefined && { query })
|
|
7761
8151
|
});
|
|
7762
8152
|
}
|
|
7763
8153
|
close() {
|
|
7764
|
-
console.log('[DirectSpotlightStateManager] Closing spotlight');
|
|
8154
|
+
// console.log('[DirectSpotlightStateManager] Closing spotlight');
|
|
7765
8155
|
this.setState({ opened: false, query: '', selectedIndex: -1 });
|
|
7766
8156
|
}
|
|
7767
8157
|
setQuery(query) {
|
|
7768
|
-
console.log('[DirectSpotlightStateManager] Setting query:', query);
|
|
8158
|
+
// console.log('[DirectSpotlightStateManager] Setting query:', query);
|
|
7769
8159
|
this.setState({ query });
|
|
7770
8160
|
}
|
|
7771
8161
|
toggle() {
|
|
7772
|
-
console.log('[DirectSpotlightStateManager] Toggling spotlight');
|
|
8162
|
+
// console.log('[DirectSpotlightStateManager] Toggling spotlight');
|
|
7773
8163
|
this.setState({ opened: !this.state.opened });
|
|
7774
8164
|
}
|
|
7775
8165
|
subscribe(listener) {
|
|
@@ -7795,7 +8185,7 @@ const directSpotlightStateManager = new DirectSpotlightStateManager();
|
|
|
7795
8185
|
function useDirectSpotlightState() {
|
|
7796
8186
|
const [state, setState] = React.useState(() => {
|
|
7797
8187
|
const globalState = directSpotlightStateManager.getState();
|
|
7798
|
-
console.log('[useDirectSpotlightState] Initializing with:', globalState);
|
|
8188
|
+
// console.log('[useDirectSpotlightState] Initializing with:', globalState);
|
|
7799
8189
|
return {
|
|
7800
8190
|
opened: globalState.opened,
|
|
7801
8191
|
query: globalState.query,
|
|
@@ -7803,9 +8193,9 @@ function useDirectSpotlightState() {
|
|
|
7803
8193
|
};
|
|
7804
8194
|
});
|
|
7805
8195
|
React.useEffect(() => {
|
|
7806
|
-
console.log('[useDirectSpotlightState] Setting up subscription');
|
|
8196
|
+
// console.log('[useDirectSpotlightState] Setting up subscription');
|
|
7807
8197
|
const unsubscribe = directSpotlightStateManager.subscribe((globalState) => {
|
|
7808
|
-
console.log('[useDirectSpotlightState] Global state changed:', globalState);
|
|
8198
|
+
// console.log('[useDirectSpotlightState] Global state changed:', globalState);
|
|
7809
8199
|
setState({
|
|
7810
8200
|
opened: globalState.opened,
|
|
7811
8201
|
query: globalState.query,
|
|
@@ -7814,14 +8204,14 @@ function useDirectSpotlightState() {
|
|
|
7814
8204
|
});
|
|
7815
8205
|
// Sync with current state
|
|
7816
8206
|
const currentState = directSpotlightStateManager.getState();
|
|
7817
|
-
console.log('[useDirectSpotlightState] Syncing with current state:', currentState);
|
|
8207
|
+
// console.log('[useDirectSpotlightState] Syncing with current state:', currentState);
|
|
7818
8208
|
setState({
|
|
7819
8209
|
opened: currentState.opened,
|
|
7820
8210
|
query: currentState.query,
|
|
7821
8211
|
selectedIndex: currentState.selectedIndex
|
|
7822
8212
|
});
|
|
7823
8213
|
return () => {
|
|
7824
|
-
console.log('[useDirectSpotlightState] Cleaning up subscription');
|
|
8214
|
+
// console.log('[useDirectSpotlightState] Cleaning up subscription');
|
|
7825
8215
|
unsubscribe();
|
|
7826
8216
|
};
|
|
7827
8217
|
}, []);
|
|
@@ -9346,10 +9736,9 @@ const useTitleRegistration = (options) => {
|
|
|
9346
9736
|
return { elementRef, id };
|
|
9347
9737
|
};
|
|
9348
9738
|
|
|
9349
|
-
|
|
9350
|
-
const LinearGradient = ({ children, style, ...props }) => (jsxRuntime.jsx(reactNative.View, { style: [style, { backgroundColor: props.colors[0] }], children: children }));
|
|
9739
|
+
const { LinearGradient: OptionalLinearGradient$3, hasLinearGradient: hasLinearGradient$2 } = resolveLinearGradient();
|
|
9351
9740
|
function Container(props) {
|
|
9352
|
-
var _a, _b;
|
|
9741
|
+
var _a, _b, _c, _d;
|
|
9353
9742
|
const theme = useTheme();
|
|
9354
9743
|
// Extract spacing props and other props
|
|
9355
9744
|
const { spacingProps, otherProps } = extractSpacingProps(props);
|
|
@@ -9380,7 +9769,10 @@ function Container(props) {
|
|
|
9380
9769
|
opacity: (_b = backgroundImage.overlay.opacity) !== null && _b !== void 0 ? _b : 0.3,
|
|
9381
9770
|
}
|
|
9382
9771
|
: {};
|
|
9383
|
-
return (jsxRuntime.jsxs(reactNative.ImageBackground, { source: { uri: backgroundImage.uri }, style: containerStyle, imageStyle: imageStyle, resizeMode: "cover", children: [backgroundImage.overlay && jsxRuntime.jsx(reactNative.View, { style: overlayStyle }), backgroundImage.gradient && (jsxRuntime.jsx(
|
|
9772
|
+
return (jsxRuntime.jsxs(reactNative.ImageBackground, { source: { uri: backgroundImage.uri }, style: containerStyle, imageStyle: imageStyle, resizeMode: "cover", children: [backgroundImage.overlay && jsxRuntime.jsx(reactNative.View, { style: overlayStyle }), backgroundImage.gradient && (hasLinearGradient$2 ? (jsxRuntime.jsx(OptionalLinearGradient$3, { colors: backgroundImage.gradient.colors, locations: backgroundImage.gradient.locations, start: backgroundImage.gradient.start || { x: 0, y: 0 }, end: backgroundImage.gradient.end || { x: 0, y: 1 }, style: reactNative.StyleSheet.absoluteFillObject })) : (jsxRuntime.jsx(reactNative.View, { style: [
|
|
9773
|
+
reactNative.StyleSheet.absoluteFillObject,
|
|
9774
|
+
{ backgroundColor: (_d = (_c = backgroundImage.gradient.colors) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : 'transparent' },
|
|
9775
|
+
] }))), children] }));
|
|
9384
9776
|
}
|
|
9385
9777
|
|
|
9386
9778
|
const Grid = factory((props, ref) => {
|
|
@@ -10512,6 +10904,7 @@ const Column = ({ direction = 'column', gap = 'sm', ...props }) => {
|
|
|
10512
10904
|
};
|
|
10513
10905
|
Row.displayName = 'Row';
|
|
10514
10906
|
|
|
10907
|
+
const { LinearGradient: OptionalLinearGradient$2, hasLinearGradient: hasLinearGradient$1 } = resolveLinearGradient();
|
|
10515
10908
|
/**
|
|
10516
10909
|
* GradientText Component
|
|
10517
10910
|
*
|
|
@@ -10701,6 +11094,9 @@ const GradientText = React.forwardRef(({ children, colors, locations, angle = 0,
|
|
|
10701
11094
|
return (jsxRuntime.jsx(Text, { ...textProps, children: children }));
|
|
10702
11095
|
}
|
|
10703
11096
|
// Web-specific gradient implementation with animation
|
|
11097
|
+
if (!hasLinearGradient$1) {
|
|
11098
|
+
return (jsxRuntime.jsx(reactNative.View, { ref: ref, testID: testID, style: styles$b.container, children: jsxRuntime.jsx(Text, { ...textProps, children: children }) }));
|
|
11099
|
+
}
|
|
10704
11100
|
if (isWeb) {
|
|
10705
11101
|
return (jsxRuntime.jsx(reactNative.View, { ref: containerRef, "data-testid": testID, style: { display: 'inline-block' }, children: jsxRuntime.jsx(Text, { ...textProps, "data-text-inner": "true", children: children }) }));
|
|
10706
11102
|
}
|
|
@@ -10714,7 +11110,7 @@ const GradientText = React.forwardRef(({ children, colors, locations, angle = 0,
|
|
|
10714
11110
|
const gradientLocations = colorLocations.length >= 2
|
|
10715
11111
|
? colorLocations
|
|
10716
11112
|
: [0, 1];
|
|
10717
|
-
return (jsxRuntime.jsx(MaskedView, { ref: ref, testID: testID, style: styles$b.container, maskElement: jsxRuntime.jsx(reactNative.View, { style: styles$b.maskContainer, children: jsxRuntime.jsx(Text, { ...textProps, style: [textProps.style, styles$b.maskText], children: children }) }), children: jsxRuntime.jsx(
|
|
11113
|
+
return (jsxRuntime.jsx(MaskedView, { ref: ref, testID: testID, style: styles$b.container, maskElement: jsxRuntime.jsx(reactNative.View, { style: styles$b.maskContainer, children: jsxRuntime.jsx(Text, { ...textProps, style: [textProps.style, styles$b.maskText], children: children }) }), children: jsxRuntime.jsx(OptionalLinearGradient$2, { colors: gradientColors, locations: gradientLocations, start: gradientStart, end: gradientEnd, style: styles$b.gradient, children: jsxRuntime.jsx(Text, { ...textProps, style: [textProps.style, styles$b.transparentText], children: children }) }) }));
|
|
10718
11114
|
});
|
|
10719
11115
|
GradientText.displayName = 'GradientText';
|
|
10720
11116
|
const styles$b = reactNative.StyleSheet.create({
|
|
@@ -10760,6 +11156,7 @@ const styles$a = reactNative.StyleSheet.create({
|
|
|
10760
11156
|
height: '100%',
|
|
10761
11157
|
},
|
|
10762
11158
|
});
|
|
11159
|
+
const { LinearGradient: OptionalLinearGradient$1} = resolveLinearGradient();
|
|
10763
11160
|
const stripColorFromStyle = (styleValue) => {
|
|
10764
11161
|
if (!styleValue) {
|
|
10765
11162
|
return styleValue;
|
|
@@ -10829,10 +11226,13 @@ function ShimmerText(props) {
|
|
|
10829
11226
|
const { spacingProps, otherProps } = extractSpacingProps(props);
|
|
10830
11227
|
const spacingStyles = getSpacingStyles(spacingProps);
|
|
10831
11228
|
const { children, text, color: baseColor = '#999999', colors, shimmerColor, duration = 1.8, delay = 0, repeatDelay = 0, repeat = true, once = false, direction = 'ltr', spread = 2, debug = false, onLayout: externalOnLayout, style, ...textProps } = otherProps;
|
|
11229
|
+
const isWeb = reactNative.Platform.OS === 'web';
|
|
11230
|
+
const gradientModuleAvailable = Boolean(OptionalLinearGradient$1);
|
|
10832
11231
|
const content = (_a = children !== null && children !== void 0 ? children : text) !== null && _a !== void 0 ? _a : null;
|
|
10833
11232
|
const normalizedSpread = Math.max(spread, MIN_SPREAD);
|
|
10834
11233
|
const shouldRepeat = repeat && !once;
|
|
10835
|
-
const
|
|
11234
|
+
const supportsShimmer = isWeb || gradientModuleAvailable;
|
|
11235
|
+
const shouldAnimate = supportsShimmer && (once || shouldRepeat);
|
|
10836
11236
|
const extraDistance = normalizedSpread - 1;
|
|
10837
11237
|
const minPosition = -extraDistance;
|
|
10838
11238
|
const maxPosition = 1 + extraDistance;
|
|
@@ -10843,7 +11243,6 @@ function ShimmerText(props) {
|
|
|
10843
11243
|
const debugFlag = Animated.useSharedValue(debug ? 1 : 0);
|
|
10844
11244
|
const startX = Animated.useSharedValue(0);
|
|
10845
11245
|
const endX = Animated.useSharedValue(0);
|
|
10846
|
-
const isWeb = reactNative.Platform.OS === 'web';
|
|
10847
11246
|
const [layout, setLayout] = React.useState({ width: 0, height: 0 });
|
|
10848
11247
|
const [gradientWidth, setGradientWidth] = React.useState(0);
|
|
10849
11248
|
const mountCountRef = React.useRef(0);
|
|
@@ -10876,7 +11275,7 @@ function ShimmerText(props) {
|
|
|
10876
11275
|
console.log(`[ShimmerText] ${message}`);
|
|
10877
11276
|
}, [debug]);
|
|
10878
11277
|
React.useEffect(() => {
|
|
10879
|
-
if (isWeb) {
|
|
11278
|
+
if (isWeb || !gradientModuleAvailable) {
|
|
10880
11279
|
return;
|
|
10881
11280
|
}
|
|
10882
11281
|
mountCountRef.current += 1;
|
|
@@ -10919,7 +11318,7 @@ function ShimmerText(props) {
|
|
|
10919
11318
|
logEvent('cleanup -> cancel animation');
|
|
10920
11319
|
Animated.cancelAnimation(progress);
|
|
10921
11320
|
};
|
|
10922
|
-
}, [delay, duration, repeat, once, repeatDelay, progress, logEvent, debugFlag, isWeb, shouldAnimate, shouldRepeat]);
|
|
11321
|
+
}, [delay, duration, repeat, once, repeatDelay, progress, logEvent, debugFlag, isWeb, shouldAnimate, shouldRepeat, gradientModuleAvailable]);
|
|
10923
11322
|
const handleLayout = React.useCallback((event) => {
|
|
10924
11323
|
const { width, height } = event.nativeEvent.layout;
|
|
10925
11324
|
setLayout((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));
|
|
@@ -11005,6 +11404,9 @@ function ShimmerText(props) {
|
|
|
11005
11404
|
};
|
|
11006
11405
|
}, [isWeb, shouldAnimate, shouldRepeat, duration, delay, repeatDelay, direction, initialWebPosition, finalWebPosition, maxPosition, positionRange, minPosition]);
|
|
11007
11406
|
const renderNative = () => {
|
|
11407
|
+
if (!gradientModuleAvailable || !OptionalLinearGradient$1) {
|
|
11408
|
+
return (jsxRuntime.jsx(Text, { ...textProps, color: baseColor, onLayout: externalOnLayout, style: style, children: content }));
|
|
11409
|
+
}
|
|
11008
11410
|
if (layout.width === 0 || layout.height === 0) {
|
|
11009
11411
|
return (jsxRuntime.jsx(Text, { ...textProps, color: baseColor, onLayout: handleLayout, style: style, children: content }));
|
|
11010
11412
|
}
|
|
@@ -11017,7 +11419,7 @@ function ShimmerText(props) {
|
|
|
11017
11419
|
height: layout.height,
|
|
11018
11420
|
},
|
|
11019
11421
|
gradientAnimatedStyle,
|
|
11020
|
-
], children: jsxRuntime.jsx(
|
|
11422
|
+
], children: jsxRuntime.jsx(OptionalLinearGradient$1, { colors: resolvedColors, locations: gradientLocations, start: { x: direction === 'rtl' ? 1 : 0, y: 0.5 }, end: { x: direction === 'rtl' ? 0 : 1, y: 0.5 }, style: styles$a.linearGradient }) }) }) })] }));
|
|
11021
11423
|
};
|
|
11022
11424
|
const renderWeb = () => {
|
|
11023
11425
|
var _a;
|
|
@@ -11138,6 +11540,7 @@ const Heading4 = (props) => jsxRuntime.jsx(Title, { order: 4, ...props });
|
|
|
11138
11540
|
const Heading5 = (props) => jsxRuntime.jsx(Title, { order: 5, ...props });
|
|
11139
11541
|
const Heading6 = (props) => jsxRuntime.jsx(Title, { order: 6, ...props });
|
|
11140
11542
|
|
|
11543
|
+
const { LinearGradient: OptionalLinearGradient, hasLinearGradient } = resolveLinearGradient();
|
|
11141
11544
|
const getIconButtonStyles = (theme, variant = 'filled', size = 'md', disabled = false, loading = false, height, radiusStyles, shadowStyles, customColor) => {
|
|
11142
11545
|
const baseStyles = {
|
|
11143
11546
|
flexDirection: 'row',
|
|
@@ -11302,6 +11705,7 @@ const IconButton = (allProps) => {
|
|
|
11302
11705
|
...restProps } = otherProps;
|
|
11303
11706
|
const theme = useTheme();
|
|
11304
11707
|
const { impactPressIn, impactPressOut } = useHaptics$1();
|
|
11708
|
+
const effectiveVariant = variant === 'gradient' && !hasLinearGradient ? 'filled' : variant;
|
|
11305
11709
|
// Animation values
|
|
11306
11710
|
const scaleAnim = React.useRef(new reactNative.Animated.Value(1)).current;
|
|
11307
11711
|
const [isPressed, setIsPressed] = React.useState(false);
|
|
@@ -11312,9 +11716,9 @@ const IconButton = (allProps) => {
|
|
|
11312
11716
|
// Create shadow styles
|
|
11313
11717
|
const shadowStyles = getShadowStyles(shadowProps, theme);
|
|
11314
11718
|
// Get button styles
|
|
11315
|
-
const buttonStyles = React.useMemo(() => getIconButtonStyles(theme,
|
|
11719
|
+
const buttonStyles = React.useMemo(() => getIconButtonStyles(theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant), [theme, effectiveVariant, size, disabled, loading, height, radiusStyles, shadowStyles, colorVariant]);
|
|
11316
11720
|
// Get icon color
|
|
11317
|
-
const resolvedIconColor = React.useMemo(() => getIconColor(theme,
|
|
11721
|
+
const resolvedIconColor = React.useMemo(() => getIconColor(theme, effectiveVariant, colorVariant, iconColor), [theme, effectiveVariant, colorVariant, iconColor]);
|
|
11318
11722
|
// Get icon size
|
|
11319
11723
|
const resolvedIconSize = iconSize || getDefaultIconSize(size);
|
|
11320
11724
|
const handlePressIn = () => {
|
|
@@ -11355,7 +11759,7 @@ const IconButton = (allProps) => {
|
|
|
11355
11759
|
getLayoutStyles(layoutProps),
|
|
11356
11760
|
{ transform: [{ scale: scaleAnim }] },
|
|
11357
11761
|
style,
|
|
11358
|
-
], children: variant === 'gradient' ? (jsxRuntime.jsx(
|
|
11762
|
+
], children: variant === 'gradient' && hasLinearGradient ? (jsxRuntime.jsx(OptionalLinearGradient, { colors: [theme.colors.primary[4], theme.colors.primary[6]], start: { x: 0, y: 0 }, end: { x: 1, y: 1 }, style: [buttonStyles, { borderWidth: 0 }], children: jsxRuntime.jsx(reactNative.Pressable, { onPress: handlePress, onPressIn: handlePressIn, onPressOut: handlePressOut, onLayout: onLayout, disabled: disabled || loading, style: {
|
|
11359
11763
|
width: '100%',
|
|
11360
11764
|
height: '100%',
|
|
11361
11765
|
alignItems: 'center',
|
|
@@ -11366,9 +11770,9 @@ const IconButton = (allProps) => {
|
|
|
11366
11770
|
}, testID: testID, ...restProps, children: renderContent() }) })) : (jsxRuntime.jsx(reactNative.Pressable, { onPress: handlePress, onPressIn: handlePressIn, onPressOut: handlePressOut, onLayout: onLayout, disabled: disabled || loading, style: [
|
|
11367
11771
|
buttonStyles,
|
|
11368
11772
|
isPressed && !disabled && !loading && {
|
|
11369
|
-
backgroundColor:
|
|
11773
|
+
backgroundColor: effectiveVariant === 'filled'
|
|
11370
11774
|
? theme.colors.primary[6]
|
|
11371
|
-
:
|
|
11775
|
+
: effectiveVariant === 'secondary'
|
|
11372
11776
|
? theme.colors.gray[2]
|
|
11373
11777
|
: buttonStyles.backgroundColor,
|
|
11374
11778
|
},
|
|
@@ -11414,7 +11818,8 @@ const getSeverityColor$1 = (severity) => {
|
|
|
11414
11818
|
}
|
|
11415
11819
|
};
|
|
11416
11820
|
function ToastBase(props, ref) {
|
|
11417
|
-
|
|
11821
|
+
var _a, _b, _c;
|
|
11822
|
+
const { variant = 'filled', color = 'gray', sev, title, children, icon, withCloseButton = true, loading = false, closeButtonLabel = 'Close notification', onClose, visible = false, animationDuration = 300, autoHide = 4000, position = 'top', style, testID, radius, actions, dismissOnTap = false, maxWidth, persistent = false, animationConfig, swipeConfig, onSwipeDismiss, keepMounted = true, ...rest } = props;
|
|
11418
11823
|
const { spacingProps, otherProps } = extractSpacingProps(rest);
|
|
11419
11824
|
const spacingStyles = getSpacingStyles(spacingProps);
|
|
11420
11825
|
const theme = useTheme();
|
|
@@ -11477,7 +11882,13 @@ function ToastBase(props, ref) {
|
|
|
11477
11882
|
return { finalColor, isThemeColor, colorConfig };
|
|
11478
11883
|
}, [sev, color, theme.colors]);
|
|
11479
11884
|
const { finalColor, isThemeColor, colorConfig } = memoizedColors;
|
|
11480
|
-
const
|
|
11885
|
+
const shouldUnmountOnHide = !keepMounted;
|
|
11886
|
+
const [shouldRender, setShouldRender] = React.useState(shouldUnmountOnHide ? visible : true);
|
|
11887
|
+
React.useEffect(() => {
|
|
11888
|
+
if (!shouldUnmountOnHide) {
|
|
11889
|
+
setShouldRender(true);
|
|
11890
|
+
}
|
|
11891
|
+
}, [shouldUnmountOnHide]);
|
|
11481
11892
|
const transformProperty = React.useMemo(() => (position === 'left' || position === 'right' ? 'translateX' : 'translateY'), [position]);
|
|
11482
11893
|
// Animation styles
|
|
11483
11894
|
const animatedStyle = Animated.useAnimatedStyle(() => {
|
|
@@ -11506,7 +11917,10 @@ function ToastBase(props, ref) {
|
|
|
11506
11917
|
opacity: fadeAnimation.value,
|
|
11507
11918
|
};
|
|
11508
11919
|
}, [transformProperty, screenWidth, finalSwipeConfig, finalAnimationConfig]);
|
|
11509
|
-
const
|
|
11920
|
+
const haptics = useHaptics$1();
|
|
11921
|
+
const notifySuccess = (_a = haptics.notifySuccess) !== null && _a !== void 0 ? _a : (() => { });
|
|
11922
|
+
const notifyWarning = (_b = haptics.notifyWarning) !== null && _b !== void 0 ? _b : (() => { });
|
|
11923
|
+
const notifyError = (_c = haptics.notifyError) !== null && _c !== void 0 ? _c : (() => { });
|
|
11510
11924
|
// Improved haptic feedback with error handling
|
|
11511
11925
|
const triggerHapticFeedback = React.useCallback((severity) => {
|
|
11512
11926
|
try {
|
|
@@ -11593,7 +12007,9 @@ function ToastBase(props, ref) {
|
|
|
11593
12007
|
}, []);
|
|
11594
12008
|
React.useEffect(() => {
|
|
11595
12009
|
if (visible) {
|
|
11596
|
-
|
|
12010
|
+
if (shouldUnmountOnHide) {
|
|
12011
|
+
setShouldRender(true);
|
|
12012
|
+
}
|
|
11597
12013
|
// Reset swipe positions
|
|
11598
12014
|
swipeX.value = 0;
|
|
11599
12015
|
swipeY.value = 0;
|
|
@@ -11638,7 +12054,7 @@ function ToastBase(props, ref) {
|
|
|
11638
12054
|
easing: Animated.Easing.in(Animated.Easing.back(1.1))
|
|
11639
12055
|
}, (finished) => {
|
|
11640
12056
|
'worklet';
|
|
11641
|
-
if (finished) {
|
|
12057
|
+
if (finished && shouldUnmountOnHide) {
|
|
11642
12058
|
Animated.runOnJS(handleShouldRenderUpdate)(false);
|
|
11643
12059
|
}
|
|
11644
12060
|
});
|
|
@@ -11652,7 +12068,7 @@ function ToastBase(props, ref) {
|
|
|
11652
12068
|
clearTimeout(autoHideTimeoutRef.current);
|
|
11653
12069
|
}
|
|
11654
12070
|
};
|
|
11655
|
-
}, [visible, finalAnimationConfig, autoHide, onClose, slideAnimation, fadeAnimation, swipeX, swipeY, position, persistent, triggerHapticFeedback, sev, getHiddenPosition, handleShouldRenderUpdate]);
|
|
12071
|
+
}, [visible, finalAnimationConfig, autoHide, onClose, slideAnimation, fadeAnimation, swipeX, swipeY, position, persistent, triggerHapticFeedback, sev, getHiddenPosition, handleShouldRenderUpdate, shouldUnmountOnHide]);
|
|
11656
12072
|
const getToastStyles = () => {
|
|
11657
12073
|
const baseStyles = {
|
|
11658
12074
|
...radiusStyles,
|
|
@@ -11777,7 +12193,7 @@ function ToastBase(props, ref) {
|
|
|
11777
12193
|
const toastStyles = getToastStyles();
|
|
11778
12194
|
const textColor = getTextColor();
|
|
11779
12195
|
const iconColor = getIconColor();
|
|
11780
|
-
if (!shouldRender) {
|
|
12196
|
+
if (shouldUnmountOnHide && !shouldRender) {
|
|
11781
12197
|
return null;
|
|
11782
12198
|
}
|
|
11783
12199
|
// Check if swipe is enabled and gesture handler is available
|
|
@@ -14686,7 +15102,7 @@ const createInputStyles = (theme, isRTL = false) => {
|
|
|
14686
15102
|
color: props.disabled ? theme.text.disabled : theme.text.primary,
|
|
14687
15103
|
fontSize: px(theme.fontSizes.sm),
|
|
14688
15104
|
fontWeight: '600',
|
|
14689
|
-
marginBottom:
|
|
15105
|
+
marginBottom: 0
|
|
14690
15106
|
},
|
|
14691
15107
|
leftSection: {
|
|
14692
15108
|
...(isRTL ? { paddingLeft: px(theme.spacing.xs) } : { paddingRight: px(theme.spacing.xs) })
|
|
@@ -14714,8 +15130,15 @@ const FieldHeader = ({ label, description, required, withAsterisk, disabled, err
|
|
|
14714
15130
|
const styles = getInputStyles({ size, disabled, error });
|
|
14715
15131
|
if (!label && !description)
|
|
14716
15132
|
return null;
|
|
14717
|
-
const
|
|
14718
|
-
|
|
15133
|
+
const hasDescription = Boolean(description);
|
|
15134
|
+
const resolvedMarginBottom = (() => {
|
|
15135
|
+
if (marginBottom !== undefined)
|
|
15136
|
+
return marginBottom;
|
|
15137
|
+
if (!hasDescription && !error)
|
|
15138
|
+
return 0;
|
|
15139
|
+
return 4;
|
|
15140
|
+
})();
|
|
15141
|
+
return (jsxRuntime.jsxs(reactNative.View, { style: { marginBottom: resolvedMarginBottom }, testID: testID, children: [label && (jsxRuntime.jsxs(reactNative.Text, { style: styles.label, children: [label, required && withAsterisk && (jsxRuntime.jsx(reactNative.Text, { style: styles.required, accessibilityLabel: "required", children: ' *' }))] })), description && (jsxRuntime.jsx(reactNative.Text, { style: { fontSize: 12, color: theme.text.muted }, children: description }))] }));
|
|
14719
15142
|
};
|
|
14720
15143
|
|
|
14721
15144
|
const TextInputBase = factory((props, ref) => {
|
|
@@ -17689,7 +18112,7 @@ const getCardStyles = (theme, variant = 'filled', padding, radiusStyles, shadowS
|
|
|
17689
18112
|
...(variant !== 'outline' && {
|
|
17690
18113
|
...DESIGN_TOKENS.shadow.sm && { boxShadow: DESIGN_TOKENS.shadow.sm },
|
|
17691
18114
|
elevation: 1,
|
|
17692
|
-
})
|
|
18115
|
+
}),
|
|
17693
18116
|
};
|
|
17694
18117
|
const variantStyles = {
|
|
17695
18118
|
outline: {
|
|
@@ -18605,11 +19028,7 @@ const Search = factory((props, ref) => {
|
|
|
18605
19028
|
fontSize: size === 'xs' ? 12 : size === 'sm' ? 14 : 16,
|
|
18606
19029
|
}, children: placeholder }), jsxRuntime.jsx(Space, { w: 64 }), rightComponent || finalRight] }));
|
|
18607
19030
|
}
|
|
18608
|
-
return jsxRuntime.jsx(Input
|
|
18609
|
-
// @ts-expect-error factory handles ref injection
|
|
18610
|
-
, {
|
|
18611
|
-
// @ts-expect-error factory handles ref injection
|
|
18612
|
-
ref: ref, type: "search", value: internal.value, onChangeText: handleChange, onEnter: handleSubmit, placeholder: placeholder, size: size, radius: radius, leftSection: left, rightSection: finalRight, accessibilityLabel: accessibilityLabel, style: style });
|
|
19031
|
+
return jsxRuntime.jsx(Input, { ref: ref, type: "search", value: internal.value, onChangeText: handleChange, onEnter: handleSubmit, placeholder: placeholder, size: size, radius: radius, leftSection: left, rightSection: finalRight, accessibilityLabel: accessibilityLabel, style: style });
|
|
18613
19032
|
});
|
|
18614
19033
|
Search.displayName = 'Search';
|
|
18615
19034
|
|
|
@@ -18713,71 +19132,217 @@ const SIZE_CONFIG = {
|
|
|
18713
19132
|
md: { fontSize: 'sm', padY: 8, padX: 12, gap: 10, radius: 8, minHeight: 38 },
|
|
18714
19133
|
lg: { fontSize: 'md', padY: 10, padX: 14, gap: 12, radius: 10, minHeight: 44 },
|
|
18715
19134
|
};
|
|
18716
|
-
const MenuItemButton = (allProps) => {
|
|
19135
|
+
const MenuItemButton = React.forwardRef((allProps, ref) => {
|
|
18717
19136
|
var _a;
|
|
18718
19137
|
const { spacingProps, otherProps } = extractSpacingProps(allProps);
|
|
18719
|
-
const { title, children, startIcon, endIcon, onPress, disabled = false, active = false, danger = false, fullWidth = true, size = 'sm', compact = false, rounded = false, style, onPressIn, onPressOut, onMouseDown, ...restProps } = otherProps;
|
|
19138
|
+
const { title, children, startIcon, endIcon, onPress, disabled = false, active = false, danger = false, fullWidth = true, size = 'sm', compact = false, rounded = false, style, onPressIn, onPressOut, onMouseDown, onMouseEnter, onMouseLeave, onHoverIn, onHoverOut, onFocus, onBlur, tone, hoverTone, activeTone, textColor: textColorOverride, hoverTextColor: hoverTextColorOverride, activeTextColor: activeTextColorOverride, testID, ...restProps } = otherProps;
|
|
18720
19139
|
const theme = useTheme();
|
|
18721
19140
|
const { isRTL } = useDirection();
|
|
18722
19141
|
const spacingStyles = getSpacingStyles(spacingProps);
|
|
18723
19142
|
const cfg = (_a = SIZE_CONFIG[size]) !== null && _a !== void 0 ? _a : SIZE_CONFIG.sm;
|
|
18724
19143
|
const content = children || title;
|
|
18725
|
-
const
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
|
|
18730
|
-
|
|
18731
|
-
|
|
18732
|
-
|
|
18733
|
-
|
|
18734
|
-
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
19144
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
19145
|
+
const [isPressed, setIsPressed] = React.useState(false);
|
|
19146
|
+
const resolveTone = React.useCallback((toneKey) => {
|
|
19147
|
+
if (danger)
|
|
19148
|
+
return 'danger';
|
|
19149
|
+
return toneKey !== null && toneKey !== void 0 ? toneKey : 'default';
|
|
19150
|
+
}, [danger]);
|
|
19151
|
+
const getPalette = React.useCallback((toneKey) => {
|
|
19152
|
+
var _a;
|
|
19153
|
+
const isDark = theme.colorScheme === 'dark';
|
|
19154
|
+
switch (toneKey) {
|
|
19155
|
+
case 'danger':
|
|
19156
|
+
return {
|
|
19157
|
+
text: theme.colors.error[6],
|
|
19158
|
+
bg: 'transparent',
|
|
19159
|
+
hoverBg: isDark ? theme.colors.error[3] : theme.colors.error[0],
|
|
19160
|
+
activeBg: isDark ? theme.colors.error[4] : theme.colors.error[1],
|
|
19161
|
+
activeText: theme.colors.error[6],
|
|
19162
|
+
};
|
|
19163
|
+
case 'success':
|
|
19164
|
+
return {
|
|
19165
|
+
text: isDark ? theme.colors.success[2] : theme.colors.success[6],
|
|
19166
|
+
bg: 'transparent',
|
|
19167
|
+
hoverBg: isDark ? theme.colors.success[4] : theme.colors.success[0],
|
|
19168
|
+
activeBg: isDark ? theme.colors.success[5] : theme.colors.success[1],
|
|
19169
|
+
activeText: isDark ? theme.colors.success[2] : theme.colors.success[6],
|
|
19170
|
+
};
|
|
19171
|
+
case 'warning':
|
|
19172
|
+
return {
|
|
19173
|
+
text: isDark ? theme.colors.warning[2] : theme.colors.warning[6],
|
|
19174
|
+
bg: 'transparent',
|
|
19175
|
+
hoverBg: isDark ? theme.colors.warning[4] : theme.colors.warning[0],
|
|
19176
|
+
activeBg: isDark ? theme.colors.warning[5] : theme.colors.warning[1],
|
|
19177
|
+
activeText: isDark ? theme.colors.warning[2] : theme.colors.warning[6],
|
|
19178
|
+
};
|
|
19179
|
+
default:
|
|
19180
|
+
return {
|
|
19181
|
+
text: theme.text.primary,
|
|
19182
|
+
bg: 'transparent',
|
|
19183
|
+
hoverBg: isDark ? theme.colors.gray[3] : theme.colors.gray[1],
|
|
19184
|
+
activeBg: isDark ? theme.colors.primary[4] : theme.colors.primary[0],
|
|
19185
|
+
activeText: isDark ? ((_a = theme.text.onPrimary) !== null && _a !== void 0 ? _a : theme.text.primary) : theme.colors.primary[6],
|
|
19186
|
+
};
|
|
18751
19187
|
}
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
const
|
|
18755
|
-
const
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
19188
|
+
}, [theme]);
|
|
19189
|
+
const baseTone = resolveTone(tone);
|
|
19190
|
+
const hoverToneResolved = resolveTone(hoverTone);
|
|
19191
|
+
const activeToneResolved = resolveTone(activeTone !== null && activeTone !== void 0 ? activeTone : tone);
|
|
19192
|
+
const basePalette = React.useMemo(() => getPalette(baseTone), [baseTone, getPalette]);
|
|
19193
|
+
const hoverPalette = React.useMemo(() => getPalette(hoverToneResolved), [hoverToneResolved, getPalette]);
|
|
19194
|
+
const activePalette = React.useMemo(() => getPalette(activeToneResolved), [activeToneResolved, getPalette]);
|
|
19195
|
+
const buttonBaseStyle = React.useMemo(() => ({
|
|
19196
|
+
flexDirection: isRTL ? 'row-reverse' : 'row',
|
|
19197
|
+
alignItems: 'center',
|
|
19198
|
+
minHeight: cfg.minHeight,
|
|
19199
|
+
paddingHorizontal: cfg.padX,
|
|
19200
|
+
paddingVertical: compact ? Math.max(2, cfg.padY - 4) : cfg.padY,
|
|
19201
|
+
width: fullWidth ? '100%' : undefined,
|
|
19202
|
+
borderRadius: rounded ? 999 : cfg.radius,
|
|
19203
|
+
opacity: disabled ? 0.45 : 1,
|
|
19204
|
+
gap: cfg.gap,
|
|
19205
|
+
backgroundColor: basePalette.bg,
|
|
19206
|
+
}), [isRTL, cfg, compact, fullWidth, rounded, disabled, basePalette.bg]);
|
|
19207
|
+
const handlePressIn = React.useCallback((event) => {
|
|
19208
|
+
if (!disabled)
|
|
19209
|
+
setIsPressed(true);
|
|
19210
|
+
onPressIn === null || onPressIn === void 0 ? void 0 : onPressIn(event);
|
|
19211
|
+
}, [disabled, onPressIn]);
|
|
19212
|
+
const handlePressOut = React.useCallback((event) => {
|
|
19213
|
+
if (!disabled)
|
|
19214
|
+
setIsPressed(false);
|
|
19215
|
+
onPressOut === null || onPressOut === void 0 ? void 0 : onPressOut(event);
|
|
19216
|
+
}, [disabled, onPressOut]);
|
|
19217
|
+
const handleHoverIn = React.useCallback((event) => {
|
|
19218
|
+
if (!disabled)
|
|
19219
|
+
setIsHovered(true);
|
|
19220
|
+
onHoverIn === null || onHoverIn === void 0 ? void 0 : onHoverIn(event);
|
|
19221
|
+
}, [disabled, onHoverIn]);
|
|
19222
|
+
const handleHoverOut = React.useCallback((event) => {
|
|
19223
|
+
if (!disabled)
|
|
19224
|
+
setIsHovered(false);
|
|
19225
|
+
onHoverOut === null || onHoverOut === void 0 ? void 0 : onHoverOut(event);
|
|
19226
|
+
}, [disabled, onHoverOut]);
|
|
19227
|
+
const handleMouseEnter = React.useCallback((event) => {
|
|
19228
|
+
if (!disabled)
|
|
19229
|
+
setIsHovered(true);
|
|
19230
|
+
onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(event);
|
|
19231
|
+
}, [disabled, onMouseEnter]);
|
|
19232
|
+
const handleMouseLeave = React.useCallback((event) => {
|
|
19233
|
+
if (!disabled)
|
|
19234
|
+
setIsHovered(false);
|
|
19235
|
+
onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(event);
|
|
19236
|
+
}, [disabled, onMouseLeave]);
|
|
19237
|
+
const isActive = active || isPressed;
|
|
19238
|
+
const baseText = textColorOverride !== null && textColorOverride !== void 0 ? textColorOverride : basePalette.text;
|
|
19239
|
+
const hoverText = hoverTextColorOverride !== null && hoverTextColorOverride !== void 0 ? hoverTextColorOverride : hoverPalette.text;
|
|
19240
|
+
const activeText = activeTextColorOverride !== null && activeTextColorOverride !== void 0 ? activeTextColorOverride : activePalette.activeText;
|
|
19241
|
+
const textColor = disabled
|
|
19242
|
+
? theme.text.disabled
|
|
19243
|
+
: isActive
|
|
19244
|
+
? activeText
|
|
19245
|
+
: isHovered
|
|
19246
|
+
? hoverText
|
|
19247
|
+
: baseText;
|
|
19248
|
+
return (jsxRuntime.jsx(reactNative.View, { ref: ref, style: [fullWidth && { width: '100%' }, spacingStyles], children: jsxRuntime.jsxs(reactNative.Pressable, { disabled: disabled, onPress: disabled ? undefined : onPress, onPressIn: disabled ? undefined : handlePressIn, onPressOut: disabled ? undefined : handlePressOut, ...(reactNative.Platform.OS === 'web' && onMouseDown ? { onMouseDown } : {}), ...(reactNative.Platform.OS === 'web' ? { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave } : {}), onHoverIn: handleHoverIn, onHoverOut: handleHoverOut, onFocus: onFocus, onBlur: onBlur, testID: testID, style: (pressableState) => {
|
|
19249
|
+
const { pressed } = pressableState;
|
|
19250
|
+
const hovered = pressableState.hovered || isHovered;
|
|
19251
|
+
const effectiveActive = isActive || pressed;
|
|
19252
|
+
return [
|
|
19253
|
+
buttonBaseStyle,
|
|
19254
|
+
!disabled && effectiveActive && { backgroundColor: activePalette.activeBg },
|
|
19255
|
+
!disabled && !effectiveActive && hovered && { backgroundColor: hoverPalette.hoverBg },
|
|
19256
|
+
style
|
|
19257
|
+
];
|
|
19258
|
+
}, ...restProps, children: [startIcon && (jsxRuntime.jsx(reactNative.View, { style: { opacity: disabled ? 0.6 : 1 }, children: startIcon })), content && (typeof content === 'string' ? (jsxRuntime.jsx(Text, { size: cfg.fontSize, weight: active ? '600' : '500', color: textColor, style: { flex: 1, overflow: 'hidden' }, children: content })) : content), endIcon && (jsxRuntime.jsx(reactNative.View, { style: isRTL ? { marginRight: cfg.gap, opacity: disabled ? 0.6 : 1 } : { marginLeft: cfg.gap, opacity: disabled ? 0.6 : 1 }, children: endIcon }))] }) }));
|
|
19259
|
+
});
|
|
18773
19260
|
MenuItemButton.displayName = 'MenuItemButton';
|
|
18774
19261
|
|
|
19262
|
+
function useMenuStyles() {
|
|
19263
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
19264
|
+
const theme = useTheme();
|
|
19265
|
+
const getPaletteColor = (palette, index) => {
|
|
19266
|
+
if (Array.isArray(palette)) {
|
|
19267
|
+
return palette[index];
|
|
19268
|
+
}
|
|
19269
|
+
return undefined;
|
|
19270
|
+
};
|
|
19271
|
+
const surfacePalette = (_a = theme.colors) === null || _a === void 0 ? void 0 : _a.surface;
|
|
19272
|
+
const grayPalette = (_b = theme.colors) === null || _b === void 0 ? void 0 : _b.gray;
|
|
19273
|
+
const lightSurfaceColor = (_h = (_g = (_e = (_c = getPaletteColor(surfacePalette, 4)) !== null && _c !== void 0 ? _c : (typeof ((_d = theme.backgrounds) === null || _d === void 0 ? void 0 : _d.surface) === 'string' ? theme.backgrounds.surface : undefined)) !== null && _e !== void 0 ? _e : (typeof ((_f = theme.backgrounds) === null || _f === void 0 ? void 0 : _f.base) === 'string' ? theme.backgrounds.base : undefined)) !== null && _g !== void 0 ? _g : getPaletteColor(grayPalette, 0)) !== null && _h !== void 0 ? _h : '#ffffff';
|
|
19274
|
+
const darkSurfaceColor = (_l = (_j = getPaletteColor(surfacePalette, 3)) !== null && _j !== void 0 ? _j : (typeof ((_k = theme.backgrounds) === null || _k === void 0 ? void 0 : _k.elevated) === 'string' ? theme.backgrounds.elevated : undefined)) !== null && _l !== void 0 ? _l : lightSurfaceColor;
|
|
19275
|
+
const fallbackRadius = (_q = (_o = (_m = theme.radii) === null || _m === void 0 ? void 0 : _m.md) !== null && _o !== void 0 ? _o : (_p = theme.radii) === null || _p === void 0 ? void 0 : _p.sm) !== null && _q !== void 0 ? _q : '8';
|
|
19276
|
+
const parsedRadius = typeof fallbackRadius === 'number'
|
|
19277
|
+
? fallbackRadius
|
|
19278
|
+
: parseInt(`${fallbackRadius}`, 10) || 8;
|
|
19279
|
+
const dropdown = {
|
|
19280
|
+
backgroundColor: theme.colorScheme === 'dark' ? darkSurfaceColor : lightSurfaceColor,
|
|
19281
|
+
borderRadius: parsedRadius,
|
|
19282
|
+
// borderWidth: 3, // Temporarily increased for debugging
|
|
19283
|
+
// borderColor: '#ff0000', // Temporarily red for debugging
|
|
19284
|
+
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
|
|
19285
|
+
elevation: 8,
|
|
19286
|
+
minWidth: 180,
|
|
19287
|
+
maxWidth: 320,
|
|
19288
|
+
overflow: 'hidden',
|
|
19289
|
+
};
|
|
19290
|
+
const item = {
|
|
19291
|
+
flexDirection: 'row',
|
|
19292
|
+
alignItems: 'center',
|
|
19293
|
+
paddingVertical: 8,
|
|
19294
|
+
paddingHorizontal: 12,
|
|
19295
|
+
minHeight: 36,
|
|
19296
|
+
};
|
|
19297
|
+
const itemPressed = {
|
|
19298
|
+
backgroundColor: theme.colors.gray[1],
|
|
19299
|
+
};
|
|
19300
|
+
const itemDisabled = {
|
|
19301
|
+
opacity: 0.5,
|
|
19302
|
+
};
|
|
19303
|
+
const itemDanger = {
|
|
19304
|
+
backgroundColor: theme.colors.error[0],
|
|
19305
|
+
};
|
|
19306
|
+
const itemDangerPressed = {
|
|
19307
|
+
backgroundColor: theme.colors.error[1],
|
|
19308
|
+
};
|
|
19309
|
+
const label = {
|
|
19310
|
+
paddingVertical: 6,
|
|
19311
|
+
paddingHorizontal: 12,
|
|
19312
|
+
};
|
|
19313
|
+
const divider = {
|
|
19314
|
+
height: 1,
|
|
19315
|
+
// backgroundColor: theme.colors.gray[2],
|
|
19316
|
+
// marginVertical: 4,
|
|
19317
|
+
};
|
|
19318
|
+
const leftSection = {
|
|
19319
|
+
marginRight: 8,
|
|
19320
|
+
};
|
|
19321
|
+
const rightSection = {
|
|
19322
|
+
marginLeft: 'auto',
|
|
19323
|
+
paddingLeft: 12,
|
|
19324
|
+
};
|
|
19325
|
+
return {
|
|
19326
|
+
dropdown,
|
|
19327
|
+
item,
|
|
19328
|
+
itemPressed,
|
|
19329
|
+
itemDisabled,
|
|
19330
|
+
itemDanger,
|
|
19331
|
+
itemDangerPressed,
|
|
19332
|
+
label,
|
|
19333
|
+
divider,
|
|
19334
|
+
leftSection,
|
|
19335
|
+
rightSection,
|
|
19336
|
+
};
|
|
19337
|
+
}
|
|
19338
|
+
|
|
18775
19339
|
const Select = factory((allProps, ref) => {
|
|
18776
19340
|
var _a;
|
|
18777
19341
|
const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(allProps);
|
|
18778
19342
|
const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
|
|
18779
19343
|
const { value: valueProp, defaultValue, onChange, options, placeholder = 'Select…', size = 'md', radius = 'md', disabled, label, helperText, description, error, renderOption, fullWidth, maxHeight = 260, closeOnSelect = true, clearable, clearButtonLabel, onClear } = otherProps;
|
|
18780
19344
|
const theme = useTheme();
|
|
19345
|
+
const menuStyles = useMenuStyles();
|
|
18781
19346
|
const { isRTL } = useDirection();
|
|
18782
19347
|
const [open, setOpen] = React.useState(false);
|
|
18783
19348
|
const [value, setValue] = React.useState((_a = valueProp !== null && valueProp !== void 0 ? valueProp : defaultValue) !== null && _a !== void 0 ? _a : null);
|
|
@@ -18785,6 +19350,8 @@ const Select = factory((allProps, ref) => {
|
|
|
18785
19350
|
const triggerRef = React.useRef(null);
|
|
18786
19351
|
const { openOverlay, closeOverlay, updateOverlay } = useOverlay();
|
|
18787
19352
|
const overlayIdRef = React.useRef(null);
|
|
19353
|
+
const menuSignatureRef = React.useRef('');
|
|
19354
|
+
const menuLayoutRef = React.useRef(null);
|
|
18788
19355
|
// keep controlled
|
|
18789
19356
|
React.useEffect(() => { if (valueProp !== undefined)
|
|
18790
19357
|
setValue(valueProp); }, [valueProp]);
|
|
@@ -18802,34 +19369,28 @@ const Select = factory((allProps, ref) => {
|
|
|
18802
19369
|
const selectedOption = options.find((o) => o.value === value) || null;
|
|
18803
19370
|
const showClearButton = !!(clearable && selectedOption && !disabled);
|
|
18804
19371
|
const clearLabel = clearButtonLabel || 'Clear selection';
|
|
19372
|
+
const optionRowHeight = React.useMemo(() => {
|
|
19373
|
+
switch (size) {
|
|
19374
|
+
case 'xs':
|
|
19375
|
+
return 30;
|
|
19376
|
+
case 'sm':
|
|
19377
|
+
return 34;
|
|
19378
|
+
case 'lg':
|
|
19379
|
+
return 44;
|
|
19380
|
+
case 'xl':
|
|
19381
|
+
return 48;
|
|
19382
|
+
default:
|
|
19383
|
+
return 38;
|
|
19384
|
+
}
|
|
19385
|
+
}, [size]);
|
|
18805
19386
|
const close = React.useCallback(() => {
|
|
18806
19387
|
setOpen(false);
|
|
18807
19388
|
if (overlayIdRef.current) {
|
|
18808
19389
|
closeOverlay(overlayIdRef.current);
|
|
18809
19390
|
overlayIdRef.current = null;
|
|
18810
19391
|
}
|
|
19392
|
+
menuLayoutRef.current = null;
|
|
18811
19393
|
}, [closeOverlay]);
|
|
18812
|
-
const computeAnchor = React.useCallback(() => {
|
|
18813
|
-
var _a;
|
|
18814
|
-
if (reactNative.Platform.OS !== 'web')
|
|
18815
|
-
return undefined;
|
|
18816
|
-
if (!triggerRef.current)
|
|
18817
|
-
return undefined;
|
|
18818
|
-
try {
|
|
18819
|
-
const node = triggerRef.current._node || triggerRef.current;
|
|
18820
|
-
const rect = (_a = node === null || node === void 0 ? void 0 : node.getBoundingClientRect) === null || _a === void 0 ? void 0 : _a.call(node);
|
|
18821
|
-
if (rect) {
|
|
18822
|
-
setTriggerWidth(rect.width);
|
|
18823
|
-
// In RTL, use rect.right instead of rect.left to align the dropdown
|
|
18824
|
-
const xPos = isRTL ? rect.right - rect.width : rect.left;
|
|
18825
|
-
return { x: xPos, y: rect.bottom + 4, width: rect.width, height: rect.height };
|
|
18826
|
-
}
|
|
18827
|
-
}
|
|
18828
|
-
catch (_e) {
|
|
18829
|
-
/* measurement failures are non-fatal on web */
|
|
18830
|
-
}
|
|
18831
|
-
return undefined;
|
|
18832
|
-
}, [isRTL]);
|
|
18833
19394
|
const measureTrigger = React.useCallback(() => {
|
|
18834
19395
|
var _a, _b;
|
|
18835
19396
|
if (reactNative.Platform.OS === 'web')
|
|
@@ -18845,29 +19406,167 @@ const Select = factory((allProps, ref) => {
|
|
|
18845
19406
|
/* native measurement failures can be ignored safely */
|
|
18846
19407
|
}
|
|
18847
19408
|
}, []);
|
|
18848
|
-
const
|
|
18849
|
-
|
|
19409
|
+
const resolveDropdownPosition = React.useCallback(async (preferredSize) => {
|
|
19410
|
+
if (reactNative.Platform.OS !== 'web')
|
|
19411
|
+
return null;
|
|
19412
|
+
if (!triggerRef.current)
|
|
19413
|
+
return null;
|
|
19414
|
+
try {
|
|
19415
|
+
const anchorRect = await measureElement(triggerRef);
|
|
19416
|
+
if (!anchorRect || anchorRect.height === 0) {
|
|
19417
|
+
return null;
|
|
19418
|
+
}
|
|
19419
|
+
const optionCount = options.length || 1;
|
|
19420
|
+
const estimatedHeight = Math.min(maxHeight, Math.max(optionRowHeight * optionCount, optionRowHeight));
|
|
19421
|
+
const estimatedWidth = (anchorRect.width && anchorRect.width > 0) ? anchorRect.width : (triggerWidth || 200);
|
|
19422
|
+
const overlayWidth = (preferredSize === null || preferredSize === void 0 ? void 0 : preferredSize.width) && preferredSize.width > 0
|
|
19423
|
+
? preferredSize.width
|
|
19424
|
+
: estimatedWidth;
|
|
19425
|
+
const overlayHeight = (preferredSize === null || preferredSize === void 0 ? void 0 : preferredSize.height) && preferredSize.height > 0
|
|
19426
|
+
? Math.min(preferredSize.height, maxHeight)
|
|
19427
|
+
: estimatedHeight;
|
|
19428
|
+
const overlaySize = {
|
|
19429
|
+
width: overlayWidth,
|
|
19430
|
+
height: overlayHeight,
|
|
19431
|
+
};
|
|
19432
|
+
const position = calculateOverlayPositionEnhanced(anchorRect, overlaySize, {
|
|
19433
|
+
placement: 'auto',
|
|
19434
|
+
offset: 6,
|
|
19435
|
+
strategy: 'fixed',
|
|
19436
|
+
flip: true,
|
|
19437
|
+
shift: true,
|
|
19438
|
+
boundary: 8,
|
|
19439
|
+
});
|
|
19440
|
+
const finalWidth = position.finalWidth || overlaySize.width;
|
|
19441
|
+
const finalHeight = position.finalHeight || overlaySize.height;
|
|
19442
|
+
setTriggerWidth(prev => {
|
|
19443
|
+
if (prev !== null && Math.abs(prev - finalWidth) < 1) {
|
|
19444
|
+
return prev;
|
|
19445
|
+
}
|
|
19446
|
+
return finalWidth;
|
|
19447
|
+
});
|
|
19448
|
+
return {
|
|
19449
|
+
position,
|
|
19450
|
+
overlaySize: {
|
|
19451
|
+
width: finalWidth,
|
|
19452
|
+
height: finalHeight,
|
|
19453
|
+
},
|
|
19454
|
+
};
|
|
19455
|
+
}
|
|
19456
|
+
catch (error) {
|
|
19457
|
+
console.warn('Select: failed to resolve dropdown position', error);
|
|
19458
|
+
return null;
|
|
19459
|
+
}
|
|
19460
|
+
}, [options, maxHeight, optionRowHeight, triggerWidth]);
|
|
19461
|
+
const handleMenuLayoutChange = React.useCallback(async (layout) => {
|
|
19462
|
+
const previous = menuLayoutRef.current;
|
|
19463
|
+
if (previous) {
|
|
19464
|
+
const widthDiff = Math.abs(previous.width - (layout.width || 0));
|
|
19465
|
+
const heightDiff = Math.abs(previous.height - (layout.height || 0));
|
|
19466
|
+
if (widthDiff < 1 && heightDiff < 1) {
|
|
19467
|
+
return;
|
|
19468
|
+
}
|
|
19469
|
+
}
|
|
19470
|
+
menuLayoutRef.current = layout;
|
|
19471
|
+
if (!open || reactNative.Platform.OS !== 'web' || !overlayIdRef.current)
|
|
19472
|
+
return;
|
|
19473
|
+
const resolved = await resolveDropdownPosition({ width: layout.width, height: layout.height });
|
|
19474
|
+
if (!resolved)
|
|
19475
|
+
return;
|
|
19476
|
+
const { position, overlaySize } = resolved;
|
|
19477
|
+
updateOverlay(overlayIdRef.current, {
|
|
19478
|
+
anchor: {
|
|
19479
|
+
x: position.x,
|
|
19480
|
+
y: position.y,
|
|
19481
|
+
width: overlaySize.width,
|
|
19482
|
+
height: overlaySize.height,
|
|
19483
|
+
},
|
|
19484
|
+
});
|
|
19485
|
+
}, [open, resolveDropdownPosition, updateOverlay]);
|
|
19486
|
+
const handleMenuLayoutEvent = React.useCallback((event) => {
|
|
19487
|
+
const { width, height } = event.nativeEvent.layout || {};
|
|
19488
|
+
if (width === undefined || height === undefined)
|
|
19489
|
+
return;
|
|
19490
|
+
handleMenuLayoutChange({ width, height });
|
|
19491
|
+
}, [handleMenuLayoutChange]);
|
|
19492
|
+
const handleSelect = React.useCallback((opt) => {
|
|
19493
|
+
if (opt.disabled)
|
|
19494
|
+
return;
|
|
19495
|
+
if (valueProp === undefined)
|
|
19496
|
+
setValue(opt.value);
|
|
19497
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(opt.value, opt);
|
|
19498
|
+
if (closeOnSelect)
|
|
19499
|
+
close();
|
|
19500
|
+
}, [onChange, valueProp, close, closeOnSelect]);
|
|
19501
|
+
const menu = React.useMemo(() => {
|
|
19502
|
+
const resolvedWidth = triggerWidth && triggerWidth > 0 ? triggerWidth : undefined;
|
|
19503
|
+
return (jsxRuntime.jsx(reactNative.View, { style: resolvedWidth ? { width: resolvedWidth, minWidth: resolvedWidth } : undefined, onLayout: reactNative.Platform.OS === 'web' ? handleMenuLayoutEvent : undefined, children: jsxRuntime.jsx(ListGroup, { variant: "default", size: "sm", style: {
|
|
19504
|
+
...menuStyles.dropdown,
|
|
19505
|
+
maxHeight,
|
|
19506
|
+
...(resolvedWidth ? { width: resolvedWidth, minWidth: resolvedWidth } : {}),
|
|
19507
|
+
}, children: jsxRuntime.jsx(reactNative.FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item }) => {
|
|
19508
|
+
const selected = item.value === value;
|
|
19509
|
+
if (renderOption) {
|
|
19510
|
+
return jsxRuntime.jsx(reactNative.View, { children: renderOption(item, false, selected) });
|
|
19511
|
+
}
|
|
19512
|
+
const successPalette = theme.colors.success || [];
|
|
19513
|
+
const highlightColor = theme.colorScheme === 'dark'
|
|
19514
|
+
? successPalette[4] || successPalette[5] || '#30D158'
|
|
19515
|
+
: successPalette[6] || successPalette[5] || '#2f9e44';
|
|
19516
|
+
const baseTextColor = item.disabled ? theme.text.disabled : theme.text.primary;
|
|
19517
|
+
const accentTextColor = item.disabled ? theme.text.disabled : highlightColor;
|
|
19518
|
+
return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: selected, tone: selected ? 'success' : 'default', hoverTone: "success", textColor: baseTextColor, hoverTextColor: accentTextColor, activeTextColor: accentTextColor, compact: true, rounded: false, style: { borderRadius: 0 }, children: item.label }));
|
|
19519
|
+
}, ItemSeparatorComponent: renderOption ? undefined : ListGroupDivider, style: { maxHeight }, bounces: false }) }) }));
|
|
19520
|
+
}, [menuStyles.dropdown, maxHeight, triggerWidth, options, value, renderOption, handleSelect, handleMenuLayoutEvent]);
|
|
19521
|
+
const getMenuContent = React.useCallback(() => menu, [menu]);
|
|
19522
|
+
const menuSignature = React.useMemo(() => {
|
|
19523
|
+
const optionSignature = options
|
|
19524
|
+
.map(opt => `${String(opt.value)}-${opt.label}-${opt.disabled ? '1' : '0'}`)
|
|
19525
|
+
.join('|');
|
|
19526
|
+
const valueSignature = typeof value === 'object' && value !== null
|
|
19527
|
+
? JSON.stringify(value)
|
|
19528
|
+
: String(value !== null && value !== void 0 ? value : '');
|
|
19529
|
+
const triggerSig = triggerWidth != null ? `tw:${Math.round(triggerWidth)}` : 'tw:auto';
|
|
19530
|
+
return `${optionSignature}|value:${valueSignature}|${triggerSig}|render:${renderOption ? 'custom' : 'default'}`;
|
|
19531
|
+
}, [options, value, triggerWidth, renderOption]);
|
|
19532
|
+
const openPortal = React.useCallback(async () => {
|
|
18850
19533
|
if (disabled || reactNative.Platform.OS !== 'web')
|
|
18851
19534
|
return;
|
|
18852
|
-
const
|
|
19535
|
+
const resolved = await resolveDropdownPosition();
|
|
19536
|
+
if (!resolved) {
|
|
19537
|
+
close();
|
|
19538
|
+
return;
|
|
19539
|
+
}
|
|
19540
|
+
const { position, overlaySize } = resolved;
|
|
18853
19541
|
const id = openOverlay({
|
|
18854
19542
|
content: getMenuContent(),
|
|
18855
|
-
anchor
|
|
18856
|
-
|
|
19543
|
+
anchor: {
|
|
19544
|
+
x: position.x,
|
|
19545
|
+
y: position.y,
|
|
19546
|
+
width: overlaySize.width,
|
|
19547
|
+
height: overlaySize.height,
|
|
19548
|
+
},
|
|
18857
19549
|
strategy: 'fixed',
|
|
18858
19550
|
zIndex: 1300,
|
|
18859
19551
|
closeOnClickOutside: true,
|
|
18860
|
-
|
|
19552
|
+
closeOnEscape: true,
|
|
19553
|
+
onClose: () => {
|
|
19554
|
+
setOpen(false);
|
|
19555
|
+
}
|
|
18861
19556
|
});
|
|
18862
19557
|
overlayIdRef.current = id;
|
|
18863
|
-
|
|
19558
|
+
menuSignatureRef.current = menuSignature;
|
|
19559
|
+
}, [disabled, resolveDropdownPosition, openOverlay, getMenuContent, close, menuSignature]);
|
|
18864
19560
|
const toggle = React.useCallback(() => {
|
|
18865
19561
|
if (disabled)
|
|
18866
19562
|
return;
|
|
18867
19563
|
setOpen(o => {
|
|
18868
19564
|
const next = !o;
|
|
18869
|
-
if (next && reactNative.Platform.OS === 'web')
|
|
18870
|
-
openPortal()
|
|
19565
|
+
if (next && reactNative.Platform.OS === 'web') {
|
|
19566
|
+
openPortal().catch(() => {
|
|
19567
|
+
close();
|
|
19568
|
+
});
|
|
19569
|
+
}
|
|
18871
19570
|
if (next && reactNative.Platform.OS !== 'web')
|
|
18872
19571
|
measureTrigger();
|
|
18873
19572
|
if (!next)
|
|
@@ -18876,21 +19575,37 @@ const Select = factory((allProps, ref) => {
|
|
|
18876
19575
|
});
|
|
18877
19576
|
}, [disabled, openPortal, close, measureTrigger]);
|
|
18878
19577
|
React.useLayoutEffect(() => {
|
|
18879
|
-
if (open
|
|
18880
|
-
const anchor = computeAnchor();
|
|
18881
|
-
if (anchor)
|
|
18882
|
-
updateOverlay(overlayIdRef.current, { anchor });
|
|
18883
|
-
}
|
|
18884
|
-
}, [open, value, options, computeAnchor, updateOverlay]);
|
|
18885
|
-
const handleSelect = React.useCallback((opt) => {
|
|
18886
|
-
if (opt.disabled)
|
|
19578
|
+
if (!open || reactNative.Platform.OS !== 'web' || !overlayIdRef.current)
|
|
18887
19579
|
return;
|
|
18888
|
-
|
|
18889
|
-
|
|
18890
|
-
|
|
18891
|
-
|
|
18892
|
-
|
|
18893
|
-
|
|
19580
|
+
let cancelled = false;
|
|
19581
|
+
(async () => {
|
|
19582
|
+
const resolved = await resolveDropdownPosition();
|
|
19583
|
+
if (!resolved || cancelled)
|
|
19584
|
+
return;
|
|
19585
|
+
const { position, overlaySize } = resolved;
|
|
19586
|
+
updateOverlay(overlayIdRef.current, {
|
|
19587
|
+
anchor: {
|
|
19588
|
+
x: position.x,
|
|
19589
|
+
y: position.y,
|
|
19590
|
+
width: overlaySize.width,
|
|
19591
|
+
height: overlaySize.height,
|
|
19592
|
+
},
|
|
19593
|
+
});
|
|
19594
|
+
})();
|
|
19595
|
+
return () => {
|
|
19596
|
+
cancelled = true;
|
|
19597
|
+
};
|
|
19598
|
+
}, [open, value, options, resolveDropdownPosition, updateOverlay]);
|
|
19599
|
+
React.useEffect(() => {
|
|
19600
|
+
if (!open || reactNative.Platform.OS !== 'web' || !overlayIdRef.current)
|
|
19601
|
+
return;
|
|
19602
|
+
if (menuSignatureRef.current === menuSignature)
|
|
19603
|
+
return;
|
|
19604
|
+
menuSignatureRef.current = menuSignature;
|
|
19605
|
+
updateOverlay(overlayIdRef.current, {
|
|
19606
|
+
content: getMenuContent(),
|
|
19607
|
+
});
|
|
19608
|
+
}, [open, menuSignature, getMenuContent, updateOverlay]);
|
|
18894
19609
|
const handleClear = React.useCallback((event) => {
|
|
18895
19610
|
var _a;
|
|
18896
19611
|
(_a = event === null || event === void 0 ? void 0 : event.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(event);
|
|
@@ -18903,22 +19618,6 @@ const Select = factory((allProps, ref) => {
|
|
|
18903
19618
|
onClear === null || onClear === void 0 ? void 0 : onClear();
|
|
18904
19619
|
close();
|
|
18905
19620
|
}, [disabled, valueProp, onChange, onClear, close]);
|
|
18906
|
-
const menu = (jsxRuntime.jsx(ListGroup, { variant: "default", size: "sm", style: {
|
|
18907
|
-
maxHeight,
|
|
18908
|
-
width: triggerWidth || undefined,
|
|
18909
|
-
minWidth: triggerWidth || undefined,
|
|
18910
|
-
}, children: jsxRuntime.jsx(reactNative.FlatList, { data: options, keyExtractor: o => String(o.value), renderItem: ({ item, index }) => {
|
|
18911
|
-
const selected = item.value === value;
|
|
18912
|
-
if (renderOption) {
|
|
18913
|
-
return jsxRuntime.jsx(reactNative.View, { children: renderOption(item, false, selected) });
|
|
18914
|
-
}
|
|
18915
|
-
const isLast = index === options.length - 1;
|
|
18916
|
-
return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelect(item), disabled: !!item.disabled, active: selected, compact: true, rounded: false, style: {
|
|
18917
|
-
borderRadius: 0,
|
|
18918
|
-
borderBottomWidth: isLast ? 0 : reactNative.StyleSheet.hairlineWidth,
|
|
18919
|
-
borderBottomColor: theme.colorScheme === 'dark' ? theme.colors.gray[4] : theme.colors.gray[2],
|
|
18920
|
-
}, children: item.label }));
|
|
18921
|
-
}, style: { maxHeight }, bounces: false }) }));
|
|
18922
19621
|
const fieldContent = selectedOption ? (jsxRuntime.jsx(reactNative.Text, { style: { color: disabled ? theme.text.disabled : theme.text.primary }, children: selectedOption.label })) : (jsxRuntime.jsx(reactNative.Text, { style: { color: disabled ? theme.text.disabled : theme.text.muted }, children: placeholder }));
|
|
18923
19622
|
return (jsxRuntime.jsxs(reactNative.View, { style: [defaultMinWidthStyle, fullWidthStyle, spacingStyles, layoutStyles,], children: [jsxRuntime.jsx(FieldHeader, { label: label, description: description, disabled: disabled, error: !!error, size: size }), jsxRuntime.jsxs(reactNative.Pressable, { ref: (node) => { triggerRef.current = node; if (typeof ref === 'function')
|
|
18924
19623
|
ref(node);
|
|
@@ -18936,36 +19635,6 @@ const Select = factory((allProps, ref) => {
|
|
|
18936
19635
|
});
|
|
18937
19636
|
|
|
18938
19637
|
const debounce = require('lodash.debounce');
|
|
18939
|
-
const HighlightedText = ({ text, query, highlight = false }) => {
|
|
18940
|
-
const theme = useTheme();
|
|
18941
|
-
const baseStyle = {
|
|
18942
|
-
color: theme.text.primary,
|
|
18943
|
-
fontSize: 15,
|
|
18944
|
-
fontFamily: theme.fontFamily,
|
|
18945
|
-
};
|
|
18946
|
-
if (!highlight || !query) {
|
|
18947
|
-
return (jsxRuntime.jsx(Text, { as: "span", variant: "span", style: baseStyle, children: text }));
|
|
18948
|
-
}
|
|
18949
|
-
const safeQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
18950
|
-
const regex = new RegExp(`(${safeQuery})`, 'gi');
|
|
18951
|
-
const parts = text.split(regex);
|
|
18952
|
-
const normalizedQuery = query.toLowerCase();
|
|
18953
|
-
return (jsxRuntime.jsx(Text, { as: "span", variant: "span", style: baseStyle, children: parts.map((part, index) => {
|
|
18954
|
-
var _a, _b, _c, _d;
|
|
18955
|
-
if (!part) {
|
|
18956
|
-
return null;
|
|
18957
|
-
}
|
|
18958
|
-
if (part.toLowerCase() === normalizedQuery) {
|
|
18959
|
-
return (jsxRuntime.jsx(Text, { as: "span", variant: "span", style: {
|
|
18960
|
-
backgroundColor: ((_a = theme.states) === null || _a === void 0 ? void 0 : _a.highlightBackground) || ((_b = theme.colors.highlight) === null || _b === void 0 ? void 0 : _b[2]) || theme.colors.primary[1],
|
|
18961
|
-
fontWeight: '600',
|
|
18962
|
-
color: ((_c = theme.states) === null || _c === void 0 ? void 0 : _c.highlightText) || ((_d = theme.colors.highlight) === null || _d === void 0 ? void 0 : _d[8]) || theme.colors.primary[7],
|
|
18963
|
-
fontFamily: theme.fontFamily,
|
|
18964
|
-
}, children: part }, `match-${index}`));
|
|
18965
|
-
}
|
|
18966
|
-
return (jsxRuntime.jsx(React.Fragment, { children: part }, `text-${index}`));
|
|
18967
|
-
}) }));
|
|
18968
|
-
};
|
|
18969
19638
|
const DEFAULT_FALLBACK_PLACEMENTS$1 = ['top-start', 'top-end', 'top', 'bottom-start', 'bottom-end', 'bottom'];
|
|
18970
19639
|
const defaultFilter = (item, query) => {
|
|
18971
19640
|
return item.label.toLowerCase().includes(query.toLowerCase()) ||
|
|
@@ -19322,6 +19991,7 @@ const AutoComplete = factory((props, ref) => {
|
|
|
19322
19991
|
}, [multiSelect, onSelect, useModal, displayProperty, onChangeText]);
|
|
19323
19992
|
// Default item renderer - use stable reference to prevent loops
|
|
19324
19993
|
const defaultRenderItem = React.useCallback((item, index, isSelected = false) => {
|
|
19994
|
+
const highlightQuery = highlightMatches ? currentQueryRef.current : undefined;
|
|
19325
19995
|
return (jsxRuntime.jsx(MenuItemButton, { onPress: () => handleSelectSuggestion(item), disabled: item.disabled, active: isSelected, compact: true, rounded: false, style: [styles.menuItemButton, suggestionItemStyle], ...(reactNative.Platform.OS === 'web' ? {
|
|
19326
19996
|
onMouseDown: (event) => {
|
|
19327
19997
|
if (event === null || event === void 0 ? void 0 : event.preventDefault) {
|
|
@@ -19331,7 +20001,7 @@ const AutoComplete = factory((props, ref) => {
|
|
|
19331
20001
|
event.stopPropagation();
|
|
19332
20002
|
}
|
|
19333
20003
|
},
|
|
19334
|
-
} : {}), children: jsxRuntime.jsx(
|
|
20004
|
+
} : {}), children: jsxRuntime.jsx(Highlight, { highlight: highlightQuery, children: item.label }) }));
|
|
19335
20005
|
}, [handleSelectSuggestion, highlightMatches, suggestionItemStyle]);
|
|
19336
20006
|
// Render item with enhanced parameters - use refs to prevent infinite loops
|
|
19337
20007
|
const renderSuggestionItem = React.useCallback((item, index) => {
|
|
@@ -19732,6 +20402,7 @@ const AutoComplete = factory((props, ref) => {
|
|
|
19732
20402
|
});
|
|
19733
20403
|
AutoComplete.displayName = 'AutoComplete';
|
|
19734
20404
|
|
|
20405
|
+
const { DocumentPicker: DocumentPickerModule, hasDocumentPicker } = resolveDocumentPicker();
|
|
19735
20406
|
const isDocumentPickerAsset = (file) => typeof (file === null || file === void 0 ? void 0 : file.uri) === 'string';
|
|
19736
20407
|
const getFileMetadata = (file) => {
|
|
19737
20408
|
var _a, _b, _c, _d, _e;
|
|
@@ -19854,7 +20525,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
|
|
|
19854
20525
|
});
|
|
19855
20526
|
}, [imagePreview]);
|
|
19856
20527
|
const processFiles = React.useCallback(async (fileList) => {
|
|
19857
|
-
var _a;
|
|
20528
|
+
var _a, _b, _c;
|
|
19858
20529
|
const filesToProcess = Array.isArray(fileList)
|
|
19859
20530
|
? [...fileList]
|
|
19860
20531
|
: Array.from(fileList !== null && fileList !== void 0 ? fileList : []);
|
|
@@ -19873,7 +20544,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
|
|
|
19873
20544
|
let previewUrl = await createFilePreview(file);
|
|
19874
20545
|
const metadata = getFileMetadata(file);
|
|
19875
20546
|
if (!previewUrl && reactNative.Platform.OS !== 'web' && isDocumentPickerAsset(file) && ((_a = metadata.type) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
|
|
19876
|
-
previewUrl = metadata.uri;
|
|
20547
|
+
previewUrl = (_b = metadata.uri) !== null && _b !== void 0 ? _b : undefined;
|
|
19877
20548
|
}
|
|
19878
20549
|
const fileInput = {
|
|
19879
20550
|
file,
|
|
@@ -19881,7 +20552,7 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
|
|
|
19881
20552
|
name: metadata.name,
|
|
19882
20553
|
size: metadata.size,
|
|
19883
20554
|
type: metadata.type,
|
|
19884
|
-
uri: metadata.uri,
|
|
20555
|
+
uri: (_c = metadata.uri) !== null && _c !== void 0 ? _c : undefined,
|
|
19885
20556
|
previewUrl,
|
|
19886
20557
|
status: validationError ? 'error' : 'pending',
|
|
19887
20558
|
error: validationError || undefined,
|
|
@@ -19937,9 +20608,14 @@ maxFiles = 10, onUpload, onProgress, onFilesChange, onFileRemove, PreviewCompone
|
|
|
19937
20608
|
}
|
|
19938
20609
|
return;
|
|
19939
20610
|
}
|
|
20611
|
+
const picker = DocumentPickerModule;
|
|
20612
|
+
if (!hasDocumentPicker || !(picker === null || picker === void 0 ? void 0 : picker.getDocumentAsync)) {
|
|
20613
|
+
console.warn('FileInput: expo-document-picker not installed, native file picker is disabled.');
|
|
20614
|
+
return;
|
|
20615
|
+
}
|
|
19940
20616
|
try {
|
|
19941
20617
|
const pickerTypes = accept.filter(type => !type.startsWith('.'));
|
|
19942
|
-
const result = await
|
|
20618
|
+
const result = await picker.getDocumentAsync({
|
|
19943
20619
|
multiple,
|
|
19944
20620
|
copyToCacheDirectory: true,
|
|
19945
20621
|
type: pickerTypes.length > 0 ? pickerTypes : undefined,
|
|
@@ -22154,14 +22830,12 @@ const TimePicker = ({ value, defaultValue, onChange, format = 24, withSeconds =
|
|
|
22154
22830
|
marginBottom: 12,
|
|
22155
22831
|
textAlign: 'center',
|
|
22156
22832
|
}, children: "Minute" }), jsxRuntime.jsx(reactNative.FlatList, { data: minuteOptions, keyExtractor: (item) => 'm-' + item, renderItem: ({ item }) => renderNumber(item, internal.minutes === item, () => commit({ minutes: item }, autoClose && !withSeconds)), style: [listCommon, { borderRadius: 12, backgroundColor: theme.colors.gray[1] }], contentContainerStyle: { paddingVertical: 8 }, showsVerticalScrollIndicator: false })] }), withSeconds && (jsxRuntime.jsxs(reactNative.View, { style: { width: columnWidth, alignItems: 'center' }, children: [jsxRuntime.jsx(Text, { size: "sm", weight: "medium", style: {
|
|
22157
|
-
color: theme.colors.gray[6],
|
|
22158
22833
|
marginBottom: 12,
|
|
22159
22834
|
textAlign: 'center',
|
|
22160
22835
|
}, children: "Second" }), jsxRuntime.jsx(reactNative.FlatList, { data: secondOptions, keyExtractor: (item) => 's-' + item, renderItem: ({ item }) => {
|
|
22161
22836
|
var _a;
|
|
22162
22837
|
return renderNumber(item, ((_a = internal.seconds) !== null && _a !== void 0 ? _a : 0) === item, () => commit({ seconds: item }, autoClose));
|
|
22163
22838
|
}, style: [listCommon, { borderRadius: 12, backgroundColor: theme.colors.gray[1] }], contentContainerStyle: { paddingVertical: 8 }, showsVerticalScrollIndicator: false })] })), is12h && (jsxRuntime.jsxs(reactNative.View, { style: { alignItems: 'center' }, children: [jsxRuntime.jsx(Text, { size: "sm", weight: "medium", style: {
|
|
22164
|
-
color: theme.colors.gray[6],
|
|
22165
22839
|
marginBottom: 12,
|
|
22166
22840
|
textAlign: 'center',
|
|
22167
22841
|
}, children: "Period" }), jsxRuntime.jsx(Flex, { align: "center", justify: "center", style: {
|
|
@@ -23865,68 +24539,6 @@ const Breadcrumbs = factory((props, ref) => {
|
|
|
23865
24539
|
});
|
|
23866
24540
|
Breadcrumbs.displayName = 'Breadcrumbs';
|
|
23867
24541
|
|
|
23868
|
-
function useMenuStyles() {
|
|
23869
|
-
const theme = useTheme();
|
|
23870
|
-
const dropdown = {
|
|
23871
|
-
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.surface[3] : theme.colors.surface[4],
|
|
23872
|
-
borderRadius: parseInt(theme.radii.md),
|
|
23873
|
-
// borderWidth: 3, // Temporarily increased for debugging
|
|
23874
|
-
// borderColor: '#ff0000', // Temporarily red for debugging
|
|
23875
|
-
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
|
|
23876
|
-
elevation: 8,
|
|
23877
|
-
minWidth: 180,
|
|
23878
|
-
maxWidth: 320,
|
|
23879
|
-
overflow: 'hidden',
|
|
23880
|
-
};
|
|
23881
|
-
const item = {
|
|
23882
|
-
flexDirection: 'row',
|
|
23883
|
-
alignItems: 'center',
|
|
23884
|
-
paddingVertical: 8,
|
|
23885
|
-
paddingHorizontal: 12,
|
|
23886
|
-
minHeight: 36,
|
|
23887
|
-
};
|
|
23888
|
-
const itemPressed = {
|
|
23889
|
-
backgroundColor: theme.colors.gray[1],
|
|
23890
|
-
};
|
|
23891
|
-
const itemDisabled = {
|
|
23892
|
-
opacity: 0.5,
|
|
23893
|
-
};
|
|
23894
|
-
const itemDanger = {
|
|
23895
|
-
backgroundColor: theme.colors.error[0],
|
|
23896
|
-
};
|
|
23897
|
-
const itemDangerPressed = {
|
|
23898
|
-
backgroundColor: theme.colors.error[1],
|
|
23899
|
-
};
|
|
23900
|
-
const label = {
|
|
23901
|
-
paddingVertical: 6,
|
|
23902
|
-
paddingHorizontal: 12,
|
|
23903
|
-
};
|
|
23904
|
-
const divider = {
|
|
23905
|
-
height: 1,
|
|
23906
|
-
// backgroundColor: theme.colors.gray[2],
|
|
23907
|
-
// marginVertical: 4,
|
|
23908
|
-
};
|
|
23909
|
-
const leftSection = {
|
|
23910
|
-
marginRight: 8,
|
|
23911
|
-
};
|
|
23912
|
-
const rightSection = {
|
|
23913
|
-
marginLeft: 'auto',
|
|
23914
|
-
paddingLeft: 12,
|
|
23915
|
-
};
|
|
23916
|
-
return {
|
|
23917
|
-
dropdown,
|
|
23918
|
-
item,
|
|
23919
|
-
itemPressed,
|
|
23920
|
-
itemDisabled,
|
|
23921
|
-
itemDanger,
|
|
23922
|
-
itemDangerPressed,
|
|
23923
|
-
label,
|
|
23924
|
-
divider,
|
|
23925
|
-
leftSection,
|
|
23926
|
-
rightSection,
|
|
23927
|
-
};
|
|
23928
|
-
}
|
|
23929
|
-
|
|
23930
24542
|
const MenuContext = React.createContext(null);
|
|
23931
24543
|
function useMenuContext() {
|
|
23932
24544
|
const context = React.useContext(MenuContext);
|
|
@@ -24155,7 +24767,7 @@ function MenuBase(props, ref) {
|
|
|
24155
24767
|
// Create a callback ref that works better with React Native Web
|
|
24156
24768
|
const triggerCallbackRef = React.useCallback((node) => {
|
|
24157
24769
|
triggerRef.current = node;
|
|
24158
|
-
console.log('Trigger ref set to:', node);
|
|
24770
|
+
// console.log('Trigger ref set to:', node);
|
|
24159
24771
|
}, []);
|
|
24160
24772
|
const enhancedTrigger = React.isValidElement(triggerElement)
|
|
24161
24773
|
? React.cloneElement(triggerElement, {
|
|
@@ -24185,7 +24797,7 @@ function MenuBase(props, ref) {
|
|
|
24185
24797
|
else if (ref) {
|
|
24186
24798
|
ref.current = node;
|
|
24187
24799
|
}
|
|
24188
|
-
console.log('Combined ref set to:', node);
|
|
24800
|
+
// console.log('Combined ref set to:', node);
|
|
24189
24801
|
}, [ref]);
|
|
24190
24802
|
return (jsxRuntime.jsx(MenuContext.Provider, { value: { closeMenu: handleClose, opened: isOpened }, children: jsxRuntime.jsx(reactNative.View, { ref: combinedRef, style: getSpacingStyles(extractSpacingProps(spacingProps).spacingProps), testID: testID, ...(trigger === 'contextmenu' && reactNative.Platform.OS === 'web'
|
|
24191
24803
|
? {
|
|
@@ -24202,16 +24814,14 @@ function MenuBase(props, ref) {
|
|
|
24202
24814
|
}
|
|
24203
24815
|
: {}), onLayout: () => {
|
|
24204
24816
|
// Force a re-render to ensure ref is available
|
|
24205
|
-
if (containerRef.current)
|
|
24206
|
-
console.log('Menu container onLayout - container ref available:', containerRef.current);
|
|
24207
|
-
}
|
|
24817
|
+
if (containerRef.current) ;
|
|
24208
24818
|
}, children: enhancedTrigger }) }));
|
|
24209
24819
|
}
|
|
24210
24820
|
// Menu.Item component
|
|
24211
24821
|
function MenuItemBase(props, ref) {
|
|
24212
|
-
const {
|
|
24822
|
+
const { spacingProps, otherProps } = extractSpacingProps(props);
|
|
24823
|
+
const { children, onPress, disabled = false, leftSection, rightSection, color = 'default', closeMenuOnClick = true, testID, ...restProps } = otherProps;
|
|
24213
24824
|
const { closeMenu } = useMenuContext();
|
|
24214
|
-
const theme = useTheme();
|
|
24215
24825
|
const handlePress = React.useCallback(() => {
|
|
24216
24826
|
if (disabled)
|
|
24217
24827
|
return;
|
|
@@ -24219,7 +24829,14 @@ function MenuItemBase(props, ref) {
|
|
|
24219
24829
|
if (closeMenuOnClick)
|
|
24220
24830
|
closeMenu();
|
|
24221
24831
|
}, [disabled, onPress, closeMenuOnClick, closeMenu]);
|
|
24222
|
-
|
|
24832
|
+
const tone = color === 'danger'
|
|
24833
|
+
? 'danger'
|
|
24834
|
+
: color === 'success'
|
|
24835
|
+
? 'success'
|
|
24836
|
+
: color === 'warning'
|
|
24837
|
+
? 'warning'
|
|
24838
|
+
: 'default';
|
|
24839
|
+
return (jsxRuntime.jsx(MenuItemButton, { ref: ref, onPress: handlePress, disabled: disabled, startIcon: leftSection, endIcon: rightSection, tone: tone, testID: testID, ...spacingProps, ...restProps, children: children }));
|
|
24223
24840
|
}
|
|
24224
24841
|
// Menu.Label component
|
|
24225
24842
|
function MenuLabelBase(props, ref) {
|
|
@@ -25764,6 +26381,467 @@ function Blockquote({ children, variant = 'default', size = 'md', color, quoteIc
|
|
|
25764
26381
|
return content;
|
|
25765
26382
|
}
|
|
25766
26383
|
|
|
26384
|
+
const createPopoverStyles = (theme) => (params) => {
|
|
26385
|
+
const radiusStyles = createRadiusStyles(params.radius);
|
|
26386
|
+
const shadowStyles = createShadowStyles(params.shadow, theme, 'popover');
|
|
26387
|
+
return reactNative.StyleSheet.create({
|
|
26388
|
+
wrapper: {
|
|
26389
|
+
position: 'relative',
|
|
26390
|
+
alignSelf: 'flex-start',
|
|
26391
|
+
overflow: 'visible',
|
|
26392
|
+
...shadowStyles,
|
|
26393
|
+
},
|
|
26394
|
+
dropdown: {
|
|
26395
|
+
backgroundColor: theme.backgrounds.surface,
|
|
26396
|
+
borderColor: theme.backgrounds.border,
|
|
26397
|
+
borderWidth: 1,
|
|
26398
|
+
...radiusStyles,
|
|
26399
|
+
overflow: 'hidden',
|
|
26400
|
+
minWidth: 0,
|
|
26401
|
+
},
|
|
26402
|
+
arrow: {
|
|
26403
|
+
position: 'absolute',
|
|
26404
|
+
width: params.arrowSize * 2,
|
|
26405
|
+
height: params.arrowSize * 2,
|
|
26406
|
+
backgroundColor: theme.backgrounds.surface,
|
|
26407
|
+
transform: [{ rotate: '45deg' }],
|
|
26408
|
+
},
|
|
26409
|
+
});
|
|
26410
|
+
};
|
|
26411
|
+
|
|
26412
|
+
const PopoverContext = React.createContext(null);
|
|
26413
|
+
function usePopoverContext(component) {
|
|
26414
|
+
const context = React.useContext(PopoverContext);
|
|
26415
|
+
if (!context) {
|
|
26416
|
+
throw new Error(`${component} must be used within Popover`);
|
|
26417
|
+
}
|
|
26418
|
+
return context;
|
|
26419
|
+
}
|
|
26420
|
+
const DEFAULT_ARROW_SIZE = 7;
|
|
26421
|
+
const PopoverBase = (props, ref) => {
|
|
26422
|
+
var _a;
|
|
26423
|
+
const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
|
|
26424
|
+
trapFocus = false, keepMounted = false, returnFocus = false, withinPortal = true, withOverlay = false, overlayProps, width, minWidth, minHeight, maxWidth, maxHeight, radius, shadow, zIndex = 300, position = 'bottom', offset = 8, floatingStrategy = 'fixed', middlewares, preventPositionChangeWhenVisible = false, hideDetached = true, viewport, fallbackPlacements, boundary, withRoles = true, id, withArrow = false, arrowSize = DEFAULT_ARROW_SIZE, arrowRadius = 0, arrowOffset = 5, arrowPosition = 'center', onPositionChange, testID, ...rest } = props;
|
|
26425
|
+
const theme = useTheme();
|
|
26426
|
+
const { spacingProps } = extractSpacingProps(rest);
|
|
26427
|
+
const spacingStyles = getSpacingStyles(spacingProps);
|
|
26428
|
+
const isControlled = controlledOpened !== undefined;
|
|
26429
|
+
const [internalOpened, setInternalOpened] = React.useState(defaultOpened);
|
|
26430
|
+
const [dropdownState, setDropdownState] = React.useState(null);
|
|
26431
|
+
const opened = isControlled ? !!controlledOpened : internalOpened;
|
|
26432
|
+
const openedRef = React.useRef(opened);
|
|
26433
|
+
const closingReasonRef = React.useRef(null);
|
|
26434
|
+
const anchorMeasurementsRef = React.useRef(null);
|
|
26435
|
+
React.useEffect(() => {
|
|
26436
|
+
openedRef.current = opened;
|
|
26437
|
+
}, [opened]);
|
|
26438
|
+
const resolvedOffset = typeof offset === 'number' ? offset : (_a = offset === null || offset === void 0 ? void 0 : offset.mainAxis) !== null && _a !== void 0 ? _a : 8;
|
|
26439
|
+
const resolvedFlip = preventPositionChangeWhenVisible
|
|
26440
|
+
? false
|
|
26441
|
+
: (middlewares === null || middlewares === void 0 ? void 0 : middlewares.flip) === false
|
|
26442
|
+
? false
|
|
26443
|
+
: true;
|
|
26444
|
+
const resolvedShift = preventPositionChangeWhenVisible
|
|
26445
|
+
? false
|
|
26446
|
+
: (middlewares === null || middlewares === void 0 ? void 0 : middlewares.shift) === false
|
|
26447
|
+
? false
|
|
26448
|
+
: true;
|
|
26449
|
+
const resolvedStrategy = floatingStrategy !== null && floatingStrategy !== void 0 ? floatingStrategy : 'fixed';
|
|
26450
|
+
const { position: positioningResult, anchorRef, popoverRef, showOverlay, hideOverlay, updatePosition } = useDropdownPositioning({
|
|
26451
|
+
isOpen: opened && !disabled && !!dropdownState,
|
|
26452
|
+
placement: position,
|
|
26453
|
+
offset: resolvedOffset,
|
|
26454
|
+
strategy: resolvedStrategy,
|
|
26455
|
+
flip: resolvedFlip,
|
|
26456
|
+
shift: resolvedShift,
|
|
26457
|
+
boundary,
|
|
26458
|
+
fallbackPlacements,
|
|
26459
|
+
viewport,
|
|
26460
|
+
onClose: () => handleOverlayClose('dismiss'),
|
|
26461
|
+
closeOnClickOutside,
|
|
26462
|
+
closeOnEscape,
|
|
26463
|
+
});
|
|
26464
|
+
const popoverStyles = React.useMemo(() => createPopoverStyles(theme)({
|
|
26465
|
+
radius,
|
|
26466
|
+
shadow,
|
|
26467
|
+
arrowSize,
|
|
26468
|
+
}), [theme, radius, shadow, arrowSize]);
|
|
26469
|
+
const layoutUpdateTimeoutRef = React.useRef(null);
|
|
26470
|
+
const hasMeasuredLayoutRef = React.useRef(false);
|
|
26471
|
+
// Defer re-measuring to the next frame so overlay position uses final layout metrics
|
|
26472
|
+
const schedulePositionUpdate = React.useCallback(() => {
|
|
26473
|
+
if (layoutUpdateTimeoutRef.current) {
|
|
26474
|
+
clearTimeout(layoutUpdateTimeoutRef.current);
|
|
26475
|
+
}
|
|
26476
|
+
layoutUpdateTimeoutRef.current = setTimeout(() => {
|
|
26477
|
+
updatePosition();
|
|
26478
|
+
}, 16);
|
|
26479
|
+
}, [updatePosition]);
|
|
26480
|
+
React.useEffect(() => {
|
|
26481
|
+
return () => {
|
|
26482
|
+
if (layoutUpdateTimeoutRef.current) {
|
|
26483
|
+
clearTimeout(layoutUpdateTimeoutRef.current);
|
|
26484
|
+
layoutUpdateTimeoutRef.current = null;
|
|
26485
|
+
}
|
|
26486
|
+
};
|
|
26487
|
+
}, []);
|
|
26488
|
+
React.useEffect(() => {
|
|
26489
|
+
if (!opened) {
|
|
26490
|
+
hasMeasuredLayoutRef.current = false;
|
|
26491
|
+
if (layoutUpdateTimeoutRef.current) {
|
|
26492
|
+
clearTimeout(layoutUpdateTimeoutRef.current);
|
|
26493
|
+
layoutUpdateTimeoutRef.current = null;
|
|
26494
|
+
}
|
|
26495
|
+
}
|
|
26496
|
+
}, [opened]);
|
|
26497
|
+
React.useEffect(() => {
|
|
26498
|
+
hasMeasuredLayoutRef.current = false;
|
|
26499
|
+
}, [dropdownState]);
|
|
26500
|
+
const handleDropdownLayout = React.useCallback(() => {
|
|
26501
|
+
if (hasMeasuredLayoutRef.current) {
|
|
26502
|
+
return;
|
|
26503
|
+
}
|
|
26504
|
+
hasMeasuredLayoutRef.current = true;
|
|
26505
|
+
schedulePositionUpdate();
|
|
26506
|
+
}, [schedulePositionUpdate]);
|
|
26507
|
+
const updateAnchorMeasurements = React.useCallback(async () => {
|
|
26508
|
+
if (!anchorRef.current)
|
|
26509
|
+
return;
|
|
26510
|
+
try {
|
|
26511
|
+
const rect = await measureElement(anchorRef);
|
|
26512
|
+
anchorMeasurementsRef.current = { width: rect.width, height: rect.height };
|
|
26513
|
+
}
|
|
26514
|
+
catch (_a) {
|
|
26515
|
+
// noop – measurement failed (likely not mounted yet)
|
|
26516
|
+
}
|
|
26517
|
+
}, [anchorRef]);
|
|
26518
|
+
const commitOpen = React.useCallback(() => {
|
|
26519
|
+
if (openedRef.current || disabled)
|
|
26520
|
+
return;
|
|
26521
|
+
if (!isControlled) {
|
|
26522
|
+
setInternalOpened(true);
|
|
26523
|
+
}
|
|
26524
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(true);
|
|
26525
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
26526
|
+
openedRef.current = true;
|
|
26527
|
+
}, [disabled, isControlled, onChange, onOpen]);
|
|
26528
|
+
const commitClose = React.useCallback((reason) => {
|
|
26529
|
+
if (!openedRef.current)
|
|
26530
|
+
return;
|
|
26531
|
+
if (!isControlled) {
|
|
26532
|
+
setInternalOpened(false);
|
|
26533
|
+
}
|
|
26534
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(false);
|
|
26535
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
26536
|
+
if (reason === 'dismiss') {
|
|
26537
|
+
onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss();
|
|
26538
|
+
}
|
|
26539
|
+
openedRef.current = false;
|
|
26540
|
+
}, [isControlled, onChange, onClose, onDismiss]);
|
|
26541
|
+
const handleOverlayClose = React.useCallback((reason) => {
|
|
26542
|
+
var _a;
|
|
26543
|
+
const closingReason = (_a = closingReasonRef.current) !== null && _a !== void 0 ? _a : reason;
|
|
26544
|
+
closingReasonRef.current = null;
|
|
26545
|
+
commitClose(closingReason);
|
|
26546
|
+
}, [commitClose]);
|
|
26547
|
+
const openPopover = React.useCallback(() => {
|
|
26548
|
+
if (disabled)
|
|
26549
|
+
return;
|
|
26550
|
+
closingReasonRef.current = null;
|
|
26551
|
+
commitOpen();
|
|
26552
|
+
}, [commitOpen, disabled]);
|
|
26553
|
+
const closePopover = React.useCallback((reason = 'programmatic') => {
|
|
26554
|
+
if (!openedRef.current)
|
|
26555
|
+
return;
|
|
26556
|
+
closingReasonRef.current = reason;
|
|
26557
|
+
hideOverlay();
|
|
26558
|
+
}, [hideOverlay]);
|
|
26559
|
+
const togglePopover = React.useCallback(() => {
|
|
26560
|
+
if (openedRef.current) {
|
|
26561
|
+
closePopover('programmatic');
|
|
26562
|
+
}
|
|
26563
|
+
else {
|
|
26564
|
+
openPopover();
|
|
26565
|
+
}
|
|
26566
|
+
}, [closePopover, openPopover]);
|
|
26567
|
+
React.useEffect(() => {
|
|
26568
|
+
if (opened) {
|
|
26569
|
+
updateAnchorMeasurements();
|
|
26570
|
+
}
|
|
26571
|
+
}, [opened, updateAnchorMeasurements]);
|
|
26572
|
+
React.useEffect(() => {
|
|
26573
|
+
if (!opened) {
|
|
26574
|
+
closingReasonRef.current = null;
|
|
26575
|
+
hideOverlay();
|
|
26576
|
+
if (returnFocus && anchorRef.current && typeof anchorRef.current.focus === 'function') {
|
|
26577
|
+
anchorRef.current.focus();
|
|
26578
|
+
}
|
|
26579
|
+
return;
|
|
26580
|
+
}
|
|
26581
|
+
if (!dropdownState)
|
|
26582
|
+
return;
|
|
26583
|
+
updatePosition();
|
|
26584
|
+
}, [opened, dropdownState, updatePosition, hideOverlay, anchorRef, returnFocus]);
|
|
26585
|
+
React.useEffect(() => {
|
|
26586
|
+
var _a;
|
|
26587
|
+
if (!opened || !dropdownState) {
|
|
26588
|
+
hideOverlay();
|
|
26589
|
+
return;
|
|
26590
|
+
}
|
|
26591
|
+
if (!positioningResult) {
|
|
26592
|
+
return;
|
|
26593
|
+
}
|
|
26594
|
+
const computedFinalWidth = positioningResult.finalWidth && positioningResult.finalWidth > 0
|
|
26595
|
+
? positioningResult.finalWidth
|
|
26596
|
+
: undefined;
|
|
26597
|
+
const widthOverride = (() => {
|
|
26598
|
+
var _a, _b;
|
|
26599
|
+
if (typeof width === 'number')
|
|
26600
|
+
return width;
|
|
26601
|
+
if (width === 'target') {
|
|
26602
|
+
return (_b = (_a = anchorMeasurementsRef.current) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : computedFinalWidth;
|
|
26603
|
+
}
|
|
26604
|
+
return computedFinalWidth;
|
|
26605
|
+
})();
|
|
26606
|
+
const sizeStyles = {};
|
|
26607
|
+
if (typeof minWidth === 'number')
|
|
26608
|
+
sizeStyles.minWidth = minWidth;
|
|
26609
|
+
if (typeof minHeight === 'number')
|
|
26610
|
+
sizeStyles.minHeight = minHeight;
|
|
26611
|
+
if (typeof maxWidth === 'number')
|
|
26612
|
+
sizeStyles.maxWidth = maxWidth;
|
|
26613
|
+
const resolvedMaxHeight = typeof maxHeight === 'number' ? maxHeight : (_a = positioningResult.maxHeight) !== null && _a !== void 0 ? _a : maxHeight;
|
|
26614
|
+
if (typeof resolvedMaxHeight === 'number')
|
|
26615
|
+
sizeStyles.maxHeight = resolvedMaxHeight;
|
|
26616
|
+
const dropdownStyle = [popoverStyles.dropdown, dropdownState.style, sizeStyles];
|
|
26617
|
+
const content = (jsxRuntime.jsxs(reactNative.View, { ref: popoverRef, style: [popoverStyles.wrapper, widthOverride ? { width: widthOverride } : null], pointerEvents: dropdownState.trapFocus ? 'auto' : 'box-none', testID: dropdownState.testID, onLayout: handleDropdownLayout, ...dropdownState.containerProps, children: [jsxRuntime.jsx(reactNative.View, { style: dropdownStyle, children: dropdownState.content }), withArrow && (jsxRuntime.jsx(reactNative.View, { style: getArrowStyle(positioningResult.placement, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme) }))] }));
|
|
26618
|
+
showOverlay(content, {
|
|
26619
|
+
width: widthOverride,
|
|
26620
|
+
maxHeight: resolvedMaxHeight,
|
|
26621
|
+
zIndex,
|
|
26622
|
+
});
|
|
26623
|
+
onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(positioningResult.placement);
|
|
26624
|
+
}, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, width, maxHeight, minWidth, minHeight, maxWidth, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate]);
|
|
26625
|
+
React.useEffect(() => {
|
|
26626
|
+
return () => {
|
|
26627
|
+
hideOverlay();
|
|
26628
|
+
};
|
|
26629
|
+
}, [hideOverlay]);
|
|
26630
|
+
const registerDropdown = React.useCallback((dropdown) => {
|
|
26631
|
+
setDropdownState(dropdown);
|
|
26632
|
+
}, []);
|
|
26633
|
+
const unregisterDropdown = React.useCallback(() => {
|
|
26634
|
+
if (!keepMounted) {
|
|
26635
|
+
setDropdownState(null);
|
|
26636
|
+
}
|
|
26637
|
+
}, [keepMounted]);
|
|
26638
|
+
const targetId = React.useMemo(() => id ? `${id}-target` : `popover-target-${Math.random().toString(36).slice(2)}`, [id]);
|
|
26639
|
+
const dropdownId = React.useMemo(() => id ? `${id}-dropdown` : `popover-dropdown-${Math.random().toString(36).slice(2)}`, [id]);
|
|
26640
|
+
const contextValue = React.useMemo(() => ({
|
|
26641
|
+
opened,
|
|
26642
|
+
open: openPopover,
|
|
26643
|
+
close: () => closePopover('programmatic'),
|
|
26644
|
+
toggle: togglePopover,
|
|
26645
|
+
registerDropdown,
|
|
26646
|
+
unregisterDropdown,
|
|
26647
|
+
anchorRef,
|
|
26648
|
+
targetId,
|
|
26649
|
+
dropdownId,
|
|
26650
|
+
withRoles,
|
|
26651
|
+
disabled,
|
|
26652
|
+
returnFocus,
|
|
26653
|
+
}), [opened, openPopover, closePopover, togglePopover, registerDropdown, unregisterDropdown, anchorRef, targetId, dropdownId, withRoles, disabled, returnFocus]);
|
|
26654
|
+
const setContainerRef = React.useCallback((node) => {
|
|
26655
|
+
if (typeof ref === 'function') {
|
|
26656
|
+
ref(node);
|
|
26657
|
+
}
|
|
26658
|
+
else if (ref && 'current' in ref) {
|
|
26659
|
+
ref.current = node;
|
|
26660
|
+
}
|
|
26661
|
+
}, [ref]);
|
|
26662
|
+
return (jsxRuntime.jsx(PopoverContext.Provider, { value: contextValue, children: jsxRuntime.jsx(reactNative.View, { ref: setContainerRef, style: spacingStyles, testID: testID, children: children }) }));
|
|
26663
|
+
};
|
|
26664
|
+
function mergeRefs(...refs) {
|
|
26665
|
+
return (value) => {
|
|
26666
|
+
refs.forEach(ref => {
|
|
26667
|
+
if (!ref)
|
|
26668
|
+
return;
|
|
26669
|
+
if (typeof ref === 'function') {
|
|
26670
|
+
ref(value);
|
|
26671
|
+
}
|
|
26672
|
+
else if ('current' in ref) {
|
|
26673
|
+
ref.current = value;
|
|
26674
|
+
}
|
|
26675
|
+
});
|
|
26676
|
+
};
|
|
26677
|
+
}
|
|
26678
|
+
const PopoverTargetBase = (props, ref) => {
|
|
26679
|
+
var _a;
|
|
26680
|
+
const { children, popupType = 'dialog', refProp = 'ref', targetProps } = props;
|
|
26681
|
+
const context = usePopoverContext('Popover.Target');
|
|
26682
|
+
if (!React.isValidElement(children)) {
|
|
26683
|
+
throw new Error('Popover.Target expects a single React element child');
|
|
26684
|
+
}
|
|
26685
|
+
const childProps = children.props;
|
|
26686
|
+
const sanitizedTargetProps = { ...(targetProps !== null && targetProps !== void 0 ? targetProps : {}) };
|
|
26687
|
+
let externalTargetRef;
|
|
26688
|
+
if (refProp && Object.prototype.hasOwnProperty.call(sanitizedTargetProps, refProp)) {
|
|
26689
|
+
externalTargetRef = sanitizedTargetProps[refProp];
|
|
26690
|
+
delete sanitizedTargetProps[refProp];
|
|
26691
|
+
}
|
|
26692
|
+
const accessibilityProps = context.withRoles && reactNative.Platform.OS === 'web'
|
|
26693
|
+
? {
|
|
26694
|
+
role: (_a = childProps.role) !== null && _a !== void 0 ? _a : 'button',
|
|
26695
|
+
'aria-haspopup': popupType,
|
|
26696
|
+
'aria-expanded': context.opened,
|
|
26697
|
+
'aria-controls': context.opened ? context.dropdownId : undefined,
|
|
26698
|
+
id: context.targetId,
|
|
26699
|
+
}
|
|
26700
|
+
: { id: context.targetId };
|
|
26701
|
+
const composedRef = mergeRefs(children.ref, externalTargetRef);
|
|
26702
|
+
const triggerHandlers = {};
|
|
26703
|
+
triggerHandlers.onPress = (...args) => {
|
|
26704
|
+
const tgt = targetProps;
|
|
26705
|
+
if (tgt && typeof tgt.onPress === 'function') {
|
|
26706
|
+
tgt.onPress(...args);
|
|
26707
|
+
}
|
|
26708
|
+
if (typeof childProps.onPress === 'function') {
|
|
26709
|
+
childProps.onPress(...args);
|
|
26710
|
+
}
|
|
26711
|
+
context.toggle();
|
|
26712
|
+
};
|
|
26713
|
+
if (reactNative.Platform.OS === 'web') {
|
|
26714
|
+
triggerHandlers.onKeyDown = (event) => {
|
|
26715
|
+
const tgt = targetProps;
|
|
26716
|
+
if (tgt && typeof tgt.onKeyDown === 'function') {
|
|
26717
|
+
tgt.onKeyDown(event);
|
|
26718
|
+
}
|
|
26719
|
+
if (typeof childProps.onKeyDown === 'function') {
|
|
26720
|
+
childProps.onKeyDown(event);
|
|
26721
|
+
}
|
|
26722
|
+
if (event.defaultPrevented)
|
|
26723
|
+
return;
|
|
26724
|
+
if (event.key === 'Escape' && context.opened) {
|
|
26725
|
+
context.close();
|
|
26726
|
+
}
|
|
26727
|
+
if ((event.key === 'Enter' || event.key === ' ') && !context.opened) {
|
|
26728
|
+
event.preventDefault();
|
|
26729
|
+
context.open();
|
|
26730
|
+
}
|
|
26731
|
+
};
|
|
26732
|
+
}
|
|
26733
|
+
const dynamicRefProp = { [refProp]: composedRef };
|
|
26734
|
+
delete sanitizedTargetProps.onPress;
|
|
26735
|
+
delete sanitizedTargetProps.onKeyDown;
|
|
26736
|
+
const mergedProps = {
|
|
26737
|
+
...sanitizedTargetProps,
|
|
26738
|
+
...triggerHandlers,
|
|
26739
|
+
...accessibilityProps,
|
|
26740
|
+
...dynamicRefProp,
|
|
26741
|
+
};
|
|
26742
|
+
if (context.disabled) {
|
|
26743
|
+
mergedProps.disabled = true;
|
|
26744
|
+
}
|
|
26745
|
+
const anchorWrapperRef = mergeRefs(context.anchorRef, ref);
|
|
26746
|
+
return (jsxRuntime.jsx(reactNative.View, { ref: anchorWrapperRef, collapsable: false, children: React.cloneElement(children, mergedProps) }));
|
|
26747
|
+
};
|
|
26748
|
+
const PopoverDropdownBase = (props, _ref) => {
|
|
26749
|
+
const { children, trapFocus = false, keepMounted, style, testID, ...rest } = props;
|
|
26750
|
+
const context = usePopoverContext('Popover.Dropdown');
|
|
26751
|
+
const dropdownValue = React.useMemo(() => ({
|
|
26752
|
+
content: children,
|
|
26753
|
+
style,
|
|
26754
|
+
trapFocus,
|
|
26755
|
+
keepMounted,
|
|
26756
|
+
testID,
|
|
26757
|
+
containerProps: rest,
|
|
26758
|
+
}), [children, rest, style, trapFocus, keepMounted, testID]);
|
|
26759
|
+
React.useEffect(() => {
|
|
26760
|
+
context.registerDropdown(dropdownValue);
|
|
26761
|
+
return () => context.unregisterDropdown();
|
|
26762
|
+
}, [context, dropdownValue]);
|
|
26763
|
+
if (keepMounted) {
|
|
26764
|
+
return (jsxRuntime.jsx(reactNative.View, { style: { display: 'none' }, children: children }));
|
|
26765
|
+
}
|
|
26766
|
+
return null;
|
|
26767
|
+
};
|
|
26768
|
+
function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme) {
|
|
26769
|
+
if (reactNative.Platform.OS !== 'web') {
|
|
26770
|
+
return {
|
|
26771
|
+
width: 0,
|
|
26772
|
+
height: 0,
|
|
26773
|
+
opacity: 0,
|
|
26774
|
+
};
|
|
26775
|
+
}
|
|
26776
|
+
const base = {
|
|
26777
|
+
position: 'absolute',
|
|
26778
|
+
width: arrowSize * 2,
|
|
26779
|
+
height: arrowSize * 2,
|
|
26780
|
+
backgroundColor: theme.backgrounds.surface,
|
|
26781
|
+
transform: [{ rotate: '45deg' }],
|
|
26782
|
+
borderRadius: arrowRadius,
|
|
26783
|
+
borderColor: theme.backgrounds.border,
|
|
26784
|
+
borderWidth: 1,
|
|
26785
|
+
};
|
|
26786
|
+
const [side, alignment] = placement.split('-');
|
|
26787
|
+
switch (side) {
|
|
26788
|
+
case 'top':
|
|
26789
|
+
return {
|
|
26790
|
+
...base,
|
|
26791
|
+
bottom: -arrowSize,
|
|
26792
|
+
left: alignment === 'end'
|
|
26793
|
+
? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
|
|
26794
|
+
: alignment === 'start'
|
|
26795
|
+
? (arrowPosition === 'side' ? arrowOffset : arrowSize)
|
|
26796
|
+
: '50%',
|
|
26797
|
+
marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
|
|
26798
|
+
};
|
|
26799
|
+
case 'bottom':
|
|
26800
|
+
return {
|
|
26801
|
+
...base,
|
|
26802
|
+
top: -arrowSize,
|
|
26803
|
+
left: alignment === 'end'
|
|
26804
|
+
? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
|
|
26805
|
+
: alignment === 'start'
|
|
26806
|
+
? (arrowPosition === 'side' ? arrowOffset : arrowSize)
|
|
26807
|
+
: '50%',
|
|
26808
|
+
marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
|
|
26809
|
+
};
|
|
26810
|
+
case 'left':
|
|
26811
|
+
return {
|
|
26812
|
+
...base,
|
|
26813
|
+
right: -arrowSize,
|
|
26814
|
+
top: alignment === 'end'
|
|
26815
|
+
? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
|
|
26816
|
+
: alignment === 'start'
|
|
26817
|
+
? (arrowPosition === 'side' ? arrowOffset : arrowSize)
|
|
26818
|
+
: '50%',
|
|
26819
|
+
marginTop: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
|
|
26820
|
+
};
|
|
26821
|
+
case 'right':
|
|
26822
|
+
return {
|
|
26823
|
+
...base,
|
|
26824
|
+
left: -arrowSize,
|
|
26825
|
+
top: alignment === 'end'
|
|
26826
|
+
? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
|
|
26827
|
+
: alignment === 'start'
|
|
26828
|
+
? (arrowPosition === 'side' ? arrowOffset : arrowSize)
|
|
26829
|
+
: '50%',
|
|
26830
|
+
marginTop: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
|
|
26831
|
+
};
|
|
26832
|
+
default:
|
|
26833
|
+
return base;
|
|
26834
|
+
}
|
|
26835
|
+
}
|
|
26836
|
+
const Popover = factory(PopoverBase);
|
|
26837
|
+
const PopoverTarget = factory(PopoverTargetBase);
|
|
26838
|
+
const PopoverDropdown = factory(PopoverDropdownBase);
|
|
26839
|
+
Popover.Target = PopoverTarget;
|
|
26840
|
+
Popover.Dropdown = PopoverDropdown;
|
|
26841
|
+
Popover.displayName = 'Popover';
|
|
26842
|
+
PopoverTarget.displayName = 'Popover.Target';
|
|
26843
|
+
PopoverDropdown.displayName = 'Popover.Dropdown';
|
|
26844
|
+
|
|
25767
26845
|
const getSpacingValue = (spacing, theme) => {
|
|
25768
26846
|
if (typeof spacing === 'number')
|
|
25769
26847
|
return spacing;
|
|
@@ -26858,7 +27936,6 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
|
|
|
26858
27936
|
else {
|
|
26859
27937
|
setInternalSearchValue(value);
|
|
26860
27938
|
}
|
|
26861
|
-
setForceUpdateCounter(c => c + 1);
|
|
26862
27939
|
}, [onSearchChange]);
|
|
26863
27940
|
const handleSort = React.useCallback((columnKey) => {
|
|
26864
27941
|
if (!onSortChange)
|
|
@@ -26996,43 +28073,44 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
|
|
|
26996
28073
|
alignItems: 'center',
|
|
26997
28074
|
marginBottom: DESIGN_TOKENS.spacing.md,
|
|
26998
28075
|
paddingHorizontal: DESIGN_TOKENS.spacing.xs
|
|
26999
|
-
}, children: [jsxRuntime.jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxRuntime.jsxs(Flex, { gap: 8, children: [jsxRuntime.jsxs(Text, { variant: "caption", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxRuntime.jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxRuntime.jsxs(
|
|
27000
|
-
|
|
27001
|
-
|
|
27002
|
-
|
|
27003
|
-
|
|
27004
|
-
|
|
27005
|
-
|
|
27006
|
-
|
|
27007
|
-
|
|
27008
|
-
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
|
|
27014
|
-
|
|
27015
|
-
|
|
27016
|
-
|
|
27017
|
-
|
|
27018
|
-
|
|
27019
|
-
|
|
27020
|
-
|
|
27021
|
-
|
|
27022
|
-
|
|
27023
|
-
|
|
27024
|
-
|
|
27025
|
-
|
|
27026
|
-
|
|
27027
|
-
|
|
27028
|
-
|
|
27029
|
-
|
|
27030
|
-
|
|
27031
|
-
|
|
27032
|
-
|
|
27033
|
-
|
|
27034
|
-
|
|
27035
|
-
}
|
|
28076
|
+
}, children: [jsxRuntime.jsx(Flex, { gap: DESIGN_TOKENS.spacing.md, align: "center", children: selectedRows.length > 0 && bulkActions.length > 0 && (jsxRuntime.jsxs(Flex, { gap: 8, children: [jsxRuntime.jsxs(Text, { variant: "caption", colorVariant: "muted", children: [selectedRows.length, " selected"] }), bulkActions.map(action => (jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: action.icon, onPress: () => action.action(selectedRows, data), children: action.label }, action.key)))] })) }), jsxRuntime.jsxs(Flex, { gap: 8, children: [(searchable || columns.some(c => c.filterable)) && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 320, trapFocus: true, children: [jsxRuntime.jsx(PopoverTarget, { children: jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "search", size: 14 }), children: ["Search", (searchValue || activeFilters.length > 0) && (jsxRuntime.jsx(reactNative.View, { style: {
|
|
28077
|
+
width: 6,
|
|
28078
|
+
height: 6,
|
|
28079
|
+
borderRadius: 3,
|
|
28080
|
+
backgroundColor: theme.colors.primary[5],
|
|
28081
|
+
marginLeft: 4
|
|
28082
|
+
} }))] }) }), jsxRuntime.jsx(PopoverDropdown, { children: jsxRuntime.jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.md, style: { width: 320 }, children: [jsxRuntime.jsx(Text, { variant: "caption", weight: "semibold", children: "Search & Filter" }), searchable && (jsxRuntime.jsx(reactNative.View, { style: {
|
|
28083
|
+
borderBottomWidth: 1,
|
|
28084
|
+
borderBottomColor: theme.colors.gray[2],
|
|
28085
|
+
paddingBottom: DESIGN_TOKENS.spacing.sm,
|
|
28086
|
+
}, children: jsxRuntime.jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, children: [jsxRuntime.jsx(Text, { variant: "caption", weight: "semibold", children: "Search" }), jsxRuntime.jsx(Input, { placeholder: searchPlaceholder, value: searchValue, onChangeText: handleSearchChange, leftSection: jsxRuntime.jsx(Icon, { name: "menu", size: 16 }), size: "sm" })] }) })), columns.some(c => c.filterable) && (jsxRuntime.jsxs(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: [jsxRuntime.jsxs(Flex, { direction: "row", justify: "space-between", align: "center", children: [jsxRuntime.jsx(Text, { variant: "caption", weight: "semibold", children: "Filters" }), activeFilters.length > 0 && (jsxRuntime.jsx(Button, { variant: "ghost", size: "xs", onPress: () => {
|
|
28087
|
+
setInternalFilters([]);
|
|
28088
|
+
setForceUpdateCounter(c => c + 1);
|
|
28089
|
+
}, children: "Clear all" }))] }), activeFilters.length > 0 && (jsxRuntime.jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.xs, style: { marginBottom: DESIGN_TOKENS.spacing.sm }, children: activeFilters.map((filter, idx) => {
|
|
28090
|
+
const column = columns.find(c => c.key === filter.column);
|
|
28091
|
+
return (jsxRuntime.jsxs(reactNative.View, { style: {
|
|
28092
|
+
flexDirection: 'row',
|
|
28093
|
+
alignItems: 'center',
|
|
28094
|
+
backgroundColor: theme.colors.primary[1],
|
|
28095
|
+
paddingHorizontal: DESIGN_TOKENS.spacing.sm,
|
|
28096
|
+
paddingVertical: DESIGN_TOKENS.spacing.xs,
|
|
28097
|
+
borderRadius: DESIGN_TOKENS.radius.sm,
|
|
28098
|
+
gap: DESIGN_TOKENS.spacing.xs
|
|
28099
|
+
}, children: [jsxRuntime.jsxs(Text, { variant: "caption", style: { color: theme.colors.primary[7] }, children: [(column === null || column === void 0 ? void 0 : column.header) || filter.column, ": ", filter.operator, " \"", filter.value, "\""] }), jsxRuntime.jsx(reactNative.Pressable, { onPress: () => {
|
|
28100
|
+
setInternalFilters(filters => filters.filter((_, i) => i !== idx));
|
|
28101
|
+
setForceUpdateCounter(c => c + 1);
|
|
28102
|
+
}, children: jsxRuntime.jsx(Icon, { name: "x", size: 12, color: theme.colors.primary[6] }) })] }, idx));
|
|
28103
|
+
}) })), jsxRuntime.jsx(Flex, { direction: "column", gap: DESIGN_TOKENS.spacing.sm, children: columns.filter(c => c.filterable).map(column => {
|
|
28104
|
+
const currentFilter = getColumnFilter(column.key);
|
|
28105
|
+
return (jsxRuntime.jsx(reactNative.View, { children: renderFilterControl(column) }, `${column.key}-${(currentFilter === null || currentFilter === void 0 ? void 0 : currentFilter.value) || 'no-filter'}`));
|
|
28106
|
+
}) })] }))] }) })] })), onEditModeChange && (jsxRuntime.jsx(Button, { variant: editMode ? 'filled' : 'outline', size: "sm", onPress: () => onEditModeChange(!editMode), children: editMode ? 'Exit Edit' : 'Edit' })), showColumnVisibilityManager && (jsxRuntime.jsxs(Popover, { position: "bottom-end", offset: { mainAxis: 12 }, width: 280, trapFocus: true, children: [jsxRuntime.jsx(PopoverTarget, { children: jsxRuntime.jsx(Button, { variant: "outline", size: "sm", startIcon: jsxRuntime.jsx(Icon, { name: "eye", size: 14 }), children: "Columns" }) }), jsxRuntime.jsx(PopoverDropdown, { children: jsxRuntime.jsxs(reactNative.View, { style: { padding: 8, maxHeight: 300, width: 260 }, children: [jsxRuntime.jsx(ComponentWithDisclaimer, { disclaimer: "Selected view determines the layout style", disclaimerProps: { colorVariant: 'muted', size: 'sm' }, children: jsxRuntime.jsxs(Row, { children: [jsxRuntime.jsx(Button, { size: "xs", title: "Deselect All", variant: hiddenColumns.length === columns.length ? 'filled' : 'outline', onPress: () => setHiddenColumns(columns.map(c => c.key)), style: { marginBottom: 8 } }), jsxRuntime.jsx(Button, { size: "xs", title: "Select All", variant: hiddenColumns.length === 0 ? 'filled' : 'outline', onPress: () => setHiddenColumns([]), style: { marginBottom: 8 } })] }) }), jsxRuntime.jsx(reactNative.ScrollView, { style: { maxHeight: 200 }, children: columns.map(col => (jsxRuntime.jsx(Checkbox, { label: tempHeaderEdits[col.key] || col.header, onChange: () => {
|
|
28107
|
+
if (hiddenColumns.includes(col.key)) {
|
|
28108
|
+
setHiddenColumns(prev => prev.filter(h => h !== col.key));
|
|
28109
|
+
}
|
|
28110
|
+
else {
|
|
28111
|
+
setHiddenColumns(prev => [...prev, col.key]);
|
|
28112
|
+
}
|
|
28113
|
+
}, style: { marginBottom: 4 } }, col.key))) })] }) })] }))] })] }));
|
|
27036
28114
|
const renderCell = React.useCallback((column, row, rowIndex) => {
|
|
27037
28115
|
const value = getValue(row, column.accessor);
|
|
27038
28116
|
const isEditing = (editingCell === null || editingCell === void 0 ? void 0 : editingCell.row) === rowIndex && (editingCell === null || editingCell === void 0 ? void 0 : editingCell.column) === column.key;
|
|
@@ -35327,6 +36405,7 @@ exports.Heading3 = Heading3;
|
|
|
35327
36405
|
exports.Heading4 = Heading4;
|
|
35328
36406
|
exports.Heading5 = Heading5;
|
|
35329
36407
|
exports.Heading6 = Heading6;
|
|
36408
|
+
exports.Highlight = Highlight;
|
|
35330
36409
|
exports.HoverCard = HoverCard;
|
|
35331
36410
|
exports.HuaweiAppGalleryBadge = HuaweiAppGalleryBadge;
|
|
35332
36411
|
exports.I18nProvider = I18nProvider;
|
|
@@ -35376,6 +36455,9 @@ exports.PermissionProvider = PermissionProvider;
|
|
|
35376
36455
|
exports.PhoneInput = PhoneInput;
|
|
35377
36456
|
exports.PinInput = PinInput;
|
|
35378
36457
|
exports.PlatformBlocksProvider = PlatformBlocksProvider;
|
|
36458
|
+
exports.Popover = Popover;
|
|
36459
|
+
exports.PopoverDropdown = PopoverDropdown;
|
|
36460
|
+
exports.PopoverTarget = PopoverTarget;
|
|
35379
36461
|
exports.PressAnimation = PressAnimation;
|
|
35380
36462
|
exports.Progress = Progress;
|
|
35381
36463
|
exports.QRCode = QRCode;
|