@cdx-ui/primitives 0.0.1-beta.175 → 0.0.1-beta.177

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 (65) hide show
  1. package/lib/commonjs/accordion/Accordion.js +24 -18
  2. package/lib/commonjs/accordion/Accordion.js.map +1 -1
  3. package/lib/commonjs/accordion/AccordionContent.js +73 -0
  4. package/lib/commonjs/accordion/AccordionContent.js.map +1 -0
  5. package/lib/commonjs/accordion/AccordionItem.js +13 -12
  6. package/lib/commonjs/accordion/AccordionItem.js.map +1 -1
  7. package/lib/commonjs/accordion/AccordionTrigger.js +8 -28
  8. package/lib/commonjs/accordion/AccordionTrigger.js.map +1 -1
  9. package/lib/commonjs/accordion/context.js +6 -18
  10. package/lib/commonjs/accordion/context.js.map +1 -1
  11. package/lib/commonjs/accordion/index.js +7 -7
  12. package/lib/commonjs/accordion/index.js.map +1 -1
  13. package/lib/commonjs/accordion/utils.js +1 -1
  14. package/lib/commonjs/accordion/utils.js.map +1 -1
  15. package/lib/commonjs/form/FormRoot.web.js +7 -2
  16. package/lib/commonjs/form/FormRoot.web.js.map +1 -1
  17. package/lib/module/accordion/Accordion.js +26 -20
  18. package/lib/module/accordion/Accordion.js.map +1 -1
  19. package/lib/module/accordion/AccordionContent.js +69 -0
  20. package/lib/module/accordion/AccordionContent.js.map +1 -0
  21. package/lib/module/accordion/AccordionItem.js +14 -13
  22. package/lib/module/accordion/AccordionItem.js.map +1 -1
  23. package/lib/module/accordion/AccordionTrigger.js +9 -29
  24. package/lib/module/accordion/AccordionTrigger.js.map +1 -1
  25. package/lib/module/accordion/context.js +3 -17
  26. package/lib/module/accordion/context.js.map +1 -1
  27. package/lib/module/accordion/index.js +2 -2
  28. package/lib/module/accordion/index.js.map +1 -1
  29. package/lib/module/accordion/utils.js +1 -1
  30. package/lib/module/accordion/utils.js.map +1 -1
  31. package/lib/module/form/FormRoot.web.js +7 -2
  32. package/lib/module/form/FormRoot.web.js.map +1 -1
  33. package/lib/typescript/accordion/Accordion.d.ts +2 -2
  34. package/lib/typescript/accordion/Accordion.d.ts.map +1 -1
  35. package/lib/typescript/accordion/AccordionContent.d.ts +8 -0
  36. package/lib/typescript/accordion/AccordionContent.d.ts.map +1 -0
  37. package/lib/typescript/accordion/AccordionItem.d.ts.map +1 -1
  38. package/lib/typescript/accordion/AccordionTrigger.d.ts.map +1 -1
  39. package/lib/typescript/accordion/context.d.ts +8 -4
  40. package/lib/typescript/accordion/context.d.ts.map +1 -1
  41. package/lib/typescript/accordion/index.d.ts +3 -3
  42. package/lib/typescript/accordion/index.d.ts.map +1 -1
  43. package/lib/typescript/accordion/types.d.ts +31 -19
  44. package/lib/typescript/accordion/types.d.ts.map +1 -1
  45. package/lib/typescript/accordion/utils.d.ts +1 -1
  46. package/lib/typescript/accordion/utils.d.ts.map +1 -1
  47. package/lib/typescript/form/FormRoot.web.d.ts +2 -0
  48. package/lib/typescript/form/FormRoot.web.d.ts.map +1 -1
  49. package/package.json +3 -4
  50. package/src/accordion/Accordion.tsx +83 -59
  51. package/src/accordion/AccordionContent.tsx +90 -0
  52. package/src/accordion/AccordionItem.tsx +19 -13
  53. package/src/accordion/AccordionTrigger.tsx +8 -29
  54. package/src/accordion/context.tsx +5 -19
  55. package/src/accordion/index.ts +6 -4
  56. package/src/accordion/types.ts +33 -19
  57. package/src/accordion/utils.ts +2 -2
  58. package/src/form/FormRoot.web.tsx +12 -6
  59. package/lib/commonjs/accordion/AccordionPanel.js +0 -71
  60. package/lib/commonjs/accordion/AccordionPanel.js.map +0 -1
  61. package/lib/module/accordion/AccordionPanel.js +0 -67
  62. package/lib/module/accordion/AccordionPanel.js.map +0 -1
  63. package/lib/typescript/accordion/AccordionPanel.d.ts +0 -7
  64. package/lib/typescript/accordion/AccordionPanel.d.ts.map +0 -1
  65. package/src/accordion/AccordionPanel.tsx +0 -72
