@cdx-ui/primitives 0.0.1-alpha.1 → 0.0.1-alpha.11

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 (147) hide show
  1. package/lib/commonjs/button/createButtonRoot.js +3 -3
  2. package/lib/commonjs/button/createButtonRoot.js.map +1 -1
  3. package/lib/commonjs/button/index.js +18 -19
  4. package/lib/commonjs/button/index.js.map +1 -1
  5. package/lib/commonjs/checkbox/context.js +14 -0
  6. package/lib/commonjs/checkbox/context.js.map +1 -0
  7. package/lib/commonjs/checkbox/createCheckboxGroup.js +44 -0
  8. package/lib/commonjs/checkbox/createCheckboxGroup.js.map +1 -0
  9. package/lib/commonjs/checkbox/createCheckboxIcon.js +28 -0
  10. package/lib/commonjs/checkbox/createCheckboxIcon.js.map +1 -0
  11. package/lib/commonjs/checkbox/createCheckboxIndicator.js +47 -0
  12. package/lib/commonjs/checkbox/createCheckboxIndicator.js.map +1 -0
  13. package/lib/commonjs/checkbox/createCheckboxLabel.js +46 -0
  14. package/lib/commonjs/checkbox/createCheckboxLabel.js.map +1 -0
  15. package/lib/commonjs/checkbox/createCheckboxRoot.js +99 -0
  16. package/lib/commonjs/checkbox/createCheckboxRoot.js.map +1 -0
  17. package/lib/commonjs/checkbox/createCheckboxRoot.web.js +90 -0
  18. package/lib/commonjs/checkbox/createCheckboxRoot.web.js.map +1 -0
  19. package/lib/commonjs/checkbox/index.js +30 -0
  20. package/lib/commonjs/checkbox/index.js.map +1 -0
  21. package/lib/commonjs/checkbox/types.js +6 -0
  22. package/lib/commonjs/checkbox/types.js.map +1 -0
  23. package/lib/commonjs/checkbox/useCheckboxRoot.js +82 -0
  24. package/lib/commonjs/checkbox/useCheckboxRoot.js.map +1 -0
  25. package/lib/commonjs/index.js +25 -1
  26. package/lib/commonjs/index.js.map +1 -1
  27. package/lib/commonjs/input/index.js +16 -18
  28. package/lib/commonjs/input/index.js.map +1 -1
  29. package/lib/commonjs/select/context.js.map +1 -1
  30. package/lib/commonjs/switch/createSwitchRoot.js +73 -0
  31. package/lib/commonjs/switch/createSwitchRoot.js.map +1 -0
  32. package/lib/commonjs/switch/index.js +15 -0
  33. package/lib/commonjs/switch/index.js.map +1 -0
  34. package/lib/commonjs/switch/types.js +6 -0
  35. package/lib/commonjs/switch/types.js.map +1 -0
  36. package/lib/commonjs/types.js +2 -0
  37. package/lib/commonjs/types.js.map +1 -0
  38. package/lib/commonjs/utils/dataAttributes.web.js +1 -4
  39. package/lib/commonjs/utils/dataAttributes.web.js.map +1 -1
  40. package/lib/module/button/createButtonRoot.js +3 -3
  41. package/lib/module/button/createButtonRoot.js.map +1 -1
  42. package/lib/module/button/index.js +18 -19
  43. package/lib/module/button/index.js.map +1 -1
  44. package/lib/module/checkbox/context.js +7 -0
  45. package/lib/module/checkbox/context.js.map +1 -0
  46. package/lib/module/checkbox/createCheckboxGroup.js +39 -0
  47. package/lib/module/checkbox/createCheckboxGroup.js.map +1 -0
  48. package/lib/module/checkbox/createCheckboxIcon.js +23 -0
  49. package/lib/module/checkbox/createCheckboxIcon.js.map +1 -0
  50. package/lib/module/checkbox/createCheckboxIndicator.js +42 -0
  51. package/lib/module/checkbox/createCheckboxIndicator.js.map +1 -0
  52. package/lib/module/checkbox/createCheckboxLabel.js +41 -0
  53. package/lib/module/checkbox/createCheckboxLabel.js.map +1 -0
  54. package/lib/module/checkbox/createCheckboxRoot.js +94 -0
  55. package/lib/module/checkbox/createCheckboxRoot.js.map +1 -0
  56. package/lib/module/checkbox/createCheckboxRoot.web.js +85 -0
  57. package/lib/module/checkbox/createCheckboxRoot.web.js.map +1 -0
  58. package/lib/module/checkbox/index.js +26 -0
  59. package/lib/module/checkbox/index.js.map +1 -0
  60. package/lib/module/checkbox/types.js +4 -0
  61. package/lib/module/checkbox/types.js.map +1 -0
  62. package/lib/module/checkbox/useCheckboxRoot.js +78 -0
  63. package/lib/module/checkbox/useCheckboxRoot.js.map +1 -0
  64. package/lib/module/index.js +3 -1
  65. package/lib/module/index.js.map +1 -1
  66. package/lib/module/input/index.js +15 -16
  67. package/lib/module/input/index.js.map +1 -1
  68. package/lib/module/select/context.js.map +1 -1
  69. package/lib/module/switch/createSwitchRoot.js +67 -0
  70. package/lib/module/switch/createSwitchRoot.js.map +1 -0
  71. package/lib/module/switch/index.js +11 -0
  72. package/lib/module/switch/index.js.map +1 -0
  73. package/lib/module/switch/types.js +4 -0
  74. package/lib/module/switch/types.js.map +1 -0
  75. package/lib/module/types.js +2 -0
  76. package/lib/module/types.js.map +1 -0
  77. package/lib/module/utils/dataAttributes.web.js +1 -4
  78. package/lib/module/utils/dataAttributes.web.js.map +1 -1
  79. package/lib/typescript/button/context.d.ts +1 -1
  80. package/lib/typescript/button/context.d.ts.map +1 -1
  81. package/lib/typescript/button/createButtonRoot.d.ts +1 -1
  82. package/lib/typescript/button/createButtonRoot.d.ts.map +1 -1
  83. package/lib/typescript/button/index.d.ts +1 -1
  84. package/lib/typescript/button/index.d.ts.map +1 -1
  85. package/lib/typescript/button/types.d.ts +0 -7
  86. package/lib/typescript/button/types.d.ts.map +1 -1
  87. package/lib/typescript/checkbox/context.d.ts +18 -0
  88. package/lib/typescript/checkbox/context.d.ts.map +1 -0
  89. package/lib/typescript/checkbox/createCheckboxGroup.d.ts +3 -0
  90. package/lib/typescript/checkbox/createCheckboxGroup.d.ts.map +1 -0
  91. package/lib/typescript/checkbox/createCheckboxIcon.d.ts +3 -0
  92. package/lib/typescript/checkbox/createCheckboxIcon.d.ts.map +1 -0
  93. package/lib/typescript/checkbox/createCheckboxIndicator.d.ts +5 -0
  94. package/lib/typescript/checkbox/createCheckboxIndicator.d.ts.map +1 -0
  95. package/lib/typescript/checkbox/createCheckboxLabel.d.ts +5 -0
  96. package/lib/typescript/checkbox/createCheckboxLabel.d.ts.map +1 -0
  97. package/lib/typescript/checkbox/createCheckboxRoot.d.ts +2 -0
  98. package/lib/typescript/checkbox/createCheckboxRoot.d.ts.map +1 -0
  99. package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts +2 -0
  100. package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts.map +1 -0
  101. package/lib/typescript/checkbox/index.d.ts +11 -0
  102. package/lib/typescript/checkbox/index.d.ts.map +1 -0
  103. package/lib/typescript/checkbox/types.d.ts +57 -0
  104. package/lib/typescript/checkbox/types.d.ts.map +1 -0
  105. package/lib/typescript/checkbox/useCheckboxRoot.d.ts +147 -0
  106. package/lib/typescript/checkbox/useCheckboxRoot.d.ts.map +1 -0
  107. package/lib/typescript/index.d.ts +4 -1
  108. package/lib/typescript/index.d.ts.map +1 -1
  109. package/lib/typescript/input/index.d.ts +3 -2
  110. package/lib/typescript/input/index.d.ts.map +1 -1
  111. package/lib/typescript/select/context.d.ts +2 -1
  112. package/lib/typescript/select/context.d.ts.map +1 -1
  113. package/lib/typescript/select/types.d.ts +1 -7
  114. package/lib/typescript/select/types.d.ts.map +1 -1
  115. package/lib/typescript/switch/createSwitchRoot.d.ts +3 -0
  116. package/lib/typescript/switch/createSwitchRoot.d.ts.map +1 -0
  117. package/lib/typescript/switch/index.d.ts +7 -0
  118. package/lib/typescript/switch/index.d.ts.map +1 -0
  119. package/lib/typescript/switch/types.d.ts +38 -0
  120. package/lib/typescript/switch/types.d.ts.map +1 -0
  121. package/lib/typescript/types.d.ts +8 -0
  122. package/lib/typescript/types.d.ts.map +1 -0
  123. package/lib/typescript/utils/dataAttributes.web.d.ts.map +1 -1
  124. package/package.json +12 -9
  125. package/src/button/context.tsx +1 -1
  126. package/src/button/createButtonRoot.tsx +5 -4
  127. package/src/button/index.tsx +18 -19
  128. package/src/button/types.ts +0 -8
  129. package/src/checkbox/context.tsx +18 -0
  130. package/src/checkbox/createCheckboxGroup.tsx +32 -0
  131. package/src/checkbox/createCheckboxIcon.tsx +18 -0
  132. package/src/checkbox/createCheckboxIndicator.tsx +43 -0
  133. package/src/checkbox/createCheckboxLabel.tsx +42 -0
  134. package/src/checkbox/createCheckboxRoot.tsx +100 -0
  135. package/src/checkbox/createCheckboxRoot.web.tsx +79 -0
  136. package/src/checkbox/index.ts +43 -0
  137. package/src/checkbox/types.ts +74 -0
  138. package/src/checkbox/useCheckboxRoot.ts +85 -0
  139. package/src/index.ts +4 -1
  140. package/src/input/index.tsx +18 -25
  141. package/src/select/context.tsx +2 -1
  142. package/src/select/types.ts +1 -10
  143. package/src/switch/createSwitchRoot.tsx +72 -0
  144. package/src/switch/index.ts +16 -0
  145. package/src/switch/types.ts +42 -0
  146. package/src/types.ts +7 -0
  147. package/src/utils/dataAttributes.web.ts +2 -4
