@impulse-ui-native/accordion 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/components/accordion.d.mts +13 -0
  4. package/dist/components/accordion.js +14 -0
  5. package/dist/components/accordion.js.map +1 -0
  6. package/dist/components/content.d.mts +8 -0
  7. package/dist/components/content.js +78 -0
  8. package/dist/components/content.js.map +1 -0
  9. package/dist/components/index.d.mts +5 -0
  10. package/dist/components/index.js +5 -0
  11. package/dist/components/index.js.map +1 -0
  12. package/dist/components/item.d.mts +8 -0
  13. package/dist/components/item.js +37 -0
  14. package/dist/components/item.js.map +1 -0
  15. package/dist/components/root.d.mts +8 -0
  16. package/dist/components/root.js +130 -0
  17. package/dist/components/root.js.map +1 -0
  18. package/dist/components/trigger.d.mts +8 -0
  19. package/dist/components/trigger.js +145 -0
  20. package/dist/components/trigger.js.map +1 -0
  21. package/dist/contexts/accordion.context.d.mts +30 -0
  22. package/dist/contexts/accordion.context.js +30 -0
  23. package/dist/contexts/accordion.context.js.map +1 -0
  24. package/dist/contexts/index.d.mts +4 -0
  25. package/dist/contexts/index.js +2 -0
  26. package/dist/contexts/index.js.map +1 -0
  27. package/dist/hooks/accordion-animation.types.d.mts +6 -0
  28. package/dist/hooks/accordion-animation.types.js +1 -0
  29. package/dist/hooks/accordion-animation.types.js.map +1 -0
  30. package/dist/hooks/index.d.mts +6 -0
  31. package/dist/hooks/index.js +4 -0
  32. package/dist/hooks/index.js.map +1 -0
  33. package/dist/hooks/use-accordion-animation-progress.hook.d.mts +6 -0
  34. package/dist/hooks/use-accordion-animation-progress.hook.js +26 -0
  35. package/dist/hooks/use-accordion-animation-progress.hook.js.map +1 -0
  36. package/dist/hooks/use-accordion-content-animation.hook.d.mts +12 -0
  37. package/dist/hooks/use-accordion-content-animation.hook.js +28 -0
  38. package/dist/hooks/use-accordion-content-animation.hook.js.map +1 -0
  39. package/dist/hooks/use-accordion-indicator-animation.hook.d.mts +10 -0
  40. package/dist/hooks/use-accordion-indicator-animation.hook.js +16 -0
  41. package/dist/hooks/use-accordion-indicator-animation.hook.js.map +1 -0
  42. package/dist/index.d.mts +5 -0
  43. package/dist/index.js +3 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/types/accordion.types.d.mts +40 -0
  46. package/dist/types/accordion.types.js +1 -0
  47. package/dist/types/accordion.types.js.map +1 -0
  48. package/dist/types/index.d.mts +3 -0
  49. package/dist/types/index.js +2 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/utils/accordion.utils.d.mts +5 -0
  52. package/dist/utils/accordion.utils.js +16 -0
  53. package/dist/utils/accordion.utils.js.map +1 -0
  54. package/dist/utils/index.d.mts +1 -0
  55. package/dist/utils/index.js +2 -0
  56. package/dist/utils/index.js.map +1 -0
  57. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ImpulseUI Native contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @impulse-ui-native/accordion
