Просмотр исходного кода

Merge branch 'release/1.0.0-pre-alpha.1'

lfabl 1 месяц назад
Родитель
Сommit
2b877bd2c7
100 измененных файлов с 4020 добавлено и 2481 удалено
  1. 2 2
      .github/ISSUE_TEMPLATE/config.yml
  2. 2 0
      .gitignore
  3. 3 0
      .npmignore
  4. 1 1
      .yarnrc.yml
  5. 101 0
      README.md
  6. 4 4
      babel.config.js
  7. 106 106
      eslint.config.mjs
  8. 10 10
      example/mobile/app.json
  9. 3 3
      example/mobile/babel.config.js
  10. 41 0
      example/mobile/global.d.ts
  11. 1 1
      example/mobile/index.ts
  12. 12 9
      example/mobile/metro.config.js
  13. 4 32
      example/mobile/package.json
  14. 0 42
      example/mobile/src/index.tsx
  15. 0 32
      example/mobile/src/navigation/index.tsx
  16. 0 7
      example/mobile/src/navigation/type.ts
  17. 0 668
      example/mobile/src/pages/home/index.tsx
  18. 0 61
      example/mobile/src/pages/testSubPage/index.tsx
  19. 0 10
      example/mobile/src/pages/testSubPage/stylesheet.ts
  20. 13 1
      example/mobile/tsconfig.json
  21. 0 0
      example/src/assets/fonts/Geist-Black.ttf
  22. 0 0
      example/src/assets/fonts/Geist-Bold.ttf
  23. 0 0
      example/src/assets/fonts/Geist-ExtraBold.ttf
  24. 0 0
      example/src/assets/fonts/Geist-ExtraLight.ttf
  25. 0 0
      example/src/assets/fonts/Geist-Light.ttf
  26. 0 0
      example/src/assets/fonts/Geist-Medium.ttf
  27. 0 0
      example/src/assets/fonts/Geist-Regular.ttf
  28. 0 0
      example/src/assets/fonts/Geist-SemiBold.ttf
  29. 0 0
      example/src/assets/fonts/Geist-Thin.ttf
  30. BIN
      example/src/assets/images/ncorelogo.png
  31. 1 0
      example/src/global.d.ts
  32. 50 0
      example/src/index.tsx
  33. 170 0
      example/src/navigation/index.tsx
  34. 1 1
      example/src/navigation/type.ts
  35. 109 0
      example/src/pages/home/index.tsx
  36. 0 0
      example/src/pages/home/stylesheet.ts
  37. 96 0
      example/src/pages/text/index.tsx
  38. 3 2
      example/src/pages/text/stylesheet.ts
  39. 35 0
      example/src/tsconfig.json
  40. 28 0
      example/src/variants/locales/default.json
  41. 677 0
      example/src/variants/themes/default.json
  42. 0 2
      example/web/.bundle/config
  43. 0 32
      example/web/App.tsx
  44. 0 13
      example/web/__tests__/App.test.tsx
  45. 2 2
      example/web/app.json
  46. 11 8
      example/web/babel.config.js
  47. 0 9
      example/web/index.js
  48. 18 0
      example/web/index.tsx
  49. 50 50
      example/web/ios/nibgatofficialwebsite/Images.xcassets/AppIcon.appiconset/Contents.json
  50. 4 4
      example/web/ios/nibgatofficialwebsite/Images.xcassets/Contents.json
  51. 4 4
      example/web/jest.config.js
  52. 31 2
      example/web/metro.config.js
  53. 5 54
      example/web/package.json
  54. 21 24
      example/web/public/index.html
  55. BIN
      example/web/src/assets/fonts/Geist-Black.ttf
  56. BIN
      example/web/src/assets/fonts/Geist-Bold.ttf
  57. BIN
      example/web/src/assets/fonts/Geist-ExtraBold.ttf
  58. BIN
      example/web/src/assets/fonts/Geist-ExtraLight.ttf
  59. BIN
      example/web/src/assets/fonts/Geist-Light.ttf
  60. BIN
      example/web/src/assets/fonts/Geist-Medium.ttf
  61. BIN
      example/web/src/assets/fonts/Geist-Regular.ttf
  62. BIN
      example/web/src/assets/fonts/Geist-SemiBold.ttf
  63. BIN
      example/web/src/assets/fonts/Geist-Thin.ttf
  64. 0 46
      example/web/src/navigation/index.tsx
  65. 0 618
      example/web/src/pages/home/index.tsx
  66. 0 61
      example/web/src/pages/testSubPage/index.tsx
  67. 0 10
      example/web/src/pages/testSubPage/stylesheet.ts
  68. 17 6
      example/web/tsconfig.json
  69. 69 17
      example/web/webpack.config.js
  70. 66 22
      package.json
  71. 0 42
      src/assets/svg/badgeAlertIcon/index.tsx
  72. 0 40
      src/assets/svg/badgeDangerIcon/index.tsx
  73. 0 40
      src/assets/svg/badgeInfoIcon/index.tsx
  74. 0 50
      src/assets/svg/badgeQuestionMarkIcon/index.tsx
  75. 0 40
      src/assets/svg/badgeRightIcon/index.tsx
  76. 0 50
      src/assets/svg/badgeSuccessIcon/index.tsx
  77. 26 0
      src/assets/svg/cayCoreIcon/index.tsx
  78. 0 40
      src/assets/svg/chevronRightIcon/index.tsx
  79. 0 40
      src/assets/svg/cleanIcon/index.tsx
  80. 0 50
      src/assets/svg/eyeClosedIcon/index.tsx
  81. 0 50
      src/assets/svg/eyeOpenedIcon/index.tsx
  82. 6 30
      src/assets/svg/index.ts
  83. 4 3
      src/assets/svg/loadingIcon/index.tsx
  84. 60 0
      src/assets/svg/nibgatCommunityIcon/index.tsx
  85. 96 0
      src/assets/svg/nibgatIcon/index.tsx
  86. 255 0
      src/components/avatar/index.tsx
  87. 184 0
      src/components/avatar/stylesheet.ts
  88. 88 0
      src/components/avatar/type.ts
  89. 172 0
      src/components/avatarGroup/index.tsx
  90. 138 0
      src/components/avatarGroup/stylesheet.ts
  91. 74 0
      src/components/avatarGroup/type.ts
  92. 327 11
      src/components/bottomSheet/index.tsx
  93. 25 1
      src/components/button/index.tsx
  94. 16 0
      src/components/button/stylesheet.ts
  95. 7 1
      src/components/button/type.ts
  96. 9 0
      src/components/checkBox/index.tsx
  97. 14 17
      src/components/dateTimePicker/index.tsx
  98. 279 0
      src/components/embeddedMenu/components/menuButton/index.tsx
  99. 36 0
      src/components/embeddedMenu/components/menuButton/type.ts
  100. 433 0
      src/components/embeddedMenu/index.tsx

+ 2 - 2
.github/ISSUE_TEMPLATE/config.yml

@@ -1,8 +1,8 @@
 blank_issues_enabled: false
 contact_links:
   - name: Feature Request 💡
-    url: https://git.nibgat.space/nibgat-community/ncore-ui-kit-mobile.git/discussions/new?category=ideas
+    url: https://git.nibgat.space/nibgat-community/ncore-ui-kit.git/discussions/new?category=ideas
     about: If you have a feature request, please create a new discussion on GitHub.
   - name: Discussions on GitHub 💬
-    url: https://git.nibgat.space/nibgat-community/ncore-ui-kit-mobile.git/discussions
+    url: https://git.nibgat.space/nibgat-community/ncore-ui-kit.git/discussions
     about: If this library works as promised but you need help, please ask questions there.

+ 2 - 0
.gitignore

@@ -53,6 +53,8 @@ node_modules/
 npm-debug.log
 yarn-debug.log
 yarn-error.log
+**/*/dist
+**/dist
 
 # BUCK
 buck-out/

+ 3 - 0
.npmignore

@@ -12,3 +12,6 @@ example
 LICENSE
 CODE_OF_CONDUCT.md
 CONTRIBUTING.md
+**/*/dist
+**/dist
+src

+ 1 - 1
.yarnrc.yml

@@ -1,4 +1,4 @@
 nodeLinker: node-modules
-nmHoistingLimits: workspaces
+nmHoistingLimits: none
 
 yarnPath: .yarn/releases/yarn-4.11.0.cjs

+ 101 - 0
README.md

@@ -1,2 +1,103 @@
 # NİBGAT® | NCore - Mobile
 The NCore, NİBGAT® UI - Kit. The NİBGAT®'s UI / Component Library.
+
+```typescript
+useEffect(() => {
+    NCoreUIKitMenu.load({
+        siteLogoProps: {
+            imageUrl: "https://www.nibgat.com/assets/images/logo.png",
+            onPress: () => {
+                navigation.navigate("Home");
+            },
+            imageProps: {
+                resizeMode: "stretch"
+            },
+            imageSpace: "spacingLg",
+            isWorkWithAction: true,
+            subTitle: "Core Tech",
+            title: "NİBGAT®"
+        },
+        renderFooter: () => {
+            return <View
+                style={{
+                    padding: spaces.spacingMd,
+                    flexDirection: "row",
+                    alignItems: "center"
+                }}
+            >
+                <View
+                    style={{
+                        marginRight: spaces.spacingSm,
+                        justifyContent: "center",
+                        flexDirection: "row",
+                        alignItems: "center"
+                    }}
+                >
+                    <Text
+                        variant="labelLargeSize"
+                    >
+                        Palet:
+                    </Text>
+                    <PaletteSwitcher/>
+                </View>
+                <View
+                    style={{
+                        justifyContent: "center",
+                        flexDirection: "row",
+                        alignItems: "center"
+                    }}
+                >
+                    <Text
+                        variant="labelLargeSize"
+                    >
+                        Tema:
+                    </Text>
+                    <ThemeSwitcher/>
+                </View>
+            </View>;
+        },
+        isAutoClosed: true,
+        buttons: [
+            {
+                redirectMain: "Home",
+                isCollapsible: true,
+                title: "Ana Sayfa",
+                icon: ({
+                    color
+                }) => <HomeIcon
+                    color={colors.content.icon[color]}
+                />,
+                subButtons: [
+                    {
+                        title: "Text",
+                        redirectMain: "TextPage"
+                    }
+                ]
+            },
+            {
+                redirectMain: "Text",
+                isCollapsible: true,
+                title: "Deneme",
+                icon: ({
+                    color
+                }) => <HomeIcon
+                    color={colors.content.icon[color]}
+                />,
+                subButtons: [
+                    {
+                        title: "Noliii",
+                        redirectMain: "Home"
+                    }
+                ]
+            },
+            {
+                title: "Text",
+                redirectMain: "TextPage"
+            }
+        ],
+        navigation: navigation as unknown as NCoreUIKit.Navigation,
+        id: "test"
+    });
+}, []);
+
+```

+ 4 - 4
babel.config.js

@@ -1,12 +1,12 @@
 module.exports = {
     overrides: [
         {
-            exclude: /\/node_modules\//,
-            presets: ["module:react-native-builder-bob/babel-preset"]
+            presets: ["module:react-native-builder-bob/babel-preset"],
+            exclude: /\/node_modules\//
         },
         {
-            include: /\/node_modules\//,
-            presets: ["module:@react-native/babel-preset"]
+            presets: ["module:@react-native/babel-preset"],
+            include: /\/node_modules\//
         }
     ],
 };

+ 106 - 106
eslint.config.mjs

