Bladeren bron

Feature: General fixes and Button page added.

lfabl 3 weken geleden
bovenliggende
commit
3a3208773c

+ 15 - 0
.agents/AGENTS.md

@@ -0,0 +1,15 @@
+# Coding & Formatting Rules
+
+The user expects strict adherence to the following coding, formatting, and behavioral rules in this repository:
+
+## General Formatting
+1. **Double Quotes:** Use double quotes (`"`) instead of single quotes for all strings and imports.
+2. **Sort by Length:** Sort arrays, JSON object keys, object properties, and import statements from **longest to shortest string length** (uzundan kısaya). This is a strict visual aesthetic preference.
+3. **Line Breaks (Newlines):** Pay attention to line breaks. Add new lines between imports and JSON object keys where appropriate. ESLint rules regarding newlines must be strictly followed.
+
+## Tooling & Checks
+1. **ESLint Validation:** Habitually run `yarn run eslint --fix <file>` or `yarn run eslint <file>` after making code edits to ensure strict ESLint compliance.
+2. **TypeScript Validation:** Habitually check and respect TypeScript compiler errors (e.g., using `tsc` or IDE feedback). Do not ignore `any` or strict typing constraints.
+
+## Behavior
+Always follow these rules by default. Pay "extreme attention" (aşırı dikkat) to the sorting rules, ESLint, and TS constraints during modifications.

+ 49 - 5
example/src/index.tsx

@@ -1,3 +1,6 @@
+import {
+    Platform
+} from "react-native";
 import Navigation from "./navigation";
 import defaultLocaleJSON from "./variants/locales/default.json";
 import defaultThemeJSON from "./variants/themes/default.json";
@@ -7,16 +10,57 @@ import {
 import moment from "moment";
 import "moment/locale/tr";
 import {
-    Host,
-    setupNCoreUIKit
+    type NCoreUIKitConfig,
+    setupNCoreUIKit,
+    Host
 } from "ncore-ui-kit";
 
-const NCoreUIKitBase = setupNCoreUIKit({
+let NCoreConfig: NCoreUIKitConfig = {
+    projectThemes: defaultThemeJSON as NCoreUIKit.Palette,
     initialSelectedGapPropagation: "spacious",
     projectLocales: defaultLocaleJSON,
-    projectThemes: defaultThemeJSON,
+    initialSelectedPalette: "nibgat",
     initialSelectedTheme: "light"
-});
+};
+
+const themeStorage = Platform.OS === "web" ? window.localStorage.getItem("theme") : null;
+
+if(themeStorage) {
+    const parsedThemeStorage = JSON.parse(themeStorage);
+
+    NCoreConfig = {
+        ...NCoreConfig,
+        initialSelectedGapPropagation: parsedThemeStorage.activeGapPropagation,
+        initialSelectedActiveSharpness: parsedThemeStorage.activeSharpness,
+        initialSelectedTheme: parsedThemeStorage.activeTheme
+    };
+}
+
+const localeStorage = Platform.OS === "web" ? window.localStorage.getItem("locale") : null;
+
+if(localeStorage) {
+    const parsedLocaleStorage = JSON.parse(localeStorage);
+
+    NCoreConfig = {
+        ...NCoreConfig,
+        initialSelectedLocale: parsedLocaleStorage.activeLocale
+    };
+}
+
+if (Platform.OS === "web") {
+    const urlParams = new URLSearchParams(window.location.search);
+    const langParam = urlParams.get("lang");
+
+    if (langParam) {
+        const isValidLocale = defaultLocaleJSON.some(item => item.locale === langParam);
+
+        if (isValidLocale) {
+            NCoreConfig.initialSelectedLocale = langParam as keyof NCoreUIKit.LocaleKey;
+        }
+    }
+}
+
+const NCoreUIKitBase = setupNCoreUIKit(NCoreConfig);
 
 moment.locale("tr");
 

+ 31 - 7
example/src/navigation/index.tsx

@@ -10,12 +10,15 @@ import {
     NCoreUIKitEmbeddedMenu,
     NCoreUIKitLocalize,
     NCoreUIKitTheme,
+    PaletteSwitcher,
+    LocaleSwitcher,
     ThemeSwitcher,
     MainHeader
 } from "ncore-ui-kit";
 import {
+    type LinkingOptions,
     NavigationContainer,
-    useNavigation
+    useNavigation,
 } from "@react-navigation/native";
 import {
     type NativeStackNavigationProp,
@@ -52,7 +55,9 @@ const ComponentsNav = () => {
 
 const RootNav = () => {
     const {
-        colors
+        activeTheme,
+        colors,
+        spaces
     } = NCoreUIKitTheme.useContext();
 
     const {
@@ -110,6 +115,7 @@ const RootNav = () => {
             id: "main-menu"
         });
 
+        NCoreUIKitLocalize.addEventListener("state", updateLocaleStorage);
         NCoreUIKitEmbeddedMenu.addEventListener("state", updateStorage);
         NCoreUIKitTheme.addEventListener("state", updateThemeStorage);
     }, []);
@@ -128,12 +134,22 @@ const RootNav = () => {
         }
     };
 
+    const updateLocaleStorage = () => {
+        if(Platform.OS === "web") {
+            const localeData = NCoreUIKitLocalize.state;
+
+            if(localeData) {
+                window.localStorage.setItem("locale", JSON.stringify(localeData));
+            }
+        }
+    };
+
     const updateThemeStorage = () => {
         if(Platform.OS === "web") {
             const themeData = NCoreUIKitTheme.state;
 
             if(themeData) {
-                window.localStorage.setItem("theme", String(themeData));
+                window.localStorage.setItem("theme", JSON.stringify(themeData));
             }
         }
     };
@@ -141,7 +157,7 @@ const RootNav = () => {
     return <MainHeader
         isWorkWithSeperator={true}
         siteLogoProps={{
-            imageUrl: "http://ncore.nibgat.space/assets/images/ncorelogo.png",
+            imageUrl: activeTheme.indexOf("dark") !== -1 ? "http://ncore.nibgat.space/assets/images/darklogo.png" : "http://ncore.nibgat.space/assets/images/ncorelogo.png",
             onPress: () => {
                 navigation.navigate("Home");
             },
@@ -158,10 +174,13 @@ const RootNav = () => {
             return <View
                 style={{
                     justifyContent: "center",
+                    gap: spaces.spacingMd,
                     flexDirection: "row",
                     alignItems: "center"
                 }}
             >
+                <LocaleSwitcher/>
+                <PaletteSwitcher/>
                 <ThemeSwitcher/>
             </View>;
         }}
@@ -200,11 +219,16 @@ const Navigation = () => {
             config: {
                 screens: {
                     Home: "",
-                    Text: "text",
-                    button: "button"
+                    Components: {
+                        path: "Components",
+                        screens: {
+                            Button: "button",
+                            Text: "text"
+                        }
+                    }
                 }
             }
-        }}
+        } as LinkingOptions<RootStackParamList>}
     >
         <RootNav/>
     </NavigationContainer>;

