@impulse-ui-native/accordion 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @impulse-ui-native/accordion
2
2
 
3
- Accessible compound accordion and collapsible sections for React Native and React Native Web.
3
+ Compound accordion and collapsible sections for React Native mobile applications.
4
4
 
5
5
  ## Installation
6
6
 
@@ -14,7 +14,7 @@ Render the component inside `ThemeProvider` from `@impulse-ui-native/theme` and
14
14
 
15
15
  - `Accordion.Root` manages controlled or uncontrolled single/multiple expansion.
16
16
  - `Accordion.Item` provides an independently disabled disclosure item.
17
- - `Accordion.Trigger` exposes expanded state and keyboard navigation.
17
+ - `Accordion.Trigger` toggles its item's expanded state.
18
18
  - `Accordion.Content` animates measured height while keeping nested content mounted.
19
19
  - Public prop types are available for every compound part.
20
20
 
@@ -42,4 +42,4 @@ export function FrequentlyAskedQuestions() {
42
42
 
43
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
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.
45
+ Content remains mounted during collapse, which preserves local and nested component state.
@@ -7,7 +7,7 @@ declare const Accordion: {
7
7
  Content: react.MemoExoticComponent<({ children, onLayout, style, ...props }: AccordionContentProps) => react_jsx_runtime.JSX.Element>;
8
8
  Item: react.MemoExoticComponent<({ children, disabled, style, value, ...props }: AccordionItemProps) => react_jsx_runtime.JSX.Element>;
9
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>;
10
+ Trigger: react.MemoExoticComponent<({ children, disabled, hideIndicator, indicator, onPress, style, ...props }: AccordionTriggerProps) => react_jsx_runtime.JSX.Element>;
11
11
  };
12
12
 
13
13
  export { Accordion };
@@ -35,23 +35,9 @@ const AccordionContent = memo(function AccordionContent2({
35
35
  return /* @__PURE__ */ jsx(
36
36
  Animated.View,
37
37
  {
38
- "aria-hidden": !item.open,
39
- accessibilityElementsHidden: !item.open,
40
- importantForAccessibility: item.open ? "auto" : "no-hide-descendants",
41
38
  pointerEvents: item.open ? "auto" : "none",
42
39
  style: viewportStyle,
43
- children: /* @__PURE__ */ jsx(
44
- View,
45
- {
46
- ...props,
47
- "aria-labelledby": item.triggerId,
48
- accessibilityLabelledBy: item.triggerId,
49
- nativeID: item.contentId,
50
- onLayout: handleLayout,
51
- style: innerStyle,
52
- children
53
- }
54
- )
40
+ children: /* @__PURE__ */ jsx(View, { ...props, onLayout: handleLayout, style: innerStyle, children })
55
41
  }
56
42
  );
57
43
  });
@@ -1 +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 type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useThemedStyles } 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 styles = useThemedStyles(themedStyles);\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, styles.viewport],\n );\n const innerStyle = useMemo(\n () => [styles.content, style],\n [style, styles.content],\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\nfunction themedStyles(theme: AppTheme) {\n const contentTokens = theme.components.accordion.content;\n\n return StyleSheet.create({\n content: {\n left: 0,\n paddingBottom: contentTokens.paddingBottom,\n paddingHorizontal: contentTokens.paddingHorizontal,\n position: \"absolute\",\n right: 0,\n top: 0,\n },\n viewport: {\n overflow: \"hidden\",\n },\n });\n}\n"],"mappings":"AAkDM;AAjDN,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAGrB,SAAS,wBAAwB;AACjC,SAAS,YAAY;AACrB,SAAS,qBAAqB,uBAAuB;AAGrD,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,SAAS,gBAAgB,YAAY;AAC3C,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,cAAc,OAAO,QAAQ;AAAA,EAChC;AACA,QAAM,aAAa;AAAA,IACjB,MAAM,CAAC,OAAO,SAAS,KAAK;AAAA,IAC5B,CAAC,OAAO,OAAO,OAAO;AAAA,EACxB;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,SAAS,aAAa,OAAiB;AACrC,QAAM,gBAAgB,MAAM,WAAW,UAAU;AAEjD,SAAO,WAAW,OAAO;AAAA,IACvB,SAAS;AAAA,MACP,MAAM;AAAA,MACN,eAAe,cAAc;AAAA,MAC7B,mBAAmB,cAAc;AAAA,MACjC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,KAAK;AAAA,IACP;AAAA,IACA,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;","names":["AccordionContent"]}
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 type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useThemedStyles } 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 styles = useThemedStyles(themedStyles);\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, styles.viewport],\n );\n const innerStyle = useMemo(\n () => [styles.content, style],\n [style, styles.content],\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 pointerEvents={item.open ? \"auto\" : \"none\"}\n style={viewportStyle}\n >\n <View {...props} onLayout={handleLayout} style={innerStyle}>\n {children}\n </View>\n </Animated.View>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n const contentTokens = theme.components.accordion.content;\n\n return StyleSheet.create({\n content: {\n left: 0,\n paddingBottom: contentTokens.paddingBottom,\n paddingHorizontal: contentTokens.paddingHorizontal,\n position: \"absolute\",\n right: 0,\n top: 0,\n },\n viewport: {\n overflow: \"hidden\",\n },\n });\n}\n"],"mappings":"AA+CM;AA9CN,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAGrB,SAAS,wBAAwB;AACjC,SAAS,YAAY;AACrB,SAAS,qBAAqB,uBAAuB;AAGrD,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,SAAS,gBAAgB,YAAY;AAC3C,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,cAAc,OAAO,QAAQ;AAAA,EAChC;AACA,QAAM,aAAa;AAAA,IACjB,MAAM,CAAC,OAAO,SAAS,KAAK;AAAA,IAC5B,CAAC,OAAO,OAAO,OAAO;AAAA,EACxB;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,eAAe,KAAK,OAAO,SAAS;AAAA,MACpC,OAAO;AAAA,MAEP,8BAAC,QAAM,GAAG,OAAO,UAAU,cAAc,OAAO,YAC7C,UACH;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,QAAM,gBAAgB,MAAM,WAAW,UAAU;AAEjD,SAAO,WAAW,OAAO;AAAA,IACvB,SAAS;AAAA,MACP,MAAM;AAAA,MACN,eAAe,cAAc;AAAA,MAC7B,mBAAmB,cAAc;AAAA,MACjC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,KAAK;AAAA,IACP;AAAA,IACA,UAAU;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;","names":["AccordionContent"]}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { memo, useId, useMemo } from "react";
2
+ import { memo, useMemo } from "react";
3
3
  import { StyleSheet } from "react-native";