@@ -13,112 +13,35 @@ export default tseslint.config(
     {
         ignores: [
             "node_modules",
-            "dist",
-            "lib",
+            "version.mjs",
             ".history",
-            "version.mjs"
+            "dist",
+            "lib"
         ]
     },
     js.configs.recommended,
     ...tseslint.configs.recommended,
     {
-        files: [
-            "**/*.{ts,tsx,js,jsx}"
-        ],
-        plugins: {
-            react,
-            "react-hooks": reactHooks,
-            "jsx-a11y": jsxA11y,
-            import: importPlugin,
-            "local-rules": {
-                rules: localRulesPlugin.rules
-            }
-        },
-        languageOptions: {
-            ecmaVersion: "latest",
-            sourceType: "module",
-            parser: tseslint.parser,
-            parserOptions: {
-                ecmaFeatures: {
-                    jsx: true
-                }
-            },
-            globals: {
-                "clearInterval": "readonly",
-                "clearTimeout": "readonly",
-                "setInterval": "readonly",
-                "setTimeout": "readonly",
-                "FormData": "readonly",
-                "console": "readonly",
-                "__DEV__": "readonly",
-                "fetch": "readonly"
-            }
-        },
-        settings: {
-            react: {
-                version: "detect"
-            },
-            "import/resolver": {
-                typescript: {
-                    alwaysTryTypes: true,
-                    project: "./tsconfig.json"
-                }
-            }
-        },
         rules: {
             "local-rules/multiline-import-specifiers": "error",
             "local-rules/multiline-object-properties": "error",
             "local-rules/multiline-jsx-attributes": "error",
             "local-rules/multiline-array-elements": "error",
-            "local-rules/custom-import-order": "error",
-            "@typescript-eslint/no-namespace": "off",
-            "quotes": [
-                "error",
-                "double",
-                {
-                    "avoidEscape": true
-                }
-            ],
-            "semi": [
-                "error",
-                "always"
-            ],
-            "no-var": "error",
-            "prefer-const": "error",
-            "comma-spacing": [
-                "error",
-                {
-                    "before": false,
-                    "after": true
-                }
-            ],
-            "object-curly-spacing": [
-                "error",
-                "always"
-            ],
-            "indent": [
-                "error",
-                4,
-                {
-                    "SwitchCase": 1
-                }
-            ],
-            "no-trailing-spaces": [
-                "error",
-                {
-                    "skipBlankLines": false
-                }
-            ],
             "@typescript-eslint/no-empty-object-type": [
                 "error",
                 {
                     "allowInterfaces": "with-single-extends"
                 }
             ],
-            "eol-last": [
+            "object-property-newline": [
                 "error",
-                "always"
+                {
+                    "allowAllPropertiesOnSameLine": false
+                }
             ],
+            "local-rules/custom-import-order": "error",
+            "@typescript-eslint/no-namespace": "off",
+            "react/react-in-jsx-scope": "off",
             "object-curly-newline": [
                 "error",
                 {
@@ -144,12 +67,23 @@ export default tseslint.config(
                     }
                 }
             ],
-            "object-property-newline": [
+            "no-trailing-spaces": [
                 "error",
                 {
-                    "allowAllPropertiesOnSameLine": false
+                    "skipBlankLines": false
+                }
+            ],
+            "quotes": [
+                "error",
+                "double",
+                {
+                    "avoidEscape": true
                 }
             ],
+            "react/jsx-indent-props": [
+                "error",
+                4
+            ],
             "array-element-newline": [
                 "error",
                 {
@@ -161,16 +95,82 @@ export default tseslint.config(
                 "error",
                 "consistent"
             ],
+            "object-curly-spacing": [
+                "error",
+                "always"
+            ],
+            "prefer-const": "error",
+            "comma-spacing": [
+                "error",
+                {
+                    "before": false,
+                    "after": true
+                }
+            ],
+            "indent": [
+                "error",
+                4,
+                {
+                    "SwitchCase": 1
+                }
+            ],
             "react/jsx-indent": [
                 "error",
                 4
             ],
-            "react/jsx-indent-props": [
+            "no-var": "error",
+            "eol-last": [
                 "error",
-                4
+                "always"
             ],
-            "react/react-in-jsx-scope": "off"
-        }
+            "semi": [
+                "error",
+                "always"
+            ]
+        },
+        settings: {
+            "import/resolver": {
+                typescript: {
+                    project: "./tsconfig.json",
+                    alwaysTryTypes: true
+                }
+            },
+            react: {
+                version: "detect"
+            }
+        },
+        plugins: {
+            "local-rules": {
+                rules: localRulesPlugin.rules
+            },
+            "react-hooks": reactHooks,
+            import: importPlugin,
+            "jsx-a11y": jsxA11y,
+            react
+        },
+        languageOptions: {
+            globals: {
+                "clearInterval": "readonly",
+                "clearTimeout": "readonly",
+                "setInterval": "readonly",
+                "setTimeout": "readonly",
+                "FormData": "readonly",
+                "__DEV__": "readonly",
+                "console": "readonly",
+                "fetch": "readonly"
+            },
+            parser: tseslint.parser,
+            ecmaVersion: "latest",
+            sourceType: "module",
+            parserOptions: {
+                ecmaFeatures: {
+                    jsx: true
+                }
+            }
+        },
+        files: [
+            "**/*.{ts,tsx,js,jsx}"
+        ]
     },
     {
         files: [
@@ -186,20 +186,7 @@ export default tseslint.config(
         }
     },
     {
-        files: [
-            "**/*.json"
-        ],
-        plugins: {
-            jsonc
-        },
-        languageOptions: {
-            parser: jsoncParser
-        },
         rules: {
-            "jsonc/indent": [
-                "error",
-                4
-            ],
             "jsonc/object-property-newline": [
                 "error",
                 {
@@ -224,7 +211,20 @@ export default tseslint.config(
             "jsonc/array-bracket-newline": [
                 "error",
                 "always"
+            ],
+            "jsonc/indent": [
+                "error",
+                4
             ]
+        },
+        languageOptions: {
+            parser: jsoncParser
+        },
+        files: [
+            "**/*.json"
+        ],
+        plugins: {
+            jsonc
         }
     }
 );

+ 10 - 10
example/mobile/app.json

@@ -1,7 +1,7 @@
 {
     "expo": {
         "name": "NCore | Ui Kit - Mobile Example",
-        "slug": "ncore-ui-kit-mobile-example-mobile",
+        "slug": "ncore-ui-kit-example-mobile",
         "version": "1.0.0",
         "orientation": "portrait",
         "icon": "./assets/icon.png",
@@ -31,15 +31,15 @@
                 "expo-font",
                 {
                     "fonts": [
-                        "./src/assets/fonts/Geist-Black.ttf",
-                        "./src/assets/fonts/Geist-Bold.ttf",
-                        "./src/assets/fonts/Geist-ExtraBold.ttf",
-                        "./src/assets/fonts/Geist-ExtraLight.ttf",
-                        "./src/assets/fonts/Geist-Light.ttf",
-                        "./src/assets/fonts/Geist-Medium.ttf",
-                        "./src/assets/fonts/Geist-Regular.ttf",
-                        "./src/assets/fonts/Geist-SemiBold.ttf",
-                        "./src/assets/fonts/Geist-Thin.ttf"
+                        "../src/assets/fonts/Geist-Black.ttf",
+                        "../src/assets/fonts/Geist-Bold.ttf",
+                        "../src/assets/fonts/Geist-ExtraBold.ttf",
+                        "../src/assets/fonts/Geist-ExtraLight.ttf",
+                        "../src/assets/fonts/Geist-Light.ttf",
+                        "../src/assets/fonts/Geist-Medium.ttf",
+                        "../src/assets/fonts/Geist-Regular.ttf",
+                        "../src/assets/fonts/Geist-SemiBold.ttf",
+                        "../src/assets/fonts/Geist-Thin.ttf"
                     ]
                 }
             ]

+ 3 - 3
example/mobile/babel.config.js

@@ -19,9 +19,9 @@ module.exports = function (api) {
                         ".json"
                     ],
                     alias: {
-                        "ncore-ui-kit-mobile": "../../src",
-                        "react": "./node_modules/react",
-                        "react-native": "./node_modules/react-native"
+                        "ncore-ui-kit": "../../src",
+                        "react": "../../node_modules/react",
+                        "react-native": "../../node_modules/react-native"
                     }
                 }
             ]

+ 41 - 0
example/mobile/global.d.ts

@@ -0,0 +1,41 @@
+import "../../src/types/index";
+import defaultLocaleJSON from "../src/variants/locales/default.json";
+import defaultThemeJSON from "../src/variants/themes/default.json";
+
+declare global {
+    namespace NCoreUIKit {
+        type PaletteNames = "gmcore";
+
+        interface PaletteKey extends Record<PaletteType, unknown>, Record<PaletteNames, unknown> {
+        }
+
+        type ProjectLocalizationL = typeof defaultLocaleJSON[0];
+
+        type GeneratedProjectTranslations = {
+            [K in keyof ProjectLocalizationL["translations"]]: ProjectLocalizationL["translations"][K];
+        };
+
+        interface Translation extends GeneratedTranslations, GeneratedProjectTranslations {
+        }
+
+        type DefaultPaletteL = typeof defaultThemeJSON.palettes[0];
+
+        type ProjectDataL = DefaultPaletteL["themes"]["dark"]["project"];
+        type DefaultProjectColorsL = ProjectDataL;
+
+        interface ProjectColorPalette extends DefaultProjectColors, DefaultProjectColorsL {
+        }
+
+        type SystemDataL = DefaultPaletteL["themes"]["dark"]["system"];
+        type DefaultSystemColorsL = SystemDataL;
+
+        interface SystemColorPalette extends DefaultSystemColors, DefaultSystemColorsL {
+        }
+
+        type ContentDataL = DefaultPaletteL["themes"]["dark"]["content"];
+        type DefaultContentColorsL = ContentDataL;
+
+        interface ContentColorPalette extends DefaultContentColors, DefaultContentColorsL {
+        }
+    }
+}

+ 1 - 1
example/mobile/index.js → example/mobile/index.ts

@@ -1,6 +1,6 @@
-import App from "./index";
 import {
     registerRootComponent
 } from "expo";
+import App from "../src/index";
 
 registerRootComponent(App);

+ 12 - 9
example/mobile/metro.config.js

@@ -2,25 +2,28 @@
 /* eslint-disable */
 
 const {
-  getDefaultConfig
+    getDefaultConfig
 } = require("expo/metro-config");
 const path = require("path");
 
-const root = path.resolve(__dirname, "..");
-
-const nodeModulesPaths = [path.resolve(__dirname, "node_modules")];
+const root = path.resolve(__dirname, "../..");
+const source = path.resolve(__dirname, "../src");
 
 const config = getDefaultConfig(__dirname);
 
-config.watchFolders = [root];
+config.watchFolders = [
+    root,
+    source
+];
 
 config.resolver.extraNodeModules = {
-  "ncore-ui-kit-mobile": path.resolve(root, "src"),
-  "react": path.resolve(__dirname, "node_modules/react"),
-  "react-native": path.resolve(__dirname, "node_modules/react-native"),
+    "ncore-ui-kit": path.resolve(root, "src"),
+    "node_modules": path.resolve(root, "node_modules")
 };
 
-config.resolver.nodeModulesPaths = nodeModulesPaths;
+config.resolver.nodeModulesPaths = [
+    path.resolve(root, "node_modules")
+];
 
 config.resolver.disableHierarchicalLookup = true;
 

+ 4 - 32
example/mobile/package.json

@@ -1,7 +1,7 @@
 {
-    "name": "ncore-ui-kit-mobile-example-mobile",
-    "version": "1.0.0",
-    "main": "index.js",
+    "name": "ncore-ui-kit-example-mobile",
+    "version": "1.0.0-pre-alpha.0",
+    "main": "index.ts",
     "type": "commonjs",
     "scripts": {
         "start": "expo start",
@@ -9,33 +9,5 @@
         "ios": "expo start --ios",
         "web": "expo start --web"
     },
-    "dependencies": {
-        "@expo/metro-runtime": "~55.0.6",
-        "@react-navigation/elements": "2.9.14",
-        "@react-navigation/native": "7.2.2",
-        "@react-navigation/native-stack": "7.14.11",
-        "expo": "~55.0.4",
-        "expo-font": "~55.0.4",
-        "expo-status-bar": "~55.0.4",
-        "lucide-react-native": "1.8.0",
-        "moment": "https://git.nibgat.space/nibgat-community/moment.git",
-        "ncore-context": "1.0.5",
-        "react": "19.2.6",
-        "react-dom": "19.2.6",
-        "react-native": "0.83.2",
-        "react-native-safe-area-context": "5.7.0",
-        "react-native-screens": "4.24.0",
-        "react-native-svg": "15.15.3",
-        "react-native-web": "~0.21.0",
-        "rrule": "https://git.nibgat.space/nibgat-community/rrule.git"
-    },
-    "private": true,
-    "devDependencies": {
-        "@expo/webpack-config": "^19.0.1",
-        "@react-native/metro-config": "0.84.1",
-        "@types/react-native": "0.73.0",
-        "babel-preset-expo": "56.0.15",
-        "react-native-builder-bob": "0.40.13",
-        "react-native-monorepo-config": "0.3.3"
-    }
+    "private": true
 }

+ 0 - 42
example/mobile/src/index.tsx

@@ -1,42 +0,0 @@
-import Navigation from "./navigation";
-import {
-    useFonts
-} from "expo-font";
-import moment from "moment";
-import {
-    setupNCoreUIKit
-} from "ncore-ui-kit-mobile";
-import "moment/locale/tr";
-
-const NCoreUIKitBase = setupNCoreUIKit({
-    initialSelectedGapPropagation: "spacious",
-    initialSelectedTheme: "light"
-});
-
-moment.locale("tr");
-
-const App = () => {
-    return <Navigation/>;
-};
-
-const ContextAPI = () => {
-    /* eslint-disable @typescript-eslint/no-require-imports */
-    const [loaded] = useFonts({
-        "Geist-ExtraLight": require("./assets/fonts/Geist-ExtraLight.ttf"),
-        "Geist-ExtraBold": require("./assets/fonts/Geist-ExtraBold.ttf"),
-        "Geist-SemiBold": require("./assets/fonts/Geist-SemiBold.ttf"),
-        "Geist-Regular": require("./assets/fonts/Geist-Regular.ttf"),
-        "Geist-Medium": require("./assets/fonts/Geist-Medium.ttf"),
-        "Geist-Black": require("./assets/fonts/Geist-Black.ttf"),
-        "Geist-Light": require("./assets/fonts/Geist-Light.ttf"),
-        "Geist-Bold": require("./assets/fonts/Geist-Bold.ttf"),
-        "Geist-Thin": require("./assets/fonts/Geist-Thin.ttf")
-    });
-
-    if (!loaded) return null;
-
-    return <NCoreUIKitBase.Provider>
-        <App/>
-    </NCoreUIKitBase.Provider>;
-};
-export default ContextAPI;

+ 0 - 32
example/mobile/src/navigation/index.tsx

@@ -1,32 +0,0 @@
-import {
-    NavigationContainer
-} from "@react-navigation/native";
-import {
-    createNativeStackNavigator
-} from "@react-navigation/native-stack";
-import Home from "../pages/home";
-import TestSubPage from "../pages/testSubPage";
-
-const RootStack = createNativeStackNavigator();
-
-const RootNav = () => {
-    return <RootStack.Navigator
-        initialRouteName="Home"
-    >
-        <RootStack.Screen
-            name="Home"
-            component={Home}
-        />
-        <RootStack.Screen
-            name="TestSubPage"
-            component={TestSubPage}
-        />
-    </RootStack.Navigator>;
-};
-
-const Navigation = () => {
-    return <NavigationContainer>
-        <RootNav/>
-    </NavigationContainer>;
-};
-export default Navigation;

+ 0 - 7
example/mobile/src/navigation/type.ts

@@ -1,7 +0,0 @@
-type RootStackParamList = {
-    TestSubPage: undefined;
-    Home: undefined;
-};
-export type {
-    RootStackParamList as default
-};

+ 0 - 668
example/mobile/src/pages/home/index.tsx

@@ -1,668 +0,0 @@
-import {
-    Fragment,
-    useState,
-    useRef
-} from "react";
-import {
-    View
-} from "react-native";
-import stylesheet from "./stylesheet";
-import {
-    NCoreUIKitBottomSheet,
-    NotificationIndicator,
-    getNCoreUIKitVersion,
-    type IBottomSheetRef,
-    NCoreUIKitSnackBar,
-    NCoreUIKitDialog,
-    NCoreUIKitToast,
-    NCoreUIKitTheme,
-    DateTimePicker,
-    MarkdownViewer,
-    PageContainer,
-    TextAreaInput,
-    BottomSheet,
-    RadioButton,
-    TextInput,
-    SelectBox,
-    StateCard,
-    CheckBox,
-    RowCard,
-    Button,
-    Dialog,
-    Switch,
-    Text,
-    Sticker,
-    Chip
-} from "ncore-ui-kit-mobile";
-import {
-    useNavigation
-} from "@react-navigation/native";
-import type {
-    NativeStackNavigationProp
-} from "@react-navigation/native-stack";
-import type RootStackParamList from "../../navigation/type";
-import {
-    ChevronRight as ChevronRightIcon,
-    HomeIcon
-} from "lucide-react-native";
-import moment from "moment";
-
-const X = [
-    {
-        t: "xdfç.öhfdşkhdfşlhkfdşlhkdfşklhjmdfkhl3",
-        p: "ydfguıy8ı*pğ34erdx",
-        n: 90
-    },
-    {
-        t: "3t4uh5ıe6ıo6eıo6eoke6ıoke6ker6kr4ok",
-        p: "y3w46pjbd57ykdr",
-        n: 91
-    },
-    {
-        t: "xr*-0k4wkh-5w40k0*wek95ujk9*",
-        p: "y467o5*3evghe5",
-        n: 92
-    },
-    {
-        t: "x-40*tyg*0w4kyh*w0ko45u*ko0w",
-        p: "y3şçwl78570*fg",
-        n: 93
-    },
-    {
-        t: "*wrüsjh*ü9kws4*h0okdfhdhdfurdkex",
-        p: "yt7ıtot7ot",
-        n: 94
-    },
-    {
-        t: "x2-0*4woy-*w4opyu-*23wou*0wık*0jk",
-        p: "yasfa33",
-        n: 95
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    }
-];
-
-const Home = () => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const bottomSheetRef = useRef<IBottomSheetRef>(null);
-
-    const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
-
-    const [
-        isCheckboxActive,
-        setIsCheckboxActive
-    ] = useState<"partially" | "checked" | null>("checked");
-
-    const [
-        isDialogActive,
-        setIsDialogActive
-    ] = useState(false);
-
-    const [
-        isRadioActive,
-        setIsRadioActive
-    ] = useState(false);
-
-    const [
-        isSwitchActive,
-        setIsSwitchActive
-    ] = useState(false);
-
-    return <PageContainer
-        scrollViewStyle={stylesheet.container}
-        isScrollable={true}
-        scrollViewProps={{
-            showsHorizontalScrollIndicator: false,
-            showsVerticalScrollIndicator: false,
-            contentContainerStyle: {
-                backgroundColor: colors.content.container.default,
-                ...stylesheet.contentContainer
-            }
-        }}
-        renderOverlays={() => {
-            return <Fragment>
-                <Dialog
-                    isVisible={isDialogActive}
-                    content="etgweı09gı9w0eg"
-                    title="Merhaba Dünya!"
-                    contentJustify="centered"
-                    modalProps={{
-                        isWorkWithPortal: false
-                    }}
-                    onOverlayPress={({
-                        closeAnimation
-                    }) => {
-                        closeAnimation(() => setIsDialogActive(false));
-                    }}
-                    variant="yes-no"
-                    secondaryButtonProps={{
-                        title: "sdfgsdg",
-                        onPress: () => {
-
-                        }
-                    }}
-                    primaryButtonProps={{
-                        onPress: ({
-                            closeAnimation
-                        }) => {
-                            closeAnimation(() => setIsDialogActive(false));
-                        }
-                    }}
-                />
-                <BottomSheet
-                    ref={bottomSheetRef}
-                    renderHeader={() => {
-                        return <View
-                            style={[
-                                {
-                                    backgroundColor: "blue",
-                                    padding: 20
-                                }
-                            ]}
-                        >
-                            <Text>Burası header.</Text>
-                        </View>;
-                    }}
-                    isCanFullScreenOnSwipe={true}
-                    isWorkWithPortal={false}
-                    snapPoint={300}
-                    key="ahmet"
-                >
-                    <Button
-                        title="Open Toast"
-                        variant="filled"
-                        type="warning"
-                        onPress={() => {
-                            NCoreUIKitToast.open({
-                                title: "sdgfsdgsdg",
-                                type: "danger"
-                            });
-                        }}
-                    />
-                    <Button
-                        onPress={() => {
-                            navigation.navigate("TestSubPage");
-                        }}
-                        title="Git."
-                    />
-                    {[
-                        0,
-                        1,
-                        2,
-                        3,
-                        4,
-                        5,
-                        6,
-                        7,
-                        8,
-                        9,
-                        10,
-                        11,
-                        12,
-                        13,
-                        14,
-                        15,
-                        16,
-                        17,
-                        18,
-                        19,
-                        20,
-                        21,
-                        22,
-                        23,
-                        24,
-                        25,
-                        26,
-                        27,
-                        28,
-                        29,
-                        30,
-                        31,
-                        32,
-                        33,
-                        34,
-                        35
-                    ].map((it) => {
-                        return <View
-                            key={`fds-${it}`}
-                            style={{
-                                backgroundColor: `rgb(${it * 10}, ${it > 30 ? it * 5 : "0"}, ${it > 20 ? it * 4 : "0"})`,
-                                height: 150
-                            }}
-                        />;
-                    })}
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                </BottomSheet>
-            </Fragment>;
-        }}
-    >
-        <Chip
-            spreadBehaviour="free"
-            title="test"
-            isLoading={false}
-            isDisabled={false}
-            icon={({
-                customColor,
-                style,
-                color,
-                size
-            }) => <HomeIcon
-                color={customColor ? customColor : colors.content.icon[color]}
-                size={size}
-                style={style}
-            />}
-        />
-        <Sticker
-            spreadBehaviour="free"
-            title="test"
-            icon={({
-                style,
-                color,
-                size
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-                size={size}
-                style={style}
-            />}
-        />
-        <StateCard
-            title="Deneme"
-            subTitle="Bu bir alt metindir ve uzun olması gerekmektedir. Ne kadar uzun olursa o kadar iyidir."
-            icon={({
-                color,
-                size
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-                size={size}
-            />}
-            action={{
-                title: "Me Action",
-                size: "small",
-                onPress: () => {
-
-                }
-            }}
-        />
-        <DateTimePicker
-            minDate={moment().subtract(2, "years").toDate()}
-            maxDate={moment().add(15, "years").toDate()}
-            isWorkWithRealtime={false}
-            isWorkWithSeconds={true}
-            isCleanEnabled={true}
-            variant="range"
-            initialDateRange={{
-                start: moment().subtract(2, "days").startOf("day").toDate(),
-                end: moment().add(6, "days").endOf("day").toDate()
-            }}
-            initialDate={new Date()}
-        />
-        <MarkdownViewer
-            content={`
-# Merhaba Furkan!.
-
-Nabersin ?
-
-<center>
-<link href="https://www.nibgat.com">
-## Deneme **title** 2
-</link>
-
-\`\`\`
-safasfasfasf
-\`\`\`
-</center>
-iyisindir **umarım.**
-
-\`\`\`
-Ahmet buraya gel.
-
-
-Geldin mi ?
-\`\`\`
-
-<<
-Burası alıntı metnidir.
->>
-
-* Merhaba __madd__e1.
-- Deneme madde2.
-
-[Alt text için deneme](https://static.vecteezy.com/system/resources/thumbnails/060/843/811/small/close-up-of-raindrops-on-leaves-hd-background-luxury-hd-wallpaper-image-trendy-background-illustration-free-photo.jpg)<100%x200>--cover--`}
-        />
-        <NotificationIndicator
-            type="danger"
-            title={53}
-        >
-            <Button
-                size="small"
-                icon={({
-                    color
-                }) => <HomeIcon
-                    color={colors.content.icon[color]}
-                />}
-                onPress={() => {
-
-                }}
-            />
-        </NotificationIndicator>
-        <Switch
-            spreadBehaviour="stretch"
-            isActive={isSwitchActive}
-            title="dsgojksdgpojk"
-            subTitle="SJFAJdfa"
-            isDisabled={false}
-            onPress={() => {
-                setIsSwitchActive(!isSwitchActive);
-            }}
-        />
-        <RowCard
-            title="Merhaba"
-            icon={({
-                color
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-            />}
-            rightIcon={({
-                color
-            }) => <ChevronRightIcon
-                color={colors.content.icon[color]}
-            />}
-        />
-        <RadioButton
-            isChecked={isRadioActive}
-            title="sadfasfsafasf"
-            isDisabled={false}
-            subTitle="asfgsaf"
-            onPress={() => {
-                setIsRadioActive(!isRadioActive);
-            }}
-        />
-        <CheckBox
-            isChecked={isCheckboxActive}
-            title="sadfasfsafasf"
-            isDisabled={false}
-            subTitle="asfgsaf"
-            onPress={() => {
-                setIsCheckboxActive(isCheckboxActive === "checked" ? null : isCheckboxActive === null ? "partially" : "checked");
-            }}
-        />
-        <TextAreaInput
-            isUpdateOnRealtime={true}
-            spreadBehaviour="stretch"
-            placeholder="efsdg"
-            maxLength={300}
-            title="Merhaba"
-            type="success"
-            isCleanEnabled={true}
-            icon={({
-                color
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-            />}
-        />
-        <SelectBox
-            keyExtractor={(data, index) => `${data.t}-${index}`}
-            titleExtractor={(data) => data.t}
-            initialSelectedItems={[{
-                __title: X[0]?.t as string,
-                __key: `${X[0]?.t}-0`
-            }]}
-            subTitle="Deneme Subtitle"
-            // isWorkWithRealtime={false}
-            isWorkWithRealtime={false}
-            spreadBehaviour="baseline"
-            isMultipleSelect={true}
-            isShowSubTitle={true}
-            hintText="Test deneme"
-            isCleanEnabled={true}
-            maxChoice={-1}
-            minChoice={0}
-            isSearchable={true}
-            title="Deneme Box"
-            isRequired={true}
-            data={X}
-            onMoreLoad={(props) => {
-                console.log("More Loaded:", props);
-            }}
-        />
-        <TextInput
-            variant="hidden"
-            placeholder="dsagdsag"
-        />
-        <Text>Version: v{getNCoreUIKitVersion()}</Text>
-        <Button
-            onPress={() => {
-                navigation.navigate("TestSubPage");
-            }}
-            title="Open Test Sub Page"
-            variant="filled"
-            spreadBehaviour="stretch"
-        />
-        <Button
-            onPress={() => {
-                bottomSheetRef.current?.open();
-            }}
-            type="success"
-            title="Open Local BottomSheet"
-            variant="filled"
-        />
-        <Button
-            onPress={() => {
-                NCoreUIKitBottomSheet.open({
-                    children: <View>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                    </View>
-                });
-            }}
-            type="success"
-            title="Open BottomSheet"
-            variant="filled"
-        />
-        <Button
-            onPress={() => {
-                setIsDialogActive(!isDialogActive);
-            }}
-            type="neutral"
-            title="Open Local Dialog"
-            variant="filled"
-        />
-        <Button
-            title="Open Snackbar"
-            variant="filled"
-            type="danger"
-            onPress={() => {
-                NCoreUIKitSnackBar.open({
-                    title: "sdgdsgs",
-                    icon: ({
-                        color
-                    }) => <HomeIcon color={colors.content.icon[color ? color : "default"]}/>
-                });
-            }}
-        />
-        <Button
-            onPress={() => {
-                NCoreUIKitDialog.open({
-                    content: "etgweı09gı9w0eg",
-                    title: "Merhaba Dünya!",
-                    isVisible: true,
-                    onOverlayPress: ({
-                        closeAnimation
-                    }) => {
-                        closeAnimation();
-                    },
-                    variant: "info",
-                    secondaryButtonProps: {
-                        title: "sdfgsdg",
-                        onPress: () => {
-
-                        }
-                    },
-                    primaryButtonProps: {
-                        onPress: ({
-                            closeAnimation
-                        }) => {
-                            closeAnimation();
-                        }
-                    }
-                });
-            }}
-            type="neutral"
-            title="Open Dialog"
-            variant="filled"
-        />
-        <Button
-            title="Open Toast"
-            variant="filled"
-            type="warning"
-            onPress={() => {
-                NCoreUIKitToast.open({
-                    title: "sdgfsdgsdafs sdlşlgkdfşiklh",
-                    subTitle: "tr9uıdgfss 0dgklsd",
-                    isShowAction: true,
-                    icon: ({
-                        color
-                    }) => <HomeIcon color={colors.content.icon[color ? color : "default"]}/>
-                });
-            }}
-        />
-    </PageContainer>;
-};
-export default Home;

+ 0 - 61
example/mobile/src/pages/testSubPage/index.tsx

@@ -1,61 +0,0 @@
-import {
-    useRef
-} from "react";
-import {
-    View
-} from "react-native";
-import stylesheet from "./stylesheet";
-import {
-    type IBottomSheetRef,
-    PageContainer,
-    BottomSheet,
-    Button,
-    Text
-} from "ncore-ui-kit-mobile";
-
-const TestSubPage = () => {
-    const bottomSheetRef = useRef<IBottomSheetRef>(null);
-
-    return <PageContainer
-        style={[
-            stylesheet.container
-        ]}
-    >
-        <Text>This is test sub page.</Text>
-        <Button
-            onPress={() => {
-                bottomSheetRef.current?.open();
-            }}
-            type="success"
-            title="Ahmet"
-            variant="filled"
-        />
-        <BottomSheet
-            isCanFullScreenOnSwipe={true}
-            isWorkWithPortal={false}
-            ref={bottomSheetRef}
-            snapPoint={300}
-        >
-            <Button
-                onPress={() => {
-
-                }}
-                title="Git."
-            />
-            <View
-                style={{
-                    backgroundColor: "red",
-                    height: 2400
-                }}
-            />
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-        </BottomSheet>
-    </PageContainer>;
-};
-export default TestSubPage;

+ 0 - 10
example/mobile/src/pages/testSubPage/stylesheet.ts

@@ -1,10 +0,0 @@
-import {
-    StyleSheet
-} from "react-native";
-
-const stylesheet = StyleSheet.create({
-    container: {
-        flex: 1
-    }
-});
-export default stylesheet;

+ 13 - 1
example/mobile/tsconfig.json

@@ -1,5 +1,17 @@
 {
     "extends": "../../tsconfig.json",
     "compilerOptions": {
-    }
+        "composite": true
+    },
+    "references": [
+        {
+            "path": "../../"
+        }
+    ],
+    "include": [
+        "**/*",
+        "../src/**/*",
+        "../src/**/*.json",
+        "../../src/assets/svg/nibgatIcon"
+    ]
 }

+ 0 - 0
example/mobile/src/assets/fonts/Geist-Black.ttf → example/src/assets/fonts/Geist-Black.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-Bold.ttf → example/src/assets/fonts/Geist-Bold.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-ExtraBold.ttf → example/src/assets/fonts/Geist-ExtraBold.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-ExtraLight.ttf → example/src/assets/fonts/Geist-ExtraLight.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-Light.ttf → example/src/assets/fonts/Geist-Light.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-Medium.ttf → example/src/assets/fonts/Geist-Medium.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-Regular.ttf → example/src/assets/fonts/Geist-Regular.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-SemiBold.ttf → example/src/assets/fonts/Geist-SemiBold.ttf


+ 0 - 0
example/mobile/src/assets/fonts/Geist-Thin.ttf → example/src/assets/fonts/Geist-Thin.ttf


BIN
example/src/assets/images/ncorelogo.png


+ 1 - 0
example/src/global.d.ts

@@ -0,0 +1 @@
+import "../../src/types/index";

+ 50 - 0
example/src/index.tsx

@@ -0,0 +1,50 @@
+import Navigation from "./navigation";
+import defaultLocaleJSON from "./variants/locales/default.json";
+import defaultThemeJSON from "./variants/themes/default.json";
+import {
+    useFonts
+} from "expo-font";
+import moment from "moment";
+import "moment/locale/tr";
+import {
+    setupNCoreUIKit
+} from "ncore-ui-kit";
+
+const NCoreUIKitBase = setupNCoreUIKit({
+    initialSelectedGapPropagation: "spacious",
+    projectLocales: defaultLocaleJSON,
+    projectThemes: defaultThemeJSON,
+    initialSelectedTheme: "light"
+});
+
+moment.locale("tr");
+
+const App = () => {
+    return <Navigation/>;
+};
+
+const isExpo = typeof globalThis !== "undefined" && ("__expo" in globalThis || "Expo" in globalThis);
+
+const ContextAPI = () => {
+    if(isExpo) {
+        /* eslint-disable @typescript-eslint/no-require-imports */
+        const [loaded] = useFonts({
+            "Geist-ExtraLight": require("./assets/fonts/Geist-ExtraLight.ttf"),
+            "Geist-ExtraBold": require("./assets/fonts/Geist-ExtraBold.ttf"),
+            "Geist-SemiBold": require("./assets/fonts/Geist-SemiBold.ttf"),
+            "Geist-Regular": require("./assets/fonts/Geist-Regular.ttf"),
+            "Geist-Medium": require("./assets/fonts/Geist-Medium.ttf"),
+            "Geist-Black": require("./assets/fonts/Geist-Black.ttf"),
+            "Geist-Light": require("./assets/fonts/Geist-Light.ttf"),
+            "Geist-Bold": require("./assets/fonts/Geist-Bold.ttf"),
+            "Geist-Thin": require("./assets/fonts/Geist-Thin.ttf")
+        });
+
+        if (!loaded) return null;
+    }
+
+    return <NCoreUIKitBase.Provider>
+        <App/>
+    </NCoreUIKitBase.Provider>;
+};
+export default ContextAPI;

+ 170 - 0
example/src/navigation/index.tsx

@@ -0,0 +1,170 @@
+import {
+    useEffect
+} from "react";
+import {
+    Platform
+} from "react-native";
+import type RootStackParamList from "./type";
+import {
+    NCoreUIKitEmbeddedMenu,
+    NCoreUIKitTheme,
+    MainHeader,
+    NCoreUIKitLocalize
+} from "ncore-ui-kit";
+import {
+    NavigationContainer,
+    useNavigation
+} from "@react-navigation/native";
+import {
+    type NativeStackNavigationProp,
+    createNativeStackNavigator
+} from "@react-navigation/native-stack";
+import {
+    ComponentIcon,
+    HomeIcon
+} from "lucide-react-native";
+import Home from "../pages/home";
+import TextPage from "../pages/text";
+
+const RootStack = createNativeStackNavigator();
+const ComponentsStack = createNativeStackNavigator();
+
+const ComponentsNav = () => {
+    return <ComponentsStack.Navigator
+        initialRouteName="TextPage"
+    >
+        <ComponentsStack.Screen
+            name="TextPage"
+            component={TextPage}
+        />
+    </ComponentsStack.Navigator>;
+};
+
+const RootNav = () => {
+    const {
+        colors
+    } = NCoreUIKitTheme.useContext();
+
+    const {
+        localize
+    } = NCoreUIKitLocalize.useContext();
+
+    const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
+
+    useEffect(() => {
+        const currentMenuStatus = Platform.OS === "web" ? window.localStorage.getItem("main-menu-status") : "false";
+
+        NCoreUIKitEmbeddedMenu.load({
+            isCollapse: currentMenuStatus === "true" ? true : false,
+            isWorkWithSafeAreaView: false,
+            siteLogoProps: {
+                isShowIcon: false,
+                title: localize("menu")
+            },
+            buttons: [
+                {
+                    redirectMain: "Home",
+                    isUseLocalize: true,
+                    title: "home",
+                    icon: ({
+                        color
+                    }) => <HomeIcon
+                        color={colors.content.icon[color]}
+                    />
+                },
+                {
+                    redirectMain: "Components",
+                    isUseLocalize: true,
+                    isCollapsible: true,
+                    title: "components",
+                    icon: ({
+                        color
+                    }) => <ComponentIcon
+                        color={colors.content.icon[color]}
+                    />,
+                    subButtons: [
+                        {
+                            redirectMain: "Components",
+                            redirectSub: "TextPage",
+                            title: "Text"
+                        }
+                    ]
+                }
+            ],
+            isAutoClosed: true,
+            id: "main-menu"
+        });
+
+        NCoreUIKitEmbeddedMenu.addEventListener("state", updateStorage);
+    }, []);
+
+    const updateStorage = () => {
+        const data = NCoreUIKitEmbeddedMenu.state.data;
+
+        if(Platform.OS === "web" && data && data.length) {
+            const currentMenu = data.find(dI => dI.id === "main-menu");
+
+            if(currentMenu) {
+                window.localStorage.setItem("main-menu-status", String(currentMenu.isCollapse));
+            }
+        }
+    };
+
+    return <MainHeader
+        isWorkWithSeperator={true}
+        siteLogoProps={{
+            imageUrl: "http://ncore.nibgat.space/assets/images/ncorelogo.png",
+            onPress: () => {
+                navigation.navigate("Home");
+            },
+            imageProps: {
+                resizeMode: "stretch"
+            },
+            subTitle: "Design System - UI Kit",
+            title: "NİBGAT® | NCore",
+            isWorkWithAction: true,
+            isWorkWithFlex1: true
+        }}
+    >
+        <NCoreUIKitEmbeddedMenu.Render
+            navigation={navigation as unknown as NCoreUIKit.Navigation}
+            id="main-menu"
+        >
+            <RootStack.Navigator
+                initialRouteName="Home"
+                screenOptions={{
+                    headerShown: false
+                }}
+            >
+                <RootStack.Screen
+                    name="Home"
+                    component={Home}
+                />
+                <RootStack.Screen
+                    name="Components"
+                    component={ComponentsNav}
+                />
+            </RootStack.Navigator>
+        </NCoreUIKitEmbeddedMenu.Render>
+    </MainHeader>;
+};
+
+const Navigation = () => {
+    return <NavigationContainer
+        linking={{
+            prefixes: [
+                "http://localhost:3000",
+                "https://ncore.nibgat.space"
+            ],
+            config: {
+                screens: {
+                    Home: "",
+                    TestSubPage: "text"
+                }
+            }
+        }}
+    >
+        <RootNav/>
+    </NavigationContainer>;
+};
+export default Navigation;

+ 1 - 1
example/web/src/navigation/type.ts → example/src/navigation/type.ts

@@ -1,5 +1,5 @@
 type RootStackParamList = {
-    TestSubPage: undefined;
+    TextPage: undefined;
     Home: undefined;
 };
 export type {

+ 109 - 0
example/src/pages/home/index.tsx

@@ -0,0 +1,109 @@
+import {
+    useLayoutEffect
+} from "react";
+import {
+    Image,
+    View
+} from "react-native";
+import stylesheet from "./stylesheet";
+import {
+    NCoreUIKitLocalize,
+    NCoreUIKitTheme,
+    PageContainer,
+    Text
+} from "ncore-ui-kit";
+import {
+    useNavigation
+} from "@react-navigation/native";
+import type RootStackParamList from "../../navigation/type";
+import type {
+    NativeStackNavigationProp
+} from "@react-navigation/native-stack";
+import packageJSON from "../../../../package.json";
+
+const Home = () => {
+    const {
+        colors,
+        spaces
+    } = NCoreUIKitTheme.useContext();
+
+    const {
+        localize
+    } = NCoreUIKitLocalize.useContext();
+
+    const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
+
+    useLayoutEffect(() => {
+        navigation.setOptions({
+            headerShown: false
+        });
+    }, []);
+
+    return <PageContainer
+        scrollViewStyle={stylesheet.container}
+        isScrollable={true}
+        scrollViewProps={{
+            showsHorizontalScrollIndicator: false,
+            showsVerticalScrollIndicator: false,
+            contentContainerStyle: {
+                backgroundColor: colors.content.container.default,
+                ...stylesheet.contentContainer
+            }
+        }}
+    >
+        <View
+            style={{
+                justifyContent: "center",
+                alignItems: "center",
+                maxWidth: 850,
+                width: "100%"
+            }}
+        >
+            <Image
+                source={{
+                    uri: "https://ncore.nibgat.space/assets/images/ncorelogo.png"
+                }}
+                style={{
+                    height: 300,
+                    width: 300
+                }}
+            />
+            <Text
+                variant="displayMediumSize"
+                style={{
+                    marginBottom: spaces.spacingMd,
+                    textAlign: "center"
+                }}
+            >
+                {localize("ncore-design-system")}
+            </Text>
+            <Text
+                variant="headlineLargeSize"
+                style={{
+                    marginBottom: spaces.spacingLg,
+                    textAlign: "center"
+                }}
+            >
+                {localize("ui-kit-library")}
+            </Text>
+            <Text
+                variant="bodyLargeSize"
+                style={{
+                    marginBottom: spaces.spacingMd,
+                    textAlign: "center"
+                }}
+            >
+                {localize("ncore-about")}
+            </Text>
+            <Text
+                color="low"
+                style={{
+                    marginBottom: spaces.spacingMd
+                }}
+            >
+                {localize("version")}: {packageJSON.version}
+            </Text>
+        </View>
+    </PageContainer>;
+};
+export default Home;

+ 0 - 0
example/mobile/src/pages/home/stylesheet.ts → example/src/pages/home/stylesheet.ts


+ 96 - 0
example/src/pages/text/index.tsx

@@ -0,0 +1,96 @@
+import {
+    useLayoutEffect,
+    useState
+} from "react";
+import {
+    View
+} from "react-native";
+import stylesheet from "./stylesheet";
+import {
+    NCoreUIKitLocalize,
+    NCoreUIKitTheme,
+    PageContainer,
+    Button,
+    Header,
+    Text
+} from "ncore-ui-kit";
+import {
+    useNavigation
+} from "@react-navigation/native";
+import type RootStackParamList from "../../navigation/type";
+import type {
+    NativeStackNavigationProp
+} from "@react-navigation/native-stack";
+
+const TextPage = () => {
+    const {
+        typography,
+        radiuses,
+        borders,
+        spaces,
+        colors
+    } = NCoreUIKitTheme.useContext();
+
+    const {
+        localize
+    } = NCoreUIKitLocalize.useContext();
+
+    const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
+
+    const [
+        variant,
+        setVariant
+    ] = useState<number>(0);
+
+    useLayoutEffect(() => {
+        navigation.setOptions({
+            header: () => <Header
+                isWrapSafeareaContext={false}
+                title={localize("text")}
+                navigation={navigation}
+                isGoBackEnable={true}
+            />
+        });
+    }, []);
+
+    return <PageContainer
+        isScrollable={false}
+        style={[
+            stylesheet.container
+        ]}
+    >
+        <View
+            style={[
+                stylesheet.contentContainer
+            ]}
+        >
+            <View
+                style={{
+                    borderColor: colors.content.border.subtle,
+                    marginBottom: spaces.spacingMd,
+                    borderRadius: radiuses.form,
+                    borderWidth: borders.line,
+                    padding: spaces.spacingMd,
+                    minHeight: 120
+                }}
+            >
+                <Text
+                    variant={Object.keys(typography)[variant] as keyof NCoreUIKit.Typography}
+                    style={{
+                        marginBottom: spaces.spacingLg
+                    }}
+                >
+                    {localize("this-is-test-sub-page")}
+                </Text>
+            </View>
+            <Button
+                title={`variant = ${Object.keys(typography)[variant]}`}
+                spreadBehaviour="stretch"
+                onPress={() => {
+                    setVariant(variant + 1 > Object.keys(typography).length - 1 ? 0 : variant + 1);
+                }}
+            />
+        </View>
+    </PageContainer>;
+};
+export default TextPage;

+ 3 - 2
example/web/src/pages/home/stylesheet.ts → example/src/pages/text/stylesheet.ts

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

+ 35 - 0
example/src/tsconfig.json

@@ -0,0 +1,35 @@
+{
+    "extends": [
+        "../../tsconfig.json",
+        "../mobile/tsconfig.json",
+        "../web/tsconfig.json",
+    ],
+    "compilerOptions": {
+        "allowSyntheticDefaultImports": true,
+        "moduleResolution": "bundler",
+        "ignoreDeprecations": "6.0",
+        "preserveSymlinks": true,
+        "esModuleInterop": true,
+        "jsx": "react-native",
+        "target": "esnext",
+        "baseUrl": "."
+    },
+    "references": [
+        {
+            "path": "../../"
+        },
+        {
+            "path": "../mobile"
+        },
+        {
+            "path": "../web"
+        }
+    ],
+    "include": [
+        "**/*.ts",
+        "**/*.tsx",
+        "../../src/**/*",
+        "../../src/types/index.ts",
+        "**/*.json"
+    ]
+}

+ 28 - 0
example/src/variants/locales/default.json

@@ -0,0 +1,28 @@
+[
+    {
+        "locale": "tr-TR",
+        "isRTL": false,
+        "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.",
+            "ncore-design-system": "NCore | Tasarım Sistemi",
+            "ui-kit-library": "KA Araçları - Kütüphanesi",
+            "text": "Text ( Metin )",
+            "home": "Ana Sayfa",
+            "version": "Sürüm"
+        }
+    },
+    {
+        "locale": "en-US",
+        "isRTL": false,
+        "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",
+            "ui-kit-library": "UI Kit - Library",
+            "version": "Version",
+            "home": "Home Page",
+            "text": "Text"
+        }
+    }
+]

+ 677 - 0
example/src/variants/themes/default.json

@@ -0,0 +1,677 @@
+{
+    "isNeedAndroidTypographyFixer": true,
+    "shapes": {
+        "radiuses": {
+            "soft": {
+                "form": 8,
+                "surface": 12,
+                "actions": 8,
+                "chip": 8,
+                "full": 9999,
+                "xs": 4,
+                "none": 0,
+                "sm": 8,
+                "md": 12,
+                "lg": 16,
+                "xl": 28
+            },
+            "sharp": {
+                "form": 4,
+                "surface": 8,
+                "actions": 4,
+                "chip": 4,
+                "full": 9999,
+                "xs": 2,
+                "none": 0,
+                "sm": 4,
+                "md": 8,
+                "lg": 12,
+                "xl": 16
+            },
+            "rounded": {
+                "form": 12,
+                "surface": 28,
+                "actions": 9999,
+                "chip": 9999,
+                "full": 9999,
+                "xs": 8,
+                "none": 0,
+                "sm": 12,
+                "md": 16,
+                "lg": 28,
+                "xl": 28
+            }
+        },
+        "inlineSpaces": {
+            "subTitle": 4,
+            "required": 4
+        },
+        "borders": {
+            "subtract": 3,
+            "line": 2
+        },
+        "spaces": {
+            "spacious": {
+                "spacingXs": 4,
+                "spacingSm": 8,
+                "spacingMd": 16,
+                "spacingLg": 24,
+                "spacingXl": 32
+            },
+            "compact": {
+                "spacingXs": 2,
+                "spacingSm": 4,
+                "spacingMd": 12,
+                "spacingLg": 16,
+                "spacingXl": 24
+            }
+        }
+    },
+    "typography": {
+        "spacious": {
+            "displayLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 57,
+                "lineHeight": 64,
+                "letterSpacing": -0.25
+            },
+            "displayMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 45,
+                "lineHeight": 52,
+                "letterSpacing": 0
+            },
+            "displaySmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 36,
+                "lineHeight": 44,
+                "letterSpacing": 0
+            },
+            "headlineLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 32,
+                "lineHeight": 40,
+                "letterSpacing": 0
+            },
+            "headlineMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 28,
+                "lineHeight": 36,
+                "letterSpacing": 0
+            },
+            "headlineSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 24,
+                "lineHeight": 32,
+                "letterSpacing": 0
+            },
+            "titleLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 22,
+                "lineHeight": 28,
+                "letterSpacing": 0
+            },
+            "titleMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 16,
+                "lineHeight": 24,
+                "letterSpacing": 0.15
+            },
+            "titleSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 14,
+                "lineHeight": 20,
+                "letterSpacing": 0.1
+            },
+            "bodyLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 16,
+                "lineHeight": 24,
+                "letterSpacing": 0.5
+            },
+            "bodyMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 14,
+                "lineHeight": 20,
+                "letterSpacing": 0.25
+            },
+            "bodySmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 12,
+                "lineHeight": 16,
+                "letterSpacing": 0.4
+            },
+            "labelLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 14,
+                "lineHeight": 20,
+                "letterSpacing": 0.1
+            },
+            "labelMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 12,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            },
+            "labelSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 11,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            }
+        },
+        "compact": {
+            "displayLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 45,
+                "lineHeight": 52,
+                "letterSpacing": 0
+            },
+            "displayMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 36,
+                "lineHeight": 44,
+                "letterSpacing": 0
+            },
+            "displaySmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "300",
+                "fontSize": 32,
+                "lineHeight": 40,
+                "letterSpacing": 0
+            },
+            "headlineLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 28,
+                "lineHeight": 36,
+                "letterSpacing": 0
+            },
+            "headlineMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 24,
+                "lineHeight": 32,
+                "letterSpacing": 0
+            },
+            "headlineSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 22,
+                "lineHeight": 28,
+                "letterSpacing": 0
+            },
+            "titleLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 16,
+                "lineHeight": 24,
+                "letterSpacing": 0.15
+            },
+            "titleMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 14,
+                "lineHeight": 20,
+                "letterSpacing": 0.1
+            },
+            "titleSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "500",
+                "fontSize": 12,
+                "lineHeight": 16,
+                "letterSpacing": 0.4
+            },
+            "bodyLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 14,
+                "lineHeight": 20,
+                "letterSpacing": 0.25
+            },
+            "bodyMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 12,
+                "lineHeight": 16,
+                "letterSpacing": 0.4
+            },
+            "bodySmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 11,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            },
+            "labelLargeSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 12,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            },
+            "labelMediumSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 11,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            },
+            "labelSmallSize": {
+                "fontFamily": "Geist",
+                "fontWeight": "400",
+                "fontSize": 11,
+                "lineHeight": 16,
+                "letterSpacing": 0.5
+            }
+        }
+    },
+    "palettes": [
+        {
+            "name": "nibgat",
+            "themes": {
+                "dark": {
+                    "system": {
+                        "default": {
+                            "primary": "rgba(64,220,195,1)",
+                            "secondary": "rgba(187,204,196,1)",
+                            "tertiary": "rgba(171,203,228,1)",
+                            "error": "rgba(255,187,177,1)",
+                            "success": "rgba(179,250,188,1)",
+                            "warning": "rgba(255,223,102,1)",
+                            "info": "rgba(167,230,255,1)",
+                            "background": "rgba(25,28,27,1)",
+                            "surface": "rgba(25,28,27,1)"
+                        },
+                        "on": {
+                            "primary": "rgba(0,63,54,1)",
+                            "secondary": "rgba(28,53,47,1)",
+                            "tertiary": "rgba(18,52,72,1)",
+                            "error": "rgba(105,0,5,1)",
+                            "success": "rgba(22,66,33,1)",
+                            "warning": "rgba(97,54,0,1)",
+                            "info": "rgba(0,62,90,1)",
+                            "background": "rgba(224,226,225,1)",
+                            "surface": "rgba(224,226,225,1)"
+                        },
+                        "container": {
+                            "primary": "rgba(0,85,69,1)",
+                            "secondary": "rgba(51,74,68,1)",
+                            "tertiary": "rgba(43,74,95,1)",
+                            "error": "rgba(147,0,8,1)",
+                            "success": "rgba(50,97,58,1)",
+                            "warning": "rgba(136,81,0,1)",
+                            "info": "rgba(0,93,128,1)"
+                        },
+                        "onContainer": {
+                            "primary": "rgba(101,250,222,1)",
+                            "secondary": "rgba(206,232,224,1)",
+                            "tertiary": "rgba(201,236,254,1)",
+                            "error": "rgba(255,187,177,1)",
+                            "success": "rgba(206,255,214,1)",
+                            "warning": "rgba(255,241,200,1)",
+                            "info": "rgba(217,241,255,1)"
+                        },
+                        "variant": {
+                            "surface": "rgba(41,50,48,1)"
+                        },
+                        "onVariant": {
+                            "surface": "rgba(191,201,199,1)"
+                        },
+                        "outline": "rgba(137,147,145,1)",
+                        "shadow": "rgba(0,0,0,1)",
+                        "scrim": "rgba(0,0,0,0.5)",
+                        "onMid": {
+                            "surface": "rgba(255,255,255,0.64)"
+                        },
+                        "onLow": {
+                            "surface": "rgba(255,255,255,0.32)"
+                        },
+                        "state": {
+                            "overlay": {
+                                "hover": {
+                                    "default": "rgba(255,255,255,0.32)",
+                                    "primary": "rgba(64,220,195,0.08)",
+                                    "error": "rgba(255,187,177,0.24)",
+                                    "warning": "rgba(255,223,102,0.24)",
+                                    "success": "rgba(179,250,188,0.24)",
+                                    "neutral": "rgba(196,199,198,0.24)",
+                                    "info": "rgba(167,230,255,0.24)"
+                                },
+                                "focus": {
+                                    "default": "rgba(255,255,255,0.64)",
+                                    "primary": "rgba(0,107,92,0.32)",
+                                    "error": "rgba(255,187,177,0.32)",
+                                    "warning": "rgba(255,223,102,0.32)",
+                                    "success": "rgba(179,250,188,0.32)",
+                                    "neutral": "rgba(196,199,198,0.32)",
+                                    "info": "rgba(167,230,255,0.32)"
+                                },
+                                "pressed": {
+                                    "default": "rgba(255,255,255,0.32)",
+                                    "primary": "rgba(0,107,92,0.32)",
+                                    "error": "rgba(255,187,177,0.32)",
+                                    "warning": "rgba(255,223,102,0.32)",
+                                    "success": "rgba(179,250,188,0.32)",
+                                    "neutral": "rgba(196,199,198,0.32)",
+                                    "info": "rgba(167,230,255,0.32)"
+                                },
+                                "disabled": {
+                                    "primary": "rgba(0,107,92,0.24)",
+                                    "error": "rgba(255,187,177,0.24)",
+                                    "warning": "rgba(255,223,102,0.24)",
+                                    "success": "rgba(179,250,188,0.24)",
+                                    "neutral": "rgba(196,199,198,0.08)",
+                                    "info": "rgba(167,230,255,0.24)"
+                                }
+                            },
+                            "border": {
+                                "disabled": {
+                                    "primary": "rgba(0,107,92,0.64)",
+                                    "error": "rgba(255,187,177,0.32)",
+                                    "warning": "rgba(255,223,102,0.32)",
+                                    "success": "rgba(179,250,188,0.32)",
+                                    "neutral": "rgba(196,199,198,0.32)",
+                                    "info": "rgba(167,230,255,0.32)"
+                                }
+                            },
+                            "content": {
+                                "disabled": {
+                                    "primary": "rgba(0,107,92,0.64)",
+                                    "error": "rgba(255,187,177,0.32)",
+                                    "warning": "rgba(255,223,102,0.32)",
+                                    "success": "rgba(179,250,188,0.32)",
+                                    "neutral": "rgba(196,199,198,0.32)",
+                                    "info": "rgba(167,230,255,0.32)"
+                                },
+                                "mid": {
+                                    "error": "rgba(255,255,255,1)"
+                                }
+                            }
+                        },
+                        "disabled": {
+                            "content": "rgba(255,255,255,0.24)"
+                        },
+                        "low": {
+                            "error": "rgba(255,187,177,0.32)",
+                            "warning": "rgba(255,223,102,0.32)",
+                            "success": "rgba(179,250,188,0.32)",
+                            "info": "rgba(167,230,255,0.32)"
+                        }
+                    },
+                    "content": {
+                        "text": {
+                            "high": "rgba(224,226,225,1)",
+                            "mid": "rgba(255,255,255,0.64)",
+                            "low": "rgba(255,255,255,0.32)",
+                            "disabled": "rgba(255,255,255,0.24)",
+                            "emphasized": "rgba(64,220,195,1)",
+                            "link": "rgba(64,220,195,1)",
+                            "onPrimary": "rgba(0,63,54,1)",
+                            "danger": "rgba(255,187,177,1)",
+                            "success": "rgba(179,250,188,1)",
+                            "warning": "rgba(255,223,102,1)",
+                            "info": "rgba(167,230,255,1)",
+                            "disabledWhite": "rgba(255,255,255,0.32)",
+                            "dangerLow": "rgba(255,187,177,0.32)",
+                            "warningLow": "rgba(255,223,102,0.32)",
+                            "successLow": "rgba(179,250,188,0.32)",
+                            "infoLow": "rgba(167,230,255,0.32)"
+                        },
+                        "icon": {
+                            "default": "rgba(191,201,199,1)",
+                            "emphasized": "rgba(64,220,195,1)",
+                            "disabled": "rgba(255,255,255,0.24)",
+                            "onPrimary": "rgba(0,63,54,1)",
+                            "danger": "rgba(255,187,177,1)",
+                            "success": "rgba(179,250,188,1)",
+                            "warning": "rgba(255,223,102,1)",
+                            "info": "rgba(167,230,255,1)",
+                            "low": "rgba(255,255,255,0.32)",
+                            "mid": "rgba(255,255,255,0.64)",
+                            "high": "rgba(224,226,225,1)",
+                            "disabledWhite": "rgba(255,255,255,0.32)"
+                        },
+                        "container": {
+                            "default": "rgba(25,28,27,1)",
+                            "subtle": "rgba(41,50,48,1)",
+                            "emphasized": "rgba(0,85,69,1)",
+                            "selected": "rgba(0,85,69,1)",
+                            "mid": "rgba(37, 35, 34, 1)",
+                            "inverse": "rgba(0,63,54,1)",
+                            "overlay": "rgba(0,0,0,0.5)",
+                            "danger": "rgba(147,0,8,1)",
+                            "success": "rgba(50,97,58,1)",
+                            "warning": "rgba(136,81,0,1)",
+                            "info": "rgba(0,93,128,1)",
+                            "primary": "rgba(64,220,195,1)"
+                        },
+                        "border": {
+                            "default": "rgba(137,147,145,1)",
+                            "subtle": "rgba(41,50,48,1)",
+                            "emphasized": "rgba(64,220,195,1)",
+                            "danger": "rgba(255,187,177,1)",
+                            "success": "rgba(179,250,188,1)",
+                            "disabled": "rgba(255,255,255,0.24)",
+                            "warning": "rgba(255,223,102,1)",
+                            "info": "rgba(167,230,255,1)"
+                        }
+                    },
+                    "project": {
+                        "moon": "#0F5792",
+                        "sun": "#C09E13"
+                    }
+                },
+                "light": {
+                    "system": {
+                        "default": {
+                            "primary": "rgba(0,107,92,1)",
+                            "secondary": "rgba(74,101,95,1)",
+                            "tertiary": "rgba(67,101,127,1)",
+                            "error": "rgba(186,16,16,1)",
+                            "success": "rgba(74,128,82,1)",
+                            "warning": "rgba(176,108,0,1)",
+                            "info": "rgba(37,123,167,1)",
+                            "background": "rgba(250,252,251,1)",
+                            "surface": "rgba(250,252,251,1)"
+                        },
+                        "on": {
+                            "primary": "rgba(182,254,238,1)",
+                            "secondary": "rgba(255,255,255,1)",
+                            "tertiary": "rgba(255,255,255,1)",
+                            "error": "rgba(255,255,255,1)",
+                            "success": "rgba(255,255,255,1)",
+                            "warning": "rgba(255,255,255,1)",
+                            "info": "rgba(255,255,255,1)",
+                            "background": "rgba(25,28,27,1)",
+                            "surface": "rgba(25,28,27,1)"
+                        },
+                        "container": {
+                            "primary": "rgba(101,250,222,1)",
+                            "secondary": "rgba(206,232,224,1)",
+                            "tertiary": "rgba(201,236,254,1)",
+                            "error": "rgba(255,218,214,1)",
+                            "success": "rgba(206,255,214,1)",
+                            "warning": "rgba(255,241,200,1)",
+                            "info": "rgba(217,241,255,1)"
+                        },
+                        "onContainer": {
+                            "primary": "rgba(0,32,27,1)",
+                            "secondary": "rgba(6,33,27,1)",
+                            "tertiary": "rgba(0,30,47,1)",
+                            "error": "rgba(65,0,2,1)",
+                            "success": "rgba(2,34,10,1)",
+                            "warning": "rgba(60,28,0,1)",
+                            "info": "rgba(0,31,54,1)"
+                        },
+                        "variant": {
+                            "surface": "rgba(233,240,238,1)"
+                        },
+                        "onVariant": {
+                            "surface": "rgba(63,73,71,1)"
+                        },
+                        "outline": "rgba(111,121,119,1)",
+                        "shadow": "rgba(0,0,0,1)",
+                        "scrim": "rgba(0,0,0,0.5)",
+                        "onMid": {
+                            "surface": "rgba(0,0,0,0.64)"
+                        },
+                        "onLow": {
+                            "surface": "rgba(0,0,0,0.32)"
+                        },
+                        "state": {
+                            "overlay": {
+                                "hover": {
+                                    "default": "rgba(0,0,0,0.32)",
+                                    "primary": "rgba(64,220,195,0.24)",
+                                    "error": "rgba(186,16,16,0.24)",
+                                    "warning": "rgba(176,108,0,0.24)",
+                                    "success": "rgba(74,128,82,0.24)",
+                                    "neutral": "rgba(91,95,94,0.24)",
+                                    "info": "rgba(37,123,167,0.24)"
+                                },
+                                "focus": {
+                                    "default": "rgba(0,0,0,0.64)",
+                                    "primary": "rgba(0,107,92,0.32)",
+                                    "error": "rgba(186,16,16,0.32)",
+                                    "warning": "rgba(176,108,0,0.32)",
+                                    "success": "rgba(74,128,82,0.32)",
+                                    "neutral": "rgba(91,95,94,0.32)",
+                                    "info": "rgba(37,123,167,0.32)"
+                                },
+                                "pressed": {
+                                    "default": "rgba(0,0,0,0.32)",
+                                    "primary": "rgba(0,107,92,0.32)",
+                                    "error": "rgba(186,16,16,0.32)",
+                                    "warning": "rgba(176,108,0,0.32)",
+                                    "success": "rgba(74,128,82,0.32)",
+                                    "neutral": "rgba(91,95,94,0.32)",
+                                    "info": "rgba(37,123,167,0.32)"
+                                },
+                                "disabled": {
+                                    "primary": "rgba(0,107,92,0.24)",
+                                    "error": "rgba(186,16,16,0.24)",
+                                    "warning": "rgba(176,108,0,0.24)",
+                                    "success": "rgba(74,128,82,0.24)",
+                                    "neutral": "rgba(91,95,94,0.08)",
+                                    "info": "rgba(37,123,167,0.24)"
+                                }
+                            },
+                            "border": {
+                                "disabled": {
+                                    "primary": "rgba(0,107,92,0.32)",
+                                    "error": "rgba(186,16,16,0.32)",
+                                    "warning": "rgba(176,108,0,0.32)",
+                                    "success": "rgba(74,128,82,0.32)",
+                                    "neutral": "rgba(91,95,94,0.32)",
+                                    "info": "rgba(37,123,167,0.32)"
+                                }
+                            },
+                            "content": {
+                                "disabled": {
+                                    "primary": "rgba(101,250,222,0.32)",
+                                    "error": "rgba(186,16,16,0.32)",
+                                    "warning": "rgba(176,108,0,0.32)",
+                                    "success": "rgba(74,128,82,0.32)",
+                                    "neutral": "rgba(91,95,94,0.32)",
+                                    "info": "rgba(37,123,167,0.32)"
+                                },
+                                "mid": {
+                                    "error": "rgba(255,255,255,1)"
+                                }
+                            }
+                        },
+                        "disabled": {
+                            "content": "rgba(0,0,0,0.24)"
+                        },
+                        "low": {
+                            "error": "rgba(186,16,16,0.32)",
+                            "warning": "rgba(176,108,0,0.32)",
+                            "success": "rgba(74,128,82,0.32)",
+                            "info": "rgba(37,123,167,0.32)"
+                        }
+                    },
+                    "content": {
+                        "text": {
+                            "high": "rgba(25,28,27,1)",
+                            "mid": "rgba(0,0,0,0.64)",
+                            "low": "rgba(0,0,0,0.32)",
+                            "disabled": "rgba(0,0,0,0.24)",
+                            "emphasized": "rgba(0,107,92,1)",
+                            "link": "rgba(0,107,92,1)",
+                            "onPrimary": "rgba(182,254,238,1)",
+                            "danger": "rgba(186,16,16,1)",
+                            "success": "rgba(74,128,82,1)",
+                            "warning": "rgba(176,108,0,1)",
+                            "info": "rgba(37,123,167,1)",
+                            "disabledWhite": "rgba(255,255,255,0.32)",
+                            "dangerLow": "rgba(186,16,16,0.32)",
+                            "warningLow": "rgba(176,108,0,0.32)",
+                            "successLow": "rgba(74,128,82,0.32)",
+                            "infoLow": "rgba(37,123,167,0.32)"
+                        },
+                        "icon": {
+                            "default": "rgba(63,73,71,1)",
+                            "emphasized": "rgba(0,107,92,1)",
+                            "disabled": "rgba(0,0,0,0.24)",
+                            "onPrimary": "rgba(182,254,238,1)",
+                            "danger": "rgba(186,16,16,1)",
+                            "success": "rgba(74,128,82,1)",
+                            "warning": "rgba(176,108,0,1)",
+                            "info": "rgba(37,123,167,1)",
+                            "low": "rgba(0,0,0,0.32)",
+                            "mid": "rgba(0,0,0,0.64)",
+                            "high": "rgba(25,28,27,1)",
+                            "disabledWhite": "rgba(255,255,255,0.32)"
+                        },
+                        "container": {
+                            "default": "rgba(250,252,251,1)",
+                            "subtle": "rgba(233,240,238,1)",
+                            "emphasized": "rgba(101,250,222,1)",
+                            "selected": "rgba(101,250,222,1)",
+                            "inverse": "rgba(182,254,238,1)",
+                            "overlay": "rgba(0,0,0,0.5)",
+                            "mid": "rgba(239, 240, 239, 1)",
+                            "danger": "rgba(255,218,214,1)",
+                            "success": "rgba(206,255,214,1)",
+                            "warning": "rgba(255,241,200,1)",
+                            "info": "rgba(217,241,255,1)",
+                            "primary": "rgba(0,107,92,1)"
+                        },
+                        "border": {
+                            "default": "rgba(111,121,119,1)",
+                            "subtle": "rgba(233,240,238,1)",
+                            "emphasized": "rgba(0,107,92,1)",
+                            "danger": "rgba(186,16,16,1)",
+                            "success": "rgba(74,128,82,1)",
+                            "disabled": "rgba(0,0,0,0.24)",
+                            "warning": "rgba(176,108,0,1)",
+                            "info": "rgba(37,123,167,1)"
+                        }
+                    },
+                    "project": {
+                        "moon": "#54A7EB",
+                        "sun": "#FFCF11"
+                    }
+                }
+            }
+        }
+    ]
+}

