@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.
- package/lib/cjs/index.js +684 -1211
- package/lib/cjs/index.js.map +1 -1
- package/lib/components/Avatar/Avatar.d.ts +1 -1
- package/lib/components/Avatar/types.d.ts +3 -3
- package/lib/components/Carousel/types.d.ts +32 -0
- package/lib/components/DataTable/DataTable.d.ts +1 -1
- package/lib/components/DataTable/types.d.ts +2 -0
- package/lib/components/HoverCard/types.d.ts +4 -2
- package/lib/components/Popover/types.d.ts +2 -0
- package/lib/components/Slider/types.d.ts +29 -1
- package/lib/components/Switch/styles.d.ts +1 -1
- package/lib/components/TextArea/styles.d.ts +1 -1
- package/lib/components/index.d.ts +0 -2
- package/lib/core/providers/OverlayProvider.d.ts +1 -1
- package/lib/core/theme/PlatformBlocksProvider.d.ts +1 -5
- package/lib/esm/index.js +685 -1193
- package/lib/esm/index.js.map +1 -1
- package/lib/index.d.ts +0 -7
- package/package.json +1 -1
- package/lib/components/Can/Can.d.ts +0 -30
- package/lib/components/Can/PermissionDemo.d.ts +0 -2
- package/lib/components/Can/ability.d.ts +0 -89
- package/lib/components/Can/builder.d.ts +0 -113
- package/lib/components/Can/context.d.ts +0 -25
- package/lib/components/Can/index.d.ts +0 -6
- package/lib/components/Can/types.d.ts +0 -230
- package/lib/components/HoverCard/index.d.ts +0 -2
- package/lib/components/NavigationProgress/NavigationProgress.d.ts +0 -4
- package/lib/components/NavigationProgress/defaults.d.ts +0 -8
- package/lib/components/NavigationProgress/hooks/useNavigationProgressState.d.ts +0 -1
- package/lib/components/NavigationProgress/index.d.ts +0 -2
- package/lib/components/NavigationProgress/styles/resolver.d.ts +0 -1
- package/lib/components/NavigationProgress/tokens.d.ts +0 -4
- 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
|
|
6240
|
-
|
|
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 &&
|
|
6244
|
-
? { minWidth:
|
|
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:
|
|
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.
|
|
10510
|
-
return
|
|
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
|
|
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
|
|
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
|
-
:
|
|
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 &&
|
|
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
|
-
:
|
|
18013
|
-
? theme.backgrounds.border
|
|
18014
|
-
: 'transparent',
|
|
17455
|
+
: theme.backgrounds.border,
|
|
18015
17456
|
borderRadius: DESIGN_TOKENS.radius.lg,
|
|
18016
|
-
borderWidth:
|
|
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
|
-
|
|
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',
|
|
19875
|
-
: { gap: 'sm',
|
|
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 =
|
|
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
|
|
21073
|
-
const
|
|
21074
|
-
const
|
|
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:
|
|
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
|
|
20524
|
+
const activeTrackBaseStyle = {
|
|
21080
20525
|
position: 'absolute',
|
|
21081
|
-
backgroundColor: disabled ? theme.colors.gray[4] : theme.colors.primary[5],
|
|
21082
|
-
borderRadius:
|
|
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
|
-
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
|
|
21091
|
-
|
|
21092
|
-
|
|
21093
|
-
|
|
21094
|
-
|
|
21095
|
-
|
|
21096
|
-
|
|
21097
|
-
|
|
21098
|
-
|
|
21099
|
-
|
|
21100
|
-
|
|
21101
|
-
|
|
21102
|
-
|
|
21103
|
-
|
|
21104
|
-
|
|
21105
|
-
|
|
21106
|
-
|
|
21107
|
-
|
|
21108
|
-
|
|
21109
|
-
|
|
21110
|
-
|
|
21111
|
-
|
|
21112
|
-
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
|
|
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
|
|
21122
|
-
const
|
|
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:
|
|
21127
|
-
left: (
|
|
20584
|
+
top: resolvedThumbSize / 2 + tick.position,
|
|
20585
|
+
left: (resolvedThumbSize - resolvedTrackHeight) / 2 - 3,
|
|
21128
20586
|
height: 2,
|
|
21129
|
-
width:
|
|
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:
|
|
21137
|
-
left:
|
|
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:
|
|
21145
|
-
top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT -
|
|
20600
|
+
left: resolvedThumbSize / 2 + tick.position,
|
|
20601
|
+
top: (SLIDER_CONSTANTS.CONTAINER_HEIGHT - resolvedTrackHeight) / 2 - 3,
|
|
21146
20602
|
width: 2,
|
|
21147
|
-
height:
|
|
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:
|
|
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
|
|
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:
|
|
21166
|
-
height:
|
|
21167
|
-
backgroundColor:
|
|
21168
|
-
borderRadius:
|
|
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
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
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
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
|
|
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
|
|
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 + (
|
|
21199
|
-
right:
|
|
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 + (
|
|
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:
|
|
21259
|
-
formatter:
|
|
21260
|
-
}), [
|
|
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,
|
|
31572
|
-
sm: { avatar: 32,
|
|
31573
|
-
md: { avatar: 40,
|
|
31574
|
-
lg: { avatar: 48,
|
|
31575
|
-
xl: { avatar: 64,
|
|
31576
|
-
'2xl': { avatar: 80,
|
|
31577
|
-
'3xl': { avatar: 96,
|
|
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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32430
|
-
|
|
32431
|
-
|
|
32432
|
-
|
|
32433
|
-
|
|
32434
|
-
|
|
32435
|
-
|
|
32436
|
-
|
|
32437
|
-
|
|
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
|
-
|
|
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
|
-
:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
37463
|
-
const
|
|
37464
|
-
|
|
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
|
|
36750
|
+
const debouncedUpdate = () => {
|
|
37480
36751
|
clearTimeout(timeoutId);
|
|
37481
|
-
timeoutId = setTimeout(
|
|
36752
|
+
timeoutId = setTimeout(update, 100); // Debounce resize events
|
|
37482
36753
|
};
|
|
37483
|
-
|
|
37484
|
-
if (reactNative.Platform.OS === 'web') {
|
|
37485
|
-
window.addEventListener('resize',
|
|
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',
|
|
36758
|
+
window.removeEventListener('resize', debouncedUpdate);
|
|
37488
36759
|
clearTimeout(timeoutId);
|
|
37489
36760
|
};
|
|
37490
36761
|
}
|
|
37491
|
-
|
|
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
|
|
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 = (
|
|
37496
|
-
const {
|
|
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 } =
|
|
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
|
|
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
|
|
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 %
|
|
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
|
-
|
|
37009
|
+
}
|
|
37569
37010
|
let count = delta;
|
|
37570
37011
|
if (loop) {
|
|
37571
|
-
const alt = delta > 0 ? delta -
|
|
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
|
|
37576
|
-
|
|
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 ||
|
|
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 &&
|
|
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:
|
|
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 =
|
|
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 }) =>
|
|
37668
|
-
|
|
37669
|
-
|
|
37670
|
-
|
|
37671
|
-
|
|
37672
|
-
|
|
37673
|
-
|
|
37674
|
-
|
|
37675
|
-
|
|
37676
|
-
|
|
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
|
|
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:
|
|
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
|