@platform-blocks/ui 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/cjs/index.js +684 -1211
  2. package/lib/cjs/index.js.map +1 -1
  3. package/lib/components/Avatar/Avatar.d.ts +1 -1
  4. package/lib/components/Avatar/types.d.ts +3 -3
  5. package/lib/components/Carousel/types.d.ts +32 -0
  6. package/lib/components/DataTable/DataTable.d.ts +1 -1
  7. package/lib/components/DataTable/types.d.ts +2 -0
  8. package/lib/components/HoverCard/types.d.ts +4 -2
  9. package/lib/components/Popover/types.d.ts +2 -0
  10. package/lib/components/Slider/types.d.ts +29 -1
  11. package/lib/components/Switch/styles.d.ts +1 -1
  12. package/lib/components/TextArea/styles.d.ts +1 -1
  13. package/lib/components/index.d.ts +0 -2
  14. package/lib/core/providers/OverlayProvider.d.ts +1 -1
  15. package/lib/core/theme/PlatformBlocksProvider.d.ts +1 -5
  16. package/lib/esm/index.js +685 -1193
  17. package/lib/esm/index.js.map +1 -1
  18. package/lib/index.d.ts +0 -7
  19. package/package.json +1 -1
  20. package/lib/components/Can/Can.d.ts +0 -30
  21. package/lib/components/Can/PermissionDemo.d.ts +0 -2
  22. package/lib/components/Can/ability.d.ts +0 -89
  23. package/lib/components/Can/builder.d.ts +0 -113
  24. package/lib/components/Can/context.d.ts +0 -25
  25. package/lib/components/Can/index.d.ts +0 -6
  26. package/lib/components/Can/types.d.ts +0 -230
  27. package/lib/components/HoverCard/index.d.ts +0 -2
  28. package/lib/components/NavigationProgress/NavigationProgress.d.ts +0 -4
  29. package/lib/components/NavigationProgress/defaults.d.ts +0 -8
  30. package/lib/components/NavigationProgress/hooks/useNavigationProgressState.d.ts +0 -1
  31. package/lib/components/NavigationProgress/index.d.ts +0 -2
  32. package/lib/components/NavigationProgress/styles/resolver.d.ts +0 -1
  33. package/lib/components/NavigationProgress/tokens.d.ts +0 -4
  34. package/lib/components/NavigationProgress/types.d.ts +0 -30
package/lib/cjs/index.js CHANGED
@@ -1184,25 +1184,50 @@ function OverlayRenderer({ style } = {}) {
1184
1184
  }) }));
1185
1185
  }