+ 0 - 2
example/web/.bundle/config

@@ -1,2 +0,0 @@
-BUNDLE_PATH: "vendor/bundle"
-BUNDLE_FORCE_RUBY_PLATFORM: 1

+ 0 - 32
example/web/App.tsx

@@ -1,32 +0,0 @@
-import React from 'react';
-import { StyleSheet, View, Pressable } from 'react-native';
-import {
-  setupNCoreUIKit,
-  Button,
-  Text
-} from "ncore-ui-kit-mobile";
-import { EyeClosed } from 'lucide-react-native';
-import Navigation from './src/navigation';
-
-const NCoreUIKitBase = setupNCoreUIKit({
-    initialSelectedGapPropagation: "spacious",
-    initialSelectedTheme: "light"
-});
-
-function App() {
-  return <AppContent />;
-}
-
-function AppContent() {
-  return <NCoreUIKitBase.Provider>
-    <Navigation/>
-  </NCoreUIKitBase.Provider>;
-}
-
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-  },
-});
-
-export default App;

+ 0 - 13
example/web/__tests__/App.test.tsx

@@ -1,13 +0,0 @@
-/**
- * @format
- */
-
-import React from 'react';
-import ReactTestRenderer from 'react-test-renderer';
-import App from '../App';
-
-test('renders correctly', async () => {
-  await ReactTestRenderer.act(() => {
-    ReactTestRenderer.create(<App />);
-  });
-});