@@ -1,7 +1,7 @@
1
1
  import type React from 'react';
2
- import { createButtonRoot } from './createButtonRoot';
3
2
  import { createButtonGroup } from './createButtonGroup';
4
3
  import { createButtonIcon } from './createButtonIcon';
4
+ import { createButtonRoot } from './createButtonRoot';
5
5
  import { createButtonSpinner } from './createButtonSpinner';
6
6
  import { createButtonText } from './createButtonText';
7
7
  import type { IButtonComponentType } from './types';
@@ -16,32 +16,31 @@ export function createButton<
16
16
  IconProps,
17
17
  ButtonRef = unknown,
18
18
  TextRef = unknown,
19
- >({
20
- Root,
21
- Text,
22
- Group,
23
- Spinner,
24
- Icon,
25
- }: {
19
+ >(BaseComponents: {
26
20
  Root: React.ComponentType<ButtonProps>;
27
21
  Text: React.ComponentType<TextProps>;
28
22
  Group: React.ComponentType<GroupProps>;
29
23
  Spinner: React.ComponentType<SpinnerProps>;
30
24
  Icon: React.ComponentType<IconProps>;
31
25
  }) {
32
- const Button = createButtonRoot(Root) as any;
33
- Button.Text = createButtonText(Text);
34
- Button.Group = createButtonGroup(Group);
35
- Button.Spinner = createButtonSpinner(Spinner);
36
- Button.Icon = createButtonIcon(Icon);
26
+ const Button = createButtonRoot(BaseComponents.Root);
27
+ const Text = createButtonText(BaseComponents.Text);
28
+ const Group = createButtonGroup(BaseComponents.Group);
29
+ const Spinner = createButtonSpinner(BaseComponents.Spinner);
30
+ const Icon = createButtonIcon(BaseComponents.Icon);
37
31
 
38
- Button.displayName = 'Button';
39
- Button.Text.displayName = 'Button.Text';
40
- Button.Group.displayName = 'Button.Group';
41
- Button.Spinner.displayName = 'Button.Spinner';
42
- Button.Icon.displayName = 'Button.Icon';
32
+ Button.displayName = 'ButtonPrimitive';
33
+ Text.displayName = 'ButtonPrimitive.Text';
34
+ Group.displayName = 'ButtonPrimitive.Group';
35
+ Spinner.displayName = 'ButtonPrimitive.Spinner';
36
+ Icon.displayName = 'ButtonPrimitive.Icon';
43
37
 
44
- return Button as IButtonComponentType<
38
+ return Object.assign(Button, {
39
+ Text,
40
+ Group,
41
+ Spinner,
42
+ Icon,
43
+ }) as IButtonComponentType<
45
44
  ButtonProps,
46
45
  GroupProps,
47
46
  SpinnerProps,
@@ -1,14 +1,6 @@
1
1
  import type { PropsWithoutRef, ReactElement, ReactNode, RefAttributes } from 'react';
2
2
  import type { PressableProps, ViewProps } from 'react-native';
3
3
 
4
- export interface InteractionState {
5
- hover: boolean;
6
- focus: boolean;
7
- active: boolean;
8
- disabled?: boolean;
9
- focusVisible: boolean;
10
- }
11
-
12
4
  export interface InterfaceButtonProps extends PressableProps {
13
5
  /**
14
6
  * If true, the button will be in hovered state.
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { createContext } from '@cdx-ui/utils';
3
+ import type { ICheckboxContextValue } from './types';
4
+
5
+ export const [CheckboxProvider, useCheckboxContext] =
6
+ createContext<ICheckboxContextValue>('CheckboxContext');
7
+
8
+ interface ICheckboxGroupState {
9
+ isReadOnly: boolean;
10
+ isDisabled: boolean;
11
+ isSelected: (value: string) => boolean;
12
+ addValue: (value: string) => void;
13
+ removeValue: (value: string) => void;
14
+ }
15
+
16
+ export const CheckboxGroupContext = React.createContext<{
17
+ state: ICheckboxGroupState;
18
+ } | null>(null);
@@ -0,0 +1,32 @@
1
+ import { forwardRef } from 'react';
2
+ import { useFormControlContext } from '@cdx-ui/utils';
3
+ import { useCheckboxGroup } from '@react-native-aria/checkbox';
4
+ import { useCheckboxGroupState } from '@react-stately/checkbox';
5
+ import { CheckboxGroupContext } from './context';
6
+ import type { ICheckboxGroupProps } from './types';
7
+
8
+ export const createCheckboxGroup = <T,>(BaseCheckboxGroup: React.ComponentType<T>) =>
9
+ forwardRef(({ children, ...props }: ICheckboxGroupProps, ref?: React.Ref<T>) => {
10
+ const state = useCheckboxGroupState({
11
+ ...props,
12
+ validationState: props.isInvalid ? 'invalid' : 'valid',
13
+ });
14
+
15
+ const { groupProps } = useCheckboxGroup(
16
+ {
17
+ ...props,
18
+ 'aria-label': props['aria-label'],
19
+ },
20
+ state,
21
+ );
22
+
23
+ const formControlContext = useFormControlContext();
24
+
25
+ return (
26
+ <CheckboxGroupContext.Provider value={{ state: { ...formControlContext, ...state } }}>
27
+ <BaseCheckboxGroup {...groupProps} {...props} ref={ref}>
28
+ {children}
29
+ </BaseCheckboxGroup>
30
+ </CheckboxGroupContext.Provider>
31
+ );
32
+ });
@@ -0,0 +1,18 @@
1
+ import { forwardRef } from 'react';
2
+ import { useCheckboxContext } from './context';
3
+ import type { ICheckboxIconProps } from './types';
4
+
5
+ export const createCheckboxIcon = <T,>(BaseCheckboxIcon: React.ComponentType<T>) =>
6
+ forwardRef<unknown, ICheckboxIconProps>(({ children, forceMount = false, ...props }, ref) => {
7
+ const { isChecked } = useCheckboxContext();
8
+
9
+ if (forceMount || isChecked) {
10
+ return (
11
+ <BaseCheckboxIcon {...(props as T)} ref={ref}>
12
+ {children}
13
+ </BaseCheckboxIcon>
14
+ );
15
+ }
16
+
17
+ return null;
18
+ });
@@ -0,0 +1,43 @@
1
+ import { forwardRef } from 'react';
2
+ import { dataAttributes } from '../utils/dataAttributes';
3
+ import { useCheckboxContext } from './context';
4
+ import type { ICheckboxIndicatorProps } from './types';
5
+
6
+ export const createCheckboxIndicator = <T,>(BaseCheckboxIndicator: React.ComponentType<T>) =>
7
+ forwardRef<unknown, ICheckboxIndicatorProps & { className?: string }>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const {
10
+ isChecked,
11
+ isDisabled,
12
+ isHovered,
13
+ isInvalid,
14
+ isReadOnly,
15
+ isPressed,
16
+ isFocused,
17
+ isIndeterminate,
18
+ isFocusVisible,
19
+ } = useCheckboxContext();
20
+
21
+ return (
22
+ <BaseCheckboxIndicator
23
+ className={className}
24
+ {...dataAttributes({
25
+ hover: isHovered,
26
+ checked: isChecked,
27
+ disabled: isDisabled,
28
+ focusVisible: isFocusVisible,
29
+ invalid: isInvalid,
30
+ readOnly: isReadOnly,
31
+ active: isPressed,
32
+ focused: isFocused,
33
+ indeterminate: isIndeterminate,
34
+ slot: 'checkbox-indicator',
35
+ })}
36
+ {...(props as T)}
37
+ ref={ref}
38
+ >
39
+ {children}
40
+ </BaseCheckboxIndicator>
41
+ );
42
+ },
43
+ );
@@ -0,0 +1,42 @@
1
+ import { forwardRef } from 'react';
2
+ import { dataAttributes } from '../utils/dataAttributes';
3
+ import { useCheckboxContext } from './context';
4
+ import type { ICheckboxLabelProps } from './types';
5
+
6
+ export const createCheckboxLabel = <T,>(BaseCheckboxLabel: React.ComponentType<T>) =>
7
+ forwardRef<unknown, ICheckboxLabelProps & { className?: string }>(
8
+ ({ children, className, ...props }, ref) => {
9
+ const {
10
+ isChecked,
11
+ isDisabled,
12
+ isHovered,
13
+ isInvalid,
14
+ isReadOnly,
15
+ isPressed,
16
+ isFocused,
17
+ isIndeterminate,
18
+ isFocusVisible,
19
+ } = useCheckboxContext();
20
+
21
+ return (
22
+ <BaseCheckboxLabel
23
+ className={className}
24
+ {...dataAttributes({
25
+ hover: isHovered,
26
+ checked: isChecked,
27
+ disabled: isDisabled,
28
+ focusVisible: isFocusVisible,
29
+ invalid: isInvalid,
30
+ readOnly: isReadOnly,
31
+ pressed: isPressed,
32
+ focused: isFocused,
33
+ indeterminate: isIndeterminate,
34
+ })}
35
+ {...(props as T)}
36
+ ref={ref}
37
+ >
38
+ {children}
39
+ </BaseCheckboxLabel>
40
+ );
41
+ },
42
+ );
@@ -0,0 +1,100 @@
1
+ import { forwardRef } from 'react';
2
+ import { composeEventHandlers } from '@cdx-ui/utils';
3
+ import { useFocus } from '@react-native-aria/focus';
4
+ import { usePress } from '@react-native-aria/interactions';
5
+ import { dataAttributes } from '../utils/dataAttributes';
6
+ import { CheckboxProvider } from './context';
7
+ import type { ICheckboxProps } from './types';
8
+ import { useCheckboxRoot } from './useCheckboxRoot';
9
+
10
+ export const createCheckboxRoot = <T,>(BaseCheckbox: React.ComponentType<T>) =>
11
+ forwardRef(
12
+ (
13
+ {
14
+ onPressIn,
15
+ onPressOut,
16
+ onHoverIn,
17
+ onHoverOut,
18
+ onFocus,
19
+ onBlur,
20
+ children,
21
+ ...props
22
+ }: ICheckboxProps,
23
+ ref?: React.Ref<T>,
24
+ ) => {
25
+ const {
26
+ isHovered: isHoveredProp,
27
+ isChecked: isCheckedProp,
28
+ isDisabled: isDisabledProp,
29
+ isInvalid: isInvalidProp,
30
+ isReadOnly: isReadOnlyProp,
31
+ isPressed: isPressedProp,
32
+ isFocused: isFocusedProp,
33
+ isIndeterminate: isIndeterminateProp,
34
+ isFocusVisible,
35
+ } = props;
36
+
37
+ const {
38
+ combinedProps,
39
+ isInvalid,
40
+ isReadOnly,
41
+ isIndeterminate,
42
+ groupItemInputProps,
43
+ isChecked,
44
+ isDisabled,
45
+ isHovered,
46
+ hoverProps,
47
+ mergedRef,
48
+ } = useCheckboxRoot(props, ref);
49
+
50
+ const { focusProps, isFocused } = useFocus();
51
+
52
+ const { pressProps, isPressed } = usePress({
53
+ isDisabled: isDisabled || isDisabledProp,
54
+ });
55
+
56
+ return (
57
+ <BaseCheckbox
58
+ disabled={isDisabled || isDisabledProp}
59
+ {...pressProps}
60
+ {...(combinedProps as T)}
61
+ {...groupItemInputProps}
62
+ ref={mergedRef}
63
+ role="checkbox"
64
+ onPressIn={composeEventHandlers(onPressIn, pressProps.onPressIn)}
65
+ onPressOut={composeEventHandlers(onPressOut, pressProps.onPressOut)}
66
+ onHoverIn={composeEventHandlers(onHoverIn, hoverProps.onHoverIn)}
67
+ onHoverOut={composeEventHandlers(onHoverOut, hoverProps.onHoverOut)}
68
+ onFocus={composeEventHandlers(composeEventHandlers(onFocus, focusProps.onFocus))}
69
+ onBlur={composeEventHandlers(composeEventHandlers(onBlur, focusProps.onBlur))}
70
+ {...dataAttributes({
71
+ checked: isChecked || isCheckedProp,
72
+ disabled: isDisabled || isDisabledProp,
73
+ hover: isHovered || isHoveredProp,
74
+ invalid: isInvalid || isInvalidProp,
75
+ readonly: isReadOnly || isReadOnlyProp,
76
+ active: isPressed,
77
+ focus: isFocused,
78
+ indeterminate: isIndeterminate || isIndeterminateProp,
79
+ focusVisible: isFocusVisible,
80
+ })}
81
+ >
82
+ <CheckboxProvider
83
+ value={{
84
+ isChecked: isChecked || isCheckedProp,
85
+ isDisabled: isDisabled || isDisabledProp,
86
+ isHovered: isHovered || isHoveredProp,
87
+ isInvalid: isInvalid || isInvalidProp,
88
+ isReadOnly: isReadOnly || isReadOnlyProp,
89
+ isPressed: isPressed || isPressedProp,
90
+ isFocused: isFocused || isFocusedProp,
91
+ isIndeterminate: isIndeterminate || isIndeterminateProp,
92
+ isFocusVisible,
93
+ }}
94
+ >
95
+ {children}
96
+ </CheckboxProvider>
97
+ </BaseCheckbox>
98
+ );
99
+ },
100
+ );
@@ -0,0 +1,79 @@
1
+ import { forwardRef } from 'react';
2
+ import { VisuallyHidden } from '@react-aria/visually-hidden';
3
+ import { useFocusRing } from '@react-native-aria/focus';
4
+ import { dataAttributes } from '../utils/dataAttributes';
5
+ import { CheckboxProvider } from './context';
6
+ import type { ICheckboxProps } from './types';
7
+ import { useCheckboxRoot } from './useCheckboxRoot';
8
+
9
+ // TODO: Label is taking focus on keyboard navigation
10
+
11
+ export const createCheckboxRoot = <T,>(BaseCheckbox: React.ComponentType<T>) =>
12
+ forwardRef(({ children, ...props }: ICheckboxProps, ref?: React.Ref<T>) => {
13
+ const {
14
+ isHovered: isHoveredProp,
15
+ isFocusVisible: isFocusVisibleProp,
16
+ isChecked: isCheckedProp,
17
+ isDisabled: isDisabledProp,
18
+ isInvalid: isInvalidProp,
19
+ isReadOnly: isReadOnlyProp,
20
+ isIndeterminate: isIndeterminateProp,
21
+ isFocused,
22
+ isPressed,
23
+ } = props;
24
+
25
+ const {
26
+ combinedProps,
27
+ isInvalid,
28
+ isReadOnly,
29
+ isIndeterminate,
30
+ groupItemInputProps,
31
+ isChecked,
32
+ isDisabled,
33
+ isHovered,
34
+ mergedRef,
35
+ inputRef,
36
+ } = useCheckboxRoot(props, ref, { useInputRefForAria: true });
37
+
38
+ const { focusProps, isFocusVisible } = useFocusRing();
39
+
40
+ return (
41
+ <BaseCheckbox
42
+ {...(combinedProps as T)}
43
+ ref={mergedRef}
44
+ role="label"
45
+ // eslint-disable-next-line react-native-a11y/has-valid-accessibility-role
46
+ accessibilityRole="label"
47
+ {...dataAttributes({
48
+ checked: isChecked || isCheckedProp,
49
+ disabled: isDisabled || isDisabledProp,
50
+ hover: isHovered || isHoveredProp,
51
+ invalid: isInvalid || isInvalidProp,
52
+ readonly: isReadOnly || isReadOnlyProp,
53
+ active: isPressed,
54
+ focus: isFocused,
55
+ indeterminate: isIndeterminate || isIndeterminateProp,
56
+ focusVisible: isFocusVisible,
57
+ })}
58
+ >
59
+ <CheckboxProvider
60
+ value={{
61
+ isChecked: isChecked || isCheckedProp,
62
+ isDisabled: isDisabled || isDisabledProp,
63
+ isFocusVisible: isFocusVisible || isFocusVisibleProp,
64
+ isHovered: isHovered || isHoveredProp,
65
+ isInvalid: isInvalid || isInvalidProp,
66
+ isReadOnly: isReadOnly || isReadOnlyProp,
67
+ isIndeterminate: isIndeterminate || isIndeterminateProp,
68
+ isPressed,
69
+ isFocused,
70
+ }}
71
+ >
72
+ <VisuallyHidden>
73
+ <input {...groupItemInputProps} {...focusProps} ref={inputRef} />
74
+ </VisuallyHidden>
75
+ {children}
76
+ </CheckboxProvider>
77
+ </BaseCheckbox>
78
+ );
79
+ });
@@ -0,0 +1,43 @@
1
+ import type React from 'react';
2
+ import { createCheckboxGroup } from './createCheckboxGroup';
3
+ import { createCheckboxIcon } from './createCheckboxIcon';
4
+ import { createCheckboxIndicator } from './createCheckboxIndicator';
5
+ import { createCheckboxLabel } from './createCheckboxLabel';
6
+ import { createCheckboxRoot } from './createCheckboxRoot';
7
+ import type { ICheckboxComponentType } from './types';
8
+
9
+ export type {
10
+ ICheckboxComponentType,
11
+ ICheckboxGroupProps,
12
+ ICheckboxIconProps,
13
+ ICheckboxIndicatorProps,
14
+ ICheckboxLabelProps,
15
+ ICheckboxProps,
16
+ } from './types';
17
+
18
+ export function createCheckbox<Root, Indicator, Icon, Label, Group>(BaseComponents: {
19
+ Root: React.ComponentType<Root>;
20
+ Indicator: React.ComponentType<Indicator>;
21
+ Icon: React.ComponentType<Icon>;
22
+ Label: React.ComponentType<Label>;
23
+ Group: React.ComponentType<Group>;
24
+ }) {
25
+ const Checkbox = createCheckboxRoot(BaseComponents.Root);
26
+ const Indicator = createCheckboxIndicator(BaseComponents.Indicator);
27
+ const Icon = createCheckboxIcon(BaseComponents.Icon);
28
+ const Label = createCheckboxLabel(BaseComponents.Label);
29
+ const Group = createCheckboxGroup(BaseComponents.Group);
30
+
31
+ Checkbox.displayName = 'CheckboxPrimitive';
32
+ Indicator.displayName = 'CheckboxPrimitive.Indicator';
33
+ Icon.displayName = 'CheckboxPrimitive.Icon';
34
+ Label.displayName = 'CheckboxPrimitive.Label';
35
+ Group.displayName = 'CheckboxPrimitive.Group';
36
+
37
+ return Object.assign(Checkbox, {
38
+ Indicator,
39
+ Icon,
40
+ Label,
41
+ Group,
42
+ }) as ICheckboxComponentType<Root, Indicator, Icon, Label, Group>;
43
+ }
@@ -0,0 +1,74 @@
1
+ import type { PressableProps } from 'react-native';
2
+ export interface InterfaceCheckbox extends PressableProps {
3
+ value: string;
4
+ onChange?: (isSelected: boolean) => void;
5
+ children?: React.ReactNode;
6
+ defaultIsChecked?: boolean;
7
+ isChecked?: boolean;
8
+ isDisabled?: boolean;
9
+ isInvalid?: boolean;
10
+ isReadOnly?: boolean;
11
+ isHovered?: boolean;
12
+ isFocused?: boolean;
13
+ isPressed?: boolean;
14
+ isRequired?: boolean;
15
+ isIndeterminate?: boolean;
16
+ isFocusVisible?: boolean;
17
+ }
18
+
19
+ export interface ICheckboxGroupProps {
20
+ value: string[];
21
+ onChange?: (values: string[]) => void;
22
+ children?: React.ReactNode;
23
+ isDisabled?: boolean;
24
+ isInvalid?: boolean;
25
+ isReadOnly?: boolean;
26
+ isRequired?: boolean;
27
+ 'aria-label'?: string;
28
+ }
29
+
30
+ export type ICheckboxComponentType<Root, Indicator, Icon, Label, Group> =
31
+ React.ForwardRefExoticComponent<
32
+ React.RefAttributes<Root> & React.PropsWithoutRef<Root> & InterfaceCheckbox
33
+ > & {
34
+ Indicator: React.ForwardRefExoticComponent<
35
+ React.RefAttributes<Indicator> & React.PropsWithoutRef<Indicator> & ICheckboxIndicatorProps
36
+ >;
37
+ Icon: React.ForwardRefExoticComponent<
38
+ React.RefAttributes<Icon> & React.PropsWithoutRef<Icon> & ICheckboxIconProps
39
+ >;
40
+ Label: React.ForwardRefExoticComponent<
41
+ React.RefAttributes<Label> & React.PropsWithoutRef<Label> & ICheckboxLabelProps
42
+ >;
43
+ Group: React.ForwardRefExoticComponent<
44
+ React.RefAttributes<Group> & React.PropsWithoutRef<Group> & ICheckboxGroupProps
45
+ >;
46
+ };
47
+
48
+ export interface ICheckboxIndicatorProps {
49
+ children?: React.ReactNode;
50
+ }
51
+
52
+ export interface ICheckboxIconProps {
53
+ children?: React.ReactNode;
54
+ /** Render the icon even when unchecked */
55
+ forceMount?: boolean;
56
+ }
57
+
58
+ export interface ICheckboxLabelProps {
59
+ children?: React.ReactNode;
60
+ }
61
+
62
+ export type ICheckboxProps = InterfaceCheckbox;
63
+
64
+ export interface ICheckboxContextValue {
65
+ isChecked?: boolean;
66
+ isDisabled?: boolean;
67
+ isHovered?: boolean;
68
+ isInvalid?: boolean;
69
+ isReadOnly?: boolean;
70
+ isPressed?: boolean;
71
+ isFocused?: boolean;
72
+ isIndeterminate?: boolean;
73
+ isFocusVisible?: boolean;
74
+ }
@@ -0,0 +1,85 @@
1
+ import { useContext, useRef } from 'react';
2
+ import { mergeRefs, useFormControlContext } from '@cdx-ui/utils';
3
+ import { useCheckbox } from '@react-native-aria/checkbox';
4
+ import { useHover } from '@react-native-aria/interactions';
5
+ import { useToggleState } from '@react-stately/toggle';
6
+ import { CheckboxGroupContext } from './context';
7
+ import type { ICheckboxProps } from './types';
8
+
9
+ interface UseCheckboxRootOptions {
10
+ useInputRefForAria?: boolean;
11
+ }
12
+
13
+ export function useCheckboxRoot(
14
+ props: ICheckboxProps,
15
+ ref?: React.Ref<unknown>,
16
+ { useInputRefForAria = false }: UseCheckboxRootOptions = {},
17
+ ) {
18
+ const formControlContext = useFormControlContext();
19
+
20
+ const { isInvalid, isReadOnly, isIndeterminate, ...combinedProps } = {
21
+ ...formControlContext,
22
+ ...props,
23
+ };
24
+
25
+ const checkboxGroupContext = useContext(CheckboxGroupContext);
26
+
27
+ const state = useToggleState({
28
+ ...combinedProps,
29
+ defaultSelected: props.defaultIsChecked,
30
+ isSelected: props.isChecked,
31
+ });
32
+
33
+ const rootRef = useRef(null);
34
+ const inputRef = useRef<HTMLInputElement | null>(null);
35
+ const mergedRootRef = mergeRefs(ref as any, rootRef as any);
36
+ const ariaLabel = combinedProps['aria-label'] || combinedProps.value || 'Checkbox';
37
+
38
+ const groupToggleState = useToggleState(
39
+ checkboxGroupContext
40
+ ? {
41
+ isReadOnly: isReadOnly || checkboxGroupContext.state.isReadOnly,
42
+ isSelected: checkboxGroupContext.state.isSelected(combinedProps.value),
43
+ onChange(isSelected: boolean) {
44
+ if (isSelected) {
45
+ checkboxGroupContext.state.addValue(combinedProps.value);
46
+ } else {
47
+ checkboxGroupContext.state.removeValue(combinedProps.value);
48
+ }
49
+ combinedProps.onChange?.(isSelected);
50
+ },
51
+ }
52
+ : { isSelected: false },
53
+ );
54
+
55
+ const { inputProps: groupItemInputProps } = useCheckbox(
56
+ {
57
+ ...combinedProps,
58
+ 'aria-label': ariaLabel,
59
+ ...(checkboxGroupContext && {
60
+ isReadOnly: isReadOnly || checkboxGroupContext.state.isReadOnly,
61
+ isDisabled: combinedProps.isDisabled || checkboxGroupContext.state.isDisabled,
62
+ }),
63
+ } as any,
64
+ checkboxGroupContext ? groupToggleState : state,
65
+ (useInputRefForAria ? inputRef : rootRef) as any,
66
+ );
67
+
68
+ const { checked: isChecked, disabled: isDisabled } = groupItemInputProps;
69
+
70
+ const { hoverProps, isHovered } = useHover({}, rootRef);
71
+
72
+ return {
73
+ combinedProps,
74
+ isInvalid,
75
+ isReadOnly,
76
+ isIndeterminate,
77
+ groupItemInputProps,
78
+ isChecked,
79
+ isDisabled,
80
+ isHovered,
81
+ hoverProps,
82
+ mergedRef: mergedRootRef,
83
+ inputRef,
84
+ };
85
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from './button';
2
+ export * from './checkbox';
2
3
  export * from './input';
4
+ export { type EdgeInsets, OverlayInsetsProvider } from './overlay';
3
5
  export * from './select';
4
- export { OverlayInsetsProvider, type EdgeInsets } from './overlay';
6
+ export * from './switch';
7
+ export type { InteractionState } from './types';