react-native-pro-accordion 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +476 -0
  2. package/index.js +3 -0
  3. package/lib/commonjs/components/Accordion.js +130 -0
  4. package/lib/commonjs/components/Accordion.js.map +1 -0
  5. package/lib/commonjs/components/AccordionContent.js +125 -0
  6. package/lib/commonjs/components/AccordionContent.js.map +1 -0
  7. package/lib/commonjs/components/AccordionItem.js +146 -0
  8. package/lib/commonjs/components/AccordionItem.js.map +1 -0
  9. package/lib/commonjs/components/AccordionSeparator.js +159 -0
  10. package/lib/commonjs/components/AccordionSeparator.js.map +1 -0
  11. package/lib/commonjs/core/AccordionContext.js +82 -0
  12. package/lib/commonjs/core/AccordionContext.js.map +1 -0
  13. package/lib/commonjs/core/AccordionRef.js +64 -0
  14. package/lib/commonjs/core/AccordionRef.js.map +1 -0
  15. package/lib/commonjs/core/types.js +6 -0
  16. package/lib/commonjs/core/types.js.map +1 -0
  17. package/lib/commonjs/hooks/useAccordion.js +18 -0
  18. package/lib/commonjs/hooks/useAccordion.js.map +1 -0
  19. package/lib/commonjs/hooks/useAccordionAccessibility.js +39 -0
  20. package/lib/commonjs/hooks/useAccordionAccessibility.js.map +1 -0
  21. package/lib/commonjs/hooks/useAccordionAnimation.js +135 -0
  22. package/lib/commonjs/hooks/useAccordionAnimation.js.map +1 -0
  23. package/lib/commonjs/hooks/useAccordionKeyboard.js +43 -0
  24. package/lib/commonjs/hooks/useAccordionKeyboard.js.map +1 -0
  25. package/lib/commonjs/hooks/useAccordionState.js +96 -0
  26. package/lib/commonjs/hooks/useAccordionState.js.map +1 -0
  27. package/lib/commonjs/index.js +176 -0
  28. package/lib/commonjs/index.js.map +1 -0
  29. package/lib/commonjs/package.json +1 -0
  30. package/lib/commonjs/theme/ThemeContext.js +48 -0
  31. package/lib/commonjs/theme/ThemeContext.js.map +1 -0
  32. package/lib/commonjs/theme/defaultTheme.js +79 -0
  33. package/lib/commonjs/theme/defaultTheme.js.map +1 -0
  34. package/lib/commonjs/theme/types.js +6 -0
  35. package/lib/commonjs/theme/types.js.map +1 -0
  36. package/lib/commonjs/utils/animations.js +41 -0
  37. package/lib/commonjs/utils/animations.js.map +1 -0
  38. package/lib/commonjs/utils/layout.js +155 -0
  39. package/lib/commonjs/utils/layout.js.map +1 -0
  40. package/lib/commonjs/utils/validators.js +26 -0
  41. package/lib/commonjs/utils/validators.js.map +1 -0
  42. package/lib/module/components/Accordion.js +125 -0
  43. package/lib/module/components/Accordion.js.map +1 -0
  44. package/lib/module/components/AccordionContent.js +120 -0
  45. package/lib/module/components/AccordionContent.js.map +1 -0
  46. package/lib/module/components/AccordionItem.js +141 -0
  47. package/lib/module/components/AccordionItem.js.map +1 -0
  48. package/lib/module/components/AccordionSeparator.js +155 -0
  49. package/lib/module/components/AccordionSeparator.js.map +1 -0
  50. package/lib/module/core/AccordionContext.js +75 -0
  51. package/lib/module/core/AccordionContext.js.map +1 -0
  52. package/lib/module/core/AccordionRef.js +59 -0
  53. package/lib/module/core/AccordionRef.js.map +1 -0
  54. package/lib/module/core/types.js +136 -0
  55. package/lib/module/core/types.js.map +1 -0
  56. package/lib/module/hooks/useAccordion.js +14 -0
  57. package/lib/module/hooks/useAccordion.js.map +1 -0
  58. package/lib/module/hooks/useAccordionAccessibility.js +34 -0
  59. package/lib/module/hooks/useAccordionAccessibility.js.map +1 -0
  60. package/lib/module/hooks/useAccordionAnimation.js +131 -0
  61. package/lib/module/hooks/useAccordionAnimation.js.map +1 -0
  62. package/lib/module/hooks/useAccordionKeyboard.js +38 -0
  63. package/lib/module/hooks/useAccordionKeyboard.js.map +1 -0
  64. package/lib/module/hooks/useAccordionState.js +92 -0
  65. package/lib/module/hooks/useAccordionState.js.map +1 -0
  66. package/lib/module/index.js +43 -0
  67. package/lib/module/index.js.map +1 -0
  68. package/lib/module/theme/ThemeContext.js +41 -0
  69. package/lib/module/theme/ThemeContext.js.map +1 -0
  70. package/lib/module/theme/defaultTheme.js +75 -0
  71. package/lib/module/theme/defaultTheme.js.map +1 -0
  72. package/lib/module/theme/types.js +66 -0
  73. package/lib/module/theme/types.js.map +1 -0
  74. package/lib/module/utils/animations.js +35 -0
  75. package/lib/module/utils/animations.js.map +1 -0
  76. package/lib/module/utils/layout.js +147 -0
  77. package/lib/module/utils/layout.js.map +1 -0
  78. package/lib/module/utils/validators.js +20 -0
  79. package/lib/module/utils/validators.js.map +1 -0
  80. package/package.json +25 -0
  81. package/src/components/Accordion.js +164 -0
  82. package/src/components/AccordionContent.js +149 -0
  83. package/src/components/AccordionItem.js +146 -0
  84. package/src/components/AccordionSeparator.js +168 -0
  85. package/src/core/AccordionContext.js +86 -0
  86. package/src/core/AccordionRef.js +69 -0
  87. package/src/core/types.js +133 -0
  88. package/src/hooks/useAccordion.js +14 -0
  89. package/src/hooks/useAccordionAccessibility.js +30 -0
  90. package/src/hooks/useAccordionAnimation.js +165 -0
  91. package/src/hooks/useAccordionKeyboard.js +38 -0
  92. package/src/hooks/useAccordionState.js +119 -0
  93. package/src/index.js +56 -0
  94. package/src/theme/ThemeContext.js +40 -0
  95. package/src/theme/defaultTheme.js +73 -0
  96. package/src/theme/types.js +63 -0
  97. package/src/utils/animations.js +38 -0
  98. package/src/utils/layout.js +138 -0
  99. package/src/utils/validators.js +20 -0