@@ -1,72 +1,96 @@
1
- import { forwardRef, useMemo } from 'react';
2
- import { View } from 'react-native';
1
+ import { forwardRef, useCallback, useMemo } from 'react';
2
+ import { View, type ViewProps } from 'react-native';
3
3
  import { useDisclosureGroupState } from '@react-stately/disclosure';
4
4
  import { Slot } from '../slot';
5
5
  import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
6
- import { AccordionContext } from './context';
7
- import type { IAccordionProps } from './types';
6
+ import { AccordionProvider } from './context';
7
+ import type { AccordionType, IAccordionProps } from './types';
8
8
  import { fromExpandedKeys, toExpandedKeys } from './utils';
9
9
 
10
- export interface AccordionRootProps extends IAccordionProps {
10
+ type WidenedAccordionProps = ViewProps & {
11
11
  asChild?: boolean;
12
12
  className?: string;
13
- }
13
+ type?: AccordionType;
14
+ collapsible?: boolean;
15
+ isDisabled?: boolean;
16
+ value?: string | string[];
17
+ defaultValue?: string | string[];
18
+ onValueChange?: (value: string | string[] | undefined) => void;
19
+ 'aria-label'?: string;
20
+ 'aria-labelledby'?: string;
21
+ };
14
22
 
15
- export const AccordionRoot = forwardRef<View, AccordionRootProps>(
16
- (
17
- {
18
- asChild,
19
- children,
20
- className,
21
- style,
22
- type = 'single',
23
- collapsible = true,
24
- isDisabled = false,
25
- value,
26
- defaultValue,
27
- onValueChange,
28
- ...props
29
- },
30
- ref,
31
- ) => {
32
- const groupState = useDisclosureGroupState({
33
- allowsMultipleExpanded: type === 'multiple',
34
- isDisabled,
35
- expandedKeys: toExpandedKeys(value),
36
- defaultExpandedKeys: toExpandedKeys(defaultValue),
37
- onExpandedChange: onValueChange
38
- ? (keys) => {
39
- onValueChange(fromExpandedKeys(keys, type));
40
- }
41
- : undefined,
42
- });
23
+ export type AccordionRootProps = IAccordionProps & {
24
+ asChild?: boolean;
25
+ className?: string;
26
+ };
43
27
 
44
- const contextValue = useMemo(
45
- () => ({
46
- groupState,
47
- type,
48
- collapsible,
49
- isDisabled,
50
- }),
51
- [groupState, type, collapsible, isDisabled],
52
- );
28
+ export const AccordionRoot = forwardRef<View, AccordionRootProps>((accordionProps, ref) => {
29
+ const {
30
+ asChild,
31
+ children,
32
+ className,
33
+ style,
34
+ type = 'single',
35
+ collapsible = true,
36
+ isDisabled = false,
37
+ value,
38
+ defaultValue,
39
+ onValueChange,
40
+ ...props
41
+ } = accordionProps as WidenedAccordionProps;
42
+ const isValueControlled = Object.prototype.hasOwnProperty.call(accordionProps, 'value');
43
+ const expandedKeys = useMemo(
44
+ () => (isValueControlled ? (toExpandedKeys(value) ?? new Set<string>()) : undefined),
45
+ [isValueControlled, value],
46
+ );
47
+ const groupState = useDisclosureGroupState({
48
+ allowsMultipleExpanded: type === 'multiple',
49
+ isDisabled,
50
+ expandedKeys,
51
+ defaultExpandedKeys: toExpandedKeys(defaultValue),
52
+ onExpandedChange: onValueChange
53
+ ? (keys) => {
54
+ onValueChange(fromExpandedKeys(keys, type));
55
+ }
56
+ : undefined,
57
+ });
58
+
59
+ const isItemOpen = useCallback(
60
+ (itemValue: string) => groupState.expandedKeys.has(itemValue),
61
+ [groupState.expandedKeys],
62
+ );
63
+ const toggleItem = useCallback(
64
+ (itemValue: string) => groupState.toggleKey(itemValue),
65
+ [groupState],
66
+ );
67
+
68
+ const contextValue = useMemo(
69
+ () => ({
70
+ type,
71
+ collapsible,
72
+ isDisabled,
73
+ isItemOpen,
74
+ toggleItem,
75
+ }),
76
+ [type, collapsible, isDisabled, isItemOpen, toggleItem],
77
+ );
53
78
 
54
- const Comp = asChild ? Slot : View;
79
+ const Comp = asChild ? Slot : View;
55
80
 
56
- return (
57
- <AccordionContext.Provider value={contextValue}>
58
- <Comp
59
- ref={ref}
60
- className={className}
61
- style={style}
62
- {...props}
63
- {...mergeDataAttributes(props, dataAttributes({ slot: 'accordion' }))}
64
- >
65
- {children}
66
- </Comp>
67
- </AccordionContext.Provider>
68
- );
69
- },
70
- );
81
+ return (
82
+ <AccordionProvider value={contextValue}>
83
+ <Comp
84
+ ref={ref}
85
+ className={className}
86
+ style={style}
87
+ {...props}
88
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'accordion' }))}
89
+ >
90
+ {children}
91
+ </Comp>
92
+ </AccordionProvider>
93
+ );
94
+ });
71
95
 