1186
1186
  function OverlayContent({ overlay, isTopmost, onBackdropPress }) {
1187
- var _a, _b, _c;
1187
+ var _a, _b, _c, _d, _e, _f;
1188
1188
  useTheme();
1189
1189
  const DEBUG = overlay.debug === true;
1190
1190
  if (DEBUG) {
1191
1191
  console.log('Rendering overlay content:');
1192
1192
  console.log('- anchor:', overlay.anchor);
1193
+ console.log('- placement:', overlay.placement);
1193
1194
  console.log('- strategy:', overlay.strategy);
1194
1195
  console.log('- zIndex:', overlay.zIndex);
1195
1196
  }
1197
+ // Check if this is a top-positioned overlay
1198
+ const isTopPlacement = (_a = overlay.placement) === null || _a === void 0 ? void 0 : _a.startsWith('top');
1199
+ // For top placements, we need to anchor from the bottom of the overlay
1200
+ // The anchor.y represents where the bottom of the overlay should be (top of the trigger minus offset)
1201
+ // So we use the estimated height to calculate where the top of the overlay would be
1196
1202
  const overlayStyle = {
1197
1203
  // Use fixed positioning on web for viewport-anchored overlays
1198
1204
  position: (reactNative.Platform.OS === 'web' && overlay.strategy === 'fixed') ? 'fixed' : 'absolute',
1199
- top: ((_a = overlay.anchor) === null || _a === void 0 ? void 0 : _a.y) || 0,
1200
1205
  left: ((_b = overlay.anchor) === null || _b === void 0 ? void 0 : _b.x) || 0,
1201
1206
  zIndex: overlay.zIndex,
1202
1207
  width: overlay.width || (((_c = overlay.anchor) === null || _c === void 0 ? void 0 : _c.width) ? overlay.anchor.width : undefined),
1203
1208
  maxWidth: overlay.maxWidth,
1204
1209
  maxHeight: overlay.maxHeight,
1205
1210
  };
1211
+ if (isTopPlacement && reactNative.Platform.OS === 'web') {
1212
+ // For top placements, position from the bottom of the overlay
1213
+ // anchor.y is where the top of the overlay should be, but we want to anchor from the bottom
1214
+ // so the overlay can grow upward naturally
1215
+ // The "bottom" of the anchor point is: viewport.height - (anchor.y + estimatedHeight)
1216
+ // But since we don't know actual height, use bottom anchoring relative to the trigger
1217
+ // Actually, anchor.y already accounts for the estimated height, so:
1218
+ // anchor.y = trigger.y - estimatedHeight - offset
1219
+ // We want the overlay's bottom edge to be at: trigger.y - offset
1220
+ // Which means: bottom = viewport.height - (trigger.y - offset) = viewport.height - anchor.y - estimatedHeight
1221
+ // Simpler: just set top and let it render, but the issue is the estimate is wrong
1222
+ // Better approach: use the anchor.y + anchor.height as the "bottom anchor point"
1223
+ // This is where the bottom of the overlay should be
1224
+ const bottomAnchorPoint = (((_d = overlay.anchor) === null || _d === void 0 ? void 0 : _d.y) || 0) + (((_e = overlay.anchor) === null || _e === void 0 ? void 0 : _e.height) || 0);
1225
+ overlayStyle.top = undefined;
1226
+ overlayStyle.bottom = `calc(100vh - ${bottomAnchorPoint}px)`;
1227
+ }
1228
+ else {
1229
+ overlayStyle.top = ((_f = overlay.anchor) === null || _f === void 0 ? void 0 : _f.y) || 0;
1230
+ }
1206
1231
  if (DEBUG) {
1207
1232
  console.log('- overlayStyle:', overlayStyle);
1208
1233
  }
@@ -6173,31 +6198,29 @@ const Button = (allProps) => {
6173
6198
  const { getDuration } = useReducedMotion$1();
6174
6199
  const { announce } = useAnnouncer();
6175
6200
  const { ref: focusRef} = useFocus(`button-${title || 'button'}`);
6201
+ // Track measured width for loading state preservation
6202
+ const [measuredWidth, setMeasuredWidth] = React.useState(null);
6203
+ const wasLoadingRef = React.useRef(loading);
6204
+ // When loading starts, we want to preserve the current measured width
6205
+ // When loading ends, clear the preserved width so it can resize naturally
6206
+ React.useEffect(() => {
6207
+ if (!loading && wasLoadingRef.current) {
6208
+ // Loading just ended, allow width to be recalculated
6209
+ setMeasuredWidth(null);
6210
+ }
6211
+ wasLoadingRef.current = loading;
6212
+ }, [loading]);
6213
+ const handleLayout = React.useCallback((event) => {
6214
+ // Only update measured width when not loading, so we capture the natural content width
6215
+ if (!loading) {
6216
+ const { width } = event.nativeEvent.layout;
6217
+ setMeasuredWidth(width);
6218
+ }
6219
+ // Call user's onLayout if provided
6220
+ onLayout === null || onLayout === void 0 ? void 0 : onLayout(event);
6221
+ }, [loading, onLayout]);
6176
6222
  // Determine button content - children takes precedence over title
6177
6223
  const buttonContent = children !== null && children !== void 0 ? children : title;
6178
- // Calculate minimum width for loading state based on content and size
6179
- const calculateMinWidth = () => {
6180
- if (!buttonContent || typeof buttonContent !== 'string')
6181
- return undefined;
6182
- // Base character width estimates based on size
6183
- const charWidthBySize = {
6184
- xs: 6,
6185
- sm: 7,
6186
- md: 8,
6187
- lg: 9,
6188
- xl: 10,
6189
- '2xl': 11,
6190
- '3xl': 12
6191
- };
6192
- const sizeKey = typeof size === 'string' ? size : 'md';
6193
- const charWidth = charWidthBySize[sizeKey] || 8;
6194
- const horizontalPadding = getSpacing(size) * 2; // Left + right padding
6195
- // Estimate content width: character count * average char width + padding
6196
- const contentWidth = buttonContent.length * charWidth + horizontalPadding;
6197
- // Add space for loader and gap when loading
6198
- const loaderWidth = getFontSize$1(size) + getSpacing(size) / 2; // Loader + margin
6199
- return Math.max(contentWidth, contentWidth + loaderWidth);
6200
- };
6201
6224
  // Determine what content to show based on loading state
6202
6225
  const displayContent = loading
6203
6226
  ? (loadingTitle !== undefined ? loadingTitle : '')
@@ -6236,12 +6259,12 @@ const Button = (allProps) => {
6236
6259
  const shadowStyles = getShadowStyles({ shadow: effectiveShadow }, theme, 'button');
6237
6260
  const spacingStyles = getSpacingStyles(spacingProps);
6238
6261
  const baseLayoutStyles = getLayoutStyles(layoutProps);
6239
- // Apply minimum width when loading to prevent size changes
6240
- const calculatedMinWidth = calculateMinWidth();
6262
+ // Apply measured width when loading to prevent size changes
6263
+ // Use the actual measured width instead of character-based estimates
6241
6264
  const layoutStyles = {
6242
6265
  ...baseLayoutStyles,
6243
- ...(loading && calculatedMinWidth && !layoutProps.width && !layoutProps.w && !layoutProps.fullWidth
6244
- ? { minWidth: calculatedMinWidth }
6266
+ ...(loading && measuredWidth && !layoutProps.width && !layoutProps.w && !layoutProps.fullWidth
6267
+ ? { width: measuredWidth, minWidth: measuredWidth }
6245
6268
  : {})
6246
6269
  };
6247
6270
  const iconSpacing = getSpacing(size) / 2;
@@ -6434,7 +6457,7 @@ const Button = (allProps) => {
6434
6457
  ...(reactNative.Platform.OS !== 'web' ? { transform: [{ translateY: 1 }] } : {})
6435
6458
  } : null,
6436
6459
  style,
6437
- ], onPress: handleInternalPress, onLayout: onLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && hasLinearGradient$4 && (jsxRuntime.jsx(OptionalLinearGradient$6, { colors: resolvedCustomColor
6460
+ ], onPress: handleInternalPress, onLayout: handleLayout, onPressIn: handlePressIn, onPressOut: handlePressOut, onHoverIn: onHoverIn, onHoverOut: onHoverOut, onLongPress: onLongPress, disabled: isInteractionDisabled, children: [variant === 'gradient' && hasLinearGradient$4 && (jsxRuntime.jsx(OptionalLinearGradient$6, { colors: resolvedCustomColor
6438
6461
  ? [resolvedCustomColor, theme.colors.primary[7]]
6439
6462
  : [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 ? (
6440
6463
  // Icon-only button
@@ -9752,593 +9775,6 @@ function UniversalCSS() {
9752
9775
  return null;
9753
9776
  }
9754
9777
 
9755
- /**
9756
- * Core Ability class for managing permissions
9757
- */
9758
- class AbilityCore {
9759
- constructor(rules = []) {
9760
- this.rules = [];
9761
- this.cache = new Map();
9762
- this.rules = [...rules];
9763
- }
9764
- /**
9765
- * Check if action is allowed on subject
9766
- */
9767
- can(action, subject, field) {
9768
- return this.check(action, subject, field).allowed;
9769
- }
9770
- /**
9771
- * Check if action is forbidden on subject
9772
- */
9773
- cannot(action, subject, field) {
9774
- return !this.can(action, subject, field);
9775
- }
9776
- /**
9777
- * Get detailed permission check result
9778
- */
9779
- check(action, subject, field) {
9780
- const cacheKey = this.getCacheKey(action, subject, field);
9781
- if (this.cache.has(cacheKey)) {
9782
- return this.cache.get(cacheKey);
9783
- }
9784
- const result = this.performCheck(action, subject, field);
9785
- this.cache.set(cacheKey, result);
9786
- return result;
9787
- }
9788
- /**
9789
- * Update ability rules and clear cache
9790
- */
9791
- update(rules) {
9792
- this.rules = [...rules];
9793
- this.cache.clear();
9794
- }
9795
- /**
9796
- * Get all current rules
9797
- */
9798
- getRules() {
9799
- return [...this.rules];
9800
- }
9801
- /**
9802
- * Clear all rules and cache
9803
- */
9804
- clear() {
9805
- this.rules = [];
9806
- this.cache.clear();
9807
- }
9808
- /**
9809
- * Perform the actual permission check
9810
- */
9811
- performCheck(action, subject, field) {
9812
- // Start with denied by default
9813
- let result = {
9814
- allowed: false,
9815
- reason: 'No matching permission rule found'
9816
- };
9817
- // Check rules in order (later rules can override earlier ones)
9818
- for (const rule of this.rules) {
9819
- if (this.ruleMatches(rule, action, subject, field)) {
9820
- result = {
9821
- allowed: !rule.inverted,
9822
- reason: rule.reason || (rule.inverted ? 'Access denied by rule' : 'Access granted by rule'),
9823
- rule
9824
- };
9825
- }
9826
- }
9827
- return result;
9828
- }
9829
- /**
9830
- * Check if a rule matches the current permission check
9831
- */
9832
- ruleMatches(rule, action, subject, field) {
9833
- // Check action match
9834
- const actions = Array.isArray(rule.action) ? rule.action : [rule.action];
9835
- if (!actions.includes(action) && !actions.includes('*')) {
9836
- return false;
9837
- }
9838
- // Check subject match
9839
- const subjects = Array.isArray(rule.subject) ? rule.subject : [rule.subject];
9840
- if (!this.subjectMatches(subjects, subject)) {
9841
- return false;
9842
- }
9843
- // Check field match (if specified)
9844
- if (field && rule.fields && !rule.fields.includes(field)) {
9845
- return false;
9846
- }
9847
- // Check conditions (if subject is an object)
9848
- if (rule.conditions && typeof subject === 'object' && subject !== null) {
9849
- return this.conditionsMatch(rule.conditions, subject);
9850
- }
9851
- return true;
9852
- }
9853
- /**
9854
- * Check if subject matches any of the rule subjects
9855
- */
9856
- subjectMatches(ruleSubjects, checkSubject) {
9857
- for (const ruleSubject of ruleSubjects) {
9858
- if (ruleSubject === '*')
9859
- return true;
9860
- if (ruleSubject === checkSubject)
9861
- return true;
9862
- // Handle class/constructor matching
9863
- if (typeof ruleSubject === 'function' && typeof checkSubject === 'object') {
9864
- if (checkSubject instanceof ruleSubject)
9865
- return true;
9866
- if (checkSubject.constructor === ruleSubject)
9867
- return true;
9868
- }
9869
- // Handle string matching for object types
9870
- if (typeof ruleSubject === 'string' && typeof checkSubject === 'object') {
9871
- if (checkSubject.__type === ruleSubject)
9872
- return true;
9873
- if (checkSubject.type === ruleSubject)
9874
- return true;
9875
- if (checkSubject.constructor.name === ruleSubject)
9876
- return true;
9877
- }
9878
- }
9879
- return false;
9880
- }
9881
- /**
9882
- * Check if conditions match the subject object
9883
- */
9884
- conditionsMatch(conditions, subject) {
9885
- for (const [key, expectedValue] of Object.entries(conditions)) {
9886
- const actualValue = subject[key];
9887
- if (!this.valuesMatch(actualValue, expectedValue)) {
9888
- return false;
9889
- }
9890
- }
9891
- return true;
9892
- }
9893
- /**
9894
- * Check if two values match (handles various comparison types)
9895
- */
9896
- valuesMatch(actual, expected) {
9897
- // Exact match
9898
- if (actual === expected)
9899
- return true;
9900
- // Array contains check
9901
- if (Array.isArray(expected) && expected.includes(actual))
9902
- return true;
9903
- if (Array.isArray(actual) && actual.includes(expected))
9904
- return true;
9905
- // Function/predicate check
9906
- if (typeof expected === 'function') {
9907
- return expected(actual);
9908
- }
9909
- // Regex match for strings
9910
- if (expected instanceof RegExp && typeof actual === 'string') {
9911
- return expected.test(actual);
9912
- }
9913
- // Object comparison (shallow)
9914
- if (typeof expected === 'object' && typeof actual === 'object' && expected !== null && actual !== null) {
9915
- return Object.keys(expected).every(key => this.valuesMatch(actual[key], expected[key]));
9916
- }
9917
- return false;
9918
- }
9919
- /**
9920
- * Generate cache key for permission check
9921
- */
9922
- getCacheKey(action, subject, field) {
9923
- const subjectKey = typeof subject === 'object'
9924
- ? JSON.stringify(subject)
9925
- : String(subject);
9926
- return `${action}:${subjectKey}:${field || ''}`;
9927
- }
9928
- }
9929
- /**
9930
- * Create a new Ability instance
9931
- */
9932
- function createAbility(rules = []) {
9933
- return new AbilityCore(rules);
9934
- }
9935
-
9936
- /**
9937
- * Permission Context
9938
- */
9939
- const PermissionContext = React.createContext(null);
9940
- /**
9941
- * Permission Provider Component
9942
- */
9943
- const PermissionProvider = ({ rules = [], user, children, dev = {} }) => {
9944
- const [ability] = React.useState(() => createAbility(rules));
9945
- const [currentUser, setCurrentUser] = React.useState(user);
9946
- const updateAbility = React.useCallback((newRules) => {
9947
- ability.update(newRules);
9948
- }, [ability]);
9949
- const can = React.useCallback((action, subject, field) => {
9950
- const result = ability.can(action, subject, field);
9951
- if (dev.logChecks) {
9952
- console.log(`[Permissions] Can ${action} ${subject}${field ? `.${field}` : ''}:`, result);
9953
- }
9954
- return result;
9955
- }, [ability, dev.logChecks]);
9956
- const cannot = React.useCallback((action, subject, field) => {
9957
- const result = ability.cannot(action, subject, field);
9958
- if (dev.logChecks) {
9959
- console.log(`[Permissions] Cannot ${action} ${subject}${field ? `.${field}` : ''}:`, result);
9960
- }
9961
- return result;
9962
- }, [ability, dev.logChecks]);
9963
- const setUser = React.useCallback((newUser) => {
9964
- setCurrentUser(newUser);
9965
- }, []);
9966
- const contextValue = React.useMemo(() => ({
9967
- ability,
9968
- updateAbility,
9969
- can,
9970
- cannot,
9971
- user: currentUser,
9972
- setUser
9973
- }), [ability, updateAbility, can, cannot, currentUser, setUser]);
9974
- return React.createElement(PermissionContext.Provider, { value: contextValue }, children);
9975
- };
9976
- /**
9977
- * Hook to access permission context
9978
- */
9979
- const usePermissions = (options = {}) => {
9980
- const context = React.useContext(PermissionContext);
9981
- if (!context) {
9982
- if (options.required) {
9983
- throw new Error('usePermissions must be used within a PermissionProvider');
9984
- }
9985
- if (options.debug) {
9986
- console.warn('[Permissions] usePermissions called outside of PermissionProvider');
9987
- }
9988
- // Return a fallback context that allows everything
9989
- return {
9990
- ability: createAbility([{ action: '*', subject: '*' }]),
9991
- updateAbility: () => { },
9992
- can: () => true,
9993
- cannot: () => false,
9994
- user: null,
9995
- setUser: () => { }
9996
- };
9997
- }
9998
- return context;
9999
- };
10000
- /**
10001
- * Hook to get the current ability instance
10002
- */
10003
- const useAbility = () => {
10004
- const { ability } = usePermissions();
10005
- return ability;
10006
- };
10007
-
10008
- /**
10009
- * Can Component - Renders children if permission is granted
10010
- */
10011
- const Can = ({ I: action, a: subject, field, children, fallback = null, ability: customAbility, style, testID, passthrough = false }) => {
10012
- const { ability: contextAbility } = usePermissions();
10013
- const ability = customAbility || contextAbility;
10014
- // Development passthrough
10015
- if (passthrough && __DEV__) {
10016
- return React.createElement(reactNative.View, { style, testID }, children);
10017
- }
10018
- const hasPermission = subject
10019
- ? ability.can(action, subject, field)
10020
- : ability.can(action, '*', field);
10021
- if (hasPermission) {
10022
- return React.createElement(reactNative.View, { style, testID }, children);
10023
- }
10024
- return React.createElement(reactNative.View, { style, testID }, fallback);
10025
- };
10026
- /**
10027
- * Can Component with conditions - For object-level permissions
10028
- */
10029
- const CanWithConditions = ({ I: action, this: subject, field, children, fallback = null, ability: customAbility, style, testID, passthrough = false }) => {
10030
- const { ability: contextAbility } = usePermissions();
10031
- const ability = customAbility || contextAbility;
10032
- // Development passthrough
10033
- if (passthrough && __DEV__) {
10034
- return React.createElement(reactNative.View, { style, testID }, children);
10035
- }
10036
- const hasPermission = ability.can(action, subject, field);
10037
- if (hasPermission) {
10038
- return React.createElement(reactNative.View, { style, testID }, children);
10039
- }
10040
- return React.createElement(reactNative.View, { style, testID }, fallback);
10041
- };
10042
- /**
10043
- * Cannot Component - Renders children if permission is NOT granted
10044
- */
10045
- const Cannot = ({ I: action, a: subject, field, children, fallback = null, ability: customAbility, style, testID, passthrough = false }) => {
10046
- const { ability: contextAbility } = usePermissions();
10047
- const ability = customAbility || contextAbility;
10048
- // Development passthrough
10049
- if (passthrough && __DEV__) {
10050
- return React.createElement(reactNative.View, { style, testID }, fallback);
10051
- }
10052
- const hasPermission = subject
10053
- ? ability.can(action, subject, field)
10054
- : ability.can(action, '*', field);
10055
- if (!hasPermission) {
10056
- return React.createElement(reactNative.View, { style, testID }, children);
10057
- }
10058
- return React.createElement(reactNative.View, { style, testID }, fallback);
10059
- };
10060
- /**
10061
- * Permission Gate - Requires ALL permissions to pass
10062
- */
10063
- const PermissionGate = ({ permissions, children, fallback = null, ability: customAbility, onUnauthorized }) => {
10064
- const { ability: contextAbility } = usePermissions();
10065
- const ability = customAbility || contextAbility;
10066
- const allPermissionsGranted = permissions.every(({ action, subject, field }) => ability.can(action, subject, field));
10067
- React.useEffect(() => {
10068
- if (!allPermissionsGranted && onUnauthorized) {
10069
- onUnauthorized();
10070
- }
10071
- }, [allPermissionsGranted, onUnauthorized]);
10072
- if (allPermissionsGranted) {
10073
- return React.createElement(React.Fragment, null, children);
10074
- }
10075
- return React.createElement(React.Fragment, null, fallback);
10076
- };
10077
- /**
10078
- * Higher-Order Component for permission checking
10079
- */
10080
- function withCan(action, subject, field) {
10081
- return function CanHOC(Component) {
10082
- const WrappedComponent = (props) => {
10083
- const { fallback, ...componentProps } = props;
10084
- return React.createElement(Can, { I: action, a: subject, field, fallback }, React.createElement(Component, componentProps));
10085
- };
10086
- WrappedComponent.displayName = `withCan(${Component.displayName || Component.name})`;
10087
- return WrappedComponent;
10088
- };
10089
- }
10090
- /**
10091
- * Higher-Order Component for permission denial checking
10092
- */
10093
- function withCannot(action, subject, field) {
10094
- return function CannotHOC(Component) {
10095
- const WrappedComponent = (props) => {
10096
- const { fallback, ...componentProps } = props;
10097
- return React.createElement(Cannot, { I: action, a: subject, field, fallback }, React.createElement(Component, componentProps));
10098
- };
10099
- WrappedComponent.displayName = `withCannot(${Component.displayName || Component.name})`;
10100
- return WrappedComponent;
10101
- };
10102
- }
10103
-
10104
- /**
10105
- * Fluent API for building permissions
10106
- */
10107
- class PermissionBuilder {
10108
- constructor() {
10109
- this.rules = [];
10110
- }
10111
- /**
10112
- * Grant permission
10113
- */
10114
- allow(action, subject, field) {
10115
- this.rules.push({
10116
- action,
10117
- subject: subject || '*',
10118
- fields: field ? [field] : undefined,
10119
- inverted: false
10120
- });
10121
- return this;
10122
- }
10123
- /**
10124
- * Deny permission
10125
- */
10126
- forbid(action, subject, field) {
10127
- this.rules.push({
10128
- action,
10129
- subject: subject || '*',
10130
- fields: field ? [field] : undefined,
10131
- inverted: true
10132
- });
10133
- return this;
10134
- }
10135
- /**
10136
- * Conditional permission
10137
- */
10138
- allowIf(action, subject, conditions, field) {
10139
- this.rules.push({
10140
- action,
10141
- subject: subject || '*',
10142
- fields: field ? [field] : undefined,
10143
- inverted: false,
10144
- conditions
10145
- });
10146
- return this;
10147
- }
10148
- /**
10149
- * Conditional denial
10150
- */
10151
- forbidIf(action, subject, conditions, field) {
10152
- this.rules.push({
10153
- action,
10154
- subject: subject || '*',
10155
- fields: field ? [field] : undefined,
10156
- inverted: true,
10157
- conditions
10158
- });
10159
- return this;
10160
- }
10161
- /**
10162
- * Grant all actions on a subject
10163
- */
10164
- manage(subject) {
10165
- this.rules.push({
10166
- action: '*',
10167
- subject,
10168
- inverted: false
10169
- });
10170
- return this;
10171
- }
10172
- /**
10173
- * Forbid all actions on a subject
10174
- */
10175
- forbidAll(subject) {
10176
- this.rules.push({
10177
- action: '*',
10178
- subject,
10179
- inverted: true
10180
- });
10181
- return this;
10182
- }
10183
- /**
10184
- * Role-based permissions
10185
- */
10186
- role(roleName, callback) {
10187
- const roleBuilder = new RoleBuilder(roleName);
10188
- callback(roleBuilder);
10189
- this.rules.push(...roleBuilder.getRules());
10190
- return this;
10191
- }
10192
- /**
10193
- * Build the ability with all rules
10194
- */
10195
- build() {
10196
- return new AbilityCore(this.rules);
10197
- }
10198
- /**
10199
- * Get all rules
10200
- */
10201
- getRules() {
10202
- return [...this.rules];
10203
- }
10204
- /**
10205
- * Clear all rules
10206
- */
10207
- clear() {
10208
- this.rules = [];
10209
- return this;
10210
- }
10211
- /**
10212
- * Merge rules from another builder
10213
- */
10214
- merge(other) {
10215
- this.rules.push(...other.getRules());
10216
- return this;
10217
- }
10218
- }
10219
- /**
10220
- * Role-specific permission builder
10221
- */
10222
- class RoleBuilder {
10223
- constructor(roleName) {
10224
- this.roleName = roleName;
10225
- this.rules = [];
10226
- }
10227
- /**
10228
- * Grant permission for this role
10229
- */
10230
- can(action, subject, field) {
10231
- this.rules.push({
10232
- action,
10233
- subject: subject || '*',
10234
- fields: field ? [field] : undefined,
10235
- inverted: false,
10236
- conditions: { role: this.roleName }
10237
- });
10238
- return this;
10239
- }
10240
- /**
10241
- * Deny permission for this role
10242
- */
10243
- cannot(action, subject, field) {
10244
- this.rules.push({
10245
- action,
10246
- subject: subject || '*',
10247
- fields: field ? [field] : undefined,
10248
- inverted: true,
10249
- conditions: { role: this.roleName }
10250
- });
10251
- return this;
10252
- }
10253
- /**
10254
- * Manage all actions on subject for this role
10255
- */
10256
- manage(subject) {
10257
- this.rules.push({
10258
- action: '*',
10259
- subject,
10260
- inverted: false,
10261
- conditions: { role: this.roleName }
10262
- });
10263
- return this;
10264
- }
10265
- /**
10266
- * Get all rules for this role
10267
- */
10268
- getRules() {
10269
- return [...this.rules];
10270
- }
10271
- }
10272
- /**
10273
- * Common permission patterns
10274
- */
10275
- class PermissionPatterns {
10276
- /**
10277
- * Admin permissions - can do everything
10278
- */
10279
- static admin() {
10280
- return new PermissionBuilder()
10281
- .manage('*');
10282
- }
10283
- /**
10284
- * User permissions - basic CRUD on own resources
10285
- */
10286
- static user(userId) {
10287
- return new PermissionBuilder()
10288
- .allowIf('read', 'User', { id: userId })
10289
- .allowIf('update', 'User', { id: userId })
10290
- .allowIf('delete', 'User', { id: userId })
10291
- .allow('read', 'public');
10292
- }
10293
- /**
10294
- * Guest permissions - read-only public content
10295
- */
10296
- static guest() {
10297
- return new PermissionBuilder()
10298
- .allow('read', 'public');
10299
- }
10300
- /**
10301
- * Moderator permissions - manage content but not users
10302
- */
10303
- static moderator() {
10304
- return new PermissionBuilder()
10305
- .manage('Content')
10306
- .manage('Comment')
10307
- .allow('read', 'User')
10308
- .forbid('delete', 'User');
10309
- }
10310
- /**
10311
- * Owner permissions - full control over owned resources
10312
- */
10313
- static owner(ownerId) {
10314
- return new PermissionBuilder()
10315
- .allowIf('*', '*', { ownerId })
10316
- .allow('create', '*');
10317
- }
10318
- }
10319
- /**
10320
- * Helper function to create a new permission builder
10321
- */
10322
- function permissions() {
10323
- return new PermissionBuilder();
10324
- }
10325
- /**
10326
- * Helper function to create ability from rules array
10327
- */
10328
- function defineAbility(callback) {
10329
- const builder = new PermissionBuilder();
10330
- callback(builder);
10331
- return builder.build();
10332
- }
10333
- /**
10334
- * Helper function to create common role-based abilities
10335
- */
10336
- function defineRoleAbility(role, callback) {
10337
- const roleBuilder = new RoleBuilder(role);
10338
- callback(roleBuilder);
10339
- return new AbilityCore(roleBuilder.getRules());
10340
- }
10341
-
10342
9778
  const ThemeModeContext = React.createContext(null);
10343
9779
  // Default persistence using localStorage (web only)
10344
9780
  const defaultPersistence = {
@@ -10468,7 +9904,6 @@ const OverlayBoundary = React.memo(function OverlayBoundary({ enabled, children
10468
9904
  const I18nBoundary = React.memo(function I18nBoundary({ locale, fallbackLocale, resources, children }) {
10469
9905
  return (jsxRuntime.jsx(I18nProvider, { initial: { locale, fallbackLocale, resources }, children: children }));
10470
9906
  });
10471
- const DEFAULT_PERMISSION_RULES = [{ action: '*', subject: '*' }];
10472
9907
  /**
10473
9908
  * Internal component that uses the enhanced theme mode when config is provided
10474
9909
  */
@@ -10506,30 +9941,20 @@ function PlatformBlocksContent({ children, theme, inherit = true, withCSSVariabl
10506
9941
  document.documentElement.setAttribute('data-platform-blocks-color-scheme', target);
10507
9942
  }
10508
9943
  }, [effectiveColorScheme, osColorScheme]);
10509
- const mainContent = (jsxRuntime.jsxs(ThemeBoundary, { theme: resolvedTheme, inherit: inherit, withCSSVariables: withCSSVariables, cssVariablesSelector: cssVariablesSelector, withGlobalCSS: withGlobalCSS, children: [children, withSpotlight && jsxRuntime.jsx(SpotlightController, { config: spotlightConfig })] }));
10510
- return (jsxRuntime.jsx(OverlayBoundary, { enabled: withOverlays, children: mainContent }));
9944
+ const mainContent = (jsxRuntime.jsx(ThemeBoundary, { theme: resolvedTheme, inherit: inherit, withCSSVariables: withCSSVariables, cssVariablesSelector: cssVariablesSelector, withGlobalCSS: withGlobalCSS, children: jsxRuntime.jsxs(OverlayBoundary, { enabled: withOverlays, children: [children, withSpotlight && jsxRuntime.jsx(SpotlightController, { config: spotlightConfig })] }) }));
9945
+ return mainContent;
10511
9946
  }
10512
9947
  /**
10513
9948
  * Main provider component for Platform Blocks library
10514
9949
  * Provides theme context and injects CSS variables
10515
9950
  */
10516
- function PlatformBlocksProvider({ children, theme, inherit = true, withCSSVariables = true, cssVariablesSelector = ':root', colorSchemeMode = 'auto', withOverlays = true, withSpotlight = false, withGlobalCSS = true, themeModeConfig, spotlightConfig, locale = 'en', fallbackLocale = 'en', i18nResources, direction, haptics, permissions }) {
9951
+ function PlatformBlocksProvider({ children, theme, inherit = true, withCSSVariables = true, cssVariablesSelector = ':root', colorSchemeMode = 'auto', withOverlays = true, withSpotlight = false, withGlobalCSS = true, themeModeConfig, spotlightConfig, locale = 'en', fallbackLocale = 'en', i18nResources, direction, haptics }) {
10517
9952
  const i18nStore = React.useMemo(() => i18nResources || { en: { translation: {} } }, [i18nResources]);
10518
9953
  const content = (jsxRuntime.jsx(PlatformBlocksContent, { theme: theme, inherit: inherit, withCSSVariables: withCSSVariables, cssVariablesSelector: cssVariablesSelector, colorSchemeMode: colorSchemeMode, withOverlays: withOverlays, withSpotlight: withSpotlight, withGlobalCSS: withGlobalCSS, spotlightConfig: spotlightConfig, themeModeConfig: themeModeConfig, children: children }));
10519
9954
  const themedTree = themeModeConfig ? (jsxRuntime.jsx(ThemeModeProvider, { config: themeModeConfig, children: content })) : (content);
10520
9955
  const directionConfig = direction === false ? null : (direction !== null && direction !== void 0 ? direction : {});
10521
9956
  const hapticsConfig = haptics === false ? null : (haptics !== null && haptics !== void 0 ? haptics : {});
10522
- const permissionConfig = permissions === false ? null : (() => {
10523
- const base = { ...(permissions !== null && permissions !== void 0 ? permissions : {}) };
10524
- if (base.rules === undefined) {
10525
- base.rules = DEFAULT_PERMISSION_RULES;
10526
- }
10527
- return base;
10528
- })();
10529
9957
  let enhancedTree = themedTree;
10530
- if (permissionConfig) {
10531
- enhancedTree = (jsxRuntime.jsx(PermissionProvider, { ...permissionConfig, children: enhancedTree }));
10532
- }
10533
9958
  if (hapticsConfig) {
10534
9959
  enhancedTree = (jsxRuntime.jsx(HapticsProvider, { ...hapticsConfig, children: enhancedTree }));
10535
9960
  }
@@ -11019,14 +10444,18 @@ function usePopoverPositioning(isOpen, options = {}) {
11019
10444
  // Get popover dimensions
11020
10445
  // Always use measureElement for robustness across platforms (RNW refs may not expose getBoundingClientRect)
11021
10446
  let popoverDimensions = { width: 200, height: 100 }; // sensible defaults for initial calculation
10447
+ let hasMeasuredPopover = false;
11022
10448
  if (popoverRef.current) {
11023
10449
  const popoverRect = await measureElement(popoverRef);
11024
10450
  if (popoverRect.width > 0 && popoverRect.height > 0) {
11025
10451
  popoverDimensions = { width: popoverRect.width, height: popoverRect.height };
10452
+ hasMeasuredPopover = true;
11026
10453
  }
11027
10454
  }
11028
10455
  // Calculate optimal position
11029
10456
  const result = calculateOverlayPositionEnhanced(anchorRect, popoverDimensions, positioningOptionsRef.current);
10457
+ // Mark whether this position is based on actual measurements
10458
+ result._hasMeasuredPopover = hasMeasuredPopover;
11030
10459
  setPosition(result);
11031
10460
  }
11032
10461
  catch (error) {
@@ -12076,7 +11505,7 @@ function AppShellBase(props, ref) {
12076
11505
  const breakpoint = useBreakpoint();
12077
11506
  // Determine if mobile based on breakpoint and platform
12078
11507
  const isMobile = reactNative.Platform.OS !== 'web' || breakpoint === 'xs' || breakpoint === 'sm';
12079
- const headerConfig = layoutVisibility.header && !isMobile ? header : undefined;
11508
+ const headerConfig = layoutVisibility.header ? header : undefined;
12080
11509
  const navbarConfig = layoutVisibility.navbar ? navbar : undefined;
12081
11510
  const asideConfig = layoutVisibility.aside ? aside : undefined;
12082
11511
  const footerConfig = layoutVisibility.footer ? footer : undefined;
@@ -17168,9 +16597,7 @@ const createInputStyles = (theme, isRTL = false) => {
17168
16597
  ? theme.colors.error[5]
17169
16598
  : props.focused
17170
16599
  ? theme.colors.primary[5]
17171
- : props.disabled
17172
- ? theme.backgrounds.border
17173
- : 'transparent',
16600
+ : theme.backgrounds.border,
17174
16601
  // Optional focus shadow (web only) without affecting layout
17175
16602
  ...(props.focused && !props.disabled && typeof window !== 'undefined' && ((_a = theme.states) === null || _a === void 0 ? void 0 : _a.focusRing) && {
17176
16603
  boxShadow: `0 0 0 2px ${theme.states.focusRing}`,
@@ -17279,6 +16706,7 @@ const TextInputBase = factory((props, ref) => {
17279
16706
  const { value, onChangeText, onEnter, label, description, error, helperText, disabled, required, size = 'md', withAsterisk, placeholder, startSection, endSection, focused: focusedProp, accessibilityLabel, accessibilityHint, testID, textInputProps, style, radius, secureTextEntry, clearable, clearButtonLabel, onClear, inputRef, name, keyboardFocusId, ...rest } = otherProps;
17280
16707
  const renderDisclaimer = useDisclaimer(disclaimerData.disclaimer, disclaimerData.disclaimerProps);
17281
16708
  const [focused, setFocused] = React.useState(false);
16709
+ const [cursorVisible, setCursorVisible] = React.useState(true);
17282
16710
  const theme = useTheme();
17283
16711
  const { isRTL } = useDirection();
17284
16712
  const internalInputRef = React.useRef(null);
@@ -17350,6 +16778,16 @@ const TextInputBase = factory((props, ref) => {
17350
16778
  return '';
17351
16779
  return '•'.repeat(length);
17352
16780
  }, [isSecureEntry, normalizedValue]);
16781
+ // Blinking cursor for secure entry (simple interval toggle)
16782
+ React.useEffect(() => {
16783
+ if (focused && isSecureEntry) {
16784
+ setCursorVisible(true);
16785
+ const interval = setInterval(() => {
16786
+ setCursorVisible(v => !v);
16787
+ }, 530);
16788
+ return () => clearInterval(interval);
16789
+ }
16790
+ }, [focused, isSecureEntry]);
17353
16791
  const textColor = (_a = flattenedInputStyle === null || flattenedInputStyle === void 0 ? void 0 : flattenedInputStyle.color) !== null && _a !== void 0 ? _a : (styleProps.disabled ? theme.text.disabled : theme.text.primary);
17354
16792
  const resolvedInputStyle = React.useMemo(() => {
17355
16793
  const base = [styles.input];
@@ -17451,7 +16889,12 @@ const TextInputBase = factory((props, ref) => {
17451
16889
  }
17452
16890
  }, [keyboardManager, pendingFocusTarget, focusTargetId]);
17453
16891
  const disclaimerNode = renderDisclaimer();
17454
- return (jsxRuntime.jsxs(reactNative.View, { style: [styles.container, spacingStyles, layoutStyles, style], ...rest, children: [jsxRuntime.jsx(FieldHeader, { label: label, description: description, required: required, withAsterisk: withAsterisk, disabled: disabled, error: !!error, size: size }), jsxRuntime.jsxs(reactNative.View, { style: styles.inputContainer, children: [startSection && (jsxRuntime.jsx(reactNative.View, { style: styles.startSection, children: startSection })), jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, position: 'relative', justifyContent: 'center' }, children: [jsxRuntime.jsx(reactNative.TextInput, { ref: assignInputRef, value: value, onChangeText: onChangeText, onFocus: handleFocus, onBlur: handleBlur, onSubmitEditing: handleSubmitEditing, editable: !disabled, placeholder: placeholder, placeholderTextColor: theme.text.muted, style: resolvedInputStyle, selectionColor: selectionColorProp !== null && selectionColorProp !== void 0 ? selectionColorProp : textColor, testID: testID, secureTextEntry: isSecureEntry, ...inputAccessibilityProps, ...restTextInputProps }), isSecureEntry && maskedValue.length > 0 && (jsxRuntime.jsx(reactNative.Text, { pointerEvents: "none", accessible: false, style: overlayStyle, numberOfLines: 1, ellipsizeMode: "clip", children: maskedValue }))] }), (showClearButton || endSection) && (jsxRuntime.jsxs(reactNative.View, { style: styles.endSection, children: [showClearButton && (jsxRuntime.jsx(ClearButton, { onPress: handleClear, size: size, accessibilityLabel: clearButtonLabelText, hasRightSection: !!endSection })), endSection] }))] }), disclaimerNode, error && (jsxRuntime.jsx(reactNative.Text, { style: styles.error, role: "alert", accessibilityLiveRegion: "polite", children: error })), helperText && !error && (jsxRuntime.jsx(reactNative.Text, { style: styles.helperText, children: helperText }))] }));
16892
+ return (jsxRuntime.jsxs(reactNative.View, { style: [styles.container, spacingStyles, layoutStyles, style], ...rest, children: [jsxRuntime.jsx(FieldHeader, { label: label, description: description, required: required, withAsterisk: withAsterisk, disabled: disabled, error: !!error, size: size }), jsxRuntime.jsxs(reactNative.View, { style: styles.inputContainer, children: [startSection && (jsxRuntime.jsx(reactNative.View, { style: styles.startSection, children: startSection })), jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, position: 'relative', justifyContent: 'center' }, children: [jsxRuntime.jsx(reactNative.TextInput, { ref: assignInputRef, value: value, onChangeText: onChangeText, onFocus: handleFocus, onBlur: handleBlur, onSubmitEditing: handleSubmitEditing, editable: !disabled, placeholder: placeholder, placeholderTextColor: theme.text.muted, style: resolvedInputStyle, selectionColor: selectionColorProp !== null && selectionColorProp !== void 0 ? selectionColorProp : textColor, testID: testID, secureTextEntry: isSecureEntry, ...inputAccessibilityProps, ...restTextInputProps }), isSecureEntry && (jsxRuntime.jsxs(reactNative.View, { pointerEvents: "none", style: [overlayStyle, { flexDirection: 'row', alignItems: 'center' }], children: [jsxRuntime.jsx(reactNative.Text, { accessible: false, style: { color: textColor, fontSize: styles.input.fontSize, fontFamily: theme.fontFamily }, numberOfLines: 1, children: maskedValue }), focused && cursorVisible && (jsxRuntime.jsx(reactNative.View, { style: {
16893
+ width: 1,
16894
+ height: styles.input.fontSize || 16,
16895
+ backgroundColor: textColor,
16896
+ marginLeft: 1,
16897
+ } }))] }))] }), (showClearButton || endSection) && (jsxRuntime.jsxs(reactNative.View, { style: styles.endSection, children: [showClearButton && (jsxRuntime.jsx(ClearButton, { onPress: handleClear, size: size, accessibilityLabel: clearButtonLabelText, hasRightSection: !!endSection })), endSection] }))] }), disclaimerNode, error && (jsxRuntime.jsx(reactNative.Text, { style: styles.error, role: "alert", accessibilityLiveRegion: "polite", children: error })), helperText && !error && (jsxRuntime.jsx(reactNative.Text, { style: styles.helperText, children: helperText }))] }));
17455
16898
  });
17456
16899
 
17457
16900
  const getInputTypeConfig = (type) => {
@@ -18009,18 +17452,19 @@ const useTextAreaStyles = (props) => {
18009
17452
  ? theme.colors.error[5]
18010
17453
  : styleProps.focused
18011
17454
  ? theme.colors.primary[5]
18012
- : styleProps.disabled
18013
- ? theme.backgrounds.border
18014
- : 'transparent',
17455
+ : theme.backgrounds.border,
18015
17456
  borderRadius: DESIGN_TOKENS.radius.lg,
18016
- borderWidth: DESIGN_TOKENS.radius.xs,
17457
+ borderWidth: 2,
18017
17458
  paddingHorizontal: DESIGN_TOKENS.spacing.sm,
18018
17459
  paddingVertical: DESIGN_TOKENS.spacing.xs,
17460
+ // Match Input focus treatment on web
18019
17461
  ...(styleProps.focused && !styleProps.disabled && reactNative.Platform.OS === 'web' && {
18020
17462
  boxShadow: `0 0 0 2px ${((_a = theme.states) === null || _a === void 0 ? void 0 : _a.focusRing) || theme.colors.primary[2]}`,
18021
17463
  }),
17464
+ // Light elevation similar to Input
18022
17465
  ...(!styleProps.disabled && theme.colorScheme === 'light' && {
18023
17466
  elevation: 1,
17467
+ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)',
18024
17468
  }),
18025
17469
  opacity: styleProps.disabled ? DESIGN_TOKENS.opacity.disabled : 1,
18026
17470
  },
@@ -19702,7 +19146,7 @@ const useSwitchStyles = (props) => {
19702
19146
  ...(reactNative.Platform.OS === 'web' && { userSelect: 'none' }),
19703
19147
  },
19704
19148
  labelContainer: {
19705
- flex: 1,
19149
+ flexShrink: 1,
19706
19150
  justifyContent: 'center',
19707
19151
  },
19708
19152
  labelDisabled: {
@@ -19871,8 +19315,8 @@ const Switch = factory((rawProps, ref) => {
19871
19315
  const LayoutComponent = isVertical ? Column : Row;
19872
19316
  // For vertical layouts (top/bottom), we want tighter spacing and center alignment
19873
19317
  const layoutProps = isVertical
19874
- ? { gap: 'xs', style: { alignItems: 'center' } }
19875
- : { gap: 'sm', style: { alignItems: 'center' } };
19318
+ ? { gap: 'xs', align: 'center' }
19319
+ : { gap: 'sm', align: 'center' };
19876
19320
  const disclaimerNode = renderDisclaimer();
19877
19321
  return (jsxRuntime.jsxs(reactNative.View, { style: spacingStyles, children: [jsxRuntime.jsxs(LayoutComponent, { ...layoutProps, children: [labelPosition === 'top' && labelElement, labelPosition === 'left' && labelElement, switchElement, labelPosition === 'right' && labelElement, labelPosition === 'bottom' && labelElement] }), disclaimerNode ? (jsxRuntime.jsx(reactNative.View, { style: { width: '100%' }, children: disclaimerNode })) : null] }));
19878
19322
  });
@@ -21067,105 +20511,116 @@ const useSliderGesture = (min, max, step, restrictToTicks, ticks, disabled) => {
21067
20511
  }, [min, max, step, restrictToTicks, ticks]);
21068
20512
  return { calculateNewValue };
21069
20513
  };
21070
- const SliderTrack = ({ disabled, theme, size, orientation, activeWidth = 0, activeLeft = SLIDER_CONSTANTS.THUMB_SIZE[size] / 2, isRange = false }) => {
20514
+ const SliderTrack = ({ disabled, theme, size, orientation, activeWidth = 0, activeLeft, isRange = false, trackColor, activeTrackColor, trackStyle, activeTrackStyle, trackHeight, thumbSize, }) => {
21071
20515
  const orientationProps = getOrientationProps(orientation);
21072
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[size];
21073
- const trackHeight = SLIDER_CONSTANTS.TRACK_HEIGHT[size];
21074
- const baseTrackStyle = {
20516
+ const resolvedThumbSize = thumbSize !== null && thumbSize !== void 0 ? thumbSize : SLIDER_CONSTANTS.THUMB_SIZE[size];
20517
+ const resolvedTrackHeight = trackHeight !== null && trackHeight !== void 0 ? trackHeight : SLIDER_CONSTANTS.TRACK_HEIGHT[size];
20518
+ const resolvedActiveLeft = activeLeft !== null && activeLeft !== void 0 ? activeLeft : (resolvedThumbSize / 2);
20519
+ const inactiveTrackBaseStyle = {
21075
20520
  position: 'absolute',
21076
- backgroundColor: disabled ? theme.colors.gray[2] : theme.colors.gray[3],
21077
- borderRadius: trackHeight / 2,
20521
+ backgroundColor: disabled && !trackColor ? theme.colors.gray[2] : (trackColor !== null && trackColor !== void 0 ? trackColor : theme.colors.gray[3]),
20522
+ borderRadius: resolvedTrackHeight / 2,
21078
20523
  };
21079
- const activeTrackStyle = {
20524
+ const activeTrackBaseStyle = {
21080
20525
  position: 'absolute',
21081
- backgroundColor: disabled ? theme.colors.gray[4] : theme.colors.primary[5],
21082
- borderRadius: trackHeight / 2,
20526
+ backgroundColor: disabled && !activeTrackColor ? theme.colors.gray[4] : (activeTrackColor !== null && activeTrackColor !== void 0 ? activeTrackColor : theme.colors.primary[5]),
20527
+ borderRadius: resolvedTrackHeight / 2,
21083
20528
  };
21084
20529
  if (orientationProps.isVertical) {
21085
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactNative.View, { style: {
21086
- ...baseTrackStyle,
21087
- top: thumbSize / 2,
21088
- bottom: thumbSize / 2,
21089
- width: trackHeight,
21090
- left: (thumbSize - trackHeight) / 2,
21091
- } }), activeWidth > 0 && (jsxRuntime.jsx(reactNative.View, { style: {
21092
- ...activeTrackStyle,
21093
- // For range sliders, use activeLeft as top position; for single sliders, start from bottom
21094
- ...(isRange ? {
21095
- top: activeLeft,
21096
- height: activeWidth,
21097
- } : {
21098
- bottom: thumbSize / 2,
21099
- height: activeWidth,
21100
- }),
21101
- width: trackHeight,
21102
- left: (thumbSize - trackHeight) / 2,
21103
- } }))] }));
21104
- }
21105
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactNative.View, { style: {
21106
- ...baseTrackStyle,
21107
- left: thumbSize / 2,
21108
- right: thumbSize / 2,
21109
- height: trackHeight,
21110
- top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - trackHeight) / 2,
21111
- } }), activeWidth > 0 && (jsxRuntime.jsx(reactNative.View, { style: {
21112
- ...activeTrackStyle,
21113
- left: activeLeft,
21114
- width: activeWidth,
21115
- height: trackHeight,
21116
- top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - trackHeight) / 2,
21117
- } }))] }));
21118
- };
21119
- const SliderTicks = ({ ticks, disabled, theme, size, orientation, keyPrefix = 'tick' }) => {
20530
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactNative.View, { style: [
20531
+ {
20532
+ ...inactiveTrackBaseStyle,
20533
+ top: resolvedThumbSize / 2,
20534
+ bottom: resolvedThumbSize / 2,
20535
+ width: resolvedTrackHeight,
20536
+ left: (resolvedThumbSize - resolvedTrackHeight) / 2,
20537
+ },
20538
+ trackStyle,
20539
+ ] }), activeWidth > 0 && (jsxRuntime.jsx(reactNative.View, { style: [
20540
+ {
20541
+ ...activeTrackBaseStyle,
20542
+ ...(isRange ? {
20543
+ top: activeLeft !== null && activeLeft !== void 0 ? activeLeft : resolvedActiveLeft,
20544
+ height: activeWidth,
20545
+ } : {
20546
+ bottom: resolvedThumbSize / 2,
20547
+ height: activeWidth,
20548
+ }),
20549
+ width: resolvedTrackHeight,
20550
+ left: (resolvedThumbSize - resolvedTrackHeight) / 2,
20551
+ },
20552
+ activeTrackStyle,
20553
+ ] }))] }));
20554
+ }
20555
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactNative.View, { style: [
20556
+ {
20557
+ ...inactiveTrackBaseStyle,
20558
+ left: resolvedThumbSize / 2,
20559
+ right: resolvedThumbSize / 2,
20560
+ height: resolvedTrackHeight,
20561
+ top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - resolvedTrackHeight) / 2,
20562
+ },
20563
+ trackStyle,
20564
+ ] }), activeWidth > 0 && (jsxRuntime.jsx(reactNative.View, { style: [
20565
+ {
20566
+ ...activeTrackBaseStyle,
20567
+ left: activeLeft !== null && activeLeft !== void 0 ? activeLeft : resolvedActiveLeft,
20568
+ width: activeWidth,
20569
+ height: resolvedTrackHeight,
20570
+ top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - resolvedTrackHeight) / 2,
20571
+ },
20572
+ activeTrackStyle,
20573
+ ] }))] }));
20574
+ };
20575
+ const SliderTicks = ({ ticks, disabled, theme, size, orientation, keyPrefix = 'tick', trackHeight, thumbSize, activeTickColor, tickColor, }) => {
21120
20576
  const orientationProps = getOrientationProps(orientation);
21121
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[size];
21122
- const trackHeight = SLIDER_CONSTANTS.TRACK_HEIGHT[size];
20577
+ const resolvedThumbSize = thumbSize !== null && thumbSize !== void 0 ? thumbSize : SLIDER_CONSTANTS.THUMB_SIZE[size];
20578
+ const resolvedTrackHeight = trackHeight !== null && trackHeight !== void 0 ? trackHeight : SLIDER_CONSTANTS.TRACK_HEIGHT[size];
20579
+ const inactiveColor = disabled && !tickColor ? theme.colors.gray[2] : (tickColor !== null && tickColor !== void 0 ? tickColor : theme.colors.gray[4]);
20580
+ const activeColor = disabled && !activeTickColor ? theme.colors.gray[4] : (activeTickColor !== null && activeTickColor !== void 0 ? activeTickColor : theme.colors.primary[5]);
21123
20581
  if (orientationProps.isVertical) {
21124
20582
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ticks.map((tick, index) => (jsxRuntime.jsx(reactNative.View, { style: {
21125
20583
  position: 'absolute',
21126
- top: thumbSize / 2 + tick.position,
21127
- left: (thumbSize - trackHeight) / 2 - 3,
20584
+ top: resolvedThumbSize / 2 + tick.position,
20585
+ left: (resolvedThumbSize - resolvedTrackHeight) / 2 - 3,
21128
20586
  height: 2,
21129
- width: trackHeight + 6,
21130
- backgroundColor: tick.isActive
21131
- ? (disabled ? theme.colors.gray[4] : theme.colors.primary[5])
21132
- : (disabled ? theme.colors.gray[2] : theme.colors.gray[4]),
20587
+ width: resolvedTrackHeight + 6,
20588
+ backgroundColor: tick.isActive ? activeColor : inactiveColor,
21133
20589
  borderRadius: 1,
21134
20590
  } }, `${keyPrefix}-${tick.value}-${index}`))), ticks.map((tick, index) => (tick.label ? (jsxRuntime.jsx(reactNative.View, { style: {
21135
20591
  position: 'absolute',
21136
- top: thumbSize / 2 + tick.position - 10,
21137
- left: thumbSize + 8,
20592
+ top: resolvedThumbSize / 2 + tick.position - 10,
20593
+ left: resolvedThumbSize + 8,
21138
20594
  height: 20,
21139
20595
  justifyContent: 'center',
21140
20596
  }, children: jsxRuntime.jsx(Text, { size: "xs", children: tick.label }) }, `${keyPrefix}-label-${tick.value}-${index}`)) : null))] }));