+ 2 - 2
example/web/app.json

@@ -1,4 +1,4 @@
 {
-  "name": "ncoreuikitwebexample",
-  "displayName": "NİBGAT® | Official Website"
+    "name": "ncoreuikitwebexample",
+    "displayName": "NİBGAT® | Official Website"
 }

+ 11 - 8
example/web/babel.config.js

@@ -1,10 +1,13 @@
 module.exports = {
-  presets: ['module:@react-native/babel-preset'],
-  "plugins": [
-    ["module-resolver", {
-      "alias": {
-        "^react-native$": "react-native-web"
-      }
-    }]
-  ]
+    presets: ["module:@react-native/babel-preset"],
+    "plugins": [
+        [
+            "module-resolver",
+            {
+                "alias": {
+                    "^react-native$": "react-native-web"
+                }
+            }
+        ]
+    ]
 };

+ 0 - 9
example/web/index.js

@@ -1,9 +0,0 @@
-import { AppRegistry } from 'react-native';
-import App from './App';
-import { name as appName } from './app.json';
-
-AppRegistry.registerComponent(appName, () => App);
-AppRegistry.runApplication(appName, {
-  initialProps: {},
-  rootTag: document.getElementById('app-root')
-});

+ 18 - 0
example/web/index.tsx

@@ -0,0 +1,18 @@
+import {
+    createRoot
+} from "react-dom/client";
+import App from "../src/index";
+
+const originalWarn = console.warn;
+console.warn = (...args) => {
+    if (typeof args[0] === "string" && (
+        args[0].includes("pointerEvents") ||
+        args[0].includes("useNativeDriver") ||
+        args[0].includes("TouchableWithoutFeedback") ||
+        args[0].includes("Cannot record touch")
+    )) return;
+    originalWarn(...args);
+};
+
+const root = createRoot(document.getElementById("app-root")!);
+root.render(<App />);

