react-native-umui 1.3.25
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/LICENSE +20 -0
- package/README.md +20 -0
- package/lib/commonjs/Badge.js +57 -0
- package/lib/commonjs/Badge.js.map +1 -0
- package/lib/commonjs/Button.js +122 -0
- package/lib/commonjs/Button.js.map +1 -0
- package/lib/commonjs/Checkbox.js +71 -0
- package/lib/commonjs/Checkbox.js.map +1 -0
- package/lib/commonjs/Divider.js +46 -0
- package/lib/commonjs/Divider.js.map +1 -0
- package/lib/commonjs/EasyIn.js +80 -0
- package/lib/commonjs/EasyIn.js.map +1 -0
- package/lib/commonjs/FlatList.js +27 -0
- package/lib/commonjs/FlatList.js.map +1 -0
- package/lib/commonjs/FlatPanel.js +63 -0
- package/lib/commonjs/FlatPanel.js.map +1 -0
- package/lib/commonjs/Grid.js +49 -0
- package/lib/commonjs/Grid.js.map +1 -0
- package/lib/commonjs/InputField.js +61 -0
- package/lib/commonjs/InputField.js.map +1 -0
- package/lib/commonjs/Line.js +33 -0
- package/lib/commonjs/Line.js.map +1 -0
- package/lib/commonjs/Load.js +84 -0
- package/lib/commonjs/Load.js.map +1 -0
- package/lib/commonjs/Numeral.js +206 -0
- package/lib/commonjs/Numeral.js.map +1 -0
- package/lib/commonjs/PanelRK.js +35 -0
- package/lib/commonjs/PanelRK.js.map +1 -0
- package/lib/commonjs/Phone.js +377 -0
- package/lib/commonjs/Phone.js.map +1 -0
- package/lib/commonjs/Press.js +18 -0
- package/lib/commonjs/Press.js.map +1 -0
- package/lib/commonjs/Radio.js +74 -0
- package/lib/commonjs/Radio.js.map +1 -0
- package/lib/commonjs/Scroll.js +43 -0
- package/lib/commonjs/Scroll.js.map +1 -0
- package/lib/commonjs/Tab.js +279 -0
- package/lib/commonjs/Tab.js.map +1 -0
- package/lib/commonjs/Text.js +29 -0
- package/lib/commonjs/Text.js.map +1 -0
- package/lib/commonjs/TextInput.js +69 -0
- package/lib/commonjs/TextInput.js.map +1 -0
- package/lib/commonjs/common.js +1917 -0
- package/lib/commonjs/common.js.map +1 -0
- package/lib/commonjs/index.js +248 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/regions.js +253 -0
- package/lib/commonjs/regions.js.map +1 -0
- package/lib/commonjs/shadows.js +231 -0
- package/lib/commonjs/shadows.js.map +1 -0
- package/lib/module/Badge.js +50 -0
- package/lib/module/Badge.js.map +1 -0
- package/lib/module/Button.js +115 -0
- package/lib/module/Button.js.map +1 -0
- package/lib/module/Checkbox.js +63 -0
- package/lib/module/Checkbox.js.map +1 -0
- package/lib/module/Divider.js +39 -0
- package/lib/module/Divider.js.map +1 -0
- package/lib/module/EasyIn.js +69 -0
- package/lib/module/EasyIn.js.map +1 -0
- package/lib/module/FlatList.js +20 -0
- package/lib/module/FlatList.js.map +1 -0
- package/lib/module/FlatPanel.js +56 -0
- package/lib/module/FlatPanel.js.map +1 -0
- package/lib/module/Grid.js +40 -0
- package/lib/module/Grid.js.map +1 -0
- package/lib/module/InputField.js +53 -0
- package/lib/module/InputField.js.map +1 -0
- package/lib/module/Line.js +26 -0
- package/lib/module/Line.js.map +1 -0
- package/lib/module/Load.js +76 -0
- package/lib/module/Load.js.map +1 -0
- package/lib/module/Numeral.js +196 -0
- package/lib/module/Numeral.js.map +1 -0
- package/lib/module/PanelRK.js +28 -0
- package/lib/module/PanelRK.js.map +1 -0
- package/lib/module/Phone.js +367 -0
- package/lib/module/Phone.js.map +1 -0
- package/lib/module/Press.js +11 -0
- package/lib/module/Press.js.map +1 -0
- package/lib/module/Radio.js +67 -0
- package/lib/module/Radio.js.map +1 -0
- package/lib/module/Scroll.js +33 -0
- package/lib/module/Scroll.js.map +1 -0
- package/lib/module/Tab.js +264 -0
- package/lib/module/Tab.js.map +1 -0
- package/lib/module/Text.js +20 -0
- package/lib/module/Text.js.map +1 -0
- package/lib/module/TextInput.js +60 -0
- package/lib/module/TextInput.js.map +1 -0
- package/lib/module/common.js +1908 -0
- package/lib/module/common.js.map +1 -0
- package/lib/module/index.js +23 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/regions.js +244 -0
- package/lib/module/regions.js.map +1 -0
- package/lib/module/shadows.js +223 -0
- package/lib/module/shadows.js.map +1 -0
- package/lib/typescript/src/Badge.d.ts +16 -0
- package/lib/typescript/src/Badge.d.ts.map +1 -0
- package/lib/typescript/src/Button.d.ts +21 -0
- package/lib/typescript/src/Button.d.ts.map +1 -0
- package/lib/typescript/src/Checkbox.d.ts +15 -0
- package/lib/typescript/src/Checkbox.d.ts.map +1 -0
- package/lib/typescript/src/Divider.d.ts +10 -0
- package/lib/typescript/src/Divider.d.ts.map +1 -0
- package/lib/typescript/src/EasyIn.d.ts +24 -0
- package/lib/typescript/src/EasyIn.d.ts.map +1 -0
- package/lib/typescript/src/FlatList.d.ts +7 -0
- package/lib/typescript/src/FlatList.d.ts.map +1 -0
- package/lib/typescript/src/FlatPanel.d.ts +10 -0
- package/lib/typescript/src/FlatPanel.d.ts.map +1 -0
- package/lib/typescript/src/Grid.d.ts +20 -0
- package/lib/typescript/src/Grid.d.ts.map +1 -0
- package/lib/typescript/src/InputField.d.ts +18 -0
- package/lib/typescript/src/InputField.d.ts.map +1 -0
- package/lib/typescript/src/Line.d.ts +10 -0
- package/lib/typescript/src/Line.d.ts.map +1 -0
- package/lib/typescript/src/Load.d.ts +13 -0
- package/lib/typescript/src/Load.d.ts.map +1 -0
- package/lib/typescript/src/Numeral.d.ts +76 -0
- package/lib/typescript/src/Numeral.d.ts.map +1 -0
- package/lib/typescript/src/PanelRK.d.ts +8 -0
- package/lib/typescript/src/PanelRK.d.ts.map +1 -0
- package/lib/typescript/src/Phone.d.ts +53 -0
- package/lib/typescript/src/Phone.d.ts.map +1 -0
- package/lib/typescript/src/Press.d.ts +8 -0
- package/lib/typescript/src/Press.d.ts.map +1 -0
- package/lib/typescript/src/Radio.d.ts +16 -0
- package/lib/typescript/src/Radio.d.ts.map +1 -0
- package/lib/typescript/src/Scroll.d.ts +13 -0
- package/lib/typescript/src/Scroll.d.ts.map +1 -0
- package/lib/typescript/src/Tab.d.ts +78 -0
- package/lib/typescript/src/Tab.d.ts.map +1 -0
- package/lib/typescript/src/Text.d.ts +8 -0
- package/lib/typescript/src/Text.d.ts.map +1 -0
- package/lib/typescript/src/TextInput.d.ts +8 -0
- package/lib/typescript/src/TextInput.d.ts.map +1 -0
- package/lib/typescript/src/common.d.ts +16 -0
- package/lib/typescript/src/common.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +23 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/regions.d.ts +244 -0
- package/lib/typescript/src/regions.d.ts.map +1 -0
- package/lib/typescript/src/shadows.d.ts +214 -0
- package/lib/typescript/src/shadows.d.ts.map +1 -0
- package/package.json +160 -0
- package/src/Badge.tsx +6 -0
- package/src/Button.tsx +7 -0
- package/src/Checkbox.tsx +3 -0
- package/src/Divider.tsx +3 -0
- package/src/EasyIn.tsx +4 -0
- package/src/FlatList.tsx +2 -0
- package/src/FlatPanel.tsx +2 -0
- package/src/Grid.tsx +3 -0
- package/src/InputField.tsx +3 -0
- package/src/Line.tsx +2 -0
- package/src/Load.tsx +3 -0
- package/src/Numeral.tsx +135 -0
- package/src/PanelRK.tsx +1 -0
- package/src/Phone.tsx +159 -0
- package/src/Press.tsx +2 -0
- package/src/Radio.tsx +2 -0
- package/src/Scroll.tsx +1 -0
- package/src/Tab.tsx +40 -0
- package/src/Text.tsx +1 -0
- package/src/TextInput.tsx +22 -0
- package/src/common.tsx +3438 -0
- package/src/index.tsx +22 -0
- package/src/regions.ts +227 -0
- package/src/shadows.ts +24 -0
package/src/Grid.tsx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React, { ReactElement, useMemo } from "react"; import { StyleProp, View, ViewStyle } from "react-native";
|
|
2
|
+
interface IColProps { colSpan: number; style?: StyleProp<ViewStyle>; children?: React.ReactNode; }; export function MCol({ }: IColProps) { return (<></>) };
|
|
3
|
+
interface IMGridProps { testID?: string; cols?: number; content?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly"; items?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline"; style?: StyleProp<ViewStyle>; gap?: number; children: ReactElement<IColProps> | Array<ReactElement<IColProps>>; }; function calc(cols: number = 12) { let _cols = Number(cols) || 12; _cols = _cols <= 0 ? 12 : cols; return Number((100.0 / _cols).toFixed(5)); }; export function MGrid(props: IMGridProps) { const span = useMemo(() => { return calc(props.cols); }, [props.cols]); return (<View testID={props.testID} style={[{ display: "flex", flexDirection: "row", flexWrap: "wrap", justifyContent: props.content, alignItems: props.items, columnGap: props.gap }, props.style,]}>{(Array.isArray(props.children) ? props.children : [props.children])?.map(k => { return (<View style={[k.props.style, { flex: (span * k.props.colSpan) || 0 }]}>{k.props.children}</View>) })}</View>) }
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React, { ReactNode } from "react"; import { TextStyle, View, ViewStyle } from "react-native"; import { MText } from "./Text"; import { StyleProp } from "react-native";
|
|
2
|
+
interface InputFieldProps { testID?: string; label?: string; containerStyle?: StyleProp<ViewStyle>; labelStyle?: StyleProp<TextStyle>; children?: ReactNode; }; export function MInputField(props: InputFieldProps) { return (<View testID={props.testID} style={[{ width: "100%", marginVertical: 5 }, props.containerStyle]}>{props.label ? <MText style={[{ color: "black", marginBottom: 3, fontSize: 15, paddingHorizontal: 3, fontWeight: "500" }, props.labelStyle]}>{props.label}</MText> : <></>}<View>{props.children}</View></View>) };
|
|
3
|
+
type MInputSetFieldProps = InputFieldProps & { noBackground?: boolean, border?: boolean }; export function MInputSetField(props: MInputSetFieldProps) { return (<View testID={props.testID} style={[{ width: "100%", marginVertical: 5 }, props.border ? { borderWidth: 1, borderColor: "#dadce0" } : {}, props.containerStyle]}>{props.label ? <MText style={[{ color: "black", fontWeight: "500", marginBottom: 3, paddingHorizontal: 7, paddingVertical: 1, fontSize: 15, top: -11.5, left: 7, zIndex: 105, position: "absolute", borderLeftWidth: 1, borderRightWidth: 1, borderColor: "#dadce0" }, props.noBackground ? {} : { backgroundColor: "white" }, props.labelStyle]}>{props.label}</MText> : <></>}<View>{props.children}</View></View>) }
|
package/src/Line.tsx
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React from "react"; import { StyleProp, View, ViewStyle } from "react-native";
|
|
2
|
+
interface HrProps { margin?: number; direction?: "w" | "h"; style?: StyleProp<ViewStyle>; }; export function MLine({ direction = "w", margin = 5, style }: HrProps) { return (<View style={[direction === "w" ? { flex: 1, height: 1, maxHeight: 1, marginVertical: margin } : { flex: 1, width: 1, maxWidth: 1, marginHorizontal: margin }, { backgroundColor: "#dadce0" }, style]} />) }
|
package/src/Load.tsx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React, { ComponentProps, useCallback, useEffect, useRef, useState } from "react"; import { ActivityIndicator, View } from "react-native";
|
|
2
|
+
function LoadActivity() { return (<View style={{ flex: 1, display: "flex", justifyContent: "center", alignItems: "center" }}><ActivityIndicator size={45} color="#016db6" /></View>) };
|
|
3
|
+
interface MLoadProps extends ComponentProps<any> { loadId: string; showLoading?: boolean; name?: string; delay?: number; load: () => Promise<{}>; onLoaded?: () => void; onError?: () => void; }; export function MLoad({ loadId, showLoading, name = "default", delay, load, ...props }: MLoadProps) { const [loaded, setLoaded] = useState<boolean>(false); const loadIfRef = useRef<string>(); const timeRef = useRef<any>(); const ref = useRef<any>(); const loadCmp = useCallback(async () => { try { if (!timeRef.current) { setLoaded(false); timeRef.current = setTimeout(async () => { try { ref.current = await load(); if (props.onLoaded) { props.onLoaded(); }; clearTimeout(timeRef.current); timeRef.current = undefined; loadIfRef.current = loadId; setLoaded(true); } catch (error) { if (props.onError) { props.onError(); } } }, delay || 25); }; } catch (error) { if (props.onError) { props.onError(); } } }, [timeRef, loadId, props.load, props.name]); useEffect(() => { loadCmp(); return () => { clearTimeout(timeRef.current); }; }, [loadCmp]); if (showLoading && !loaded) { return (<LoadActivity />) }; const Component = ref.current && ref.current[name] ? ref.current[name] : LoadActivity; return (<Component key={loadIfRef.current} {...props} />) }
|
package/src/Numeral.tsx
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import React from "react"; import { cts, stc } from "./common";
|
|
2
|
+
/**
|
|
3
|
+
* @param fraction default 2
|
|
4
|
+
* @param thousandSeperator default true
|
|
5
|
+
*/
|
|
6
|
+
export interface INumeralOptions { fraction?: number; thousandSeperator?: boolean; }
|
|
7
|
+
/**
|
|
8
|
+
* @param gte >= Y
|
|
9
|
+
* @param gt > Y
|
|
10
|
+
* @param lte <= Y
|
|
11
|
+
* @param lt < Y
|
|
12
|
+
*/
|
|
13
|
+
export interface NumeralValidity {
|
|
14
|
+
gte?: number;
|
|
15
|
+
gt?: number;
|
|
16
|
+
lte?: number;
|
|
17
|
+
lt?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface NumeralUtil {
|
|
20
|
+
/**
|
|
21
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
setCode: (code?: string) => void;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
currency: (value: number, code?: string | null, thousandSeperator?: boolean | null, fraction?: number, direction?: "ltr" | "rtl") => string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
format: (value: number, code?: string | null, thousandSeperator?: boolean | null, fraction?: number) => string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
parseRaw: (value: string, code?: string | null, fraction?: number) => string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
toNumber: (value: string | number, fraction?: number) => number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
toFloat: (value: string | number, fraction?: number) => number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
58
|
+
*/
|
|
59
|
+
export interface ICurrencySlotProps { direction?: "ltr" | "ltr"; value: number; code?: string; thousandSeperator?: boolean | null; fraction?: number; };
|
|
60
|
+
/**
|
|
61
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
62
|
+
*/
|
|
63
|
+
export interface NumeralSlotProps { value: number; code?: string; thousandSeperator?: boolean | null; fraction?: number; };
|
|
64
|
+
|
|
65
|
+
const fractionDefault: number = 2; const isopt = (k: any) => k == undefined || k === null; const setFraction = (defaultval: number, fraction?: number) => isopt(fraction) ? defaultval : fraction; const decOptions = (fraction?: number) => { const value = setFraction(fractionDefault, fraction); return { minimumFractionDigits: value, maximumFractionDigits: value }; }; const fraction = (value: number, fraction: number) => fraction === 0 ? Math.floor(value) : value;
|
|
66
|
+
// function testValid(value: string, validity?: NumeralValidity) { const amount = Number(value); if (!validity || value == "" || isopt(value)) { return ""; }; const gte = Number(validity.gte); const gt = Number(validity.gt); const lte = Number(validity.lte); const lt = Number(validity.lt); if (!isopt(validity.gte) && amount < gte) { return `X >= ${gte}`; }; if (!isopt(validity.gt) && amount <= gt) { return `X > ${gt}`; }; if (!isopt(validity.lte) && amount > lte) { return `X <= ${lte}`; }; if (!isopt(validity.lt) && amount > lt) { return `X < ${lt}`; }; return ""; }
|
|
67
|
+
const cache = { code: "", countryCode: null, symbol: "", separatorThousands: "", separatorDecimal: "", regexThousands: /[]/g, regexDecimal: /[]/g };
|
|
68
|
+
class Numeral {
|
|
69
|
+
private fraction?: number;
|
|
70
|
+
private thousandSeperator: boolean = false;
|
|
71
|
+
|
|
72
|
+
static new() { return new Numeral(); };
|
|
73
|
+
|
|
74
|
+
static convert(value: number | string, fraction?: number): number { if (isopt(fraction)) { return Number(value); }; return Number(Number((value || "").toString().replace(",", ".")).toFixed(fraction)); };
|
|
75
|
+
|
|
76
|
+
init(code?: string) { if (code !== cache.code) { cache.code = code; cache.countryCode = stc[code] || cts[code]; if (stc[code]) { cache.countryCode = stc[code]; } else if (cts[code]) { cache.countryCode = code; }; cache.symbol = cts[cache.countryCode]; cache.separatorThousands = new Intl.NumberFormat(cache.countryCode, { style: "decimal" }).format(1111).replace(/\d/g, ""); cache.separatorDecimal = new Intl.NumberFormat(cache.countryCode, { style: "decimal" }).format(11.11).replace(/\d/g, ""); cache.regexThousands = new RegExp(`[${cache.separatorThousands}]`, "g"); cache.regexDecimal = new RegExp(`[${cache.separatorDecimal}]`, "g"); } return this; };
|
|
77
|
+
|
|
78
|
+
setFraction(val?: number) { this.fraction = val; return this; };
|
|
79
|
+
|
|
80
|
+
setThousandSeperator(val: boolean = false) { this.thousandSeperator = val; return this; };
|
|
81
|
+
|
|
82
|
+
format(value: number): string { try { const amount = fraction(Number(value), this.fraction); const stt = decOptions(this.fraction); const amountformat = new Intl.NumberFormat(cache.countryCode, stt).format(amount); return this.thousandSeperator ? amountformat.replace(cache.regexThousands, "") : amountformat; } catch (error) { return ""; } };
|
|
83
|
+
|
|
84
|
+
inputFormat(value: number): string { try { const amountformat = this.format(value); return amountformat.replace(cache.regexThousands, ""); } catch (error) { return ""; } };
|
|
85
|
+
|
|
86
|
+
currency(value: number, direction: "ltr" | "rtl" = "ltr") { try { const amountformat = this.format(value); return direction === "ltr" ? `${amountformat}${cache.symbol}` : `${cache.symbol}${amountformat}`; } catch (error) { return ""; } };
|
|
87
|
+
|
|
88
|
+
parseRawFormat(value: string) { const stringNumber = (value || "").replace(cache.regexThousands, "").replace(cache.regexDecimal, ".").replace(new RegExp(`[${cache.symbol}]`, "g"), ""); const amount = fraction(parseFloat(stringNumber), this.fraction); return stringNumber ? amount.toFixed(setFraction(fractionDefault, this.fraction)) : stringNumber; }
|
|
89
|
+
}
|
|
90
|
+
export const numeral: NumeralUtil = (() => {
|
|
91
|
+
let _code: string = null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
95
|
+
* @returns
|
|
96
|
+
*/
|
|
97
|
+
function setCode(code?: string) { _code = code; };
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
101
|
+
*/
|
|
102
|
+
function currency(value: number, code?: string | null, thousandSeperator?: boolean | null, fraction?: number, direction: "ltr" | "rtl" = "ltr") { return Numeral.new().init(code || _code).setFraction(fraction).setThousandSeperator(thousandSeperator).currency(value, direction); };
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
106
|
+
*/
|
|
107
|
+
function format(value: number, code?: string | null, thousandSeperator?: boolean | null, fraction?: number) { return Numeral.new().init(code || _code).setFraction(fraction).setThousandSeperator(thousandSeperator).format(value); };
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param code country iat code or currency symbol, if it is empty set it geves from global
|
|
111
|
+
*/
|
|
112
|
+
function parseRaw(value: string, code?: string | null, fraction?: number) { return Numeral.new().init(code || _code).setFraction(fraction).parseRawFormat(value); };
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
* @param value
|
|
117
|
+
* @param fraction
|
|
118
|
+
* @returns
|
|
119
|
+
*/
|
|
120
|
+
function toNumber(value: string | number, fraction?: number): number { return Numeral.convert(value, fraction); };
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @param value
|
|
125
|
+
* @param fraction
|
|
126
|
+
* @returns
|
|
127
|
+
*/
|
|
128
|
+
function toFloat(value: string | number, fraction: number = 2): number { return Numeral.convert(value, fraction); };
|
|
129
|
+
|
|
130
|
+
return { setCode, currency, format, parseRaw, toNumber, toFloat }
|
|
131
|
+
})();
|
|
132
|
+
export function CurrencySlot(props: ICurrencySlotProps) {
|
|
133
|
+
return (<>{numeral.currency(props.value, props.code, props.thousandSeperator, props.fraction)}</>)
|
|
134
|
+
};
|
|
135
|
+
export function NumeralSlot(props: NumeralSlotProps) { return (<>{numeral.format(props.value, props.code, props.thousandSeperator, props.fraction)}</>) };
|
package/src/PanelRK.tsx
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from "react"; import { View, ViewProps } from "react-native"; interface MPanelRkProps extends ViewProps { children?: React.ReactNode; }; export function MPanelRK({ style, children, ...props }: MPanelRkProps) { return (<View style={[{ backgroundColor: "white", height: 53, borderWidth: 1, borderColor: "gray", marginTop: 7, marginBottom: 7, padding: 11, paddingHorizontal: 9, display: "flex", flexDirection: "row", alignItems: "center" }, style]} {...props}>{children}</View>) };
|
package/src/Phone.tsx
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React from "react"; import { StyleProp, TextStyle, TouchableHighlight, View, ViewStyle } from "react-native"; import { MText } from "./Text"; import { aa3phone } from "./common"; import { MTextInput } from "./TextInput"; import { codesMap } from "./regions";
|
|
2
|
+
export enum PhoneType { ANY = "ANY", MOBILE = "MOBILE", LAND = "LAND" }; export interface PhoneRaw { aa2: string; code: number; nn: string; example?: string; };
|
|
3
|
+
export interface PhoneUtil {
|
|
4
|
+
regisons: () => string[]
|
|
5
|
+
flag: (code: string) => string
|
|
6
|
+
/**
|
|
7
|
+
* @param phone
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
parseRaw: (phone: string) => PhoneRaw | null
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param code
|
|
14
|
+
* @param phone
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
parseRawByCountryCode: (code: string, phone: string) => PhoneRaw | null
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param code
|
|
21
|
+
* @param phone
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
pretty: (phone: string, phoneType?: PhoneType) => string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function checkList(item: AA3, phoneType: PhoneType) {
|
|
28
|
+
const regexlist: RegExp[] = []; const phonelenghts = item.phone_number_lengths; const beginwiths = item.mobile_begin_with; const isNotOnlyMobile = phoneType === PhoneType.MOBILE;
|
|
29
|
+
if (phonelenghts.length && beginwiths.length) {
|
|
30
|
+
phonelenghts.forEach(pl => { beginwiths.forEach(bw => { const r = new RegExp(`^${item.countryCode}${isNotOnlyMobile ? bw : `[0-9]{${bw.toString().length}}`}[0-9]{${pl - (bw as number).toString().length}}$`); regexlist.push(r); }); });
|
|
31
|
+
} else if (!phonelenghts.length && beginwiths.length) {
|
|
32
|
+
beginwiths.forEach(bw => { const r = new RegExp(`^${item.countryCode}${isNotOnlyMobile ? bw : `[0-9]{${bw.toString().length}}`}[0-9]`); regexlist.push(r); })
|
|
33
|
+
} else if (phonelenghts.length && !beginwiths.length) {
|
|
34
|
+
phonelenghts.forEach(pl => { const r = new RegExp(`^${item.countryCode}[0-9]{${pl}}$`); regexlist.push(r); });
|
|
35
|
+
} else {
|
|
36
|
+
const r = new RegExp(`^${item.countryCode}[0-9]`); regexlist.push(r);
|
|
37
|
+
}
|
|
38
|
+
return regexlist
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface AA3 { countryCode: number; mobile_begin_with?: number[]; phone_number_lengths?: number[]; flag: string; }; interface AA2 { aa2: string; flag: string; };
|
|
42
|
+
|
|
43
|
+
class Phone {
|
|
44
|
+
private supportAa2s: AA2[] = []
|
|
45
|
+
|
|
46
|
+
static new() { return new Phone() }
|
|
47
|
+
|
|
48
|
+
setRegions(vals: string[] = []) {
|
|
49
|
+
try {
|
|
50
|
+
vals.forEach(k => { if (aa3phone[k]) { this.supportAa2s.push({ aa2: k, flag: this.itemAa3ByAa2(k).flag }) } })
|
|
51
|
+
} catch (error) {
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get supportsIat2(): AA2[] { return this.supportAa2s }
|
|
58
|
+
|
|
59
|
+
formatRaw(raw: PhoneRaw, noPlusPrefix: boolean = false) { return `${noPlusPrefix ? "" : "+"}${raw.code}${raw.nn}` }
|
|
60
|
+
|
|
61
|
+
private itemAa3ByAa2(aa2: string): AA3 | null { const item: AA3 = aa3phone[aa2]; return item ? item : null; }
|
|
62
|
+
|
|
63
|
+
private check(aa2: string, fullPn: string, phoneType: PhoneType = PhoneType.MOBILE): PhoneRaw | null {
|
|
64
|
+
const item: AA3 | null = this.itemAa3ByAa2(aa2); const regexlist = checkList(item, phoneType);
|
|
65
|
+
if (regexlist.map(k => k.test(fullPn)).filter(k => k).length > 0) { const line = `${item.mobile_begin_with.length ? item.mobile_begin_with[item.mobile_begin_with.length - 1] : ""}${"512312387612638131123"}`; return ({ aa2: aa2, code: item.countryCode, nn: fullPn.substring(item.countryCode.toString().length, fullPn.length), example: line.substring(0, item.phone_number_lengths.length ? item.phone_number_lengths[item.mobile_begin_with.length - 1] : line.length) }); } return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
parseRaw(fullPn: string, phoneType?: PhoneType): PhoneRaw | null {
|
|
69
|
+
try {
|
|
70
|
+
const pn = (fullPn || "").replace(/\D/g, "").replace(/ /g, ""); const aa2s = Object.keys(aa3phone); let index = 0; let raw: PhoneRaw | null = null; for (index = 0; index < aa2s.length; index++) { raw = this.check(aa2s[index], pn, phoneType); if (raw) { break; }; }
|
|
71
|
+
|
|
72
|
+
return raw;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
parseRawInput(aa2: string, nn: string, phoneType?: PhoneType): PhoneRaw | null {
|
|
79
|
+
try {
|
|
80
|
+
const item: AA3 | null = this.itemAa3ByAa2(aa2); if (!item) { return null; }; const fullPn = `${item.countryCode}${nn}`;
|
|
81
|
+
return this.check(aa2, fullPn, phoneType);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
placeholder(aa2: string): string {
|
|
88
|
+
try {
|
|
89
|
+
const item: AA3 | null = this.itemAa3ByAa2(aa2); if (!item) { return ""; }; const line = `${item.mobile_begin_with.length ? item.mobile_begin_with[item.mobile_begin_with.length - 1] : ""}${"512312387612638131123"}`
|
|
90
|
+
return line.substring(0, item.phone_number_lengths.length ? item.phone_number_lengths[item.phone_number_lengths.length - 1] : line.length)
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return ""
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private mask(lenght: number, pt: string, txt: string, rmt: string): string {
|
|
97
|
+
if (rmt.length === 0 || txt.length >= lenght) { return txt; }; const c = pt.at(0); const v = rmt.at(0); if (c != "#") { txt += c; } else { txt += v; rmt = rmt.split("").filter((_, i) => i != 0).join(""); }; pt = pt.split("").filter((_, i) => i != 0).join("");
|
|
98
|
+
return this.mask(lenght, pt, txt, rmt);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
prettyMaskWoc(aa2: string, nn: string) {
|
|
102
|
+
try {
|
|
103
|
+
const item = aa3phone[aa2]; const mask = item?.mask?.replace(`+${item.countryCode.toString()} `, "");
|
|
104
|
+
return this.mask(mask.length, mask, "", nn);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
return ""
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
prettyMask(aa2: string, nn: string) {
|
|
111
|
+
try {
|
|
112
|
+
const item = aa3phone[aa2]; const mask = item?.mask;
|
|
113
|
+
return this.mask(mask.length, mask, "", nn);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return ""
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const phoneUtil: PhoneUtil = (() => {
|
|
121
|
+
function regisons() { return Object.keys(codesMap); }
|
|
122
|
+
function flag(code: string) { return aa3phone[code]?.flag; }
|
|
123
|
+
/**
|
|
124
|
+
* @param phone
|
|
125
|
+
* @returns
|
|
126
|
+
*/
|
|
127
|
+
function parseRaw(phone: string, phoneType?: PhoneType): PhoneRaw | null {
|
|
128
|
+
try {
|
|
129
|
+
return Phone.new().parseRaw(phone, phoneType);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
return null
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param code
|
|
137
|
+
* @param phone
|
|
138
|
+
* @returns
|
|
139
|
+
*/
|
|
140
|
+
function parseRawByCountryCode(code: string, phone: string, phoneType?: PhoneType): PhoneRaw | null {
|
|
141
|
+
try {
|
|
142
|
+
return Phone.new().parseRawInput(code, phone, phoneType);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
return null
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function pretty(phone: string, phoneType?: PhoneType): string {
|
|
149
|
+
try {
|
|
150
|
+
const raw = Phone.new().parseRaw(phone.replace(/\D/g, ""), phoneType || PhoneType.ANY);
|
|
151
|
+
return Phone.new().prettyMask(raw.aa2, raw.nn);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
return ""
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return { regisons, flag, parseRaw, parseRawByCountryCode, pretty }
|
|
158
|
+
})();
|
|
159
|
+
interface MPhoneInputProps { containerStyle?: StyleProp<ViewStyle>; phoneStyle?: StyleProp<TextStyle>; placeholder?: string; disabled?: boolean; noPlusPrefix?: boolean; regions?: Array<keyof typeof codesMap>; phoneType?: PhoneType; code: string; value: any; onChangeCountry: (regions: string[], active?: string) => void; onChange: (value: string) => void; onBlur: () => void; }; export function MPhoneInput(props: MPhoneInputProps) { const [init, setInit] = React.useState<boolean>(false); const [focus, setFocus] = React.useState<boolean>(false); const [raw, setRaw] = React.useState<PhoneRaw & { pretty: string, flag: any }>({ aa2: "", nn: "", code: 0, pretty: "", flag: "" }); function onChangeCountryCode(v: string, isReset?: boolean) { try { setRaw(vals => { const item = ({ ...vals, aa2: v, nn: isReset ? "" : vals.nn, code: aa3phone[props.code]?.countryCode, flag: aa3phone[props.code]?.flag, example: Phone.new().setRegions(props.regions).placeholder(v) }); item.pretty = Phone.new().prettyMaskWoc(item.aa2, item.nn); return item; }); } catch (error) { } }; function onChangeNn(v: string) { try { const value = String(v).replace(/\D/g, ""); setRaw(vals => { const item = { ...vals, nn: value }; item.pretty = Phone.new().prettyMaskWoc(item.aa2, item.nn); return item; }); } catch (error) { }; }; React.useEffect(() => { if (init) { const instance = Phone.new().setRegions(props.regions); const rawResponse = instance.parseRawInput(raw.aa2, raw.nn, props.phoneType); if (rawResponse) { const a = instance.formatRaw(rawResponse, props.noPlusPrefix); props.onChange(a); } else if (props.onChange) { props.onChange(""); }; }; }, [init, focus, raw, props.regions?.length]); React.useEffect(() => { if (init && !focus) { const rawResponse = Phone.new().setRegions(props.regions).parseRaw(props.value, props.phoneType); if (rawResponse) { const item: PhoneRaw & { pretty: string, flag: any } = { ...rawResponse, pretty: "", flag: aa3phone[rawResponse.aa2]?.flag }; item.pretty = Phone.new().prettyMaskWoc(rawResponse.aa2, raw.nn); setRaw(item); } else { onChangeCountryCode(props.code); }; if (rawResponse?.nn == raw?.nn && props.code !== raw.aa2) { onChangeCountryCode(props.code, true); }; } }, [init, focus, props.code, props.value]); React.useEffect(() => { setInit(true); }, []); return (<View style={[{ flex: 1, height: 45, maxHeight: 45, display: "flex", flexDirection: "row", borderWidth: 1, borderColor: "#dadce0" }, props.containerStyle]}><TouchableHighlight style={{ flex: 1, maxWidth: 55, display: "flex", justifyContent: "center", alignItems: "center", borderRightWidth: 1, borderRightColor: "#dadce0", backgroundColor: "white" }} onPress={() => props.onChangeCountry(Phone.new().setRegions(props.regions).supportsIat2.map(k => k.aa2), raw.aa2)}><MText style={{ textAlign: "center", fontSize: 23 }}>{raw.flag || "🏁"}</MText> </TouchableHighlight> <View style={{ flex: 1, maxWidth: 55, padding: 5, display: "flex", justifyContent: "center", alignItems: "center", backgroundColor: "white", borderRightWidth: 1, borderRightColor: "#dadce0" }}> <MText style={{ color: "black", textAlign: "center", padding: 5, fontWeight: "500" }}> +{raw?.code} </MText> </View> <MTextInput style={[{ flex: 1, color: "black", borderWidth: 0, borderRadius: 0, minHeight: 43, height: 43 }, props.phoneStyle]} value={raw.pretty} autoFocus={false} maxLength={Phone.new().prettyMaskWoc(raw.aa2, raw.example)?.length} placeholder={props.placeholder} onChangeText={onChangeNn} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} /></View>); }
|
package/src/Press.tsx
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React, { ReactNode } from "react"; import { Pressable, PressableProps } from "react-native";
|
|
2
|
+
interface MPressProps extends PressableProps { children: ReactNode; }; export function MPress({ children, ...props }: MPressProps) { return (<Pressable {...props}>{children}</Pressable>) }
|
package/src/Radio.tsx
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React, { ReactNode } from "react"; import { TextStyle, TouchableHighlight, TouchableHighlightProps, View } from "react-native"; import { MText } from "./Text";
|
|
2
|
+
interface MRadioProps extends TouchableHighlightProps { name?: string; activeValue?: string | number | boolean; value: string | number | boolean; size?: number; color: string; label?: string; labelStyle?: TextStyle; onChange?: (values: string | number | boolean, checked: boolean, name?: string) => void; children?: ReactNode; }; export function MRadio({ name = "", activeValue, value, color, label, size = 26, labelStyle, style, onChange, ...props }: MRadioProps) { const checked = value == activeValue; return (<TouchableHighlight activeOpacity={0.85}{...props} onPress={() => { if (onChange) { onChange(checked ? "" : value, !checked, name); }; }} underlayColor="transparent" style={[{ flex: 1 }, style]}><View style={{ display: "flex", flexDirection: "row", alignItems: "center" }}><View style={{ padding: 4, width: size, height: size, borderRadius: size, borderWidth: 1, borderColor: color, backgroundColor: "white", display: "flex", justifyContent: "center", alignItems: "center" }}><View style={{ width: size - 8, height: size - 8, backgroundColor: checked ? color : "white", borderRadius: size }} /></View><MText style={[{ flex: 1, fontSize: 15, paddingLeft: 5 }, labelStyle]}>{label}</MText></View></TouchableHighlight>) }
|
package/src/Scroll.tsx
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React, { forwardRef, ReactNode } from "react"; import { RefreshControl, ScrollView, StyleProp, ViewStyle, ScrollViewProps } from "react-native"; export const styleMSVerticalCenter = { justifyContent: "center" } as any; interface MScrollProps extends ScrollViewProps { name?: string; contentContainerStyle?: StyleProp<ViewStyle>; isRefreshing?: boolean; onRefresh?: () => void; children?: ReactNode; }; export const MScroll = forwardRef<ScrollView, MScrollProps>(({ contentContainerStyle, onRefresh, isRefreshing, children, ...props }, ref) => { return (<ScrollView contentInsetAdjustmentBehavior="automatic" contentContainerStyle={{ flexGrow: 1, backgroundColor: "transparent", paddingBottom: 175, padding: 9, ...(contentContainerStyle || {}) as any }} refreshControl={(onRefresh ? (<RefreshControl refreshing={Boolean(isRefreshing)} onRefresh={onRefresh} />) : (<></>))}{...props} ref={ref}>{children}</ScrollView>) });
|
package/src/Tab.tsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React, { Fragment, ReactElement, ReactNode } from "react"; import { StyleProp, View, ViewStyle, PanResponder, Animated, Dimensions } from "react-native"; import { MButton } from "./Button"; import { MText } from "./Text";
|
|
2
|
+
interface IMTabButtonProps { testID?: string; size?: "xs" | "sm" | "md" | "nm"; noSizeLimit?: boolean; style?: StyleProp<ViewStyle>; label?: string; textAlign?: "center" | "left" | "right"; disabled?: boolean; outline?: boolean; noborder?: boolean; loading?: boolean; btnType?: "primary" | "success" | "warning" | "secondary" | "danger" | "light" | "navy" | "smokelight"; onPress?: () => void; children?: ReactNode; }; export function MTabButton({ children, btnType = "smokelight", style, size = "md", outline = true, ...props }: IMTabButtonProps) { return (<MButton btnType={btnType} size={size} outline={outline}{...props} style={[{ borderWidth: 1, borderColor: "#dadada" }, style]}>{children}</MButton>) };
|
|
3
|
+
export interface MCustomTabProps { value: string | number; active: boolean; disabled: boolean; onPress: (value: any) => void; }; interface MTabProps { value: string | number; tab: string | ((props: MCustomTabProps) => ReactNode); disabled?: boolean; isHidden?: boolean; render?: () => ReactNode; children?: ReactNode; }; export function MTab(props: MTabProps) { return (<>{props.children || props.render()}</>) };
|
|
4
|
+
interface TabContainerProps { testID?: string; tabStyle?: StyleProp<ViewStyle>; isTop: boolean; activeValue: string | number; onChange: (value: any) => void; items: Array<ReactElement<MTabProps>>; }; function TabContainer(props: TabContainerProps) { return (<View style={[{ width: "100%", display: "flex", flexDirection: "row", justifyContent: "space-around", alignItems: "center" }, props.tabStyle]}>{props.items.filter(k => k && !k.props.isHidden).map((item, index) => { const isActive = item.props.value === props.activeValue; return (<Fragment key={`${index}${props.activeValue}`}>{typeof item.props.tab === "string" ? (<MButton testID={props.testID} size="md" btnType={isActive ? "navy" : "light"} outline={isActive} disabled={item.props.disabled} style={{ backgroundColor: "transparent", flex: 1, borderRadius: 0, borderColor: null, borderWidth: 0, borderTopWidth: !props.isTop ? 2 : 0, borderBottomWidth: props.isTop ? 2 : 0, borderTopColor: !props.isTop && isActive ? undefined : "transparent", borderBottomColor: props.isTop && isActive ? undefined : "transparent", minHeight: 43, maxHeight: 43 }} onPress={() => props.onChange(item.props.value)}><MText style={{ color: "black", fontSize: 15 }}>{item.props.tab}</MText></MButton>) : (item.props.tab({ active: isActive, value: item.props.value, disabled: item.props.disabled, onPress: props.onChange }))}</Fragment>); })}</View>) };
|
|
5
|
+
interface MTabsProps { position?: "top" | "bottom"; tabStyle?: StyleProp<ViewStyle>; active: string | number; children: ReactElement<MTabProps> | Array<ReactElement<MTabProps>>; onChange: (value: any) => void; }; export function MTabs({ position = "top", ...props }: MTabsProps) { const fadeAnim = React.useRef(new Animated.Value(0, { useNativeDriver: true })).current; const children = Array.isArray(props.children) ? props.children : [props.children]; const activeIndex = React.useMemo(() => { return children.findIndex(k => k.props.value === props.active); }, [props.active]); const panResponder = React.useMemo(() => { fadeAnim.setValue(0); return PanResponder.create({ onMoveShouldSetPanResponder(_e1, gestureState) { if ((Math.abs(gestureState.dx) > (Dimensions.get("window").width / 2.5)) && (Math.abs(gestureState.dx) > Math.abs(gestureState.dy * 3.5)) && (Math.abs(gestureState.vx) > Math.abs(gestureState.vy * 2.5))) { if (gestureState.dx > 0 && activeIndex > 0) { props.onChange(children[activeIndex - 1].props.value); return true; }; if (gestureState.dx < 0 && activeIndex < children.length - 1) { props.onChange(children[activeIndex + 1].props.value); return true; }; }; if ((gestureState.dx > 0 && activeIndex > 0) || (gestureState.dx < 0 && activeIndex < children.length - 1)) { fadeAnim.setValue(gestureState.dx); }; return true; }, onPanResponderRelease(_e1, _g1) { fadeAnim.setValue(0); }, onPanResponderTerminate() { } }); }, [activeIndex]); return (<View style={{ flex: 1, display: "flex", flexDirection: "column" }} {...panResponder.panHandlers} onTouchEnd={() => { fadeAnim.setValue(0); }}>{position === "top" ? <TabContainer isTop={true} activeValue={props.active} tabStyle={props.tabStyle} items={children} onChange={props.onChange} /> : <></>}<Animated.View style={{ flex: 1, transform: [{ translateX: fadeAnim }] }}>{children[activeIndex]?.props?.children || children[activeIndex]?.props?.render()}</Animated.View>{position === "bottom" ? <TabContainer isTop={false} activeValue={props.active} tabStyle={props.tabStyle} items={children} onChange={props.onChange} /> : <></>}</View>) }
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
class MTabButtonBaseProps { testID?: string; value: string | number; disabled?: boolean; label: string; style?: StyleProp<ViewStyle>; }; class MTabButtonProps extends MTabButtonBaseProps { activeValue?: string | number; onChange?: (value: any) => void; }; export function MTabControlButton(props: MTabButtonProps) { const isActive = props.value === props.activeValue; return (<MButton testID={props.testID} btnType={isActive ? "navy" : "light"} disabled={props.disabled} style={[{ borderRadius: 0, borderWidth: 1, borderColor: "#fafafa" }, props.style]} onPress={() => props.onChange(props.value)}><MText style={{ color: isActive ? "white" : "black", fontSize: 15 }}>{props.label}</MText></MButton>) };
|
|
10
|
+
interface MTabContollerProps { active: string | number; style?: StyleProp<ViewStyle>; children: Array<ReactElement<MTabButtonBaseProps | ReactNode>>; onChange: (value: any) => void; }; export function MTabContoller(props: MTabContollerProps) { return (<View style={[{ width: "100%", display: "flex", flexDirection: "row", justifyContent: "space-evenly", alignItems: "center" }, props.style]}>{props.children.map((k, index) => { if (k.type["name"] === "MTabControlButton") { return (<MTabControlButton key={index}{...k.props as any} activeValue={props.active} onChange={(value) => { props.onChange(value); if (k.props["onChange"]) { k.props["onChange"](value); } }} />) } else { return k; } })}</View>) }
|
|
11
|
+
interface MTabContentProps { value: string | number; style?: StyleProp<ViewStyle>; children: ReactNode; }; export function MTabContent(props: MTabContentProps) { return (<View style={[{ flex: 1 }, props.style]}>{props.children}</View>) };
|
|
12
|
+
interface MTabContentsProps { active: string | number; children: Array<ReactElement<MTabContentProps>>; }; export function MTabContents(props: MTabContentsProps) { return (<>{props.children?.find(k => k.props.value === props.active)}</>) };
|
|
13
|
+
interface MTabContainerProps { style?: StyleProp<ViewStyle>; children: [ReactElement<MTabContollerProps>, ReactElement<MTabContentsProps>]; }; export function MTabContainer(props: MTabContainerProps) { return (<View style={[{ flex: 1, display: "flex", flexDirection: "column" }, props.style]}>{props.children}</View>) };
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
<MTabContainer>
|
|
17
|
+
<MTabContoller active={tab} onChange={setTab}>
|
|
18
|
+
<MTabControlButton value={ORDER_GROUP_TYPE.PENDING} label="Paketlerim" />
|
|
19
|
+
<MTabControlButton value={ORDER_GROUP_TYPE.DELIVERED} label="Teslim-İptal" />
|
|
20
|
+
<MTabControlButton value={ORDER_GROUP_TYPE.ACCEPTED} label="Aktifler" />
|
|
21
|
+
<MButton color="light" onPress={()=> {}} style={{maxWidth: 41}}>
|
|
22
|
+
|
|
23
|
+
</MButton>
|
|
24
|
+
</MTabContoller>
|
|
25
|
+
|
|
26
|
+
<MTabContents active={tab}>
|
|
27
|
+
<MTabContent value={ORDER_GROUP_TYPE.PENDING}>
|
|
28
|
+
<MText style={{ color: "black" }}>{ORDER_GROUP_TYPE.PENDING}</MText>
|
|
29
|
+
</MTabContent>
|
|
30
|
+
|
|
31
|
+
<MTabContent value={ORDER_GROUP_TYPE.DELIVERED}>
|
|
32
|
+
<MText style={{ color: "black" }}>{ORDER_GROUP_TYPE.DELIVERED}</MText>
|
|
33
|
+
</MTabContent>
|
|
34
|
+
|
|
35
|
+
<MTabContent value={ORDER_GROUP_TYPE.ACCEPTED}>
|
|
36
|
+
<MText style={{ color: "black" }}>{ORDER_GROUP_TYPE.ACCEPTED}</MText>
|
|
37
|
+
</MTabContent>
|
|
38
|
+
</MTabContents>
|
|
39
|
+
</MTabContainer>
|
|
40
|
+
*/
|
package/src/Text.tsx
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from "react"; import { Text, TextProps } from "react-native"; interface MTextProps extends TextProps { }; export function lineHeight(fontSize) { const multiplier = (fontSize > 20) ? 1.5 : 1; return parseInt(fontSize + (fontSize * multiplier), 10); }; export const MText = React.forwardRef<Text, MTextProps>((props, ref) => { return (<Text ref={ref} {...props} style={[{ fontSize: 15, letterSpacing: 0.65 }, props.style]}>{props.children}</Text>) })
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { StyleSheet, TextInput, TextInputProps } from "react-native";
|
|
2
|
+
const styleOTI = StyleSheet.create({
|
|
3
|
+
txtInput: {
|
|
4
|
+
flex: 1,
|
|
5
|
+
height: 45,
|
|
6
|
+
minHeight: 45,
|
|
7
|
+
maxHeight: 45,
|
|
8
|
+
borderStyle: "solid",
|
|
9
|
+
zIndex: 101,
|
|
10
|
+
backgroundColor: "white",
|
|
11
|
+
color: "black",
|
|
12
|
+
borderRadius: 3,
|
|
13
|
+
fontSize: 16.25,
|
|
14
|
+
paddingHorizontal: 11,
|
|
15
|
+
paddingVertical: 5,
|
|
16
|
+
borderWidth: 1,
|
|
17
|
+
borderColor: "#dadce0",
|
|
18
|
+
letterSpacing: 1
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
interface ITextInputProps extends TextInputProps { }; export function MTextInput({ style, ...props }: ITextInputProps) { return (<TextInput autoCapitalize="none" autoFocus={false}{...props} style={[styleOTI.txtInput, { backgroundColor: props.editable == false ? "#f7f7f7" : "white" }, style]} placeholderTextColor="#919191" />) };
|
|
22
|
+
export function MTextareaInput({ style, ...props }: ITextInputProps) { return (<TextInput autoCapitalize="none" numberOfLines={4} multiline={true} editable={true} autoFocus={false}{...props} style={[styleOTI.txtInput, { height: null, maxHeight: null, backgroundColor: props.editable == false ? "#f7f7f7" : "white" }, style]} placeholderTextColor="#919191" />) };
|