21141
20597
  }
21142
20598
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ticks.map((tick, index) => (jsxRuntime.jsx(reactNative.View, { style: {
21143
20599
  position: 'absolute',
21144
- left: thumbSize / 2 + tick.position,
21145
- top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - trackHeight) / 2 - 3,
20600
+ left: resolvedThumbSize / 2 + tick.position,
20601
+ top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - resolvedTrackHeight) / 2 - 3,
21146
20602
  width: 2,
21147
- height: trackHeight + 6,
21148
- backgroundColor: tick.isActive
21149
- ? (disabled ? theme.colors.gray[4] : theme.colors.primary[5])
21150
- : (disabled ? theme.colors.gray[2] : theme.colors.gray[4]),
20603
+ height: resolvedTrackHeight + 6,
20604
+ backgroundColor: tick.isActive ? activeColor : inactiveColor,
21151
20605
  borderRadius: 1,
21152
20606
  } }, `${keyPrefix}-${tick.value}-${index}`))), ticks.map((tick, index) => (tick.label ? (jsxRuntime.jsx(reactNative.View, { style: {
21153
20607
  position: 'absolute',
21154
- left: thumbSize / 2 + tick.position - 20,
20608
+ left: resolvedThumbSize / 2 + tick.position - 20,
21155
20609
  top: SLIDER_CONSTANTS.CONTAINER_HEIGHT + 8,
21156
20610
  width: 40,
21157
20611
  alignItems: 'center',
21158
20612
  }, children: jsxRuntime.jsx(Text, { size: "xs", style: { textAlign: 'center' }, children: tick.label }) }, `${keyPrefix}-label-${tick.value}-${index}`)) : null))] }));
21159
20613
  };
