@korsolutions/ui 0.0.90 → 0.0.92
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/dist/module/components/avatar/components/avatar-image.js.map +1 -1
- package/dist/module/components/badge/badge.js +1 -6
- package/dist/module/components/badge/badge.js.map +1 -1
- package/dist/module/components/badge/variants/default.js +3 -2
- package/dist/module/components/badge/variants/default.js.map +1 -1
- package/dist/module/components/badge/variants/secondary.js +2 -1
- package/dist/module/components/badge/variants/secondary.js.map +1 -1
- package/dist/module/components/card/card-title.js +2 -3
- package/dist/module/components/card/card-title.js.map +1 -1
- package/dist/module/components/combobox/components/combobox-list.js +24 -0
- package/dist/module/components/combobox/components/combobox-list.js.map +1 -0
- package/dist/module/components/combobox/components/combobox-option.js +17 -25
- package/dist/module/components/combobox/components/combobox-option.js.map +1 -1
- package/dist/module/components/combobox/components/combobox-overlay.js +0 -1
- package/dist/module/components/combobox/components/combobox-overlay.js.map +1 -1
- package/dist/module/components/combobox/components/combobox-root.js +62 -11
- package/dist/module/components/combobox/components/combobox-root.js.map +1 -1
- package/dist/module/components/combobox/components/combobox-trigger.js +32 -18
- package/dist/module/components/combobox/components/combobox-trigger.js.map +1 -1
- package/dist/module/components/combobox/context.js.map +1 -1
- package/dist/module/components/combobox/index.js +2 -0
- package/dist/module/components/combobox/index.js.map +1 -1
- package/dist/module/components/link/link.js +16 -6
- package/dist/module/components/link/link.js.map +1 -1
- package/dist/module/components/menu/components/menu-selection-indicator.js +4 -3
- package/dist/module/components/menu/components/menu-selection-indicator.js.map +1 -1
- package/dist/module/components/phone-input/components/phone-input.js +16 -7
- package/dist/module/components/phone-input/components/phone-input.js.map +1 -1
- package/dist/module/components/portal/portal.js.map +1 -1
- package/dist/module/components/select/components/select-option.js +13 -16
- package/dist/module/components/select/components/select-option.js.map +1 -1
- package/dist/module/components/select/components/select-trigger.js +3 -1
- package/dist/module/components/select/components/select-trigger.js.map +1 -1
- package/dist/module/components/select/variants/default.js +6 -3
- package/dist/module/components/select/variants/default.js.map +1 -1
- package/dist/module/hooks/use-relative-position.js.map +1 -1
- package/dist/module/utils/normalize-layout.js.map +1 -1
- package/dist/typescript/src/components/avatar/components/avatar-image.d.ts +2 -2
- package/dist/typescript/src/components/avatar/components/avatar-image.d.ts.map +1 -1
- package/dist/typescript/src/components/badge/badge.d.ts.map +1 -1
- package/dist/typescript/src/components/badge/variants/default.d.ts.map +1 -1
- package/dist/typescript/src/components/badge/variants/secondary.d.ts.map +1 -1
- package/dist/typescript/src/components/card/card-title.d.ts +2 -2
- package/dist/typescript/src/components/card/card-title.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/components/combobox-list.d.ts +12 -0
- package/dist/typescript/src/components/combobox/components/combobox-list.d.ts.map +1 -0
- package/dist/typescript/src/components/combobox/components/combobox-option.d.ts +5 -5
- package/dist/typescript/src/components/combobox/components/combobox-option.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/components/combobox-overlay.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/components/combobox-root.d.ts +26 -6
- package/dist/typescript/src/components/combobox/components/combobox-root.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/components/combobox-trigger.d.ts +13 -4
- package/dist/typescript/src/components/combobox/components/combobox-trigger.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/context.d.ts +6 -2
- package/dist/typescript/src/components/combobox/context.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/index.d.ts +3 -0
- package/dist/typescript/src/components/combobox/index.d.ts.map +1 -1
- package/dist/typescript/src/components/combobox/types.d.ts +2 -3
- package/dist/typescript/src/components/combobox/types.d.ts.map +1 -1
- package/dist/typescript/src/components/input/input.d.ts +1 -1
- package/dist/typescript/src/components/input/input.d.ts.map +1 -1
- package/dist/typescript/src/components/link/link.d.ts +9 -3
- package/dist/typescript/src/components/link/link.d.ts.map +1 -1
- package/dist/typescript/src/components/menu/components/menu-selection-indicator.d.ts.map +1 -1
- package/dist/typescript/src/components/phone-input/components/phone-input.d.ts +4 -6
- package/dist/typescript/src/components/phone-input/components/phone-input.d.ts.map +1 -1
- package/dist/typescript/src/components/phone-input/index.d.ts +1 -2
- package/dist/typescript/src/components/phone-input/index.d.ts.map +1 -1
- package/dist/typescript/src/components/select/components/select-option.d.ts +4 -1
- package/dist/typescript/src/components/select/components/select-option.d.ts.map +1 -1
- package/dist/typescript/src/components/select/components/select-trigger.d.ts.map +1 -1
- package/dist/typescript/src/components/select/variants/default.d.ts.map +1 -1
- package/dist/typescript/src/hooks/use-relative-position.d.ts +2 -2
- package/dist/typescript/src/hooks/use-relative-position.d.ts.map +1 -1
- package/dist/typescript/src/themes/types.d.ts +4 -0
- package/dist/typescript/src/themes/types.d.ts.map +1 -1
- package/dist/typescript/src/types/element.types.d.ts +3 -10
- package/dist/typescript/src/types/element.types.d.ts.map +1 -1
- package/dist/typescript/src/types/props.types.d.ts +1 -1
- package/dist/typescript/src/types/props.types.d.ts.map +1 -1
- package/dist/typescript/src/utils/normalize-layout.d.ts +3 -2
- package/dist/typescript/src/utils/normalize-layout.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/avatar/components/avatar-image.tsx +2 -2
- package/src/components/badge/badge.tsx +1 -3
- package/src/components/badge/variants/default.tsx +2 -1
- package/src/components/badge/variants/secondary.tsx +1 -0
- package/src/components/card/card-title.tsx +7 -4
- package/src/components/combobox/components/combobox-list.tsx +32 -0
- package/src/components/combobox/components/combobox-option.tsx +25 -36
- package/src/components/combobox/components/combobox-overlay.tsx +0 -1
- package/src/components/combobox/components/combobox-root.tsx +110 -23
- package/src/components/combobox/components/combobox-trigger.tsx +44 -21
- package/src/components/combobox/context.ts +7 -2
- package/src/components/combobox/index.ts +3 -0
- package/src/components/combobox/types.ts +2 -3
- package/src/components/link/link.tsx +24 -8
- package/src/components/menu/components/menu-selection-indicator.tsx +5 -4
- package/src/components/phone-input/components/phone-input.tsx +33 -23
- package/src/components/portal/portal.tsx +2 -2
- package/src/components/select/components/select-option.tsx +23 -19
- package/src/components/select/components/select-trigger.tsx +11 -6
- package/src/components/select/variants/default.tsx +4 -0
- package/src/hooks/use-relative-position.ts +4 -4
- package/src/themes/types.ts +4 -0
- package/src/types/element.types.ts +3 -10
- package/src/types/props.types.ts +1 -1
- package/src/utils/normalize-layout.ts +3 -2
|
@@ -6,9 +6,17 @@ import { measureLayoutPosition } from "../../../utils/normalize-layout";
|
|
|
6
6
|
import { useCombobox } from "../context";
|
|
7
7
|
import type { ComboboxTriggerState } from "../types";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
type ExtendableProps = Omit<TextInputProps, "value" | "onChange" | "onChangeText">;
|
|
10
|
+
|
|
11
|
+
type RenderProps = {
|
|
12
|
+
inputRef: React.RefObject<TextInputRef | null>;
|
|
13
|
+
open: () => void;
|
|
14
|
+
setInputValue: (value: string) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type ComboboxTriggerProps = ExtendableProps & {
|
|
18
|
+
render?: (props: RenderProps) => React.ReactNode;
|
|
19
|
+
};
|
|
12
20
|
|
|
13
21
|
const calculateState = (isDisabled: boolean, isOpen: boolean): ComboboxTriggerState => {
|
|
14
22
|
if (isDisabled) return "disabled";
|
|
@@ -16,17 +24,17 @@ const calculateState = (isDisabled: boolean, isOpen: boolean): ComboboxTriggerSt
|
|
|
16
24
|
return "default";
|
|
17
25
|
};
|
|
18
26
|
|
|
19
|
-
export function ComboboxTrigger(props: ComboboxTriggerProps) {
|
|
27
|
+
export function ComboboxTrigger({ render, ...props }: ComboboxTriggerProps) {
|
|
20
28
|
const combobox = useCombobox();
|
|
21
29
|
const triggerRef = useRef<TextInputRef>(null);
|
|
22
30
|
|
|
23
31
|
const triggerState = calculateState(combobox.isDisabled, combobox.isOpen);
|
|
24
|
-
|
|
25
|
-
const displayValue = combobox.isOpen ? combobox.inputValue :
|
|
32
|
+
const selectedLabel = combobox.value != null ? combobox.getItemLabel(combobox.value) : "";
|
|
33
|
+
const displayValue = combobox.isOpen ? combobox.inputValue : selectedLabel;
|
|
26
34
|
|
|
27
35
|
const open = () => {
|
|
28
36
|
if (combobox.isDisabled) return;
|
|
29
|
-
combobox.setInputValue(
|
|
37
|
+
combobox.setInputValue(selectedLabel);
|
|
30
38
|
requestAnimationFrame(() => {
|
|
31
39
|
measureLayoutPosition(triggerRef.current, (layout) => {
|
|
32
40
|
combobox.setTriggerPosition(layout);
|
|
@@ -35,9 +43,25 @@ export function ComboboxTrigger(props: ComboboxTriggerProps) {
|
|
|
35
43
|
});
|
|
36
44
|
};
|
|
37
45
|
|
|
46
|
+
const onChangeText = (text: string) => {
|
|
47
|
+
if (combobox.isDisabled) return;
|
|
48
|
+
combobox.setInputValue(text);
|
|
49
|
+
if (!combobox.isOpen) open();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const onFocus = () => {
|
|
53
|
+
if (!combobox.isOpen) open();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const setInputValue = (value: string) => {
|
|
57
|
+
combobox.setInputValue(value);
|
|
58
|
+
if (triggerRef.current) {
|
|
59
|
+
setInnerInputValue(triggerRef.current, value);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
38
63
|
useEffect(() => {
|
|
39
|
-
|
|
40
|
-
setInnerInputValue(triggerRef.current, displayValue);
|
|
64
|
+
setInputValue(displayValue);
|
|
41
65
|
}, [displayValue]);
|
|
42
66
|
|
|
43
67
|
useEffect(() => {
|
|
@@ -60,26 +84,25 @@ export function ComboboxTrigger(props: ComboboxTriggerProps) {
|
|
|
60
84
|
const composedStyle = StyleSheet.flatten([
|
|
61
85
|
triggerStyles?.default?.style,
|
|
62
86
|
triggerStyles?.[triggerState]?.style,
|
|
87
|
+
props.style,
|
|
63
88
|
]);
|
|
64
89
|
|
|
90
|
+
if (render) {
|
|
91
|
+
return render({
|
|
92
|
+
inputRef: triggerRef,
|
|
93
|
+
open,
|
|
94
|
+
setInputValue,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
65
98
|
return (
|
|
66
99
|
<TextInput
|
|
67
100
|
{...composedProps}
|
|
68
101
|
ref={triggerRef}
|
|
69
102
|
value={undefined}
|
|
70
103
|
onChange={undefined}
|
|
71
|
-
onChangeText={
|
|
72
|
-
|
|
73
|
-
combobox.setInputValue(text);
|
|
74
|
-
if (!combobox.isOpen) {
|
|
75
|
-
open();
|
|
76
|
-
}
|
|
77
|
-
}}
|
|
78
|
-
onFocus={() => {
|
|
79
|
-
if (!combobox.isOpen) {
|
|
80
|
-
open();
|
|
81
|
-
}
|
|
82
|
-
}}
|
|
104
|
+
onChangeText={onChangeText}
|
|
105
|
+
onFocus={onFocus}
|
|
83
106
|
style={composedStyle}
|
|
84
107
|
/>
|
|
85
108
|
);
|
|
@@ -4,8 +4,13 @@ import type { LayoutPosition } from "../../hooks";
|
|
|
4
4
|
import type { ComboboxState, ComboboxStyles } from "./types";
|
|
5
5
|
|
|
6
6
|
export interface ComboboxContext {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
items: readonly unknown[];
|
|
8
|
+
filteredItems: readonly unknown[];
|
|
9
|
+
getItemValue: (item: unknown) => string;
|
|
10
|
+
getItemLabel: (item: unknown) => string;
|
|
11
|
+
|
|
12
|
+
value: unknown | undefined;
|
|
13
|
+
onChange: ((item: unknown) => void) | undefined;
|
|
9
14
|
|
|
10
15
|
isOpen: boolean;
|
|
11
16
|
setIsOpen: Dispatch<React.SetStateAction<boolean>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ComboboxContent } from "./components/combobox-content";
|
|
2
2
|
import { ComboboxEmpty } from "./components/combobox-empty";
|
|
3
|
+
import { ComboboxList } from "./components/combobox-list";
|
|
3
4
|
import { ComboboxOption } from "./components/combobox-option";
|
|
4
5
|
import { ComboboxOverlay } from "./components/combobox-overlay";
|
|
5
6
|
import { ComboboxPortal } from "./components/combobox-portal";
|
|
@@ -12,12 +13,14 @@ export const Combobox = {
|
|
|
12
13
|
Portal: ComboboxPortal,
|
|
13
14
|
Overlay: ComboboxOverlay,
|
|
14
15
|
Content: ComboboxContent,
|
|
16
|
+
List: ComboboxList,
|
|
15
17
|
Option: ComboboxOption,
|
|
16
18
|
Empty: ComboboxEmpty,
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export type { ComboboxContentProps } from "./components/combobox-content";
|
|
20
22
|
export type { ComboboxEmptyProps } from "./components/combobox-empty";
|
|
23
|
+
export type { ComboboxListProps } from "./components/combobox-list";
|
|
21
24
|
export type { ComboboxOptionProps } from "./components/combobox-option";
|
|
22
25
|
export type { ComboboxOverlayProps } from "./components/combobox-overlay";
|
|
23
26
|
export type { ComboboxPortalProps } from "./components/combobox-portal";
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { TextInputProps, TextStyle } from "react-native";
|
|
1
|
+
import type { StyleProp, TextInputProps, TextStyle, ViewStyle } from "react-native";
|
|
2
2
|
import type { ComboboxContentProps } from "./components/combobox-content";
|
|
3
3
|
import type { ComboboxOverlayProps } from "./components/combobox-overlay";
|
|
4
|
-
import type { ComboboxRootProps } from "./components/combobox-root";
|
|
5
4
|
|
|
6
5
|
export type ComboboxState = "default" | "disabled";
|
|
7
6
|
export type ComboboxTriggerState = ComboboxState | "focused";
|
|
8
7
|
export type ComboboxOptionState = ComboboxState | "hovered" | "selected";
|
|
9
8
|
|
|
10
9
|
export interface ComboboxStyles {
|
|
11
|
-
root?: Partial<Record<ComboboxState,
|
|
10
|
+
root?: Partial<Record<ComboboxState, StyleProp<ViewStyle>>>;
|
|
12
11
|
trigger?: Partial<Record<ComboboxTriggerState, TextInputProps>>;
|
|
13
12
|
overlay?: Partial<Record<ComboboxState, ComboboxOverlayProps["style"]>>;
|
|
14
13
|
content?: Partial<Record<ComboboxState, ComboboxContentProps["style"]>>;
|
|
@@ -1,26 +1,42 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Linking, Text as RnText, type TextProps as RnTextProps } from "react-native";
|
|
2
|
+
import { Linking, Text as RnText, StyleSheet, type TextProps as RnTextProps } from "react-native";
|
|
3
|
+
import { useComponentConfig } from "../../themes/provider";
|
|
3
4
|
import { LinkVariants } from "./variants";
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
href?: string;
|
|
6
|
+
export type ExtendableProps = Omit<RnTextProps, "onPress" | "style">;
|
|
7
7
|
|
|
8
|
+
export type LinkStyles = RnTextProps["style"];
|
|
9
|
+
|
|
10
|
+
export type LinkProps = RnTextProps & {
|
|
8
11
|
variant?: keyof typeof LinkVariants;
|
|
9
|
-
|
|
12
|
+
style?: LinkStyles;
|
|
13
|
+
} & (
|
|
14
|
+
| {
|
|
15
|
+
href?: string;
|
|
16
|
+
}
|
|
17
|
+
| {
|
|
18
|
+
onPress?: RnTextProps["onPress"];
|
|
19
|
+
}
|
|
20
|
+
);
|
|
10
21
|
|
|
11
22
|
export function Link(props: LinkProps) {
|
|
12
|
-
const
|
|
23
|
+
const { style, onPress, variant = "default", ...rest } = props;
|
|
24
|
+
const useVariantStyles = LinkVariants[variant];
|
|
25
|
+
const config = useComponentConfig("link");
|
|
13
26
|
const variantStyles = useVariantStyles();
|
|
14
27
|
|
|
15
28
|
const handlePress: RnTextProps["onPress"] = async (e) => {
|
|
16
|
-
if (props.href) {
|
|
29
|
+
if ("href" in props && props.href) {
|
|
17
30
|
const supported = await Linking.canOpenURL(props.href);
|
|
18
31
|
if (supported) {
|
|
19
32
|
await Linking.openURL(props.href);
|
|
20
33
|
}
|
|
34
|
+
} else {
|
|
35
|
+
onPress?.(e);
|
|
21
36
|
}
|
|
22
|
-
props.onPress?.(e);
|
|
23
37
|
};
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
const composedStyles = StyleSheet.flatten([variantStyles, config?.styles, style]);
|
|
40
|
+
|
|
41
|
+
return <RnText {...rest} style={composedStyles} onPress={handlePress} />;
|
|
26
42
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Text, View } from "react-native";
|
|
2
|
+
import { Text, View, type StyleProp, type ViewStyle } from "react-native";
|
|
3
3
|
import { useComponentConfig } from "../../../themes/provider";
|
|
4
4
|
import { useMenu } from "../context";
|
|
5
5
|
|
|
@@ -11,14 +11,15 @@ export function MenuSelectionIndicator({ isSelected }: MenuSelectionIndicatorPro
|
|
|
11
11
|
const config = useComponentConfig("menu");
|
|
12
12
|
const menu = useMenu();
|
|
13
13
|
const SelectionIcon = config?.selectionIcon;
|
|
14
|
+
const indicatorStyles = menu.styles?.selectionIndicator;
|
|
14
15
|
|
|
15
16
|
if (!isSelected) {
|
|
16
|
-
return <View style={
|
|
17
|
+
return <View style={indicatorStyles as StyleProp<ViewStyle>} />;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
if (SelectionIcon) {
|
|
20
|
-
return <SelectionIcon {...
|
|
21
|
+
return <SelectionIcon {...indicatorStyles} />;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
return <Text style={
|
|
24
|
+
return <Text style={indicatorStyles}>✓</Text>;
|
|
24
25
|
}
|
|
@@ -1,28 +1,38 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import {
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import { StyleSheet, TextInput, type TextInputProps } from "react-native";
|
|
3
|
+
import type { TextInputRef } from "../../../types/element.types";
|
|
3
4
|
import { usePhoneInput } from "../context";
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
placeholder?: string;
|
|
7
|
-
style?: StyleProp<TextStyle>;
|
|
8
|
-
}
|
|
6
|
+
export type ExpandableProps = Omit<TextInputProps, "value" | "onChangeText">;
|
|
9
7
|
|
|
10
|
-
export
|
|
11
|
-
const { styles, state, setIsFocused, phoneMask, isDisabled } = usePhoneInput();
|
|
8
|
+
export type PhoneInputProps = ExpandableProps;
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
export const PhoneInput = forwardRef<TextInputRef, PhoneInputProps>(
|
|
11
|
+
({ placeholder = "Enter phone number", style, ...props }, ref) => {
|
|
12
|
+
const { styles, state, setIsFocused, phoneMask, isDisabled } = usePhoneInput();
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
const inputStyles = StyleSheet.flatten([styles.input?.default, styles.input?.[state], style]);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<TextInput
|
|
18
|
+
{...props}
|
|
19
|
+
ref={ref}
|
|
20
|
+
value={phoneMask.displayValue}
|
|
21
|
+
onChangeText={phoneMask.onChangeText}
|
|
22
|
+
keyboardType={phoneMask.keyboardType}
|
|
23
|
+
placeholder={placeholder}
|
|
24
|
+
placeholderTextColor={StyleSheet.flatten(styles.countryButtonText?.disabled)?.color}
|
|
25
|
+
readOnly={isDisabled}
|
|
26
|
+
onFocus={(e) => {
|
|
27
|
+
setIsFocused(true);
|
|
28
|
+
props.onFocus?.(e);
|
|
29
|
+
}}
|
|
30
|
+
onBlur={(e) => {
|
|
31
|
+
setIsFocused(false);
|
|
32
|
+
props.onBlur?.(e);
|
|
33
|
+
}}
|
|
34
|
+
style={inputStyles}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
@@ -6,7 +6,7 @@ import React, {
|
|
|
6
6
|
useState,
|
|
7
7
|
useSyncExternalStore,
|
|
8
8
|
} from "react";
|
|
9
|
-
import { Platform, View
|
|
9
|
+
import { Platform, View } from "react-native";
|
|
10
10
|
import { measureLayoutPosition } from "../../utils/normalize-layout";
|
|
11
11
|
import { PortalOffsetContext, type PortalOffset } from "./portal-offset";
|
|
12
12
|
import { DEFAULT_PORTAL_HOST, type PortalHostProps, type PortalProps } from "./portal.constants";
|
|
@@ -58,7 +58,7 @@ function removePortal(hostName: string, name: string) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function DefaultContainer(props: React.PropsWithChildren) {
|
|
61
|
-
const containerRef = useRef<
|
|
61
|
+
const containerRef = useRef<React.ComponentRef<typeof View>>(null);
|
|
62
62
|
const [offset, setOffset] = useState<PortalOffset | null>(null);
|
|
63
63
|
|
|
64
64
|
const onLayout = useCallback(() => {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { calculateComposedStyles } from "../../../utils/calculate-styles";
|
|
2
1
|
import React, { useEffect, useState } from "react";
|
|
3
|
-
import { Pressable,
|
|
2
|
+
import { Pressable, StyleSheet, type PressableProps } from "react-native";
|
|
3
|
+
import type { ElementChildren } from "../../../types/element.types";
|
|
4
4
|
import { useSelect } from "../context";
|
|
5
5
|
import type { SelectOptionState, SelectState } from "../types";
|
|
6
6
|
|
|
7
7
|
export type SelectOptionProps = {
|
|
8
8
|
value: string;
|
|
9
|
-
children?:
|
|
9
|
+
children?: ElementChildren;
|
|
10
|
+
style?: PressableProps["style"];
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
const calculateState = (
|
|
@@ -32,8 +33,7 @@ export function SelectOption(props: SelectOptionProps): React.ReactElement {
|
|
|
32
33
|
const isSelected = select.value === props.value;
|
|
33
34
|
|
|
34
35
|
const optionState = calculateState(select.state, isHovered, isSelected);
|
|
35
|
-
const
|
|
36
|
-
|
|
36
|
+
const optionStyles = select.styles?.option;
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
select.setOptions((prev) => {
|
|
39
39
|
if (prev.find((option) => option.value === props.value)) {
|
|
@@ -43,23 +43,27 @@ export function SelectOption(props: SelectOptionProps): React.ReactElement {
|
|
|
43
43
|
});
|
|
44
44
|
}, [props.value, props.children]);
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const handlePress = () => {
|
|
47
|
+
select.onChange?.(props.value);
|
|
48
|
+
select.setIsOpen(false);
|
|
49
|
+
};
|
|
50
|
+
const handlePointerEnter = () => setIsHovered(true);
|
|
51
|
+
const handlePointerLeave = () => setIsHovered(false);
|
|
47
52
|
|
|
48
53
|
return (
|
|
49
|
-
<
|
|
50
|
-
onPress={
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
style={composedStyles}
|
|
54
|
+
<Pressable
|
|
55
|
+
onPress={handlePress}
|
|
56
|
+
onPointerEnter={handlePointerEnter}
|
|
57
|
+
onPointerLeave={handlePointerLeave}
|
|
58
|
+
style={(styleProps) =>
|
|
59
|
+
StyleSheet.flatten([
|
|
60
|
+
optionStyles?.default,
|
|
61
|
+
optionStyles?.[optionState],
|
|
62
|
+
typeof props.style === "function" ? props.style(styleProps) : props.style,
|
|
63
|
+
])
|
|
64
|
+
}
|
|
61
65
|
>
|
|
62
66
|
{props.children}
|
|
63
|
-
</
|
|
67
|
+
</Pressable>
|
|
64
68
|
);
|
|
65
69
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { useRef } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Pressable,
|
|
4
|
+
Text,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
type TextStyle,
|
|
7
|
+
type ViewStyle,
|
|
8
|
+
} from "react-native";
|
|
3
9
|
import type { ViewRef } from "../../../types/element.types";
|
|
4
10
|
import { calculateComposedStyles } from "../../../utils/calculate-styles";
|
|
5
11
|
import { measureLayoutPosition } from "../../../utils/normalize-layout";
|
|
@@ -56,11 +62,10 @@ export function SelectValue(props: SelectValueProps) {
|
|
|
56
62
|
const selectedOptionLabel = selectedOption?.label;
|
|
57
63
|
const displayValue = selectedOptionLabel ?? select.value;
|
|
58
64
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
);
|
|
65
|
+
const key = displayValue ? "value" : "placeholder";
|
|
66
|
+
const slotStyles = select.styles?.[key];
|
|
67
|
+
const composedStyles: StyleProp<TextStyle> = [slotStyles?.default, slotStyles?.[select.state]];
|
|
68
|
+
|
|
64
69
|
if (!!displayValue && typeof displayValue !== "string") {
|
|
65
70
|
return <>{displayValue}</>;
|
|
66
71
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CursorValue } from "react-native";
|
|
1
2
|
import type { Size } from "../../../utils/size-scale";
|
|
2
3
|
import { useThemedStyles } from "../../../utils/use-themed-styles";
|
|
3
4
|
import { type SelectStyles } from "../types";
|
|
@@ -23,6 +24,7 @@ export function useSelectVariantDefault(size: Size): SelectStyles {
|
|
|
23
24
|
},
|
|
24
25
|
disabled: {
|
|
25
26
|
backgroundColor: colors.muted,
|
|
27
|
+
cursor: "not-allowed" as CursorValue,
|
|
26
28
|
},
|
|
27
29
|
},
|
|
28
30
|
value: {
|
|
@@ -74,9 +76,11 @@ export function useSelectVariantDefault(size: Size): SelectStyles {
|
|
|
74
76
|
lineHeight: s.lineHeight,
|
|
75
77
|
color: colors.foreground,
|
|
76
78
|
borderRadius: radius / 2,
|
|
79
|
+
cursor: "pointer",
|
|
77
80
|
},
|
|
78
81
|
disabled: {
|
|
79
82
|
color: colors.mutedForeground,
|
|
83
|
+
cursor: "not-allowed" as CursorValue,
|
|
80
84
|
},
|
|
81
85
|
selected: {
|
|
82
86
|
backgroundColor: colors.muted,
|
|
@@ -2,8 +2,8 @@ import { useMemo } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
Platform,
|
|
4
4
|
useWindowDimensions,
|
|
5
|
-
type DisplayMetrics,
|
|
6
5
|
type LayoutRectangle,
|
|
6
|
+
type ScaledSize,
|
|
7
7
|
type ViewStyle,
|
|
8
8
|
} from "react-native";
|
|
9
9
|
import { usePortalOffset } from "../components/portal";
|
|
@@ -118,7 +118,7 @@ export interface LayoutPosition {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
interface GetPositionArgs {
|
|
121
|
-
dimensions:
|
|
121
|
+
dimensions: ScaledSize;
|
|
122
122
|
triggerPosition: LayoutPosition;
|
|
123
123
|
contentLayout: LayoutRectangle;
|
|
124
124
|
insets: SafeAreaInsets;
|
|
@@ -148,7 +148,7 @@ interface GetSideArgs {
|
|
|
148
148
|
positionTop: number;
|
|
149
149
|
positionBottom: number;
|
|
150
150
|
contentLayout: LayoutRectangle;
|
|
151
|
-
dimensions:
|
|
151
|
+
dimensions: ScaledSize;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
function getSide({
|
|
@@ -272,7 +272,7 @@ function getLeftPosition(
|
|
|
272
272
|
contentWidth: number,
|
|
273
273
|
alignOffset: number,
|
|
274
274
|
insets: SafeAreaInsets,
|
|
275
|
-
dimensions:
|
|
275
|
+
dimensions: ScaledSize,
|
|
276
276
|
) {
|
|
277
277
|
let left = 0;
|
|
278
278
|
if (align === "start") {
|
package/src/themes/types.ts
CHANGED
|
@@ -53,6 +53,7 @@ import type { EmptyStyles } from "../components/empty/types";
|
|
|
53
53
|
import type { FieldStyles } from "../components/field/types";
|
|
54
54
|
import type { IconButtonStyles } from "../components/icon-button/types";
|
|
55
55
|
import type { InputStyles } from "../components/input/types";
|
|
56
|
+
import type { LinkStyles } from "../components/link";
|
|
56
57
|
import type { MenuStyles } from "../components/menu/types";
|
|
57
58
|
import type { PhoneInputStyles } from "../components/phone-input/types";
|
|
58
59
|
import type { PopoverStyles } from "../components/popover/types";
|
|
@@ -115,6 +116,9 @@ export interface ComponentsConfig {
|
|
|
115
116
|
input?: {
|
|
116
117
|
styles?: InputStyles;
|
|
117
118
|
};
|
|
119
|
+
link?: {
|
|
120
|
+
styles?: LinkStyles;
|
|
121
|
+
};
|
|
118
122
|
menu?: {
|
|
119
123
|
selectionIcon?: React.ComponentType<SvgProps>;
|
|
120
124
|
styles?: MenuStyles;
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TextInput, View } from "react-native";
|
|
2
2
|
import type { SvgProps } from "./props.types";
|
|
3
3
|
|
|
4
|
-
export type ViewRef =
|
|
5
|
-
export type TextInputRef =
|
|
6
|
-
focus: () => void;
|
|
7
|
-
blur: () => void;
|
|
8
|
-
clear: () => void;
|
|
9
|
-
isFocused: () => boolean;
|
|
10
|
-
getNativeRef: () => HostInstance;
|
|
11
|
-
setSelection: (start: number, end?: number) => void;
|
|
12
|
-
};
|
|
4
|
+
export type ViewRef = React.ComponentRef<typeof View>;
|
|
5
|
+
export type TextInputRef = React.ComponentRef<typeof TextInput>;
|
|
13
6
|
|
|
14
7
|
export type TextChild = string | number | bigint | boolean | null | undefined;
|
|
15
8
|
export type TextChildren = TextChild | TextChild[];
|
package/src/types/props.types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type React from "react";
|
|
|
2
2
|
import type { ColorValue, StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
3
3
|
|
|
4
4
|
export type PropsWithRender<P> = P & {
|
|
5
|
-
render?:
|
|
5
|
+
render?: React.ComponentType<P>;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export type PropsWithRequiredRender<P> = P & {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LayoutRectangle } from "react-native";
|
|
2
2
|
import type { LayoutPosition } from "../hooks";
|
|
3
|
+
import type { TextInputRef, ViewRef } from "../types/element.types";
|
|
3
4
|
|
|
4
5
|
export const normalizeLayout = (layout: LayoutRectangle) => {
|
|
5
6
|
const _layout = { ...layout };
|
|
@@ -22,7 +23,7 @@ const isValidNumber = (value: unknown): value is number => {
|
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
export const measureLayoutPosition = (
|
|
25
|
-
ref:
|
|
26
|
+
ref: ViewRef | TextInputRef | null,
|
|
26
27
|
callback: (layout: LayoutPosition) => void,
|
|
27
28
|
) => {
|
|
28
29
|
if (ref && "getBoundingClientRect" in ref) {
|