2
+
3
+ Accessible compound accordion and collapsible sections for React Native and React Native Web.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ pnpm add @impulse-ui-native/accordion react-native-reanimated react-native-worklets
9
+ ```
10
+
11
+ Render the component inside `ThemeProvider` from `@impulse-ui-native/theme` and configure Reanimated for your host application.
12
+
13
+ ## Main exports
14
+
15
+ - `Accordion.Root` manages controlled or uncontrolled single/multiple expansion.
16
+ - `Accordion.Item` provides an independently disabled disclosure item.
17
+ - `Accordion.Trigger` exposes expanded state and keyboard navigation.
18
+ - `Accordion.Content` animates measured height while keeping nested content mounted.
19
+ - Public prop types are available for every compound part.
20
+
21
+ ## Usage
22
+
23
+ ```tsx
24
+ import { Accordion } from "@impulse-ui-native/accordion";
25
+ import { Typography } from "@impulse-ui-native/primitives";
26
+
27
+ export function FrequentlyAskedQuestions() {
28
+ return (
29
+ <Accordion.Root defaultValue="shipping">
30
+ <Accordion.Item value="shipping">
31
+ <Accordion.Trigger>How long does shipping take?</Accordion.Trigger>
32
+ <Accordion.Content>
33
+ <Typography.Body>
34
+ Standard shipping normally arrives in three to five business days.
35
+ </Typography.Body>
36
+ </Accordion.Content>
37
+ </Accordion.Item>
38
+ </Accordion.Root>
39
+ );
40
+ }
41
+ ```
42
+
43
+ Set `type="multiple"` and use string arrays for `value`, `defaultValue`, and `onValueChange` when several items may be open. Single accordions collapse an open item by default; use `collapsible={false}` when one item must remain open.
44
+
45
+ Triggers support Enter and Space activation through the native pressable behavior. Arrow Up/Down and Home/End move focus between enabled triggers. Content remains mounted during collapse, which preserves local and nested component state. Reduced-motion preferences disable the height and indicator duration.
@@ -0,0 +1,13 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AccordionContentProps, AccordionItemProps, AccordionRootProps, AccordionTriggerProps } from '../types/accordion.types.mjs';
4
+ import 'react-native';
5
+
6
+ declare const Accordion: {
7
+ Content: react.MemoExoticComponent<({ children, onLayout, style, ...props }: AccordionContentProps) => react_jsx_runtime.JSX.Element>;
8
+ Item: react.MemoExoticComponent<({ children, disabled, style, value, ...props }: AccordionItemProps) => react_jsx_runtime.JSX.Element>;
9
+ Root: react.MemoExoticComponent<({ children, collapsible, defaultValue, disabled, onValueChange, style, type, value, ...props }: AccordionRootProps) => react_jsx_runtime.JSX.Element>;
10
+ Trigger: react.MemoExoticComponent<({ accessibilityState, onBlur, children, disabled, hideIndicator, indicator, onFocus, onKeyDown, onPress, style, ...props }: AccordionTriggerProps) => react_jsx_runtime.JSX.Element>;
11
+ };
12
+
13
+ export { Accordion };
@@ -0,0 +1,14 @@
1
+ import { AccordionContent } from "./content";
2
+ import { AccordionItem } from "./item";
3
+ import { AccordionRoot } from "./root";
4
+ import { AccordionTrigger } from "./trigger";
5
+ const Accordion = {
6
+ Content: AccordionContent,
7
+ Item: AccordionItem,
8
+ Root: AccordionRoot,
9
+ Trigger: AccordionTrigger
10
+ };
11
+ export {
12
+ Accordion
13
+ };
14
+ //# sourceMappingURL=accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/accordion.ts"],"sourcesContent":["import { AccordionContent } from \"./content\";\nimport { AccordionItem } from \"./item\";\nimport { AccordionRoot } from \"./root\";\nimport { AccordionTrigger } from \"./trigger\";\n\nexport const Accordion = {\n Content: AccordionContent,\n Item: AccordionItem,\n Root: AccordionRoot,\n Trigger: AccordionTrigger,\n};\n"],"mappings":"AAAA,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAE1B,MAAM,YAAY;AAAA,EACvB,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AACX;","names":[]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AccordionContentProps } from '../types/accordion.types.mjs';
4
+ import 'react-native';
5
+
6
+ declare const AccordionContent: react.MemoExoticComponent<({ children, onLayout, style, ...props }: AccordionContentProps) => react_jsx_runtime.JSX.Element>;
7
+
8
+ export { AccordionContent };
@@ -0,0 +1,78 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo, useMemo } from "react";
3
+ import { StyleSheet } from "react-native";
4
+ import Animated from "react-native-reanimated";
5
+ import { useEventCallback } from "@impulse-ui-native/core";
6
+ import { View } from "@impulse-ui-native/primitives";
7
+ import { useComponentsTokens } from "@impulse-ui-native/theme";
8
+ import { useAccordionItemContext } from "../contexts";
9
+ import { useAccordionContentAnimation } from "../hooks";
10
+ const AccordionContent = memo(function AccordionContent2({
11
+ children,
12
+ onLayout,
13
+ style,
14
+ ...props
15
+ }) {
16
+ const item = useAccordionItemContext();
17
+ const tokens = useComponentsTokens().accordion;
18
+ const { contentStyle, setContentHeight } = useAccordionContentAnimation({
19
+ duration: tokens.animationDuration,
20
+ open: item.open
21
+ });
22
+ const viewportStyle = useMemo(
23
+ () => [styles.viewport, contentStyle],
24
+ [contentStyle]
25
+ );
26
+ const innerStyle = useMemo(
27
+ () => [
28
+ styles.content,
29
+ {
30
+ paddingBottom: tokens.content.paddingBottom,
31
+ paddingHorizontal: tokens.content.paddingHorizontal
32
+ },
33
+ style
34
+ ],
35
+ [style, tokens.content.paddingBottom, tokens.content.paddingHorizontal]
36
+ );
37
+ const handleLayout = useEventCallback((event) => {
38
+ setContentHeight(event.nativeEvent.layout.height);
39
+ onLayout?.(event);
40
+ });
41
+ return /* @__PURE__ */ jsx(
42
+ Animated.View,
43
+ {
44
+ "aria-hidden": !item.open,
45
+ accessibilityElementsHidden: !item.open,
46
+ importantForAccessibility: item.open ? "auto" : "no-hide-descendants",
47
+ pointerEvents: item.open ? "auto" : "none",
48
+ style: viewportStyle,
49
+ children: /* @__PURE__ */ jsx(
50
+ View,
51
+ {
52
+ ...props,
53
+ "aria-labelledby": item.triggerId,
54
+ accessibilityLabelledBy: item.triggerId,
55
+ nativeID: item.contentId,
56
+ onLayout: handleLayout,
57
+ style: innerStyle,
58
+ children
59
+ }
60
+ )
61
+ }
62
+ );
63
+ });
64
+ const styles = StyleSheet.create({
65
+ content: {
66
+ left: 0,
67
+ position: "absolute",
68
+ right: 0,
69
+ top: 0
70
+ },
71
+ viewport: {
72
+ overflow: "hidden"
73
+ }
74
+ });
75
+ export {
76
+ AccordionContent
77
+ };
78
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/content.tsx"],"sourcesContent":["import type { LayoutChangeEvent } from \"react-native\";\nimport { memo, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated from \"react-native-reanimated\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { AccordionContentProps } from \"../types\";\nimport { useAccordionItemContext } from \"../contexts\";\nimport { useAccordionContentAnimation } from \"../hooks\";\n\nexport const AccordionContent = memo(function AccordionContent({\n children,\n onLayout,\n style,\n ...props\n}: AccordionContentProps) {\n const item = useAccordionItemContext();\n const tokens = useComponentsTokens().accordion;\n const { contentStyle, setContentHeight } = useAccordionContentAnimation({\n duration: tokens.animationDuration,\n open: item.open,\n });\n\n const viewportStyle = useMemo(\n () => [styles.viewport, contentStyle],\n [contentStyle],\n );\n const innerStyle = useMemo(\n () => [\n styles.content,\n {\n paddingBottom: tokens.content.paddingBottom,\n paddingHorizontal: tokens.content.paddingHorizontal,\n },\n style,\n ],\n [style, tokens.content.paddingBottom, tokens.content.paddingHorizontal],\n );\n\n const handleLayout = useEventCallback((event: LayoutChangeEvent) => {\n setContentHeight(event.nativeEvent.layout.height);\n onLayout?.(event);\n });\n\n return (\n <Animated.View\n aria-hidden={!item.open}\n accessibilityElementsHidden={!item.open}\n importantForAccessibility={item.open ? \"auto\" : \"no-hide-descendants\"}\n pointerEvents={item.open ? \"auto\" : \"none\"}\n style={viewportStyle}\n >\n <View\n {...props}\n aria-labelledby={item.triggerId}\n accessibilityLabelledBy={item.triggerId}\n nativeID={item.contentId}\n onLayout={handleLayout}\n style={innerStyle}\n >\n {children}\n </View>\n </Animated.View>\n );\n});\n\nconst styles = StyleSheet.create({\n content: {\n left: 0,\n position: \"absolute\",\n right: 0,\n top: 0,\n },\n viewport: {\n overflow: \"hidden\",\n },\n});\n"],"mappings":"AAuDM;AAtDN,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAErB,SAAS,wBAAwB;AACjC,SAAS,YAAY;AACrB,SAAS,2BAA2B;AAGpC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAEtC,MAAM,mBAAmB,KAAK,SAASA,kBAAiB;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,OAAO,wBAAwB;AACrC,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,EAAE,cAAc,iBAAiB,IAAI,6BAA6B;AAAA,IACtE,UAAU,OAAO;AAAA,IACjB,MAAM,KAAK;AAAA,EACb,CAAC;AAED,QAAM,gBAAgB;AAAA,IACpB,MAAM,CAAC,OAAO,UAAU,YAAY;AAAA,IACpC,CAAC,YAAY;AAAA,EACf;AACA,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,MACJ,OAAO;AAAA,MACP;AAAA,QACE,eAAe,OAAO,QAAQ;AAAA,QAC9B,mBAAmB,OAAO,QAAQ;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,OAAO,OAAO,QAAQ,eAAe,OAAO,QAAQ,iBAAiB;AAAA,EACxE;AAEA,QAAM,eAAe,iBAAiB,CAAC,UAA6B;AAClE,qBAAiB,MAAM,YAAY,OAAO,MAAM;AAChD,eAAW,KAAK;AAAA,EAClB,CAAC;AAED,SACE;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC,eAAa,CAAC,KAAK;AAAA,MACnB,6BAA6B,CAAC,KAAK;AAAA,MACnC,2BAA2B,KAAK,OAAO,SAAS;AAAA,MAChD,eAAe,KAAK,OAAO,SAAS;AAAA,MACpC,OAAO;AAAA,MAEP;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ,mBAAiB,KAAK;AAAA,UACtB,yBAAyB,KAAK;AAAA,UAC9B,UAAU,KAAK;AAAA,UACf,UAAU;AAAA,UACV,OAAO;AAAA,UAEN;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,MAAM,SAAS,WAAW,OAAO;AAAA,EAC/B,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK;AAAA,EACP;AAAA,EACA,UAAU;AAAA,IACR,UAAU;AAAA,EACZ;AACF,CAAC;","names":["AccordionContent"]}
@@ -0,0 +1,5 @@
1
+ export { Accordion } from './accordion.mjs';
2
+ import 'react';
3
+ import 'react/jsx-runtime';
4
+ import '../types/accordion.types.mjs';
5
+ import 'react-native';
@@ -0,0 +1,5 @@
1
+ import { Accordion } from "./accordion";
2
+ export {
3
+ Accordion
4
+ };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["export { Accordion } from \"./accordion\";\n"],"mappings":"AAAA,SAAS,iBAAiB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AccordionItemProps } from '../types/accordion.types.mjs';
4
+ import 'react-native';
5
+
6
+ declare const AccordionItem: react.MemoExoticComponent<({ children, disabled, style, value, ...props }: AccordionItemProps) => react_jsx_runtime.JSX.Element>;
7
+
8
+ export { AccordionItem };
@@ -0,0 +1,37 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo, useId, useMemo } from "react";
3
+ import { View } from "@impulse-ui-native/primitives";
4
+ import { useComponentsTokens } from "@impulse-ui-native/theme";
5
+ import { AccordionItemProvider, useAccordionContext } from "../contexts";
6
+ const AccordionItem = memo(function AccordionItem2({
7
+ children,
8
+ disabled = false,
9
+ style,
10
+ value,
11
+ ...props
12
+ }) {
13
+ const accordion = useAccordionContext();
14
+ const tokens = useComponentsTokens().accordion;
15
+ const reactId = useId().replaceAll(":", "");
16
+ const resolvedDisabled = accordion.disabled || disabled;
17
+ const open = accordion.expandedValues.includes(value);
18
+ const context = useMemo(
19
+ () => ({
20
+ contentId: `accordion-content-${reactId}`,
21
+ disabled: resolvedDisabled,
22
+ open,
23
+ triggerId: `accordion-trigger-${reactId}`,
24
+ value
25
+ }),
26
+ [open, reactId, resolvedDisabled, value]
27
+ );
28
+ const itemStyle = useMemo(
29
+ () => [{ backgroundColor: tokens.backgroundColor }, style],
30
+ [style, tokens.backgroundColor]
31
+ );
32
+ return /* @__PURE__ */ jsx(AccordionItemProvider, { value: context, children: /* @__PURE__ */ jsx(View, { ...props, style: itemStyle, children }) });
33
+ });
34
+ export {
35
+ AccordionItem
36
+ };
37
+ //# sourceMappingURL=item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/item.tsx"],"sourcesContent":["import { memo, useId, useMemo } from \"react\";\n\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { AccordionItemContextData } from \"../contexts\";\nimport type { AccordionItemProps } from \"../types\";\nimport { AccordionItemProvider, useAccordionContext } from \"../contexts\";\n\nexport const AccordionItem = memo(function AccordionItem({\n children,\n disabled = false,\n style,\n value,\n ...props\n}: AccordionItemProps) {\n const accordion = useAccordionContext();\n const tokens = useComponentsTokens().accordion;\n const reactId = useId().replaceAll(\":\", \"\");\n const resolvedDisabled = accordion.disabled || disabled;\n const open = accordion.expandedValues.includes(value);\n\n const context = useMemo<AccordionItemContextData>(\n () => ({\n contentId: `accordion-content-${reactId}`,\n disabled: resolvedDisabled,\n open,\n triggerId: `accordion-trigger-${reactId}`,\n value,\n }),\n [open, reactId, resolvedDisabled, value],\n );\n const itemStyle = useMemo(\n () => [{ backgroundColor: tokens.backgroundColor }, style],\n [style, tokens.backgroundColor],\n );\n\n return (\n <AccordionItemProvider value={context}>\n <View {...props} style={itemStyle}>\n {children}\n </View>\n </AccordionItemProvider>\n );\n});\n"],"mappings":"AAuCM;AAvCN,SAAS,MAAM,OAAO,eAAe;AAErC,SAAS,YAAY;AACrB,SAAS,2BAA2B;AAIpC,SAAS,uBAAuB,2BAA2B;AAEpD,MAAM,gBAAgB,KAAK,SAASA,eAAc;AAAA,EACvD;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,YAAY,oBAAoB;AACtC,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,UAAU,MAAM,EAAE,WAAW,KAAK,EAAE;AAC1C,QAAM,mBAAmB,UAAU,YAAY;AAC/C,QAAM,OAAO,UAAU,eAAe,SAAS,KAAK;AAEpD,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL,WAAW,qBAAqB,OAAO;AAAA,MACvC,UAAU;AAAA,MACV;AAAA,MACA,WAAW,qBAAqB,OAAO;AAAA,MACvC;AAAA,IACF;AAAA,IACA,CAAC,MAAM,SAAS,kBAAkB,KAAK;AAAA,EACzC;AACA,QAAM,YAAY;AAAA,IAChB,MAAM,CAAC,EAAE,iBAAiB,OAAO,gBAAgB,GAAG,KAAK;AAAA,IACzD,CAAC,OAAO,OAAO,eAAe;AAAA,EAChC;AAEA,SACE,oBAAC,yBAAsB,OAAO,SAC5B,8BAAC,QAAM,GAAG,OAAO,OAAO,WACrB,UACH,GACF;AAEJ,CAAC;","names":["AccordionItem"]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AccordionRootProps } from '../types/accordion.types.mjs';
4
+ import 'react-native';
5
+
6
+ declare const AccordionRoot: react.MemoExoticComponent<({ children, collapsible, defaultValue, disabled, onValueChange, style, type, value, ...props }: AccordionRootProps) => react_jsx_runtime.JSX.Element>;
7
+
8
+ export { AccordionRoot };
@@ -0,0 +1,130 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo, useCallback, useMemo, useRef } from "react";
3
+ import { StyleSheet } from "react-native";
4
+ import {
5
+ useControllableState,
6
+ useEventCallback
7
+ } from "@impulse-ui-native/core";
8
+ import { View } from "@impulse-ui-native/primitives";
9
+ import { useComponentsTokens } from "@impulse-ui-native/theme";
10
+ import { AccordionProvider } from "../contexts";
11
+ import { normalizeAccordionValue } from "../utils";
12
+ const AccordionRoot = memo(function AccordionRoot2({
13
+ children,
14
+ collapsible = true,
15
+ defaultValue,
16
+ disabled = false,
17
+ onValueChange,
18
+ style,
19
+ type = "single",
20
+ value,
21
+ ...props
22
+ }) {
23
+ const tokens = useComponentsTokens().accordion;
24
+ const triggerRegistry = useRef([]);
25
+ const notifyValueChange = useEventCallback(
26
+ (nextValues) => {
27
+ if (type === "multiple") {
28
+ onValueChange?.([
29
+ ...nextValues
30
+ ]);
31
+ return;
32
+ }
33
+ onValueChange?.(
34
+ nextValues[0]
35
+ );
36
+ }
37
+ );
38
+ const normalizedValue = useMemo(
39
+ () => value === void 0 ? void 0 : normalizeAccordionValue(value),
40
+ [value]
41
+ );
42
+ const normalizedDefaultValue = useMemo(
43
+ () => normalizeAccordionValue(defaultValue),
44
+ [defaultValue]
45
+ );
46
+ const [expandedValues, setExpandedValues] = useControllableState({
47
+ prop: normalizedValue,
48
+ defaultProp: normalizedDefaultValue,
49
+ onChange: notifyValueChange
50
+ });
51
+ const registerTrigger = useCallback((registration) => {
52
+ triggerRegistry.current = [...triggerRegistry.current, registration];
53
+ return () => {
54
+ triggerRegistry.current = triggerRegistry.current.filter(
55
+ (candidate) => candidate !== registration
56
+ );
57
+ };
58
+ }, []);
59
+ const focusTrigger = useCallback(
60
+ (currentValue, direction) => {
61
+ const enabledTriggers = triggerRegistry.current.filter(
62
+ (trigger) => !trigger.disabled
63
+ );
64
+ const currentIndex = enabledTriggers.findIndex(
65
+ (trigger) => trigger.value === currentValue
66
+ );
67
+ if (enabledTriggers.length === 0) return;
68
+ let nextIndex = currentIndex;
69
+ if (direction === "first") nextIndex = 0;
70
+ if (direction === "last") nextIndex = enabledTriggers.length - 1;
71
+ if (direction === "next") {
72
+ nextIndex = (currentIndex + 1) % enabledTriggers.length;
73
+ }
74
+ if (direction === "previous") {
75
+ nextIndex = (currentIndex - 1 + enabledTriggers.length) % enabledTriggers.length;
76
+ }
77
+ enabledTriggers[nextIndex]?.ref.current?.focus();
78
+ },
79
+ []
80
+ );
81
+ const toggleItem = useCallback(
82
+ (itemValue) => {
83
+ setExpandedValues((currentValues) => {
84
+ const isOpen = currentValues.includes(itemValue);
85
+ if (type === "multiple") {
86
+ return isOpen ? currentValues.filter((current) => current !== itemValue) : [...currentValues, itemValue];
87
+ }
88
+ if (isOpen) {
89
+ return collapsible ? [] : currentValues;
90
+ }
91
+ return [itemValue];
92
+ });
93
+ },
94
+ [collapsible, setExpandedValues, type]
95
+ );
96
+ const context = useMemo(
97
+ () => ({
98
+ disabled,
99
+ expandedValues,
100
+ focusTrigger,
101
+ registerTrigger,
102
+ toggleItem
103
+ }),
104
+ [disabled, expandedValues, focusTrigger, registerTrigger, toggleItem]
105
+ );
106
+ const rootStyle = useMemo(
107
+ () => [
108
+ styles.root,
109
+ {
110
+ backgroundColor: tokens.dividerColor,
111
+ borderColor: tokens.borderColor,
112
+ borderRadius: tokens.borderRadius,
113
+ borderWidth: tokens.borderWidth,
114
+ gap: tokens.dividerWidth
115
+ },
116
+ style
117
+ ],
118
+ [style, tokens]
119
+ );
120
+ return /* @__PURE__ */ jsx(AccordionProvider, { value: context, children: /* @__PURE__ */ jsx(View, { ...props, style: rootStyle, children }) });
121
+ });
122
+ const styles = StyleSheet.create({
123
+ root: {
124
+ overflow: "hidden"
125
+ }
126
+ });
127
+ export {
128
+ AccordionRoot
129
+ };
130
+ //# sourceMappingURL=root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/root.tsx"],"sourcesContent":["import { memo, useCallback, useMemo, useRef } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport {\n useControllableState,\n useEventCallback,\n} from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { AccordionContextData } from \"../contexts\";\nimport type {\n AccordionMultipleRootProps,\n AccordionRootProps,\n AccordionSingleRootProps,\n} from \"../types\";\nimport { AccordionProvider } from \"../contexts\";\nimport { normalizeAccordionValue } from \"../utils\";\n\ntype TriggerRegistration = Parameters<\n AccordionContextData[\"registerTrigger\"]\n>[0];\n\nexport const AccordionRoot = memo(function AccordionRoot({\n children,\n collapsible = true,\n defaultValue,\n disabled = false,\n onValueChange,\n style,\n type = \"single\",\n value,\n ...props\n}: AccordionRootProps) {\n const tokens = useComponentsTokens().accordion;\n const triggerRegistry = useRef<TriggerRegistration[]>([]);\n\n const notifyValueChange = useEventCallback(\n (nextValues: readonly string[]) => {\n if (type === \"multiple\") {\n (onValueChange as AccordionMultipleRootProps[\"onValueChange\"])?.([\n ...nextValues,\n ]);\n return;\n }\n\n (onValueChange as AccordionSingleRootProps[\"onValueChange\"])?.(\n nextValues[0],\n );\n },\n );\n const normalizedValue = useMemo(\n () => (value === undefined ? undefined : normalizeAccordionValue(value)),\n [value],\n );\n const normalizedDefaultValue = useMemo(\n () => normalizeAccordionValue(defaultValue),\n [defaultValue],\n );\n const [expandedValues, setExpandedValues] = useControllableState<\n readonly string[]\n >({\n prop: normalizedValue,\n defaultProp: normalizedDefaultValue,\n onChange: notifyValueChange,\n });\n\n const registerTrigger = useCallback((registration: TriggerRegistration) => {\n triggerRegistry.current = [...triggerRegistry.current, registration];\n\n return () => {\n triggerRegistry.current = triggerRegistry.current.filter(\n (candidate) => candidate !== registration,\n );\n };\n }, []);\n\n const focusTrigger = useCallback<AccordionContextData[\"focusTrigger\"]>(\n (currentValue, direction) => {\n const enabledTriggers = triggerRegistry.current.filter(\n (trigger) => !trigger.disabled,\n );\n const currentIndex = enabledTriggers.findIndex(\n (trigger) => trigger.value === currentValue,\n );\n\n if (enabledTriggers.length === 0) return;\n\n let nextIndex = currentIndex;\n\n if (direction === \"first\") nextIndex = 0;\n if (direction === \"last\") nextIndex = enabledTriggers.length - 1;\n if (direction === \"next\") {\n nextIndex = (currentIndex + 1) % enabledTriggers.length;\n }\n if (direction === \"previous\") {\n nextIndex =\n (currentIndex - 1 + enabledTriggers.length) % enabledTriggers.length;\n }\n\n enabledTriggers[nextIndex]?.ref.current?.focus();\n },\n [],\n );\n\n const toggleItem = useCallback(\n (itemValue: string) => {\n setExpandedValues((currentValues) => {\n const isOpen = currentValues.includes(itemValue);\n\n if (type === \"multiple\") {\n return isOpen\n ? currentValues.filter((current) => current !== itemValue)\n : [...currentValues, itemValue];\n }\n\n if (isOpen) {\n return collapsible ? [] : currentValues;\n }\n\n return [itemValue];\n });\n },\n [collapsible, setExpandedValues, type],\n );\n\n const context = useMemo<AccordionContextData>(\n () => ({\n disabled,\n expandedValues,\n focusTrigger,\n registerTrigger,\n toggleItem,\n }),\n [disabled, expandedValues, focusTrigger, registerTrigger, toggleItem],\n );\n const rootStyle = useMemo(\n () => [\n styles.root,\n {\n backgroundColor: tokens.dividerColor,\n borderColor: tokens.borderColor,\n borderRadius: tokens.borderRadius,\n borderWidth: tokens.borderWidth,\n gap: tokens.dividerWidth,\n },\n style,\n ],\n [style, tokens],\n );\n\n return (\n <AccordionProvider value={context}>\n <View {...props} style={rootStyle}>\n {children}\n </View>\n </AccordionProvider>\n );\n});\n\nconst styles = StyleSheet.create({\n root: {\n overflow: \"hidden\",\n },\n});\n"],"mappings":"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","names":["AccordionRoot"]}
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AccordionTriggerProps } from '../types/accordion.types.mjs';
4
+ import 'react-native';
5
+
6
+ declare const AccordionTrigger: react.MemoExoticComponent<({ accessibilityState, onBlur, children, disabled, hideIndicator, indicator, onFocus, onKeyDown, onPress, style, ...props }: AccordionTriggerProps) => react_jsx_runtime.JSX.Element>;
7
+
8
+ export { AccordionTrigger };
@@ -0,0 +1,145 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { Platform, StyleSheet } from "react-native";
4
+ import Animated from "react-native-reanimated";
5
+ import { useEventCallback } from "@impulse-ui-native/core";
6
+ import { Icon } from "@impulse-ui-native/icon/components/icon";
7
+ import { CaretDownIcon } from "@impulse-ui-native/icon/icons/caret-down";
8
+ import { Pressable, Typography, View } from "@impulse-ui-native/primitives";
9
+ import { useComponentsTokens } from "@impulse-ui-native/theme";
10
+ import { useAccordionContext, useAccordionItemContext } from "../contexts";
11
+ import { useAccordionIndicatorAnimation } from "../hooks";
12
+ import { getAccordionFocusDirection } from "../utils";
13
+ const AccordionTrigger = memo(function AccordionTrigger2({
14
+ accessibilityState,
15
+ onBlur,
16
+ children,
17
+ disabled,
18
+ hideIndicator = false,
19
+ indicator,
20
+ onFocus,
21
+ onKeyDown,
22
+ onPress,
23
+ style,
24
+ ...props
25
+ }) {
26
+ const { focusTrigger, registerTrigger, toggleItem } = useAccordionContext();
27
+ const item = useAccordionItemContext();
28
+ const tokens = useComponentsTokens().accordion;
29
+ const [focused, setFocused] = useState(false);
30
+ const triggerRef = useRef(null);
31
+ const resolvedDisabled = item.disabled || disabled === true;
32
+ const indicatorStyle = useAccordionIndicatorAnimation({
33
+ duration: tokens.animationDuration,
34
+ open: item.open
35
+ });
36
+ const resolvedAccessibilityState = useMemo(
37
+ () => ({
38
+ ...accessibilityState,
39
+ disabled: resolvedDisabled,
40
+ expanded: item.open
41
+ }),
42
+ [accessibilityState, item.open, resolvedDisabled]
43
+ );
44
+ const titleStyle = useMemo(
45
+ () => ({
46
+ color: resolvedDisabled ? tokens.disabledColor : tokens.titleColor
47
+ }),
48
+ [resolvedDisabled, tokens.disabledColor, tokens.titleColor]
49
+ );
50
+ const triggerStyle = useCallback(
51
+ ({ pressed }) => [
52
+ styles.trigger,
53
+ {
54
+ backgroundColor: focused ? tokens.focusBackgroundColor : "transparent",
55
+ gap: tokens.trigger.gap,
56
+ minHeight: tokens.trigger.minHeight,
57
+ opacity: resolvedDisabled ? tokens.disabledOpacity : pressed ? tokens.pressedOpacity : 1,
58
+ paddingHorizontal: tokens.trigger.paddingHorizontal,
59
+ paddingVertical: tokens.trigger.paddingVertical
60
+ },
61
+ typeof style === "function" ? style({ pressed }) : style
62
+ ],
63
+ [focused, resolvedDisabled, style, tokens]
64
+ );
65
+ const handleBlur = useEventCallback(
66
+ (event) => {
67
+ setFocused(false);
68
+ onBlur?.(event);
69
+ }
70
+ );
71
+ const handleFocus = useEventCallback(
72
+ (event) => {
73
+ setFocused(true);
74
+ onFocus?.(event);
75
+ }
76
+ );
77
+ const handlePress = useEventCallback((event) => {
78
+ toggleItem(item.value);
79
+ onPress?.(event);
80
+ });
81
+ const handleKeyDown = useEventCallback((event) => {
82
+ onKeyDown?.(event);
83
+ if (event.isDefaultPrevented()) return;
84
+ const direction = getAccordionFocusDirection(event.nativeEvent.key);
85
+ if (direction) {
86
+ event.preventDefault();
87
+ focusTrigger(item.value, direction);
88
+ }
89
+ });
90
+ const webInteractionProps = useMemo(
91
+ () => Platform.OS === "web" ? {
92
+ "aria-controls": item.contentId,
93
+ onKeyDown: handleKeyDown
94
+ } : void 0,
95
+ [handleKeyDown, item.contentId]
96
+ );
97
+ useEffect(
98
+ () => registerTrigger({
99
+ disabled: resolvedDisabled,
100
+ ref: triggerRef,
101
+ value: item.value
102
+ }),
103
+ [item.value, registerTrigger, resolvedDisabled]
104
+ );
105
+ return /* @__PURE__ */ jsxs(
106
+ Pressable,
107
+ {
108
+ ...props,
109
+ ...webInteractionProps,
110
+ ref: triggerRef,
111
+ "aria-expanded": item.open,
112
+ accessibilityRole: "button",
113
+ accessibilityState: resolvedAccessibilityState,
114
+ disabled: resolvedDisabled,
115
+ focusable: !resolvedDisabled,
116
+ nativeID: item.triggerId,
117
+ onBlur: handleBlur,
118
+ onFocus: handleFocus,
119
+ onPress: handlePress,
120
+ style: triggerStyle,
121
+ children: [
122
+ /* @__PURE__ */ jsx(View, { flex: 1, pointerEvents: "none", children: typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx(Typography.Label, { style: titleStyle, children }) : children }),
123
+ hideIndicator ? null : /* @__PURE__ */ jsx(Animated.View, { pointerEvents: "none", style: indicatorStyle, children: indicator ?? /* @__PURE__ */ jsx(
124
+ Icon,
125
+ {
126
+ color: resolvedDisabled ? tokens.disabledColor : tokens.iconColor,
127
+ icon: CaretDownIcon,
128
+ size: tokens.iconSize
129
+ }
130
+ ) })
131
+ ]
132
+ }
133
+ );
134
+ });
135
+ const styles = StyleSheet.create({
136
+ trigger: {
137
+ alignItems: "center",
138
+ flexDirection: "row",
139
+ justifyContent: "space-between"
140
+ }
141
+ });
142
+ export {
143
+ AccordionTrigger
144
+ };
145
+ //# sourceMappingURL=trigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/trigger.tsx"],"sourcesContent":["import type { ComponentRef } from \"react\";\nimport type {\n GestureResponderEvent,\n PressableProps,\n PressableStateCallbackType,\n StyleProp,\n ViewStyle,\n} from \"react-native\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Platform, StyleSheet } from \"react-native\";\nimport Animated from \"react-native-reanimated\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { Icon } from \"@impulse-ui-native/icon/components/icon\";\nimport { CaretDownIcon } from \"@impulse-ui-native/icon/icons/caret-down\";\nimport { Pressable, Typography, View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { AccordionKeyDownEvent, AccordionTriggerProps } from \"../types\";\nimport { useAccordionContext, useAccordionItemContext } from \"../contexts\";\nimport { useAccordionIndicatorAnimation } from \"../hooks\";\nimport { getAccordionFocusDirection } from \"../utils\";\n\nexport const AccordionTrigger = memo(function AccordionTrigger({\n accessibilityState,\n onBlur,\n children,\n disabled,\n hideIndicator = false,\n indicator,\n onFocus,\n onKeyDown,\n onPress,\n style,\n ...props\n}: AccordionTriggerProps) {\n const { focusTrigger, registerTrigger, toggleItem } = useAccordionContext();\n const item = useAccordionItemContext();\n const tokens = useComponentsTokens().accordion;\n const [focused, setFocused] = useState(false);\n // The host ref is required for roving keyboard focus between triggers.\n const triggerRef = useRef<ComponentRef<typeof Pressable>>(null);\n const resolvedDisabled = item.disabled || disabled === true;\n const indicatorStyle = useAccordionIndicatorAnimation({\n duration: tokens.animationDuration,\n open: item.open,\n });\n\n const resolvedAccessibilityState = useMemo(\n () => ({\n ...accessibilityState,\n disabled: resolvedDisabled,\n expanded: item.open,\n }),\n [accessibilityState, item.open, resolvedDisabled],\n );\n const titleStyle = useMemo(\n () => ({\n color: resolvedDisabled ? tokens.disabledColor : tokens.titleColor,\n }),\n [resolvedDisabled, tokens.disabledColor, tokens.titleColor],\n );\n\n const triggerStyle = useCallback(\n ({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => [\n styles.trigger,\n {\n backgroundColor: focused ? tokens.focusBackgroundColor : \"transparent\",\n gap: tokens.trigger.gap,\n minHeight: tokens.trigger.minHeight,\n opacity: resolvedDisabled\n ? tokens.disabledOpacity\n : pressed\n ? tokens.pressedOpacity\n : 1,\n paddingHorizontal: tokens.trigger.paddingHorizontal,\n paddingVertical: tokens.trigger.paddingVertical,\n },\n typeof style === \"function\" ? style({ pressed }) : style,\n ],\n [focused, resolvedDisabled, style, tokens],\n );\n\n const handleBlur = useEventCallback<NonNullable<PressableProps[\"onBlur\"]>>(\n (event) => {\n setFocused(false);\n onBlur?.(event);\n },\n );\n\n const handleFocus = useEventCallback<NonNullable<PressableProps[\"onFocus\"]>>(\n (event) => {\n setFocused(true);\n onFocus?.(event);\n },\n );\n\n const handlePress = useEventCallback((event: GestureResponderEvent) => {\n toggleItem(item.value);\n onPress?.(event);\n });\n\n const handleKeyDown = useEventCallback((event: AccordionKeyDownEvent) => {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n const direction = getAccordionFocusDirection(event.nativeEvent.key);\n\n if (direction) {\n event.preventDefault();\n focusTrigger(item.value, direction);\n }\n });\n\n const webInteractionProps = useMemo(\n () =>\n Platform.OS === \"web\"\n ? ({\n \"aria-controls\": item.contentId,\n onKeyDown: handleKeyDown,\n } as PressableProps)\n : undefined,\n [handleKeyDown, item.contentId],\n );\n\n useEffect(\n () =>\n registerTrigger({\n disabled: resolvedDisabled,\n ref: triggerRef,\n value: item.value,\n }),\n [item.value, registerTrigger, resolvedDisabled],\n );\n\n return (\n <Pressable\n {...props}\n {...webInteractionProps}\n ref={triggerRef}\n aria-expanded={item.open}\n accessibilityRole=\"button\"\n accessibilityState={resolvedAccessibilityState}\n disabled={resolvedDisabled}\n focusable={!resolvedDisabled}\n nativeID={item.triggerId}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onPress={handlePress}\n style={triggerStyle}\n >\n <View flex={1} pointerEvents=\"none\">\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Typography.Label style={titleStyle}>{children}</Typography.Label>\n ) : (\n children\n )}\n </View>\n\n {hideIndicator ? null : (\n <Animated.View pointerEvents=\"none\" style={indicatorStyle}>\n {indicator ?? (\n <Icon\n color={resolvedDisabled ? tokens.disabledColor : tokens.iconColor}\n icon={CaretDownIcon}\n size={tokens.iconSize}\n />\n )}\n </Animated.View>\n )}\n </Pressable>\n );\n});\n\nconst styles = StyleSheet.create({\n trigger: {\n alignItems: \"center\",\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n },\n});\n"],"mappings":"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","names":["AccordionTrigger"]}
@@ -0,0 +1,30 @@
1
+ import * as react from 'react';
2
+ import { RefObject, ComponentRef } from 'react';
3
+ import { Pressable } from '@impulse-ui-native/primitives';
4
+ import { AccordionFocusDirection } from '../utils/accordion.utils.mjs';
5
+
6
+ interface AccordionTriggerRegistration {
7
+ disabled: boolean;
8
+ ref: RefObject<ComponentRef<typeof Pressable> | null>;
9
+ value: string;
10
+ }
11
+ interface AccordionContextData {
12
+ disabled: boolean;
13
+ expandedValues: readonly string[];
14
+ focusTrigger: (value: string, direction: AccordionFocusDirection) => void;
15
+ registerTrigger: (registration: AccordionTriggerRegistration) => () => void;
16
+ toggleItem: (value: string) => void;
17
+ }
18
+ interface AccordionItemContextData {
19
+ contentId: string;
20
+ disabled: boolean;
21
+ open: boolean;
22
+ triggerId: string;
23
+ value: string;
24
+ }
25
+ declare const AccordionProvider: react.Provider<AccordionContextData | undefined>;
26
+ declare const AccordionItemProvider: react.Provider<AccordionItemContextData | undefined>;
27
+ declare function useAccordionContext(): AccordionContextData;
28
+ declare function useAccordionItemContext(): AccordionItemContextData;
29
+
30
+ export { type AccordionContextData, type AccordionItemContextData, AccordionItemProvider, AccordionProvider, useAccordionContext, useAccordionItemContext };
@@ -0,0 +1,30 @@
1
+ import { createContext, useContext } from "react";
2
+ const AccordionContext = createContext(
3
+ void 0
4
+ );
5
+ const AccordionItemContext = createContext(void 0);
6
+ const AccordionProvider = AccordionContext.Provider;
7
+ const AccordionItemProvider = AccordionItemContext.Provider;
8
+ function useAccordionContext() {
9
+ const context = useContext(AccordionContext);
10
+ if (!context) {
11
+ throw new Error("Accordion parts must be used within Accordion.Root");
12
+ }
13
+ return context;
14
+ }
15
+ function useAccordionItemContext() {
16
+ const context = useContext(AccordionItemContext);
17
+ if (!context) {
18
+ throw new Error(
19
+ "Accordion.Trigger and Accordion.Content must be used within Accordion.Item"
20
+ );
21
+ }
22
+ return context;
23
+ }
24
+ export {
25
+ AccordionItemProvider,
26
+ AccordionProvider,
27
+ useAccordionContext,
28
+ useAccordionItemContext
29
+ };
30
+ //# sourceMappingURL=accordion.context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/contexts/accordion.context.ts"],"sourcesContent":["import type { ComponentRef, RefObject } from \"react\";\nimport { createContext, useContext } from \"react\";\n\nimport type { Pressable } from \"@impulse-ui-native/primitives\";\n\nimport type { AccordionFocusDirection } from \"../utils\";\n\ninterface AccordionTriggerRegistration {\n disabled: boolean;\n ref: RefObject<ComponentRef<typeof Pressable> | null>;\n value: string;\n}\n\nexport interface AccordionContextData {\n disabled: boolean;\n expandedValues: readonly string[];\n focusTrigger: (value: string, direction: AccordionFocusDirection) => void;\n registerTrigger: (registration: AccordionTriggerRegistration) => () => void;\n toggleItem: (value: string) => void;\n}\n\nexport interface AccordionItemContextData {\n contentId: string;\n disabled: boolean;\n open: boolean;\n triggerId: string;\n value: string;\n}\n\nconst AccordionContext = createContext<AccordionContextData | undefined>(\n undefined,\n);\nconst AccordionItemContext = createContext<\n AccordionItemContextData | undefined\n>(undefined);\n\nexport const AccordionProvider = AccordionContext.Provider;\nexport const AccordionItemProvider = AccordionItemContext.Provider;\n\nexport function useAccordionContext() {\n const context = useContext(AccordionContext);\n\n if (!context) {\n throw new Error(\"Accordion parts must be used within Accordion.Root\");\n }\n\n return context;\n}\n\nexport function useAccordionItemContext() {\n const context = useContext(AccordionItemContext);\n\n if (!context) {\n throw new Error(\n \"Accordion.Trigger and Accordion.Content must be used within Accordion.Item\",\n );\n }\n\n return context;\n}\n"],"mappings":"AACA,SAAS,eAAe,kBAAkB;AA4B1C,MAAM,mBAAmB;AAAA,EACvB;AACF;AACA,MAAM,uBAAuB,cAE3B,MAAS;AAEJ,MAAM,oBAAoB,iBAAiB;AAC3C,MAAM,wBAAwB,qBAAqB;AAEnD,SAAS,sBAAsB;AACpC,QAAM,UAAU,WAAW,gBAAgB;AAE3C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AACT;AAEO,SAAS,0BAA0B;AACxC,QAAM,UAAU,WAAW,oBAAoB;AAE/C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,4 @@
1
+ export { AccordionContextData, AccordionItemContextData, AccordionItemProvider, AccordionProvider, useAccordionContext, useAccordionItemContext } from './accordion.context.mjs';
2
+ import 'react';
3
+ import '@impulse-ui-native/primitives';
4
+ import '../utils/accordion.utils.mjs';
@@ -0,0 +1,2 @@
1
+ export * from "./accordion.context";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/contexts/index.ts"],"sourcesContent":["export * from \"./accordion.context\";\n"],"mappings":"AAAA,cAAc;","names":[]}
@@ -0,0 +1,6 @@
1
+ interface AccordionAnimationOptions {
2
+ duration: number;
3
+ open: boolean;
4
+ }
5
+
6
+ export type { AccordionAnimationOptions };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=accordion-animation.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,6 @@
1
+ export { useAccordionAnimationProgress } from './use-accordion-animation-progress.hook.mjs';
2
+ export { useAccordionContentAnimation } from './use-accordion-content-animation.hook.mjs';
3
+ export { useAccordionIndicatorAnimation } from './use-accordion-indicator-animation.hook.mjs';
4
+ import 'react-native-reanimated';
5
+ import './accordion-animation.types.mjs';
6
+ import 'react-native-reanimated/lib/typescript/hook/commonTypes';
@@ -0,0 +1,4 @@
1
+ export * from "./use-accordion-animation-progress.hook";
2
+ export * from "./use-accordion-content-animation.hook";
3
+ export * from "./use-accordion-indicator-animation.hook";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/index.ts"],"sourcesContent":["export * from \"./use-accordion-animation-progress.hook\";\nexport * from \"./use-accordion-content-animation.hook\";\nexport * from \"./use-accordion-indicator-animation.hook\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,6 @@
1
+ import * as react_native_reanimated from 'react-native-reanimated';
2
+ import { AccordionAnimationOptions } from './accordion-animation.types.mjs';
3
+
4
+ declare function useAccordionAnimationProgress({ duration, open, }: AccordionAnimationOptions): react_native_reanimated.SharedValue<number>;
5
+
6
+ export { useAccordionAnimationProgress };
@@ -0,0 +1,26 @@
1
+ import { useEffect } from "react";
2
+ import {
3
+ Easing,
4
+ useReducedMotion,
5
+ useSharedValue,
6
+ withTiming
7
+ } from "react-native-reanimated";
8
+ const accordionEasing = Easing.out(Easing.cubic);
9
+ function useAccordionAnimationProgress({
10
+ duration,
11
+ open
12
+ }) {
13
+ const reduceMotion = useReducedMotion();
14
+ const progress = useSharedValue(open ? 1 : 0);
15
+ useEffect(() => {
16
+ progress.value = withTiming(open ? 1 : 0, {
17
+ duration: reduceMotion ? 0 : duration,
18
+ easing: accordionEasing
19
+ });
20
+ }, [duration, open, progress, reduceMotion]);
21
+ return progress;
22
+ }
23
+ export {
24
+ useAccordionAnimationProgress
25
+ };
26
+ //# sourceMappingURL=use-accordion-animation-progress.hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-accordion-animation-progress.hook.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport {\n Easing,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from \"react-native-reanimated\";\n\nimport type { AccordionAnimationOptions } from \"./accordion-animation.types\";\n\nconst accordionEasing = Easing.out(Easing.cubic);\n\nexport function useAccordionAnimationProgress({\n duration,\n open,\n}: AccordionAnimationOptions) {\n const reduceMotion = useReducedMotion();\n const progress = useSharedValue(open ? 1 : 0);\n\n useEffect(() => {\n progress.value = withTiming(open ? 1 : 0, {\n duration: reduceMotion ? 0 : duration,\n easing: accordionEasing,\n });\n }, [duration, open, progress, reduceMotion]);\n\n return progress;\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,MAAM,kBAAkB,OAAO,IAAI,OAAO,KAAK;AAExC,SAAS,8BAA8B;AAAA,EAC5C;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,eAAe,iBAAiB;AACtC,QAAM,WAAW,eAAe,OAAO,IAAI,CAAC;AAE5C,YAAU,MAAM;AACd,aAAS,QAAQ,WAAW,OAAO,IAAI,GAAG;AAAA,MACxC,UAAU,eAAe,IAAI;AAAA,MAC7B,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,MAAM,UAAU,YAAY,CAAC;AAE3C,SAAO;AACT;","names":[]}
@@ -0,0 +1,12 @@
1
+ import * as react_native_reanimated_lib_typescript_hook_commonTypes from 'react-native-reanimated/lib/typescript/hook/commonTypes';
2
+ import { AccordionAnimationOptions } from './accordion-animation.types.mjs';
3
+
4
+ declare function useAccordionContentAnimation({ duration, open, }: AccordionAnimationOptions): {
5
+ contentStyle: react_native_reanimated_lib_typescript_hook_commonTypes.AnimatedStyleHandle<{
6
+ height: number;
7
+ opacity: number;
8
+ }>;
9
+ setContentHeight: (height: number) => void;
10
+ };
11
+
12
+ export { useAccordionContentAnimation };
@@ -0,0 +1,28 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useAnimatedStyle, useSharedValue } from "react-native-reanimated";
3
+ import { useAccordionAnimationProgress } from "./use-accordion-animation-progress.hook";
4
+ function useAccordionContentAnimation({
5
+ duration,
6
+ open
7
+ }) {
8
+ const measuredHeight = useSharedValue(0);
9
+ const progress = useAccordionAnimationProgress({ duration, open });
10
+ const contentStyle = useAnimatedStyle(() => ({
11
+ height: measuredHeight.value * progress.value,
12
+ opacity: progress.value
13
+ }));
14
+ const setContentHeight = useCallback(
15
+ (height) => {
16
+ measuredHeight.value = height;
17
+ },
18
+ [measuredHeight]
19
+ );
20
+ return useMemo(
21
+ () => ({ contentStyle, setContentHeight }),
22
+ [contentStyle, setContentHeight]
23
+ );
24
+ }
25
+ export {
26
+ useAccordionContentAnimation
27
+ };
28
+ //# sourceMappingURL=use-accordion-content-animation.hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-accordion-content-animation.hook.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { useAnimatedStyle, useSharedValue } from \"react-native-reanimated\";\n\nimport type { AccordionAnimationOptions } from \"./accordion-animation.types\";\nimport { useAccordionAnimationProgress } from \"./use-accordion-animation-progress.hook\";\n\nexport function useAccordionContentAnimation({\n duration,\n open,\n}: AccordionAnimationOptions) {\n const measuredHeight = useSharedValue(0);\n const progress = useAccordionAnimationProgress({ duration, open });\n\n const contentStyle = useAnimatedStyle(() => ({\n height: measuredHeight.value * progress.value,\n opacity: progress.value,\n }));\n\n const setContentHeight = useCallback(\n (height: number) => {\n measuredHeight.value = height;\n },\n [measuredHeight],\n );\n\n return useMemo(\n () => ({ contentStyle, setContentHeight }),\n [contentStyle, setContentHeight],\n );\n}\n"],"mappings":"AAAA,SAAS,aAAa,eAAe;AACrC,SAAS,kBAAkB,sBAAsB;AAGjD,SAAS,qCAAqC;AAEvC,SAAS,6BAA6B;AAAA,EAC3C;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,iBAAiB,eAAe,CAAC;AACvC,QAAM,WAAW,8BAA8B,EAAE,UAAU,KAAK,CAAC;AAEjE,QAAM,eAAe,iBAAiB,OAAO;AAAA,IAC3C,QAAQ,eAAe,QAAQ,SAAS;AAAA,IACxC,SAAS,SAAS;AAAA,EACpB,EAAE;AAEF,QAAM,mBAAmB;AAAA,IACvB,CAAC,WAAmB;AAClB,qBAAe,QAAQ;AAAA,IACzB;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,SAAO;AAAA,IACL,OAAO,EAAE,cAAc,iBAAiB;AAAA,IACxC,CAAC,cAAc,gBAAgB;AAAA,EACjC;AACF;","names":[]}
@@ -0,0 +1,10 @@
1
+ import * as react_native_reanimated_lib_typescript_hook_commonTypes from 'react-native-reanimated/lib/typescript/hook/commonTypes';
2
+ import { AccordionAnimationOptions } from './accordion-animation.types.mjs';
3
+
4
+ declare function useAccordionIndicatorAnimation({ duration, open, }: AccordionAnimationOptions): react_native_reanimated_lib_typescript_hook_commonTypes.AnimatedStyleHandle<{
5
+ transform: {
6
+ rotate: string;
7
+ }[];
8
+ }>;
9
+
10
+ export { useAccordionIndicatorAnimation };
@@ -0,0 +1,16 @@
1
+ import { useAnimatedStyle } from "react-native-reanimated";
2
+ import { useAccordionAnimationProgress } from "./use-accordion-animation-progress.hook";
3
+ function useAccordionIndicatorAnimation({
4
+ duration,
5
+ open
6
+ }) {
7
+ const progress = useAccordionAnimationProgress({ duration, open });
8
+ const indicatorStyle = useAnimatedStyle(() => ({
9
+ transform: [{ rotate: `${progress.value * 180}deg` }]
10
+ }));
11
+ return indicatorStyle;
12
+ }
13
+ export {
14
+ useAccordionIndicatorAnimation
15
+ };
16
+ //# sourceMappingURL=use-accordion-indicator-animation.hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-accordion-indicator-animation.hook.ts"],"sourcesContent":["import { useAnimatedStyle } from \"react-native-reanimated\";\n\nimport type { AccordionAnimationOptions } from \"./accordion-animation.types\";\nimport { useAccordionAnimationProgress } from \"./use-accordion-animation-progress.hook\";\n\nexport function useAccordionIndicatorAnimation({\n duration,\n open,\n}: AccordionAnimationOptions) {\n const progress = useAccordionAnimationProgress({ duration, open });\n\n const indicatorStyle = useAnimatedStyle(() => ({\n transform: [{ rotate: `${progress.value * 180}deg` }],\n }));\n\n return indicatorStyle;\n}\n"],"mappings":"AAAA,SAAS,wBAAwB;AAGjC,SAAS,qCAAqC;AAEvC,SAAS,+BAA+B;AAAA,EAC7C;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,WAAW,8BAA8B,EAAE,UAAU,KAAK,CAAC;AAEjE,QAAM,iBAAiB,iBAAiB,OAAO;AAAA,IAC7C,WAAW,CAAC,EAAE,QAAQ,GAAG,SAAS,QAAQ,GAAG,MAAM,CAAC;AAAA,EACtD,EAAE;AAEF,SAAO;AACT;","names":[]}
@@ -0,0 +1,5 @@
1
+ export { Accordion } from './components/accordion.mjs';
2
+ export { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './types/accordion.types.mjs';
3
+ import 'react';
4
+ import 'react/jsx-runtime';
5
+ import 'react-native';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./components";
2
+ export * from "./types";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./components\";\nexport * from \"./types\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,40 @@
1
+ import { ReactNode } from 'react';
2
+ import { ViewProps, PressableProps, NativeSyntheticEvent } from 'react-native';
3
+
4
+ interface AccordionRootCommonProps extends ViewProps {
5
+ children?: ReactNode;
6
+ collapsible?: boolean;
7
+ disabled?: boolean;
8
+ }
9
+ interface AccordionSingleRootProps extends AccordionRootCommonProps {
10
+ defaultValue?: string;
11
+ onValueChange?: (value: string | undefined) => void;
12
+ type?: "single";
13
+ value?: string;
14
+ }
15
+ interface AccordionMultipleRootProps extends AccordionRootCommonProps {
16
+ defaultValue?: string[];
17
+ onValueChange?: (value: string[]) => void;
18
+ type: "multiple";
19
+ value?: string[];
20
+ }
21
+ type AccordionRootProps = AccordionSingleRootProps | AccordionMultipleRootProps;
22
+ interface AccordionItemProps extends ViewProps {
23
+ children?: ReactNode;
24
+ disabled?: boolean;
25
+ value: string;
26
+ }
27
+ interface AccordionTriggerProps extends Omit<PressableProps, "accessibilityRole" | "children"> {
28
+ children?: ReactNode;
29
+ hideIndicator?: boolean;
30
+ indicator?: ReactNode;
31
+ onKeyDown?: (event: AccordionKeyDownEvent) => void;
32
+ }
33
+ type AccordionKeyDownEvent = NativeSyntheticEvent<{
34
+ key: string;
35
+ }>;
36
+ interface AccordionContentProps extends ViewProps {
37
+ children?: ReactNode;
38
+ }
39
+
40
+ export type { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=accordion.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,3 @@
1
+ export { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './accordion.types.mjs';
2
+ import 'react';
3
+ import 'react-native';
@@ -0,0 +1,2 @@
1
+ export * from "./accordion.types";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export * from \"./accordion.types\";\n"],"mappings":"AAAA,cAAc;","names":[]}
@@ -0,0 +1,5 @@
1
+ type AccordionFocusDirection = "first" | "last" | "next" | "previous";
2
+ declare function getAccordionFocusDirection(key: string): AccordionFocusDirection | undefined;
3
+ declare function normalizeAccordionValue(value: string | readonly string[] | undefined): readonly string[];
4
+
5
+ export { type AccordionFocusDirection, getAccordionFocusDirection, normalizeAccordionValue };
@@ -0,0 +1,16 @@
1
+ function getAccordionFocusDirection(key) {
2
+ if (key === "ArrowDown") return "next";
3
+ if (key === "ArrowUp") return "previous";
4
+ if (key === "Home") return "first";
5
+ if (key === "End") return "last";
6
+ return void 0;
7
+ }
8
+ function normalizeAccordionValue(value) {
9
+ if (value === void 0) return [];
10
+ return typeof value === "string" ? [value] : value;
11
+ }
12
+ export {
13
+ getAccordionFocusDirection,
14
+ normalizeAccordionValue
15
+ };
16
+ //# sourceMappingURL=accordion.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/accordion.utils.ts"],"sourcesContent":["export type AccordionFocusDirection = \"first\" | \"last\" | \"next\" | \"previous\";\n\nexport function getAccordionFocusDirection(\n key: string,\n): AccordionFocusDirection | undefined {\n if (key === \"ArrowDown\") return \"next\";\n if (key === \"ArrowUp\") return \"previous\";\n if (key === \"Home\") return \"first\";\n if (key === \"End\") return \"last\";\n return undefined;\n}\n\nexport function normalizeAccordionValue(\n value: string | readonly string[] | undefined,\n): readonly string[] {\n if (value === undefined) return [];\n return typeof value === \"string\" ? [value] : value;\n}\n"],"mappings":"AAEO,SAAS,2BACd,KACqC;AACrC,MAAI,QAAQ,YAAa,QAAO;AAChC,MAAI,QAAQ,UAAW,QAAO;AAC9B,MAAI,QAAQ,OAAQ,QAAO;AAC3B,MAAI,QAAQ,MAAO,QAAO;AAC1B,SAAO;AACT;AAEO,SAAS,wBACd,OACmB;AACnB,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,SAAO,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI;AAC/C;","names":[]}
@@ -0,0 +1 @@
1
+ export { AccordionFocusDirection, getAccordionFocusDirection, normalizeAccordionValue } from './accordion.utils.mjs';
@@ -0,0 +1,2 @@
1
+ export * from "./accordion.utils";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from \"./accordion.utils\";\n"],"mappings":"AAAA,cAAc;","names":[]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@impulse-ui-native/accordion",
3
+ "version": "2.8.0",
4
+ "description": "Accessible animated accordion components for ImpulseUI Native applications.",
5
+ "keywords": [
6
+ "react-native",
7
+ "accordion",
8
+ "collapsible",
9
+ "disclosure",
10
+ "components",
11
+ "impulse-ui-native"
12
+ ],
13
+ "license": "MIT",
14
+ "source": "src/index.ts",
15
+ "module": "dist/index.js",
16
+ "types": "dist/index.d.mts",
17
+ "react-native": "src/index.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.mts",
21
+ "react-native": "./src/index.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "sideEffects": false,
31
+ "dependencies": {
32
+ "@impulse-ui-native/core": "2.8.0",
33
+ "@impulse-ui-native/icon": "2.8.0",
34
+ "@impulse-ui-native/primitives": "2.8.0",
35
+ "@impulse-ui-native/theme": "2.8.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/react": "~19.2.14",
39
+ "eslint": "^9.38.0",
40
+ "prettier": "^3.6.2",
41
+ "react": "19.2.3",
42
+ "react-native": "0.86.2",
43
+ "react-native-reanimated": "4.5.1",
44
+ "react-native-worklets": "0.10.1",
45
+ "typescript": "~6.0.3",
46
+ "@impulse-ui-native/prettier-config": "1.0.0",
47
+ "@impulse-ui-native/eslint-config": "1.0.0",
48
+ "@impulse-ui-native/tsconfig": "1.0.0"
49
+ },
50
+ "peerDependencies": {
51
+ "react": ">=18",
52
+ "react-native": ">=0.73",
53
+ "react-native-reanimated": ">=3.6.0",
54
+ "react-native-worklets": ">=0.5"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "prettier": "@impulse-ui-native/prettier-config",
60
+ "scripts": {
61
+ "build": "tsup --config tsup.config.ts",
62
+ "typecheck": "tsc -p tsconfig.json --noEmit",
63
+ "lint": "pnpm exec eslint . --fix",
64
+ "format": "prettier --write \"./**/*.{ts,tsx,js,jsx,json,md}\" --ignore-path ../../.prettierignore"
65
+ }
66
+ }