72
96
  AccordionRoot.displayName = 'AccordionRoot';
@@ -0,0 +1,90 @@
1
+ import { forwardRef } from 'react';
2
+ import { Platform, View } from 'react-native';
3
+ import { Slot } from '../slot';
4
+ import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
5
+ import {
6
+ domDataAttributes,
7
+ mergeDomDataAttributes,
8
+ type DomDataAttributeValue,
9
+ } from '../utils/domDataAttributes';
10
+ import { useAccordionItemContext } from './context';
11
+ import type { IAccordionContentProps } from './types';
12
+
13
+ export interface AccordionContentRootProps extends IAccordionContentProps {
14
+ asChild?: boolean;
15
+ className?: string;
16
+ }
17
+
18
+ export const AccordionContentRoot = forwardRef<View, AccordionContentRootProps>(
19
+ ({ asChild, children, className, style, ...props }, ref) => {
20
+ const { isOpen, triggerId, contentId } = useAccordionItemContext();
21
+ const Comp = asChild ? Slot : View;
22
+
23
+ if (!isOpen) {
24
+ return null;
25
+ }
26
+
27
+ const dataAttrValues = {
28
+ slot: 'accordion-content',
29
+ state: 'open',
30
+ };
31
+
32
+ if (Platform.OS === 'web' && asChild) {
33
+ const {
34
+ dataSet,
35
+ nativeID: _nativeID,
36
+ ...domProps
37
+ } = props as typeof props & {
38
+ dataSet?: Record<string, DomDataAttributeValue>;
39
+ };
40
+ const dataAttrs = mergeDomDataAttributes(
41
+ domDataAttributes(dataSet ?? {}),
42
+ domProps,
43
+ domDataAttributes(dataAttrValues),
44
+ );
45
+
46
+ return (
47
+ <Slot
48
+ ref={ref}
49
+ className={className}
50
+ style={style}
51
+ {...domProps}
52
+ {...dataAttrs}
53
+ id={contentId}
54
+ role="region"
55
+ aria-labelledby={triggerId}
56
+ >
57
+ {children}
58
+ </Slot>
59
+ );
60
+ }
61
+
62
+ const platformA11yProps =
63
+ Platform.OS === 'web'
64
+ ? {
65
+ id: contentId,
66
+ role: 'region' as const,
67
+ 'aria-labelledby': triggerId,
68
+ }
69
+ : {
70
+ nativeID: contentId,
71
+ accessibilityLabelledBy: triggerId,
72
+ accessibilityRole: 'none' as const,
73
+ };
74
+
75
+ return (
76
+ <Comp
77
+ ref={ref}
78
+ className={className}
79
+ style={style}
80
+ {...props}
81
+ {...mergeDataAttributes(props, dataAttributes(dataAttrValues))}
82
+ {...platformA11yProps}
83
+ >
84
+ {children}
85
+ </Comp>
86
+ );
87
+ },
88
+ );
89
+
90
+ AccordionContentRoot.displayName = 'AccordionContentRoot';
@@ -2,7 +2,7 @@ import { forwardRef, useCallback, useId, useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { Slot } from '../slot';
4
4
  import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
5
- import { AccordionItemContext, useAccordionContext } from './context';
5
+ import { AccordionItemProvider, useAccordionContext } from './context';
6
6
  import type { IAccordionItemProps } from './types';
7
7
 
8
8
  export interface AccordionItemRootProps extends IAccordionItemProps {
@@ -12,40 +12,46 @@ export interface AccordionItemRootProps extends IAccordionItemProps {
12
12
 
13
13
  export const AccordionItemRoot = forwardRef<View, AccordionItemRootProps>(
14
14
  ({ asChild, children, className, style, value, disabled = false, ...props }, ref) => {
15
- const { groupState, type, collapsible, isDisabled: groupDisabled } = useAccordionContext();
15
+ const {
16
+ type,
17
+ collapsible,
18
+ isDisabled: groupDisabled,
19
+ isItemOpen,
20
+ toggleItem,
21
+ } = useAccordionContext();
16
22
  const reactId = useId().replace(/[^a-zA-Z0-9_-]/g, '');
17
23
  const triggerId = `accordion-${reactId}-trigger`;
18
- const panelId = `accordion-${reactId}-panel`;
24
+ const contentId = `accordion-${reactId}-content`;
19
25
 
20
- const isExpanded = groupState.expandedKeys.has(value);
26
+ const isOpen = isItemOpen(value);
21
27
  const isDisabled = disabled || groupDisabled;
22
28
 
23
29
  const toggle = useCallback(() => {
24
30
  if (isDisabled) {
25
31
  return;
26
32
  }
27
- if (type === 'single' && !collapsible && isExpanded) {
33
+ if (type === 'single' && !collapsible && isOpen) {
28
34
  return;
29
35
  }
30
- groupState.toggleKey(value);
31
- }, [isDisabled, type, collapsible, isExpanded, groupState, value]);
36
+ toggleItem(value);
37
+ }, [isDisabled, type, collapsible, isOpen, toggleItem, value]);
32
38
 
33
39
  const contextValue = useMemo(
34
40
  () => ({
35
41
  value,
36
- isExpanded,
42
+ isOpen,
37
43
  isDisabled,
38
44
  triggerId,
39
- panelId,
45
+ contentId,
40
46
  toggle,
41
47
  }),
42
- [value, isExpanded, isDisabled, triggerId, panelId, toggle],
48
+ [value, isOpen, isDisabled, triggerId, contentId, toggle],
43
49
  );
44
50
 
45
51
  const Comp = asChild ? Slot : View;
46
52
 
47
53
  return (
48
- <AccordionItemContext.Provider value={contextValue}>
54
+ <AccordionItemProvider value={contextValue}>
49
55
  <Comp
50
56
  ref={ref}
51
57
  className={className}
@@ -55,14 +61,14 @@ export const AccordionItemRoot = forwardRef<View, AccordionItemRootProps>(
55
61
  props,
56
62
  dataAttributes({
57
63
  slot: 'accordion-item',
58
- state: isExpanded ? 'open' : 'closed',
64
+ state: isOpen ? 'open' : 'closed',
59
65
  disabled: isDisabled,
60
66
  }),
61
67
  )}
62
68
  >
63
69
  {children}
64
70
  </Comp>
65
- </AccordionItemContext.Provider>
71
+ </AccordionItemProvider>
66
72
  );
67
73
  },
68
74
  );
@@ -1,9 +1,8 @@
1
- import { forwardRef, useMemo } from 'react';
1
+ import { forwardRef } from 'react';
2
2
  import { Platform, Pressable } from 'react-native';
3
3
  import { composeEventHandlers } from '@cdx-ui/utils';
4
4
  import { useFocus, useFocusRing } from '@react-native-aria/focus';
5
5
  import { usePress, useHover } from '@react-native-aria/interactions';
6
- import { useDisclosureButton } from '@react-native-aria/disclosure';
7
6
  import { Slot } from '../slot';
8
7
  import { dataAttributes, mergeDataAttributes } from '../utils/dataAttributes';
9
8
  import { useAccordionItemContext } from './context';
@@ -35,23 +34,7 @@ export const AccordionTriggerRoot = forwardRef<
35
34
  },