+ 10 - 2
example/src/navigation/type.ts

@@ -1,9 +1,17 @@
-type RootStackParamList = {
+import type {
+    NavigatorScreenParams
+} from "@react-navigation/native";
+
+export type ComponentsStackParamList = {
     Button: undefined;
-    Home: undefined;
     Text: undefined;
 };
 
+type RootStackParamList = {
+    Components: NavigatorScreenParams<ComponentsStackParamList>;
+    Home: undefined;
+};
+
 export type {
     RootStackParamList as default
 };

+ 162 - 82
example/src/pages/button/index.tsx

@@ -3,7 +3,6 @@ import {
     useState
 } from "react";
 import {
-    ScrollView,
     View
 } from "react-native";
 import stylesheet from "./stylesheet";
@@ -12,8 +11,10 @@ import {
     type IButtonProps,
     NCoreUIKitTheme,
     PageContainer,
+    SelectBox,
     TextInput,
     Button,
+    Switch,
     Header
 } from "ncore-ui-kit";
 import {
@@ -54,6 +55,21 @@ const BUTTON_SIZES: Array<IButtonProps["size"]> = [
     "large"
 ];
 
+const BUTTON_TYPES_DATA = BUTTON_TYPES.map(item => ({
+    __key: item as string,
+    __title: item as string
+}));
+
+const BUTTON_VARIANTS_DATA = BUTTON_VARIANTS.map(item => ({
+    __key: item as string,
+    __title: item as string
+}));
+
+const BUTTON_SIZES_DATA = BUTTON_SIZES.map(item => ({
+    __key: item as string,
+    __title: item as string
+}));
+
 const ButtonPage = () => {
     const {
         radiuses,
@@ -68,17 +84,55 @@ const ButtonPage = () => {
 
     const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
 
-    const [typeIndex, setTypeIndex] = useState<number>(0);
-    const [spreadIndex, setSpreadIndex] = useState<number>(0);
-    const [variantIndex, setVariantIndex] = useState<number>(0);
-    const [sizeIndex, setSizeIndex] = useState<number>(1);
-    const [title, setTitle] = useState<string>("");
+    const [
+        typeIndex,
+        setTypeIndex
+    ] = useState<number>(0);
+
+    const [
+        spreadIndex,
+        setSpreadIndex
+    ] = useState<number>(0);
+
+    const [
+        variantIndex,
+        setVariantIndex
+    ] = useState<number>(0);
+
+    const [
+        sizeIndex,
+        setSizeIndex
+    ] = useState<number>(1);
+
+    const [
+        title,
+        setTitle
+    ] = useState<string>("");
+
+    const [
+        isLoading,
+        setIsLoading
+    ] = useState<boolean>(false);
+
+    const [
+        isDisabled,
+        setIsDisabled
+    ] = useState<boolean>(false);
+
+    const [
+        isCustomPadding,
+        setIsCustomPadding
+    ] = useState<boolean>(false);
+
+    const [
+        showIcon,
+        setShowIcon
+    ] = useState<boolean>(false);
 
-    const [isLoading, setIsLoading] = useState<boolean>(false);
-    const [isDisabled, setIsDisabled] = useState<boolean>(false);
-    const [isCustomPadding, setIsCustomPadding] = useState<boolean>(false);
-    const [showIcon, setShowIcon] = useState<boolean>(false);
-    const [iconDirection, setIconDirection] = useState<"left" | "right">("left");
+    const [
+        iconDirection,
+        setIconDirection
+    ] = useState<"left" | "right">("left");
 
     useLayoutEffect(() => {
         navigation.setOptions({
@@ -94,8 +148,11 @@ const ButtonPage = () => {
 
     return <PageContainer
         isWorkWithHeaderSpace={false}
-        isScrollable={false}
-        style={[
+        isScrollable={true}
+        scrollViewProps={{
+            contentContainerStyle: stylesheet.scrollContent
+        }}
+        scrollViewStyle={[
             stylesheet.container
         ]}
     >
@@ -118,8 +175,8 @@ const ButtonPage = () => {
             >
                 <Button
                     spreadBehaviour={BUTTON_SPREAD_BEHAVIOURS[spreadIndex]}
+                    title={title || localize("example-button")}
                     variant={BUTTON_VARIANTS[variantIndex]}
-                    title={title || "Example Button"}
                     isCustomPadding={isCustomPadding}
                     type={BUTTON_TYPES[typeIndex]}
                     size={BUTTON_SIZES[sizeIndex]}
@@ -141,10 +198,10 @@ const ButtonPage = () => {
                 />
             </View>
             <TextInput
+                placeholder={localize("enter-text")}
+                title={localize("button-title")}
                 spreadBehaviour="stretch"
-                placeholder="Enter text"
                 onChangeText={setTitle}
-                title="Button Title"
                 value={title}
                 style={{
                     marginBottom: spaces.spacingMd
@@ -152,93 +209,116 @@ const ButtonPage = () => {
             />
             <View
                 style={{
+                    justifyContent: "space-between",
                     gap: spaces.spacingMd,
                     flexDirection: "row",
                     flexWrap: "wrap",
                     width: "100%"
                 }}
             >
-                <Button
-                    title={`Change Type: ${BUTTON_TYPES[typeIndex]}`}
-                    spreadBehaviour="free"
-                    variant="outline"
-                    size="small"
-                    onPress={() => {
-                        setTypeIndex((typeIndex + 1) % BUTTON_TYPES.length);
-                    }}
-                />
-                <Button
-                    title={`Change Variant: ${BUTTON_VARIANTS[variantIndex]}`}
-                    spreadBehaviour="free"
-                    variant="outline"
-                    size="small"
-                    onPress={() => {
-                        setVariantIndex((variantIndex + 1) % BUTTON_VARIANTS.length);
-                    }}
-                />
-                <Button
-                    title={`Change Spread: ${BUTTON_SPREAD_BEHAVIOURS[spreadIndex]}`}
+                <SelectBox
+                    initialSelectedItems={BUTTON_TYPES_DATA[typeIndex] ? [
+                        BUTTON_TYPES_DATA[typeIndex]
+                    ] : []}
+                    titleExtractor={(item) => item.__title}
+                    keyExtractor={(item) => item.__key}
+                    title={localize("change-type")}
                     spreadBehaviour="free"
-                    variant="outline"
-                    size="small"
-                    onPress={() => {
-                        setSpreadIndex((spreadIndex + 1) % BUTTON_SPREAD_BEHAVIOURS.length);
+                    data={BUTTON_TYPES_DATA}
+                    onChange={(selectedItems) => {
+                        if (selectedItems.length > 0) {
+                            const index = BUTTON_TYPES.indexOf(selectedItems[0]!.__key as IButtonProps["type"]);
+                            if (index !== -1) setTypeIndex(index);
+                        }
                     }}
                 />
-                <Button
-                    title={`Change Size: ${BUTTON_SIZES[sizeIndex]}`}
+                <SelectBox
+                    initialSelectedItems={BUTTON_VARIANTS_DATA[variantIndex] ? [
+                        BUTTON_VARIANTS_DATA[variantIndex]
+                    ] : []}
+                    titleExtractor={(item) => item.__title}
+                    keyExtractor={(item) => item.__key}
+                    title={localize("change-variant")}
+                    data={BUTTON_VARIANTS_DATA}
                     spreadBehaviour="free"
-                    variant="outline"
-                    size="small"
-                    onPress={() => {
-                        setSizeIndex((sizeIndex + 1) % BUTTON_SIZES.length);
+                    onChange={(selectedItems) => {
+                        if (selectedItems.length > 0) {
+                            const index = BUTTON_VARIANTS.indexOf(selectedItems[0]!.__key as IButtonProps["variant"]);
+                            if (index !== -1) setVariantIndex(index);
+                        }
                     }}
                 />
                 <Button
-                    title={`Toggle Icon: ${showIcon ? "ON" : "OFF"}`}
-                    variant={showIcon ? "filled" : "outline"}
+                    title={`${localize("change-spread")}: ${BUTTON_SPREAD_BEHAVIOURS[spreadIndex]}`}
+                    verticalLocationForStretchFix="center"
+                    isFixVerticalStretch={true}
                     spreadBehaviour="free"
-                    size="small"
                     onPress={() => {
-                        setShowIcon(!showIcon);
+                        setSpreadIndex(prev => prev + 1 > BUTTON_SPREAD_BEHAVIOURS.length - 1 ? 0 : prev + 1);
                     }}
                 />
-                <Button
-                    title={`Toggle Icon Direction: ${iconDirection}`}
+                <SelectBox
+                    initialSelectedItems={BUTTON_SIZES_DATA[sizeIndex] ? [
+                        BUTTON_SIZES_DATA[sizeIndex]
+                    ] : []}
+                    titleExtractor={(item) => item.__title}
+                    keyExtractor={(item) => item.__key}
+                    title={localize("change-size")}
                     spreadBehaviour="free"
-                    variant="outline"
-                    size="small"
-                    onPress={() => {
-                        setIconDirection(iconDirection === "left" ? "right" : "left");
-                    }}
-                />
-                <Button
-                    title={`Toggle Loading: ${isLoading ? "ON" : "OFF"}`}
-                    variant={isLoading ? "filled" : "outline"}
-                    spreadBehaviour="free"
-                    size="small"
-                    onPress={() => {
-                        setIsLoading(!isLoading);
+                    data={BUTTON_SIZES_DATA}
+                    onChange={(selectedItems) => {
+                        if (selectedItems.length > 0) {
+                            const index = BUTTON_SIZES.indexOf(selectedItems[0]!.__key as IButtonProps["size"]);
+                            if (index !== -1) setSizeIndex(index);
+                        }
                     }}
                 />
-                <Button
-                    title={`Toggle Disabled: ${isDisabled ? "ON" : "OFF"}`}
-                    variant={isDisabled ? "filled" : "outline"}
-                    spreadBehaviour="free"
-                    size="small"
-                    onPress={() => {
-                        setIsDisabled(!isDisabled);
-                    }}
-                />
-                <Button
-                    title={`Toggle Custom Padding: ${isCustomPadding ? "ON" : "OFF"}`}
-                    variant={isCustomPadding ? "filled" : "outline"}
-                    spreadBehaviour="free"
-                    size="small"
-                    onPress={() => {
-                        setIsCustomPadding(!isCustomPadding);
+                <View
+                    style={{
+                        justifyContent: "space-between",
+                        flexDirection: "row",
+                        alignItems: "center",
+                        flexWrap: "wrap",
+                        width: "100%"
                     }}
-                />
+                >
+                    <Switch
+                        title={localize("toggle-icon-direction")}
+                        isActive={iconDirection === "right"}
+                        subTitle={localize(iconDirection)}
+                        onPress={() => {
+                            setIconDirection(iconDirection === "left" ? "right" : "left");
+                        }}
+                    />
+                    <Switch
+                        title={localize("toggle-icon")}
+                        isActive={showIcon}
+                        onPress={() => {
+                            setShowIcon(!showIcon);
+                        }}
+                    />
+                    <Switch
+                        title={localize("toggle-loading")}
+                        isActive={isLoading}
+                        onPress={() => {
+                            setIsLoading(!isLoading);
+                        }}
+                    />
+                    <Switch
+                        title={localize("toggle-disabled")}
+                        isActive={isDisabled}
+                        onPress={() => {
+                            setIsDisabled(!isDisabled);
+                        }}
+                    />
+                    <Switch
+                        title={localize("toggle-custom-padding")}
+                        isActive={isCustomPadding}
+                        onPress={() => {
+                            setIsCustomPadding(!isCustomPadding);
+                        }}
+                    />
+                </View>
             </View>
         </View>
     </PageContainer>;

+ 4 - 1
example/src/pages/button/stylesheet.ts

@@ -4,12 +4,15 @@ import {
 
 const stylesheet = StyleSheet.create({
     container: {
-        alignItems: "center",
         flex: 1
     },
     contentContainer: {
         maxWidth: 850,
         width: "100%"
+    },
+    scrollContent: {
+        justifyContent: "center",
+        alignItems: "center"
     }
 });
 export default stylesheet;

+ 31 - 3
example/src/variants/locales/default.json

@@ -5,12 +5,26 @@
         "translations": {
             "ncore-about": "NCore, başta NİBGAT® ve NİBGAT® | Topluluk olmak üzere herkes için geliştirilmiş bir tasarım sistemi ve bileşen kütüphanesidir. Hızlı geliştirme süreçleri ve yüksek stabilizasyon ile şık sistemler üretmek üzere tasarlanmıştır.",
             "this-is-test-sub-page": "Bu bir test alt sayfasıdır.",
+            "toggle-custom-padding": "Özel Boşluğu Aç/Kapat",
             "ncore-design-system": "NCore | Tasarım Sistemi",
+            "toggle-icon-direction": "İkon Yönünü Aç/Kapat",
             "ui-kit-library": "KA Araçları - Kütüphanesi",
+            "toggle-disabled": "Devre Dışıyı Aç/Kapat",
+            "toggle-loading": "Yükleniyoru Aç/Kapat",
+            "change-variant": "Varyantı Değiştir",
+            "change-spread": "Yayılımı Değiştir",
+            "change-size": "Boyutu Değiştir",
+            "example-button": "Örnek Buton",
+            "button-title": "Buton Başlığı",
+            "toggle-icon": "İkonu Aç/Kapat",
+            "change-type": "Türü Değiştir",
+            "enter-text": "Metin Girin",
             "text": "Text ( Metin )",
             "home": "Ana Sayfa",
+            "version": "Sürüm",
             "button": "Button",
-            "version": "Sürüm"
+            "right": "Sağ",
+            "left": "Sol"
         }
     },
     {
@@ -19,12 +33,26 @@
         "translations": {
             "ncore-about": "NCore is a design system and component library developed for everyone, primarily NİBGAT® and NİBGAT® | Community. It is designed to build elegant systems with rapid development processes and high stability.",
             "this-is-test-sub-page": "This is test sub-page.",
-            "design-system": "NCore | Design System",
+            "toggle-icon-direction": "Toggle Icon Direction",
+            "toggle-custom-padding": "Toggle Custom Padding",
+            "ncore-design-system": "NCore | Design System",
             "ui-kit-library": "UI Kit - Library",
+            "toggle-disabled": "Toggle Disabled",
+            "toggle-loading": "Toggle Loading",
+            "example-button": "Example Button",
+            "change-variant": "Change Variant",
+            "change-spread": "Change Spread",
+            "button-title": "Button Title",
+            "change-type": "Change Type",
+            "change-size": "Change Size",
+            "toggle-icon": "Toggle Icon",
+            "enter-text": "Enter Text",
             "version": "Version",
             "home": "Home Page",
             "button": "Button",
-            "text": "Text"
+            "right": "Right",
+            "text": "Text",
+            "left": "Left"
         }
     }
 ]

+ 31 - 3
example/web/public/index.html

@@ -1,8 +1,36 @@
 <!DOCTYPE html>
-<html>
+<html id="doc">
     <head>
-        <meta charset="utf-8" />
-        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script>
+            const theme = window.localStorage.getItem("theme");
+
+            if(theme) {
+                const themeObject = JSON.parse(theme);
+
+                const htmlDoc = document.getElementById("doc");
+                const appDoc = document.getElementById("app-root");
+
+                if(htmlDoc) {
+                    htmlDoc.style.backgroundColor = themeObject.colors.content.container.default;
+                }
+
+                if(appDoc) {
+                    appDoc.style.backgroundColor = themeObject.colors.content.container.default;
+                }
+            }
+        </script>
+        <meta
+            charset="utf-8"
+        />
+        <meta
+            name="viewport"
+            content="width=device-width, initial-scale=1"
+        />
+        <link
+            rel="icon"
+            type="image/x-icon"
+            href="http://ncore.nibgat.space/assets/images/darklogo.png"
+        />
         <link
             rel="stylesheet"
             href="https://fonts.nibgat.com/ncore.css"

+ 2 - 2
src/assets/svg/nibgatIcon/index.tsx

@@ -33,7 +33,7 @@ const NIBGATIcon = ({
             fillOpacity={0.922}
             clipRule="evenodd"
             fillRule="evenodd"
-            fill="url(#a)"
+            fill="url(#nibgat_gradient)"
         />
         <Path
             d="m222.613 198.652 21.808-37.795 21.846-37.834h87.307l21.846 37.834 21.807 37.795-21.807 37.833-21.846 37.795h-87.307l-21.846-37.795-21.808-37.833ZM353.574 425.537l21.846-37.834 21.808-37.795h87.345l21.808 37.795 21.845 37.834-21.845 37.795-21.808 37.833h-87.345l-21.808-37.833-21.846-37.795ZM91.615 425.537l21.846-37.834 21.808-37.795h87.345l21.808 37.795 21.845 37.834-21.845 37.795-21.808 37.833h-87.345l-21.808-37.833-21.846-37.795Z"
@@ -83,7 +83,7 @@ const NIBGATIcon = ({
                 x2={135.764 / pathScale}
                 y2={531.137 / pathScale}
                 y1={88.682 / pathScale}
-                id="a"
+                id="nibgat_gradient"
             >
                 <Stop stopColor="#36B49E" />
                 <Stop

+ 4 - 0
src/components/button/index.tsx

@@ -26,10 +26,12 @@ import Text from "../text";
  */
 const Button: FC<IButtonProps> = ({
     displayBehaviourWhileLoading = "disabled",
+    verticalLocationForStretchFix = "start",
     spreadBehaviour = "baseline",
     isCustomPadding = false,
     icon: IconComponentProp,
     iconDirection = "left",
+    isFixVerticalStretch,
     variant = "filled",
     isDisabled = false,
     customBorderColor,
@@ -75,8 +77,10 @@ const Button: FC<IButtonProps> = ({
         overlay: overlayDynamicStyle,
         title: titleDynamicStyle
     } = useStyles({
+        verticalLocationForStretchFix,
         displayBehaviourWhileLoading,
         icon: IconComponentProp,
+        isFixVerticalStretch,
         customBorderColor,
         isCustomPadding,
         spreadBehaviour,

+ 4 - 2
src/components/button/stylesheet.ts

@@ -170,7 +170,9 @@ const stylesheet = StyleSheet.create({
 });
 
 export const useStyles = ({
+    verticalLocationForStretchFix,
     displayBehaviourWhileLoading,
+    isFixVerticalStretch,
     customBorderColor,
     spreadBehaviour,
     isCustomPadding,
@@ -194,13 +196,13 @@ export const useStyles = ({
 
     const styles = {
         container: {
+            alignSelf: isFixVerticalStretch ? verticalLocationForStretchFix === "center" ? verticalLocationForStretchFix : `flex-${verticalLocationForStretchFix}` : "auto",
             paddingRight: currentSize.paddingHorizontal,
             paddingBottom: currentSize.paddingVertical,
             paddingLeft: currentSize.paddingHorizontal,
             paddingTop: currentSize.paddingVertical,
             borderRadius: radiuses.actions,
-            borderWidth: borders.line,
-            alignSelf: "auto"
+            borderWidth: borders.line
         } as Mutable<ViewStyle>,
         title: {
         } as Mutable<TextStyle>,

+ 4 - 0
src/components/button/type.ts

@@ -15,11 +15,13 @@ export type ButtonDynamicStyleType = {
     customBorderColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     displayBehaviourWhileLoading?: ButtonDisplayBehaviourWhileLoading;
+    verticalLocationForStretchFix?: "center" | "start" | "end";
     radiuses: NCoreUIKit.ActivePalette["radiuses"];
     spaces: NCoreUIKit.ActivePalette["spaces"];
     colors: NCoreUIKit.ActivePalette["colors"];
     spreadBehaviour?: ButtonSpreadBehaviour;
     iconDirection?: "left" | "right";
+    isFixVerticalStretch?: boolean;
     currentVariant: ButtonVariants;
     borders: NCoreUIKit.Borders;
     currentSize: ButtonMeasures;
@@ -89,6 +91,7 @@ interface IButtonProps extends Omit<ButtonProps, "title" | "disabled"> {
     customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     displayBehaviourWhileLoading?: ButtonDisplayBehaviourWhileLoading;
     titleStyle?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
+    verticalLocationForStretchFix?: "center" | "start" | "end";
     customTheme?: {
         gapPropagation?: keyof NCoreUIKit.GapPropagationKey;
         sharpness?: keyof NCoreUIKit.SharpnessKey;
@@ -99,6 +102,7 @@ interface IButtonProps extends Omit<ButtonProps, "title" | "disabled"> {
     spreadBehaviour?: ButtonSpreadBehaviour;
     iconDirection?: "left" | "right";
     renderLoading?: () => ReactNode;
+    isFixVerticalStretch?: boolean;
     isCustomPadding?: boolean;
     variant?: ButtonVariant;
     icon?: NCoreUIKitIcon;

+ 4 - 0
src/components/highlightButton/index.tsx

@@ -25,10 +25,12 @@ import Text from "../text";
  */
 const HighlightButton: FC<IHighlightButtonProps> = ({
     displayBehaviourWhileLoading = "disabled",
+    verticalLocationForStretchFix = "start",
     spreadBehaviour = "baseline",
     isCustomPadding = false,
     icon: IconComponentProp,
     iconDirection = "left",
+    isFixVerticalStretch,
     isDisabled = false,
     customBorderColor,
     customIconColor,
@@ -69,8 +71,10 @@ const HighlightButton: FC<IHighlightButtonProps> = ({
         overlay: overlayDynamicStyle,
         title: titleDynamicStyle
     } = useStyles({
+        verticalLocationForStretchFix,
         displayBehaviourWhileLoading,
         icon: IconComponentProp,
+        isFixVerticalStretch,
         customBorderColor,
         isCustomPadding,
         spreadBehaviour,

+ 3 - 1
src/components/highlightButton/stylesheet.ts

@@ -138,7 +138,9 @@ const stylesheet = StyleSheet.create({
 });
 
 export const useStyles = ({
+    verticalLocationForStretchFix,
     displayBehaviourWhileLoading,
+    isFixVerticalStretch,
     customBorderColor,
     spreadBehaviour,
     isCustomPadding,
@@ -161,6 +163,7 @@ export const useStyles = ({
 
     const styles = {
         container: {
+            alignSelf: isFixVerticalStretch ? verticalLocationForStretchFix === "center" ? verticalLocationForStretchFix : `flex-${verticalLocationForStretchFix}` : "auto",
             backgroundColor: colors.system.low[currentType.containerColor],
             borderColor: colors.content.border[currentType.borderColor],
             paddingRight: currentSize.paddingHorizontal,
@@ -169,7 +172,6 @@ export const useStyles = ({
             paddingTop: currentSize.paddingVertical,
             borderRadius: radiuses.actions,
             borderWidth: borders.line / 4,
-            alignSelf: "auto",
             ...webStyle({
                 boxShadow: `inset 0 0px 0.5px ${currentType.borderColor}, inset 0 -2px 6px ${currentType.borderColor}, 0 10px 30px ${currentType.borderColor}`,
                 WebkitBackdropFilter: `blur(${glassEffect}px) saturate(180%) brightness(1.1)`,

+ 4 - 0
src/components/highlightButton/type.ts

@@ -15,6 +15,7 @@ export type HighlightButtonDynamicStyleType = {
     displayBehaviourWhileLoading?: HighlightButtonDisplayBehaviourWhileLoading;
     customBorderColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
+    verticalLocationForStretchFix?: "center" | "start" | "end";
     spreadBehaviour?: HighlightButtonSpreadBehaviour;
     radiuses: NCoreUIKit.ActivePalette["radiuses"];
     spaces: NCoreUIKit.ActivePalette["spaces"];
@@ -22,6 +23,7 @@ export type HighlightButtonDynamicStyleType = {
     currentSize: HighlightButtonMeasures;
     currentType: HighlightButtonTypes;
     iconDirection?: "left" | "right";
+    isFixVerticalStretch?: boolean;
     borders: NCoreUIKit.Borders;
     isCustomPadding?: boolean;
     type: HighlightButtonType;
@@ -75,6 +77,7 @@ interface IHighlightButtonProps extends Omit<ButtonProps, "title" | "disabled">
     customTextColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     titleStyle?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
+    verticalLocationForStretchFix?: "center" | "start" | "end";
     customTheme?: {
         gapPropagation?: keyof NCoreUIKit.GapPropagationKey;
         sharpness?: keyof NCoreUIKit.SharpnessKey;
@@ -85,6 +88,7 @@ interface IHighlightButtonProps extends Omit<ButtonProps, "title" | "disabled">
     spreadBehaviour?: HighlightButtonSpreadBehaviour;
     iconDirection?: "left" | "right";
     renderLoading?: () => ReactNode;
+    isFixVerticalStretch?: boolean;
     size?: HighlightButtonSize;
     type?: HighlightButtonType;
     isCustomPadding?: boolean;

+ 14 - 3
src/components/localeSwitcher/index.tsx

@@ -20,7 +20,7 @@ import {
 } from "../../assets/svg";
 import HighlightButton from "../highlightButton";
 
-const PaletteSwitcher: FC<ILocaleSwitcherProps> = ({
+const LocaleSwitcher: FC<ILocaleSwitcherProps> = ({
     variants: variantsProps = [],
     isWorkWithHighlightButton,
     isWorkWithNextShowSystem,
@@ -87,7 +87,18 @@ const PaletteSwitcher: FC<ILocaleSwitcherProps> = ({
     }
 
     const variants = [...variantsPre].sort((a, b) => {
-        return localeKeys.indexOf(a.localeKey) - localeKeys.indexOf(b.localeKey);
+        const indexA = localeKeys.indexOf(a.localeKey);
+        const indexB = localeKeys.indexOf(b.localeKey);
+
+        if (indexA === -1 && indexB !== -1) return 1;
+
+        if (indexB === -1 && indexA !== -1) return -1;
+
+        if (indexA === -1 && indexB === -1) {
+            return a.localeKey.localeCompare(b.localeKey);
+        }
+
+        return indexA - indexB;
     });
 
     const currentVariantIndex = variants.findIndex(e => e.localeKey === activeLocale);
@@ -146,4 +157,4 @@ const PaletteSwitcher: FC<ILocaleSwitcherProps> = ({
         {...allProps}
     />;
 };
-export default PaletteSwitcher;
+export default LocaleSwitcher;

+ 12 - 1
src/components/paletteSwitcher/index.tsx

@@ -105,7 +105,18 @@ const PaletteSwitcher: FC<IPaletteSwitcherProps> = ({
     }
 
     const variants = [...variantsPre].sort((a, b) => {
-        return paletteKeys.indexOf(a.paletteKey) - paletteKeys.indexOf(b.paletteKey);
+        const indexA = paletteKeys.indexOf(a.paletteKey);
+        const indexB = paletteKeys.indexOf(b.paletteKey);
+
+        if (indexA === -1 && indexB !== -1) return 1;
+
+        if (indexB === -1 && indexA !== -1) return -1;
+
+        if (indexA === -1 && indexB === -1) {
+            return a.paletteKey.localeCompare(b.paletteKey);
+        }
+
+        return indexA - indexB;
     });
 
     const currentVariantIndex = variants.findIndex(e => e.paletteKey === activePalette);

+ 12 - 1
src/components/themeSwitcher/index.tsx

@@ -98,7 +98,18 @@ const ThemeSwitcher: FC<IThemeSwitcherProps> = ({
     }
 
     const variants = [...variantsPre].sort((a, b) => {
-        return themeKeys.indexOf(a.themeKey) - themeKeys.indexOf(b.themeKey);
+        const indexA = themeKeys.indexOf(a.themeKey);
+        const indexB = themeKeys.indexOf(b.themeKey);
+
+        if (indexA === -1 && indexB !== -1) return 1;
+
+        if (indexB === -1 && indexA !== -1) return -1;
+
+        if (indexA === -1 && indexB === -1) {
+            return a.themeKey.localeCompare(b.themeKey);
+        }
+
+        return indexA - indexB;
     });
 
     const currentVariantIndex = variants.findIndex(e => e.themeKey === activeTheme);