فهرست منبع

Feature: LocaleSwitcher component added.

lfabl 1 ماه پیش
والد
کامیت
9b45576d41

+ 77 - 0
src/assets/svg/enUSIcon/index.tsx

@@ -0,0 +1,77 @@
+import type {
+    INCoreUIKitIconProps
+} from "../../../types";
+import {
+    Path,
+    Mask,
+    Svg,
+    G
+} from "react-native-svg";
+
+const EnUsIcon = ({
+    size = 32,
+    style,
+    ...props
+}: INCoreUIKitIconProps) => {
+    const pathScale = 32 / size;
+
+    return <Svg
+        height={size}
+        width={size}
+        style={{
+            ...style
+        }}
+        {...props}
+    >
+        <Mask
+            id="a"
+            maskUnits="userSpaceOnUse"
+            height={32}
+            width={32}
+            x={0}
+            y={0}
+            style={{
+                maskType: "luminance"
+            }}
+        >
+            <Path
+                fill="#fff"
+                d="M16 32c8.837 0 16-7.163 16-16S24.837 0 16 0 0 7.163 0 16s7.163 16 16 16Z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+        </Mask>
+        <G mask="url(#a)">
+            <Path
+                fill="#EEE"
+                d="M16 0h16v4l-2 2 2 2v4l-2 2 2 2v4l-2 2 2 2v4l-16 2-16-2v-4l2-2-2-2v-4L16 0Z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+            <Path
+                fill="#D80027"
+                d="M14 4h18v4H14V4Zm0 8h18v4H16l-2-4ZM0 20h32v4H0v-4Zm0 8h32v4H0v-4Z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+            <Path
+                fill="#0052B4"
+                d="M0 0h16v16H0V0Z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+            <Path
+                fill="#EEE"
+                d="m11.688 15.188 3.562-2.563h-4.375l3.563 2.563L13.062 11l-1.374 4.188Zm-5.063 0 3.563-2.563H5.811l3.563 2.563L8 11l-1.375 4.188Zm-5.063 0 3.563-2.563H.75l3.563 2.563L2.938 11l-1.376 4.188Zm10.126-5.063 3.562-2.563h-4.375l3.563 2.563-1.376-4.188-1.374 4.188Zm-5.063 0 3.563-2.563H5.811l3.563 2.563L8 5.937l-1.375 4.188Zm-5.063 0 3.563-2.563H.75l3.563 2.563-1.375-4.188-1.376 4.188ZM11.688 5l3.562-2.563h-4.375L14.438 5 13.062.812 11.688 5ZM6.625 5l3.563-2.563H5.811L9.376 5 8 .812 6.625 5ZM1.562 5l3.563-2.563H.75L4.313 5 2.938.812 1.562 5Z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+        </G>
+    </Svg>;
+};
+export default EnUsIcon;

+ 8 - 0
src/assets/svg/index.ts

