@idealyst/components 1.0.83 → 1.0.84
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/CLAUDE.md +199 -232
- package/README.md +5 -5
- package/package.json +20 -2
- package/plugin/README.md +272 -0
- package/plugin/test-cases.jsx +112 -0
- package/plugin/web-legacy.js +320 -0
- package/plugin/web.js +422 -124
- package/src/Accordion/Accordion.native.tsx +182 -0
- package/src/Accordion/Accordion.styles.tsx +260 -0
- package/src/Accordion/Accordion.web.tsx +147 -0
- package/src/Accordion/index.native.tsx +3 -0
- package/src/Accordion/index.ts +3 -0
- package/src/Accordion/index.web.tsx +3 -0
- package/src/Accordion/types.ts +23 -0
- package/src/ActivityIndicator/ActivityIndicator.native.tsx +17 -12
- package/src/ActivityIndicator/ActivityIndicator.styles.tsx +83 -109
- package/src/ActivityIndicator/ActivityIndicator.web.tsx +23 -17
- package/src/ActivityIndicator/index.ts +5 -2
- package/src/ActivityIndicator/index.web.ts +5 -2
- package/src/ActivityIndicator/types.ts +15 -10
- package/src/Alert/Alert.native.tsx +113 -0
- package/src/Alert/Alert.styles.tsx +304 -0
- package/src/Alert/Alert.web.tsx +123 -0
- package/src/Alert/index.native.ts +5 -0
- package/src/Alert/index.ts +5 -0
- package/src/Alert/index.web.ts +5 -0
- package/src/Alert/types.ts +21 -0
- package/src/Avatar/Avatar.native.tsx +8 -6
- package/src/Avatar/Avatar.styles.tsx +64 -58
- package/src/Avatar/Avatar.web.tsx +13 -8
- package/src/Avatar/index.ts +5 -2
- package/src/Avatar/index.web.ts +5 -2
- package/src/Avatar/types.ts +19 -13
- package/src/Badge/Badge.native.tsx +59 -14
- package/src/Badge/Badge.styles.tsx +125 -139
- package/src/Badge/Badge.web.tsx +72 -16
- package/src/Badge/index.ts +5 -2
- package/src/Badge/index.web.ts +5 -2
- package/src/Badge/types.ts +23 -11
- package/src/Breadcrumb/Breadcrumb.native.tsx +225 -0
- package/src/Breadcrumb/Breadcrumb.styles.tsx +234 -0
- package/src/Breadcrumb/Breadcrumb.web.tsx +268 -0
- package/src/Breadcrumb/index.native.ts +5 -0
- package/src/Breadcrumb/index.ts +5 -0
- package/src/Breadcrumb/index.web.ts +5 -0
- package/src/Breadcrumb/types.ts +56 -0
- package/src/Button/Button.native.tsx +75 -24
- package/src/Button/Button.styles.tsx +248 -205
- package/src/Button/Button.web.tsx +82 -25
- package/src/Button/index.ts +5 -5
- package/src/Button/index.web.ts +5 -3
- package/src/Button/types.ts +32 -15
- package/src/Card/Card.native.tsx +14 -11
- package/src/Card/Card.styles.tsx +146 -220
- package/src/Card/Card.web.tsx +20 -21
- package/src/Card/index.ts +5 -5
- package/src/Card/index.web.ts +5 -3
- package/src/Card/types.ts +24 -17
- package/src/Checkbox/Checkbox.native.tsx +24 -34
- package/src/Checkbox/Checkbox.styles.tsx +223 -275
- package/src/Checkbox/Checkbox.web.tsx +30 -37
- package/src/Checkbox/index.ts +5 -5
- package/src/Checkbox/index.web.ts +5 -3
- package/src/Checkbox/types.ts +26 -20
- package/src/Chip/Chip.native.tsx +126 -0
- package/src/Chip/Chip.styles.tsx +138 -0
- package/src/Chip/Chip.web.tsx +154 -0
- package/src/Chip/index.native.ts +5 -0
- package/src/Chip/index.ts +5 -0
- package/src/Chip/index.web.ts +5 -0
- package/src/Chip/types.ts +51 -0
- package/src/Dialog/Dialog.native.tsx +65 -12
- package/src/Dialog/Dialog.styles.tsx +154 -136
- package/src/Dialog/Dialog.web.tsx +16 -11
- package/src/Dialog/index.ts +5 -2
- package/src/Dialog/index.web.ts +5 -2
- package/src/Dialog/types.ts +22 -16
- package/src/Divider/Divider.native.tsx +19 -14
- package/src/Divider/Divider.styles.tsx +273 -595
- package/src/Divider/Divider.web.tsx +19 -12
- package/src/Divider/index.ts +5 -5
- package/src/Divider/index.web.ts +5 -3
- package/src/Divider/types.ts +28 -19
- package/src/Icon/Icon.native.tsx +17 -24
- package/src/Icon/Icon.styles.tsx +64 -48
- package/src/Icon/Icon.web.tsx +14 -11
- package/src/Icon/IconSvg/IconSvg.native.tsx +42 -0
- package/src/Icon/IconSvg/IconSvg.web.tsx +40 -0
- package/src/Icon/IconSvg/index.native.ts +1 -0
- package/src/Icon/IconSvg/index.ts +1 -0
- package/src/Icon/icon-resolver.native.ts +27 -0
- package/src/Icon/icon-resolver.ts +70 -0
- package/src/Icon/index.ts +5 -5
- package/src/Icon/index.web.ts +5 -3
- package/src/Icon/types.ts +17 -11
- package/src/Image/Image.native.tsx +86 -0
- package/src/Image/Image.styles.tsx +57 -0
- package/src/Image/Image.web.tsx +92 -0
- package/src/Image/index.native.ts +5 -0
- package/src/Image/index.ts +5 -0
- package/src/Image/types.ts +21 -0
- package/src/Input/Input.native.tsx +103 -26
- package/src/Input/Input.styles.tsx +240 -177
- package/src/Input/Input.web.tsx +141 -38
- package/src/Input/index.ts +5 -5
- package/src/Input/index.web.ts +5 -3
- package/src/Input/types.ts +43 -20
- package/src/List/List.native.tsx +56 -0
- package/src/List/List.styles.tsx +257 -0
- package/src/List/List.web.tsx +43 -0
- package/src/List/ListContext.tsx +16 -0
- package/src/List/ListItem.native.tsx +111 -0
- package/src/List/ListItem.web.tsx +110 -0
- package/src/List/ListSection.native.tsx +31 -0
- package/src/List/ListSection.web.tsx +33 -0
- package/src/List/index.native.tsx +5 -0
- package/src/List/index.ts +5 -0
- package/src/List/index.web.tsx +5 -0
- package/src/List/types.ts +42 -0
- package/src/Menu/Menu.native.tsx +150 -0
- package/src/Menu/Menu.styles.tsx +185 -0
- package/src/Menu/Menu.web.tsx +99 -0
- package/src/Menu/MenuItem.native.tsx +66 -0
- package/src/Menu/MenuItem.styles.tsx +119 -0
- package/src/Menu/MenuItem.web.tsx +67 -0
- package/src/Menu/index.native.ts +3 -0
- package/src/Menu/index.ts +3 -0
- package/src/Menu/index.web.ts +3 -0
- package/src/Menu/types.ts +30 -0
- package/src/Popover/Popover.native.tsx +102 -32
- package/src/Popover/Popover.styles.tsx +100 -67
- package/src/Popover/Popover.web.tsx +36 -260
- package/src/Popover/index.ts +5 -2
- package/src/Popover/index.web.ts +5 -2
- package/src/Popover/types.ts +14 -13
- package/src/Pressable/Pressable.native.tsx +7 -6
- package/src/Pressable/Pressable.web.tsx +8 -6
- package/src/Pressable/index.ts +5 -2
- package/src/Pressable/index.web.ts +5 -2
- package/src/Pressable/types.ts +11 -10
- package/src/Progress/Progress.native.tsx +179 -0
- package/src/Progress/Progress.styles.tsx +164 -0
- package/src/Progress/Progress.web.tsx +144 -0
- package/src/Progress/index.native.ts +1 -0
- package/src/Progress/index.ts +5 -0
- package/src/Progress/index.web.ts +5 -0
- package/src/Progress/types.ts +21 -0
- package/src/RadioButton/RadioButton.native.tsx +88 -0
- package/src/RadioButton/RadioButton.styles.tsx +163 -0
- package/src/RadioButton/RadioButton.web.tsx +85 -0
- package/src/RadioButton/RadioGroup.native.tsx +43 -0
- package/src/RadioButton/RadioGroup.web.tsx +49 -0
- package/src/RadioButton/index.native.ts +2 -0
- package/src/RadioButton/index.ts +2 -0
- package/src/RadioButton/index.web.ts +2 -0
- package/src/RadioButton/types.ts +29 -0
- package/src/SVGImage/SVGImage.native.tsx +9 -7
- package/src/SVGImage/SVGImage.styles.tsx +63 -55
- package/src/SVGImage/SVGImage.web.tsx +16 -13
- package/src/SVGImage/index.ts +5 -5
- package/src/SVGImage/index.web.ts +5 -2
- package/src/SVGImage/types.ts +7 -3
- package/src/Screen/Screen.native.tsx +43 -17
- package/src/Screen/Screen.styles.tsx +58 -54
- package/src/Screen/Screen.web.tsx +11 -5
- package/src/Screen/index.ts +5 -2
- package/src/Screen/index.web.ts +5 -2
- package/src/Screen/types.ts +23 -9
- package/src/Select/Select.native.tsx +140 -63
- package/src/Select/Select.styles.tsx +312 -302
- package/src/Select/Select.web.tsx +156 -316
- package/src/Select/index.ts +5 -2
- package/src/Select/index.web.ts +5 -2
- package/src/Select/types.ts +13 -7
- package/src/Skeleton/Skeleton.native.tsx +139 -0
- package/src/Skeleton/Skeleton.styles.tsx +59 -0
- package/src/Skeleton/Skeleton.web.tsx +112 -0
- package/src/Skeleton/index.native.ts +4 -0
- package/src/Skeleton/index.ts +5 -0
- package/src/Skeleton/index.web.ts +5 -0
- package/src/Skeleton/types.ts +75 -0
- package/src/Slider/Slider.native.tsx +248 -0
- package/src/Slider/Slider.styles.tsx +241 -0
- package/src/Slider/Slider.web.tsx +226 -0
- package/src/Slider/index.native.ts +3 -0
- package/src/Slider/index.ts +5 -0
- package/src/Slider/index.web.ts +5 -0
- package/src/Slider/types.ts +31 -0
- package/src/Switch/Switch.native.tsx +131 -0
- package/src/Switch/Switch.styles.tsx +169 -0
- package/src/Switch/Switch.web.tsx +121 -0
- package/src/Switch/index.native.ts +3 -0
- package/src/Switch/index.ts +5 -0
- package/src/Switch/index.web.ts +5 -0
- package/src/Switch/types.ts +21 -0
- package/src/TabBar/TabBar.native.tsx +142 -0
- package/src/TabBar/TabBar.styles.tsx +399 -0
- package/src/TabBar/TabBar.web.tsx +205 -0
- package/src/TabBar/index.native.tsx +3 -0
- package/src/TabBar/index.ts +3 -0
- package/src/TabBar/index.web.tsx +3 -0
- package/src/TabBar/types.ts +26 -0
- package/src/Table/Table.native.tsx +122 -0
- package/src/Table/Table.styles.tsx +283 -0
- package/src/Table/Table.web.tsx +112 -0
- package/src/Table/index.native.tsx +3 -0
- package/src/Table/index.ts +3 -0
- package/src/Table/index.web.tsx +3 -0
- package/src/Table/types.ts +28 -0
- package/src/Text/Text.native.tsx +12 -11
- package/src/Text/Text.styles.tsx +76 -64
- package/src/Text/Text.web.tsx +14 -9
- package/src/Text/index.ts +5 -5
- package/src/Text/index.web.ts +5 -3
- package/src/Text/types.ts +20 -13
- package/src/TextArea/TextArea.native.tsx +134 -0
- package/src/TextArea/TextArea.styles.tsx +175 -0
- package/src/TextArea/TextArea.web.tsx +156 -0
- package/src/TextArea/index.native.ts +3 -0
- package/src/TextArea/index.ts +3 -0
- package/src/TextArea/index.web.ts +3 -0
- package/src/TextArea/types.ts +30 -0
- package/src/Tooltip/Tooltip.native.tsx +165 -0
- package/src/Tooltip/Tooltip.styles.tsx +73 -0
- package/src/Tooltip/Tooltip.web.tsx +87 -0
- package/src/Tooltip/index.native.ts +3 -0
- package/src/Tooltip/index.ts +3 -0
- package/src/Tooltip/types.ts +18 -0
- package/src/Video/Video.native.tsx +105 -0
- package/src/Video/Video.styles.tsx +39 -0
- package/src/Video/Video.web.tsx +115 -0
- package/src/Video/index.native.ts +5 -0
- package/src/Video/index.ts +5 -0
- package/src/Video/types.ts +29 -0
- package/src/View/View.native.tsx +9 -14
- package/src/View/View.styles.tsx +101 -93
- package/src/View/View.web.tsx +16 -17
- package/src/View/index.ts +5 -5
- package/src/View/index.web.ts +5 -3
- package/src/View/types.ts +29 -21
- package/src/examples/AccordionExamples.tsx +126 -0
- package/src/examples/AlertExamples.tsx +280 -0
- package/src/examples/AvatarExamples.tsx +23 -23
- package/src/examples/BadgeExamples.tsx +109 -41
- package/src/examples/BreadcrumbExamples.tsx +312 -0
- package/src/examples/ButtonExamples.tsx +160 -33
- package/src/examples/CardExamples.tsx +40 -40
- package/src/examples/CheckboxExamples.tsx +12 -12
- package/src/examples/ChipExamples.tsx +197 -0
- package/src/examples/DialogExamples.tsx +22 -22
- package/src/examples/DividerExamples.tsx +49 -49
- package/src/examples/IconExamples.tsx +270 -54
- package/src/examples/ImageExamples.tsx +174 -0
- package/src/examples/InputExamples.tsx +75 -17
- package/src/examples/ListExamples.tsx +288 -0
- package/src/examples/MenuExamples.tsx +144 -0
- package/src/examples/PopoverExamples.tsx +69 -73
- package/src/examples/ProgressExamples.tsx +137 -0
- package/src/examples/RadioButtonExamples.tsx +161 -0
- package/src/examples/SVGImageExamples.tsx +19 -17
- package/src/examples/ScreenExamples.tsx +31 -31
- package/src/examples/SelectExamples.tsx +67 -67
- package/src/examples/SkeletonExamples.tsx +206 -0
- package/src/examples/SliderExamples.tsx +200 -0
- package/src/examples/SwitchExamples.tsx +182 -0
- package/src/examples/TabBarExamples.tsx +143 -0
- package/src/examples/TableExamples.tsx +280 -0
- package/src/examples/TextAreaExamples.tsx +173 -0
- package/src/examples/TextExamples.tsx +28 -32
- package/src/examples/ThemeExtensionExamples.tsx +10 -10
- package/src/examples/TooltipExamples.tsx +126 -0
- package/src/examples/VideoExamples.tsx +144 -0
- package/src/examples/ViewExamples.tsx +64 -56
- package/src/examples/index.ts +17 -3
- package/src/hooks/useMergeRefs.ts +16 -0
- package/src/hooks/useSmartPosition.native.ts +169 -0
- package/src/index.native.ts +80 -9
- package/src/index.ts +71 -1
- package/src/internal/BoundedModalContent.native.tsx +58 -0
- package/src/internal/PositionedPortal.tsx +254 -0
- package/src/internal/SafeAreaDebugOverlay.native.tsx +173 -0
- package/src/unistyles.d.ts +6 -0
- package/src/utils/buildSizeVariants.ts +16 -0
- package/src/utils/deepMerge.ts +43 -0
- package/src/utils/positionUtils.native.ts +280 -0
- package/src/utils/styleHelpers.ts +48 -0
- package/LLM-ACCESS-GUIDE.md +0 -143
- package/src/ActivityIndicator/README.md +0 -132
- package/src/Avatar/README.md +0 -139
- package/src/Badge/README.md +0 -170
- package/src/Button/Button.types.ts +0 -12
- package/src/Button/README.md +0 -262
- package/src/Card/README.md +0 -258
- package/src/Checkbox/README.md +0 -102
- package/src/Dialog/README.md +0 -210
- package/src/Divider/README.md +0 -108
- package/src/Icon/README.md +0 -81
- package/src/Input/README.md +0 -100
- package/src/SVGImage/README.md +0 -209
- package/src/Screen/README.md +0 -86
- package/src/Select/README.md +0 -166
- package/src/Text/README.md +0 -94
- package/src/View/README.md +0 -107
- package/src/examples/AllExamples.tsx +0 -88
- package/src/examples/README.md +0 -136
- package/src/examples/ValidationExamples.tsx +0 -95
- package/src/examples/extendedTheme.ts +0 -329
- package/src/theme/breakpoints.ts +0 -8
- package/src/theme/colorResolver.ts +0 -218
- package/src/theme/colors.ts +0 -315
- package/src/theme/defaultThemes.ts +0 -326
- package/src/theme/index.ts +0 -188
- package/src/theme/themeBuilder.ts +0 -602
- package/src/theme/unistyles.d.ts +0 -6
- package/src/theme/variantHelpers.ts +0 -584
- package/src/theme/variants.ts +0 -56
package/src/examples/index.ts
CHANGED
|
@@ -13,7 +13,21 @@ export { SVGImageExamples } from './SVGImageExamples';
|
|
|
13
13
|
export { DialogExamples } from './DialogExamples';
|
|
14
14
|
export { PopoverExamples } from './PopoverExamples';
|
|
15
15
|
export { SelectExamples } from './SelectExamples';
|
|
16
|
+
export { SliderExamples } from './SliderExamples';
|
|
17
|
+
export { SwitchExamples } from './SwitchExamples';
|
|
18
|
+
export { RadioButtonExamples } from './RadioButtonExamples';
|
|
19
|
+
export { ProgressExamples } from './ProgressExamples';
|
|
20
|
+
export { TextAreaExamples } from './TextAreaExamples';
|
|
21
|
+
export { TabBarExamples } from './TabBarExamples';
|
|
22
|
+
export { TooltipExamples } from './TooltipExamples';
|
|
23
|
+
export { AccordionExamples } from './AccordionExamples';
|
|
24
|
+
export { ListExamples } from './ListExamples';
|
|
25
|
+
export { TableExamples } from './TableExamples';
|
|
26
|
+
export { MenuExamples } from './MenuExamples';
|
|
27
|
+
export { ImageExamples } from './ImageExamples';
|
|
28
|
+
export { VideoExamples } from './VideoExamples';
|
|
29
|
+
export { AlertExamples } from './AlertExamples';
|
|
30
|
+
export { SkeletonExamples } from './SkeletonExamples';
|
|
31
|
+
export { ChipExamples } from './ChipExamples';
|
|
32
|
+
export { BreadcrumbExamples } from './BreadcrumbExamples';
|
|
16
33
|
export { ThemeExtensionExamples } from './ThemeExtensionExamples';
|
|
17
|
-
export { extendedThemes, } from './extendedTheme';
|
|
18
|
-
export type { ExtendedColorVariant, ExtendedIntentVariant } from './extendedTheme';
|
|
19
|
-
export { AllExamples } from './AllExamples';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Userful when workign with getWebProps and forwarding refs
|
|
3
|
+
* @param refs
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export default function useMergeRefs<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {
|
|
7
|
+
return (value: T) => {
|
|
8
|
+
refs.forEach((ref) => {
|
|
9
|
+
if (typeof ref === 'function') {
|
|
10
|
+
ref(value);
|
|
11
|
+
} else if (ref && 'current' in ref) {
|
|
12
|
+
ref.current = value;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
3
|
+
import { calculateSmartPosition, type Placement } from '../utils/positionUtils.native';
|
|
4
|
+
|
|
5
|
+
export interface UseSmartPositionOptions {
|
|
6
|
+
placement?: Placement;
|
|
7
|
+
offset?: number;
|
|
8
|
+
maxHeight?: number;
|
|
9
|
+
matchWidth?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SmartPosition {
|
|
13
|
+
top: number;
|
|
14
|
+
left: number;
|
|
15
|
+
width: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SmartSize {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface UseSmartPositionReturn {
|
|
24
|
+
position: SmartPosition;
|
|
25
|
+
size: SmartSize;
|
|
26
|
+
isPositioned: boolean;
|
|
27
|
+
anchorRef: React.MutableRefObject<any>;
|
|
28
|
+
measureAndPosition: () => void;
|
|
29
|
+
handleLayout: (event: any) => void;
|
|
30
|
+
reset: () => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Hook for smart positioning of modals/dropdowns with automatic flip detection
|
|
35
|
+
* and stable measurement-based positioning.
|
|
36
|
+
*
|
|
37
|
+
* This hook handles the complex two-phase rendering pattern:
|
|
38
|
+
* 1. Render invisible at initial position
|
|
39
|
+
* 2. Measure actual content size
|
|
40
|
+
* 3. Calculate final position based on measured size
|
|
41
|
+
* 4. Show once positioned and measurements are stable
|
|
42
|
+
*/
|
|
43
|
+
export const useSmartPosition = ({
|
|
44
|
+
placement = 'bottom-start',
|
|
45
|
+
offset = 8,
|
|
46
|
+
maxHeight = 300,
|
|
47
|
+
matchWidth = false,
|
|
48
|
+
}: UseSmartPositionOptions = {}): UseSmartPositionReturn => {
|
|
49
|
+
const [position, setPosition] = useState<SmartPosition>({ top: 0, left: 0, width: 0 });
|
|
50
|
+
const [size, setSize] = useState<SmartSize>({ width: 0, height: 0 });
|
|
51
|
+
const [isPositioned, setIsPositioned] = useState(false);
|
|
52
|
+
|
|
53
|
+
const anchorRef = useRef<any>(null);
|
|
54
|
+
const anchorMeasurements = useRef<{ x: number; y: number; width: number; height: number } | null>(null);
|
|
55
|
+
const previousHeightRef = useRef<number>(0);
|
|
56
|
+
const rafRef = useRef<any | null>(null);
|
|
57
|
+
const insets = useSafeAreaInsets();
|
|
58
|
+
|
|
59
|
+
// Calculate position based on anchor and content measurements
|
|
60
|
+
const calculatePosition = (x: number, y: number, width: number, height: number) => {
|
|
61
|
+
// For flip detection, use maxHeight to properly detect insufficient space
|
|
62
|
+
// But once we have a measured height, use that for tighter positioning
|
|
63
|
+
let heightForPositioning = maxHeight;
|
|
64
|
+
|
|
65
|
+
if (size.height > 0) {
|
|
66
|
+
// We have a measured height - use it if it's less than maxHeight
|
|
67
|
+
heightForPositioning = Math.min(size.height, maxHeight);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const desiredSize = {
|
|
71
|
+
width: size.width,
|
|
72
|
+
height: heightForPositioning
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Calculate position with flip detection
|
|
76
|
+
const calculatedPosition = calculateSmartPosition(
|
|
77
|
+
{ x, y, width, height },
|
|
78
|
+
desiredSize,
|
|
79
|
+
placement,
|
|
80
|
+
offset,
|
|
81
|
+
matchWidth,
|
|
82
|
+
insets
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
setPosition({
|
|
86
|
+
top: calculatedPosition.top,
|
|
87
|
+
left: calculatedPosition.left,
|
|
88
|
+
width: calculatedPosition.width || width,
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Recalculate position when size changes
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (anchorMeasurements.current && size.width > 0 && size.height > 0) {
|
|
95
|
+
const { x, y, width, height } = anchorMeasurements.current;
|
|
96
|
+
calculatePosition(x, y, width, height);
|
|
97
|
+
|
|
98
|
+
// Cancel any pending RAF
|
|
99
|
+
if (rafRef.current !== null) {
|
|
100
|
+
cancelAnimationFrame(rafRef.current);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Wait for next frame to allow layout to settle before showing
|
|
104
|
+
rafRef.current = setTimeout(() => {
|
|
105
|
+
setIsPositioned(true);
|
|
106
|
+
rafRef.current = null;
|
|
107
|
+
}, 20)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return () => {
|
|
111
|
+
if (rafRef.current !== null) {
|
|
112
|
+
clearTimeout(rafRef.current);
|
|
113
|
+
rafRef.current = null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}, [size]);
|
|
117
|
+
|
|
118
|
+
// Measure anchor and set initial position
|
|
119
|
+
const measureAndPosition = () => {
|
|
120
|
+
anchorRef.current?.measureInWindow((x: number, y: number, width: number, height: number) => {
|
|
121
|
+
// Store anchor measurements for potential recalculation
|
|
122
|
+
anchorMeasurements.current = { x, y, width, height };
|
|
123
|
+
|
|
124
|
+
// Set initial position (will be adjusted after measurement)
|
|
125
|
+
setPosition({ top: y + height + offset, left: x, width });
|
|
126
|
+
setIsPositioned(false);
|
|
127
|
+
previousHeightRef.current = 0;
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Handle layout measurement from content
|
|
132
|
+
const handleLayout = (event: any) => {
|
|
133
|
+
const { width, height } = event.nativeEvent.layout;
|
|
134
|
+
|
|
135
|
+
if (__DEV__) {
|
|
136
|
+
console.log('[useSmartPosition] onLayout:', { width, height, currentSize: size, isPositioned });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Only update if size has changed significantly
|
|
140
|
+
if (Math.abs(width - size.width) > 1 || Math.abs(height - size.height) > 1) {
|
|
141
|
+
if (__DEV__) {
|
|
142
|
+
console.log('[useSmartPosition] Size changed, updating');
|
|
143
|
+
}
|
|
144
|
+
previousHeightRef.current = size.height;
|
|
145
|
+
setSize({ width, height });
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// Reset state (call when closing modal)
|
|
150
|
+
const reset = () => {
|
|
151
|
+
if (rafRef.current !== null) {
|
|
152
|
+
clearTimeout(rafRef.current);
|
|
153
|
+
rafRef.current = null;
|
|
154
|
+
}
|
|
155
|
+
setIsPositioned(false);
|
|
156
|
+
setSize({ width: 0, height: 0 });
|
|
157
|
+
previousHeightRef.current = 0;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
position,
|
|
162
|
+
size,
|
|
163
|
+
isPositioned,
|
|
164
|
+
anchorRef,
|
|
165
|
+
measureAndPosition,
|
|
166
|
+
handleLayout,
|
|
167
|
+
reset,
|
|
168
|
+
};
|
|
169
|
+
};
|
package/src/index.native.ts
CHANGED
|
@@ -7,9 +7,13 @@ export * from './Text/types';
|
|
|
7
7
|
export { default as View } from './View';
|
|
8
8
|
export * from './View/types';
|
|
9
9
|
|
|
10
|
+
export { default as Pressable } from './Pressable';
|
|
11
|
+
export * from './Pressable/types';
|
|
12
|
+
|
|
10
13
|
export { default as Input } from './Input';
|
|
11
14
|
export * from './Input/types';
|
|
12
15
|
|
|
16
|
+
// New primitive components
|
|
13
17
|
export { default as Checkbox } from './Checkbox';
|
|
14
18
|
export * from './Checkbox/types';
|
|
15
19
|
|
|
@@ -40,8 +44,62 @@ export * from './Dialog/types';
|
|
|
40
44
|
export { default as Popover } from './Popover';
|
|
41
45
|
export * from './Popover/types';
|
|
42
46
|
|
|
43
|
-
export { default as
|
|
44
|
-
export * from './
|
|
47
|
+
export { default as ActivityIndicator } from './ActivityIndicator';
|
|
48
|
+
export * from './ActivityIndicator/types';
|
|
49
|
+
|
|
50
|
+
export { default as Select } from './Select';
|
|
51
|
+
export * from './Select/types';
|
|
52
|
+
|
|
53
|
+
export { default as Slider } from './Slider';
|
|
54
|
+
export * from './Slider/types';
|
|
55
|
+
|
|
56
|
+
export { default as Switch } from './Switch';
|
|
57
|
+
export * from './Switch/types';
|
|
58
|
+
|
|
59
|
+
export { RadioButton, RadioGroup } from './RadioButton';
|
|
60
|
+
export * from './RadioButton/types';
|
|
61
|
+
|
|
62
|
+
export { default as Progress } from './Progress';
|
|
63
|
+
export * from './Progress/types';
|
|
64
|
+
|
|
65
|
+
export { default as TextArea } from './TextArea';
|
|
66
|
+
export * from './TextArea/types';
|
|
67
|
+
|
|
68
|
+
export { default as TabBar } from './TabBar';
|
|
69
|
+
export * from './TabBar/types';
|
|
70
|
+
|
|
71
|
+
export { default as Tooltip } from './Tooltip';
|
|
72
|
+
export * from './Tooltip/types';
|
|
73
|
+
|
|
74
|
+
export { default as Accordion } from './Accordion';
|
|
75
|
+
export * from './Accordion/types';
|
|
76
|
+
|
|
77
|
+
export { List, ListItem, ListSection } from './List';
|
|
78
|
+
export * from './List/types';
|
|
79
|
+
|
|
80
|
+
export { default as Table } from './Table';
|
|
81
|
+
export * from './Table/types';
|
|
82
|
+
|
|
83
|
+
export { default as Menu } from './Menu';
|
|
84
|
+
export * from './Menu/types';
|
|
85
|
+
|
|
86
|
+
export { default as Image } from './Image';
|
|
87
|
+
export * from './Image/types';
|
|
88
|
+
|
|
89
|
+
export { default as Video } from './Video';
|
|
90
|
+
export * from './Video/types';
|
|
91
|
+
|
|
92
|
+
export { default as Alert } from './Alert';
|
|
93
|
+
export * from './Alert/types';
|
|
94
|
+
|
|
95
|
+
export { default as Skeleton, SkeletonGroup } from './Skeleton';
|
|
96
|
+
export * from './Skeleton/types';
|
|
97
|
+
|
|
98
|
+
export { default as Chip } from './Chip';
|
|
99
|
+
export * from './Chip/types';
|
|
100
|
+
|
|
101
|
+
export { default as Breadcrumb } from './Breadcrumb';
|
|
102
|
+
export * from './Breadcrumb/types';
|
|
45
103
|
|
|
46
104
|
export type { ButtonProps } from './Button/types';
|
|
47
105
|
export type { TextProps } from './Text/types';
|
|
@@ -57,10 +115,23 @@ export type { IconProps } from './Icon/types';
|
|
|
57
115
|
export type { SVGImageProps } from './SVGImage/types';
|
|
58
116
|
export type { DialogProps } from './Dialog/types';
|
|
59
117
|
export type { PopoverProps } from './Popover/types';
|
|
60
|
-
export type {
|
|
61
|
-
|
|
62
|
-
export {
|
|
63
|
-
export type {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
118
|
+
export type { ActivityIndicatorProps } from './ActivityIndicator/types';
|
|
119
|
+
export type { SelectProps } from './Select/types';
|
|
120
|
+
export type { SwitchProps } from './Switch/types';
|
|
121
|
+
export type { RadioButtonProps, RadioGroupProps } from './RadioButton/types';
|
|
122
|
+
export type { ProgressProps } from './Progress/types';
|
|
123
|
+
export type { TextAreaProps } from './TextArea/types';
|
|
124
|
+
export type { TabBarProps, TabBarItem } from './TabBar/types';
|
|
125
|
+
export type { TooltipProps } from './Tooltip/types';
|
|
126
|
+
export type { AccordionProps, AccordionItem } from './Accordion/types';
|
|
127
|
+
export type { ListProps, ListItemProps, ListSectionProps } from './List/types';
|
|
128
|
+
export type { TableProps, TableColumn } from './Table/types';
|
|
129
|
+
export type { MenuProps, MenuItem } from './Menu/types';
|
|
130
|
+
export type { ImageProps } from './Image/types';
|
|
131
|
+
export type { VideoProps, VideoSource } from './Video/types';
|
|
132
|
+
export type { AlertProps } from './Alert/types';
|
|
133
|
+
export type { SkeletonProps, SkeletonGroupProps, SkeletonShape, SkeletonAnimation } from './Skeleton/types';
|
|
134
|
+
export type { ChipProps, ChipSize, ChipIntent } from './Chip/types';
|
|
135
|
+
export type { BreadcrumbProps, BreadcrumbItem } from './Breadcrumb/types';
|
|
136
|
+
|
|
137
|
+
export type { AppTheme } from '@idealyst/theme';
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import useMergeRefs from './hooks/useMergeRefs';
|
|
2
|
+
|
|
1
3
|
export { default as Button } from './Button';
|
|
2
4
|
export * from './Button/types';
|
|
3
5
|
|
|
@@ -50,6 +52,57 @@ export * from './ActivityIndicator/types';
|
|
|
50
52
|
export { default as Select } from './Select';
|
|
51
53
|
export * from './Select/types';
|
|
52
54
|
|
|
55
|
+
export { default as Slider } from './Slider';
|
|
56
|
+
export * from './Slider/types';
|
|
57
|
+
|
|
58
|
+
export { default as Switch } from './Switch';
|
|
59
|
+
export * from './Switch/types';
|
|
60
|
+
|
|
61
|
+
export { RadioButton, RadioGroup } from './RadioButton';
|
|
62
|
+
export * from './RadioButton/types';
|
|
63
|
+
|
|
64
|
+
export { default as Progress } from './Progress';
|
|
65
|
+
export * from './Progress/types';
|
|
66
|
+
|
|
67
|
+
export { default as TextArea } from './TextArea';
|
|
68
|
+
export * from './TextArea/types';
|
|
69
|
+
|
|
70
|
+
export { default as TabBar } from './TabBar';
|
|
71
|
+
export * from './TabBar/types';
|
|
72
|
+
|
|
73
|
+
export { default as Tooltip } from './Tooltip';
|
|
74
|
+
export * from './Tooltip/types';
|
|
75
|
+
|
|
76
|
+
export { default as Accordion } from './Accordion';
|
|
77
|
+
export * from './Accordion/types';
|
|
78
|
+
|
|
79
|
+
export { List, ListItem, ListSection } from './List';
|
|
80
|
+
export * from './List/types';
|
|
81
|
+
|
|
82
|
+
export { default as Table } from './Table';
|
|
83
|
+
export * from './Table/types';
|
|
84
|
+
|
|
85
|
+
export { default as Menu } from './Menu';
|
|
86
|
+
export * from './Menu/types';
|
|
87
|
+
|
|
88
|
+
export { default as Image } from './Image';
|
|
89
|
+
export * from './Image/types';
|
|
90
|
+
|
|
91
|
+
export { default as Video } from './Video';
|
|
92
|
+
export * from './Video/types';
|
|
93
|
+
|
|
94
|
+
export { default as Alert } from './Alert';
|
|
95
|
+
export * from './Alert/types';
|
|
96
|
+
|
|
97
|
+
export { default as Skeleton, SkeletonGroup } from './Skeleton';
|
|
98
|
+
export * from './Skeleton/types';
|
|
99
|
+
|
|
100
|
+
export { default as Chip } from './Chip';
|
|
101
|
+
export * from './Chip/types';
|
|
102
|
+
|
|
103
|
+
export { default as Breadcrumb } from './Breadcrumb';
|
|
104
|
+
export * from './Breadcrumb/types';
|
|
105
|
+
|
|
53
106
|
export type { ButtonProps } from './Button/types';
|
|
54
107
|
export type { TextProps } from './Text/types';
|
|
55
108
|
export type { ViewProps } from './View/types';
|
|
@@ -66,6 +119,23 @@ export type { DialogProps } from './Dialog/types';
|
|
|
66
119
|
export type { PopoverProps } from './Popover/types';
|
|
67
120
|
export type { ActivityIndicatorProps } from './ActivityIndicator/types';
|
|
68
121
|
export type { SelectProps } from './Select/types';
|
|
122
|
+
export type { SwitchProps } from './Switch/types';
|
|
123
|
+
export type { RadioButtonProps, RadioGroupProps } from './RadioButton/types';
|
|
124
|
+
export type { ProgressProps } from './Progress/types';
|
|
125
|
+
export type { TextAreaProps } from './TextArea/types';
|
|
126
|
+
export type { TabBarProps, TabBarItem } from './TabBar/types';
|
|
127
|
+
export type { TooltipProps } from './Tooltip/types';
|
|
128
|
+
export type { AccordionProps, AccordionItem } from './Accordion/types';
|
|
129
|
+
export type { ListProps, ListItemProps, ListSectionProps } from './List/types';
|
|
130
|
+
export type { TableProps, TableColumn } from './Table/types';
|
|
131
|
+
export type { MenuProps, MenuItem } from './Menu/types';
|
|
132
|
+
export type { ImageProps } from './Image/types';
|
|
133
|
+
export type { VideoProps, VideoSource } from './Video/types';
|
|
134
|
+
export type { AlertProps } from './Alert/types';
|
|
135
|
+
export type { SkeletonProps, SkeletonGroupProps, SkeletonShape, SkeletonAnimation } from './Skeleton/types';
|
|
136
|
+
export type { ChipProps, ChipSize, ChipIntent } from './Chip/types';
|
|
137
|
+
export type { BreadcrumbProps, BreadcrumbItem } from './Breadcrumb/types';
|
|
138
|
+
|
|
139
|
+
export { useMergeRefs };
|
|
69
140
|
|
|
70
|
-
export { breakpoints } from '@idealyst/theme';
|
|
71
141
|
export type { AppTheme } from '@idealyst/theme';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { View, Dimensions, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
4
|
+
|
|
5
|
+
interface BoundedModalContentProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
top: number;
|
|
8
|
+
left: number;
|
|
9
|
+
width?: number;
|
|
10
|
+
maxHeight?: number;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
onLayout?: (event: any) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A wrapper component for modal content that automatically constrains its height
|
|
17
|
+
* to fit within screen boundaries, accounting for safe areas.
|
|
18
|
+
*/
|
|
19
|
+
export const BoundedModalContent: React.FC<BoundedModalContentProps> = ({
|
|
20
|
+
children,
|
|
21
|
+
top,
|
|
22
|
+
left,
|
|
23
|
+
width,
|
|
24
|
+
maxHeight = 500,
|
|
25
|
+
style,
|
|
26
|
+
onLayout,
|
|
27
|
+
}) => {
|
|
28
|
+
const insets = useSafeAreaInsets();
|
|
29
|
+
const { height: windowHeight } = Dimensions.get('window');
|
|
30
|
+
const padding = 12;
|
|
31
|
+
|
|
32
|
+
// Calculate dynamic maxHeight to ensure content stays within bounds
|
|
33
|
+
// The safe area goes from the top of the window to windowHeight - insets.bottom
|
|
34
|
+
// We then subtract padding from available space for visual breathing room
|
|
35
|
+
const bottomSafeEdge = windowHeight - insets.bottom;
|
|
36
|
+
const bottomBound = bottomSafeEdge - padding;
|
|
37
|
+
|
|
38
|
+
// Calculate available height: from current top position to bottom boundary
|
|
39
|
+
const availableHeight = Math.max(100, bottomBound - top);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<View
|
|
43
|
+
style={[
|
|
44
|
+
{
|
|
45
|
+
position: 'absolute',
|
|
46
|
+
top,
|
|
47
|
+
left,
|
|
48
|
+
...(width && { width }),
|
|
49
|
+
maxHeight: availableHeight,
|
|
50
|
+
},
|
|
51
|
+
style,
|
|
52
|
+
]}
|
|
53
|
+
onLayout={onLayout}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
</View>
|
|
57
|
+
);
|
|
58
|
+
};
|