36
35
  ref,
37
36
  ) => {
38
- const { isExpanded, isDisabled, triggerId, panelId, toggle } = useAccordionItemContext();
39
-
40
- const toggleState = useMemo(
41
- () => ({
42
- isSelected: isExpanded,
43
- defaultSelected: false,
44
- setSelected: (selected: boolean) => {
45
- if (selected !== isExpanded) {
46
- toggle();
47
- }
48
- },
49
- toggle,
50
- }),
51
- [isExpanded, toggle],
52
- );
53
-
54
- const { buttonProps } = useDisclosureButton({}, toggleState);
37
+ const { isOpen, isDisabled, triggerId, contentId, toggle } = useAccordionItemContext();
55
38
  const { focusProps, isFocused } = useFocus();
56
39
  const { focusProps: focusRingProps, isFocusVisible } = useFocusRing() as {
57
40
  focusProps: { onFocus?: () => void; onBlur?: () => void };
@@ -67,20 +50,17 @@ export const AccordionTriggerRoot = forwardRef<
67
50
  ? {
68
51
  id: triggerId,
69
52
  role: 'button' as const,
70
- 'aria-expanded': isExpanded,
53
+ 'aria-expanded': isOpen,
71
54
  'aria-disabled': isDisabled || undefined,
72
- 'aria-controls': isExpanded ? panelId : undefined,
55
+ 'aria-controls': contentId,
73
56
  }
74
57
  : {
75
58
  nativeID: triggerId,
76
59
  accessibilityRole: 'button' as const,
77
- accessibilityState: { expanded: isExpanded, disabled: isDisabled },
78
- accessibilityControls: isExpanded ? panelId : undefined,
60
+ accessibilityState: { expanded: isOpen, disabled: isDisabled },
61
+ accessibilityControls: contentId,
79
62
  };
80
63
 
81
- const { onPress: disclosureOnPress, ...disclosureRestProps } = buttonProps;
82
- const disclosureProps = Platform.OS === 'web' ? {} : disclosureRestProps;
83
-
84
64
  return (
85
65
  <Comp
86
66
  ref={ref}
@@ -89,13 +69,12 @@ export const AccordionTriggerRoot = forwardRef<
89
69
  className={className}
90
70
  style={style}
91
71
  {...props}
92
- {...disclosureProps}
93
72
  {...platformA11yProps}
94
73
  {...mergeDataAttributes(
95
74
  props,
96
75
  dataAttributes({
97
76
  slot: 'accordion-trigger',
98
- state: isExpanded ? 'open' : 'closed',
77
+ state: isOpen ? 'open' : 'closed',
99
78
  disabled: isDisabled,
100
79
  hover: isHovered,
101
80
  active: isPressed,
@@ -107,7 +86,7 @@ export const AccordionTriggerRoot = forwardRef<
107
86
  onPressOut={composeEventHandlers(onPressOut, pressProps.onPressOut)}
108
87
  onHoverIn={composeEventHandlers(onHoverIn, hoverProps.onHoverIn)}
109
88
  onHoverOut={composeEventHandlers(onHoverOut, hoverProps.onHoverOut)}
110
- onPress={composeEventHandlers(onPress, disclosureOnPress)}
89
+ onPress={composeEventHandlers(onPress, toggle)}
111
90
  onFocus={composeEventHandlers(onFocus, focusProps.onFocus, focusRingProps.onFocus)}
112
91
  onBlur={composeEventHandlers(onBlur, focusProps.onBlur, focusRingProps.onBlur)}
113
92
  >
@@ -1,22 +1,8 @@
1
- import { createContext, useContext } from 'react';
1
+ import { createContext } from '@cdx-ui/utils';
2
2
  import type { IAccordionContextValue, IAccordionItemContextValue } from './types';
3
3
 
4
- export const AccordionContext = createContext<IAccordionContextValue | null>(null);
4
+ export const [AccordionProvider, useAccordionContext] =
5
+ createContext<IAccordionContextValue>('AccordionContext');
5
6
 
6
- export const AccordionItemContext = createContext<IAccordionItemContextValue | null>(null);
7
-
8
- export function useAccordionContext(): IAccordionContextValue {
9
- const context = useContext(AccordionContext);
10
- if (!context) {
11
- throw new Error('Accordion compound components must be used within Accordion');
12
- }
13
- return context;
14
- }
15
-
16
- export function useAccordionItemContext(): IAccordionItemContextValue {
17
- const context = useContext(AccordionItemContext);
18
- if (!context) {
19
- throw new Error('Accordion.Item sub-components must be used within Accordion.Item');
20
- }
21
- return context;
22
- }
7
+ export const [AccordionItemProvider, useAccordionItemContext] =
8
+ createContext<IAccordionItemContextValue>('AccordionItemContext');
@@ -1,16 +1,18 @@
1
1
  export type {
2
2
  IAccordionProps,
3
+ IAccordionSingleProps,
4
+ IAccordionMultipleProps,
3
5
  IAccordionItemProps,
4
6
  IAccordionTriggerProps,
5
- IAccordionPanelProps,
7
+ IAccordionContentProps,
6
8
  IAccordionContextValue,
7
9
  IAccordionItemContextValue,
8
10
  AccordionType,
9
11
  } from './types';
10
12
 
11
13
  export {
12
- AccordionContext,
13
- AccordionItemContext,
14
+ AccordionProvider,
15
+ AccordionItemProvider,
14
16
  useAccordionContext,
15
17
  useAccordionItemContext,
16
18
  } from './context';
@@ -18,4 +20,4 @@ export {
18
20
  export { AccordionRoot, type AccordionRootProps } from './Accordion';
19
21
  export { AccordionItemRoot, type AccordionItemRootProps } from './AccordionItem';
20
22
  export { AccordionTriggerRoot, type AccordionTriggerRootProps } from './AccordionTrigger';
21
- export { AccordionPanelRoot, type AccordionPanelRootProps } from './AccordionPanel';
23
+ export { AccordionContentRoot, type AccordionContentRootProps } from './AccordionContent';
@@ -1,26 +1,42 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { PressableProps, ViewProps } from 'react-native';
3
- import type { DisclosureGroupState } from '@react-stately/disclosure';
4
3
 
5
4
  export type AccordionType = 'single' | 'multiple';
6
5
 
7
- export interface IAccordionProps extends ViewProps {
8
- /** Controlled expanded item value(s). */
9
- value?: string | string[];
10
- /** Default expanded value(s) for uncontrolled usage. */
11
- defaultValue?: string | string[];
12
- /** Called when expanded items change. */
13
- onValueChange?: (value: string | string[]) => void;
14
- /** Single-select (accordion) vs multi-select (disclosure group). @default 'single' */
15
- type?: AccordionType;
16
- /** When `type="single"`, allow closing the open item. @default true */
17
- collapsible?: boolean;
6
+ interface IAccordionBaseProps extends ViewProps {
18
7
  /** Disables expansion for all items. */
19
8
  isDisabled?: boolean;
20
9
  'aria-label'?: string;
21
10
  'aria-labelledby'?: string;
22
11
  }
23
12
 
13
+ export interface IAccordionSingleProps extends IAccordionBaseProps {
14
+ /** Single-item expansion mode. @default 'single' */
15
+ type?: 'single';
16
+ /** Controlled open item value. */
17
+ value?: string;
18
+ /** Initial open item value for uncontrolled usage. */
19
+ defaultValue?: string;
20
+ /** Called when the open item changes. */
21
+ onValueChange?: (value: string | undefined) => void;
22
+ /** Allows closing the open item. @default true */
23
+ collapsible?: boolean;
24
+ }
25
+
26
+ export interface IAccordionMultipleProps extends IAccordionBaseProps {
27
+ /** Multiple-item expansion mode. */
28
+ type: 'multiple';
29
+ /** Controlled open item values. */
30
+ value?: string[];
31
+ /** Initial open item values for uncontrolled usage. */
32
+ defaultValue?: string[];
33
+ /** Called when the open items change. */
34
+ onValueChange?: (value: string[]) => void;
35
+ collapsible?: never;
36
+ }
37
+
38
+ export type IAccordionProps = IAccordionSingleProps | IAccordionMultipleProps;
39
+
24
40
  export interface IAccordionItemProps extends ViewProps {
25
41
  /** Required stable id within the Accordion. */
26
42
  value: string;
@@ -32,25 +48,23 @@ export interface IAccordionTriggerProps extends PressableProps {
32
48
  asChild?: boolean;
33
49
  }
34
50
 
35
- export interface IAccordionPanelProps extends ViewProps {
51
+ export interface IAccordionContentProps extends ViewProps {
36
52
  children?: ReactNode;
37
- className?: string;
38
53
  }
39
54
 
40
55
  export interface IAccordionContextValue {
41
- groupState: DisclosureGroupState;
42
56
  type: AccordionType;
43
57
  collapsible: boolean;
44
58
  isDisabled: boolean;
59
+ isItemOpen: (value: string) => boolean;
60
+ toggleItem: (value: string) => void;
45
61
  }
46
62
 
47
63
  export interface IAccordionItemContextValue {
48
64
  value: string;
49
- isExpanded: boolean;
65
+ isOpen: boolean;
50
66
  isDisabled: boolean;
51
67
  triggerId: string;
52
- panelId: string;
68
+ contentId: string;
53
69
  toggle: () => void;
54
- disableGutters?: boolean;
55
- showSeparator?: boolean;
56
70
  }
@@ -16,7 +16,7 @@ export function toExpandedKeys(value: string | string[] | undefined): Set<string
16
16
  export function fromExpandedKeys(
17
17
  keys: Iterable<string | number>,
18
18
  type: AccordionType,
19
- ): string | string[] {
19
+ ): string | string[] | undefined {
20
20
  const values = Array.from(keys).map(String);
21
- return type === 'single' ? (values[0] ?? '') : values;
21
+ return type === 'single' ? values[0] : values;
22
22
  }
@@ -1,17 +1,23 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import { Slot } from '../slot';
3
+ import { domDataAttributes, type DomDataAttributeValue } from '../utils/domDataAttributes';
3
4
 
4
5
  export interface FormRootProps extends React.FormHTMLAttributes<HTMLFormElement> {
5
6
  asChild?: boolean;
6
7
  className?: string;
7
8
  children?: React.ReactNode;
9
+ dataSet?: Record<string, DomDataAttributeValue>;
8
10
  }
9
11
 
10
- export const FormRoot = forwardRef<HTMLFormElement, FormRootProps>(({ asChild, ...props }, ref) => {
11
- if (asChild) {
12
- return <Slot ref={ref} {...(props as Record<string, unknown>)} />;
13
- }
14
- return <form ref={ref} {...props} />;
15
- });
12
+ export const FormRoot = forwardRef<HTMLFormElement, FormRootProps>(
13
+ ({ asChild, dataSet, ...props }, ref) => {
14
+ const dataAttrs = domDataAttributes(dataSet ?? {});
15
+
16
+ if (asChild) {
17
+ return <Slot ref={ref} {...(props as Record<string, unknown>)} {...dataAttrs} />;
18
+ }
19
+ return <form ref={ref} {...props} {...dataAttrs} />;
20
+ },
21
+ );
16
22
 
17
23
  FormRoot.displayName = 'FormRoot';
@@ -1,71 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.AccordionPanelRoot = void 0;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _disclosure = require("@react-native-aria/disclosure");
10
- var _slot = require("../slot");
11
- var _dataAttributes = require("../utils/dataAttributes");
12
- var _context = require("./context");
13
- var _jsxRuntime = require("react/jsx-runtime");
14
- const AccordionPanelRoot = exports.AccordionPanelRoot = /*#__PURE__*/(0, _react.forwardRef)(({
15
- asChild,
16
- children,
17
- className,
18
- style,
19
- ...props
20
- }, ref) => {
21
- const {
22
- isExpanded,
23
- isDisabled,
24
- triggerId,
25
- panelId,
26
- toggle
27
- } = (0, _context.useAccordionItemContext)();
28
- const toggleState = {
29
- isSelected: isExpanded,
30
- defaultSelected: false,
31
- setSelected: selected => {
32
- if (selected !== isExpanded) {
33
- toggle();
34
- }
35
- },
36
- toggle
37
- };
38
- const {
39
- disclosureProps
40
- } = (0, _disclosure.useDisclosure)({}, toggleState);
41
- const Comp = asChild ? _slot.Slot : _reactNative.View;
42
- if (!isExpanded) {
43
- return null;
44
- }
45
- const platformA11yProps = _reactNative.Platform.OS === 'web' ? {
46
- id: panelId,
47
- nativeID: panelId,
48
- role: 'region',
49
- 'aria-labelledby': triggerId
50
- } : {
51
- nativeID: panelId,
52
- accessibilityLabelledBy: triggerId,
53
- accessibilityRole: 'none'
54
- };
55
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
56
- ref: ref,
57
- className: className,
58
- style: style,
59
- ...disclosureProps,
60
- ...props,
61
- ...(0, _dataAttributes.mergeDataAttributes)(props, (0, _dataAttributes.dataAttributes)({
62
- slot: 'accordion-panel',
63
- state: 'open',
64
- disabled: isDisabled
65
- })),
66
- ...platformA11yProps,
67
- children: children
68
- });
69
- });
70
- AccordionPanelRoot.displayName = 'AccordionPanelRoot';
71
- //# sourceMappingURL=AccordionPanel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","_reactNative","_disclosure","_slot","_dataAttributes","_context","_jsxRuntime","AccordionPanelRoot","exports","forwardRef","asChild","children","className","style","props","ref","isExpanded","isDisabled","triggerId","panelId","toggle","useAccordionItemContext","toggleState","isSelected","defaultSelected","setSelected","selected","disclosureProps","useDisclosure","Comp","Slot","View","platformA11yProps","Platform","OS","id","nativeID","role","accessibilityLabelledBy","accessibilityRole","jsx","mergeDataAttributes","dataAttributes","slot","state","disabled","displayName"],"sourceRoot":"../../../src","sources":["accordion/AccordionPanel.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AACA,IAAAK,QAAA,GAAAL,OAAA;AAAoD,IAAAM,WAAA,GAAAN,OAAA;AAO7C,MAAMO,kBAAkB,GAAAC,OAAA,CAAAD,kBAAA,gBAAG,IAAAE,iBAAU,EAC1C,CAAC;EAAEC,OAAO;EAAEC,QAAQ;EAAEC,SAAS;EAAEC,KAAK;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EAC1D,MAAM;IAAEC,UAAU;IAAEC,UAAU;IAAEC,SAAS;IAAEC,OAAO;IAAEC;EAAO,CAAC,GAAG,IAAAC,gCAAuB,EAAC,CAAC;EAExF,MAAMC,WAAW,GAAG;IAClBC,UAAU,EAAEP,UAAU;IACtBQ,eAAe,EAAE,KAAK;IACtBC,WAAW,EAAGC,QAAiB,IAAK;MAClC,IAAIA,QAAQ,KAAKV,UAAU,EAAE;QAC3BI,MAAM,CAAC,CAAC;MACV;IACF,CAAC;IACDA;EACF,CAAC;EAED,MAAM;IAAEO;EAAgB,CAAC,GAAG,IAAAC,yBAAa,EAAC,CAAC,CAAC,EAAEN,WAAW,CAAC;EAC1D,MAAMO,IAAI,GAAGnB,OAAO,GAAGoB,UAAI,GAAGC,iBAAI;EAElC,IAAI,CAACf,UAAU,EAAE;IACf,OAAO,IAAI;EACb;EAEA,MAAMgB,iBAAiB,GACrBC,qBAAQ,CAACC,EAAE,KAAK,KAAK,GACjB;IACEC,EAAE,EAAEhB,OAAO;IACXiB,QAAQ,EAAEjB,OAAO;IACjBkB,IAAI,EAAE,QAAiB;IACvB,iBAAiB,EAAEnB;EACrB,CAAC,GACD;IACEkB,QAAQ,EAAEjB,OAAO;IACjBmB,uBAAuB,EAAEpB,SAAS;IAClCqB,iBAAiB,EAAE;EACrB,CAAC;EAEP,oBACE,IAAAjC,WAAA,CAAAkC,GAAA,EAACX,IAAI;IACHd,GAAG,EAAEA,GAAI;IACTH,SAAS,EAAEA,SAAU;IACrBC,KAAK,EAAEA,KAAM;IAAA,GACTc,eAAe;IAAA,GACfb,KAAK;IAAA,GACL,IAAA2B,mCAAmB,EACrB3B,KAAK,EACL,IAAA4B,8BAAc,EAAC;MACbC,IAAI,EAAE,iBAAiB;MACvBC,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE5B;IACZ,CAAC,CACH,CAAC;IAAA,GACGe,iBAAiB;IAAArB,QAAA,EAEpBA;EAAQ,CACL,CAAC;AAEX,CACF,CAAC;AAEDJ,kBAAkB,CAACuC,WAAW,GAAG,oBAAoB","ignoreList":[]}