@@ -13,3 +13,11 @@ export {
 export {
     default as CayCoreIcon
 } from "./cayCoreIcon";
+
+export {
+    default as EnUsIcon
+} from "./enUSIcon";
+
+export {
+    default as TRTRIcon
+} from "./trTRIcon";

+ 47 - 0
src/assets/svg/trTRIcon/index.tsx

@@ -0,0 +1,47 @@
+import type {
+    INCoreUIKitIconProps
+} from "../../../types";
+import {
+    Path,
+    Svg
+} from "react-native-svg";
+
+const TRTRIcon = ({
+    size = 32,
+    style,
+    ...props
+}: INCoreUIKitIconProps) => {
+    const pathScale = 32 / size;
+
+    return <Svg
+        height={size}
+        width={size}
+        style={{
+            ...style
+        }}
+        {...props}
+    >
+        <Path
+            fill="#ED4C5C"
+            d="M16 32c8.837 0 16-7.163 16-16S24.837 0 16 0 0 7.163 0 16s7.163 16 16 16Z"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+        />
+        <Path
+            fill="#fff"
+            d="m20.96 19.734.053-2.88-2.88-.853 2.88-.853-.054-2.88 1.76 2.293 2.88-.853L23.84 16l1.76 2.293-2.88-.853-1.76 2.293Z"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+        />
+        <Path
+            fill="#fff"
+            d="M16.638 22.4c-3.52 0-6.346-2.88-6.346-6.4 0-3.52 2.826-6.4 6.346-6.4 1.334 0 2.56.427 3.627 1.12A7.901 7.901 0 0 0 14.292 8c-4.374 0-7.894 3.573-7.894 8s3.52 8 7.894 8c2.4 0 4.533-1.067 5.973-2.72a6.355 6.355 0 0 1-3.627 1.12Z"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+        />
+    </Svg>;
+};
+export default TRTRIcon;

+ 4 - 0
src/components/index.ts

@@ -186,6 +186,10 @@ export {
     default as HighlightButton
 } from "./highlightButton";
 
+export {
+    default as LocaleSwitcher
+} from "./localeSwitcher";
+
 export type {
     EnterMarkdownTypes,
     CodeMarkdownTypes,

+ 136 - 0
src/components/localeSwitcher/index.tsx

@@ -0,0 +1,136 @@
+import {
+    useEffect,
+    useState,
+    type FC
+} from "react";
+import type ILocaleSwitcherProps from "./type";
+import type {
+    LocaleSwitchVariants
+} from "./type";
+import {
+    NCoreUIKitLocalize
+} from "../../core/hooks";
+import type {
+    NCoreUIKitIcon
+} from "../../types";
+import Button from "../button";
+import {
+    EnUsIcon,
+    TRTRIcon
+} from "../../assets/svg";
+
+const PaletteSwitcher: FC<ILocaleSwitcherProps> = ({
+    variants: variantsProps = [],
+    isWorkWithNextShowSystem,
+    customLocalize,
+    color,
+    style,
+    ...props
+}) => {
+    const {
+        activeLocale,
+        localeKeys
+    } = NCoreUIKitLocalize.useContext(customLocalize);
+
+    const [
+        currentIndex,
+        setCurrentIndex
+    ] = useState(localeKeys.findIndex(t => t === activeLocale));
+
+    useEffect(() => {
+        const cI = localeKeys.findIndex(tI => tI === activeLocale);
+
+        const nextCI = isWorkWithNextShowSystem ? cI + 1 > localeKeys.length - 1 ? 0 : cI + 1 : cI;
+
+        if(currentIndex !== nextCI) {
+            setCurrentIndex(nextCI);
+        }
+    }, [activeLocale]);
+
+    const variantsPre: LocaleSwitchVariants = variantsProps;
+
+    const isHaveNCTRTR = variantsProps.findIndex(iV => iV.localeKey === "tr-TR") !== -1;
+    const isHaveNCENUS = variantsProps.findIndex(iV => iV.localeKey === "en-US") !== -1;
+
+    if(!isHaveNCTRTR) {
+        variantsPre.unshift({
+            borderColor: "transparent",
+            backgroundColor: "subtle",
+            iconColor: "turkish",
+            localeKey: "tr-TR",
+            icon: ({
+                size
+            }) => {
+                return <TRTRIcon
+                    size={size + 5}
+                />;
+            }
+        });
+    }
+
+    if(!isHaveNCENUS) {
+        variantsPre.unshift({
+            borderColor: "transparent",
+            backgroundColor: "subtle",
+            iconColor: "english",
+            localeKey: "en-US",
+            icon: ({
+                size
+            }) => {
+                return <EnUsIcon
+                    size={size + 5}
+                />;
+            }
+        });
+    }
+
+    const variants = [...variantsPre].sort((a, b) => {
+        return localeKeys.indexOf(a.localeKey) - localeKeys.indexOf(b.localeKey);
+    });
+
+    const currentVariantIndex = variants.findIndex(e => e.localeKey === activeLocale);
+
+    if(currentVariantIndex === -1) {
+        return null;
+    }
+
+    const nextVariantIndex = currentVariantIndex + 1;
+    const viewVariantIndex = nextVariantIndex > variants.length - 1 ? 0 : nextVariantIndex;
+
+    const currentVariant = variants[isWorkWithNextShowSystem ? viewVariantIndex : currentVariantIndex];
+
+    return <Button
+        {...props}
+        customBorderColor={currentVariant && currentVariant.borderColor ?
+            currentVariant.borderColor
+            :
+            color
+        }
+        customColor={currentVariant && currentVariant.backgroundColor ?
+            currentVariant.backgroundColor
+            :
+            color
+        }
+        icon={({
+            color,
+            size
+        }) => {
+            const Icon = currentVariant?.icon as NCoreUIKitIcon;
+
+            return <Icon
+                customColor={currentVariant && currentVariant.iconColor ? currentVariant.iconColor : undefined}
+                color={color}
+                size={size}
+            />;
+        }}
+        onPress={() => {
+            NCoreUIKitLocalize.switch({
+                localeKey: localeKeys[viewVariantIndex] as keyof NCoreUIKit.LocaleKey
+            });
+        }}
+        style={[
+            style
+        ]}
+    />;
+};
+export default PaletteSwitcher;

+ 31 - 0
src/components/localeSwitcher/type.ts

@@ -0,0 +1,31 @@
+import {
+    type TextStyle,
+    type StyleProp
+} from "react-native";
+import type {
+    NCoreUIKitIcon
+} from "../../types";
+import type IButtonProps from "../button/type";
+
+export type LocaleSwitchVariant = {
+    backgroundColor: keyof NCoreUIKit.ContainerContentColors | "transparent";
+    borderColor: keyof NCoreUIKit.BorderContentColors | "transparent";
+    iconColor: keyof NCoreUIKit.ProjectColorPalette;
+    localeKey: keyof NCoreUIKit.LocaleKey;
+    icon: NCoreUIKitIcon;
+};
+
+export type LocaleSwitchVariants = Array<LocaleSwitchVariant>;
+
+interface ILocaleSwitcherProps extends Omit<IButtonProps, "onPress"> {
+    color?: keyof NCoreUIKit.ContainerContentColors | "transparent";
+    style?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
+    customLocalize?: {
+        activeLocale?: keyof NCoreUIKit.LocaleKey;
+    };
+    isWorkWithNextShowSystem?: boolean;
+    variants?: LocaleSwitchVariants;
+}
+export type {
+    ILocaleSwitcherProps as default
+};

+ 9 - 1
src/context/localize.tsx

@@ -66,7 +66,8 @@ class NCoreUIKitLocalize<T extends LocalizeType> extends NCoreContext<LocalizeCo
             localize: () => "Localization is loading...",
             translations: initialLanguage.translations,
             rruleConfig: initialLanguage.rruleConfig,
-            isRTL: initialLanguage.isRTL
+            isRTL: initialLanguage.isRTL,
+            localeKeys: []
         }, {
             key: "NCoreUIKitLocalize"
         });
