@cdx-ui/primitives 0.0.1-alpha.10 → 0.0.1-alpha.12
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/lib/commonjs/button/index.js +18 -19
- package/lib/commonjs/button/index.js.map +1 -1
- package/lib/commonjs/checkbox/createCheckboxRoot.web.js +2 -0
- package/lib/commonjs/checkbox/createCheckboxRoot.web.js.map +1 -1
- package/lib/commonjs/checkbox/index.js +19 -21
- package/lib/commonjs/checkbox/index.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/input/index.js +16 -18
- package/lib/commonjs/input/index.js.map +1 -1
- package/lib/commonjs/link/LinkProvider.js +28 -0
- package/lib/commonjs/link/LinkProvider.js.map +1 -0
- package/lib/commonjs/link/createLink.js +74 -0
- package/lib/commonjs/link/createLink.js.map +1 -0
- package/lib/commonjs/link/index.js +27 -0
- package/lib/commonjs/link/index.js.map +1 -0
- package/lib/commonjs/link/types.js +6 -0
- package/lib/commonjs/link/types.js.map +1 -0
- package/lib/commonjs/link/useLink.js +56 -0
- package/lib/commonjs/link/useLink.js.map +1 -0
- package/lib/commonjs/select/context.js.map +1 -1
- package/lib/commonjs/utils/dataAttributes.web.js +1 -4
- package/lib/commonjs/utils/dataAttributes.web.js.map +1 -1
- package/lib/module/button/index.js +18 -19
- package/lib/module/button/index.js.map +1 -1
- package/lib/module/checkbox/createCheckboxRoot.web.js +2 -0
- package/lib/module/checkbox/createCheckboxRoot.web.js.map +1 -1
- package/lib/module/checkbox/index.js +18 -19
- package/lib/module/checkbox/index.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/input/index.js +15 -16
- package/lib/module/input/index.js.map +1 -1
- package/lib/module/link/LinkProvider.js +23 -0
- package/lib/module/link/LinkProvider.js.map +1 -0
- package/lib/module/link/createLink.js +68 -0
- package/lib/module/link/createLink.js.map +1 -0
- package/lib/module/link/index.js +6 -0
- package/lib/module/link/index.js.map +1 -0
- package/lib/module/link/types.js +4 -0
- package/lib/module/link/types.js.map +1 -0
- package/lib/module/link/useLink.js +52 -0
- package/lib/module/link/useLink.js.map +1 -0
- package/lib/module/select/context.js.map +1 -1
- package/lib/module/utils/dataAttributes.web.js +1 -4
- package/lib/module/utils/dataAttributes.web.js.map +1 -1
- package/lib/typescript/button/index.d.ts +1 -1
- package/lib/typescript/button/index.d.ts.map +1 -1
- package/lib/typescript/checkbox/createCheckboxRoot.web.d.ts.map +1 -1
- package/lib/typescript/checkbox/index.d.ts +3 -2
- package/lib/typescript/checkbox/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/input/index.d.ts +3 -2
- package/lib/typescript/input/index.d.ts.map +1 -1
- package/lib/typescript/link/LinkProvider.d.ts +36 -0
- package/lib/typescript/link/LinkProvider.d.ts.map +1 -0
- package/lib/typescript/link/createLink.d.ts +6 -0
- package/lib/typescript/link/createLink.d.ts.map +1 -0
- package/lib/typescript/link/index.d.ts +6 -0
- package/lib/typescript/link/index.d.ts.map +1 -0
- package/lib/typescript/link/types.d.ts +45 -0
- package/lib/typescript/link/types.d.ts.map +1 -0
- package/lib/typescript/link/useLink.d.ts +9 -0
- package/lib/typescript/link/useLink.d.ts.map +1 -0
- package/lib/typescript/select/context.d.ts +2 -1
- package/lib/typescript/select/context.d.ts.map +1 -1
- package/lib/typescript/select/types.d.ts +0 -1
- package/lib/typescript/select/types.d.ts.map +1 -1
- package/lib/typescript/utils/dataAttributes.web.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/button/index.tsx +18 -19
- package/src/checkbox/createCheckboxRoot.web.tsx +2 -0
- package/src/checkbox/index.ts +20 -20
- package/src/index.ts +1 -0
- package/src/input/index.tsx +18 -25
- package/src/link/LinkProvider.tsx +50 -0
- package/src/link/createLink.tsx +71 -0
- package/src/link/index.tsx +5 -0
- package/src/link/types.ts +47 -0
- package/src/link/useLink.ts +54 -0
- package/src/select/context.tsx +2 -1
- package/src/select/types.ts +0 -1
- package/src/utils/dataAttributes.web.ts +2 -4
package/src/button/index.tsx
CHANGED
|
@@ -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)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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 = '
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
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,
|
|
@@ -6,6 +6,8 @@ import { CheckboxProvider } from './context';
|
|
|
6
6
|
import type { ICheckboxProps } from './types';
|
|
7
7
|
import { useCheckboxRoot } from './useCheckboxRoot';
|
|
8
8
|
|
|
9
|
+
// TODO: Label is taking focus on keyboard navigation
|
|
10
|
+
|
|
9
11
|
export const createCheckboxRoot = <T,>(BaseCheckbox: React.ComponentType<T>) =>
|
|
10
12
|
forwardRef(({ children, ...props }: ICheckboxProps, ref?: React.Ref<T>) => {
|
|
11
13
|
const {
|
package/src/checkbox/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type React from 'react';
|
|
1
2
|
import { createCheckboxGroup } from './createCheckboxGroup';
|
|
2
3
|
import { createCheckboxIcon } from './createCheckboxIcon';
|
|
3
4
|
import { createCheckboxIndicator } from './createCheckboxIndicator';
|
|
@@ -14,30 +15,29 @@ export type {
|
|
|
14
15
|
ICheckboxProps,
|
|
15
16
|
} from './types';
|
|
16
17
|
|
|
17
|
-
export
|
|
18
|
-
Root,
|
|
19
|
-
Indicator,
|
|
20
|
-
Icon,
|
|
21
|
-
Label,
|
|
22
|
-
Group,
|
|
23
|
-
}: {
|
|
18
|
+
export function createCheckbox<Root, Indicator, Icon, Label, Group>(BaseComponents: {
|
|
24
19
|
Root: React.ComponentType<Root>;
|
|
25
20
|
Indicator: React.ComponentType<Indicator>;
|
|
26
21
|
Icon: React.ComponentType<Icon>;
|
|
27
22
|
Label: React.ComponentType<Label>;
|
|
28
23
|
Group: React.ComponentType<Group>;
|
|
29
|
-
})
|
|
30
|
-
const Checkbox = createCheckboxRoot(Root)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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);
|
|
35
30
|
|
|
36
|
-
Checkbox.displayName = '
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
Checkbox.displayName = 'CheckboxPrimitive';
|
|
32
|
+
Indicator.displayName = 'CheckboxPrimitive.Indicator';
|
|
33
|
+
Icon.displayName = 'CheckboxPrimitive.Icon';
|
|
34
|
+
Label.displayName = 'CheckboxPrimitive.Label';
|
|
35
|
+
Group.displayName = 'CheckboxPrimitive.Group';
|
|
41
36
|
|
|
42
|
-
return Checkbox
|
|
43
|
-
|
|
37
|
+
return Object.assign(Checkbox, {
|
|
38
|
+
Indicator,
|
|
39
|
+
Icon,
|
|
40
|
+
Label,
|
|
41
|
+
Group,
|
|
42
|
+
}) as ICheckboxComponentType<Root, Indicator, Icon, Label, Group>;
|
|
43
|
+
}
|
package/src/index.ts
CHANGED
package/src/input/index.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type React from 'react';
|
|
1
2
|
import { createInputField } from './createInputField';
|
|
2
3
|
import { createInputIcon } from './createInputIcon';
|
|
3
4
|
import { createInputRoot } from './createInputRoot';
|
|
@@ -12,40 +13,32 @@ export type {
|
|
|
12
13
|
IInputSlotProps,
|
|
13
14
|
} from './types';
|
|
14
15
|
|
|
15
|
-
export
|
|
16
|
+
export function createInput<
|
|
16
17
|
RootProps,
|
|
17
18
|
IconProps,
|
|
18
19
|
SlotProps,
|
|
19
20
|
FieldProps,
|
|
20
21
|
RootRef = unknown,
|
|
21
22
|
FieldRef = unknown,
|
|
22
|
-
>({
|
|
23
|
-
Root,
|
|
24
|
-
Icon,
|
|
25
|
-
Slot,
|
|
26
|
-
Field,
|
|
27
|
-
}: {
|
|
23
|
+
>(BaseComponents: {
|
|
28
24
|
Root: React.ComponentType<RootProps>;
|
|
29
25
|
Icon: React.ComponentType<IconProps>;
|
|
30
26
|
Slot: React.ComponentType<SlotProps>;
|
|
31
27
|
Field: React.ComponentType<FieldProps>;
|
|
32
|
-
})
|
|
33
|
-
const Input = createInputRoot(Root)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
}) {
|
|
29
|
+
const Input = createInputRoot(BaseComponents.Root);
|
|
30
|
+
const Icon = createInputIcon(BaseComponents.Icon);
|
|
31
|
+
const Slot = createInputSlot(BaseComponents.Slot);
|
|
32
|
+
const Field = createInputField(BaseComponents.Field);
|
|
37
33
|
|
|
38
|
-
Input.displayName = '
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
Input.displayName = 'InputPrimitive';
|
|
35
|
+
Icon.displayName = 'InputPrimitive.Icon';
|
|
36
|
+
Slot.displayName = 'InputPrimitive.Slot';
|
|
37
|
+
Field.displayName = 'InputPrimitive.Field';
|
|
42
38
|
|
|
43
|
-
return Input
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
FieldRef
|
|
50
|
-
>;
|
|
51
|
-
};
|
|
39
|
+
return Object.assign(Input, {
|
|
40
|
+
Icon,
|
|
41
|
+
Slot,
|
|
42
|
+
Field,
|
|
43
|
+
}) as IInputComponentType<RootProps, IconProps, SlotProps, FieldProps, RootRef, FieldRef>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createContext, useContext, type ReactNode } from 'react';
|
|
2
|
+
import type { LinkAction } from './types';
|
|
3
|
+
|
|
4
|
+
export interface LinkConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Global navigation handler for `<Link>` instances whose `href` passes the
|
|
7
|
+
* `shouldNavigate` check. Called with the `href` and the per-instance `action`.
|
|
8
|
+
*
|
|
9
|
+
* @param href - The URL or path to navigate to.
|
|
10
|
+
* @param action - Navigation intent from the per-instance `action` prop:
|
|
11
|
+
* `'navigate'` (default) — smart navigation, avoids duplicates.
|
|
12
|
+
* `'push'` — always pushes a new entry onto the stack.
|
|
13
|
+
* `'replace'` — replaces the current entry without stacking.
|
|
14
|
+
*/
|
|
15
|
+
navigate: (href: string, action: LinkAction) => void | Promise<void>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Optional predicate evaluated at **render time** to decide whether the
|
|
19
|
+
* provider should handle a given `href`.
|
|
20
|
+
*
|
|
21
|
+
* - Returns `true` → the provider's `navigate` is called on press;
|
|
22
|
+
* on web the native `<a href>` is **removed** so the browser doesn't
|
|
23
|
+
* follow the link.
|
|
24
|
+
* - Returns `false` → the provider is bypassed; on web the `<a href>` is
|
|
25
|
+
* preserved (cmd-click, SEO, etc.); on native `Linking.openURL` is used.
|
|
26
|
+
*
|
|
27
|
+
* Defaults to `() => true` when omitted (all hrefs go through the provider).
|
|
28
|
+
*/
|
|
29
|
+
shouldNavigate?: (href: string) => boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const LinkConfigContext = createContext<LinkConfig | undefined>(undefined);
|
|
33
|
+
|
|
34
|
+
export function LinkProvider({
|
|
35
|
+
navigate,
|
|
36
|
+
shouldNavigate,
|
|
37
|
+
children,
|
|
38
|
+
}: LinkConfig & { children: ReactNode }) {
|
|
39
|
+
return (
|
|
40
|
+
<LinkConfigContext.Provider value={{ navigate, shouldNavigate }}>
|
|
41
|
+
{children}
|
|
42
|
+
</LinkConfigContext.Provider>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
LinkProvider.displayName = 'LinkProvider';
|
|
47
|
+
|
|
48
|
+
export function useLinkConfig(): LinkConfig | undefined {
|
|
49
|
+
return useContext(LinkConfigContext);
|
|
50
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { composeEventHandlers } from '@cdx-ui/utils';
|
|
3
|
+
import { useFocusRing, useFocus } from '@react-native-aria/focus';
|
|
4
|
+
import { useHover, usePress } from '@react-native-aria/interactions';
|
|
5
|
+
import { dataAttributes } from '../utils/dataAttributes';
|
|
6
|
+
import { useLink } from './useLink';
|
|
7
|
+
import type { ILinkProps } from './types';
|
|
8
|
+
|
|
9
|
+
export const createLink = <RootT, R = unknown>({ Root }: { Root: React.ComponentType<RootT> }) =>
|
|
10
|
+
forwardRef(
|
|
11
|
+
(
|
|
12
|
+
{
|
|
13
|
+
children,
|
|
14
|
+
isHovered: isHoveredProp,
|
|
15
|
+
isPressed: isPressedProp,
|
|
16
|
+
isFocused: isFocusedProp,
|
|
17
|
+
isFocusVisible: isFocusVisibleProp,
|
|
18
|
+
href,
|
|
19
|
+
onPress,
|
|
20
|
+
action,
|
|
21
|
+
webProps,
|
|
22
|
+
...props
|
|
23
|
+
}: ILinkProps,
|
|
24
|
+
ref: React.ForwardedRef<R>,
|
|
25
|
+
) => {
|
|
26
|
+
const { isFocused, focusProps } = useFocus();
|
|
27
|
+
const { isFocusVisible, focusProps: focusRingProps } = useFocusRing() as {
|
|
28
|
+
isFocusVisible: boolean;
|
|
29
|
+
focusProps: typeof focusProps;
|
|
30
|
+
};
|
|
31
|
+
const { pressProps, isPressed } = usePress({});
|
|
32
|
+
const { isHovered, hoverProps } = useHover();
|
|
33
|
+
|
|
34
|
+
const { linkProps } = useLink({
|
|
35
|
+
href,
|
|
36
|
+
onPress,
|
|
37
|
+
action,
|
|
38
|
+
webProps,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const interactionAttrs = dataAttributes({
|
|
42
|
+
hover: isHoveredProp || isHovered,
|
|
43
|
+
focus: isFocusedProp || isFocused,
|
|
44
|
+
active: isPressedProp || isPressed,
|
|
45
|
+
focusVisible: isFocusVisibleProp || isFocusVisible,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Root
|
|
50
|
+
ref={ref}
|
|
51
|
+
{...interactionAttrs}
|
|
52
|
+
{...linkProps}
|
|
53
|
+
{...(props as RootT)}
|
|
54
|
+
onPressIn={composeEventHandlers(props?.onPressIn, pressProps.onPressIn)}
|
|
55
|
+
onPressOut={composeEventHandlers(props?.onPressOut, pressProps.onPressOut)}
|
|
56
|
+
onHoverIn={composeEventHandlers(props?.onHoverIn, hoverProps.onHoverIn)}
|
|
57
|
+
onHoverOut={composeEventHandlers(props?.onHoverOut, hoverProps.onHoverOut)}
|
|
58
|
+
onFocus={composeEventHandlers(
|
|
59
|
+
composeEventHandlers(props?.onFocus, focusProps.onFocus),
|
|
60
|
+
focusRingProps.onFocus,
|
|
61
|
+
)}
|
|
62
|
+
onBlur={composeEventHandlers(
|
|
63
|
+
composeEventHandlers(props?.onBlur, focusProps.onBlur),
|
|
64
|
+
focusRingProps.onBlur,
|
|
65
|
+
)}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
</Root>
|
|
69
|
+
);
|
|
70
|
+
},
|
|
71
|
+
);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { GestureResponderEvent, PressableProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Navigation action forwarded to the `LinkProvider.navigate` callback.
|
|
6
|
+
*
|
|
7
|
+
* - `'navigate'` — (default) Smart navigation. In React Navigation this
|
|
8
|
+
* avoids duplicating a screen that is already in the stack. In expo-router
|
|
9
|
+
* it maps to `router.navigate()`.
|
|
10
|
+
* - `'push'` — Always pushes a new screen onto the navigation stack,
|
|
11
|
+
* even if the destination is already present.
|
|
12
|
+
* - `'replace'` — Replaces the current screen without adding to the stack.
|
|
13
|
+
* Useful for post-login redirects or wizard flows.
|
|
14
|
+
*/
|
|
15
|
+
export type LinkAction = 'navigate' | 'push' | 'replace';
|
|
16
|
+
|
|
17
|
+
export interface ILinkProps extends PressableProps {
|
|
18
|
+
/**
|
|
19
|
+
* URL that should be opened on Link press
|
|
20
|
+
*/
|
|
21
|
+
href?: string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Callback that will be invoked on Link press
|
|
24
|
+
*/
|
|
25
|
+
onPress?: ((event?: GestureResponderEvent) => void) | null | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Navigation action forwarded to the `LinkProvider`.
|
|
28
|
+
* Defaults to `'navigate'`.
|
|
29
|
+
*/
|
|
30
|
+
action?: LinkAction;
|
|
31
|
+
isPressed?: boolean;
|
|
32
|
+
isHovered?: boolean;
|
|
33
|
+
isFocused?: boolean;
|
|
34
|
+
isFocusVisible?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* HTML anchor attributes applied only on web. Ignored on native platforms.
|
|
37
|
+
* `target`, `rel`, and `download` are forwarded via react-native-web's `hrefAttrs`.
|
|
38
|
+
*/
|
|
39
|
+
webProps?: React.AnchorHTMLAttributes<HTMLAnchorElement>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IUseLinkProp {
|
|
43
|
+
href?: string;
|
|
44
|
+
onPress: ((event?: GestureResponderEvent) => void) | null | undefined;
|
|
45
|
+
action?: LinkAction;
|
|
46
|
+
webProps?: React.AnchorHTMLAttributes<HTMLAnchorElement>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Linking, Platform } from 'react-native';
|
|
2
|
+
import type { AccessibilityRole, GestureResponderEvent } from 'react-native';
|
|
3
|
+
import { useLinkConfig } from './LinkProvider';
|
|
4
|
+
import type { IUseLinkProp } from './types';
|
|
5
|
+
|
|
6
|
+
function defaultNavigate(href: string): void {
|
|
7
|
+
Linking.canOpenURL(href)
|
|
8
|
+
.then((supported) => {
|
|
9
|
+
if (supported) return Linking.openURL(href);
|
|
10
|
+
console.warn(`Cannot open URL: ${href}`);
|
|
11
|
+
})
|
|
12
|
+
.catch((err: unknown) => console.error('Failed to open URL', err));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useLink(props: IUseLinkProp) {
|
|
16
|
+
const { href, onPress, action = 'navigate', webProps } = props;
|
|
17
|
+
const config = useLinkConfig();
|
|
18
|
+
|
|
19
|
+
const providerHandles = !!config && !!href && (config.shouldNavigate?.(href) ?? true);
|
|
20
|
+
|
|
21
|
+
let platformLinkProps = {};
|
|
22
|
+
|
|
23
|
+
if (Platform.OS === 'web') {
|
|
24
|
+
platformLinkProps = {
|
|
25
|
+
href: providerHandles ? undefined : href,
|
|
26
|
+
hrefAttrs: webProps,
|
|
27
|
+
onPress: (event: GestureResponderEvent) => {
|
|
28
|
+
onPress?.(event);
|
|
29
|
+
if (providerHandles) void config.navigate(href, action);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
} else {
|
|
33
|
+
platformLinkProps = {
|
|
34
|
+
onPress: (event: GestureResponderEvent) => {
|
|
35
|
+
onPress?.(event);
|
|
36
|
+
if (href) {
|
|
37
|
+
if (providerHandles) {
|
|
38
|
+
void config.navigate(href, action);
|
|
39
|
+
} else {
|
|
40
|
+
defaultNavigate(href);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
linkProps: {
|
|
49
|
+
...platformLinkProps,
|
|
50
|
+
role: 'link' as AccessibilityRole,
|
|
51
|
+
accessible: true,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
package/src/select/context.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext } from 'react';
|
|
2
|
-
import type { InteractionState
|
|
2
|
+
import type { InteractionState } from '../types';
|
|
3
|
+
import type { SelectContextValue, SelectItemInteractionState } from './types';
|
|
3
4
|
|
|
4
5
|
const defaultContextValue: SelectContextValue = {
|
|
5
6
|
open: false,
|
package/src/select/types.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { PropsWithoutRef, ReactNode, RefAttributes, RefObject } from 'react
|
|
|
2
2
|
import type { PressableProps, ViewProps } from 'react-native';
|
|
3
3
|
import type { EntryOrExitLayoutType } from 'react-native-reanimated';
|
|
4
4
|
import type { InteractionState } from '../types';
|
|
5
|
-
export type { InteractionState };
|
|
6
5
|
|
|
7
6
|
export interface SelectItemInteractionState extends InteractionState {
|
|
8
7
|
highlighted: boolean;
|
|
@@ -17,10 +17,8 @@ export function dataAttributes(attrs: Record<string, DataAttributeValue>): {
|
|
|
17
17
|
const dataSet: Record<string, boolean | string> = {};
|
|
18
18
|
for (const key in attrs) {
|
|
19
19
|
const value = attrs[key];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
dataSet[key] = value;
|
|
20
|
+
|
|
21
|
+
dataSet[key] = value ?? false;
|
|
24
22
|
}
|
|
25
23
|
return { dataSet };
|
|
26
24
|
}
|