4
4
  import { View } from "@impulse-ui-native/primitives";
5
5
  import { useThemedStyles } from "@impulse-ui-native/theme";
@@ -12,19 +12,16 @@ const AccordionItem = memo(function AccordionItem2({
12
12
  ...props
13
13
  }) {
14
14
  const accordion = useAccordionContext();
15
- const reactId = useId().replaceAll(":", "");
16
15
  const styles = useThemedStyles(themedStyles);
17
16
  const resolvedDisabled = accordion.disabled || disabled;
18
17
  const open = accordion.expandedValues.includes(value);
19
18
  const context = useMemo(
20
19
  () => ({
21
- contentId: `accordion-content-${reactId}`,
22
20
  disabled: resolvedDisabled,
23
21
  open,
24
- triggerId: `accordion-trigger-${reactId}`,
25
22
  value
26
23
  }),
27
- [open, reactId, resolvedDisabled, value]
24
+ [open, resolvedDisabled, value]
28
25
  );
29
26
  const itemStyle = useMemo(() => [styles.item, style], [style, styles.item]);
30
27
  return /* @__PURE__ */ jsx(AccordionItemProvider, { value: context, children: /* @__PURE__ */ jsx(View, { ...props, style: itemStyle, children }) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/item.tsx"],"sourcesContent":["import { memo, useId, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useThemedStyles } 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 reactId = useId().replaceAll(\":\", \"\");\n const styles = useThemedStyles(themedStyles);\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(() => [styles.item, style], [style, styles.item]);\n\n return (\n <AccordionItemProvider value={context}>\n <View {...props} style={itemStyle}>\n {children}\n </View>\n </AccordionItemProvider>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n return StyleSheet.create({\n item: {\n backgroundColor: theme.components.accordion.backgroundColor,\n },\n });\n}\n"],"mappings":"AAsCM;AAtCN,SAAS,MAAM,OAAO,eAAe;AACrC,SAAS,kBAAkB;AAG3B,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAIhC,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,UAAU,MAAM,EAAE,WAAW,KAAK,EAAE;AAC1C,QAAM,SAAS,gBAAgB,YAAY;AAC3C,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,QAAQ,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,CAAC,OAAO,OAAO,IAAI,CAAC;AAE1E,SACE,oBAAC,yBAAsB,OAAO,SAC5B,8BAAC,QAAM,GAAG,OAAO,OAAO,WACrB,UACH,GACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,SAAO,WAAW,OAAO;AAAA,IACvB,MAAM;AAAA,MACJ,iBAAiB,MAAM,WAAW,UAAU;AAAA,IAC9C;AAAA,EACF,CAAC;AACH;","names":["AccordionItem"]}
1
+ {"version":3,"sources":["../../src/components/item.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useThemedStyles } 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 styles = useThemedStyles(themedStyles);\n const resolvedDisabled = accordion.disabled || disabled;\n const open = accordion.expandedValues.includes(value);\n\n const context = useMemo<AccordionItemContextData>(\n () => ({\n disabled: resolvedDisabled,\n open,\n value,\n }),\n [open, resolvedDisabled, value],\n );\n const itemStyle = useMemo(() => [styles.item, style], [style, styles.item]);\n\n return (\n <AccordionItemProvider value={context}>\n <View {...props} style={itemStyle}>\n {children}\n </View>\n </AccordionItemProvider>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n return StyleSheet.create({\n item: {\n backgroundColor: theme.components.accordion.backgroundColor,\n },\n });\n}\n"],"mappings":"AAmCM;AAnCN,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAAkB;AAG3B,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAIhC,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,gBAAgB,YAAY;AAC3C,QAAM,mBAAmB,UAAU,YAAY;AAC/C,QAAM,OAAO,UAAU,eAAe,SAAS,KAAK;AAEpD,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,kBAAkB,KAAK;AAAA,EAChC;AACA,QAAM,YAAY,QAAQ,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,CAAC,OAAO,OAAO,IAAI,CAAC;AAE1E,SACE,oBAAC,yBAAsB,OAAO,SAC5B,8BAAC,QAAM,GAAG,OAAO,OAAO,WACrB,UACH,GACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,SAAO,WAAW,OAAO;AAAA,IACvB,MAAM;AAAA,MACJ,iBAAiB,MAAM,WAAW,UAAU;AAAA,IAC9C;AAAA,EACF,CAAC;AACH;","names":["AccordionItem"]}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { memo, useCallback, useMemo, useRef } from "react";
2
+ import { memo, useCallback, useMemo } from "react";
3
3
  import { StyleSheet } from "react-native";
4
4
  import {
5
5
  useControllableState,
@@ -20,7 +20,6 @@ const AccordionRoot = memo(function AccordionRoot2({
20
20
  value,
21
21
  ...props
22
22
  }) {
23
- const triggerRegistry = useRef([]);
24
23
  const styles = useThemedStyles(themedStyles);
25
24
  const notifyValueChange = useEventCallback(
26
25
  (nextValues) => {
@@ -48,36 +47,6 @@ const AccordionRoot = memo(function AccordionRoot2({
48
47
  defaultProp: normalizedDefaultValue,
49
48
  onChange: notifyValueChange
50
49
  });
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
50
  const toggleItem = useCallback(
82
51
  (itemValue) => {
83
52
  setExpandedValues((currentValues) => {
@@ -97,11 +66,9 @@ const AccordionRoot = memo(function AccordionRoot2({
97
66
  () => ({
98
67
  disabled,
99
68
  expandedValues,
100
- focusTrigger,
101
- registerTrigger,
102
69
  toggleItem
103
70
  }),
104
- [disabled, expandedValues, focusTrigger, registerTrigger, toggleItem]
71
+ [disabled, expandedValues, toggleItem]
105
72
  );
106
73
  const rootStyle = useMemo(() => [styles.root, style], [style, styles.root]);
107
74
  return /* @__PURE__ */ jsx(AccordionProvider, { value: context, children: /* @__PURE__ */ jsx(View, { ...props, style: rootStyle, children }) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/root.tsx"],"sourcesContent":["import { memo, useCallback, useMemo, useRef } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport {\n useControllableState,\n useEventCallback,\n} from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useThemedStyles } 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 triggerRegistry = useRef<TriggerRegistration[]>([]);\n const styles = useThemedStyles(themedStyles);\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(() => [styles.root, style], [style, styles.root]);\n\n return (\n <AccordionProvider value={context}>\n <View {...props} style={rootStyle}>\n {children}\n </View>\n </AccordionProvider>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n const accordionTokens = theme.components.accordion;\n\n return StyleSheet.create({\n root: {\n backgroundColor: accordionTokens.dividerColor,\n borderColor: accordionTokens.borderColor,\n borderRadius: accordionTokens.borderRadius,\n borderWidth: accordionTokens.borderWidth,\n gap: accordionTokens.dividerWidth,\n overflow: \"hidden\",\n },\n });\n}\n"],"mappings":"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","names":["AccordionRoot"]}
1
+ {"version":3,"sources":["../../src/components/root.tsx"],"sourcesContent":["import { memo, useCallback, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport {\n useControllableState,\n useEventCallback,\n} from \"@impulse-ui-native/core\";\nimport { View } from \"@impulse-ui-native/primitives\";\nimport { useThemedStyles } 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\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 styles = useThemedStyles(themedStyles);\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 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 toggleItem,\n }),\n [disabled, expandedValues, toggleItem],\n );\n const rootStyle = useMemo(() => [styles.root, style], [style, styles.root]);\n\n return (\n <AccordionProvider value={context}>\n <View {...props} style={rootStyle}>\n {children}\n </View>\n </AccordionProvider>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n const accordionTokens = theme.components.accordion;\n\n return StyleSheet.create({\n root: {\n backgroundColor: accordionTokens.dividerColor,\n borderColor: accordionTokens.borderColor,\n borderRadius: accordionTokens.borderRadius,\n borderWidth: accordionTokens.borderWidth,\n gap: accordionTokens.dividerWidth,\n overflow: \"hidden\",\n },\n });\n}\n"],"mappings":"AAgGM;AAhGN,SAAS,MAAM,aAAa,eAAe;AAC3C,SAAS,kBAAkB;AAG3B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAQhC,SAAS,yBAAyB;AAClC,SAAS,+BAA+B;AAEjC,MAAM,gBAAgB,KAAK,SAASA,eAAc;AAAA,EACvD;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,SAAS,gBAAgB,YAAY;AAE3C,QAAM,oBAAoB;AAAA,IACxB,CAAC,eAAkC;AACjC,UAAI,SAAS,YAAY;AACvB,QAAC,gBAAgE;AAAA,UAC/D,GAAG;AAAA,QACL,CAAC;AACD;AAAA,MACF;AAEA,MAAC;AAAA,QACC,WAAW,CAAC;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,QAAM,kBAAkB;AAAA,IACtB,MAAO,UAAU,SAAY,SAAY,wBAAwB,KAAK;AAAA,IACtE,CAAC,KAAK;AAAA,EACR;AACA,QAAM,yBAAyB;AAAA,IAC7B,MAAM,wBAAwB,YAAY;AAAA,IAC1C,CAAC,YAAY;AAAA,EACf;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,qBAE1C;AAAA,IACA,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,EACZ,CAAC;AAED,QAAM,aAAa;AAAA,IACjB,CAAC,cAAsB;AACrB,wBAAkB,CAAC,kBAAkB;AACnC,cAAM,SAAS,cAAc,SAAS,SAAS;AAE/C,YAAI,SAAS,YAAY;AACvB,iBAAO,SACH,cAAc,OAAO,CAAC,YAAY,YAAY,SAAS,IACvD,CAAC,GAAG,eAAe,SAAS;AAAA,QAClC;AAEA,YAAI,QAAQ;AACV,iBAAO,cAAc,CAAC,IAAI;AAAA,QAC5B;AAEA,eAAO,CAAC,SAAS;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,mBAAmB,IAAI;AAAA,EACvC;AAEA,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,UAAU,gBAAgB,UAAU;AAAA,EACvC;AACA,QAAM,YAAY,QAAQ,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,CAAC,OAAO,OAAO,IAAI,CAAC;AAE1E,SACE,oBAAC,qBAAkB,OAAO,SACxB,8BAAC,QAAM,GAAG,OAAO,OAAO,WACrB,UACH,GACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,QAAM,kBAAkB,MAAM,WAAW;AAEzC,SAAO,WAAW,OAAO;AAAA,IACvB,MAAM;AAAA,MACJ,iBAAiB,gBAAgB;AAAA,MACjC,aAAa,gBAAgB;AAAA,MAC7B,cAAc,gBAAgB;AAAA,MAC9B,aAAa,gBAAgB;AAAA,MAC7B,KAAK,gBAAgB;AAAA,MACrB,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;","names":["AccordionRoot"]}
@@ -3,6 +3,6 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { AccordionTriggerProps } from '../types/accordion.types.mjs';
4
4
  import 'react-native';
5
5
 
6
- declare const AccordionTrigger: react.MemoExoticComponent<({ accessibilityState, onBlur, children, disabled, hideIndicator, indicator, onFocus, onKeyDown, onPress, style, ...props }: AccordionTriggerProps) => react_jsx_runtime.JSX.Element>;
6
+ declare const AccordionTrigger: react.MemoExoticComponent<({ children, disabled, hideIndicator, indicator, onPress, style, ...props }: AccordionTriggerProps) => react_jsx_runtime.JSX.Element>;
7
7
 
8
8
  export { AccordionTrigger };
@@ -1,51 +1,38 @@
1
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";
2
+ import { memo, useCallback } from "react";
3
+ import { StyleSheet } from "react-native";
4
4
  import Animated from "react-native-reanimated";
5
5
  import { useEventCallback } from "@impulse-ui-native/core";
6
6
  import { Icon } from "@impulse-ui-native/icon/components/icon";
7
7
  import { CaretDownIcon } from "@impulse-ui-native/icon/icons/caret-down";
8
8
  import { Pressable, Typography, View } from "@impulse-ui-native/primitives";
9
- import { useComponentsTokens, useThemedStyles } from "@impulse-ui-native/theme";
9
+ import {
10
+ getControlStateTokens,
11
+ useComponentsTokens,
12
+ useThemedStyles
13
+ } from "@impulse-ui-native/theme";
10
14
  import { useAccordionContext, useAccordionItemContext } from "../contexts";
11
15
  import { useAccordionIndicatorAnimation } from "../hooks";
12
- import { getAccordionFocusDirection } from "../utils";
13
16
  const AccordionTrigger = memo(function AccordionTrigger2({
14
- accessibilityState,
15
- onBlur,
16
17
  children,
17
18
  disabled,
18
19
  hideIndicator = false,
19
20
  indicator,
20
- onFocus,
21
- onKeyDown,
22
21
  onPress,
23
22
  style,
24
23
  ...props
25
24
  }) {
26
- const { focusTrigger, registerTrigger, toggleItem } = useAccordionContext();
25
+ const { toggleItem } = useAccordionContext();
27
26
  const item = useAccordionItemContext();
28
- const [focused, setFocused] = useState(false);
29
- const triggerRef = useRef(null);
30
27
  const tokens = useComponentsTokens().accordion;
31
28
  const resolvedDisabled = item.disabled || disabled === true;
32
29
  const indicatorStyle = useAccordionIndicatorAnimation({
33
30
  duration: tokens.animationDuration,
34
31
  open: item.open
35
32
  });
36
- const styles = useThemedStyles(
37
- themedStyles,
38
- { focused, disabled: resolvedDisabled },
39
- [focused, resolvedDisabled]
40
- );
41
- const resolvedAccessibilityState = useMemo(
42
- () => ({
43
- ...accessibilityState,
44
- disabled: resolvedDisabled,
45
- expanded: item.open
46
- }),
47
- [accessibilityState, item.open, resolvedDisabled]
48
- );
33
+ const styles = useThemedStyles(themedStyles, { disabled: resolvedDisabled }, [
34
+ resolvedDisabled
35
+ ]);
49
36
  const triggerStyle = useCallback(
50
37
  ({ pressed }) => [
51
38
  styles.trigger,
@@ -54,60 +41,15 @@ const AccordionTrigger = memo(function AccordionTrigger2({
54
41
  ],
55
42
  [style, styles.trigger, styles.triggerPressed]
56
43
  );
57
- const handleBlur = useEventCallback(
58
- (event) => {
59
- setFocused(false);
60
- onBlur?.(event);
61
- }
62
- );
63
- const handleFocus = useEventCallback(
64
- (event) => {
65
- setFocused(true);
66
- onFocus?.(event);
67
- }
68
- );
69
44
  const handlePress = useEventCallback((event) => {
70
45
  toggleItem(item.value);
71
46
  onPress?.(event);
72
47
  });
73
- const handleKeyDown = useEventCallback((event) => {
74
- onKeyDown?.(event);
75
- if (event.isDefaultPrevented()) return;
76
- const direction = getAccordionFocusDirection(event.nativeEvent.key);
77
- if (direction) {
78
- event.preventDefault();
79
- focusTrigger(item.value, direction);
80
- }
81
- });
82
- const webInteractionProps = useMemo(
83
- () => Platform.OS === "web" ? {
84
- "aria-controls": item.contentId,
85
- onKeyDown: handleKeyDown
86
- } : void 0,
87
- [handleKeyDown, item.contentId]
88
- );
89
- useEffect(
90
- () => registerTrigger({
91
- disabled: resolvedDisabled,
92
- ref: triggerRef,
93
- value: item.value
94
- }),
95
- [item.value, registerTrigger, resolvedDisabled]
96
- );
97
48
  return /* @__PURE__ */ jsxs(
98
49
  Pressable,
99
50
  {
100
51
  ...props,
101
- ...webInteractionProps,
102
- ref: triggerRef,
103
- "aria-expanded": item.open,
104
- accessibilityRole: "button",
105
- accessibilityState: resolvedAccessibilityState,
106
52
  disabled: resolvedDisabled,
107
- focusable: !resolvedDisabled,
108
- nativeID: item.triggerId,
109
- onBlur: handleBlur,
110
- onFocus: handleFocus,
111
53
  onPress: handlePress,
112
54
  style: triggerStyle,
113
55
  children: [
@@ -115,7 +57,7 @@ const AccordionTrigger = memo(function AccordionTrigger2({
115
57
  hideIndicator ? null : /* @__PURE__ */ jsx(Animated.View, { pointerEvents: "none", style: indicatorStyle, children: indicator ?? /* @__PURE__ */ jsx(
116
58
  Icon,
117
59
  {
118
- color: resolvedDisabled ? tokens.disabledColor : tokens.iconColor,
60
+ color: styles.icon.color,
119
61
  icon: CaretDownIcon,
120
62
  size: tokens.iconSize
121
63
  }
@@ -125,25 +67,32 @@ const AccordionTrigger = memo(function AccordionTrigger2({
125
67
  );
126
68
  });
127
69
  function themedStyles(theme, props) {
128
- const { disabled, focused } = props;
70
+ const { disabled } = props;
129
71
  const accordionTokens = theme.components.accordion;
72
+ const appearanceTokens = getControlStateTokens(
73
+ accordionTokens.trigger.states,
74
+ { disabled }
75
+ );
130
76
  return StyleSheet.create({
131
77
  title: {
132
- color: disabled ? accordionTokens.disabledColor : accordionTokens.titleColor
78
+ color: appearanceTokens.titleColor
79
+ },
80
+ icon: {
81
+ color: appearanceTokens.iconColor
133
82
  },
134
83
  trigger: {
135
84
  alignItems: "center",
136
- backgroundColor: focused ? accordionTokens.focusBackgroundColor : "transparent",
85
+ backgroundColor: appearanceTokens.backgroundColor,
137
86
  flexDirection: "row",
138
87
  gap: accordionTokens.trigger.gap,
139
88
  justifyContent: "space-between",
140
89
  minHeight: accordionTokens.trigger.minHeight,
141
- opacity: disabled ? accordionTokens.disabledOpacity : 1,
90
+ opacity: appearanceTokens.opacity,
142
91
  paddingHorizontal: accordionTokens.trigger.paddingHorizontal,
143
92
  paddingVertical: accordionTokens.trigger.paddingVertical
144
93
  },
145
94
  triggerPressed: {
146
- opacity: disabled ? accordionTokens.disabledOpacity : accordionTokens.pressedOpacity
95
+ opacity: appearanceTokens.pressedOpacity
147
96
  }
148
97
  });
149
98
  }
@@ -1 +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 type { AppTheme } from \"@impulse-ui-native/theme\";\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, useThemedStyles } 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 [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 tokens = useComponentsTokens().accordion;\n const resolvedDisabled = item.disabled || disabled === true;\n const indicatorStyle = useAccordionIndicatorAnimation({\n duration: tokens.animationDuration,\n open: item.open,\n });\n const styles = useThemedStyles(\n themedStyles,\n { focused, disabled: resolvedDisabled },\n [focused, resolvedDisabled],\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 triggerStyle = useCallback(\n ({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => [\n styles.trigger,\n pressed ? styles.triggerPressed : undefined,\n typeof style === \"function\" ? style({ pressed }) : style,\n ],\n [style, styles.trigger, styles.triggerPressed],\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={styles.title}>{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\ninterface AccordionTriggerThemeProps {\n disabled: boolean;\n focused: boolean;\n}\n\nfunction themedStyles(theme: AppTheme, props: AccordionTriggerThemeProps) {\n const { disabled, focused } = props;\n const accordionTokens = theme.components.accordion;\n\n return StyleSheet.create({\n title: {\n color: disabled\n ? accordionTokens.disabledColor\n : accordionTokens.titleColor,\n },\n trigger: {\n alignItems: \"center\",\n backgroundColor: focused\n ? accordionTokens.focusBackgroundColor\n : \"transparent\",\n flexDirection: \"row\",\n gap: accordionTokens.trigger.gap,\n justifyContent: \"space-between\",\n minHeight: accordionTokens.trigger.minHeight,\n opacity: disabled ? accordionTokens.disabledOpacity : 1,\n paddingHorizontal: accordionTokens.trigger.paddingHorizontal,\n paddingVertical: accordionTokens.trigger.paddingVertical,\n },\n triggerPressed: {\n opacity: disabled\n ? accordionTokens.disabledOpacity\n : accordionTokens.pressedOpacity,\n },\n });\n}\n"],"mappings":"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","names":["AccordionTrigger"]}
1
+ {"version":3,"sources":["../../src/components/trigger.tsx"],"sourcesContent":["import type {\n GestureResponderEvent,\n PressableStateCallbackType,\n StyleProp,\n ViewStyle,\n} from \"react-native\";\nimport { memo, useCallback } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated from \"react-native-reanimated\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\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 {\n getControlStateTokens,\n useComponentsTokens,\n useThemedStyles,\n} from \"@impulse-ui-native/theme\";\n\nimport type { AccordionTriggerProps } from \"../types\";\nimport { useAccordionContext, useAccordionItemContext } from \"../contexts\";\nimport { useAccordionIndicatorAnimation } from \"../hooks\";\n\nexport const AccordionTrigger = memo(function AccordionTrigger({\n children,\n disabled,\n hideIndicator = false,\n indicator,\n onPress,\n style,\n ...props\n}: AccordionTriggerProps) {\n const { toggleItem } = useAccordionContext();\n const item = useAccordionItemContext();\n const tokens = useComponentsTokens().accordion;\n const resolvedDisabled = item.disabled || disabled === true;\n const indicatorStyle = useAccordionIndicatorAnimation({\n duration: tokens.animationDuration,\n open: item.open,\n });\n const styles = useThemedStyles(themedStyles, { disabled: resolvedDisabled }, [\n resolvedDisabled,\n ]);\n const triggerStyle = useCallback(\n ({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => [\n styles.trigger,\n pressed ? styles.triggerPressed : undefined,\n typeof style === \"function\" ? style({ pressed }) : style,\n ],\n [style, styles.trigger, styles.triggerPressed],\n );\n\n const handlePress = useEventCallback((event: GestureResponderEvent) => {\n toggleItem(item.value);\n onPress?.(event);\n });\n\n return (\n <Pressable\n {...props}\n disabled={resolvedDisabled}\n onPress={handlePress}\n style={triggerStyle}\n >\n <View flex={1} pointerEvents=\"none\">\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Typography.Label style={styles.title}>{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={styles.icon.color}\n icon={CaretDownIcon}\n size={tokens.iconSize}\n />\n )}\n </Animated.View>\n )}\n </Pressable>\n );\n});\n\ninterface AccordionTriggerThemeProps {\n disabled: boolean;\n}\n\nfunction themedStyles(theme: AppTheme, props: AccordionTriggerThemeProps) {\n const { disabled } = props;\n const accordionTokens = theme.components.accordion;\n const appearanceTokens = getControlStateTokens(\n accordionTokens.trigger.states,\n { disabled },\n );\n\n return StyleSheet.create({\n title: {\n color: appearanceTokens.titleColor,\n },\n icon: {\n color: appearanceTokens.iconColor,\n },\n trigger: {\n alignItems: \"center\",\n backgroundColor: appearanceTokens.backgroundColor,\n flexDirection: \"row\",\n gap: accordionTokens.trigger.gap,\n justifyContent: \"space-between\",\n minHeight: accordionTokens.trigger.minHeight,\n opacity: appearanceTokens.opacity,\n paddingHorizontal: accordionTokens.trigger.paddingHorizontal,\n paddingVertical: accordionTokens.trigger.paddingVertical,\n },\n triggerPressed: {\n opacity: appearanceTokens.pressedOpacity,\n },\n });\n}\n"],"mappings":"AA4DI,SAQM,KARN;AAtDJ,SAAS,MAAM,mBAAmB;AAClC,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAGrB,SAAS,wBAAwB;AACjC,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAC9B,SAAS,WAAW,YAAY,YAAY;AAC5C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,qBAAqB,+BAA+B;AAC7D,SAAS,sCAAsC;AAExC,MAAM,mBAAmB,KAAK,SAASA,kBAAiB;AAAA,EAC7D;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,WAAW,IAAI,oBAAoB;AAC3C,QAAM,OAAO,wBAAwB;AACrC,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,mBAAmB,KAAK,YAAY,aAAa;AACvD,QAAM,iBAAiB,+BAA+B;AAAA,IACpD,UAAU,OAAO;AAAA,IACjB,MAAM,KAAK;AAAA,EACb,CAAC;AACD,QAAM,SAAS,gBAAgB,cAAc,EAAE,UAAU,iBAAiB,GAAG;AAAA,IAC3E;AAAA,EACF,CAAC;AACD,QAAM,eAAe;AAAA,IACnB,CAAC,EAAE,QAAQ,MAAwD;AAAA,MACjE,OAAO;AAAA,MACP,UAAU,OAAO,iBAAiB;AAAA,MAClC,OAAO,UAAU,aAAa,MAAM,EAAE,QAAQ,CAAC,IAAI;AAAA,IACrD;AAAA,IACA,CAAC,OAAO,OAAO,SAAS,OAAO,cAAc;AAAA,EAC/C;AAEA,QAAM,cAAc,iBAAiB,CAAC,UAAiC;AACrE,eAAW,KAAK,KAAK;AACrB,cAAU,KAAK;AAAA,EACjB,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MAEP;AAAA,4BAAC,QAAK,MAAM,GAAG,eAAc,QAC1B,iBAAO,aAAa,YAAY,OAAO,aAAa,WACnD,oBAAC,WAAW,OAAX,EAAiB,OAAO,OAAO,OAAQ,UAAS,IAEjD,UAEJ;AAAA,QAEC,gBAAgB,OACf,oBAAC,SAAS,MAAT,EAAc,eAAc,QAAO,OAAO,gBACxC,uBACC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO,KAAK;AAAA,YACnB,MAAM;AAAA,YACN,MAAM,OAAO;AAAA;AAAA,QACf,GAEJ;AAAA;AAAA;AAAA,EAEJ;AAEJ,CAAC;AAMD,SAAS,aAAa,OAAiB,OAAmC;AACxE,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,kBAAkB,MAAM,WAAW;AACzC,QAAM,mBAAmB;AAAA,IACvB,gBAAgB,QAAQ;AAAA,IACxB,EAAE,SAAS;AAAA,EACb;AAEA,SAAO,WAAW,OAAO;AAAA,IACvB,OAAO;AAAA,MACL,OAAO,iBAAiB;AAAA,IAC1B;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,iBAAiB;AAAA,IAC1B;AAAA,IACA,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,iBAAiB,iBAAiB;AAAA,MAClC,eAAe;AAAA,MACf,KAAK,gBAAgB,QAAQ;AAAA,MAC7B,gBAAgB;AAAA,MAChB,WAAW,gBAAgB,QAAQ;AAAA,MACnC,SAAS,iBAAiB;AAAA,MAC1B,mBAAmB,gBAAgB,QAAQ;AAAA,MAC3C,iBAAiB,gBAAgB,QAAQ;AAAA,IAC3C;AAAA,IACA,gBAAgB;AAAA,MACd,SAAS,iBAAiB;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;","names":["AccordionTrigger"]}
@@ -1,25 +1,13 @@
1
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
2
 
6
- interface AccordionTriggerRegistration {
7
- disabled: boolean;
8
- ref: RefObject<ComponentRef<typeof Pressable> | null>;
9
- value: string;
10
- }
11
3
  interface AccordionContextData {
12
4
  disabled: boolean;
13
5
  expandedValues: readonly string[];
14
- focusTrigger: (value: string, direction: AccordionFocusDirection) => void;
15
- registerTrigger: (registration: AccordionTriggerRegistration) => () => void;
16
6
  toggleItem: (value: string) => void;
17
7
  }
18
8
  interface AccordionItemContextData {
19
- contentId: string;
20
9
  disabled: boolean;
21
10
  open: boolean;
22
- triggerId: string;
23
11
  value: string;
24
12
  }
25
13
  declare const AccordionProvider: react.Provider<AccordionContextData | undefined>;
@@ -1 +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":[]}
1
+ {"version":3,"sources":["../../src/contexts/accordion.context.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\n\nexport interface AccordionContextData {\n disabled: boolean;\n expandedValues: readonly string[];\n toggleItem: (value: string) => void;\n}\n\nexport interface AccordionItemContextData {\n disabled: boolean;\n open: boolean;\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":"AAAA,SAAS,eAAe,kBAAkB;AAc1C,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":[]}
@@ -1,4 +1,2 @@
1
1
  export { AccordionContextData, AccordionItemContextData, AccordionItemProvider, AccordionProvider, useAccordionContext, useAccordionItemContext } from './accordion.context.mjs';
2
2
  import 'react';
3
- import '@impulse-ui-native/primitives';
4
- import '../utils/accordion.utils.mjs';
@@ -1,23 +1,17 @@
1
1
  import { useEffect } from "react";
2
- import {
3
- Easing,
4
- useReducedMotion,
5
- useSharedValue,
6
- withTiming
7
- } from "react-native-reanimated";
2
+ import { Easing, useSharedValue, withTiming } from "react-native-reanimated";
8
3
  const accordionEasing = Easing.out(Easing.cubic);
9
4
  function useAccordionAnimationProgress({
10
5
  duration,
11
6
  open
12
7
  }) {
13
- const reduceMotion = useReducedMotion();
14
8
  const progress = useSharedValue(open ? 1 : 0);
15
9
  useEffect(() => {
16
10
  progress.value = withTiming(open ? 1 : 0, {
17
- duration: reduceMotion ? 0 : duration,
11
+ duration,
18
12
  easing: accordionEasing
19
13
  });
20
- }, [duration, open, progress, reduceMotion]);
14
+ }, [duration, open, progress]);
21
15
  return progress;
22
16
  }
23
17
  export {
@@ -1 +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":[]}
1
+ {"version":3,"sources":["../../src/hooks/use-accordion-animation-progress.hook.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { Easing, useSharedValue, withTiming } 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 progress = useSharedValue(open ? 1 : 0);\n\n useEffect(() => {\n progress.value = withTiming(open ? 1 : 0, {\n duration,\n easing: accordionEasing,\n });\n }, [duration, open, progress]);\n\n return progress;\n}\n"],"mappings":"AAAA,SAAS,iBAAiB;AAC1B,SAAS,QAAQ,gBAAgB,kBAAkB;AAInD,MAAM,kBAAkB,OAAO,IAAI,OAAO,KAAK;AAExC,SAAS,8BAA8B;AAAA,EAC5C;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,WAAW,eAAe,OAAO,IAAI,CAAC;AAE5C,YAAU,MAAM;AACd,aAAS,QAAQ,WAAW,OAAO,IAAI,GAAG;AAAA,MACxC;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,GAAG,CAAC,UAAU,MAAM,QAAQ,CAAC;AAE7B,SAAO;AACT;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Accordion } from './components/accordion.mjs';
2
- export { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './types/accordion.types.mjs';
2
+ export { AccordionContentProps, AccordionItemProps, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './types/accordion.types.mjs';
3
3
  import 'react';
4
4
  import 'react/jsx-runtime';
5
5
  import 'react-native';
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { ViewProps, PressableProps, NativeSyntheticEvent } from 'react-native';
2
+ import { ViewProps, PressableProps } from 'react-native';
3
3
 
4
4
  interface AccordionRootCommonProps extends ViewProps {
5
5
  children?: ReactNode;
@@ -24,17 +24,13 @@ interface AccordionItemProps extends ViewProps {
24
24
  disabled?: boolean;
25
25
  value: string;
26
26
  }
27
- interface AccordionTriggerProps extends Omit<PressableProps, "accessibilityRole" | "children"> {
27
+ interface AccordionTriggerProps extends Omit<PressableProps, "children"> {
28
28
  children?: ReactNode;
29
29
  hideIndicator?: boolean;
30
30
  indicator?: ReactNode;
31
- onKeyDown?: (event: AccordionKeyDownEvent) => void;
32
31
  }
33
- type AccordionKeyDownEvent = NativeSyntheticEvent<{
34
- key: string;
35
- }>;
36
32
  interface AccordionContentProps extends ViewProps {
37
33
  children?: ReactNode;
38
34
  }
39
35
 
40
- export type { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps };
36
+ export type { AccordionContentProps, AccordionItemProps, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps };
@@ -1,3 +1,3 @@
1
- export { AccordionContentProps, AccordionItemProps, AccordionKeyDownEvent, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './accordion.types.mjs';
1
+ export { AccordionContentProps, AccordionItemProps, AccordionMultipleRootProps, AccordionRootProps, AccordionSingleRootProps, AccordionTriggerProps } from './accordion.types.mjs';
2
2
  import 'react';
3
3
  import 'react-native';
@@ -1,5 +1,3 @@
1
- type AccordionFocusDirection = "first" | "last" | "next" | "previous";
2
- declare function getAccordionFocusDirection(key: string): AccordionFocusDirection | undefined;
3
1
  declare function normalizeAccordionValue(value: string | readonly string[] | undefined): readonly string[];
4
2
 
5
- export { type AccordionFocusDirection, getAccordionFocusDirection, normalizeAccordionValue };
3
+ export { normalizeAccordionValue };
@@ -1,16 +1,8 @@
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
1
  function normalizeAccordionValue(value) {
9
2
  if (value === void 0) return [];
10
3
  return typeof value === "string" ? [value] : value;
11
4
  }
12
5
  export {
13
- getAccordionFocusDirection,
14
6
  normalizeAccordionValue
15
7
  };
16
8
  //# sourceMappingURL=accordion.utils.js.map
@@ -1 +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":[]}
1
+ {"version":3,"sources":["../../src/utils/accordion.utils.ts"],"sourcesContent":["export 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":"AAAO,SAAS,wBACd,OACmB;AACnB,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,SAAO,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI;AAC/C;","names":[]}
@@ -1 +1 @@
1
- export { AccordionFocusDirection, getAccordionFocusDirection, normalizeAccordionValue } from './accordion.utils.mjs';
1
+ export { normalizeAccordionValue } from './accordion.utils.mjs';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@impulse-ui-native/accordion",
3
- "version": "3.0.0",
4
- "description": "Accessible animated accordion components for ImpulseUI Native applications.",
3
+ "version": "5.0.0",
4
+ "description": "Animated accordion components for ImpulseUI Native applications.",
5
5
  "keywords": [
6
6
  "react-native",
7
7
  "accordion",
@@ -29,10 +29,10 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
- "@impulse-ui-native/core": "3.0.0",
33
- "@impulse-ui-native/primitives": "3.0.0",
34
- "@impulse-ui-native/theme": "3.0.0",
35
- "@impulse-ui-native/icon": "3.0.0"
32
+ "@impulse-ui-native/core": "5.0.0",
33
+ "@impulse-ui-native/primitives": "5.0.0",
34
+ "@impulse-ui-native/icon": "5.0.0",
35
+ "@impulse-ui-native/theme": "5.0.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/react": "~19.2.14",
@@ -43,8 +43,8 @@
43
43
  "react-native-reanimated": "4.5.1",
44
44
  "react-native-worklets": "0.10.1",
45
45
  "typescript": "~6.0.3",
46
- "@impulse-ui-native/eslint-config": "1.0.0",
47
46
  "@impulse-ui-native/prettier-config": "1.0.0",
47
+ "@impulse-ui-native/eslint-config": "1.0.0",
48
48
  "@impulse-ui-native/tsconfig": "1.0.0"
49
49
  },
50
50
  "peerDependencies": {