@@ -0,0 +1,73 @@
1
+ export const defaultLightTheme = {
2
+ colors: {
3
+ background: "#FFFFFF",
4
+ surface: "#F5F5F5",
5
+ primary: "#2196F3",
6
+ text: "#000000",
7
+ textSecondary: "#666666",
8
+ border: "#E0E0E0",
9
+ disabled: "#BDBDBD",
10
+ icon: "#666666",
11
+ },
12
+ spacing: {
13
+ xs: 4,
14
+ sm: 8,
15
+ md: 16,
16
+ lg: 24,
17
+ xl: 32,
18
+ },
19
+ typography: {
20
+ header: {
21
+ fontSize: 16,
22
+ fontWeight: "500",
23
+ color: "#000000",
24
+ },
25
+ content: {
26
+ fontSize: 14,
27
+ lineHeight: 20,
28
+ color: "#333333",
29
+ },
30
+ },
31
+ borderRadius: {
32
+ sm: 4,
33
+ md: 8,
34
+ lg: 12,
35
+ },
36
+ };
37
+
38
+ export const defaultDarkTheme = {
39
+ colors: {
40
+ background: "#121212",
41
+ surface: "#1E1E1E",
42
+ primary: "#64B5F6",
43
+ text: "#FFFFFF",
44
+ textSecondary: "#B0B0B0",
45
+ border: "#2C2C2C",
46
+ disabled: "#6B6B6B",
47
+ icon: "#B0B0B0",
48
+ },
49
+ spacing: {
50
+ xs: 4,
51
+ sm: 8,
52
+ md: 16,
53
+ lg: 24,
54
+ xl: 32,
55
+ },
56
+ typography: {
57
+ header: {
58
+ fontSize: 16,
59
+ fontWeight: "500",
60
+ color: "#FFFFFF",
61
+ },
62
+ content: {
63
+ fontSize: 14,
64
+ lineHeight: 20,
65
+ color: "#E0E0E0",
66
+ },
67
+ },
68
+ borderRadius: {
69
+ sm: 4,
70
+ md: 8,
71
+ lg: 12,
72
+ },
73
+ };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Theme type definitions for JSDoc
3
+ */
4
+
5
+ /**
6
+ * @typedef {Object} ThemeColors
7
+ * @property {string} background - Background color
8
+ * @property {string} surface - Surface/card color
9
+ * @property {string} primary - Primary accent color
10
+ * @property {string} text - Primary text color
11
+ * @property {string} textSecondary - Secondary text color
12
+ * @property {string} border - Border color
13
+ * @property {string} disabled - Disabled state color
14
+ * @property {string} icon - Icon color
15
+ */
16
+
17
+ /**
18
+ * @typedef {Object} ThemeSpacing
19
+ * @property {number} xs - Extra small spacing (4px)
20
+ * @property {number} sm - Small spacing (8px)
21
+ * @property {number} md - Medium spacing (16px)
22
+ * @property {number} lg - Large spacing (24px)
23
+ * @property {number} xl - Extra large spacing (32px)
24
+ */
25
+
26
+ /**
27
+ * @typedef {Object} ThemeTypography
28
+ * @property {Object} header - Header text style
29
+ * @property {Object} content - Content text style
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} ThemeBorderRadius
34
+ * @property {number} sm - Small border radius (4px)
35
+ * @property {number} md - Medium border radius (8px)
36
+ * @property {number} lg - Large border radius (12px)
37
+ */
38
+
39
+ /**
40
+ * @typedef {Object} CompleteAccordionTheme
41
+ * @property {ThemeColors} colors
42
+ * @property {ThemeSpacing} spacing
43
+ * @property {ThemeTypography} typography
44
+ * @property {ThemeBorderRadius} borderRadius
45
+ */
46
+
47
+ /**
48
+ * @typedef {Object} ThemeContextValue
49
+ * @property {CompleteAccordionTheme} theme
50
+ * @property {boolean} darkMode
51
+ * @property {Function} setDarkMode
52
+ * @property {Function} toggleDarkMode
53
+ */
54
+
55
+ /**
56
+ * @typedef {Object} ThemeProviderProps
57
+ * @property {React.ReactNode} children
58
+ * @property {Partial<CompleteAccordionTheme>} [theme]
59
+ * @property {boolean} [darkMode]
60
+ * @property {Function} [onDarkModeChange]
61
+ */
62
+
63
+ export {};
@@ -0,0 +1,38 @@
1
+ import { withTiming, withSpring, Easing } from "react-native-reanimated";
2
+
3
+ export const getAnimatedHeight = (expanded, contentHeight, config) => {
4
+ const toValue = expanded ? contentHeight : 0;
5
+
6
+ if (config.type === "spring") {
7
+ return withSpring(toValue, {
8
+ damping: config.damping ?? 10,
9
+ mass: config.mass ?? 1,
10
+ stiffness: config.stiffness ?? 100,
11
+ overshootClamping: config.overshootClamping ?? false,
12
+ restSpeedThreshold: config.restSpeedThreshold ?? 0.01,
13
+ restDisplacementThreshold: config.restDisplacementThreshold ?? 0.01,
14
+ });
15
+ }
16
+
17
+ return withTiming(toValue, {
18
+ duration: config.duration ?? 300,
19
+ easing: config.easing ?? Easing.inOut(Easing.ease),
20
+ });
21
+ };
22
+
23
+ export const getAnimatedOpacity = (expanded, config) => {
24
+ const toValue = expanded ? 1 : 0;
25
+
26
+ if (config.type === "spring") {
27
+ return withSpring(toValue, {
28
+ damping: config.damping ?? 10,
29
+ mass: config.mass ?? 1,
30
+ stiffness: config.stiffness ?? 100,
31
+ });
32
+ }
33
+
34
+ return withTiming(toValue, {
35
+ duration: (config.duration ?? 300) * 0.6,
36
+ easing: config.easing ?? Easing.inOut(Easing.ease),
37
+ });
38
+ };
@@ -0,0 +1,138 @@
1
+ import { useState, useCallback, useRef, useEffect } from "react";
2
+ import { LayoutAnimation, Platform, UIManager } from "react-native";
3
+
4
+ // Enable LayoutAnimation on Android
5
+ if (
6
+ Platform.OS === "android" &&
7
+ UIManager.setLayoutAnimationEnabledExperimental
8
+ ) {
9
+ UIManager.setLayoutAnimationEnabledExperimental(true);
10
+ }
11
+
12
+ /**
13
+ * Hook for measuring content height
14
+ * @returns {Object} Height measurement utilities
15
+ */
16
+ export const useContentHeight = () => {
17
+ const [height, setHeight] = useState(0);
18
+ const [isMeasured, setIsMeasured] = useState(false);
19
+ const measuredHeightRef = useRef(0);
20
+
21
+ const onLayout = useCallback((event) => {
22
+ const newHeight = event.nativeEvent.layout.height;
23
+ if (newHeight !== measuredHeightRef.current && newHeight > 0) {
24
+ measuredHeightRef.current = newHeight;
25
+ setHeight(newHeight);
26
+ setIsMeasured(true);
27
+ }
28
+ }, []);
29
+
30
+ const resetHeight = useCallback(() => {
31
+ setHeight(0);
32
+ setIsMeasured(false);
33
+ measuredHeightRef.current = 0;
34
+ }, []);
35
+
36
+ return {
37
+ height,
38
+ isMeasured,
39
+ onLayout,
40
+ resetHeight,
41
+ };
42
+ };
43
+
44
+ /**
45
+ * Hook for measuring multiple content heights
46
+ * @returns {Object} Map of heights for multiple items
47
+ */
48
+ export const useMultipleContentHeights = () => {
49
+ const [heights, setHeights] = useState({});
50
+ const measuredRefs = useRef({});
51
+
52
+ const onLayout = useCallback((id, event) => {
53
+ const newHeight = event.nativeEvent.layout.height;
54
+ if (newHeight !== measuredRefs.current[id] && newHeight > 0) {
55
+ measuredRefs.current[id] = newHeight;
56
+ setHeights((prev) => ({ ...prev, [id]: newHeight }));
57
+ }
58
+ }, []);
59
+
60
+ const getHeight = useCallback(
61
+ (id) => {
62
+ return heights[id] || 0;
63
+ },
64
+ [heights],
65
+ );
66
+
67
+ const resetHeights = useCallback(() => {
68
+ setHeights({});
69
+ measuredRefs.current = {};
70
+ }, []);
71
+
72
+ return {
73
+ heights,
74
+ getHeight,
75
+ onLayout,
76
+ resetHeights,
77
+ };
78
+ };
79
+
80
+ /**
81
+ * Animates layout changes
82
+ * @param {Object} config - Animation configuration
83
+ */
84
+ export const animateLayout = (config = {}) => {
85
+ const { duration = 300, type = "easeInEaseOut", property = "all" } = config;
86
+
87
+ LayoutAnimation.configureNext(
88
+ LayoutAnimation.create(duration, type, property),
89
+ );
90
+ };
91
+
92
+ /**
93
+ * Smooth scroll to an accordion item
94
+ * @param {Object} scrollViewRef - Reference to ScrollView
95
+ * @param {number} yPosition - Y position to scroll to
96
+ * @param {Object} options - Scroll options
97
+ */
98
+ export const scrollToAccordionItem = (
99
+ scrollViewRef,
100
+ yPosition,
101
+ options = {},
102
+ ) => {
103
+ const { animated = true, duration = 300, offset = 0 } = options;
104
+
105
+ if (!scrollViewRef?.current) return;
106
+
107
+ const targetY = yPosition - offset;
108
+
109
+ if (Platform.OS === "ios") {
110
+ scrollViewRef.current.scrollTo({ y: targetY, animated });
111
+ } else {
112
+ if (animated && duration) {
113
+ // For Android with custom duration
114
+ scrollViewRef.current.scrollTo({ y: targetY, animated: false });
115
+ // You might need a custom scroll animation library for smooth Android scrolling
116
+ } else {
117
+ scrollViewRef.current.scrollTo({ y: targetY, animated });
118
+ }
119
+ }
120
+ };
121
+
122
+ /**
123
+ * Get element position relative to parent
124
+ * @param {Object} elementRef - Reference to element
125
+ * @returns {Promise<Object>} Position information
126
+ */
127
+ export const getElementPosition = (elementRef) => {
128
+ return new Promise((resolve) => {
129
+ if (!elementRef?.current) {
130
+ resolve({ x: 0, y: 0, width: 0, height: 0 });
131
+ return;
132
+ }
133
+
134
+ elementRef.current.measure((x, y, width, height, pageX, pageY) => {
135
+ resolve({ x: pageX, y: pageY, width, height });
136
+ });
137
+ });
138
+ };
@@ -0,0 +1,20 @@
1
+ export const validateAnimationConfig = (config) => {
2
+ if (config.type === "timing") {
3
+ return !(config.duration !== undefined && config.duration <= 0);
4
+ }
5
+
6
+ if (config.type === "spring") {
7
+ const { damping, mass, stiffness } = config;
8
+ return !(
9
+ (damping !== undefined && damping <= 0) ||
10
+ (mass !== undefined && mass <= 0) ||
11
+ (stiffness !== undefined && stiffness <= 0)
12
+ );
13
+ }
14
+
15
+ return false;
16
+ };
17
+
18
+ export const validateAccordionMode = (mode) => {
19
+ return mode === "single" || mode === "multiple";
20
+ };