21160
- const SliderThumb = ({ position, disabled, theme, size, orientation, isDragging, zIndex = 1, panHandlers }) => {
20614
+ const SliderThumb = ({ position, disabled, theme, size, orientation, isDragging, zIndex = 1, panHandlers, thumbColor, thumbStyle, thumbSize, }) => {
21161
20615
  const orientationProps = getOrientationProps(orientation);
21162
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[size];
20616
+ const resolvedThumbSize = thumbSize !== null && thumbSize !== void 0 ? thumbSize : SLIDER_CONSTANTS.THUMB_SIZE[size];
20617
+ const resolvedThumbColor = disabled && !thumbColor ? theme.colors.gray[4] : (thumbColor !== null && thumbColor !== void 0 ? thumbColor : theme.colors.primary[5]);
21163
20618
  const baseStyle = {
21164
20619
  position: 'absolute',
21165
- width: thumbSize,
21166
- height: thumbSize,
21167
- backgroundColor: disabled ? theme.colors.gray[4] : theme.colors.primary[5],
21168
- borderRadius: thumbSize / 2,
20620
+ width: resolvedThumbSize,
20621
+ height: resolvedThumbSize,
20622
+ backgroundColor: resolvedThumbColor,
20623
+ borderRadius: resolvedThumbSize / 2,
21169
20624
  borderWidth: 2,
21170
20625
  borderColor: 'white',
21171
20626
  boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',
@@ -21174,36 +20629,43 @@ const SliderThumb = ({ position, disabled, theme, size, orientation, isDragging,
21174
20629
  zIndex,
21175
20630
  };
21176
20631
  if (orientationProps.isVertical) {
21177
- return (jsxRuntime.jsx(reactNative.View, { style: {
21178
- ...baseStyle,
21179
- top: position,
21180
- left: 0,
21181
- }, ...panHandlers }));
20632
+ return (jsxRuntime.jsx(reactNative.View, { style: [
20633
+ baseStyle,
20634
+ {
20635
+ top: position,
20636
+ left: 0,
20637
+ },
20638
+ thumbStyle,
20639
+ ], ...panHandlers }));
21182
20640
  }
21183
- return (jsxRuntime.jsx(reactNative.View, { style: {
21184
- ...baseStyle,
21185
- left: position,
21186
- top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - thumbSize) / 2,
21187
- }, ...panHandlers }));
20641
+ return (jsxRuntime.jsx(reactNative.View, { style: [
20642
+ baseStyle,
20643
+ {
20644
+ left: position,
20645
+ top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - resolvedThumbSize) / 2,
20646
+ },
20647
+ thumbStyle,
20648
+ ], ...panHandlers }));
21188
20649
  };
21189
20650
  const SliderLabel = ({ label }) => (jsxRuntime.jsx(reactNative.View, { style: { marginBottom: 8 }, children: typeof label === 'string' ? (jsxRuntime.jsx(Text, { size: "sm", weight: "medium", children: label })) : (label) }));
21190
- const SliderValueLabel = ({ value, position, size, orientation, isCard = false }) => {
20651
+ const SliderValueLabel = ({ value, position, size, orientation, isCard = false, thumbSize, }) => {
21191
20652
  const orientationProps = getOrientationProps(orientation);
21192
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[size];
20653
+ const resolvedThumbSize = thumbSize !== null && thumbSize !== void 0 ? thumbSize : SLIDER_CONSTANTS.THUMB_SIZE[size];
21193
20654
  // round number to 2 decimal places for display
21194
20655
  const displayValue = typeof value === 'number' ? value.toFixed(2) : value;
21195
20656
  if (orientationProps.isVertical) {
20657
+ const verticalLabelOffset = resolvedThumbSize + 16; // keep label clear of the thumb
21196
20658
  return (jsxRuntime.jsx(reactNative.View, { style: {
21197
20659
  position: 'absolute',
21198
- top: position + (thumbSize / 2) - 10,
21199
- right: thumbSize + 8,
20660
+ top: position + (resolvedThumbSize / 2) - 10,
20661
+ right: verticalLabelOffset,
21200
20662
  height: 20,
21201
20663
  justifyContent: 'center',
21202
20664
  }, children: isCard ? (jsxRuntime.jsx(Card, { p: "xs", variant: "filled", children: jsxRuntime.jsx(Text, { size: "sm", children: displayValue }) })) : (jsxRuntime.jsx(Text, { size: "sm", children: displayValue })) }));
21203
20665
  }
21204
20666
  return (jsxRuntime.jsx(reactNative.View, { style: {
21205
20667
  position: 'absolute',
21206
- left: position + (thumbSize / 2) - 50,
20668
+ left: position + (resolvedThumbSize / 2) - 50,
21207
20669
  bottom: SLIDER_CONSTANTS.CONTAINER_HEIGHT - 6, // Moved closer to thumb
21208
20670
  width: 100,
21209
20671
  alignItems: 'center',
@@ -21219,9 +20681,34 @@ const SLIDER_SIZE_SCALE = {
21219
20681
  '2xl': 'lg',
21220
20682
  '3xl': 'lg',
21221
20683
  };
20684
+ const resolvePaletteColor = (themeColors, scheme) => {
20685
+ if (!scheme || typeof scheme !== 'string') {
20686
+ return undefined;
20687
+ }
20688
+ const palette = themeColors[scheme];
20689
+ if (Array.isArray(palette)) {
20690
+ return palette;
20691
+ }
20692
+ return undefined;
20693
+ };
20694
+ const resolveSliderColors = (theme, { colorScheme, trackColor, activeTrackColor, thumbColor, tickColor, activeTickColor, }) => {
20695
+ var _a, _b;
20696
+ const palette = resolvePaletteColor(theme.colors, colorScheme);
20697
+ const schemeColor = (_b = (_a = palette === null || palette === void 0 ? void 0 : palette[5]) !== null && _a !== void 0 ? _a : (typeof colorScheme === 'string' ? colorScheme : undefined)) !== null && _b !== void 0 ? _b : theme.colors.primary[5];
20698
+ const resolvedActiveTrack = activeTrackColor !== null && activeTrackColor !== void 0 ? activeTrackColor : schemeColor;
20699
+ const defaultTrackColor = theme.colorScheme === 'dark' ? theme.colors.gray[6] : theme.colors.gray[3];
20700
+ const defaultTickColor = theme.colorScheme === 'dark' ? theme.colors.gray[5] : theme.colors.gray[4];
20701
+ return {
20702
+ trackColor: trackColor !== null && trackColor !== void 0 ? trackColor : defaultTrackColor,
20703
+ activeTrackColor: resolvedActiveTrack,
20704
+ thumbColor: thumbColor !== null && thumbColor !== void 0 ? thumbColor : resolvedActiveTrack,
20705
+ tickColor: tickColor !== null && tickColor !== void 0 ? tickColor : defaultTickColor,
20706
+ activeTickColor: activeTickColor !== null && activeTickColor !== void 0 ? activeTickColor : resolvedActiveTrack,
20707
+ };
20708
+ };
21222
20709
  // Optimized Single Slider Component
21223
20710
  const Slider = factory((props, ref) => {
21224
- const { value, defaultValue = 0, onChange, min = 0, max = 100, step = 1, disabled = false, size = 'md', orientation = 'horizontal', containerSize, fullWidth = true, label, valueLabel, valueLabelAlwaysOn = false, ticks, showTicks = false, restrictToTicks = false, style, ...spacingProps } = props;
20711
+ const { value, defaultValue = 0, onChange, min = 0, max = 100, step = 1, disabled = false, size = 'md', orientation = 'horizontal', containerSize, fullWidth = true, label, valueLabel, valueLabelAlwaysOn = false, ticks, showTicks = false, restrictToTicks = false, trackColor, activeTrackColor, thumbColor, trackSize, thumbSize: thumbSizeProp, colorScheme = 'primary', trackStyle, activeTrackStyle, thumbStyle, tickColor, activeTickColor, style, ...spacingProps } = props;
21225
20712
  const theme = useTheme();
21226
20713
  const [isDragging, setIsDragging] = React.useState(false);
21227
20714
  // Uncontrolled internal value
@@ -21250,14 +20737,31 @@ const Slider = factory((props, ref) => {
21250
20737
  : 'md'
21251
20738
  : (resolvedSliderSize !== null && resolvedSliderSize !== void 0 ? resolvedSliderSize : 'md');
21252
20739
  const orientationProps = getOrientationProps(orientation, containerSize);
21253
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[sliderSize];
20740
+ const thumbSize = thumbSizeProp !== null && thumbSizeProp !== void 0 ? thumbSizeProp : SLIDER_CONSTANTS.THUMB_SIZE[sliderSize];
20741
+ const trackHeight = trackSize !== null && trackSize !== void 0 ? trackSize : SLIDER_CONSTANTS.TRACK_HEIGHT[sliderSize];
21254
20742
  // Memoized processed value
21255
20743
  const clampedValue = useSliderValue(isControlled ? value : internal, min, max, step, restrictToTicks, ticks, false);
21256
20744
  // Memoized value label handling
20745
+ const defaultValueFormatter = React.useCallback((val) => Math.round(val).toString(), []);
20746
+ const resolvedValueLabel = React.useMemo(() => {
20747
+ if (valueLabel === null)
20748
+ return null;
20749
+ if (valueLabel)
20750
+ return valueLabel;
20751
+ return defaultValueFormatter;
20752
+ }, [valueLabel, defaultValueFormatter]);
21257
20753
  const labelConfig = React.useMemo(() => ({
21258
- shouldShow: valueLabel !== null && (valueLabelAlwaysOn || isDragging || (reactNative.Platform.OS === 'web' && isHovering)),
21259
- formatter: valueLabel || ((val) => (Number.isInteger(val) ? val.toString() : val.toFixed(2)))
21260
- }), [valueLabel, valueLabelAlwaysOn, isDragging, isHovering]);
20754
+ shouldShow: !!resolvedValueLabel && (valueLabelAlwaysOn || isDragging || (reactNative.Platform.OS === 'web' && isHovering)),
20755
+ formatter: resolvedValueLabel !== null && resolvedValueLabel !== void 0 ? resolvedValueLabel : defaultValueFormatter,
20756
+ }), [resolvedValueLabel, valueLabelAlwaysOn, isDragging, isHovering, defaultValueFormatter]);
20757
+ const sliderColors = React.useMemo(() => resolveSliderColors(theme, {
20758
+ colorScheme,
20759
+ trackColor,
20760
+ activeTrackColor,
20761
+ thumbColor,
20762
+ tickColor,
20763
+ activeTickColor,
20764
+ }), [theme, colorScheme, trackColor, activeTrackColor, thumbColor, tickColor, activeTickColor]);
21261
20765
  // Memoized position calculations
21262
20766
  const positions = React.useMemo(() => {
21263
20767
  var _a, _b;
@@ -21387,6 +20891,7 @@ const Slider = factory((props, ref) => {
21387
20891
  height: fullWidth && orientation === 'vertical' ? '100%' : orientationProps.containerHeight,
21388
20892
  justifyContent: 'center',
21389
20893
  position: 'relative',
20894
+ ...(reactNative.Platform.OS === 'web' && orientation === 'vertical' ? { touchAction: 'none' } : null),
21390
20895
  }, onLayout: (event) => {
21391
20896
  // When fullWidth is enabled, track the actual container dimensions
21392
20897
  if (fullWidth) {
@@ -21400,11 +20905,11 @@ const Slider = factory((props, ref) => {
21400
20905
  }, onStartShouldSetResponder: () => !isDragging, onResponderGrant: handlePress, ...(reactNative.Platform.OS === 'web' && {
21401
20906
  onMouseEnter: () => setIsHovering(true),
21402
20907
  onMouseLeave: () => setIsHovering(false),
21403
- }), ...panResponder.panHandlers, children: [jsxRuntime.jsx(SliderTrack, { disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, activeWidth: positions.activeLength }), jsxRuntime.jsx(SliderTicks, { ticks: allTicks, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation }), jsxRuntime.jsx(SliderThumb, { position: positions.thumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: isDragging }), labelConfig.shouldShow && (jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(clampedValue), position: positions.thumbPosition, size: sliderSize, orientation: orientation, isCard: true }))] })] }));
20908
+ }), ...panResponder.panHandlers, children: [jsxRuntime.jsx(SliderTrack, { disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, activeWidth: positions.activeLength, trackColor: sliderColors.trackColor, activeTrackColor: sliderColors.activeTrackColor, trackStyle: trackStyle, activeTrackStyle: activeTrackStyle, trackHeight: trackHeight, thumbSize: thumbSize }), jsxRuntime.jsx(SliderTicks, { ticks: allTicks, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, trackHeight: trackHeight, thumbSize: thumbSize, tickColor: sliderColors.tickColor, activeTickColor: sliderColors.activeTickColor }), jsxRuntime.jsx(SliderThumb, { position: positions.thumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: isDragging, thumbColor: sliderColors.thumbColor, thumbStyle: thumbStyle, thumbSize: thumbSize }), labelConfig.shouldShow && (jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(clampedValue), position: positions.thumbPosition, size: sliderSize, orientation: orientation, isCard: true, thumbSize: thumbSize }))] })] }));
21404
20909
  });
21405
20910
  // Optimized Range Slider Component
21406
20911
  const RangeSlider = factory((props, ref) => {
21407
- const { value = [0, 100], onChange, min = 0, max = 100, step = 1, disabled = false, size = 'md', orientation = 'horizontal', containerSize, fullWidth = true, label, valueLabel, valueLabelAlwaysOn = false, ticks, showTicks = false, restrictToTicks = false, pushOnOverlap = true, style, ...spacingProps } = props;
20912
+ const { value = [0, 100], onChange, min = 0, max = 100, step = 1, disabled = false, size = 'md', orientation = 'horizontal', containerSize, fullWidth = true, label, valueLabel, valueLabelAlwaysOn = false, ticks, showTicks = false, restrictToTicks = false, pushOnOverlap = true, trackColor, activeTrackColor, thumbColor, trackSize, thumbSize: thumbSizeProp, colorScheme = 'primary', trackStyle, activeTrackStyle, thumbStyle, tickColor, activeTickColor, style, ...spacingProps } = props;
21408
20913
  const theme = useTheme();
21409
20914
  const [dragState, setDragState] = React.useState({ thumb: null });
21410
20915
  const [isHovering, setIsHovering] = React.useState(false);
@@ -21424,8 +20929,17 @@ const RangeSlider = factory((props, ref) => {
21424
20929
  : 'md'
21425
20930
  : (rangeResolvedSliderSize !== null && rangeResolvedSliderSize !== void 0 ? rangeResolvedSliderSize : 'md');
21426
20931
  const orientationProps = getOrientationProps(orientation, containerSize);
21427
- const thumbSize = SLIDER_CONSTANTS.THUMB_SIZE[sliderSize];
20932
+ const thumbSize = thumbSizeProp !== null && thumbSizeProp !== void 0 ? thumbSizeProp : SLIDER_CONSTANTS.THUMB_SIZE[sliderSize];
20933
+ const trackHeight = trackSize !== null && trackSize !== void 0 ? trackSize : SLIDER_CONSTANTS.TRACK_HEIGHT[sliderSize];
21428
20934
  React.useRef(null);
20935
+ const sliderColors = React.useMemo(() => resolveSliderColors(theme, {
20936
+ colorScheme,
20937
+ trackColor,
20938
+ activeTrackColor,
20939
+ thumbColor,
20940
+ tickColor,
20941
+ activeTickColor,
20942
+ }), [theme, colorScheme, trackColor, activeTrackColor, thumbColor, tickColor, activeTickColor]);
21429
20943
  // Memoized processed values
21430
20944
  const [minValue, maxValue] = useSliderValue(value, min, max, step, restrictToTicks, ticks, true);
21431
20945
  // Memoized backward compatibility handling
@@ -21661,6 +21175,7 @@ const RangeSlider = factory((props, ref) => {
21661
21175
  height: fullWidth && orientation === 'vertical' ? '100%' : orientationProps.containerHeight,
21662
21176
  justifyContent: 'center',
21663
21177
  position: 'relative',
21178
+ ...(reactNative.Platform.OS === 'web' && orientation === 'vertical' ? { touchAction: 'none' } : null),
21664
21179
  }, onLayout: (event) => {
21665
21180
  // When fullWidth is enabled, track the actual container dimensions
21666
21181
  if (fullWidth) {
@@ -21674,7 +21189,7 @@ const RangeSlider = factory((props, ref) => {
21674
21189
  }, onStartShouldSetResponder: () => true, onResponderGrant: handleTrackPress, ...(reactNative.Platform.OS === 'web' && {
21675
21190
  onMouseEnter: () => setIsHovering(true),
21676
21191
  onMouseLeave: () => setIsHovering(false),
21677
- }), collapsable: false, children: [jsxRuntime.jsx(SliderTrack, { disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, activeWidth: positions.activeWidth, activeLeft: positions.activeLeft, isRange: true }), jsxRuntime.jsx(SliderTicks, { ticks: allTicks, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, keyPrefix: "range-tick" }), jsxRuntime.jsx(SliderThumb, { position: positions.minThumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: dragState.thumb === 'min', zIndex: dragState.thumb === 'min' ? 10 : 1, panHandlers: minThumbPanResponder.panHandlers }), jsxRuntime.jsx(SliderThumb, { position: positions.maxThumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: dragState.thumb === 'max', zIndex: dragState.thumb === 'max' ? 10 : 2, panHandlers: maxThumbPanResponder.panHandlers }), labelConfig.shouldShow && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(minValue, 0), position: positions.minThumbPosition, size: sliderSize, orientation: orientation, isCard: true }), jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(maxValue, 1), position: positions.maxThumbPosition, size: sliderSize, orientation: orientation, isCard: true })] }))] })] }));
21192
+ }), collapsable: false, children: [jsxRuntime.jsx(SliderTrack, { disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, activeWidth: positions.activeWidth, activeLeft: positions.activeLeft, isRange: true, trackColor: sliderColors.trackColor, activeTrackColor: sliderColors.activeTrackColor, trackStyle: trackStyle, activeTrackStyle: activeTrackStyle, trackHeight: trackHeight, thumbSize: thumbSize }), jsxRuntime.jsx(SliderTicks, { ticks: allTicks, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, keyPrefix: "range-tick", trackHeight: trackHeight, thumbSize: thumbSize, tickColor: sliderColors.tickColor, activeTickColor: sliderColors.activeTickColor }), jsxRuntime.jsx(SliderThumb, { position: positions.minThumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: dragState.thumb === 'min', zIndex: dragState.thumb === 'min' ? 10 : 1, panHandlers: minThumbPanResponder.panHandlers, thumbColor: sliderColors.thumbColor, thumbStyle: thumbStyle, thumbSize: thumbSize }), jsxRuntime.jsx(SliderThumb, { position: positions.maxThumbPosition, disabled: disabled, theme: theme, size: sliderSize, orientation: orientation, isDragging: dragState.thumb === 'max', zIndex: dragState.thumb === 'max' ? 10 : 2, panHandlers: maxThumbPanResponder.panHandlers, thumbColor: sliderColors.thumbColor, thumbStyle: thumbStyle, thumbSize: thumbSize }), labelConfig.shouldShow && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(minValue, 0), position: positions.minThumbPosition, size: sliderSize, orientation: orientation, isCard: true, thumbSize: thumbSize }), jsxRuntime.jsx(SliderValueLabel, { value: labelConfig.formatter(maxValue, 1), position: positions.maxThumbPosition, size: sliderSize, orientation: orientation, isCard: true, thumbSize: thumbSize })] }))] })] }));
21678
21193
  });
21679
21194
 
21680
21195
  const clampNumber$1 = (value, min, max) => Math.min(max, Math.max(min, value));
@@ -27415,7 +26930,7 @@ const MiniCalendar = ({ value, onChange, defaultValue, numberOfDays = 7, default
27415
26930
  }
27416
26931
  onChange === null || onChange === void 0 ? void 0 : onChange(date);
27417
26932
  }, [isControlled, maxDate, minDate, onChange]);