+ 50 - 50
example/web/ios/nibgatofficialwebsite/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -1,53 +1,53 @@
 {
-  "images" : [
-    {
-      "idiom" : "iphone",
-      "scale" : "2x",
-      "size" : "20x20"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "3x",
-      "size" : "20x20"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "2x",
-      "size" : "29x29"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "3x",
-      "size" : "29x29"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "2x",
-      "size" : "40x40"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "3x",
-      "size" : "40x40"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "2x",
-      "size" : "60x60"
-    },
-    {
-      "idiom" : "iphone",
-      "scale" : "3x",
-      "size" : "60x60"
-    },
-    {
-      "idiom" : "ios-marketing",
-      "scale" : "1x",
-      "size" : "1024x1024"
+    "images" : [
+        {
+            "idiom" : "iphone",
+            "scale" : "2x",
+            "size" : "20x20"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "3x",
+            "size" : "20x20"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "2x",
+            "size" : "29x29"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "3x",
+            "size" : "29x29"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "2x",
+            "size" : "40x40"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "3x",
+            "size" : "40x40"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "2x",
+            "size" : "60x60"
+        },
+        {
+            "idiom" : "iphone",
+            "scale" : "3x",
+            "size" : "60x60"
+        },
+        {
+            "idiom" : "ios-marketing",
+            "scale" : "1x",
+            "size" : "1024x1024"
+        }
+    ],
+    "info" : {
+        "author" : "xcode",
+        "version" : 1
     }
-  ],
-  "info" : {
-    "author" : "xcode",
-    "version" : 1
-  }
 }

+ 4 - 4
example/web/ios/nibgatofficialwebsite/Images.xcassets/Contents.json

@@ -1,6 +1,6 @@
 {
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
+    "info" : {
+        "version" : 1,
+        "author" : "xcode"
+    }
 }

+ 4 - 4
example/web/jest.config.js

@@ -1,6 +1,6 @@
 module.exports = {
-  preset: '@react-native/jest-preset',
-  "moduleNameMapper": {
-    "^react-native$": "react-native-web"
-  }
+    preset: "@react-native/jest-preset",
+    "moduleNameMapper": {
+        "^react-native$": "react-native-web"
+    }
 };

+ 31 - 2
example/web/metro.config.js

@@ -1,4 +1,17 @@
-const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
+/* eslint-disable */
+
+const {
+    getDefaultConfig,
+    mergeConfig
+} = require("@react-native/metro-config");
+const path = require("path");
+
+const root = path.resolve(__dirname, "../..");
+const source = path.resolve(__dirname, "../src");
+
+const nodeModulesPaths = [
+    path.resolve(root, "node_modules")
+];
 
 /**
  * Metro configuration
@@ -6,6 +19,22 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
  *
  * @type {import('@react-native/metro-config').MetroConfig}
  */
-const config = {};
+const config = {
+};
+
+config.watchFolders = [
+    root,
+    source
+];
+
+config.resolver.extraNodeModules = {
+    "ncore-ui-kit": path.resolve(root, "src"),
+    "react": path.resolve(root, "node_modules/react"),
+    "react-native": path.resolve(root, "node_modules/react-native")
+};
+
+config.resolver.nodeModulesPaths = nodeModulesPaths;
+
+config.resolver.disableHierarchicalLookup = true;
 
 module.exports = mergeConfig(getDefaultConfig(__dirname), config);

+ 5 - 54
example/web/package.json

@@ -1,66 +1,17 @@
 {
-    "name": "ncore-ui-kit-mobile-example-web",
+    "name": "ncore-ui-kit-example-web",
     "version": "1.0.0-pre-alpha.0",
+    "main": "index.tsx",
     "type": "commonjs",
-    "main": "index.js",
     "private": true,
     "scripts": {
         "android": "react-native run-android",
         "ios": "react-native run-ios",
         "lint": "eslint .",
         "start": "react-native start",
-        "web": "webpack serve --config ./webpack.config.js",
-        "test": "jest"
-    },
-    "dependencies": {
-        "@react-native/new-app-screen": "0.85.3",
-        "@react-navigation/elements": "2.9.18",
-        "@react-navigation/native": "7.2.4",
-        "@react-navigation/native-stack": "7.15.1",
-        "lucide-react-native": "1.16.0",
-        "moment": "https://git.nibgat.space/nibgat-community/moment.git",
-        "ncore-context": "1.0.5",
-        "react": "19.2.3",
-        "react-dom": "19.2.3",
-        "react-native": "0.85.3",
-        "react-native-safe-area-context": "5.5.2",
-        "react-native-svg": "15.15.5",
-        "react-native-web": "0.21.2",
-        "rrule": "https://git.nibgat.space/nibgat-community/rrule.git"
-    },
-    "devDependencies": {
-        "@babel/core": "7.25.2",
-        "@babel/plugin-proposal-class-properties": "7.18.6",
-        "@babel/plugin-transform-modules-commonjs": "7.28.6",
-        "@babel/plugin-transform-private-methods": "7.28.6",
-        "@babel/plugin-transform-private-property-in-object": "7.28.6",
-        "@babel/preset-env": "7.25.3",
-        "@babel/preset-typescript": "7.28.5",
-        "@babel/runtime": "7.25.0",
-        "@react-native-community/cli": "20.1.0",
-        "@react-native-community/cli-platform-android": "20.1.0",
-        "@react-native-community/cli-platform-ios": "20.1.0",
-        "@react-native/babel-preset": "0.85.3",
-        "@react-native/eslint-config": "0.85.3",
-        "@react-native/jest-preset": "0.85.3",
-        "@react-native/metro-config": "0.85.3",
-        "@react-native/typescript-config": "0.85.3",
-        "@types/jest": "29.5.13",
-        "@types/react": "19.2.0",
-        "@types/react-test-renderer": "19.1.0",
-        "babel-loader": "10.1.1",
-        "babel-plugin-module-resolver": "5.0.3",
-        "babel-plugin-react-native-web": "0.21.2",
-        "eslint": "8.19.0",
-        "html-webpack-plugin": "5.6.7",
-        "jest": "29.6.3",
-        "prettier": "2.8.8",
-        "react-test-renderer": "19.2.3",
-        "typescript": "5.8.3",
-        "url-loader": "4.1.1",
-        "webpack": "5.107.1",
-        "webpack-cli": "7.0.2",
-        "webpack-dev-server": "5.2.4"
+        "test": "jest",
+        "web": "webpack serve --mode development --config ./webpack.config.js",
+        "web:build": "cross-env NODE_ENV=production webpack --mode production --config ./webpack.config.js"
     },
     "engines": {
         "node": ">= 22.11.0"

+ 21 - 24
example/web/public/index.html

@@ -1,27 +1,24 @@
 <!DOCTYPE html>
 <html>
-<head>
-  <meta charset="utf-8" />
-  <meta name="viewport" content="width=device-width, initial-scale=1" />
-  <link
-      rel="stylesheet"
-      href="https://fonts.nibgat.com/ncore.css"
-  />
-  <title>React Native Web Test</title>
-  <style>
-    /* Uygulamanın tüm ekrana yayılması için */
-    html, body, #app-root {
-      height: 100%;
-      margin: 0;
-      padding: 0;
-      display: flex;
-      flex-direction: column;
-    }
-  </style>
-</head>
-<body>
-  <div id="app-root"></div>
-  
-  <script src="/bundle.web.js"></script>
-</body>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <link
+            rel="stylesheet"
+            href="https://fonts.nibgat.com/ncore.css"
+        />
+        <title>React Native Web Test</title>
+        <style>
+            html, body, #app-root {
+                flex-direction: column;
+                display: flex;
+                height: 100%;
+                padding: 0;
+                margin: 0;
+            }
+        </style>
+    </head>
+    <body>
+        <div id="app-root"></div>
+    </body>
 </html>

BIN
example/web/src/assets/fonts/Geist-Black.ttf


BIN
example/web/src/assets/fonts/Geist-Bold.ttf


BIN
example/web/src/assets/fonts/Geist-ExtraBold.ttf


BIN
example/web/src/assets/fonts/Geist-ExtraLight.ttf


BIN
example/web/src/assets/fonts/Geist-Light.ttf


BIN
example/web/src/assets/fonts/Geist-Medium.ttf


BIN
example/web/src/assets/fonts/Geist-Regular.ttf


BIN
example/web/src/assets/fonts/Geist-SemiBold.ttf


BIN
example/web/src/assets/fonts/Geist-Thin.ttf


+ 0 - 46
example/web/src/navigation/index.tsx

@@ -1,46 +0,0 @@
-import {
-    NavigationContainer
-} from "@react-navigation/native";
-import {
-    createNativeStackNavigator
-} from "@react-navigation/native-stack";
-import Home from "../pages/home";
-import TestSubPage from "../pages/testSubPage";
-
-const RootStack = createNativeStackNavigator();
-
-const RootNav = () => {
-    return <RootStack.Navigator
-        initialRouteName="Home"
-    >
-        <RootStack.Screen
-            name="Home"
-            component={Home}
-        />
-        <RootStack.Screen
-            name="TestSubPage"
-            component={TestSubPage}
-        />
-    </RootStack.Navigator>;
-};
-
-const Navigation = () => {
-    return <NavigationContainer
-        linking={{
-            prefixes: [
-                'http://localhost:3000',
-                'https://nibgat.com.tr',
-                'https://nibgat.com'
-            ],
-            config: {
-                screens: {
-                    Home: '',
-                    TestSubPage: "test"
-                }
-            }
-        }}
-    >
-        <RootNav/>
-    </NavigationContainer>;
-};
-export default Navigation;

+ 0 - 618
example/web/src/pages/home/index.tsx

@@ -1,618 +0,0 @@
-import {
-    Fragment,
-    useState,
-    useRef
-} from "react";
-import {
-    View
-} from "react-native";
-import stylesheet from "./stylesheet";
-import {
-    NCoreUIKitBottomSheet,
-    NotificationIndicator,
-    getNCoreUIKitVersion,
-    type IBottomSheetRef,
-    NCoreUIKitSnackBar,
-    NCoreUIKitDialog,
-    NCoreUIKitToast,
-    NCoreUIKitTheme,
-    DateTimePicker,
-    MarkdownViewer,
-    PageContainer,
-    TextAreaInput,
-    BottomSheet,
-    RadioButton,
-    TextInput,
-    SelectBox,
-    CheckBox,
-    RowCard,
-    Button,
-    Dialog,
-    Switch,
-    Text
-} from "ncore-ui-kit-mobile";
-import {
-    useNavigation
-} from "@react-navigation/native";
-import type {
-    NativeStackNavigationProp
-} from "@react-navigation/native-stack";
-import type RootStackParamList from "../../navigation/type";
-import {
-    ChevronRight as ChevronRightIcon,
-    HomeIcon
-} from "lucide-react-native";
-import moment from "moment";
-
-const X = [
-    {
-        t: "xdfç.öhfdşkhdfşlhkfdşlhkdfşklhjmdfkhl3",
-        p: "ydfguıy8ı*pğ34erdx",
-        n: 90
-    },
-    {
-        t: "3t4uh5ıe6ıo6eıo6eoke6ıoke6ker6kr4ok",
-        p: "y3w46pjbd57ykdr",
-        n: 91
-    },
-    {
-        t: "xr*-0k4wkh-5w40k0*wek95ujk9*",
-        p: "y467o5*3evghe5",
-        n: 92
-    },
-    {
-        t: "x-40*tyg*0w4kyh*w0ko45u*ko0w",
-        p: "y3şçwl78570*fg",
-        n: 93
-    },
-    {
-        t: "*wrüsjh*ü9kws4*h0okdfhdhdfurdkex",
-        p: "yt7ıtot7ot",
-        n: 94
-    },
-    {
-        t: "x2-0*4woy-*w4opyu-*23wou*0wık*0jk",
-        p: "yasfa33",
-        n: 95
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    },
-    {
-        t: "x vmönöpwoı6-pğfş -*235*çda",
-        p: "ydfasdfasf",
-        n: 96
-    }
-];
-
-const Home = () => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const bottomSheetRef = useRef<IBottomSheetRef>(null);
-
-    const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
-
-    const [
-        isCheckboxActive,
-        setIsCheckboxActive
-    ] = useState<"partially" | "checked" | null>("checked");
-
-    const [
-        isDialogActive,
-        setIsDialogActive
-    ] = useState(false);
-
-    const [
-        isRadioActive,
-        setIsRadioActive
-    ] = useState(false);
-
-    const [
-        isSwitchActive,
-        setIsSwitchActive
-    ] = useState(false);
-
-    return <PageContainer
-        scrollViewStyle={stylesheet.container}
-        isScrollable={true}
-        scrollViewProps={{
-            showsHorizontalScrollIndicator: false,
-            showsVerticalScrollIndicator: false,
-            contentContainerStyle: {
-                backgroundColor: colors.content.container.default,
-                ...stylesheet.contentContainer
-            }
-        }}
-        renderOverlays={() => {
-            return <Fragment>
-                <Dialog
-                    isVisible={isDialogActive}
-                    content="etgweı09gı9w0eg"
-                    title="Merhaba Dünya!"
-                    contentJustify="centered"
-                    modalProps={{
-                        isWorkWithPortal: false
-                    }}
-                    onOverlayPress={({
-                        closeAnimation
-                    }) => {
-                        closeAnimation(() => setIsDialogActive(false));
-                    }}
-                    variant="yes-no"
-                    secondaryButtonProps={{
-                        title: "sdfgsdg",
-                        onPress: () => {
-
-                        }
-                    }}
-                    primaryButtonProps={{
-                        onPress: ({
-                            closeAnimation
-                        }) => {
-                            closeAnimation(() => setIsDialogActive(false));
-                        }
-                    }}
-                />
-                <BottomSheet
-                    ref={bottomSheetRef}
-                    renderHeader={() => {
-                        return <View
-                            style={[
-                                {
-                                    backgroundColor: "blue",
-                                    padding: 20
-                                }
-                            ]}
-                        >
-                            <Text>Burası header.</Text>
-                        </View>;
-                    }}
-                    isCanFullScreenOnSwipe={true}
-                    isWorkWithPortal={false}
-                    snapPoint={300}
-                    key="ahmet"
-                >
-                    <Button
-                        title="Open Toast"
-                        variant="filled"
-                        type="warning"
-                        onPress={() => {
-                            NCoreUIKitToast.open({
-                                title: "sdgfsdgsdg",
-                                type: "danger"
-                            });
-                        }}
-                    />
-                    <Button
-                        onPress={() => {
-                            navigation.navigate("TestSubPage");
-                        }}
-                        title="Git."
-                    />
-                    {[
-                        0,
-                        1,
-                        2,
-                        3,
-                        4,
-                        5,
-                        6,
-                        7,
-                        8,
-                        9,
-                        10,
-                        11,
-                        12,
-                        13,
-                        14,
-                        15,
-                        16,
-                        17,
-                        18,
-                        19,
-                        20,
-                        21,
-                        22,
-                        23,
-                        24,
-                        25,
-                        26,
-                        27,
-                        28,
-                        29,
-                        30,
-                        31,
-                        32,
-                        33,
-                        34,
-                        35
-                    ].map((it) => {
-                        return <View
-                            key={`fds-${it}`}
-                            style={{
-                                backgroundColor: `rgb(${it * 10}, ${it > 30 ? it * 5 : "0"}, ${it > 20 ? it * 4 : "0"})`,
-                                height: 150
-                            }}
-                        />;
-                    })}
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                    <Text>Deneme 123</Text>
-                </BottomSheet>
-            </Fragment>;
-        }}
-    >
-        <DateTimePicker
-            minDate={moment().subtract(2, "months").toDate()}
-            maxDate={moment().add(1, "months").toDate()}
-            isWorkWithRealtime={false}
-            spreadBehaviour="free"
-            isCleanEnabled={true}
-            variant="range"
-            initialDateRange={{
-                start: moment().subtract(2, "days").startOf("day").toDate(),
-                end: moment().add(6, "days").endOf("day").toDate()
-            }}
-            initialDate={new Date()}
-        />
-        <MarkdownViewer
-            content={`
-# Merhaba Furkan!.
-
-Nabersin ?
-
-<center>
-<link href="https://www.nibgat.com">
-## Deneme **title** 2
-</link>
-
-\`\`\`
-safasfasfasf
-\`\`\`
-</center>
-iyisindir **umarım.**
-
-\`\`\`
-Ahmet buraya gel.
-
-
-Geldin mi ?
-\`\`\`
-
-<<
-Burası alıntı metnidir.
->>
-
-* Merhaba __madd__e1.
-- Deneme madde2.
-
-[Alt text için deneme](https://static.vecteezy.com/system/resources/thumbnails/060/843/811/small/close-up-of-raindrops-on-leaves-hd-background-luxury-hd-wallpaper-image-trendy-background-illustration-free-photo.jpg)<100%x200>--cover--`}
-        />
-        <NotificationIndicator
-            type="danger"
-            title={53}
-        >
-            <Button
-                size="small"
-                icon={({
-                    color
-                }) => <HomeIcon
-                    color={colors.content.icon[color]}
-                />}
-                onPress={() => {
-
-                }}
-            />
-        </NotificationIndicator>
-        <Switch
-            spreadBehaviour="stretch"
-            isActive={isSwitchActive}
-            title="dsgojksdgpojk"
-            subTitle="SJFAJdfa"
-            isDisabled={false}
-            onPress={() => {
-                setIsSwitchActive(!isSwitchActive);
-            }}
-        />
-        <RowCard
-            title="Merhaba"
-            icon={({
-                color
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-            />}
-            rightIcon={({
-                color
-            }) => <ChevronRightIcon
-                color={colors.content.icon[color]}
-            />}
-        />
-        <RadioButton
-            isChecked={isRadioActive}
-            title="sadfasfsafasf"
-            isDisabled={false}
-            subTitle="asfgsaf"
-            onPress={() => {
-                setIsRadioActive(!isRadioActive);
-            }}
-        />
-        <CheckBox
-            isChecked={isCheckboxActive}
-            title="sadfasfsafasf"
-            isDisabled={false}
-            subTitle="asfgsaf"
-            onPress={() => {
-                setIsCheckboxActive(isCheckboxActive === "checked" ? null : isCheckboxActive === null ? "partially" : "checked");
-            }}
-        />
-        <TextAreaInput
-            isUpdateOnRealtime={true}
-            spreadBehaviour="stretch"
-            placeholder="efsdg"
-            maxLength={300}
-            title="Merhaba"
-            type="success"
-            isCleanEnabled={true}
-            icon={({
-                color
-            }) => <HomeIcon
-                color={colors.content.icon[color]}
-            />}
-        />
-        <SelectBox
-            keyExtractor={(data, index) => `${data.t}-${index}`}
-            titleExtractor={(data) => data.t}
-            initialSelectedItems={[{
-                __title: X[0]?.t as string,
-                __key: `${X[0]?.t}-0`
-            }]}
-            subTitle="Deneme Subtitle"
-            // isWorkWithRealtime={false}
-            isWorkWithRealtime={false}
-            spreadBehaviour="baseline"
-            isMultipleSelect={true}
-            isShowSubTitle={true}
-            hintText="Test deneme"
-            isCleanEnabled={true}
-            maxChoice={-1}
-            minChoice={0}
-            isSearchable={true}
-            title="Deneme Box"
-            isRequired={true}
-            data={X}
-            onMoreLoad={(props) => {
-                console.log("More Loaded:", props);
-            }}
-        />
-        <TextInput
-            variant="hidden"
-            placeholder="dsagdsag"
-        />
-        <Text>Version: v{getNCoreUIKitVersion()}</Text>
-        <Button
-            onPress={() => {
-                navigation.navigate("TestSubPage");
-            }}
-            title="Open Test Sub Page"
-            variant="filled"
-            spreadBehaviour="stretch"
-        />
-        <Button
-            onPress={() => {
-                bottomSheetRef.current?.open();
-            }}
-            type="success"
-            title="Open Local BottomSheet"
-            variant="filled"
-        />
-        <Button
-            onPress={() => {
-                NCoreUIKitBottomSheet.open({
-                    children: <View>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                        <Text>Deneme 123</Text>
-                    </View>
-                });
-            }}
-            type="success"
-            title="Open BottomSheet"
-            variant="filled"
-        />
-        <Button
-            onPress={() => {
-                setIsDialogActive(!isDialogActive);
-            }}
-            type="neutral"
-            title="Open Local Dialog"
-            variant="filled"
-        />
-        <Button
-            title="Open Snackbar"
-            variant="filled"
-            type="danger"
-            onPress={() => {
-                NCoreUIKitSnackBar.open({
-                    title: "sdgdsgs",
-                    icon: ({
-                        color
-                    }) => <HomeIcon color={colors.content.icon[color ? color : "default"]}/>
-                });
-            }}
-        />
-        <Button
-            onPress={() => {
-                NCoreUIKitDialog.open({
-                    content: "etgweı09gı9w0eg",
-                    title: "Merhaba Dünya!",
-                    isVisible: true,
-                    onOverlayPress: ({
-                        closeAnimation
-                    }) => {
-                        closeAnimation();
-                    },
-                    variant: "info",
-                    secondaryButtonProps: {
-                        title: "sdfgsdg",
-                        onPress: () => {
-
-                        }
-                    },
-                    primaryButtonProps: {
-                        onPress: ({
-                            closeAnimation
-                        }) => {
-                            closeAnimation();
-                        }
-                    }
-                });
-            }}
-            type="neutral"
-            title="Open Dialog"
-            variant="filled"
-        />
-        <Button
-            title="Open Toast"
-            variant="filled"
-            type="warning"
-            onPress={() => {
-                NCoreUIKitToast.open({
-                    title: "sdgfsdgsdafs sdlşlgkdfşiklh",
-                    subTitle: "tr9uıdgfss 0dgklsd",
-                    isShowAction: true,
-                    icon: ({
-                        color
-                    }) => <HomeIcon color={colors.content.icon[color ? color : "default"]}/>
-                });
-            }}
-        />
-    </PageContainer>;
-};
-export default Home;

+ 0 - 61
example/web/src/pages/testSubPage/index.tsx

@@ -1,61 +0,0 @@
-import {
-    useRef
-} from "react";
-import {
-    View
-} from "react-native";
-import stylesheet from "./stylesheet";
-import {
-    type IBottomSheetRef,
-    PageContainer,
-    BottomSheet,
-    Button,
-    Text
-} from "ncore-ui-kit-mobile";
-
-const TestSubPage = () => {
-    const bottomSheetRef = useRef<IBottomSheetRef>(null);
-
-    return <PageContainer
-        style={[
-            stylesheet.container
-        ]}
-    >
-        <Text>This is test sub page.</Text>
-        <Button
-            onPress={() => {
-                bottomSheetRef.current?.open();
-            }}
-            type="success"
-            title="Ahmet"
-            variant="filled"
-        />
-        <BottomSheet
-            isCanFullScreenOnSwipe={true}
-            isWorkWithPortal={false}
-            ref={bottomSheetRef}
-            snapPoint={300}
-        >
-            <Button
-                onPress={() => {
-
-                }}
-                title="Git."
-            />
-            <View
-                style={{
-                    backgroundColor: "red",
-                    height: 2400
-                }}
-            />
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-            <Text>Deneme 123</Text>
-        </BottomSheet>
-    </PageContainer>;
-};
-export default TestSubPage;

+ 0 - 10
example/web/src/pages/testSubPage/stylesheet.ts

@@ -1,10 +0,0 @@
-import {
-    StyleSheet
-} from "react-native";
-
-const stylesheet = StyleSheet.create({
-    container: {
-        flex: 1
-    }
-});
-export default stylesheet;

+ 17 - 6
example/web/tsconfig.json

@@ -1,8 +1,19 @@
 {
-  "extends": "@react-native/typescript-config",
-  "compilerOptions": {
-    "types": ["jest"]
-  },
-  "include": ["**/*.ts", "**/*.tsx"],
-  "exclude": ["**/node_modules", "**/Pods"]
+    "extends": "../../tsconfig.json",
+    "compilerOptions": {
+        "types": [
+            "node"
+        ]
+    },
+    "include": [
+        "../src/**/*",
+        "**/*.json",
+        "**/*.tsx",
+        "**/*.ts",
+        "../../src/assets/svg/nibgatIcon"
+    ],
+    "exclude": [
+        "**/node_modules",
+        "**/Pods"
+    ]
 }

+ 69 - 17
example/web/webpack.config.js

@@ -1,26 +1,35 @@
-const path = require("path");
-const webpack = require("webpack");
+/* eslint-disable */
+
 const HtmlWebpackPlugin = require("html-webpack-plugin");
+const ESLintPlugin = require("eslint-webpack-plugin");
+const CopyPlugin = require("copy-webpack-plugin");
+const webpack = require("webpack");
+const path = require("path");
 
 const appDirectory = path.resolve(__dirname, "./");
+const srcDirectory = path.resolve(__dirname, "../src");
 const rootDirectory = path.resolve(__dirname, "../../");
 
 const babelLoaderConfiguration = {
     test: /\.(tsx|ts|js|jsx)$/,
     include: [
-        path.resolve(appDirectory, "index.js"),
-        path.resolve(appDirectory, "App.tsx"),
-        path.resolve(appDirectory, "src"),
+        path.resolve(appDirectory, "index.tsx"),
+        path.resolve(srcDirectory, "index.tsx"),
+        path.resolve(srcDirectory),
 
         path.resolve(rootDirectory, "src"),
 
-        path.resolve(appDirectory, "node_modules/@react-navigation/native-stack"),
-        path.resolve(appDirectory, "node_modules/@react-native/new-app-screen"),
-        path.resolve(appDirectory, "node_modules/@react-navigation/elements"),
-        path.resolve(appDirectory, "node_modules/@react-navigation/native"),
-        path.resolve(appDirectory, "node_modules/react-native-uncompiled"),
-        path.resolve(appDirectory, "node_modules/lucide-react-native"),
-        path.resolve(appDirectory, "node_modules/react-native")
+        path.resolve(rootDirectory, "node_modules/@react-navigation/native-stack"),
+        path.resolve(rootDirectory, "node_modules/@react-native/new-app-screen"),
+        path.resolve(rootDirectory, "node_modules/@react-navigation/elements"),
+        path.resolve(rootDirectory, "node_modules/@react-navigation/native"),
+        path.resolve(rootDirectory, "node_modules/react-native-uncompiled"),
+        path.resolve(rootDirectory, "node_modules/lucide-react-native"),
+        path.resolve(rootDirectory, "node_modules/react-native"),
+
+        path.resolve(rootDirectory, "node_modules/expo-font"),
+        path.resolve(rootDirectory, "node_modules/expo-modules-core"),
+        path.resolve(rootDirectory, "node_modules/expo-asset")
     ],
     use: {
         loader: "babel-loader",
@@ -50,7 +59,7 @@ const imageLoaderConfiguration = {
 
 module.exports = {
     entry: [
-        path.resolve(appDirectory, "index.js")
+        path.resolve(appDirectory, "index.tsx")
     ],
     mode: "development",
     devtool: "source-map",
@@ -63,6 +72,7 @@ module.exports = {
         port: 3000,
         historyApiFallback: true,
         client: {
+            logging: "none",
             overlay: {
                 errors: true,
                 warnings: false
@@ -77,7 +87,7 @@ module.exports = {
             module: /@react-navigation/
         },
         {
-            module: /ncore-ui-kit-mobile/
+            module: /ncore-ui-kit/
         }
     ],
     module: {
@@ -87,7 +97,7 @@ module.exports = {
             {
                 test: /\.(js|mjs|jsx)$/,
                 include: [
-                    path.resolve(appDirectory, "node_modules/@react-navigation")
+                    path.resolve(rootDirectory, "node_modules/@react-navigation")
                 ],
                 type: "javascript/auto",
                 resolve: {
@@ -98,6 +108,13 @@ module.exports = {
                 test: /\.mjs$/,
                 include: /node_modules/,
                 type: "javascript/auto"
+            },
+            {
+                test: /\.(ttf|otf|eot|woff|woff2)$/,
+                type: "asset/resource",
+                generator: {
+                    filename: "../src/assets/fonts/[name][ext]"
+                }
             }
         ]
     },
@@ -107,13 +124,49 @@ module.exports = {
             filename: "index.html"
         }),
         new webpack.DefinePlugin({
+            "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
             __DEV__: JSON.stringify(process.env.NODE_ENV !== "production"),
+            "__REACT_DEVTOOLS_GLOBAL_HOOK__": "({ isDisabled: true })",
+            "process.env.EXPO_OS": JSON.stringify("web"),
+            "process.env": JSON.stringify({})
+        }),
+        new ESLintPlugin({
+            overrideConfigFile: path.resolve(rootDirectory, "eslint.config.mjs"),
+            failOnError: process.env.NODE_ENV === "production",
+            exclude: [
+                path.resolve(rootDirectory, "node_modules"),
+                path.resolve(appDirectory, "dist")
+            ],
+            eslintPath: "eslint/use-at-your-own-risk",
+            configType: "flat",
+            emitWarning: true,
+            extensions: [
+                "tsx",
+                "jsx",
+                "ts",
+                "js"
+            ]
+        }),
+        new CopyPlugin({
+            patterns: [
+                {
+                    globOptions: {
+                        ignore: [
+                            "**/index.html"
+                        ]
+                    },
+                    noErrorOnMissing: true,
+                    from: "public",
+                    to: "."
+                }
+            ]
         })
     ],
     resolve: {
+        symlinks: false,
         alias: {
             "react-native$": "react-native-web",
-            "ncore-ui-kit-mobile": path.resolve(rootDirectory, "src/index")
+            "ncore-ui-kit": path.resolve(rootDirectory, "src/index")
         },
         extensions: [
             ".web.tsx",
@@ -125,7 +178,6 @@ module.exports = {
             ".mjs"
         ],
         modules: [
-            path.resolve(appDirectory, "node_modules"),
             path.resolve(rootDirectory, "node_modules"),
             "node_modules"
         ]

+ 66 - 22
package.json

@@ -1,6 +1,6 @@
 {
-    "name": "ncore-ui-kit-mobile",
-    "version": "1.0.0-pre-alpha.23",
+    "name": "ncore-ui-kit",
+    "version": "1.0.0-pre-alpha.1",
     "description": "NİBGAT® | NCore - UI Kit for React-Native Mobile Apps.",
     "main": "./lib/module/index.js",
     "types": "./lib/typescript/src/index.d.ts",
@@ -32,12 +32,12 @@
         "!**/.*"
     ],
     "scripts": {
-        "example-mobile": "yarn workspace ncore-ui-kit-mobile-example-mobile",
-        "example-web": "yarn workspace ncore-ui-kit-mobile-example-web",
+        "example-mobile": "yarn workspace ncore-ui-kit-example-mobile",
+        "example-web": "yarn workspace ncore-ui-kit-example-web",
         "clean": "del-cli lib",
         "lint": "eslint . --ext .ts,.tsx --fix",
         "prepare": "bob build && copyfiles -u 1 \"src/variants/**/*.json\" lib/typescript/src/ && node version.mjs",
-        "typecheck": "tsc",
+        "typecheck": "tsc -p tsconfig.build.json",
         "release": "release-it --only-version",
         "build": "yarn clean && yarn lint && yarn typecheck && yarn prepare && npm publish"
     },
@@ -60,27 +60,55 @@
     ],
     "repository": {
         "type": "git",
-        "url": "git+https://git.nibgat.space/nibgat-community/ncore-ui-kit-mobile.git.git"
+        "url": "git+https://git.nibgat.space/nibgat-community/ncore-ui-kit.git.git"
     },
     "author": "nibgat <development@nibgat.com> (https://git.nibgat.space/nibgat-community)",
     "license": "MIT",
     "bugs": {
-        "url": "https://git.nibgat.space/nibgat-community/ncore-ui-kit-mobile.git/issues"
+        "url": "https://git.nibgat.space/nibgat-community/ncore-ui-kit.git/issues"
     },
-    "homepage": "https://git.nibgat.space/nibgat-community/ncore-ui-kit-mobile.git#readme",
+    "homepage": "https://git.nibgat.space/nibgat-community/ncore-ui-kit.git#readme",
     "publishConfig": {
         "registry": "https://registry.npmjs.org/"
     },
     "devDependencies": {
-        "@react-native/babel-preset": "0.83.0",
-        "@react-native/typescript-config": "^0.86.0",
+        "@babel/core": "7.25.2",
+        "@babel/plugin-proposal-class-properties": "7.18.6",
+        "@babel/plugin-transform-modules-commonjs": "7.28.6",
+        "@babel/plugin-transform-private-methods": "7.28.6",
+        "@babel/plugin-transform-private-property-in-object": "7.28.6",
+        "@babel/preset-env": "7.25.3",
+        "@babel/preset-typescript": "7.28.5",
+        "@babel/runtime": "7.25.0",
+        "@expo/metro-runtime": "56.0.15",
+        "@react-native-community/cli": "20.1.0",
+        "@react-native-community/cli-platform-android": "20.1.0",
+        "@react-native-community/cli-platform-ios": "20.1.0",
+        "@react-native/babel-preset": "0.85.3",
+        "@react-native/eslint-config": "0.85.3",
+        "@react-native/jest-preset": "0.85.3",
+        "@react-native/metro-config": "0.85.3",
+        "@react-native/new-app-screen": "0.85.3",
+        "@react-native/typescript-config": "0.85.3",
+        "@react-navigation/elements": "2.9.18",
+        "@react-navigation/native": "7.2.4",
+        "@react-navigation/native-stack": "7.15.1",
         "@release-it/conventional-changelog": "10.0.1",
         "@types/copyfiles": "2",
         "@types/eslint-plugin-jsx-a11y": "6",
-        "@types/react": "19.2.14",
+        "@types/jest": "29.5.13",
+        "@types/node": "25.9.3",
+        "@types/react": "19.2.0",
+        "@types/react-dom": "19.2.3",
         "@types/react-native": "0.73.0",
-        "babel-plugin-module-resolver": "5.0.2",
+        "@types/react-test-renderer": "19.1.0",
+        "babel-loader": "10.1.1",
+        "babel-plugin-module-resolver": "5.0.3",
+        "babel-plugin-react-native-web": "0.21.2",
+        "babel-preset-expo": "56.0.15",
+        "copy-webpack-plugin": "11.0.0",
         "copyfiles": "2.4.1",
+        "cross-env": "10.1.0",
         "del-cli": "6.0.0",
         "eslint": "9.37.0",
         "eslint-import-resolver-typescript": "4.4.4",
@@ -91,20 +119,35 @@
         "eslint-plugin-react": "7.37.5",
         "eslint-plugin-react-hooks": "7.0.0",
         "eslint-plugin-react-native": "5.0.0",
+        "eslint-webpack-plugin": "5.0.1",
+        "expo": "56.0.11",
+        "expo-font": "56.0.6",
+        "expo-status-bar": "56.0.4",
         "globals": "17.4.0",
+        "html-webpack-plugin": "5.6.7",
+        "jest": "29.6.3",
         "jsonc-eslint-parser": "2.4.1",
-        "react": "19.2.6",
-        "react-native": "0.83.2",
+        "react": "19.2.3",
+        "react-dom": "19.2.3",
+        "react-native": "0.85.3",
         "react-native-builder-bob": "0.40.13",
+        "react-native-monorepo-config": "0.3.3",
+        "react-native-screens": "4.24.0",
+        "react-native-web": "0.21.2",
+        "react-test-renderer": "19.2.3",
         "release-it": "19.0.4",
         "turbo": "2.5.6",
         "typescript": "5.9.3",
-        "typescript-eslint": "8.46.1"
+        "typescript-eslint": "8.46.1",
+        "url-loader": "4.1.1",
+        "webpack": "5.107.1",
+        "webpack-cli": "7.0.2",
+        "webpack-dev-server": "5.2.4"
     },
     "peerDependencies": {
-        "lucide-react-native": ">= 0.577.0",
+        "lucide-react-native": ">= 1.16.0",
         "moment": "*",
-        "ncore-context": ">= 1.0.5",
+        "ncore-context": ">= 1.0.7",
         "react": "*",
         "react-native": "*",
         "react-native-safe-area-context": ">= 5.7.0",
@@ -113,7 +156,8 @@
     },
     "workspaces": [
         "example/mobile",
-        "example/web"
+        "example/web",
+        "example/src"
     ],
     "packageManager": "yarn@4.11.0",
     "react-native-builder-bob": {
@@ -162,11 +206,11 @@
         "version": "0.57.2"
     },
     "dependencies": {
-        "lucide-react-native": "0.577.0",
+        "lucide-react-native": "1.16.0",
         "moment": "https://git.nibgat.space/nibgat-community/moment.git",
-        "ncore-context": "1.0.5",
-        "react-native-safe-area-context": "5.7.0",
-        "react-native-svg": "15.15.3",
+        "ncore-context": "1.0.8",
+        "react-native-safe-area-context": "5.5.2",
+        "react-native-svg": "15.15.5",
         "rrule": "https://git.nibgat.space/nibgat-community/rrule.git"
     }
 }

+ 0 - 42
src/assets/svg/badgeAlertIcon/index.tsx

@@ -1,42 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgBadgeAlertIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    const finalColor = customColor ? customColor : colors.content.icon[color];
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="M10 6.667V10m0 3.333h.008m-6.8-6.15a3.333 3.333 0 0 1 3.984-3.975 3.333 3.333 0 0 1 5.616 0 3.333 3.333 0 0 1 3.984 3.984 3.333 3.333 0 0 1 0 5.616 3.333 3.333 0 0 1-3.975 3.984 3.333 3.333 0 0 1-5.625 0 3.333 3.333 0 0 1-3.984-3.975 3.335 3.335 0 0 1 0-5.634Z"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-    </Svg>;
-};
-export default SvgBadgeAlertIcon;

+ 0 - 40
src/assets/svg/badgeDangerIcon/index.tsx

@@ -1,40 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgBadgeDangerIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="m12.5 7.5-5 5m0-5 5 5M3.208 7.183a3.333 3.333 0 0 1 3.984-3.975 3.333 3.333 0 0 1 5.616 0 3.333 3.333 0 0 1 3.984 3.984 3.333 3.333 0 0 1 0 5.616 3.333 3.333 0 0 1-3.975 3.984 3.333 3.333 0 0 1-5.625 0 3.333 3.333 0 0 1-3.984-3.975 3.335 3.335 0 0 1 0-5.634Z"
-            stroke={customColor ? customColor : colors.content.icon[color]}
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-        />
-    </Svg>;
-};
-export default SvgBadgeDangerIcon;

+ 0 - 40
src/assets/svg/badgeInfoIcon/index.tsx

@@ -1,40 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgBadgeInfoIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="M10 13.333V10m0-3.333h.008m-6.8.516a3.333 3.333 0 0 1 3.984-3.975 3.333 3.333 0 0 1 5.616 0 3.333 3.333 0 0 1 3.984 3.984 3.333 3.333 0 0 1 0 5.616 3.333 3.333 0 0 1-3.975 3.984 3.333 3.333 0 0 1-5.625 0 3.333 3.333 0 0 1-3.984-3.975 3.335 3.335 0 0 1 0-5.634Z"
-            stroke={customColor ? customColor : colors.content.icon[color]}
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-        />
-    </Svg>;
-};
-export default SvgBadgeInfoIcon;

+ 0 - 50
src/assets/svg/badgeQuestionMarkIcon/index.tsx

@@ -1,50 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgBadgeQuestionMarkIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    const finalColor = customColor ? customColor : colors.content.icon[color];
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="m12.5 7.5-5 5m0-5 5 5M3.208 7.183a3.333 3.333 0 0 1 3.984-3.975 3.333 3.333 0 0 1 5.616 0 3.333 3.333 0 0 1 3.984 3.984 3.333 3.333 0 0 1 0 5.616 3.333 3.333 0 0 1-3.975 3.984 3.333 3.333 0 0 1-5.625 0 3.333 3.333 0 0 1-3.984-3.975 3.335 3.335 0 0 1 0-5.634Z"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-        <Path
-            d="M7.575 7.5a2.5 2.5 0 0 1 4.858.833c0 1.667-2.5 2.5-2.5 2.5M10 14.167h.008"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinecap="round"
-            strokeLinejoin="round"
-            stroke={finalColor}
-            strokeWidth={1.167}
-        />
-    </Svg>;
-};
-export default SvgBadgeQuestionMarkIcon;

+ 0 - 40
src/assets/svg/badgeRightIcon/index.tsx

@@ -1,40 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgChevronRight = ({
-    color = "default",
-    customColor,
-    size = 30,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 26 / size;
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            stroke={customColor ? customColor : colors.content.icon[color]}
-            transform={`scale(${1 / pathScale})`}
-            d="m7.5 24 11-11-11-11"
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.55}
-        />
-    </Svg>;
-};
-export default SvgChevronRight;

+ 0 - 50
src/assets/svg/badgeSuccessIcon/index.tsx

@@ -1,50 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgBadgeSuccessIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    const finalColor = customColor ? customColor : colors.content.icon[color];
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="m12.5 7.5-5 5m0-5 5 5M3.208 7.183a3.333 3.333 0 0 1 3.984-3.975 3.333 3.333 0 0 1 5.616 0 3.333 3.333 0 0 1 3.984 3.984 3.333 3.333 0 0 1 0 5.616 3.333 3.333 0 0 1-3.975 3.984 3.333 3.333 0 0 1-5.625 0 3.333 3.333 0 0 1-3.984-3.975 3.335 3.335 0 0 1 0-5.634Z"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-        <Path
-            transform={`scale(${1 / pathScale})`}
-            d="m7.5 10 1.667 1.667L12.5 8.333"
-            strokeLinecap="round"
-            strokeLinejoin="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-    </Svg>;
-};
-export default SvgBadgeSuccessIcon;

Разница между файлами не показана из-за своего большого размера
+ 26 - 0
src/assets/svg/cayCoreIcon/index.tsx


+ 0 - 40
src/assets/svg/chevronRightIcon/index.tsx

@@ -1,40 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgChevronRight = ({
-    color = "default",
-    customColor,
-    size = 30,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 26 / size;
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            stroke={customColor ? customColor : colors.content.icon[color]}
-            transform={`scale(${1 / pathScale})`}
-            d="m7.5 24 11-11-11-11"
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.55}
-        />
-    </Svg>;
-};
-export default SvgChevronRight;

+ 0 - 40
src/assets/svg/cleanIcon/index.tsx

@@ -1,40 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgCleanIcon = ({
-    color = "default",
-    customColor,
-    size = 20,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 27 / size;
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="M13.5 25C19.851 25 25 19.851 25 13.5S19.851 2 13.5 2 2 7.149 2 13.5 7.149 25 13.5 25ZM16.95 10.05l-6.9 6.9m0-6.9 6.9 6.9"
-            stroke={customColor ? customColor : colors.content.icon[color]}
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.25}
-        />
-    </Svg>;
-};
-export default SvgCleanIcon;

+ 0 - 50
src/assets/svg/eyeClosedIcon/index.tsx

@@ -1,50 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgEyeClosed = ({
-    color = "default",
-    customColor,
-    size = 30,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    const finalColor = customColor ? customColor : colors.content.icon[color];
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="M8.958 4.233a8.954 8.954 0 0 1 9.338 5.48c.069.187.069.392 0 .58a9.002 9.002 0 0 1-1.204 2.075m-5.341-.566a2.5 2.5 0 0 1-3.536-3.535"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-        <Path
-            d="M14.58 14.586a8.957 8.957 0 0 1-12.848-4.293.833.833 0 0 1 0-.58 8.958 8.958 0 0 1 3.705-4.285M1.68 1.67l16.667 16.667"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            strokeWidth={1.167}
-            stroke={finalColor}
-        />
-    </Svg>;
-};
-export default SvgEyeClosed;

+ 0 - 50
src/assets/svg/eyeOpenedIcon/index.tsx

@@ -1,50 +0,0 @@
-import {
-    NCoreUIKitTheme
-} from "../../../core/hooks";
-import {
-    type INCoreUIKitIconProps
-} from "../../../types";
-import {
-    Path,
-    Svg
-} from "react-native-svg";
-
-const SvgEyeOpened = ({
-    color = "default",
-    customColor,
-    size = 30,
-    ...props
-}: INCoreUIKitIconProps) => {
-    const {
-        colors
-    } = NCoreUIKitTheme.useContext();
-
-    const pathScale = 20 / size;
-
-    const finalColor = customColor ? customColor : colors.content.icon[color];
-
-    return <Svg
-        height={size}
-        width={size}
-        fill="none"
-        {...props}
-    >
-        <Path
-            d="M1.732 10.293a.833.833 0 0 1 0-.58 8.958 8.958 0 0 1 16.563 0c.07.187.07.393 0 .58a8.958 8.958 0 0 1-16.563 0Z"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            stroke={finalColor}
-            strokeWidth={1.167}
-        />
-        <Path
-            d="M10.014 12.503a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Z"
-            transform={`scale(${1 / pathScale})`}
-            strokeLinejoin="round"
-            strokeLinecap="round"
-            stroke={finalColor}
-            strokeWidth={1.167}
-        />
-    </Svg>;
-};
-export default SvgEyeOpened;

+ 6 - 30
src/assets/svg/index.ts

@@ -3,37 +3,13 @@ export {
 } from "./loadingIcon";
 
 export {
-    default as CleanIcon
-} from "./cleanIcon";
+    default as NIBGATIcon
+} from "./nibgatIcon";
 
 export {
-    default as ChevronRightIcon
-} from "./chevronRightIcon";
+    default as NIBGATCommunityIcon
+} from "./nibgatCommunityIcon";
 
 export {
-    default as EyeClosedIcon
-} from "./eyeClosedIcon";
-
-export {
-    default as EyeOpenedIcon
-} from "./eyeOpenedIcon";
-
-export {
-    default as BadgeInfoIcon
-} from "./badgeInfoIcon";
-
-export {
-    default as BadgeDangerIcon
-} from "./badgeDangerIcon";
-
-export {
-    default as BadgeSuccessIcon
-} from "./badgeSuccessIcon";
-
-export {
-    default as BadgeQuestionMarkIcon
-} from "./badgeQuestionMarkIcon";
-
-export {
-    default as BadgeAlertIcon
-} from "./badgeAlertIcon";
+    default as CayCoreIcon
+} from "./cayCoreIcon";

+ 4 - 3
src/assets/svg/loadingIcon/index.tsx

@@ -4,6 +4,7 @@ import {
 } from "react";
 import {
     Animated,
+    Platform,
     Easing,
     View
 } from "react-native";
@@ -18,7 +19,7 @@ import {
     Svg
 } from "react-native-svg";
 
-const SvgLoadingIcon = ({
+const LoadingIcon = ({
     color = "emphasized",
     customColor,
     size = 22,
@@ -38,7 +39,7 @@ const SvgLoadingIcon = ({
                 toValue: 1,
                 duration: 2000,
                 easing: Easing.linear,
-                useNativeDriver: true
+                useNativeDriver: Platform.OS !== "web"
             })
         );
 
@@ -92,4 +93,4 @@ const SvgLoadingIcon = ({
         </Animated.View>
     </View>;
 };
-export default SvgLoadingIcon;
+export default LoadingIcon;

+ 60 - 0
src/assets/svg/nibgatCommunityIcon/index.tsx

@@ -0,0 +1,60 @@
+import {
+    NCoreUIKitTheme
+} from "../../../core/hooks";
+import type {
+    INCoreUIKitIconProps
+} from "../../../types";
+import Svg, {
+    Path,
+    Defs,
+    G
+} from "react-native-svg";
+
+const NIBGATCommunityIcon = ({
+    customColor = "#00c2a9",
+    size = 30,
+    color,
+    style,
+    ...props
+}: INCoreUIKitIconProps) => {
+    const {
+        colors
+    } = NCoreUIKitTheme.useContext();
+
+    const pathScale = 3543 / size;
+
+    const strokeWidth = (size * 2.362) / 3543;
+
+    return <Svg
+        fillRule="evenodd"
+        clipRule="evenodd"
+        height={size}
+        width={size}
+        style={{
+            ...style
+        }}
+        {...props}
+    >
+        <Defs></Defs>
+        <G id="Layer_x0020_1">
+            <Path
+                d="m1263 780 127-220 127-221h509l127 221 127 220-127 220-127 221h-509l-127-221zM2121 1276l128-221 127-220h509l127 220 127 221-127 220-127 220h-509l-127-220zM2121 2267l128-220 127-220h509l127 220 127 220-127 221-127 220h-509l-127-220zM1263 2763l127-220 127-221h509l127 221 127 220-127 220-127 221h-509l-127-221zM404 2267l127-220 127-220h509l127 220 128 220-128 221-127 220H658l-127-220zM404 1276l127-221 127-220h509l127 220 128 221-128 220-127 220H658l-127-220z"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+            <Path
+                d="m1263 1772 127-221 127-220h509l127 220 127 221-127 220-127 220h-509l-127-220-127-220zm599-215h0c9-5 21-2 26 6l114 199c2 3 3 6 3 10 0 3-1 6-3 9l-113 197c-2 4-5 7-9 9h0c-9 4-20 1-25-8l-185-368-92 161 109 189c5 9 2 20-6 25h0c-9 5-21 2-26-6l-114-199c-2-3-3-6-3-10 0-3 1-6 3-9l113-197c2-4 5-7 9-9h0c9-4 20-1 25 8l185 368 92-160-109-190c-5-9-2-20 6-25z"
+                stroke={color ? colors.content.icon[color] : customColor}
+                fill={color ? colors.content.icon[color] : customColor}
+                strokeWidth={strokeWidth}
+                strokeLinejoin="round"
+                strokeLinecap="round"
+                transform={[{
+                    scale: 1 / pathScale
+                }]}
+            />
+        </G>
+    </Svg>;
+};
+export default NIBGATCommunityIcon;

+ 96 - 0
src/assets/svg/nibgatIcon/index.tsx

@@ -0,0 +1,96 @@
+import type {
+    INCoreUIKitIconProps
+} from "../../../types";
+import Svg, {
+    LinearGradient,
+    Path,
+    Defs,
+    Stop
+} from "react-native-svg";
+
+const NIBGATIcon = ({
+    size = 30,
+    style,
+    ...props
+}: INCoreUIKitIconProps) => {
+    const pathScale = 620 / size;
+
+    return <Svg
+        height={size}
+        width={size}
+        fill="none"
+        {...props}
+        style={{
+            ...style
+        }}
+    >
+        <Path
+            d="m171.363 110.098 138.558-80.013 138.557 80.013v159.987l138.18 79.635v159.987L448.1 589.72l-137.801-80.013-138.558 80.013-138.557-80.013V349.72l138.179-79.635V110.098Z"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+            fillOpacity={0.922}
+            clipRule="evenodd"
+            fillRule="evenodd"
+            fill="url(#a)"
+        />
+        <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"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+            strokeOpacity={0.69}
+            strokeWidth={6.65}
+            clipRule="evenodd"
+            stroke="#323232"
+        />
+        <Path
+            d="m353.574 123.024 25.625-52.914M397.229 198.652h51.25M266.267 123.023l-29.329-50.796M222.614 198.652h-51.251M484.572 349.908l25.512-44.296M528.227 425.537h58.431M484.572 501.165l29.216 50.646M397.227 501.165l-25.625 44.145M222.613 501.165l25.625 44.372M135.268 501.165l-29.215 50.646M91.615 425.537H33.184M135.268 349.908l-25.512-44.296"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+            strokeOpacity={0.69}
+            strokeWidth={5.669}
+            stroke="#323232"
+        />
+        <Path
+            d="m222.613 349.909 21.808-37.796 21.846-37.833h87.307l21.846 37.833 21.807 37.796-21.807 37.795-21.846 37.833h-87.307l-21.846-37.833-21.808-37.795Z"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+            strokeWidth={6.65}
+            clipRule="evenodd"
+            fillRule="evenodd"
+            stroke="#323232"
+            fill="#323232"
+        />
+        <Path
+            d="m284.031 298.394-29.707 51.515 29.707 51.514M335.811 298.394l29.707 51.515-29.707 51.514M284.031 298.394l51.78 103.029"
+            transform={[{
+                scale: 1 / pathScale
+            }]}
+            strokeLinejoin="round"
+            strokeOpacity={0.941}
+            strokeLinecap="round"
+            strokeWidth={9.449}
+            stroke="#FBFBFB"
+        />
+        <Defs>
+            <LinearGradient
+                gradientUnits="userSpaceOnUse"
+                x1={484.077 / pathScale}
+                x2={135.764 / pathScale}
+                y2={531.137 / pathScale}
+                y1={88.682 / pathScale}
+                id="a"
+            >
+                <Stop stopColor="#36B49E" />
+                <Stop
+                    stopColor="#068F7C"
+                    offset={1}
+                />
+            </LinearGradient>
+        </Defs>
+    </Svg>;
+};
+export default NIBGATIcon;

+ 255 - 0
src/components/avatar/index.tsx

@@ -0,0 +1,255 @@
+import {
+    useState
+} from "react";
+import {
+    TouchableOpacity,
+    Image,
+    View
+} from "react-native";
+import type IAvatarProps from "./type";
+import stylesheet, {
+    getAvatarSize,
+    useStyles
+} from "./stylesheet";
+import {
+    NCoreUIKitTheme
+} from "../../core/hooks";
+import {
+    UserRound as UserRoundIcon
+} from "lucide-react-native";
+import Loading from "../loading";
+import Text from "../text";
+
+const Avatar = ({
+    titleAbbreviationType = "first-last",
+    isShowStatusIndicatorSplicer = true,
+    avatarBackgroundColor = "default",
+    statusIndicatorType = "online",
+    titleColor = "onPrimary",
+    isShowBorder = false,
+    isStatusIndicator,
+    isWorkWithAction,
+    image: ImageProp,
+    backgroundColor,
+    size = "medium",
+    icon: IconProp,
+    imageSource,
+    customTheme,
+    borderColor,
+    isDisabled,
+    imageProps,
+    isLoading,
+    iconColor,
+    imageUrl,
+    onPress,
+    title,
+    style
+}: IAvatarProps) => {
+    const {
+        borders,
+        colors,
+        spaces
+    } = NCoreUIKitTheme.useContext(customTheme);
+
+    const currentSize = getAvatarSize({
+        spaces,
+        size
+    });
+
+    const [
+        imageLoadError,
+        setImageLoadError
+    ] = useState(false);
+
+    const {
+        statusIndicator: statusIndicatorDynamicStyle,
+        container: containerDynamicStyle,
+        image: imageDynamicStyle,
+        icon: iconDynamicStyle
+    } = useStyles({
+        isShowStatusIndicatorSplicer,
+        avatarBackgroundColor,
+        statusIndicatorType,
+        image: ImageProp,
+        backgroundColor,
+        isShowBorder,
+        borderColor,
+        currentSize,
+        isDisabled,
+        isLoading,
+        imageUrl,
+        borders,
+        colors,
+        title
+    });
+
+    const calculateShortTitle = () => {
+        if(!title) {
+            return "";
+        }
+
+        const allWords: Array<string> = title.split(" ");
+
+        if(titleAbbreviationType === "every-first") {
+            let newString = "";
+
+            allWords.forEach((wordItem, wordIndex) => {
+                if(wordIndex < 3) newString += wordItem[0];
+            });
+
+            return newString;
+        }
+
+        if(titleAbbreviationType === "first-last") {
+            let newString = "";
+
+            if(allWords[0]) newString += allWords[0][0];
+
+            if(allWords.length > 1 && allWords[allWords.length - 1]) newString += allWords[allWords.length - 1]?.[0];
+
+            return newString;
+        }
+
+        if(titleAbbreviationType === "first-next") {
+            let newString = "";
+
+            if(allWords[0]) newString += allWords[0][0];
+
+            if(allWords[1]) newString += allWords[1][0];
+
+            return newString;
+        }
+
+        return title;
+    };
+
+    const renderIcon = () => {
+        if(IconProp) {
+            return <IconProp
+                size={currentSize.iconSize}
+                customColor={iconColor}
+                color="default"
+                style={{
+                    ...iconDynamicStyle
+                }}
+            />;
+        }
+
+        return <UserRoundIcon
+            color={iconColor ? iconColor : colors.content.icon.default}
+            size={currentSize.iconSize}
+            style={{
+                ...iconDynamicStyle
+            }}
+        />;
+    };
+
+    const renderStatusIndicator = () => {
+        if(!isStatusIndicator) {
+            return null;
+        }
+
+        return <View
+            style={[
+                stylesheet.statusIndicator,
+                statusIndicatorDynamicStyle
+            ]}
+        />;
+    };
+
+    const renderLoading = () => {
+        let loadingColor: keyof NCoreUIKit.IconContentColors = "default";
+
+        if(title) {
+            loadingColor = "onPrimary";
+        } else if(imageUrl || ImageProp) {
+            loadingColor = "mid";
+        }
+
+        return <Loading
+            color={loadingColor}
+        />;
+    };
+
+    const renderContent = () => {
+        if(isLoading) {
+            return renderLoading();
+        }
+
+        if(IconProp) {
+            return renderIcon();
+        }
+
+        if(!title && !ImageProp && !imageUrl) {
+            return renderIcon();
+        }
+
+        if((imageUrl || ImageProp) && imageLoadError) {
+            if(title) {
+                return <Text
+                    variant={currentSize.fontSize}
+                    color={titleColor}
+                >
+                    {calculateShortTitle()}
+                </Text>;
+            } else {
+                return renderIcon();
+            }
+        }
+
+        if(ImageProp) {
+            return <ImageProp
+                {...imageProps}
+                onError={() => setImageLoadError(true)}
+                height={currentSize.size}
+                width={currentSize.size}
+                style={[
+                    stylesheet.image,
+                    imageDynamicStyle,
+                    imageProps?.style
+                ]}
+            />;
+        }
+
+        if(imageUrl) {
+            return <Image
+                {...imageProps}
+                onError={() => setImageLoadError(true)}
+                height={currentSize.size}
+                width={currentSize.size}
+                source={{
+                    uri: imageUrl,
+                    ...imageSource
+                }}
+                style={[
+                    stylesheet.image,
+                    imageDynamicStyle,
+                    imageProps?.style
+                ]}
+            />;
+        }
+
+        return <Text
+            variant={currentSize.fontSize}
+            color={titleColor}
+        >
+            {calculateShortTitle()}
+        </Text>;
+    };
+
+    return <TouchableOpacity
+        disabled={!isWorkWithAction || isDisabled || isLoading}
+        onPress={!isWorkWithAction || isDisabled || isLoading ? undefined : () => {
+            if(onPress) onPress();
+        }}
+        style={[
+            style,
+            stylesheet.container,
+            containerDynamicStyle
+        ]}
+    >
+        {renderContent()}
+        {renderStatusIndicator()}
+    </TouchableOpacity>;
+};
+export default Avatar;

+ 184 - 0
src/components/avatar/stylesheet.ts

@@ -0,0 +1,184 @@
+import {
+    type ImageStyle,
+    type ViewStyle,
+    StyleSheet
+} from "react-native";
+import type {
+    AvatarSizeConstantType,
+    AvatarDynamicStyleType,
+    AvatarMeasuresKeys,
+    AvatarSizeType,
+    AvatarMeasures,
+    AvatarStatusIndicatorType
+} from "./type";
+import type {
+    Mutable
+} from "../../types";
+
+export const AVATAR_SIZES: Record<AvatarSizeType, AvatarMeasuresKeys> = {
+    xxSmall: {
+        fontSize: "labelSmallSize",
+        statusIndicatorSize: 8,
+        iconSize: 14,
+        size: 24
+    },
+    xSmall: {
+        fontSize: "labelMediumSize",
+        statusIndicatorSize: 10,
+        iconSize: 18,
+        size: 32
+    },
+    small: {
+        fontSize: "labelLargeSize",
+        statusIndicatorSize: 12,
+        iconSize: 22,
+        size: 40
+    },
+    medium: {
+        fontSize: "bodyLargeSize",
+        statusIndicatorSize: 14,
+        iconSize: 26,
+        size: 48
+    },
+    large: {
+        fontSize: "headlineSmallSize",
+        statusIndicatorSize: 16,
+        iconSize: 32,
+        size: 64
+    },
+    xLarge: {
+        fontSize: "headlineMediumSize",
+        statusIndicatorSize: 20,
+        iconSize: 40,
+        size: 80
+    },
+    xxLarge: {
+        fontSize: "displaySmallSize",
+        statusIndicatorSize: 28,
+        iconSize: 60,
+        size: 120
+    },
+    xxxLarge: {
+        fontSize: "displayMediumSize",
+        statusIndicatorSize: 32,
+        iconSize: 76,
+        size: 150
+    }
+};
+
+export const getAvatarSize = ({
+    size
+}: AvatarSizeConstantType): AvatarMeasures => {
+    const currentSize = AVATAR_SIZES[size];
+
+    return {
+        statusIndicatorSize: currentSize.statusIndicatorSize,
+        fontSize: currentSize.fontSize,
+        iconSize: currentSize.iconSize,
+        size: currentSize.size
+    };
+};
+
+export const AvatarStatusCheatsheet: Record<AvatarStatusIndicatorType, keyof NCoreUIKit.IconContentColors> = {
+    "offline": "default",
+    "online": "success",
+    "away": "warning",
+    "busy": "danger",
+    "idle": "info"
+};
+
+const stylesheet = StyleSheet.create({
+    container: {
+        position: "relative",
+        overflow: "visible",
+        display: "flex"
+    },
+    image: {
+        objectFit: "cover"
+    },
+    icon: {
+    },
+    statusIndicator: {
+        position: "absolute",
+        bottom: 0,
+        right: 0
+    }
+});
+
+export const useStyles = ({
+    isShowStatusIndicatorSplicer,
+    avatarBackgroundColor,
+    statusIndicatorType,
+    backgroundColor,
+    isShowBorder,
+    borderColor,
+    currentSize,
+    isDisabled,
+    isLoading,
+    imageUrl,
+    borders,
+    colors,
+    image,
+    title
+}: AvatarDynamicStyleType) => {
+    const styles = {
+        container: {
+            borderColor: borderColor && borderColor !== "transparent" ? colors.content.border[borderColor] : avatarBackgroundColor ? colors.content.container[avatarBackgroundColor] : "transparent",
+            backgroundColor: backgroundColor ? backgroundColor === "transparent" ? "transparent" : colors.content.container[backgroundColor] : colors.content.container.subtle,
+            borderRadius: currentSize.size / 2,
+            height: currentSize.size,
+            width: currentSize.size
+        } as Mutable<ViewStyle>,
+        image: {
+            borderColor: borderColor && borderColor !== "transparent" ? colors.content.border[borderColor] : avatarBackgroundColor ? colors.content.container[avatarBackgroundColor] : "transparent",
+            borderRadius: currentSize.size / 2,
+            height: currentSize.size,
+            width: currentSize.size
+        } as Mutable<ImageStyle>,
+        icon: {
+        } as Mutable<ViewStyle>,
+        statusIndicator: {
+            backgroundColor: colors.content.icon[AvatarStatusCheatsheet[statusIndicatorType]],
+            borderColor: colors.content.container[avatarBackgroundColor],
+            borderRadius: currentSize.statusIndicatorSize / 2,
+            height: currentSize.statusIndicatorSize,
+            width: currentSize.statusIndicatorSize
+        } as Mutable<ViewStyle>
+    };
+
+    if(isShowBorder) {
+        styles.container.borderWidth = borders.subtract;
+        styles.image.borderWidth = borders.subtract;
+    }
+
+    if(!title && !image && !imageUrl && !backgroundColor) {
+        styles.container.backgroundColor = colors.content.container.subtle;
+
+        styles.container.justifyContent = "center";
+        styles.container.alignItems = "center";
+    }
+
+    if(title) {
+        styles.container.backgroundColor = colors.content.container.primary;
+
+        styles.container.justifyContent = "center";
+        styles.container.alignItems = "center";
+    }
+
+    if(isShowStatusIndicatorSplicer) {
+        const multiplier = currentSize.statusIndicatorSize / 14;
+
+        styles.statusIndicator.borderWidth = borders.subtract * multiplier;
+    }
+
+    if(isDisabled) {
+        styles.container.opacity = 0.33;
+    }
+
+    if(isLoading) {
+        styles.container.opacity = 0.33;
+    }
+
+    return styles;
+};
+export default stylesheet;

+ 88 - 0
src/components/avatar/type.ts

@@ -0,0 +1,88 @@
+import type {
+    ComponentType
+} from "react";
+import {
+    type ImageURISource,
+    type ImageProps,
+    type TextStyle,
+    type StyleProp
+} from "react-native";
+import type {
+    NCoreUIKitIcon
+} from "../../types";
+
+export type AvatarDynamicStyleType = {
+    backgroundColor?: keyof NCoreUIKit.ContainerContentColors | "transparent";
+    borderColor?: keyof NCoreUIKit.BorderContentColors | "transparent";
+    avatarBackgroundColor: keyof NCoreUIKit.ContainerContentColors;
+    statusIndicatorType: AvatarStatusIndicatorType;
+    borders: NCoreUIKit.ActivePalette["borders"];
+    colors: NCoreUIKit.ActivePalette["colors"];
+    isShowStatusIndicatorSplicer?: boolean;
+    image?: ComponentType<ImageProps>;
+    currentSize: AvatarMeasures;
+    isShowBorder?: boolean;
+    isDisabled?: boolean;
+    isLoading?: boolean;
+    imageUrl?: string;
+    title?: string;
+};
+
+export type AvatarMeasuresKeys = {
+    fontSize: keyof NCoreUIKit.Typography;
+    statusIndicatorSize: number;
+    iconSize: number;
+    size: number;
+};
+
+export type AvatarMeasures = {
+    fontSize: keyof NCoreUIKit.Typography;
+    statusIndicatorSize: number;
+    iconSize: number;
+    size: number;
+};
+
+export type AvatarSizeConstantType = {
+    spaces: NCoreUIKit.ActivePalette["spaces"];
+    size: AvatarSizeType;
+};
+
+export type AvatarStatusIndicatorType = "online" | "offline" | "busy" | "away" | "idle";
+
+export type AvatarTitleAbbreviationTypes = "first-last" | "first-next" | "every-first";
+
+export type AvatarSizeType = "xxSmall" | "xSmall" | "small" | "medium" | "large" | "xLarge" | "xxLarge" | "xxxLarge";
+
+interface IAvatarProps {
+    backgroundColor?: keyof NCoreUIKit.ContainerContentColors | "transparent";
+    borderColor?: keyof NCoreUIKit.BorderContentColors | "transparent";
+    avatarBackgroundColor?: keyof NCoreUIKit.ContainerContentColors;
+    iconColor?: keyof NCoreUIKit.ProjectColorPalette;
+    customTheme?: {
+        gapPropagation?: keyof NCoreUIKit.GapPropagationKey;
+        sharpness?: keyof NCoreUIKit.SharpnessKey;
+        paletteKey?: keyof NCoreUIKit.PaletteKey;
+        themeKey?: keyof NCoreUIKit.ThemeKey;
+    };
+    style?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
+    titleAbbreviationType?: AvatarTitleAbbreviationTypes;
+    statusIndicatorType?: AvatarStatusIndicatorType;
+    titleColor?: keyof NCoreUIKit.TextContentColors;
+    isShowStatusIndicatorSplicer?: boolean;
+    image?: ComponentType<ImageProps>;
+    imageSource?: ImageURISource;
+    isStatusIndicator?: boolean;
+    isWorkWithAction?: boolean;
+    imageProps?: ImageProps;
+    isShowBorder?: boolean;
+    icon?: NCoreUIKitIcon;
+    size?: AvatarSizeType;
+    isDisabled?: boolean;
+    onPress?: () => void;
+    isLoading?: boolean;
+    imageUrl?: string;
+    title?: string;
+}
+export type {
+    IAvatarProps as default
+};

+ 172 - 0
src/components/avatarGroup/index.tsx

@@ -0,0 +1,172 @@
+import {
+    Fragment
+} from "react";
+import {
+    TouchableOpacity,
+    View
+} from "react-native";
+import type IAvatarProps from "./type";
+import stylesheet, {
+    getAvatarGroupSize,
+    useStyles
+} from "./stylesheet";
+import {
+    NCoreUIKitTheme
+} from "../../core/hooks";
+import {
+    UserRound as UserRoundIcon
+} from "lucide-react-native";
+import Loading from "../loading";
+import Avatar from "../avatar";
+import Text from "../text";
+
+const AvatarGroup = ({
+    titleAbbreviationType = "first-last",
+    isShowStatusIndicatorSplicer = true,
+    avatarBackgroundColor = "default",
+    isStatusIndicator,
+    isWorkWithAction,
+    size = "medium",
+    borderColor,
+    customTheme,
+    isDisabled,
+    imageProps,
+    isLoading,
+    avatars,
+    onPress,
+    style
+}: IAvatarProps) => {
+    const {
+        borders,
+        colors
+    } = NCoreUIKitTheme.useContext(customTheme);
+
+    const currentSize = getAvatarGroupSize({
+        size
+    });
+
+    const currentAvatars = avatars && avatars.length > 2 ? avatars?.slice(0, 2) : avatars;
+
+    const {
+        moreAvatarsContainer: moreAvatarsContainerDynamicStyle,
+        iconContainer: iconContainerDynamicStyle,
+        container: containerDynamicStyle,
+        avatar: avatarDynamicStyle,
+        icon: iconDynamicStyle
+    } = useStyles({
+        avatarBackgroundColor,
+        currentSize,
+        borderColor,
+        isDisabled,
+        isLoading,
+        avatars,
+        borders,
+        colors
+    });
+
+    const renderIcon = () => {
+        if(isLoading) {
+            return renderLoading();
+        }
+
+        return <UserRoundIcon
+            color={colors.content.icon.default}
+            size={currentSize.iconSize}
+            style={{
+                ...iconDynamicStyle
+            }}
+        />;
+    };
+
+    const renderLoading = () => {
+        return <Loading
+            color="default"
+        />;
+    };
+
+    const renderAvatars = () => {
+        if(!currentAvatars || !currentAvatars.length) {
+            return null;
+        }
+
+        return currentAvatars.map((avatarItem, avatarIndex) => {
+            return <Avatar
+                {...avatarItem}
+                isShowStatusIndicatorSplicer={isShowStatusIndicatorSplicer}
+                titleAbbreviationType={titleAbbreviationType}
+                avatarBackgroundColor={avatarBackgroundColor}
+                isStatusIndicator={isStatusIndicator}
+                isWorkWithAction={undefined}
+                borderColor={borderColor}
+                customTheme={customTheme}
+                imageProps={imageProps}
+                isShowBorder={true}
+                onPress={undefined}
+                isDisabled={false}
+                isLoading={false}
+                size={size}
+                style={{
+                    ...avatarDynamicStyle,
+                    ...avatarItem.style,
+                    transform: [{
+                        translateX: avatarIndex === 0 ? currentSize.size / 3 : 0
+                    }]
+                }}
+            />;
+        });
+    };
+
+    const renderMoreAvatars = () => {
+        if(!avatars) {
+            return null;
+        }
+
+        if(avatars.length < 3) {
+            return null;
+        }
+
+        return <View
+            style={[
+                stylesheet.moreAvatarsContainer,
+                moreAvatarsContainerDynamicStyle
+            ]}
+        >
+            <Text
+                variant="labelLargeSize"
+                color="mid"
+            >
+                +{avatars.length - 2}
+            </Text>
+        </View>;
+    };
+
+    const renderContent = () => {
+        return <Fragment>
+            {renderAvatars()}
+            <View
+                style={[
+                    stylesheet.iconContainer,
+                    iconContainerDynamicStyle
+                ]}
+            >
+                {renderIcon()}
+            </View>
+            {renderMoreAvatars()}
+        </Fragment>;
+    };
+
+    return <TouchableOpacity
+        disabled={!isWorkWithAction || isDisabled || isLoading}
+        onPress={!isWorkWithAction || isDisabled || isLoading ? undefined : () => {
+            if(onPress) onPress();
+        }}
+        style={[
+            style,
+            stylesheet.container,
+            containerDynamicStyle
+        ]}
+    >
+        {renderContent()}
+    </TouchableOpacity>;
+};
+export default AvatarGroup;

+ 138 - 0
src/components/avatarGroup/stylesheet.ts

@@ -0,0 +1,138 @@
+import {
+    type ViewStyle,
+    StyleSheet
+} from "react-native";
+import type {
+    AvatarGroupSizeConstantType,
+    AvatarGroupDynamicStyleType,
+    AvatarGroupMeasuresKeys,
+    AvatarGroupSizeType
+} from "./type";
+import type {
+    Mutable
+} from "../../types";
+
+export const AVATAR_GROUP_SIZES: Record<AvatarGroupSizeType, AvatarGroupMeasuresKeys> = {
+    xxSmall: {
+        fontSize: "labelSmallSize",
+        iconSize: 14,
+        size: 24
+    },
+    xSmall: {
+        fontSize: "labelMediumSize",
+        iconSize: 18,
+        size: 32
+    },
+    small: {
+        fontSize: "labelLargeSize",
+        iconSize: 22,
+        size: 40
+    },
+    medium: {
+        fontSize: "bodyLargeSize",
+        iconSize: 26,
+        size: 48
+    },
+    large: {
+        fontSize: "headlineSmallSize",
+        iconSize: 32,
+        size: 64
+    },
+    xLarge: {
+        fontSize: "headlineMediumSize",
+        iconSize: 40,
+        size: 80
+    },
+    xxLarge: {
+        fontSize: "displaySmallSize",
+        iconSize: 60,
+        size: 120
+    },
+    xxxLarge: {
+        fontSize: "displayMediumSize",
+        iconSize: 76,
+        size: 150
+    }
+};
+
+export const getAvatarGroupSize = ({
+    size
+}: AvatarGroupSizeConstantType): AvatarGroupMeasuresKeys => {
+    const currentSize = AVATAR_GROUP_SIZES[size];
+
+    return {
+        fontSize: currentSize.fontSize,
+        iconSize: currentSize.iconSize,
+        size: currentSize.size
+    };
+};
+
+const stylesheet = StyleSheet.create({
+    container: {
+        flexDirection: "row",
+        position: "relative"
+    },
+    iconContainer: {
+        justifyContent: "center",
+        alignItems: "center"
+    },
+    icon: {
+    },
+    moreAvatarsContainer: {
+        justifyContent: "center",
+        alignItems: "center"
+    }
+});
+
+export const useStyles = ({
+    avatarBackgroundColor,
+    currentSize,
+    borderColor,
+    isDisabled,
+    isLoading,
+    avatars,
+    borders,
+    colors
+}: AvatarGroupDynamicStyleType) => {
+    const styles = {
+        container: {
+        } as Mutable<ViewStyle>,
+        iconContainer: {
+            borderColor: borderColor ? borderColor === "transparent" ? "transparent" : colors.content.border[borderColor] : avatarBackgroundColor ? colors.content.container[avatarBackgroundColor] : colors.content.container.default,
+            transform: [{
+                translateX: avatars && avatars.length === 1 ? 0 : (currentSize.size / 3) * -1
+            }],
+            backgroundColor: colors.content.container.subtle,
+            borderRadius: currentSize.size / 2,
+            borderWidth: borders.subtract,
+            height: currentSize.size,
+            width: currentSize.size
+        } as Mutable<ViewStyle>,
+        icon: {
+        } as Mutable<ViewStyle>,
+        moreAvatarsContainer: {
+            borderColor: borderColor ? borderColor === "transparent" ? "transparent" : colors.content.border[borderColor] : avatarBackgroundColor ? colors.content.container[avatarBackgroundColor] : colors.content.container.default,
+            backgroundColor: colors.content.container.subtle,
+            transform: [{
+                translateX: (currentSize.size / 1.5) * -1
+            }],
+            borderRadius: currentSize.size / 2,
+            borderWidth: borders.subtract,
+            height: currentSize.size,
+            width: currentSize.size
+        } as Mutable<ViewStyle>,
+        avatar: {
+        } as Mutable<ViewStyle>
+    };
+
+    if(isDisabled) {
+        styles.container.opacity = 0.33;
+    }
+
+    if(isLoading) {
+        styles.container.opacity = 0.33;
+    }
+
+    return styles;
+};
+export default stylesheet;

+ 74 - 0
src/components/avatarGroup/type.ts

@@ -0,0 +1,74 @@
+import {
+    type ImageProps,
+    type TextStyle,
+    type StyleProp
+} from "react-native";
+import type IAvatarProps from "../avatar/type";
+import type {
+    AvatarTitleAbbreviationTypes,
+    AvatarSizeType
+} from "../avatar/type";
+
+export type AvatarGroupDynamicStyleType = {
+    borderColor?: keyof NCoreUIKit.BorderContentColors | "transparent";
+    avatarBackgroundColor: keyof NCoreUIKit.ContainerContentColors;
+    borders: NCoreUIKit.ActivePalette["borders"];
+    colors: NCoreUIKit.ActivePalette["colors"];
+    avatars?: Array<AvatarGroupAvatarsType>;
+    currentSize: AvatarGroupMeasuresKeys;
+    isDisabled?: boolean;
+    isLoading?: boolean;
+};
+
+export type AvatarGroupSizeConstantType = {
+    size: AvatarGroupSizeType;
+};
+
+export type AvatarGroupMeasuresKeys = {
+    fontSize: keyof NCoreUIKit.Typography;
+    iconSize: number;
+    size: number;
+};
+
+export type AvatarGroupTitleAbbreviationTypes = "first-last" | "first-next" | "every-first";
+
+export type AvatarGroupSizeType = "xxSmall" | "xSmall" | "small" | "medium" | "large" | "xLarge" | "xxLarge" | "xxxLarge";
+
+export type AvatarGroupAvatarsType = Omit<
+    IAvatarProps,
+    "isShowStatusIndicatorSplicer" |
+    "avatarBackgroundColor" |
+    "titleAbbreviationType" |
+    "isStatusIndicator" |
+    "isWorkWithAction" |
+    "isDisabled" |
+    "imageProps" |
+    "isLoading" |
+    "onPress" |
+    "size"
+>;
+
+interface IAvatarGroupProps {
+    borderColor?: keyof NCoreUIKit.BorderContentColors | "transparent";
+    avatarBackgroundColor?: keyof NCoreUIKit.ContainerContentColors;
+    customTheme?: {
+        gapPropagation?: keyof NCoreUIKit.GapPropagationKey;
+        sharpness?: keyof NCoreUIKit.SharpnessKey;
+        paletteKey?: keyof NCoreUIKit.PaletteKey;
+        themeKey?: keyof NCoreUIKit.ThemeKey;
+    };
+    style?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
+    titleAbbreviationType?: AvatarTitleAbbreviationTypes;
+    avatars?: Array<AvatarGroupAvatarsType>;
+    isShowStatusIndicatorSplicer?: boolean;
+    isStatusIndicator?: boolean;
+    isWorkWithAction?: boolean;
+    imageProps?: ImageProps;
+    size?: AvatarSizeType;
+    isDisabled?: boolean;
+    onPress?: () => void;
+    isLoading?: boolean;
+}
+export type {
+    IAvatarGroupProps as default
+};

+ 327 - 11
src/components/bottomSheet/index.tsx

@@ -4,12 +4,14 @@ import {
     forwardRef,
     useEffect,
     useState,
-    useRef
+    useRef,
+    type PointerEvent
 } from "react";
 import {
     type LayoutChangeEvent,
     PanResponder,
     ScrollView,
+    Platform,
     Animated,
     Easing,
     View
@@ -25,14 +27,18 @@ import {
 import {
     useSafeAreaInsets
 } from "react-native-safe-area-context";
-import type {
-    RefForwardingComponent
+import {
+    type RefForwardingComponent,
+    type SafePointerEvent,
+    safeGlobal
 } from "../../types";
 import type {
     IModalRef
 } from "../modal/type";
 import {
     windowHeight,
+    windowWidth,
+    webStyle,
     uuid
 } from "../../utils";
 import Modal from "../modal";
@@ -419,6 +425,7 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
                 return true;
             },
             onPanResponderGrant: (evt) => {
+                console.log("GRANT", evt.nativeEvent);
                 if(!isCanSwipeRef.current) return;
 
                 gestureStartY.current = evt.nativeEvent.pageY;
@@ -743,7 +750,274 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
     const renderView = () => {
         return <Animated.View
             {...props}
-            {...panResponder.panHandlers}
+            {...(Platform.OS === "web" ? {} : panResponder.panHandlers)}
+            onPointerDown={Platform.OS === "web" ? (evt) => {
+                const nativeEvt = evt as unknown as PointerEvent;
+                const startY = nativeEvt.clientY;
+                gestureStartY.current = nativeEvt.clientY;
+
+                const initialT = translateYValue.current;
+                const initialH = heightValue.current;
+                const initialS = scrollOffset.current;
+
+                animatedTranslateY.setOffset(initialT);
+                animatedTranslateY.setValue(0);
+
+                animatedHeight.setOffset(initialH);
+                animatedHeight.setValue(0);
+
+                let lastY = startY;
+                let lastTime = Date.now();
+                let velocityY = 0;
+
+                const handlePointerMove = (moveEvt: SafePointerEvent) => {
+                    if (!isCanSwipeRef.current) return;
+
+                    const dy = moveEvt.clientY - startY;
+                    if (Math.abs(dy) < 5) return;
+
+                    const now = Date.now();
+                    const dt = now - lastTime;
+                    if (dt > 0) {
+                        velocityY = (moveEvt.clientY - lastY) / dt;
+                    }
+                    lastY = moveEvt.clientY;
+                    lastTime = now;
+
+                    const delta = -dy;
+                    const pivot = snapPoint ?? contentHeight.current;
+                    const isAtTavan = heightValue.current >= maxHeight.current - 1;
+                    const hasScroll = scrollViewContentHeight.current > scrollViewLayoutHeight.current;
+                    const isAtTop = scrollOffset.current <= 0;
+                    const isFromTopArea = gestureStartY.current < TOP_GRAB_AREA;
+                    const maxS = Math.max(0, scrollViewContentHeight.current - scrollViewLayoutHeight.current);
+
+                    if (dy > 0 && isAtTavan && hasScroll && !isAtTop && !isFromTopArea) {
+                        const usedForS = Math.max(-dy, -initialS);
+                        scrollOffset.current = initialS + usedForS;
+                        scrollViewRef.current?.scrollTo({
+                            y: scrollOffset.current,
+                            animated: false
+                        });
+                        return;
+                    }
+
+                    if (dy < 0) {
+                        let currentDelta = delta;
+
+                        const effectiveInitialT = Math.max(0, initialT);
+                        const usedForT = Math.min(currentDelta, effectiveInitialT);
+                        animatedTranslateY.setValue(-usedForT);
+                        currentDelta -= usedForT;
+
+                        if (currentDelta > 0) {
+                            if (initialH < pivot) {
+                                const spaceToPivot = pivot - initialH;
+                                const usedForH = Math.min(currentDelta, spaceToPivot);
+                                animatedHeight.setValue(usedForH);
+                                currentDelta -= usedForH;
+                            }
+
+                            const isRestoringHeight = initialH < pivot;
+                            const canScroll = isCanFullScreenOnSwipeRef.current || isWorkAsFullScreenRef.current || !isRestoringHeight;
+
+                            if (currentDelta > 0 && canScroll) {
+                                const remainingScroll = maxS - initialS;
+                                if (remainingScroll > 0) {
+                                    const usedForS = Math.min(currentDelta, remainingScroll);
+                                    scrollOffset.current = initialS + usedForS;
+                                    scrollViewRef.current?.scrollTo({
+                                        y: scrollOffset.current,
+                                        animated: false
+                                    });
+                                    currentDelta -= usedForS;
+                                    animatedHeight.setValue(initialH < pivot ? (pivot - initialH) : 0);
+                                }
+                            }
+
+                            if (currentDelta > 0) {
+                                if (isCanFullScreenOnSwipeRef.current) {
+                                    const totalUsedBefore = initialH < pivot ? (pivot - initialH) : 0;
+                                    animatedHeight.setValue(totalUsedBefore + currentDelta);
+                                } else {
+                                    animatedHeight.setValue(initialH < pivot ? (pivot - initialH) : 0);
+                                }
+                            }
+                        }
+                    } else {
+                        let currentDelta = delta;
+
+                        if (initialH > pivot || initialS > 0) {
+                            if (initialS > 0) {
+                                const usedForS = Math.max(currentDelta, -initialS);
+                                scrollOffset.current = initialS + usedForS;
+                                scrollViewRef.current?.scrollTo({
+                                    y: scrollOffset.current,
+                                    animated: false
+                                });
+                                currentDelta -= usedForS;
+                                animatedHeight.setValue(initialH > pivot ? 0 : pivot - initialH);
+                            }
+
+                            if (currentDelta < 0 && initialH > pivot) {
+                                const distanceToPivot = pivot - initialH;
+                                const usedForH = Math.max(currentDelta, distanceToPivot);
+                                animatedHeight.setValue(usedForH);
+                                currentDelta -= usedForH;
+                            }
+                        }
+
+                        if (currentDelta < 0) {
+                            animatedHeight.setValue(initialH > pivot ? (pivot - initialH) : 0);
+                            animatedTranslateY.setValue(-currentDelta);
+                            scrollOffset.current = 0;
+                            scrollViewRef.current?.scrollTo({
+                                y: 0,
+                                animated: false
+                            });
+                        }
+                    }
+                };
+
+                const handlePointerUp = () => {
+                    safeGlobal.removeEventListener("pointermove", handlePointerMove);
+                    safeGlobal.removeEventListener("pointerup", handlePointerUp);
+
+                    animatedHeight.flattenOffset();
+                    animatedTranslateY.flattenOffset();
+
+                    const currentT = translateYValue.current;
+                    const currentH = heightValue.current;
+                    const pivot = snapPoint ?? contentHeight.current;
+                    const tavan = maxHeight.current;
+
+                    const isAtTavan = currentH >= tavan - 1;
+                    const hasScroll = scrollViewContentHeight.current > scrollViewLayoutHeight.current;
+                    const isAtTop = scrollOffset.current <= 1;
+                    const isFromTopArea = gestureStartY.current < TOP_GRAB_AREA;
+
+                    if (isAtTavan && hasScroll && !isAtTop && !isFromTopArea) {
+                        if (Math.abs(velocityY) > 0.1) {
+                            const momentum = velocityY * -350;
+                            const maxS = Math.max(0, scrollViewContentHeight.current - scrollViewLayoutHeight.current);
+                            const targetOffset = Math.max(0, Math.min(scrollOffset.current + momentum, maxS));
+
+                            const scrollAnim = new Animated.Value(scrollOffset.current);
+                            scrollAnim.addListener(({
+                                value
+                            }) => {
+                                scrollViewRef.current?.scrollTo({
+                                    y: value,
+                                    animated: false
+                                });
+                                scrollOffset.current = value;
+                            });
+
+                            Animated.timing(scrollAnim, {
+                                toValue: targetOffset,
+                                duration: Math.min(Math.abs(momentum) * 2, 600),
+                                easing: Easing.out(Easing.quad),
+                                useNativeDriver: false
+                            }).start(() => {
+                                scrollAnim.removeAllListeners();
+                                checkScrollThreshold();
+                            });
+                        } else {
+                            checkScrollThreshold();
+                        }
+                        return;
+                    }
+
+                    const isFastSwipeDown = velocityY > 0.5;
+                    const isFastSwipeUp = velocityY < -0.5;
+
+                    if (currentT <= Math.max(pivot * 0.2, 60)) {
+                        let toValue = pivot;
+
+                        if (isFastSwipeUp && isCanFullScreenOnSwipeRef.current) {
+                            toValue = tavan;
+                        } else if (isFastSwipeDown) {
+                            toValue = pivot;
+                        } else {
+                            if (!isCanFullScreenOnSwipeRef.current) {
+                                toValue = pivot;
+                            } else {
+                                const totalRange = tavan - pivot;
+                                const distFromPivot = currentH - pivot;
+
+                                if (distFromPivot < totalRange * 0.33) toValue = pivot;
+                                else if (distFromPivot > totalRange * 0.66) toValue = tavan;
+                                else toValue = (tavan - currentH) < (currentH - pivot) ? tavan : pivot;
+                            }
+                        }
+
+                        Animated.spring(animatedHeight, {
+                            toValue,
+                            useNativeDriver: false,
+                            friction: 10,
+                            tension: 40
+                        }).start();
+                        Animated.spring(animatedTranslateY, {
+                            toValue: 0,
+                            useNativeDriver: false,
+                            friction: 10,
+                            tension: 40
+                        }).start();
+                    } else {
+                        if (!isSwipeCloseRef.current) {
+                            Animated.spring(animatedHeight, {
+                                toValue: pivot,
+                                useNativeDriver: false,
+                                friction: 10,
+                                tension: 40
+                            }).start();
+                            Animated.timing(animatedTranslateY, {
+                                toValue: 0,
+                                useNativeDriver: false,
+                                duration: 300
+                            }).start();
+                        } else {
+                            let toValueT = 0;
+                            let isClosing = false;
+
+                            if (isFastSwipeDown) {
+                                toValueT = pivot + 100;
+                                isClosing = true;
+                            } else {
+                                if (currentT > pivot * 0.5) {
+                                    toValueT = pivot + 100;
+                                    isClosing = true;
+                                } else {
+                                    toValueT = 0;
+                                    isClosing = false;
+                                }
+                            }
+
+                            if (onClose) onClose({
+                                id: id.current
+                            });
+
+                            Animated.timing(animatedTranslateY, {
+                                toValue: toValueT,
+                                useNativeDriver: false,
+                                duration: 300
+                            }).start(({
+                                finished
+                            }) => {
+                                if (finished && isClosing) {
+                                    setIsActive(false);
+                                    if (onClosed) onClosed({
+                                        id: id.current
+                                    });
+                                }
+                            });
+                        }
+                    }
+                };
+
+                safeGlobal.addEventListener("pointermove", handlePointerMove);
+                safeGlobal.addEventListener("pointerup", handlePointerUp);
+            } : undefined}
             onLayout={onLayout}
             style={[
                 {
@@ -764,7 +1038,12 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
                         translateY: animatedTranslateY
                     }]
                 },
-                stylesheet.container
+                stylesheet.container,
+                webStyle({
+                    touchAction: "none",
+                    userSelect: "none",
+                    cursor: "grab"
+                })
             ]}
         >
             {renderHeader()}
@@ -786,7 +1065,12 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
                 ref={scrollViewRef}
                 bounces={false}
                 style={[
-                    scrollViewStyle
+                    scrollViewStyle,
+                    webStyle({
+                        maxWidth: windowWidth > 500 ? 500 : undefined,
+                        width: windowWidth > 500 ? 500 : undefined,
+                        alignSelf: "center"
+                    })
                 ]}
             >
                 {children}
@@ -801,6 +1085,20 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
             return null;
         }
 
+        if(Platform.OS === "web") {
+            return <View
+                style={[
+                    webStyle({
+                        maxWidth: windowWidth > 500 ? 500 : undefined,
+                        width: windowWidth > 500 ? 500 : undefined,
+                        alignSelf: "center"
+                    })
+                ]}
+            >
+                {RenderHeaderComponent()}
+            </View>;
+        }
+
         return RenderHeaderComponent();
     };
 
@@ -809,6 +1107,20 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
             return null;
         }
 
+        if(Platform.OS === "web") {
+            return <View
+                style={[
+                    webStyle({
+                        maxWidth: windowWidth > 500 ? 500 : undefined,
+                        width: windowWidth > 500 ? 500 : undefined,
+                        alignSelf: "center"
+                    })
+                ]}
+            >
+                <RenderBottomComponent/>
+            </View>;
+        }
+
         return <RenderBottomComponent/>;
     };
 
@@ -822,9 +1134,8 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
         const handleBorderRadius = Math.ceil(handleHeight / 2);
 
         return <View
-            {...panResponder.panHandlers}
-            onStartShouldSetResponderCapture={() => false}
-            onMoveShouldSetResponderCapture={() => false}
+            onStartShouldSetResponderCapture={() => Platform.OS === "web"}
+            onMoveShouldSetResponderCapture={() => Platform.OS === "web"}
             style={[
                 stylesheet.handleContainer,
                 {
@@ -833,9 +1144,14 @@ const BottomSheet: RefForwardingComponent<IBottomSheetRef, IBottomSheetProps> =
                         : "transparent",
                     height: handleContainerHeight,
                     transform: [{
-                        translateY: -handleContainerHeight
+                        translateY: -handleContainerHeight * (Platform.OS === "web" ? 1.75 : 1)
                     }]
-                }
+                },
+                webStyle({
+                    touchAction: "none !important",
+                    userSelect: "none",
+                    cursor: "grab"
+                })
             ]}
         >
             <View

+ 25 - 1
src/components/button/index.tsx

@@ -32,9 +32,13 @@ const Button: FC<IButtonProps> = ({
     iconDirection = "left",
     variant = "filled",
     isDisabled = false,
+    customBorderColor,
     type = "primary",
+    customIconColor,
+    customTextColor,
     size = "medium",
     renderLoading,
+    customColor,
     customTheme,
     titleStyle,
     isLoading,
@@ -72,12 +76,14 @@ const Button: FC<IButtonProps> = ({
     } = useStyles({
         displayBehaviourWhileLoading,
         icon: IconComponentProp,
+        customBorderColor,
         isCustomPadding,
         spreadBehaviour,
         currentVariant,
         iconDirection,
         currentType,
         currentSize,
+        customColor,
         isDisabled,
         isLoading,
         radiuses,
@@ -90,7 +96,7 @@ const Button: FC<IButtonProps> = ({
     });
 
     const titleProps: ITextProps = {
-        color: currentType.titleColor,
+        color: currentType.titleColor
     };
 
     const iconProps: NCoreUIKit.IconCallbackProps = {
@@ -124,6 +130,18 @@ const Button: FC<IButtonProps> = ({
     }
 
     const renderIcon = () => {
+        if(!isDisabled && !isLoading) {
+            if(customTextColor) {
+                const _customTextColor = customTextColor as keyof NCoreUIKit.ProjectColorPalette;
+                iconProps.customColor = colors.project[_customTextColor] ? colors.project[_customTextColor] : customTextColor;
+            }
+
+            if(customIconColor) {
+                const _customIconColor = customIconColor as keyof NCoreUIKit.ProjectColorPalette;
+                iconProps.customColor = colors.project[_customIconColor] ? colors.project[_customIconColor] : customIconColor;
+            }
+        }
+
         if (isLoading) {
             if(renderLoading) {
                 return renderLoading();
@@ -149,6 +167,12 @@ const Button: FC<IButtonProps> = ({
             return null;
         }
 
+        if(!isDisabled && !isLoading) {
+            if(customTextColor) {
+                titleProps.customColor = customTextColor;
+            }
+        }
+
         return <Text
             variant={currentSize.fontSize}
             style={[

+ 16 - 0
src/components/button/stylesheet.ts

@@ -170,12 +170,14 @@ const stylesheet = StyleSheet.create({
 
 export const useStyles = ({
     displayBehaviourWhileLoading,
+    customBorderColor,
     spreadBehaviour,
     isCustomPadding,
     currentVariant,
     iconDirection,
     currentType,
     currentSize,
+    customColor,
     isDisabled,
     isLoading,
     radiuses,
@@ -289,6 +291,20 @@ export const useStyles = ({
         delete styles.container.paddingTop;
     }
 
+    if(customColor) {
+        const _customContainerColor = customColor as keyof NCoreUIKit.ContainerContentColors;
+        const _customColor = customColor as keyof NCoreUIKit.ProjectColorPalette;
+
+        styles.container.backgroundColor = colors.project[_customColor] ? colors.project[_customColor] : colors.content.container[_customContainerColor] ? colors.content.container[_customContainerColor] : customColor;
+    }
+
+    if(customBorderColor) {
+        const _customContentBorderColor = customBorderColor as keyof NCoreUIKit.BorderContentColors;
+        const _customBorderColor = customBorderColor as keyof NCoreUIKit.ProjectColorPalette;
+
+        styles.container.borderColor = colors.project[_customBorderColor] ? colors.project[_customBorderColor] : colors.content.border[_customContentBorderColor] ? colors.content.border[_customContentBorderColor] : customBorderColor;
+    }
+
     return styles;
 };
 export default stylesheet;

+ 7 - 1
src/components/button/type.ts

@@ -12,6 +12,8 @@ import {
 } from "../../types";
 
 export type ButtonDynamicStyleType = {
+    customBorderColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
+    customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     displayBehaviourWhileLoading?: ButtonDisplayBehaviourWhileLoading;
     radiuses: NCoreUIKit.ActivePalette["radiuses"];
     spaces: NCoreUIKit.ActivePalette["spaces"];
@@ -81,15 +83,19 @@ export type ButtonVariant = "filled" | "outline" | "ghost";
 export type ButtonSize = "small" | "medium" | "large";
 
 interface IButtonProps extends Omit<ButtonProps, "title" | "disabled"> {
+    customBorderColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
+    customIconColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
+    customTextColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
+    customColor?: keyof NCoreUIKit.ProjectColorPalette | (string & {});
     displayBehaviourWhileLoading?: ButtonDisplayBehaviourWhileLoading;
     titleStyle?: StyleProp<TextStyle>[] | StyleProp<TextStyle>;
-    style?: StyleProp<ViewStyle>[] | StyleProp<ViewStyle>;
     customTheme?: {
         gapPropagation?: keyof NCoreUIKit.GapPropagationKey;
         sharpness?: keyof NCoreUIKit.SharpnessKey;
         paletteKey?: keyof NCoreUIKit.PaletteKey;
         themeKey?: keyof NCoreUIKit.ThemeKey;
     };
+    style?: StyleProp<ViewStyle>[] | StyleProp<ViewStyle>;
     spreadBehaviour?: ButtonSpreadBehaviour;
     iconDirection?: "left" | "right";
     renderLoading?: () => ReactNode;

+ 9 - 0
src/components/checkBox/index.tsx

@@ -3,6 +3,7 @@ import {
 } from "react";
 import {
     TouchableOpacity,
+    Platform,
     View
 } from "react-native";
 import type ICheckBoxProps from "./type";
@@ -253,6 +254,14 @@ const CheckBox: FC<ICheckBoxProps> = ({
                 stylesheet.container,
                 containerDynamicStyle
             ]}
+            {...Platform.select({
+                web: {
+                    dataSet: {
+                        disablePressableDownEffect: "true"
+                    }
+                },
+                default: {}
+            })}
         >
             {isFlip ? null : renderCheckIndicator()}
 

+ 14 - 17
src/components/dateTimePicker/index.tsx

@@ -25,9 +25,6 @@ import {
     NCoreUIKitTheme,
     NCoreUIKitToast
 } from "../../core/hooks";
-import {
-    type NCoreUIKitIcon
-} from "../../types";
 import type {
     IBottomSheetRef
 } from "../bottomSheet/type";
@@ -38,13 +35,14 @@ import {
 } from "rrule";
 import moment from "moment";
 import {
-    BadgeQuestionMarkIcon,
-    BadgeSuccessIcon,
-    BadgeDangerIcon,
-    BadgeAlertIcon,
-    BadgeInfoIcon,
-    CleanIcon
-} from "../../assets/svg";
+    BadgeQuestionMark as BadgeQuestionMarkIcon,
+    BadgeAlert as BadgeAlertIcon,
+    BadgeCheck as BadgeCheckIcon,
+    BadgeInfo as BadgeInfoIcon,
+    CircleX as CircleXIcon,
+    BadgeX as BadgeXIcon,
+    type LucideIcon
+} from "lucide-react-native";
 import {
     uuid
 } from "../../utils";
@@ -54,12 +52,12 @@ import {
     parseRRuleConfig
 } from "../../helpers";
 
-const DateTimePickerTypeIcon: Record<Exclude<DateTimePickerType, "default">, NCoreUIKitIcon> = {
+const DateTimePickerTypeIcon: Record<Exclude<DateTimePickerType, "default">, LucideIcon> = {
     "question": BadgeQuestionMarkIcon,
-    "success": BadgeSuccessIcon,
+    "success": BadgeCheckIcon,
     "warning": BadgeAlertIcon,
-    "danger": BadgeDangerIcon,
-    "info": BadgeInfoIcon
+    "info": BadgeInfoIcon,
+    "danger": BadgeXIcon
 };
 
 const DateTimePicker = ({
@@ -605,7 +603,7 @@ const DateTimePicker = ({
                 setTempDate(undefined);
             }}
         >
-            <CleanIcon
+            <CircleXIcon
                 color="mid"
                 size={20}
             />
@@ -682,8 +680,7 @@ const DateTimePicker = ({
         const CurrentHintIcon = DateTimePickerTypeIcon[type === "default" ? "question" : type];
 
         return <CurrentHintIcon
-            customColor={isDisabled ? colors.system.state.content.disabled[styleType] : undefined}
-            color={currentType.hintTextIconColor}
+            color={isDisabled ? colors.system.state.content.disabled[styleType] : colors.content.icon[currentType.hintTextIconColor]}
             size={20}
             style={[
                 hintTextIconStyle,

+ 279 - 0
src/components/embeddedMenu/components/menuButton/index.tsx

@@ -0,0 +1,279 @@
+import {
+    useLayoutEffect,
+    useEffect,
+    useState,
+    type FC,
+    useRef
+} from "react";
+import {
+    Platform,
+    Animated,
+    Easing,
+    View
+} from "react-native";
+import type {
+    EmbeddedMenuButton as EmbeddedMenuButtonType
+} from "./type";
+import type IEmbeddedMenuButton from "./type";
+import {
+    NCoreUIKitLocalize,
+    NCoreUIKitTheme
+} from "../../../../core/hooks";
+import {
+    ChevronRightIcon,
+    ChevronDownIcon,
+    ChevronLeftIcon
+} from "lucide-react-native";
+import RowCard from "../../../rowCard";
+
+const getDeepActiveRouteName = (state: NCoreUIKit.NavigationState): string | undefined => {
+    if (!state?.routes?.length) return undefined;
+
+    const activeIndex = state.index ?? 0;
+    const activeRoute = state.routes[activeIndex];
+
+    if (!activeRoute) return undefined;
+
+    if (activeRoute.state) {
+        return getDeepActiveRouteName(activeRoute.state);
+    }
+    return activeRoute.name;
+};
+
+const isPageActive = (
+    buttonItem: EmbeddedMenuButtonType,
+    navigation: NCoreUIKit.Navigation
+): boolean => {
+    if (!navigation) return false;
+
+    const state = typeof navigation.getRootState === "function"
+        ? navigation.getRootState()
+        : typeof navigation.getState === "function"
+            ? navigation.getState()
+            : null;
+
+    if (!state?.routes) return false;
+
+    const activeRouteName = getDeepActiveRouteName(state);
+    const targetName = buttonItem.redirectSub ?? buttonItem.redirectMain;
+
+    if (targetName && activeRouteName === targetName) return true;
+
+    if (buttonItem.subButtons?.length) {
+        return buttonItem.subButtons.some(sub => isPageActive(sub, navigation));
+    }
+
+    return false;
+};
+
+const EmbeddedMenuButton: FC<IEmbeddedMenuButton> = ({
+    updateMenuButtonCollabs,
+    isMenuCollabs,
+    closeAction,
+    buttonIndex,
+    buttonItem,
+    navigation,
+    depthMap,
+    openMenu,
+    id
+}) => {
+    const {
+        colors
+    } = NCoreUIKitTheme.useContext();
+
+    const {
+        localize
+    } = NCoreUIKitLocalize.useContext();
+
+    const [
+        measure,
+        setMeasure
+    ] = useState<null | number>(null);
+
+    const [
+        navStateTracker,
+        setNavStateTracker
+    ] = useState(Date.now());
+
+    const [
+        isShowSubs,
+        setIsShowSubs
+    ] = useState(buttonItem.isCollapse);
+
+    const animatedCollabs = useRef(new Animated.Value(0)).current;
+
+    useEffect(() => {
+        if (!navigation || typeof navigation.addListener !== "function") return;
+
+        const unsubscribeState = navigation.addListener("state", () => {
+            setNavStateTracker(Date.now());
+        });
+
+        const unsubscribeFocus = navigation.addListener("focus", () => {
+            setNavStateTracker(Date.now());
+        });
+
+        return () => {
+            if (unsubscribeState) unsubscribeState();
+            if (unsubscribeFocus) unsubscribeFocus();
+        };
+    }, [navigation]);
+
+    useLayoutEffect(() => {
+        if(isShowSubs) {
+            Animated.timing(animatedCollabs, {
+                toValue: Platform.OS === "web" ? Number(measure) : 1,
+                useNativeDriver: Platform.OS !== "web",
+                easing: Easing.linear,
+                duration: 150
+            }).start();
+        }
+    }, [isShowSubs]);
+
+    useLayoutEffect(() => {
+        if(!buttonItem.isCollapsible) return;
+
+        if(Platform.OS === "web" && measure === null) return;
+
+        if(buttonItem.isCollapse) {
+            setIsShowSubs(true);
+        } else {
+            Animated.timing(animatedCollabs, {
+                useNativeDriver: Platform.OS !== "web",
+                easing: Easing.linear,
+                duration: 150,
+                toValue: 0
+            }).start(({
+                finished
+            }) => {
+                if(finished) {
+                    setIsShowSubs(false);
+                }
+            });
+        }
+    }, [
+        buttonItem.isCollapse,
+        measure
+    ]);
+
+    const isPActive = isPageActive(buttonItem, navigation);
+
+    if(!isMenuCollabs && !buttonItem.icon) {
+        return null;
+    }
+
+    return <View
+        key={`menu-button-${id}-${buttonIndex}-${navStateTracker.toString()}`}
+    >
+        <RowCard
+            {...buttonItem.props}
+            title={isMenuCollabs ? buttonItem.isUseLocalize ? localize(buttonItem.title as keyof NCoreUIKit.Translation) : buttonItem.title : ""}
+            rightIcon={
+                isMenuCollabs && (buttonItem.isCollapsible || buttonItem.isShowRedirectIcon) ?
+                    () => {
+                        if(buttonItem.isCollapsible) {
+                            if(buttonItem.isCollapse) {
+                                return <ChevronDownIcon
+                                    color={isPActive ? colors.content.icon.onPrimary : colors.content.icon.low}
+                                    size={18}
+                                />;
+                            } else {
+                                return <ChevronLeftIcon
+                                    color={isPActive ? colors.content.icon.onPrimary : colors.content.icon.low}
+                                    size={18}
+                                />;
+                            }
+                        } else {
+                            return <ChevronRightIcon
+                                color={isPActive ? colors.content.icon.onPrimary : colors.content.icon.low}
+                                size={18}
+                            />;
+                        }
+                    }
+                    :
+                    undefined
+            }
+            backgroundColor={isPActive ? "primary" : undefined}
+            titleColor={isPActive ? "onPrimary" : undefined}
+            iconColor={isPActive ? "onPrimary" : undefined}
+            icon={buttonItem.icon}
+            onPress={() => {
+                if(!isMenuCollabs && buttonItem.subButtons && buttonItem.subButtons.length) {
+                    openMenu();
+                    updateMenuButtonCollabs({
+                        status: true,
+                        buttonItem,
+                        depthMap
+                    });
+                    return;
+                }
+
+                if(buttonItem.isCollapsible) {
+                    updateMenuButtonCollabs({
+                        status: !buttonItem.isCollapse,
+                        buttonItem,
+                        depthMap
+                    });
+                } else {
+                    if(buttonItem.redirectMain || buttonItem.redirectSub) {
+                        if(buttonItem.redirectMain && buttonItem.redirectSub) {
+                            navigation.navigate(buttonItem.redirectMain, {
+                                screen: buttonItem.redirectSub
+                            });
+                        } else if(buttonItem.redirectMain) {
+                            navigation.navigate(buttonItem.redirectMain);
+                        }
+                    }
+
+                    if(buttonItem.props?.onPress) buttonItem.props.onPress();
+                }
+
+                if(closeAction && !buttonItem.isCollapsible) closeAction();
+            }}
+        />
+        {
+            buttonItem.subButtons && buttonItem.subButtons.length ?
+                <Animated.View
+                    onLayout={buttonItem.isCollapsible ? (event) => {
+                        const height = event.nativeEvent.layout.height;
+
+                        if(height !== 0 && measure === null) setMeasure(height);
+                    } : undefined}
+                    style={[
+                        Platform.OS === "web" ? {
+                            height: measure === null ? "auto" : animatedCollabs,
+                            overflow: "hidden"
+                        } : {
+                            display: isShowSubs ? "flex" : "none",
+                            transform: [{
+                                scaleY: animatedCollabs
+                            }],
+                            transformOrigin: "top",
+                            overflow: "hidden"
+                        }
+                    ]}
+                >
+                    {buttonItem.subButtons.map((subButtonItem, subButtonIndex) => {
+                        return <EmbeddedMenuButton
+                            key={`embedded-menu-sub-button-${id}-${subButtonIndex}`}
+                            updateMenuButtonCollabs={updateMenuButtonCollabs}
+                            isMenuCollabs={isMenuCollabs}
+                            buttonIndex={subButtonIndex}
+                            buttonItem={subButtonItem}
+                            closeAction={closeAction}
+                            navigation={navigation}
+                            openMenu={openMenu}
+                            depthMap={[
+                                ...depthMap,
+                                subButtonIndex
+                            ]}
+                            id={id}
+                        />;
+                    })}
+                </Animated.View>
+                :
+                null
+        }
+    </View>;
+};
+export default EmbeddedMenuButton;

+ 36 - 0
src/components/embeddedMenu/components/menuButton/type.ts

@@ -0,0 +1,36 @@
+import type {
+    NCoreUIKitIcon
+} from "../../../../types";
+import type IRowCardProps from "../../../rowCard/type";
+
+export type EmbeddedMenuButton = {
+    title: keyof NCoreUIKit.Translation | (string & {});
+    subButtons?: Array<EmbeddedMenuButton>;
+    isShowRedirectIcon?: NCoreUIKitIcon;
+    isCollapsible?: boolean;
+    isUseLocalize?: boolean;
+    redirectMain?: string;
+    props?: IRowCardProps;
+    icon?: NCoreUIKitIcon;
+    redirectSub?: string;
+    isCollapse?: boolean;
+};
+
+interface IEmbeddedMenuButton {
+    updateMenuButtonCollabs: (props: {
+        buttonItem: EmbeddedMenuButton;
+        depthMap: Array<number>;
+        status: boolean;
+    }) => void;
+    navigation: NCoreUIKit.Navigation;
+    buttonItem: EmbeddedMenuButton;
+    closeAction?: () => void;
+    depthMap: Array<number>;
+    isMenuCollabs: boolean;
+    openMenu: () => void;
+    buttonIndex: number;
+    id: string;
+};
+export type {
+    IEmbeddedMenuButton as default
+};

+ 433 - 0
src/components/embeddedMenu/index.tsx

@@ -0,0 +1,433 @@
+import {
+    useImperativeHandle,
+    useLayoutEffect,
+    forwardRef,
+    useEffect,
+    useState,
+    Fragment,
+    useRef
+} from "react";
+import {
+    Platform,
+    Animated,
+    Easing,
+    View
+} from "react-native";
+import {
+    type EmbeddedMenuButton as EmbeddedMenuButtonType
+} from "./components/menuButton/type";
+import {
+    type IEmbeddedMenuRef
+} from "./type";
+import type IEmbeddedMenuProps from "./type";
+import stylesheet, {
+    useStyles
+} from "./stylesheet";
+import MenuButton from "./components/menuButton";
+import {
+    NCoreUIKitEmbeddedMenu,
+    NCoreUIKitTheme
+} from "../../core/hooks";
+import type {
+    RefForwardingComponent
+} from "../../types";
+import {
+    PanelLeftClose,
+    PanelLeftOpen
+} from "lucide-react-native";
+import {
+    SafeAreaView
+} from "react-native-safe-area-context";
+import Seperator from "../seperator";
+import SiteLogo from "../siteLogo";
+import Button from "../button";
+
+const Menu: RefForwardingComponent<IEmbeddedMenuRef, IEmbeddedMenuProps> = ({
+    isWorkWithSafeAreaView = true,
+    isWorkWithAnimation = true,
+    renderHeader: RenderHeader,
+    renderFooter: RenderFooter,
+    isShowSiteLogo = true,
+    close: closeAction,
+    maxWidth = 300,
+    minWidth = 75,
+    siteLogoProps,
+    customTheme,
+    navigation,
+    isCollapse,
+    onClosed,
+    onOpened,
+    buttons,
+    onClose,
+    onOpen,
+    style,
+    id,
+    ...props
+}, ref) => {
+    const {
+        colors,
+        spaces
+    } = NCoreUIKitTheme.useContext(customTheme);
+
+    const [
+        isActive,
+        setIsActive
+    ] = useState(false);
+
+    const {
+        headerContentContainer: headerContentContainerDynamicStyle,
+        headerContainer: headerContainerDynamicStyle,
+        collapseButton: collapseButtonDynamicStyle,
+        seperator: seperatorDynamicStyle,
+        container: containerDynamicStyle,
+        siteLogo: siteLogoDynamicStyle
+    } = useStyles({
+        isCollapse: isActive,
+        colors,
+        spaces
+    });
+
+    const animatedX = useRef(new Animated.Value(!isCollapse ? minWidth : maxWidth)).current;
+
+    useImperativeHandle(
+        ref,
+        () => ({
+            close,
+            open
+        }),
+        []
+    );
+
+    useEffect(() => {
+        if(isCollapse !== undefined && isActive !== isCollapse) setIsActive(isCollapse);
+    }, [isCollapse]);
+
+    useLayoutEffect(() => {
+        if(isActive) {
+            if(onOpen) onOpen({
+                id
+            });
+
+            if(Platform.OS !== "web") {
+                if(onOpened) onOpened({
+                    id
+                });
+            } else if(isWorkWithAnimation) {
+                openAnimation();
+            } else {
+                animatedX.setValue(maxWidth);
+
+                if(onOpened) onOpened({
+                    id
+                });
+            }
+        } else {
+            if(onClose) onClose({
+                id
+            });
+
+            if(isWorkWithAnimation && Platform.OS === "web") {
+                closeAnimation();
+            } else {
+                animatedX.setValue(minWidth);
+
+                if(onClosed) onClosed({
+                    id
+                });
+            }
+        }
+    }, [
+        isActive
+    ]);
+
+    const open = () => {
+        NCoreUIKitEmbeddedMenu.open({
+            id
+        });
+    };
+
+    const close = () => {
+        NCoreUIKitEmbeddedMenu.close({
+            id
+        });
+    };
+
+    const openAnimation = () => {
+        Animated.timing(animatedX, {
+            useNativeDriver: Platform.OS !== "web",
+            easing: Easing.linear,
+            toValue: maxWidth,
+            duration: 300
+        }).start(({
+            finished
+        }) => {
+            if(finished) {
+                if(onOpened) onOpened({
+                    id
+                });
+            }
+        });
+    };
+
+    const closeAnimation = () => {
+        Animated.timing(animatedX, {
+            useNativeDriver: Platform.OS !== "web",
+            easing: Easing.linear,
+            toValue: minWidth,
+            duration: 300
+        }).start(({
+            finished
+        }) => {
+            if(finished) {
+                if(onClosed) onClosed({
+                    id
+                });
+            }
+        });
+    };
+
+    const updateMenuButtonCollabs = ({
+        depthMap,
+        status
+    }: {
+        depthMap: Array<number>;
+        status: boolean;
+    }) => {
+        const state = NCoreUIKitEmbeddedMenu.get({
+            id
+        });
+
+        if(!state) {
+            return;
+        }
+
+        const recursivelyCatch = (item: Array<EmbeddedMenuButtonType>, index = 0): Array<EmbeddedMenuButtonType> => {
+            const tIndex = depthMap[index];
+
+            return item.map((c_item, c_index) => {
+                if(c_index !== tIndex) {
+                    return c_item;
+                }
+
+                if(index === depthMap.length - 1) {
+                    return {
+                        ...c_item,
+                        isCollapse: status
+                    };
+                }
+
+                return {
+                    ...c_item,
+                    subButtons: recursivelyCatch(c_item.subButtons as Array<EmbeddedMenuButtonType>, index + 1)
+                };
+            });
+        };
+
+        const newButtons = recursivelyCatch(state.buttons);
+
+        state.buttons = newButtons;
+
+        NCoreUIKitEmbeddedMenu.update({
+            menuData: state,
+            id: id
+        });
+    };
+
+    const renderToggleCollapseForCollabsed = () => {
+        if(isActive) {
+            return null;
+        }
+
+        return <Button
+            isCustomPadding={true}
+            spreadBehaviour="free"
+            type="neutral"
+            size="medium"
+            icon={({
+                color,
+                size
+            }) => {
+                return <PanelLeftOpen
+                    color={colors.content.icon[color]}
+                    size={size * 2}
+                />;
+            }}
+            style={{
+                ...collapseButtonDynamicStyle
+            }}
+            onPress={() => {
+                if(isActive) {
+                    close();
+                } else {
+                    open();
+                }
+            }}
+        />;
+    };
+
+    const renderToggleCollapseForExpended = () => {
+        if(!isActive) {
+            return null;
+        }
+
+        return <Button
+            isCustomPadding={true}
+            spreadBehaviour="free"
+            type="neutral"
+            size="medium"
+            icon={({
+                color,
+                size
+            }) => {
+                return <PanelLeftClose
+                    color={colors.content.icon[color]}
+                    size={size * 2}
+                />;
+            }}
+            style={{
+                ...collapseButtonDynamicStyle
+            }}
+            onPress={() => {
+                if(isActive) {
+                    close();
+                } else {
+                    open();
+                }
+            }}
+        />;
+    };
+
+    const renderHeader = () => {
+        if(RenderHeader) {
+            return <RenderHeader
+                isCollapse={isActive}
+                maxWidth={maxWidth}
+                minWidth={minWidth}
+            />;
+        }
+
+        return <View
+            style={[
+                stylesheet.headerContainer,
+                headerContainerDynamicStyle
+            ]}
+        >
+            {renderToggleCollapseForCollabsed()}
+            <View
+                style={[
+                    stylesheet.headerContentContainer,
+                    headerContentContainerDynamicStyle
+                ]}
+            >
+                {isShowSiteLogo ? <SiteLogo
+                    {...siteLogoProps}
+                    title={isActive ? siteLogoProps?.title : undefined}
+                    size={isActive ? siteLogoProps?.size : "small"}
+                    style={[
+                        siteLogoProps?.style,
+                        siteLogoDynamicStyle
+                    ]}
+                /> : <View
+                    style={{
+                        flex: 1
+                    }}
+                />}
+                {renderToggleCollapseForExpended()}
+            </View>
+            <Seperator
+                style={[
+                    stylesheet.seperator,
+                    seperatorDynamicStyle
+                ]}
+            />
+        </View>;
+    };
+
+    const renderButtons = () => {
+        if(!buttons || !buttons.length) {
+            return null;
+        }
+
+        return buttons.map((buttonItem, buttonIndex) => {
+            return <MenuButton
+                key={`embedded-menu-button-${id}-${buttonIndex}`}
+                updateMenuButtonCollabs={updateMenuButtonCollabs}
+                closeAction={closeAction}
+                buttonIndex={buttonIndex}
+                isMenuCollabs={isActive}
+                depthMap={[buttonIndex]}
+                buttonItem={buttonItem}
+                navigation={navigation}
+                openMenu={() => {
+                    open();
+                }}
+                id={id}
+            />;
+        });
+    };
+
+    const renderFooter = () => {
+        if(!RenderFooter) {
+            return null;
+        }
+
+        return <RenderFooter
+            isCollapse={isActive}
+            maxWidth={maxWidth}
+            minWidth={minWidth}
+        />;
+    };
+
+    const renderSafeAreaContext = () => {
+        if(!isWorkWithSafeAreaView) {
+            return <Fragment>
+                {renderHeader()}
+                <View
+                    style={[
+                        stylesheet.content
+                    ]}
+                >
+                    {renderButtons()}
+                </View>
+                {renderFooter()}
+            </Fragment>;
+        }
+
+        return <SafeAreaView
+            style={[
+                stylesheet.safeAreaView
+            ]}
+        >
+            {renderHeader()}
+            <View
+                style={[
+                    stylesheet.content
+                ]}
+            >
+                {renderButtons()}
+            </View>
+            {renderFooter()}
+        </SafeAreaView>;
+    };
+
+    const renderContent = () => {
+        return <Animated.View
+            {...props}
+            style={[
+                style,
+                stylesheet.container,
+                containerDynamicStyle,
+                Platform.OS === "web" ? {
+                    width: animatedX
+                } : {
+                    width: isActive ? maxWidth : minWidth
+                }
+            ]}
+        >
+            {renderSafeAreaContext()}
+        </Animated.View>;
+    };
+
+    return renderContent();
+};
+export default forwardRef(Menu);

Некоторые файлы не были показаны из-за большого количества измененных файлов