@@ -88,6 +89,7 @@ class NCoreUIKitLocalize<T extends LocalizeType> extends NCoreContext<LocalizeCo
         const defaultLocale = defaultLocalesData.find(l => l.locale === locale) ?? defaultLocalesData[0]!;
 
         const defaultState: LocalizeContextStateType = {
+            localeKeys: defaultLocalesData.map(lDI => lDI.locale) as Array<keyof NCoreUIKit.LocaleKey>,
             activeLocale: defaultLocale.locale as keyof NCoreUIKit.LocaleKey,
             // localizeWithObject: this.localizeWithObject,
             translations: defaultLocale.translations,
@@ -106,8 +108,14 @@ class NCoreUIKitLocalize<T extends LocalizeType> extends NCoreContext<LocalizeCo
             return defaultState;
         }
 
+        const dLKeys = [...new Set([
+            ...defaultLocalesData.map(p => p.locale),
+            ...this.projectLocales.map(p => p.locale)
+        ])];
+
         const newState: LocalizeContextStateType = {
             activeLocale: currentProjectLocale.locale as keyof NCoreUIKit.LocaleKey,
+            localeKeys: dLKeys as Array<keyof NCoreUIKit.LocaleKey>,
             // localizeWithObject: this.localizeWithObject,
             rruleConfig: {
                 ...defaultLocale.rruleConfig,

+ 4 - 1
src/index.tsx

@@ -21,6 +21,7 @@ export {
     PaletteSwitcher,
     MarkdownViewer,
     DateTimePicker,
+    LocaleSwitcher,
     PageContainer,
     DateTimeSheet,
     TextAreaInput,
@@ -105,7 +106,9 @@ export {
     NIBGATCommunityIcon,
     CayCoreIcon,
     LoadingIcon,
-    NIBGATIcon
+    NIBGATIcon,
+    TRTRIcon,
+    EnUsIcon
 } from "./assets/svg";
 
 export type {

+ 1 - 0
src/types/locale.ts

@@ -15,6 +15,7 @@ export type LocalizeContextStateType = Partial<LocalizeContextType>;
 
 export type LocalizeContextType = {
     rruleConfig: NCoreUIKit.GeneratedRRuleConfigsForReturn;
+    localeKeys: Array<keyof NCoreUIKit.LocaleKey>;
     translations: NCoreUIKit.Translation;
     localizeWithObject: (
         translation: keyof NCoreUIKit.Translation,

+ 12 - 0
src/variants/themes/default.json

@@ -484,6 +484,8 @@
                         }
                     },
                     "project": {
+                        "english": "#3333FF",
+                        "turkish": "#FF5555",
                         "moon": "#0F5792",
                         "sun": "#C09E13"
                     }
@@ -685,6 +687,8 @@
                         }
                     },
                     "project": {
+                        "english": "#2222FF",
+                        "turkish": "#FF3333",
                         "moon": "#54A7EB",
                         "sun": "#FFCF11"
                     }
@@ -879,6 +883,8 @@
                         }
                     },
                     "project": {
+                        "english": "#3333FF",
+                        "turkish": "#FF5555",
                         "moon": "#6D5BFF",
                         "sun": "#FFD36A"
                     }
@@ -1068,6 +1074,8 @@
                         }
                     },
                     "project": {
+                        "english": "#2222FF",
+                        "turkish": "#FF3333",
                         "moon": "#54A7EB",
                         "sun": "#FFCF11"
                     }
@@ -1262,6 +1270,8 @@
                         }
                     },
                     "project": {
+                        "english": "#3333FF",
+                        "turkish": "#FF5555",
                         "moon": "#FF4D4D",
                         "sun": "#FFFFFF"
                     }
@@ -1451,6 +1461,8 @@
                         }
                     },
                     "project": {
+                        "english": "#2222FF",
+                        "turkish": "#FF3333",
                         "moon": "#FF4D4D",
                         "sun": "#FFFFFF"
                     }