27418
- return (jsxRuntime.jsxs(reactNative.View, { children: [jsxRuntime.jsxs(Flex, { direction: "row", justify: "space-between", align: "center", style: { marginBottom: 16 }, children: [jsxRuntime.jsx(reactNative.Pressable, { onPress: handlePrevious, style: ({ pressed }) => [
26933
+ return (jsxRuntime.jsxs(reactNative.View, { style: { alignSelf: 'flex-start' }, children: [jsxRuntime.jsxs(Flex, { direction: "row", justify: "space-between", align: "center", style: { marginBottom: 16 }, children: [jsxRuntime.jsx(reactNative.Pressable, { onPress: handlePrevious, style: ({ pressed }) => [
27419
26934
  {
27420
26935
  padding: 8,
27421
26936
  borderRadius: 6,
@@ -27427,7 +26942,7 @@ const MiniCalendar = ({ value, onChange, defaultValue, numberOfDays = 7, default
27427
26942
  borderRadius: 6,
27428
26943
  backgroundColor: pressed ? theme.colors.gray[2] : 'transparent',
27429
26944
  },
27430
- ], ...nextControlProps, children: jsxRuntime.jsx(Icon, { name: "chevron-right", size: 16, color: theme.colors.gray[6] }) })] }), jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: jsxRuntime.jsx(Flex, { direction: "row", gap: 4, children: days.map((date) => {
26945
+ ], ...nextControlProps, children: jsxRuntime.jsx(Icon, { name: "chevron-right", size: 16, color: theme.colors.gray[6] }) })] }), jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, contentContainerStyle: { flexGrow: 0 }, style: { flexGrow: 0 }, children: jsxRuntime.jsx(Flex, { direction: "row", gap: 4, children: days.map((date) => {
27431
26946
  const isSelected = selectedDate ? dateUtils$1.isSameDay(date, selectedDate) : false;
27432
26947
  const isToday = dateUtils$1.isToday(date);
27433
26948
  const isWeekend = dateUtils$1.isWeekend(date);
@@ -30168,6 +29683,7 @@ function MenuBase(props, ref) {
30168
29683
  const overlayId = openOverlay({
30169
29684
  content: menuDropdown,
30170
29685
  anchor: { x: positionResult.x, y: positionResult.y, width: overlaySize.width, height: overlaySize.height },
29686
+ placement: positionResult.placement || position,
30171
29687
  closeOnClickOutside,
30172
29688
  closeOnEscape,
30173
29689
  strategy,
@@ -31568,13 +31084,13 @@ function Indicator({ size = 'sm', color, borderColor, borderWidth = 1, placement
31568
31084
 
31569
31085
  const AVATAR_ALLOWED_SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'];
31570
31086
  const AVATAR_SIZE_SCALE = {
31571
- xs: { avatar: 24, badge: 6, text: 'xs' },
31572
- sm: { avatar: 32, badge: 8, text: 'xs' },
31573
- md: { avatar: 40, badge: 10, text: 'sm' },
31574
- lg: { avatar: 48, badge: 12, text: 'md' },
31575
- xl: { avatar: 64, badge: 16, text: 'lg' },
31576
- '2xl': { avatar: 80, badge: 20, text: 'xl' },
31577
- '3xl': { avatar: 96, badge: 24, text: '2xl' },
31087
+ xs: { avatar: 24, indicator: 6, text: 'xs' },
31088
+ sm: { avatar: 32, indicator: 8, text: 'xs' },
31089
+ md: { avatar: 40, indicator: 10, text: 'sm' },
31090
+ lg: { avatar: 48, indicator: 12, text: 'md' },
31091
+ xl: { avatar: 64, indicator: 16, text: 'lg' },
31092
+ '2xl': { avatar: 80, indicator: 20, text: 'xl' },
31093
+ '3xl': { avatar: 96, indicator: 24, text: '2xl' },
31578
31094
  };
31579
31095
  const BASE_AVATAR_METRICS = AVATAR_SIZE_SCALE.md;
31580
31096
  function resolveAvatarMetrics(value) {
@@ -31592,11 +31108,11 @@ function resolveAvatarMetrics(value) {
31592
31108
  }
31593
31109
  function calculateNumericMetrics$1(value) {
31594
31110
  const ratio = value / BASE_AVATAR_METRICS.avatar;
31595
- const badge = Math.max(4, Math.round(BASE_AVATAR_METRICS.badge * ratio));
31111
+ const indicator = Math.max(4, Math.round(BASE_AVATAR_METRICS.indicator * ratio));
31596
31112
  const text = pickTextSize(value);
31597
31113
  return {
31598
31114
  avatar: value,
31599
- badge,
31115
+ indicator,
31600
31116
  text,
31601
31117
  };
31602
31118
  }
@@ -31615,9 +31131,9 @@ function pickTextSize(value) {
31615
31131
  return 'sm';
31616
31132
  return 'xs';
31617
31133
  }
31618
- function Avatar({ size = 'md', src, fallback, backgroundColor, textColor = 'white', online, badgeColor, style, accessibilityLabel, label, description, gap = 8, showText = true, }) {
31134
+ function Avatar({ size = 'md', src, fallback, backgroundColor, textColor = 'white', online, indicatorColor, style, accessibilityLabel, label, description, gap = 8, showText = true, }) {
31619
31135
  const theme = useTheme();
31620
- const { avatar: avatarSize, badge: badgeSize, text: textSize } = resolveAvatarMetrics(size);
31136
+ const { avatar: avatarSize, indicator: indicatorSize, text: textSize } = resolveAvatarMetrics(size);
31621
31137
  const avatarStyle = {
31622
31138
  width: avatarSize,
31623
31139
  height: avatarSize,
@@ -31635,7 +31151,7 @@ function Avatar({ size = 'md', src, fallback, backgroundColor, textColor = 'whit
31635
31151
  width: avatarSize,
31636
31152
  height: avatarSize,
31637
31153
  borderRadius: avatarSize / 2,
31638
- }, accessibilityLabel: accessibilityLabel })) : (jsxRuntime.jsx(Text, { size: textSize, color: textColor, weight: "semibold", style: { textAlign: 'center' }, children: fallback || '?' })) }), online && (jsxRuntime.jsx(Indicator, { size: badgeSize, color: badgeColor || theme.colors.success[5], borderColor: theme.colors.gray[0], placement: "bottom-right" }))] }));
31154
+ }, accessibilityLabel: accessibilityLabel })) : (jsxRuntime.jsx(Text, { size: textSize, color: textColor, weight: "semibold", style: { textAlign: 'center' }, children: fallback || '?' })) }), online && (jsxRuntime.jsx(Indicator, { size: indicatorSize, color: indicatorColor || theme.colors.success[5], borderColor: theme.colors.gray[0], placement: "bottom-right" }))] }));
31639
31155
  if (label || description) {
31640
31156
  return (jsxRuntime.jsxs(reactNative.View, { style: { flexDirection: 'row', alignItems: 'center' }, children: [content, showText && (jsxRuntime.jsxs(reactNative.View, { style: { marginLeft: gap, justifyContent: 'center' }, children: [label && (typeof label === 'string' ? (jsxRuntime.jsx(Text, { size: textSize, weight: "semibold", children: label })) : label), description && (typeof description === 'string' ? (jsxRuntime.jsx(Text, { size: textSize, color: theme.colors.gray[6], children: description })) : description)] }))] }));
31641
31157
  }
@@ -32137,7 +31653,7 @@ function usePopoverContext(component) {
32137
31653
  const DEFAULT_ARROW_SIZE = 7;
32138
31654
  const PopoverBase = (props, ref) => {
32139
31655
  var _a;
32140
- const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
31656
+ const { children, opened: controlledOpened, defaultOpened = false, onChange, onOpen, onClose, onDismiss, trigger = 'click', disabled = false, closeOnClickOutside = true, closeOnEscape = true, clickOutsideEvents, // currently not implemented
32141
31657
  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, keyboardAvoidance = true, fallbackPlacements, boundary, withRoles = true, id, withArrow = false, arrowSize = DEFAULT_ARROW_SIZE, arrowRadius = 0, arrowOffset = 5, arrowPosition = 'center', onPositionChange, testID, ...rest } = props;
32142
31658
  const theme = useTheme();
32143
31659
  const { spacingProps } = extractSpacingProps(rest);
@@ -32149,9 +31665,18 @@ const PopoverBase = (props, ref) => {
32149
31665
  const openedRef = React.useRef(opened);
32150
31666
  const closingReasonRef = React.useRef(null);
32151
31667
  const anchorMeasurementsRef = React.useRef(null);
31668
+ const hoverTimeoutRef = React.useRef(null);
32152
31669
  React.useEffect(() => {
32153
31670
  openedRef.current = opened;
32154
31671
  }, [opened]);
31672
+ // Cleanup hover timeout on unmount
31673
+ React.useEffect(() => {
31674
+ return () => {
31675
+ if (hoverTimeoutRef.current) {
31676
+ clearTimeout(hoverTimeoutRef.current);
31677
+ }
31678
+ };
31679
+ }, []);
32155
31680
  const resolvedOffset = typeof offset === 'number' ? offset : (_a = offset === null || offset === void 0 ? void 0 : offset.mainAxis) !== null && _a !== void 0 ? _a : 8;
32156
31681
  const resolvedFlip = preventPositionChangeWhenVisible
32157
31682
  ? false
@@ -32164,7 +31689,7 @@ const PopoverBase = (props, ref) => {
32164
31689
  ? false
32165
31690
  : true;
32166
31691
  const resolvedStrategy = floatingStrategy !== null && floatingStrategy !== void 0 ? floatingStrategy : 'fixed';
32167
- const { position: positioningResult, anchorRef, popoverRef, showOverlay, hideOverlay, updatePosition } = useDropdownPositioning({
31692
+ const { position: positioningResult, anchorRef, popoverRef, showOverlay, hideOverlay, updatePosition, isPositioning } = useDropdownPositioning({
32168
31693
  isOpen: opened && !disabled && !!dropdownState,
32169
31694
  placement: position,
32170
31695
  offset: resolvedOffset,
@@ -32176,9 +31701,20 @@ const PopoverBase = (props, ref) => {
32176
31701
  fallbackPlacements,
32177
31702
  viewport,
32178
31703
  onClose: () => handleOverlayClose('dismiss'),
32179
- closeOnClickOutside,
31704
+ closeOnClickOutside: trigger === 'hover' ? false : closeOnClickOutside,
32180
31705
  closeOnEscape,
32181
31706
  });
31707
+ // Track if we've done measurement-based positioning to avoid flicker
31708
+ const hasPositionedRef = React.useRef(false);
31709
+ React.useEffect(() => {
31710
+ // Only mark as positioned when we have a measurement-based position
31711
+ if (opened && positioningResult && positioningResult._hasMeasuredPopover) {
31712
+ hasPositionedRef.current = true;
31713
+ }
31714
+ if (!opened) {
31715
+ hasPositionedRef.current = false;
31716
+ }
31717
+ }, [opened, positioningResult]);
32182
31718
  const popoverStyles = React.useMemo(() => createPopoverStyles(theme)({
32183
31719
  radius,
32184
31720
  shadow,
@@ -32282,6 +31818,28 @@ const PopoverBase = (props, ref) => {
32282
31818
  openPopover();
32283
31819
  }
32284
31820
  }, [closePopover, openPopover]);
31821
+ // Hover-specific handlers with delay to prevent glitching when moving between target and dropdown
31822
+ const handleHoverOpen = React.useCallback(() => {
31823
+ if (hoverTimeoutRef.current) {
31824
+ clearTimeout(hoverTimeoutRef.current);
31825
+ hoverTimeoutRef.current = null;
31826
+ }
31827
+ openPopover();
31828
+ }, [openPopover]);
31829
+ const handleHoverClose = React.useCallback(() => {
31830
+ if (hoverTimeoutRef.current) {
31831
+ clearTimeout(hoverTimeoutRef.current);
31832
+ }
31833
+ hoverTimeoutRef.current = setTimeout(() => {
31834
+ closePopover('programmatic');
31835
+ hoverTimeoutRef.current = null;
31836
+ }, 150); // Delay to allow mouse to move to dropdown
31837
+ }, [closePopover]);
31838
+ // Store hover handlers in refs to avoid causing re-renders in useEffect
31839
+ const hoverHandlersRef = React.useRef({ open: handleHoverOpen, close: handleHoverClose });
31840
+ React.useEffect(() => {
31841
+ hoverHandlersRef.current = { open: handleHoverOpen, close: handleHoverClose };
31842
+ }, [handleHoverOpen, handleHoverClose]);
32285
31843
  React.useEffect(() => {
32286
31844
  if (opened) {
32287
31845
  updateAnchorMeasurements();
@@ -32340,14 +31898,26 @@ const PopoverBase = (props, ref) => {
32340
31898
  if (typeof resolvedMaxHeight === 'number')
32341
31899
  sizeStyles.maxHeight = resolvedMaxHeight;
32342
31900
  const dropdownStyle = [popoverStyles.dropdown, dropdownState.style, sizeStyles];
32343
- 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) }))] }));
31901
+ // Hover handlers for the dropdown to keep it open when mouse moves from target to dropdown
31902
+ const dropdownHoverHandlers = trigger === 'hover' && reactNative.Platform.OS === 'web'
31903
+ ? {
31904
+ onMouseEnter: () => hoverHandlersRef.current.open(),
31905
+ onMouseLeave: () => hoverHandlersRef.current.close(),
31906
+ }
31907
+ : {};
31908
+ // Hide content until we have measurement-based positioning to prevent visual "snap"
31909
+ const hasMeasuredPosition = (positioningResult === null || positioningResult === void 0 ? void 0 : positioningResult._hasMeasuredPopover) === true;
31910
+ const visibilityStyle = !hasMeasuredPosition && reactNative.Platform.OS === 'web'
31911
+ ? { opacity: 0 }
31912
+ : {};
31913
+ const content = (jsxRuntime.jsxs(reactNative.View, { ref: popoverRef, style: [popoverStyles.wrapper, widthOverride ? { width: widthOverride } : null, visibilityStyle], pointerEvents: trigger === 'hover' ? 'auto' : (dropdownState.trapFocus ? 'auto' : 'box-none'), testID: dropdownState.testID, onLayout: handleDropdownLayout, ...dropdownHoverHandlers, ...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) }))] }));
32344
31914
  showOverlay(content, {
32345
31915
  width: widthOverride,
32346
31916
  maxHeight: resolvedMaxHeight,
32347
31917
  zIndex,
32348
31918
  });
32349
31919
  onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(positioningResult.placement);
32350
- }, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, width, maxHeight, minWidth, minHeight, maxWidth, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate]);
31920
+ }, [opened, dropdownState, positioningResult, popoverRef, showOverlay, hideOverlay, popoverStyles.dropdown, popoverStyles.wrapper, width, maxHeight, minWidth, minHeight, maxWidth, withArrow, arrowSize, arrowRadius, arrowOffset, arrowPosition, theme, zIndex, onPositionChange, schedulePositionUpdate, trigger, isPositioning]);
32351
31921
  React.useEffect(() => {
32352
31922
  return () => {
32353
31923
  hideOverlay();
@@ -32368,6 +31938,8 @@ const PopoverBase = (props, ref) => {
32368
31938
  open: openPopover,
32369
31939
  close: () => closePopover('programmatic'),
32370
31940
  toggle: togglePopover,
31941
+ hoverOpen: handleHoverOpen,
31942
+ hoverClose: handleHoverClose,
32371
31943
  registerDropdown,
32372
31944
  unregisterDropdown,
32373
31945
  anchorRef,
@@ -32376,7 +31948,8 @@ const PopoverBase = (props, ref) => {
32376
31948
  withRoles,
32377
31949
  disabled,
32378
31950
  returnFocus,
32379
- }), [opened, openPopover, closePopover, togglePopover, registerDropdown, unregisterDropdown, anchorRef, targetId, dropdownId, withRoles, disabled, returnFocus]);
31951
+ trigger,
31952
+ }), [opened, openPopover, closePopover, togglePopover, handleHoverOpen, handleHoverClose, registerDropdown, unregisterDropdown, anchorRef, targetId, dropdownId, withRoles, disabled, returnFocus, trigger]);
32380
31953
  const setContainerRef = React.useCallback((node) => {
32381
31954
  if (typeof ref === 'function') {
32382
31955
  ref(node);
@@ -32426,16 +31999,44 @@ const PopoverTargetBase = (props, ref) => {
32426
31999
  : { id: context.targetId };
32427
32000
  const composedRef = mergeRefs(children.ref, externalTargetRef);
32428
32001
  const triggerHandlers = {};
32429
- triggerHandlers.onPress = (...args) => {
32430
- const tgt = targetProps;
32431
- if (tgt && typeof tgt.onPress === 'function') {
32432
- tgt.onPress(...args);
32433
- }
32434
- if (typeof childProps.onPress === 'function') {
32435
- childProps.onPress(...args);
32436
- }
32437
- context.toggle();
32438
- };
32002
+ const wrapperHoverHandlers = {};
32003
+ // Click trigger: toggle on press
32004
+ if (context.trigger === 'click') {
32005
+ triggerHandlers.onPress = (...args) => {
32006
+ const tgt = targetProps;
32007
+ if (tgt && typeof tgt.onPress === 'function') {
32008
+ tgt.onPress(...args);
32009
+ }
32010
+ if (typeof childProps.onPress === 'function') {
32011
+ childProps.onPress(...args);
32012
+ }
32013
+ context.toggle();
32014
+ };
32015
+ }
32016
+ // Hover trigger: open/close on mouse enter/leave (web only)
32017
+ // Applied to the wrapper View for reliable hover detection
32018
+ if (context.trigger === 'hover' && reactNative.Platform.OS === 'web') {
32019
+ wrapperHoverHandlers.onMouseEnter = (...args) => {
32020
+ const tgt = targetProps;
32021
+ if (tgt && typeof tgt.onMouseEnter === 'function') {
32022
+ tgt.onMouseEnter(...args);
32023
+ }
32024
+ if (typeof childProps.onMouseEnter === 'function') {
32025
+ childProps.onMouseEnter(...args);
32026
+ }
32027
+ context.hoverOpen();
32028
+ };
32029
+ wrapperHoverHandlers.onMouseLeave = (...args) => {
32030
+ const tgt = targetProps;
32031
+ if (tgt && typeof tgt.onMouseLeave === 'function') {
32032
+ tgt.onMouseLeave(...args);
32033
+ }
32034
+ if (typeof childProps.onMouseLeave === 'function') {
32035
+ childProps.onMouseLeave(...args);
32036
+ }
32037
+ context.hoverClose();
32038
+ };
32039
+ }
32439
32040
  if (reactNative.Platform.OS === 'web') {
32440
32041
  triggerHandlers.onKeyDown = (event) => {
32441
32042
  const tgt = targetProps;
@@ -32457,7 +32058,14 @@ const PopoverTargetBase = (props, ref) => {
32457
32058
  };
32458
32059
  }
32459
32060
  const dynamicRefProp = { [refProp]: composedRef };
32460
- delete sanitizedTargetProps.onPress;
32061
+ // Remove handlers that we're overriding from sanitizedTargetProps
32062
+ if (context.trigger === 'click') {
32063
+ delete sanitizedTargetProps.onPress;
32064
+ }
32065
+ if (context.trigger === 'hover') {
32066
+ delete sanitizedTargetProps.onMouseEnter;
32067
+ delete sanitizedTargetProps.onMouseLeave;
32068
+ }
32461
32069
  delete sanitizedTargetProps.onKeyDown;
32462
32070
  const mergedProps = {
32463
32071
  ...sanitizedTargetProps,
@@ -32469,7 +32077,7 @@ const PopoverTargetBase = (props, ref) => {
32469
32077
  mergedProps.disabled = true;
32470
32078
  }
32471
32079
  const anchorWrapperRef = mergeRefs(context.anchorRef, ref);
32472
- return (jsxRuntime.jsx(reactNative.View, { ref: anchorWrapperRef, collapsable: false, children: React.cloneElement(children, mergedProps) }));
32080
+ return (jsxRuntime.jsx(reactNative.View, { ref: anchorWrapperRef, collapsable: false, ...wrapperHoverHandlers, children: React.cloneElement(children, mergedProps) }));
32473
32081
  };
32474
32082
  const PopoverDropdownBase = (props, _ref) => {
32475
32083
  const { children, trapFocus = false, keepMounted, style, testID, ...rest } = props;
@@ -32513,8 +32121,11 @@ function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosi
32513
32121
  const [side, alignment] = placement.split('-');
32514
32122
  switch (side) {
32515
32123
  case 'top':
32124
+ // Arrow points down, hide the borders that overlap with content (top-left corner after rotation)
32516
32125
  return {
32517
32126
  ...base,
32127
+ borderTopWidth: 0,
32128
+ borderLeftWidth: 0,
32518
32129
  bottom: -arrowSize,
32519
32130
  left: alignment === 'end'
32520
32131
  ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
@@ -32524,8 +32135,11 @@ function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosi
32524
32135
  marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
32525
32136
  };
32526
32137
  case 'bottom':
32138
+ // Arrow points up, hide the borders that overlap with content (bottom-right corner after rotation)
32527
32139
  return {
32528
32140
  ...base,
32141
+ borderBottomWidth: 0,
32142
+ borderRightWidth: 0,
32529
32143
  top: -arrowSize,
32530
32144
  left: alignment === 'end'
32531
32145
  ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
@@ -32535,8 +32149,11 @@ function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosi
32535
32149
  marginLeft: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
32536
32150
  };
32537
32151
  case 'left':
32152
+ // Arrow points right, hide the borders that overlap with content (bottom-left corner after rotation)
32538
32153
  return {
32539
32154
  ...base,
32155
+ borderBottomWidth: 0,
32156
+ borderLeftWidth: 0,
32540
32157
  right: -arrowSize,
32541
32158
  top: alignment === 'end'
32542
32159
  ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
@@ -32546,8 +32163,11 @@ function getArrowStyle(placement, arrowSize, arrowRadius, arrowOffset, arrowPosi
32546
32163
  marginTop: alignment || arrowPosition === 'side' ? 0 : -arrowSize,
32547
32164
  };
32548
32165
  case 'right':
32166
+ // Arrow points left, hide the borders that overlap with content (top-right corner after rotation)
32549
32167
  return {
32550
32168
  ...base,
32169
+ borderTopWidth: 0,
32170
+ borderRightWidth: 0,
32551
32171
  left: -arrowSize,
32552
32172
  top: alignment === 'end'
32553
32173
  ? `calc(100% - ${(arrowPosition === 'side' ? arrowOffset : arrowSize)}px)`
@@ -33468,7 +33088,7 @@ const filterData = (data, filters, columns, searchValue, rowFeatureToggle) => {
33468
33088
  return filteredData;
33469
33089
  };
33470
33090
  // DataTable component
33471
- const DataTable = ({ id, data, columns, loading = false, error = null, emptyMessage = 'No data available', searchable = true, searchPlaceholder = 'Search...', searchValue: controlledSearchValue, onSearchChange, sortBy = [], onSortChange, filters = [], onFilterChange, pagination, onPaginationChange, selectable = false, selectedRows = [], onSelectionChange, getRowId = (_, index) => index, onRowClick, editMode = false, onEditModeChange, onCellEdit, bulkActions = [], variant = 'default', density = 'normal', height, virtual = false, style, hoverHighlight = true, enableColumnResizing = false, rowFeatureToggle, initialHiddenColumns = [], onColumnVisibilityChange, onColumnSettings, showColumnVisibilityManager = true, rowsPerPageOptions = [10, 25, 50, 100], showRowsPerPageControl = true, rowActions, actionsColumnWidth = 100, fullWidth = true,
33091
+ const DataTable = ({ id, data, columns, loading = false, error = null, emptyMessage = 'No data available', searchable = true, searchPlaceholder = 'Search...', searchValue: controlledSearchValue, onSearchChange, sortBy = [], onSortChange, filters = [], onFilterChange, pagination, onPaginationChange, selectable = false, selectedRows = [], onSelectionChange, getRowId = (_, index) => index, onRowClick, editMode = false, onEditModeChange, onCellEdit, bulkActions = [], variant = 'default', striped: stripedProp, density = 'normal', height, virtual = false, style, hoverHighlight = true, enableColumnResizing = false, rowFeatureToggle, initialHiddenColumns = [], onColumnVisibilityChange, onColumnSettings, showColumnVisibilityManager = true, rowsPerPageOptions = [10, 25, 50, 100], showRowsPerPageControl = true, rowActions, actionsColumnWidth = 100, fullWidth = true,
33472
33092
  // Border styling props
33473
33093
  rowBorderWidth, rowBorderColor, rowBorderStyle = 'solid', columnBorderWidth, columnBorderColor, columnBorderStyle = 'solid', showOuterBorder = false, outerBorderWidth = 1, outerBorderColor,
33474
33094
  // Expandable rows props
@@ -33476,6 +33096,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33476
33096
  const { spacingProps, otherProps } = extractSpacingProps(props);
33477
33097
  const theme = useTheme();
33478
33098
  const { isRTL } = useDirection();
33099
+ const isStriped = stripedProp !== null && stripedProp !== void 0 ? stripedProp : variant === 'striped';
33479
33100
  // Local state
33480
33101
  const [internalSearchValue, setInternalSearchValue] = React.useState('');
33481
33102
  const [editingCell, setEditingCell] = React.useState(null);
@@ -33912,7 +33533,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33912
33533
  const rowElement = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(TableTr, { selected: isSelected, onPress: () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row, rowIndex), style: {
33913
33534
  backgroundColor: isSelected
33914
33535
  ? theme.colors.primary[1]
33915
- : variant === 'striped' && rowIndex % 2 === 1
33536
+ : isStriped && rowIndex % 2 === 1
33916
33537
  ? theme.colors.gray[0]
33917
33538
  : 'transparent',
33918
33539
  borderBottomWidth: rowBorderWidth || (variant === 'bordered' ? 1 : 0),
@@ -33992,7 +33613,7 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
33992
33613
  borderRadius: showOuterBorder ? 8 : 0
33993
33614
  };
33994
33615
  if (loading) {
33995
- return (jsxRuntime.jsxs(reactNative.View, { style: [getSpacingStyles(spacingProps), style], ...otherProps, children: [renderHeader(), jsxRuntime.jsxs(Table, { striped: variant === 'striped', withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: [jsxRuntime.jsxs(TableTr, { style: { backgroundColor: theme.colors.gray[0] }, children: [selectable && (jsxRuntime.jsx(TableTh, { w: 50, children: jsxRuntime.jsx(reactNative.View, { style: { width: 20, height: 20, backgroundColor: theme.colors.gray[2], borderRadius: 4 } }) })), expandableRowRender && (jsxRuntime.jsx(TableTh, { w: 50, children: jsxRuntime.jsx(reactNative.View, { style: { width: 20, height: 20, backgroundColor: theme.colors.gray[2], borderRadius: 4 } }) })), visibleColumns.map(column => (jsxRuntime.jsx(TableTh, { w: column.width || columnWidths[column.key], minWidth: column.minWidth, children: jsxRuntime.jsx(reactNative.View, { style: {
33616
+ return (jsxRuntime.jsxs(reactNative.View, { style: [getSpacingStyles(spacingProps), style], ...otherProps, children: [renderHeader(), jsxRuntime.jsxs(Table, { striped: isStriped, withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: [jsxRuntime.jsxs(TableTr, { style: { backgroundColor: theme.colors.gray[0] }, children: [selectable && (jsxRuntime.jsx(TableTh, { w: 50, children: jsxRuntime.jsx(reactNative.View, { style: { width: 20, height: 20, backgroundColor: theme.colors.gray[2], borderRadius: 4 } }) })), expandableRowRender && (jsxRuntime.jsx(TableTh, { w: 50, children: jsxRuntime.jsx(reactNative.View, { style: { width: 20, height: 20, backgroundColor: theme.colors.gray[2], borderRadius: 4 } }) })), visibleColumns.map(column => (jsxRuntime.jsx(TableTh, { w: column.width || columnWidths[column.key], minWidth: column.minWidth, children: jsxRuntime.jsx(reactNative.View, { style: {
33996
33617
  height: 20,
33997
33618
  backgroundColor: theme.colors.gray[2],
33998
33619
  borderRadius: 4,
@@ -34014,9 +33635,9 @@ expandableRowRender, initialExpandedRows = [], expandedRows: controlledExpandedR
34014
33635
  borderColor: theme.colors.error[2]
34015
33636
  }, children: [jsxRuntime.jsx(Icon, { name: "error", size: 32, color: theme.colors.error[5], style: { marginBottom: 12 } }), jsxRuntime.jsx(Text, { variant: "h6", color: theme.colors.error[7], style: { marginBottom: 8 }, children: "Error Loading Data" }), jsxRuntime.jsx(Text, { variant: "p", colorVariant: "muted", style: { textAlign: 'center' }, children: error })] })] }));
34016
33637
  }
34017
- return (jsxRuntime.jsxs(reactNative.View, { style: [getSpacingStyles(spacingProps), style], ...otherProps, children: [renderHeader(), virtual ? (jsxRuntime.jsx(reactNative.View, { style: [{ width: '100%', overflow: 'hidden' }, tableBorderStyle], children: jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: reactNative.Platform.OS === 'web', contentContainerStyle: minWidthValue ? { minWidth: minWidthValue } : undefined, children: jsxRuntime.jsxs(reactNative.View, { style: { flex: 1 }, children: [jsxRuntime.jsx(Table, { striped: variant === 'striped', withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: headerRow }), processedData.length === 0 ? (jsxRuntime.jsx(Table, { striped: variant === 'striped', withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: emptyStateRow })) : (jsxRuntime.jsx(flashList.FlashList, { data: processedData, keyExtractor: (item, index) => String(getRowId(item, index)), renderItem: renderVirtualRow, ...flashListSizingProps, extraData: flashListExtraData, contentContainerStyle: { flexGrow: 1 }, showsVerticalScrollIndicator: reactNative.Platform.OS === 'web' }))] }) }) })) : (
33638
+ return (jsxRuntime.jsxs(reactNative.View, { style: [getSpacingStyles(spacingProps), style], ...otherProps, children: [renderHeader(), virtual ? (jsxRuntime.jsx(reactNative.View, { style: [{ width: '100%', overflow: 'hidden' }, tableBorderStyle], children: jsxRuntime.jsx(reactNative.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: reactNative.Platform.OS === 'web', contentContainerStyle: minWidthValue ? { minWidth: minWidthValue } : undefined, children: jsxRuntime.jsxs(reactNative.View, { style: { flex: 1 }, children: [jsxRuntime.jsx(Table, { striped: isStriped, withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: headerRow }), processedData.length === 0 ? (jsxRuntime.jsx(Table, { striped: isStriped, withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth: fullWidth, children: emptyStateRow })) : (jsxRuntime.jsx(flashList.FlashList, { data: processedData, keyExtractor: (item, index) => String(getRowId(item, index)), renderItem: renderVirtualRow, ...flashListSizingProps, extraData: flashListExtraData, contentContainerStyle: { flexGrow: 1 }, showsVerticalScrollIndicator: reactNative.Platform.OS === 'web' }))] }) }) })) : (
34018
33639
  // <TableScrollContainer style={tableBorderStyle} minWidth={minWidthValue}>
34019
- jsxRuntime.jsxs(Table, { striped: variant === 'striped', withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth //</TableScrollContainer>={fullWidth}
33640
+ jsxRuntime.jsxs(Table, { striped: isStriped, withTableBorder: variant === 'bordered', withRowBorders: variant !== 'default', verticalSpacing: density === 'compact' ? 'xs' : density === 'comfortable' ? 'lg' : 'sm', fullWidth //</TableScrollContainer>={fullWidth}
34020
33641
  : true, children: [headerRow, processedData.length === 0 ? emptyStateRow : nonVirtualRows] })
34021
33642
  // </TableScrollContainer>
34022
33643
  ), pagination && onPaginationChange && (jsxRuntime.jsx(reactNative.View, { style: {
@@ -35681,104 +35302,6 @@ const Ring = factory((props, ref) => {
35681
35302
  return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: [styles$8.container, spacingStyles, style], testID: testID, accessibilityLabel: accessibilityLabel !== null && accessibilityLabel !== void 0 ? accessibilityLabel : `Ring value ${Math.round(percent)} percent`, accessibilityRole: "progressbar", accessibilityValue: { min, max, now: Math.round(clampedValue) }, ...otherProps, children: [jsxRuntime.jsxs(reactNative.View, { style: [styles$8.ringWrapper, { width: size, height: size }, ringStyle], children: [jsxRuntime.jsxs(Svg, { width: size, height: size, viewBox: `0 0 ${size} ${size}`, children: [jsxRuntime.jsx(Svg.Circle, { cx: size / 2, cy: size / 2, r: radius, stroke: defaultTrackColor, strokeWidth: thickness, fill: "transparent" }), jsxRuntime.jsx(Svg.Circle, { cx: size / 2, cy: size / 2, r: radius, stroke: resolvedProgressColor, strokeWidth: thickness, strokeLinecap: roundedCaps ? 'round' : 'butt', strokeDasharray: `${circumference} ${circumference}`, strokeDashoffset: dashOffset, fill: "transparent", transform: `rotate(-90 ${size / 2} ${size / 2})` })] }), jsxRuntime.jsx(reactNative.View, { pointerEvents: "none", style: [styles$8.centerContent, { width: size, height: size }, contentStyle], children: centerContent })] }), caption !== undefined && caption !== null ? (React.isValidElement(caption) ? (caption) : (jsxRuntime.jsx(Text, { variant: "span", size: "xs", color: captionTextColor, weight: "600", style: [{ marginTop: 6, letterSpacing: 1 }, captionStyle], children: caption }))) : null] }));
35682
35303
  }, { displayName: 'Ring' });
35683
35304
 
35684
- const NAVIGATIONPROGRESS_DEFAULTS = {
35685
- size: 3,
35686
- color: 'primary',
35687
- zIndex: 9999,
35688
- overlay: true,
35689
- stepInterval: 500,
35690
- radius: 0,
35691
- };
35692
-
35693
- let subscribers = new Set();
35694
- let internalState = { value: 0, active: false };
35695
- let interval = null;
35696
- function broadcast() { subscribers.forEach(cb => cb({ ...internalState })); }
35697
- function schedule(intervalMs) {
35698
- clearInterval(interval);
35699
- interval = setInterval(() => {
35700
- if (!internalState.active)
35701
- return;
35702
- const remain = 100 - internalState.value;
35703
- const inc = Math.max(0.1, remain * 0.03);
35704
- internalState.value = Math.min(99, internalState.value + inc);
35705
- broadcast();
35706
- }, intervalMs);
35707
- }
35708
- const navigationProgress = {
35709
- start() { if (internalState.active)
35710
- return; internalState.active = true; if (internalState.value >= 100)
35711
- internalState.value = 0; broadcast(); schedule(NAVIGATIONPROGRESS_DEFAULTS.stepInterval); },
35712
- stop() { internalState.active = false; broadcast(); },
35713
- complete() { internalState.active = true; internalState.value = 100; broadcast(); setTimeout(() => { internalState.active = false; internalState.value = 0; broadcast(); }, 400); },
35714
- reset() { internalState.value = 0; internalState.active = false; broadcast(); },
35715
- set(v) { internalState.value = Math.max(0, Math.min(100, v)); broadcast(); },
35716
- increment(delta = 5) { internalState.value = Math.min(100, internalState.value + delta); broadcast(); },
35717
- decrement(delta = 5) { internalState.value = Math.max(0, internalState.value - delta); broadcast(); },
35718
- isActive() { return internalState.active; }
35719
- };
35720
- const NavigationProgress = ({ value, size = NAVIGATIONPROGRESS_DEFAULTS.size, color = NAVIGATIONPROGRESS_DEFAULTS.color, zIndex = NAVIGATIONPROGRESS_DEFAULTS.zIndex, overlay = NAVIGATIONPROGRESS_DEFAULTS.overlay, stepInterval = NAVIGATIONPROGRESS_DEFAULTS.stepInterval, radius = NAVIGATIONPROGRESS_DEFAULTS.radius, active = true, style }) => {
35721
- const theme = useTheme();
35722
- const scheme = useColorScheme();
35723
- const isDark = scheme === 'dark';
35724
- const progress = Animated.useSharedValue(0);
35725
- const opacity = Animated.useSharedValue(0);
35726
- React.useEffect(() => {
35727
- const sub = (s) => {
35728
- if (value == null) {
35729
- progress.value = Animated.withTiming(s.value, { duration: stepInterval });
35730
- opacity.value = Animated.withTiming(s.active ? 1 : 0, { duration: 150 });
35731
- }
35732
- };
35733
- subscribers.add(sub);
35734
- broadcast();
35735
- return () => { subscribers.delete(sub); };
35736
- }, [value, stepInterval, progress, opacity]);
35737
- React.useEffect(() => {
35738
- if (value != null) {
35739
- progress.value = Animated.withTiming(value, { duration: stepInterval });
35740
- opacity.value = Animated.withTiming(active ? 1 : 0, { duration: 150 });
35741
- }
35742
- }, [value, active, stepInterval]);
35743
- let resolvedColor = color;
35744
- if (theme.colors[color]) {
35745
- const bucket = theme.colors[color];
35746
- resolvedColor = bucket[5] || bucket[4] || bucket[0];
35747
- }
35748
- const barStyle = Animated.useAnimatedStyle(() => ({ width: `${progress.value}%` }));
35749
- const containerStyle = Animated.useAnimatedStyle(() => ({ opacity: opacity.value }));
35750
- return (jsxRuntime.jsxs(Animated.View, { style: [
35751
- {
35752
- position: overlay ? 'absolute' : 'relative',
35753
- top: 0,
35754
- left: 0,
35755
- right: 0,
35756
- height: size,
35757
- backgroundColor: isDark ? theme.colors.gray[3] : theme.colors.gray[2],
35758
- overflow: 'hidden',
35759
- zIndex,
35760
- borderRadius: radius,
35761
- pointerEvents: 'none'
35762
- },
35763
- containerStyle,
35764
- style
35765
- ], children: [jsxRuntime.jsx(Animated.View, { style: [{
35766
- position: 'absolute',
35767
- top: 0,
35768
- bottom: 0,
35769
- left: 0,
35770
- backgroundColor: resolvedColor,
35771
- borderRadius: radius,
35772
- }, barStyle] }), jsxRuntime.jsx(Animated.View, { style: [{
35773
- position: 'absolute',
35774
- top: 0,
35775
- bottom: 0,
35776
- right: 0,
35777
- width: 80,
35778
- backgroundColor: 'rgba(255,255,255,0.2)'
35779
- }, barStyle] })] }));
35780
- };
35781
-
35782
35305
  const DEFAULT_OPACITY = 0.6;
35783
35306
  const HEX_COLOR_REGEX = /^#?[0-9a-f]{3,8}$/i;
35784
35307
  const clampOpacity = (value) => {
@@ -35971,270 +35494,6 @@ const LoadingOverlay = React.forwardRef((props, ref) => {
35971
35494
  });
35972
35495
  LoadingOverlay.displayName = 'LoadingOverlay';
35973
35496
 
35974
- // A lightweight hover-activated floating panel similar to Mantine HoverCard
35975
- function HoverCardBase(props, ref) {
35976
- const { children, target, position = 'top', offset = 8, openDelay = 100, closeDelay = 150, opened: controlledOpened, shadow = 'md', radius = 'md', withinPortal = true, width, withArrow = false, closeOnEscape = true, onOpen, onClose, disabled = false, style, testID, zIndex = 3000, keepMounted = false, trigger = 'hover', } = props;
35977
- const [opened, setOpened] = React.useState(false);
35978
- const openTimeout = React.useRef(null);
35979
- const closeTimeout = React.useRef(null);
35980
- const containerRef = React.useRef(null);
35981
- const targetRef = React.useRef(null);
35982
- const overlayIdRef = React.useRef(null);
35983
- const overlayContentRef = React.useRef(null);
35984
- const isHoveringTargetRef = React.useRef(false);
35985
- const isHoveringOverlayRef = React.useRef(false);
35986
- const theme = useTheme();
35987
- const { openOverlay, closeOverlay, updateOverlay } = useOverlay();
35988
- const isOpened = controlledOpened !== undefined ? controlledOpened : opened;
35989
- const clearTimers = () => {
35990
- if (openTimeout.current) {
35991
- clearTimeout(openTimeout.current);
35992
- openTimeout.current = null;
35993
- }
35994
- if (closeTimeout.current) {
35995
- clearTimeout(closeTimeout.current);
35996
- closeTimeout.current = null;
35997
- }
35998
- };
35999
- const doOpen = React.useCallback(() => {
36000
- if (disabled)
36001
- return;
36002
- setOpened(true);
36003
- onOpen === null || onOpen === void 0 ? void 0 : onOpen();
36004
- }, [disabled, onOpen]);
36005
- const doClose = React.useCallback(() => {
36006
- setOpened(false);
36007
- onClose === null || onClose === void 0 ? void 0 : onClose();
36008
- }, [onClose]);
36009
- const scheduleOpen = React.useCallback(() => {
36010
- clearTimers();
36011
- openTimeout.current = setTimeout(doOpen, openDelay);
36012
- }, [doOpen, openDelay]);
36013
- const scheduleClose = React.useCallback(() => {
36014
- clearTimers();
36015
- closeTimeout.current = setTimeout(() => {
36016
- // Only close if neither target nor overlay are hovered (web)
36017
- if (reactNative.Platform.OS === 'web') {
36018
- if (isHoveringTargetRef.current || isHoveringOverlayRef.current)
36019
- return;
36020
- }
36021
- doClose();
36022
- }, closeDelay);
36023
- }, [doClose, closeDelay]);
36024
- React.useEffect(() => () => clearTimers(), []);
36025
- // Escape key (web only)
36026
- React.useEffect(() => {
36027
- if (!closeOnEscape || reactNative.Platform.OS !== 'web')
36028
- return;
36029
- const handler = (e) => { if (e.key === 'Escape')
36030
- doClose(); };
36031
- document.addEventListener('keydown', handler);
36032
- return () => document.removeEventListener('keydown', handler);
36033
- }, [closeOnEscape, doClose]);
36034
- const getInlinePositionStyle = () => {
36035
- const base = { position: 'absolute' };
36036
- switch (position) {
36037
- case 'top': return { ...base, bottom: '100%', left: 0, marginBottom: offset };
36038
- case 'bottom': return { ...base, top: '100%', left: 0, marginTop: offset };
36039
- case 'left': return { ...base, right: '100%', top: 0, marginRight: offset };
36040
- case 'right': return { ...base, left: '100%', top: 0, marginLeft: offset };
36041
- default: return { ...base, top: '100%', left: 0, marginTop: offset };
36042
- }
36043
- };
36044
- const shadowStyle = (() => {
36045
- switch (shadow) {
36046
- case 'sm':
36047
- return { boxShadow: '0 1px 2px rgba(0, 0, 0, 0.1)', elevation: 2 };
36048
- case 'md':
36049
- return { boxShadow: '0 2px 4px rgba(0, 0, 0, 0.15)', elevation: 4 };
36050
- case 'lg':
36051
- return { boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)', elevation: 8 };
36052
- default:
36053
- return {};
36054
- }
36055
- })();
36056
- const renderArrow = (placement) => {
36057
- if (!withArrow)
36058
- return null;
36059
- const base = { position: 'absolute', width: 0, height: 0 };
36060
- const color = theme.colors.gray[0];
36061
- const styles = {
36062
- top: { top: '100%', left: 12, borderLeftWidth: 6, borderRightWidth: 6, borderTopWidth: 6, borderLeftColor: 'transparent', borderRightColor: 'transparent', borderTopColor: color },
36063
- bottom: { bottom: '100%', left: 12, borderLeftWidth: 6, borderRightWidth: 6, borderBottomWidth: 6, borderLeftColor: 'transparent', borderRightColor: 'transparent', borderBottomColor: color },
36064
- left: { left: '100%', top: 12, borderTopWidth: 6, borderBottomWidth: 6, borderLeftWidth: 6, borderTopColor: 'transparent', borderBottomColor: 'transparent', borderLeftColor: color },
36065
- right: { right: '100%', top: 12, borderTopWidth: 6, borderBottomWidth: 6, borderRightWidth: 6, borderTopColor: 'transparent', borderBottomColor: 'transparent', borderRightColor: color },
36066
- };
36067
- const key = placement.split('-')[0];
36068
- return jsxRuntime.jsx(reactNative.View, { style: { ...base, ...(styles[key] || styles.top) } });
36069
- };
36070
- const openPortal = React.useCallback(async () => {
36071
- if (!withinPortal || !isOpened || overlayIdRef.current)
36072
- return;
36073
- const rect = await measureElement(targetRef);
36074
- const estWidth = width || 240;
36075
- const estHeight = 160; // rough initial height
36076
- const pos = calculateOverlayPositionEnhanced(rect, { width: estWidth, height: estHeight }, {
36077
- placement: position,
36078
- offset,
36079
- viewport: getViewport(),
36080
- strategy: 'fixed'
36081
- });
36082
- const overlayContent = (jsxRuntime.jsxs(reactNative.View, { ref: overlayContentRef, style: [
36083
- {
36084
- backgroundColor: theme.colors.gray[0],
36085
- borderRadius: getRadius$2(radius),
36086
- paddingHorizontal: getSpacing('md'),
36087
- paddingVertical: getSpacing('sm'),
36088
- borderWidth: 1,
36089
- borderColor: theme.colors.gray[3],
36090
- minWidth: width || 160,
36091
- maxWidth: width || 320,
36092
- },
36093
- shadowStyle,
36094
- ], ...(reactNative.Platform.OS === 'web' && trigger === 'hover' ? {
36095
- onMouseEnter: () => { isHoveringOverlayRef.current = true; clearTimers(); },
36096
- onMouseLeave: () => { isHoveringOverlayRef.current = false; scheduleClose(); },
36097
- } : {}), children: [children, renderArrow(pos.placement)] }));
36098
- const id = openOverlay({
36099
- content: overlayContent,
36100
- anchor: { x: pos.x, y: pos.y, width: estWidth, height: estHeight },
36101
- trigger: trigger,
36102
- // For hover-triggered overlays, do NOT render a click-outside backdrop – it steals hover
36103
- // and immediately fires target onMouseLeave. We rely on pointer leave timers instead.
36104
- closeOnClickOutside: trigger !== 'hover',
36105
- closeOnEscape: closeOnEscape,
36106
- strategy: 'fixed',
36107
- onClose: () => { overlayIdRef.current = null; if (opened)
36108
- setOpened(false); onClose === null || onClose === void 0 ? void 0 : onClose(); },
36109
- zIndex
36110
- });
36111
- overlayIdRef.current = id;
36112
- }, [withinPortal, isOpened, overlayIdRef, position, offset, width, trigger, closeOnEscape, theme, radius, shadowStyle, children, opened, onClose, getSpacing, getRadius$2]);
36113
- const closePortal = React.useCallback(() => {
36114
- if (overlayIdRef.current) {
36115
- closeOverlay(overlayIdRef.current);
36116
- overlayIdRef.current = null;
36117
- }
36118
- }, [closeOverlay]);
36119
- React.useEffect(() => {
36120
- if (withinPortal) {
36121
- if (isOpened)
36122
- openPortal();
36123
- else
36124
- closePortal();
36125
- }
36126
- return () => { if (!isOpened)
36127
- closePortal(); };
36128
- }, [isOpened, withinPortal, openPortal, closePortal]);
36129
- React.useEffect(() => {
36130
- if (!withinPortal || reactNative.Platform.OS !== 'web' || !isOpened || !overlayIdRef.current)
36131
- return;
36132
- const handler = () => {
36133
- Promise.all([measureElement(targetRef)]).then(([rect]) => {
36134
- var _a, _b;
36135
- const actualWidth = ((_a = overlayContentRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || width || 240;
36136
- const actualHeight = ((_b = overlayContentRef.current) === null || _b === void 0 ? void 0 : _b.offsetHeight) || 160;
36137
- const pos = calculateOverlayPositionEnhanced(rect, { width: actualWidth, height: actualHeight }, {
36138
- placement: position,
36139
- offset,
36140
- viewport: getViewport(),
36141
- strategy: 'fixed'
36142
- });
36143
- updateOverlay(overlayIdRef.current, { anchor: { x: pos.x, y: pos.y, width: actualWidth, height: actualHeight } });
36144
- });
36145
- };
36146
- window.addEventListener('resize', handler);
36147
- window.addEventListener('scroll', handler, true);
36148
- return () => {
36149
- window.removeEventListener('resize', handler);
36150
- window.removeEventListener('scroll', handler, true);
36151
- };
36152
- }, [withinPortal, isOpened, position, offset, width, updateOverlay]);
36153
- // Smart sizing: after content mounts, measure actual size and reposition if changed
36154
- React.useEffect(() => {
36155
- if (!withinPortal || !isOpened || !overlayIdRef.current)
36156
- return;
36157
- let frame;
36158
- const attempt = () => {
36159
- Promise.all([
36160
- measureElement(targetRef),
36161
- measureElement({ current: overlayContentRef.current })
36162
- ]).then(([targetRect, contentRect]) => {
36163
- if (!targetRect.width || !contentRect.width)
36164
- return; // skip invalid
36165
- const desiredWidth = width || contentRect.width;
36166
- const desiredHeight = contentRect.height;
36167
- // Recalculate with actual content size
36168
- const pos = calculateOverlayPositionEnhanced(targetRect, { width: desiredWidth, height: desiredHeight }, {
36169
- placement: position,
36170
- offset,
36171
- viewport: getViewport(),
36172
- strategy: 'fixed'
36173
- });
36174
- updateOverlay(overlayIdRef.current, { anchor: { x: pos.x, y: pos.y, width: desiredWidth, height: desiredHeight } });
36175
- });
36176
- };
36177
- // Delay a bit to allow layout
36178
- frame = setTimeout(attempt, 30);
36179
- return () => { if (frame)
36180
- clearTimeout(frame); };
36181
- }, [withinPortal, isOpened, position, offset, width, updateOverlay]);
36182
- const targetProps = {};
36183
- if (trigger === 'hover') {
36184
- if (reactNative.Platform.OS === 'web') {
36185
- targetProps.onMouseEnter = () => { isHoveringTargetRef.current = true; scheduleOpen(); };
36186
- targetProps.onMouseLeave = () => { isHoveringTargetRef.current = false; scheduleClose(); };
36187
- }
36188
- else {
36189
- // fallback: tap to toggle on native
36190
- targetProps.onPress = () => {
36191
- if (isOpened) {
36192
- doClose();
36193
- }
36194
- else {
36195
- doOpen();
36196
- }
36197
- };
36198
- }
36199
- }
36200
- else if (trigger === 'click') {
36201
- targetProps.onPress = () => {
36202
- if (isOpened) {
36203
- doClose();
36204
- }
36205
- else {
36206
- doOpen();
36207
- }
36208
- };
36209
- }
36210
- const inlineContent = (isOpened || keepMounted) && !withinPortal ? (jsxRuntime.jsxs(reactNative.View, { style: [
36211
- getInlinePositionStyle(),
36212
- {
36213
- backgroundColor: theme.colors.gray[0],
36214
- borderRadius: getRadius$2(radius),
36215
- paddingHorizontal: getSpacing('md'),
36216
- paddingVertical: getSpacing('sm'),
36217
- borderWidth: 1,
36218
- borderColor: theme.colors.gray[3],
36219
- minWidth: width,
36220
- zIndex,
36221
- },
36222
- shadowStyle,
36223
- ], pointerEvents: "auto", ...(reactNative.Platform.OS === 'web' && trigger === 'hover' ? {
36224
- onMouseEnter: () => { isHoveringOverlayRef.current = true; clearTimers(); },
36225
- onMouseLeave: () => { isHoveringOverlayRef.current = false; scheduleClose(); },
36226
- } : {}), children: [children, renderArrow(position)] })) : null;
36227
- return (jsxRuntime.jsxs(reactNative.View, { ref: ref, style: [{ position: 'relative', alignSelf: 'flex-start' }, style], testID: testID, children: [jsxRuntime.jsx(reactNative.Pressable, { ref: (node) => { containerRef.current = node; targetRef.current = node; }, ...targetProps, style: ({ pressed }) => {
36228
- var _a;
36229
- return [
36230
- { opacity: pressed ? 0.85 : 1 },
36231
- (_a = target === null || target === void 0 ? void 0 : target.props) === null || _a === void 0 ? void 0 : _a.style,
36232
- ];
36233
- }, children: target }), inlineContent] }));
36234
- }
36235
- const HoverCard = factory(HoverCardBase);
36236
- HoverCard.displayName = 'HoverCard';
36237
-
36238
35497
  const ContextMenu = ({ children, items, closeOnSelect = true, longPressDelay = 350, maxHeight = 280, onOpen, onClose, open: controlledOpen, position: controlledPosition, portalId, style, }) => {
36239
35498
  var _a, _b;
36240
35499
  const [internalOpen, setInternalOpen] = React.useState(false);
@@ -37454,49 +36713,101 @@ const CarouselDot = React.memo(({ index, pageProgress, metrics, totalPages, loop
37454
36713
  : { marginHorizontal: metrics.margin, height: baseDotSize, justifyContent: 'center' };
37455
36714
  return (jsxRuntime.jsx(reactNative.Pressable, { onPress: handlePress, accessibilityRole: "button", accessibilityLabel: `Go to slide ${index + 1}`, style: containerStyle, children: jsxRuntime.jsx(Animated.View, { style: [{ borderRadius: baseDotSize / 2 }, animatedStyle] }) }));
37456
36715
  });
36716
+ const getBreakpointName = (width) => {
36717
+ if (width >= 1200)
36718
+ return 'xl';
36719
+ if (width >= 992)
36720
+ return 'lg';
36721
+ if (width >= 768)
36722
+ return 'md';
36723
+ if (width >= 576)
36724
+ return 'sm';
36725
+ return 'xs';
36726
+ };
36727
+ const getViewportWidth = () => {
36728
+ if (reactNative.Platform.OS === 'web' && typeof window !== 'undefined' && typeof window.innerWidth === 'number') {
36729
+ return window.innerWidth;
36730
+ }
36731
+ const dimensions = reactNative.Dimensions.get('window');
36732
+ return typeof (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) === 'number' ? dimensions.width : 0;
36733
+ };
37457
36734
  // Optimized breakpoint hook with debouncing
37458
36735
  const useOptimizedBreakpoint = () => {
37459
- const [breakpoint, setBreakpoint] = React.useState('sm');
36736
+ const computeState = () => {
36737
+ const width = getViewportWidth();
36738
+ return {
36739
+ width,
36740
+ breakpoint: getBreakpointName(width),
36741
+ };
36742
+ };
36743
+ const [state, setState] = React.useState(computeState);
37460
36744
  React.useEffect(() => {
37461
36745
  let timeoutId;
37462
- const compute = () => {
37463
- const w = reactNative.Platform.OS === 'web'
37464
- ? window.innerWidth
37465
- : reactNative.Dimensions.get('window').width;
37466
- let newBreakpoint = 'sm';
37467
- if (w >= 1200)
37468
- newBreakpoint = 'xl';
37469
- else if (w >= 992)
37470
- newBreakpoint = 'lg';
37471
- else if (w >= 768)
37472
- newBreakpoint = 'md';
37473
- else if (w >= 576)
37474
- newBreakpoint = 'sm';
37475
- else
37476
- newBreakpoint = 'xs';
37477
- setBreakpoint(prev => prev !== newBreakpoint ? newBreakpoint : prev);
36746
+ const update = () => {
36747
+ const next = computeState();
36748
+ setState(prev => (prev.breakpoint === next.breakpoint && prev.width === next.width) ? prev : next);
37478
36749
  };
37479
- const debouncedCompute = () => {
36750
+ const debouncedUpdate = () => {
37480
36751
  clearTimeout(timeoutId);
37481
- timeoutId = setTimeout(compute, 100); // Debounce resize events
36752
+ timeoutId = setTimeout(update, 100); // Debounce resize events
37482
36753
  };
37483
- compute();
37484
- if (reactNative.Platform.OS === 'web') {
37485
- window.addEventListener('resize', debouncedCompute, { passive: true });
36754
+ update();
36755
+ if (reactNative.Platform.OS === 'web' && typeof window !== 'undefined') {
36756
+ window.addEventListener('resize', debouncedUpdate, { passive: true });
37486
36757
  return () => {
37487
- window.removeEventListener('resize', debouncedCompute);
36758
+ window.removeEventListener('resize', debouncedUpdate);
37488
36759
  clearTimeout(timeoutId);
37489
36760
  };
37490
36761
  }
37491
- return () => clearTimeout(timeoutId);
36762
+ const subscription = reactNative.Dimensions.addEventListener('change', debouncedUpdate);
36763
+ return () => {
36764
+ subscription === null || subscription === void 0 ? void 0 : subscription.remove();
36765
+ clearTimeout(timeoutId);
36766
+ };
37492
36767
  }, []);
37493
- return breakpoint;
36768
+ return state;
36769
+ };
36770
+ const parseMediaQuery = (query) => {
36771
+ const minMatch = query.match(/min-width:\s*(\d+)px/);
36772
+ const maxMatch = query.match(/max-width:\s*(\d+)px/);
36773
+ return {
36774
+ min: minMatch ? parseInt(minMatch[1], 10) : undefined,
36775
+ max: maxMatch ? parseInt(maxMatch[1], 10) : undefined,
36776
+ };
36777
+ };
36778
+ const matchQuery = (query, width) => {
36779
+ const { min, max } = parseMediaQuery(query);
36780
+ if (min != null && width < min)
36781
+ return false;
36782
+ if (max != null && width > max)
36783
+ return false;
36784
+ return true;
36785
+ };
36786
+ const mergeBreakpointProps = (baseProps, breakpointProps, width) => {
36787
+ if (!breakpointProps)
36788
+ return baseProps;
36789
+ const sortedEntries = Object.entries(breakpointProps).sort((a, b) => {
36790
+ var _a, _b;
36791
+ const aMin = (_a = parseMediaQuery(a[0]).min) !== null && _a !== void 0 ? _a : 0;
36792
+ const bMin = (_b = parseMediaQuery(b[0]).min) !== null && _b !== void 0 ? _b : 0;
36793
+ return aMin - bMin;
36794
+ });
36795
+ let resolvedProps = { ...baseProps };
36796
+ sortedEntries.forEach(([query, value]) => {
36797
+ const shouldApply = width != null ? matchQuery(query, width) : (reactNative.Platform.OS === 'web' && typeof window !== 'undefined' ? window.matchMedia(query).matches : false);
36798
+ if (shouldApply) {
36799
+ resolvedProps = { ...resolvedProps, ...value };
36800
+ }
36801
+ });
36802
+ return resolvedProps;
37494
36803
  };
37495
- const Carousel = (props) => {
37496
- const { children, orientation = 'horizontal', height = 200, w = 300, showDots = true, showArrows = true, loop = true, autoPlay = false, autoPlayInterval = 3000, itemsPerPage = 1, slideSize, slideGap, itemGap = 16, onSlideChange, style, itemStyle, arrowSize = 'md', dotSize = 'md', // currently uniform size; active expands
36804
+ const Carousel = (incomingProps) => {
36805
+ const { breakpoint, width: viewportWidth } = useOptimizedBreakpoint();
36806
+ const mergedProps = React.useMemo(() => mergeBreakpointProps(incomingProps, incomingProps.breakpoints, viewportWidth), [incomingProps, viewportWidth]);
36807
+ const { children, orientation = 'horizontal', height = 200, showDots = true, showArrows = true, loop = true, autoPlay = false, autoPlayInterval = 3000, itemsPerPage = 1, slidesToScroll, slideSize, slideGap, itemGap = 16, containScroll = 'trimSnaps', startIndex, align = 'start', dragFree = false, skipSnaps = true, dragThreshold, duration, breakpoints: _breakpoints, onSlideChange, style, itemStyle, arrowSize = 'md', dotSize = 'md', // currently uniform size; active expands
37497
36808
  snapToItem = true, // kept for API parity (engine handles snapping)
37498
36809
  windowSize = 0, // 0 means no virtualization
37499
- reducedMotion = false, ...rest } = props;
36810
+ reducedMotion = false, ...rest } = mergedProps;
37500
36811
  const { spacingProps, otherProps } = extractSpacingProps(rest);
37501
36812
  const spacingStyles = getSpacingStyles(spacingProps);
37502
36813
  const theme = useTheme();
@@ -37508,10 +36819,9 @@ const Carousel = (props) => {
37508
36819
  // progress holds absolute item progress (fractional, not modulo) supplied by engine
37509
36820
  const progress = Animated.useSharedValue(0);
37510
36821
  const [currentIndex, setCurrentIndex] = React.useState(0);
36822
+ const hasInitializedRef = React.useRef(false);
37511
36823
  const itemsArray = React.useMemo(() => React.Children.toArray(children), [children]);
37512
36824
  const totalItems = itemsArray.length;
37513
- // Use optimized breakpoint detection with debouncing
37514
- const breakpoint = useOptimizedBreakpoint();
37515
36825
  const resolvedGap = React.useMemo(() => {
37516
36826
  const raw = resolveResponsive(slideGap, breakpoint);
37517
36827
  if (raw == null)
@@ -37526,7 +36836,7 @@ const Carousel = (props) => {
37526
36836
  }, [slideGap, breakpoint, itemGap]);
37527
36837
  const isVertical = orientation === 'vertical';
37528
36838
  const containerSize = isVertical ? containerHeight : containerWidth;
37529
- const itemSize = React.useMemo(() => {
36839
+ const desiredItemSize = React.useMemo(() => {
37530
36840
  if (containerSize <= 0)
37531
36841
  return 0;
37532
36842
  const rawSize = resolveResponsive(slideSize, breakpoint);
@@ -37552,28 +36862,166 @@ const Carousel = (props) => {
37552
36862
  }
37553
36863
  return (containerSize - resolvedGap * (itemsPerPage - 1)) / itemsPerPage;
37554
36864
  }, [slideSize, breakpoint, containerSize, itemsPerPage, resolvedGap]);
36865
+ const hasLayout = isVertical ? containerHeight > 0 : containerWidth > 0;
36866
+ const baseItemsPerPage = Math.max(1, itemsPerPage);
36867
+ const slidesToScrollValue = Math.max(1, slidesToScroll !== null && slidesToScroll !== void 0 ? slidesToScroll : baseItemsPerPage);
36868
+ const containMode = containScroll === false
36869
+ ? 'none'
36870
+ : containScroll === 'keepSnaps'
36871
+ ? 'keepSnaps'
36872
+ : 'trimSnaps';
36873
+ const isDragFree = !!dragFree;
36874
+ const allowSkipSnaps = skipSnaps !== null && skipSnaps !== void 0 ? skipSnaps : true;
36875
+ const dragThresholdValue = typeof dragThreshold === 'number'
36876
+ ? Math.max(dragThreshold, 0)
36877
+ : undefined;
36878
+ const visibleSlides = React.useMemo(() => {
36879
+ if (!hasLayout || containerSize <= 0)
36880
+ return baseItemsPerPage;
36881
+ if (desiredItemSize <= 0)
36882
+ return baseItemsPerPage;
36883
+ const maxFit = Math.max(1, Math.floor((containerSize + resolvedGap) / (desiredItemSize + resolvedGap)));
36884
+ if (slideSize == null) {
36885
+ return Math.min(baseItemsPerPage, maxFit);
36886
+ }
36887
+ return maxFit;
36888
+ }, [hasLayout, containerSize, desiredItemSize, resolvedGap, baseItemsPerPage, slideSize]);
36889
+ const cardSize = React.useMemo(() => {
36890
+ if (!hasLayout)
36891
+ return desiredItemSize;
36892
+ if (visibleSlides <= 1) {
36893
+ if (desiredItemSize > 0)
36894
+ return desiredItemSize;
36895
+ return containerSize > 0 ? containerSize : desiredItemSize;
36896
+ }
36897
+ const totalGap = resolvedGap * (visibleSlides - 1);
36898
+ const available = Math.max(containerSize - totalGap, 0);
36899
+ return available / visibleSlides;
36900
+ }, [hasLayout, desiredItemSize, visibleSlides, resolvedGap, containerSize]);
36901
+ const slideExtent = React.useMemo(() => {
36902
+ if (!hasLayout || cardSize <= 0)
36903
+ return undefined;
36904
+ return cardSize + resolvedGap;
36905
+ }, [hasLayout, cardSize, resolvedGap]);
36906
+ const scrollStep = React.useMemo(() => {
36907
+ if (totalItems === 0)
36908
+ return slidesToScrollValue;
36909
+ return Math.min(slidesToScrollValue, Math.max(1, totalItems));
36910
+ }, [slidesToScrollValue, totalItems]);
36911
+ const maxScrollDistancePerSwipe = React.useMemo(() => {
36912
+ if (allowSkipSnaps || slideExtent == null)
36913
+ return undefined;
36914
+ return slideExtent * scrollStep;
36915
+ }, [allowSkipSnaps, slideExtent, scrollStep]);
36916
+ const lastStart = React.useMemo(() => Math.max(totalItems - visibleSlides, 0), [totalItems, visibleSlides]);
36917
+ const pageStartIndices = React.useMemo(() => {
36918
+ if (totalItems === 0)
36919
+ return [];
36920
+ if (loop) {
36921
+ const count = Math.max(1, Math.ceil(totalItems / scrollStep));
36922
+ return Array.from({ length: count }, (_, idx) => (idx * scrollStep) % totalItems);
36923
+ }
36924
+ const starts = [];
36925
+ const seen = new Set();
36926
+ const limit = containMode === 'none' ? Math.max(totalItems - 1, 0) : lastStart;
36927
+ const addStart = (value) => {
36928
+ if (!seen.has(value)) {
36929
+ seen.add(value);
36930
+ starts.push(Math.max(0, value));
36931
+ }
36932
+ };
36933
+ for (let start = 0; start <= limit; start += scrollStep) {
36934
+ const value = containMode === 'trimSnaps'
36935
+ ? Math.min(start, lastStart)
36936
+ : start;
36937
+ addStart(value);
36938
+ }
36939
+ if (containMode !== 'trimSnaps') {
36940
+ addStart(lastStart);
36941
+ }
36942
+ starts.sort((a, b) => a - b);
36943
+ return starts;
36944
+ }, [totalItems, loop, scrollStep, containMode, lastStart]);
36945
+ const pagedItems = React.useMemo(() => {
36946
+ if (!totalItems)
36947
+ return [];
36948
+ return pageStartIndices.map(start => {
36949
+ const group = [];
36950
+ for (let offset = 0; offset < visibleSlides; offset++) {
36951
+ const targetIndex = start + offset;
36952
+ if (loop) {
36953
+ const normalized = ((targetIndex % totalItems) + totalItems) % totalItems;
36954
+ group.push(itemsArray[normalized]);
36955
+ }
36956
+ else if (targetIndex < totalItems) {
36957
+ group.push(itemsArray[targetIndex]);
36958
+ }
36959
+ }
36960
+ return group;
36961
+ });
36962
+ }, [pageStartIndices, visibleSlides, loop, totalItems, itemsArray]);
36963
+ const totalPages = pagedItems.length;
36964
+ const normalizedStartIndex = React.useMemo(() => {
36965
+ if (!totalItems)
36966
+ return 0;
36967
+ const rawIndex = startIndex !== null && startIndex !== void 0 ? startIndex : 0;
36968
+ if (loop) {
36969
+ return ((rawIndex % totalItems) + totalItems) % totalItems;
36970
+ }
36971
+ return Math.max(0, Math.min(rawIndex, Math.max(totalItems - 1, 0)));
36972
+ }, [startIndex, totalItems, loop]);
36973
+ const initialPageStart = React.useMemo(() => {
36974
+ if (!totalItems)
36975
+ return 0;
36976
+ const base = Math.floor(normalizedStartIndex / scrollStep) * scrollStep;
36977
+ if (loop) {
36978
+ return totalItems ? base % totalItems : 0;
36979
+ }
36980
+ if (containMode === 'none') {
36981
+ return Math.min(base, Math.max(totalItems - 1, 0));
36982
+ }
36983
+ if (containMode === 'keepSnaps') {
36984
+ return Math.min(base, Math.max(totalItems - 1, 0));
36985
+ }
36986
+ return Math.min(base, lastStart);
36987
+ }, [normalizedStartIndex, scrollStep, loop, totalItems, containMode, lastStart]);
36988
+ const initialPageIndex = React.useMemo(() => {
36989
+ if (!pageStartIndices.length)
36990
+ return 0;
36991
+ const idx = pageStartIndices.indexOf(initialPageStart);
36992
+ return idx >= 0 ? idx : 0;
36993
+ }, [pageStartIndices, initialPageStart]);
37555
36994
  const handleLayout = React.useCallback((e) => {
37556
36995
  setContainerWidth(e.nativeEvent.layout.width);
37557
36996
  setContainerHeight(e.nativeEvent.layout.height);
37558
36997
  }, []);
37559
- const goTo = React.useCallback((index) => {
37560
- if (!carouselRef.current)
37561
- return;
37562
- if (totalItems === 0)
36998
+ const scrollToPage = React.useCallback((index, animated = true) => {
36999
+ if (!carouselRef.current || totalPages === 0)
37563
37000
  return;
37564
- const clamped = ((index % totalItems) + totalItems) % totalItems;
37001
+ const clamped = ((index % totalPages) + totalPages) % totalPages;
37565
37002
  const delta = clamped - currentIndex;
37566
- if (delta === 0)
37003
+ if (delta === 0) {
37004
+ if (!animated) {
37005
+ progress.value = clamped;
37006
+ setCurrentIndex(clamped);
37007
+ }
37567
37008
  return;
37568
- // For looping choose shortest path if loop enabled
37009
+ }
37569
37010
  let count = delta;
37570
37011
  if (loop) {
37571
- const alt = delta > 0 ? delta - totalItems : delta + totalItems;
37012
+ const alt = delta > 0 ? delta - totalPages : delta + totalPages;
37572
37013
  if (Math.abs(alt) < Math.abs(count))
37573
37014
  count = alt;
37574
37015
  }
37575
- carouselRef.current.scrollTo({ count, animated: true });
37576
- }, [carouselRef, totalItems, currentIndex, loop]);
37016
+ carouselRef.current.scrollTo({ count, animated });
37017
+ if (!animated) {
37018
+ progress.value = clamped;
37019
+ setCurrentIndex(clamped);
37020
+ }
37021
+ }, [carouselRef, totalPages, currentIndex, loop, progress]);
37022
+ const goTo = React.useCallback((index) => {
37023
+ scrollToPage(index, true);
37024
+ }, [scrollToPage]);
37577
37025
  const goPrev = React.useCallback(() => {
37578
37026
  if (!carouselRef.current)
37579
37027
  return;
@@ -37584,13 +37032,22 @@ const Carousel = (props) => {
37584
37032
  return;
37585
37033
  carouselRef.current.next();
37586
37034
  }, []);
37587
- const totalPages = React.useMemo(() => totalItems, [totalItems]);
37588
37035
  // Page progress derived directly from absolute item progress
37589
37036
  const pageProgress = Animated.useDerivedValue(() => {
37590
37037
  return progress.value;
37591
37038
  }, []);
37592
37039
  const arrowMetrics = React.useMemo(() => resolveCarouselArrowMetrics(arrowSize), [arrowSize]);
37593
37040
  const dotMetrics = React.useMemo(() => resolveCarouselDotMetrics(dotSize), [dotSize]);
37041
+ const alignJustify = React.useMemo(() => {
37042
+ switch (align) {
37043
+ case 'center':
37044
+ return 'center';
37045
+ case 'end':
37046
+ return 'flex-end';
37047
+ default:
37048
+ return 'flex-start';
37049
+ }
37050
+ }, [align]);
37594
37051
  // Memoized render functions to prevent unnecessary re-renders
37595
37052
  const renderDots = React.useMemo(() => {
37596
37053
  if (!showDots || totalPages <= 1)
@@ -37606,7 +37063,7 @@ const Carousel = (props) => {
37606
37063
  }, [showDots, totalPages, pageProgress, dotMetrics, loop, theme, goTo, isVertical, isRTL]);
37607
37064
  // Arrows
37608
37065
  const renderArrows = () => {
37609
- if (!showArrows || totalItems <= 1)
37066
+ if (!showArrows || totalPages <= 1)
37610
37067
  return null;
37611
37068
  const buttonSize = arrowMetrics.buttonSizeToken;
37612
37069
  const iconSize = arrowMetrics.iconSize;
@@ -37643,37 +37100,69 @@ const Carousel = (props) => {
37643
37100
  }, children: jsxRuntime.jsx(Button, { size: buttonSize, variant: "secondary", icon: jsxRuntime.jsx(Icon, { name: isRTL ? 'chevron-left' : 'chevron-right', size: iconSize }), onPress: goNext, radius: "full" }) })] }));
37644
37101
  };
37645
37102
  // Autoplay: if library autoPlay not sufficient for pause logic, we can just pass through for now.
37646
- const enableAutoPlay = autoPlay && totalItems > 1;
37103
+ const enableAutoPlay = autoPlay && totalPages > 1;
37104
+ React.useEffect(() => {
37105
+ if (!carouselRef.current || totalPages === 0 || !hasLayout)
37106
+ return;
37107
+ const controlledStart = startIndex != null;
37108
+ if (controlledStart) {
37109
+ scrollToPage(initialPageIndex, false);
37110
+ return;
37111
+ }
37112
+ if (!hasInitializedRef.current) {
37113
+ scrollToPage(initialPageIndex, false);
37114
+ hasInitializedRef.current = true;
37115
+ }
37116
+ }, [scrollToPage, initialPageIndex, startIndex, totalPages, hasLayout]);
37647
37117
  return (jsxRuntime.jsxs(reactNative.View, { ref: containerRef, style: [
37648
37118
  {
37119
+ width: '100%',
37649
37120
  position: 'relative',
37650
37121
  ...(isVertical ? { flexDirection: 'row' } : {})
37651
37122
  },
37652
37123
  spacingStyles,
37653
37124
  style
37654
- ], onLayout: handleLayout, ...otherProps, children: [jsxRuntime.jsx(reactNative.View, { style: { flex: 1 }, children: itemSize > 0 && (jsxRuntime.jsx(ReanimatedCarousel, { ref: carouselRef, width: isVertical ? containerWidth : itemSize, height: isVertical ? itemSize : height, style: isVertical ? { height: containerHeight } : { width: containerWidth }, vertical: isVertical, loop: loop, autoPlay: enableAutoPlay, autoPlayInterval: autoPlayInterval, data: itemsArray, pagingEnabled: snapToItem, windowSize: windowSize > 0 ? windowSize : undefined,
37125
+ ], onLayout: handleLayout, ...otherProps, children: [jsxRuntime.jsx(reactNative.View, { style: { flex: 1 }, children: hasLayout && pagedItems.length > 0 && cardSize > 0 && (jsxRuntime.jsx(ReanimatedCarousel, { ref: carouselRef, width: isVertical ? containerWidth : containerWidth, height: isVertical ? containerHeight : height, style: isVertical ? { height: containerHeight } : { width: containerWidth }, vertical: isVertical, loop: loop, autoPlay: enableAutoPlay, autoPlayInterval: autoPlayInterval, data: pagedItems, pagingEnabled: isDragFree ? false : snapToItem, snapEnabled: isDragFree ? false : undefined, windowSize: windowSize > 0 ? windowSize : undefined, scrollAnimationDuration: duration,
37655
37126
  // Performance optimizations
37656
37127
  overscrollEnabled: false, enabled: !reducedMotion, withAnimation: reducedMotion ?
37657
37128
  { type: 'timing', config: { duration: 100 } } :
37658
- { type: 'spring', config: { damping: 60, stiffness: 150 } }, onProgressChange: (offset, absolute) => {
37129
+ { type: 'spring', config: { damping: 60, stiffness: 150 } }, maxScrollDistancePerSwipe: maxScrollDistancePerSwipe, minScrollDistancePerSwipe: dragThresholdValue, onProgressChange: (offset, absolute) => {
37659
37130
  // absolute may be undefined in some versions; fallback to offset
37660
37131
  const val = typeof absolute === 'number' ? absolute : offset;
37661
37132
  progress.value = val;
37662
- const ci = ((Math.round(val) % totalItems) + totalItems) % totalItems;
37133
+ const ci = totalPages > 0
37134
+ ? ((Math.round(val) % totalPages) + totalPages) % totalPages
37135
+ : 0;
37663
37136
  if (ci !== currentIndex) {
37664
37137
  setCurrentIndex(ci);
37665
37138
  onSlideChange === null || onSlideChange === void 0 ? void 0 : onSlideChange(ci);
37666
37139
  }
37667
- }, renderItem: ({ item, index }) => (jsxRuntime.jsx(reactNative.View, { style: [
37668
- {
37669
- width: isVertical ? containerWidth : itemSize,
37670
- height: isVertical ? itemSize : height,
37671
- ...(isVertical
37672
- ? { marginBottom: index < itemsArray.length - 1 ? resolvedGap : 0 }
37673
- : { marginRight: index < itemsArray.length - 1 ? resolvedGap : 0 }),
37674
- },
37675
- itemStyle,
37676
- ], accessibilityLabel: `Carousel item ${index + 1} of ${totalItems}`, children: item })) })) }), renderArrows(), renderDots] }));
37140
+ }, renderItem: ({ item, index }) => {
37141
+ const pageItems = Array.isArray(item) ? item : [item];
37142
+ const pageWidth = isVertical ? containerWidth : containerWidth;
37143
+ const pageHeight = isVertical ? containerHeight : height;
37144
+ const justify = containMode === 'trimSnaps' ? 'flex-start' : alignJustify;
37145
+ return (jsxRuntime.jsx(reactNative.View, { style: [
37146
+ {
37147
+ width: pageWidth,
37148
+ height: pageHeight,
37149
+ justifyContent: 'center',
37150
+ },
37151
+ itemStyle,
37152
+ ], accessibilityLabel: `Carousel item ${index + 1} of ${totalPages}`, children: jsxRuntime.jsx(reactNative.View, { style: {
37153
+ flexDirection: isVertical ? 'column' : 'row',
37154
+ alignItems: 'stretch',
37155
+ justifyContent: justify,
37156
+ flexWrap: 'nowrap',
37157
+ flex: 1,
37158
+ }, children: pageItems.map((child, childIndex) => (jsxRuntime.jsx(reactNative.View, { style: {
37159
+ width: isVertical ? '100%' : cardSize,
37160
+ height: isVertical ? cardSize : '100%',
37161
+ marginRight: !isVertical && childIndex < pageItems.length - 1 ? resolvedGap : 0,
37162
+ marginBottom: isVertical && childIndex < pageItems.length - 1 ? resolvedGap : 0,
37163
+ flexShrink: 0,
37164
+ }, children: child }, childIndex))) }) }));
37165
+ } })) }), renderArrows(), renderDots] }));
37677
37166
  };
37678
37167
 
37679
37168
  // Types extracted to types.ts
@@ -39594,11 +39083,14 @@ QRCodeSVG.displayName = 'QRCodeSVG';
39594
39083
  */
39595
39084
  function QRCode(props) {
39596
39085
  var _a;
39086
+ const theme = useTheme();
39597
39087
  const { spacingProps, otherProps: propsAfterSpacing } = extractSpacingProps(props);
39598
39088
  const { layoutProps, otherProps } = extractLayoutProps(propsAfterSpacing);
39599
- const { value, size = 400, backgroundColor = 'transparent', color = '#000000', errorCorrectionLevel = 'M', quietZone = 4, logo, style, testID, accessibilityLabel, onError, onLoadStart, // deprecated noop
39089
+ const { value, size = 400, backgroundColor = 'transparent', color, errorCorrectionLevel = 'M', quietZone = 4, logo, style, testID, accessibilityLabel, onError, onLoadStart, // deprecated noop
39600
39090
  onLoadEnd, // deprecated noop
39601
39091
  ...rest } = otherProps;
39092
+ // Default color to theme's primary text color for dark mode support
39093
+ const resolvedColor = color !== null && color !== void 0 ? color : theme.text.primary;
39602
39094
  const { copy } = useClipboard();
39603
39095
  const toast = useToast();
39604
39096
  const shouldCopyOnPress = !!otherProps.copyOnPress;
@@ -39614,7 +39106,7 @@ function QRCode(props) {
39614
39106
  });
39615
39107
  }
39616
39108
  }, [copy, copyValue, toast, otherProps.copyToastMessage, otherProps.copyToastTitle]);
39617
- const content = (jsxRuntime.jsxs(reactNative.View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [jsxRuntime.jsx(QRCodeSVG, { value: value, size: size, maxWidth: '100%', backgroundColor: backgroundColor, color: color, errorCorrectionLevel: errorCorrectionLevel, quietZone: quietZone, logo: logo, style: style, testID: testID, accessibilityLabel: accessibilityLabel, onError: onError, ...spacingProps, ...layoutProps, ...rest }), otherProps.showCopyButton && (jsxRuntime.jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
39109
+ const content = (jsxRuntime.jsxs(reactNative.View, { style: { borderRadius: 8, overflow: 'hidden' }, children: [jsxRuntime.jsx(QRCodeSVG, { value: value, size: size, maxWidth: '100%', backgroundColor: backgroundColor, color: resolvedColor, errorCorrectionLevel: errorCorrectionLevel, quietZone: quietZone, logo: logo, style: style, testID: testID, accessibilityLabel: accessibilityLabel, onError: onError, ...spacingProps, ...layoutProps, ...rest }), otherProps.showCopyButton && (jsxRuntime.jsx(CopyButton, { value: copyValue, iconOnly: true, size: "sm", style: { position: 'absolute', top: 8, right: 8 }, onCopy: () => { } }))] }));
39618
39110
  if (shouldCopyOnPress) {
39619
39111
  return (jsxRuntime.jsx(reactNative.Pressable, { onPress: handleCopy, accessibilityLabel: accessibilityLabel || 'QR code', children: content }));
39620
39112
  }
@@ -41687,7 +41179,6 @@ function withPressAnimation(Component, animationProps) {
41687
41179
  */
41688
41180
  const AnimatedPressable = PressAnimation;
41689
41181
 
41690
- exports.AbilityCore = AbilityCore;
41691
41182
  exports.AccessibilityProvider = AccessibilityProvider;
41692
41183
  exports.Accordion = Accordion;
41693
41184
  exports.AmazonAppstoreBadge = AmazonAppstoreBadge;
@@ -41727,9 +41218,6 @@ exports.Button = Button;
41727
41218
  exports.COMPONENT_SIZES = COMPONENT_SIZES$1;
41728
41219
  exports.COMPONENT_SIZE_ORDER = COMPONENT_SIZE_ORDER;
41729
41220
  exports.Calendar = Calendar;
41730
- exports.Can = Can;
41731
- exports.CanWithConditions = CanWithConditions;
41732
- exports.Cannot = Cannot;
41733
41221
  exports.Card = Card;
41734
41222
  exports.Carousel = Carousel;
41735
41223
  exports.Checkbox = Checkbox;
@@ -41790,7 +41278,6 @@ exports.Heading4 = Heading4;
41790
41278
  exports.Heading5 = Heading5;
41791
41279
  exports.Heading6 = Heading6;
41792
41280
  exports.Highlight = Highlight;
41793
- exports.HoverCard = HoverCard;
41794
41281
  exports.HuaweiAppGalleryBadge = HuaweiAppGalleryBadge;
41795
41282
  exports.I18nProvider = I18nProvider;
41796
41283
  exports.Icon = Icon;
@@ -41828,7 +41315,6 @@ exports.MiniCalendar = MiniCalendar;
41828
41315
  exports.Month = Month;
41829
41316
  exports.MonthPicker = MonthPicker;
41830
41317
  exports.MonthPickerInput = MonthPickerInput;
41831
- exports.NavigationProgress = NavigationProgress;
41832
41318
  exports.Notice = Notice;
41833
41319
  exports.NumberInput = NumberInput;
41834
41320
  exports.Overlay = Overlay;
@@ -41836,10 +41322,6 @@ exports.OverlayProvider = OverlayProvider;
41836
41322
  exports.P = P;
41837
41323
  exports.Pagination = Pagination;
41838
41324
  exports.PasswordInput = PasswordInput;
41839
- exports.PermissionBuilder = PermissionBuilder;
41840
- exports.PermissionGate = PermissionGate;
41841
- exports.PermissionPatterns = PermissionPatterns;
41842
- exports.PermissionProvider = PermissionProvider;
41843
41325
  exports.PhoneInput = PhoneInput;
41844
41326
  exports.PinInput = PinInput;
41845
41327
  exports.PlatformBlocksProvider = PlatformBlocksProvider;
@@ -41854,7 +41336,6 @@ exports.Rating = Rating;
41854
41336
  exports.RedditJoinBadge = RedditJoinBadge;
41855
41337
  exports.RichTextEditor = RichTextEditor;
41856
41338
  exports.Ring = Ring;
41857
- exports.RoleBuilder = RoleBuilder;
41858
41339
  exports.Row = Row;
41859
41340
  exports.SIZE_SCALES = SIZE_SCALES;
41860
41341
  exports.Search = Search;
@@ -41912,9 +41393,7 @@ exports.createSound = createSound;
41912
41393
  exports.createSpotlightStore = createSpotlightStore;
41913
41394
  exports.createTheme = createTheme;
41914
41395
  exports.debounce = debounce$1;
41915
- exports.defineAbility = defineAbility;
41916
41396
  exports.defineAppLayout = defineAppLayout;
41917
- exports.defineRoleAbility = defineRoleAbility;
41918
41397
  exports.directSpotlight = directSpotlight;
41919
41398
  exports.extractDisclaimerProps = extractDisclaimerProps;
41920
41399
  exports.factory = factory;
@@ -41935,11 +41414,9 @@ exports.globalHotkeys = globalHotkeys;
41935
41414
  exports.measureAsyncPerformance = measureAsyncPerformance;
41936
41415
  exports.measureElement = measureElement;
41937
41416
  exports.measurePerformance = measurePerformance;
41938
- exports.navigationProgress = navigationProgress;
41939
41417
  exports.onDialogsRequested = onDialogsRequested;
41940
41418
  exports.onSpotlightRequested = onSpotlightRequested;
41941
41419
  exports.onToastsRequested = onToastsRequested;
41942
- exports.permissions = permissions;
41943
41420
  exports.pointInRect = pointInRect;
41944
41421
  exports.polymorphicFactory = polymorphicFactory;
41945
41422
  exports.px = px;
@@ -41950,7 +41427,6 @@ exports.resolveResponsiveValue = resolveResponsiveValue;
41950
41427
  exports.resolveSize = resolveSize;
41951
41428
  exports.spotlight = spotlight;
41952
41429
  exports.throttle = throttle;
41953
- exports.useAbility = useAbility;
41954
41430
  exports.useAccessibility = useAccessibility;
41955
41431
  exports.useAppLayoutContext = useAppLayoutContext;
41956
41432
  exports.useAppShell = useAppShell;
@@ -41980,7 +41456,6 @@ exports.useOptionalFormContext = useOptionalFormContext;
41980
41456
  exports.useOverlay = useOverlay;
41981
41457
  exports.useOverlayApi = useOverlayApi;
41982
41458
  exports.useOverlays = useOverlays;
41983
- exports.usePermissions = usePermissions;
41984
41459
  exports.usePopoverPositioning = usePopoverPositioning;
41985
41460
  exports.useSimpleDialog = useSimpleDialog;
41986
41461
  exports.useSound = useSound;
@@ -41995,8 +41470,6 @@ exports.useToast = useToast;
41995
41470
  exports.useToastApi = useToastApi;
41996
41471
  exports.useToggleColorScheme = useToggleColorScheme;
41997
41472
  exports.useTooltipPositioning = useTooltipPositioning;
41998
- exports.withCan = withCan;
41999
- exports.withCannot = withCannot;
42000
41473
  exports.withDisclaimer = withDisclaimer;
42001
41474
  exports.withPressAnimation = withPressAnimation;
42002
41475
  //# sourceMappingURL=index.js.map