{"id":1594,"date":"2025-06-28T02:37:21","date_gmt":"2025-06-28T02:37:21","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=1594"},"modified":"2025-06-28T07:11:34","modified_gmt":"2025-06-28T07:11:34","slug":"flmbottomsheet","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/06\/28\/flmbottomsheet\/","title":{"rendered":"\ubc14\ud140\uc2dc\ud2b8\/FlmBottomSheet"},"content":{"rendered":"\n<p><strong>1.react-native-freelifemakers-ui NPM \ubaa8\ub4c8 \uc124\uce58\ud558\uae30 \/ react-native-freelifemakers-ui NPM Module Instal<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># npm install react-native-freelifemakers-ui<\/code><\/pre>\n\n\n\n<p><strong>2.\uc758\uc874\uc131 \ubaa8\ub4c8 \uc124\uce58 \/ peerModule install<\/strong><\/p>\n\n\n\n<p>&#8212; FlmBottomSheet\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c \ubc18\ub4dc\uc2dc \uc124\uce58\ud574\uc57c \ud558\ub294 \ubaa8\ub4c8\uc785\ub2c8\ub2e4.<br>This is a module that must be installed to use FlmBottomSheet.<\/p>\n\n\n\n<p>1)React-Native Expo \ud83c\udf0d<\/p>\n\n\n\n<p>&#8212; \u2757  react-native-freelifemakers-ui \uc774 \ubaa8\ub4c8\uc744 \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798 \ub450\uac1c\uc758 \ubaa8\ub4c8\uc744 \ubc18\ub4dc\uc2dc \uc124\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.<br>To use this module, you must install the following two modules: react-native-freelifemakers-ui<\/p>\n\n\n\n<p>&#8212; \u2757 \ub9ac\uc561\ud2b8 \ub124\uc774\ud2f0\ube0c \uc5d1\uc2a4\ud3ec\ub294 \ubc18\ub4dc\uc2dc react-native-reanimated@3.17.4 \ubc84\uc804\uc744 \uc124\uce58 \ud569\ub2c8\ub2e4.<br>React Native Expo requires react-native-reanimated@3.17.4 to be installed.<\/p>\n\n\n\n<p>&#8212; \u2757 \uc5d1\uc2a4\ud3ec \ud504\ub85c\uc81d\ud2b8\uc640 3.17.4\ubc84\uc804\uc774 \uac00\uc7a5 \ud638\ud658\uc774 \uc798\ub418\uba70 \uc774\uac83\ubcf4\ub2e4 \uc0c1\uc704\ubc84\uc804 \uc124\uce58\uc2dc \ubc14\ud140\uc2dc\ud2b8\uac00 \ub3d9\uc791\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>Expo Project is most compatible with version 3.17.4, and the bottom sheet may not work when installing a higher version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># npm install react-native-gesture-handler\n\n# npm install react-native-reanimated@3.17.4<\/code><\/pre>\n\n\n\n<p>&#8212; babel.config.js \ud83c\udf0d<br>&#8211;&gt; \uc774 \ud30c\uc77c\uc774 \uc5c6\uc73c\uba74 \ud30c\uc77c\uc744 \uc9c1\uc811 \ub9cc\ub4e7\ub2c8\ub2e4.<br>If this file does not exist, create it yourself.<br>&#8211;&gt; \ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \ub0b4 package.json\ud30c\uc77c\uacfc \ub3d9\uc77c\ud55c \uc704\uce58\uc5d0 \ub9cc\ub4e4\uba74 \ub429\ub2c8\ub2e4.<br>Just create it in the same location as the package.json file in your project folder.<br>&#8211;&gt; \uc544\ub798\uc5d0 reanimated\ubaa8\ub4c8\uc744 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \uc124\uc815\uc744 \uc801\uc6a9\ud569\ub2c8\ub2e4.<br>Apply the following settings for the reanimated module below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ babel.config.js\nmodule.exports = function(api) {\n  api.cache(true);\n  return {\n    presets: &#91;'babel-preset-expo'],\n    plugins: &#91;\n      'react-native-reanimated\/plugin', \/\/react-native-reanimated module setting\n    ],\n  };\n};<\/code><\/pre>\n\n\n\n<p>2)React-Native CLI \ud83c\udf0d<\/p>\n\n\n\n<p>&#8212;  \u2757 react-native-freelifemakers-ui \uc774 \ubaa8\ub4c8\uc744 \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798 \ub450\uac1c\uc758 \ubaa8\ub4c8\uc744 \ubc18\ub4dc\uc2dc \uc124\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.<br>To use this module, you must install the following two modules: react-native-freelifemakers-ui<\/p>\n\n\n\n<p>&#8212; \u2757 \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c\ub294 react-native-reanimated\ubaa8\ub4c8\uc774 \uc548\uc815\uc801\uc73c\ub85c \ub3d9\uc791\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0\uac00 \uc788\uc2b5\ub2c8\ub2e4.<br>On Android, the react-native-reanimated module may not work reliably.<\/p>\n\n\n\n<p>&#8212; IOS\uc5d0\uc11c\ub294 \uc815\uc0c1\uc801\uc73c\ub85c \uc791\ub3d9\ud569\ub2c8\ub2e4.<br>It works fine on iOS.<\/p>\n\n\n\n<p>&#8212; \ub9ac\uc561\ud2b8\ub124\uc774\ud2f0\ube0c CLI\uc5d0\uc11c\ub294 react-native-reanimated \ucd5c\uc120\ubc84\uc804\uc744 \uc124\uce58\ud574\ub3c4 \ub429\ub2c8\ub2e4.<br>For React Native CLI, you can install the latest version of react-native-reanimated.<\/p>\n\n\n\n<p>&#8212; \ud604\uc7ac 3.18.0\ubc84\uc804 \uc124\uce58\ud574\uc11c \ud14c\uc2a4\ud2b8 \ud574\ubcf8 \uacb0\uacfc \uc798 \uc791\ub3d9 \ud569\ub2c8\ub2e4.<br>I have currently installed version 3.18.0 and tested it and it works well.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># npm install react-native-gesture-handler\n# npm install react-native-reanimated<\/code><\/pre>\n\n\n\n<p>&#8212; babel.config.js \ud83c\udf0d<br>&#8211;&gt; \uc774 \ud30c\uc77c\uc774 \uc5c6\uc73c\uba74 \ud30c\uc77c\uc744 \uc9c1\uc811 \ub9cc\ub4e7\ub2c8\ub2e4.<br>If this file does not exist, create it yourself.<br>&#8211;&gt; \ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \ub0b4 package.json\ud30c\uc77c\uacfc \ub3d9\uc77c\ud55c \uc704\uce58\uc5d0 \ub9cc\ub4e4\uba74\ub429\ub2c8\ub2e4.<br>Just create it in the same location as the package.json file in your project folder.<br>&#8211;&gt; \uc544\ub798\uc5d0 reanimated\ubaa8\ub4c8\uc744 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \uc124\uc815\uc744 \uc801\uc6a9\ud569\ub2c8\ub2e4.<br>Apply the following settings for the reanimated module below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ babel.config.js\nmodule.exports = {\n  presets: &#91;'module:@react-native\/babel-preset'],\n  plugins: &#91;'react-native-reanimated\/plugin'], \/\/react-native-reanimated module setting\n};<\/code><\/pre>\n\n\n\n<p><strong>3.\uc0ac\uc6a9\ud558\uae30 \/ Usage<\/strong><\/p>\n\n\n\n<p>&#8212; \ubc84\ud2bc \ud074\ub9ad\uc2dc \ubc14\ud140\uc2dc\ud2b8 \ubcf4\uc774\uba70 \ubc14\ud0d5\ud654\uba74 \ud0ed\ud558\uac70\ub098 \ubc84\ud2bc \ud074\ub9ad\uc2dc \ubc14\ud140\uc2dc\ud2b8 \ub2eb\ud799\ub2c8\ub2e4.<br>When you click the button, the bottom sheet appears, and when you tap the desktop or click the button, the bottom sheet closes.<\/p>\n\n\n\n<p>&#8212; \ubc14\ud140\uc2dc\ud2b8 \ub4dc\ub798\uadf8\ub85c \ub2eb\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>Bottom sheet can be closed by dragging<\/p>\n\n\n\n<p>&#8212; \uc544\ub798\uc758 \ucf54\ub4dc\ub97c \ubcf5\uc0ac\ud574\uc11c \uc2e4\ud589\ud574\ubcf4\uace0 \uc798 \uc791\ub3d9\ud558\uba74 \uc218\uc815\ud574\uc11c \uc0ac\uc6a9\ud558\uc2dc\uba74 \ub429\ub2c8\ub2e4.<br>Please copy and run the code below. If it works well, you can modify it and use it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\/\/ module import\nimport React, { useRef, useState, useEffect } from \"react\";\nimport { SafeAreaView, View, StyleSheet, ScrollView } from \"react-native\";\n\n\/\/ Required modules\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport {FlmBottomSheet, FlmButton, FlmText} from 'react-native-freelifemakers-ui';\n\n\nexprt default function App(){\n\n  \/\/ \ubc14\ud140 \uc2dc\ud2b8 \uc0c1\ud0dc \uc124\uc815 \/ bottom sheet status settings\n  const bottomSheetRef1 = useRef(null);\n  const &#91;isVisible1, setIsVisible1] = useState(false);\n\n \/\/ \ubc14\ud140 \uc2dc\ud2b8 \uc5f4\uae30 \/ Open the bottom sheet\n  const openSheet1 = () =&gt; {\n    setIsVisible1(true);\n  };\n\n \/\/ \ubc14\ud140 \uc2dc\ud2b8 \ub2eb\uae30 (useEffect\uc5d0\uc11c isVisible1 \uc0c1\ud0dc \ubcc0\ud654\uc5d0 \ub530\ub77c \ud638\ucd9c\ub428)\n \/\/ Close the bottom sheet (called in useEffect when isVisible1 state changes)\n  const closeSheet1 = () =&gt; {\n    \/\/ isVisible \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uc5ec useEffect\uac00 close()\ub97c \ud638\ucd9c\ud558\ub3c4\ub85d \uc720\ub3c4\n    \/\/ Change the isVisible state to force useEffect to call close().\n    setIsVisible1(false);\n  };\n\n  \/\/ \ubc14\ud140 \uc2dc\ud2b8 onClose \ucf5c\ubc31 (\ubc14\ud140 \uc2dc\ud2b8 \uc560\ub2c8\uba54\uc774\uc158 \uc644\ub8cc \ud6c4 \ud638\ucd9c\ub428)\n  \/\/ bottom sheet onClose callback (called after bottom sheet animation completes)\n  const onSheet1Close = () =&gt; setIsVisible1(false);\n\n  \/\/ openSheet1\uc2e4\ud589\ub420\ub54c,\ubc14\ud140\uc2dc\ud2b8\uc5f4\uae30 \ud074\ub9ad \ud560\ub54c \/ When OpenSheet1 is executed, click Open Bottom Sheet\n  \/\/ \ubc14\ud140 \uc2dc\ud2b8 \uc624\ud508 \/ Bottom sheet open\n  useEffect(() =&gt; {\n    if (isVisible1) {\n      bottomSheetRef1.current?.open(0);\n    } else if (bottomSheetRef1.current) {\n      bottomSheetRef1.current.close();\n    }\n  }, &#91;isVisible1]);\n\n  \/\/ UI area\n  return (\n    &lt;GestureHandlerRootView style={{ flex: 1 }}&gt;\n      &lt;SafeAreaView style={styles.container}&gt;\n        &lt;ScrollView contentContainerStyle={styles.scrollContent}&gt;\n          {\/* \ubc14\ud140 \uc2dc\ud2b8 \ubc84\ud2bc \/ First bottom sheet button *\/}\n          &lt;FlmButton\n            title=\"\uccab \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\uae30\/Open first sheet\"\n            onPress={openSheet1}\n          \/&gt;\n        &lt;\/ScrollView&gt;\n\n        {\/*  \ubc14\ud140\uc2dc\ud2b8\ub294 ScrollView \uc678\ubd80\uc5d0\uc11c \ub80c\ub354\ub9c1 \/ Bottom sheet is rendered outside ScrollView *\/}\n        {isVisible1 &amp;&amp; (\n          &lt;FlmBottomSheet\n            ref={bottomSheetRef1}\n            snapPoints={&#91;\"30%\", \"60%\"]} \/\/ \uc2dc\ud2b8\uc704\uce58 \/ sheet location\n\n            \/\/ \uc2dc\ud2b8 \uc2dc\uc791\uc704\uce58(\ud654\uba74\uc544\ub798) \/ Sheet start position (bottom of screen)\n            \/\/ -1 : \ub79c\ub354\ub9c1\uc2dc \uc790\ub3d9\uc73c\ub85c \uc2dc\ud2b8 \uc5f4\uc9c0 \uc54a\uc74c \/ Do not automatically open sheets when rendering\n            \/\/ 0 : snapPoints 30% \uc2e4\ud589 \/ 30% of snapPoints are executed\n            \/\/ 1 : snapPoints 60% \uc2e4\ud589 \/ snapPoints 60% running\n            initialSnapIndex={-1}\n\n            enablePanDownToClose={true} \/\/ \uc544\ub798\ub85c \ub4dc\ub798\uadf8\ud574\uc11c \ub2eb\uae30 \uae30\ub2a5 \/ Drag down to close feature\n            onOpen={() =&gt; console.log(\"\uccab \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\ub9bc\/First sheet opened\")}\n            onClose={onSheet1Close} \/\/ \uc2dc\ud2b8\ub2eb\uae30 \/ sheet close\n          &gt;\n            &lt;ScrollView contentContainerStyle={styles.sheetContent}&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub0b4\uc6a9\uc785\ub2c8\ub2e4.\n              &lt;\/FlmText&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                Here is the first bottom sheet content.\n              &lt;\/FlmText&gt;\n              &lt;FlmButton title=\"\ub2eb\uae30\/Close\" onPress={closeSheet1} \/&gt;\n            &lt;\/ScrollView&gt;\n          &lt;\/FlmBottomSheet&gt;\n        )}\n     &lt;\/SafeAreaView&gt;\n    &lt;\/GestureHandlerRootView&gt;\n  );\n}\n\n} \/\/ App()\n\n<\/code><\/pre>\n\n\n\n<p><strong>4.\uc608\uc81c\ucf54\ub4dc \/ Example code<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nimport React, { useRef, useState, useEffect } from \"react\";\nimport { SafeAreaView, View, StyleSheet, ScrollView } from \"react-native\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport {\n  FlmBottomSheet,\n  FlmButton,\n  FlmText,\n} from \"react-native-freelifemakers-ui\";\n\nexport default function App() {\n  \/\/ \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc0c1\ud0dc \/ First bottom sheet status\n  const bottomSheetRef1 = useRef(null);\n  const &#91;isVisible1, setIsVisible1] = useState(false);\n\n  \/\/ \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc0c1\ud0dc \/ Second Bottom Sheet Status\n  const bottomSheetRef2 = useRef(null);\n  const &#91;isVisible2, setIsVisible2] = useState(false);\n\n  \/\/ \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc0c1\ud0dc \/ Third Bottom Sheet State\n  const bottomSheetRef3 = useRef(null);\n  const &#91;isVisible3, setIsVisible3] = useState(false);\n\n  \/\/======= \uccab\ubc88\uc9f8 \ubc14\ud140\uc2dc\ud2b8 \/ First bottom sheet =======\n\n  \/\/ \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc5f4\uae30 \/ Open the first bottom sheet\n  const openSheet1 = () =&gt; {\n    setIsVisible1(true);\n  };\n\n  \/\/ \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub2eb\uae30 (useEffect\uc5d0\uc11c isVisible1 \uc0c1\ud0dc \ubcc0\ud654\uc5d0 \ub530\ub77c \ud638\ucd9c\ub428)\n  \/\/ Close the first bottom sheet (called in useEffect when isVisible1 state changes)\n  const closeSheet1 = () =&gt; {\n    \/\/ isVisible \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uc5ec useEffect\uac00 close()\ub97c \ud638\ucd9c\ud558\ub3c4\ub85d \uc720\ub3c4\n    \/\/ Change the isVisible state to force useEffect to call close().\n    setIsVisible1(false);\n  };\n\n  \/\/ \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 onClose \ucf5c\ubc31 (\ubc14\ud140 \uc2dc\ud2b8 \uc560\ub2c8\uba54\uc774\uc158 \uc644\ub8cc \ud6c4 \ud638\ucd9c\ub428)\n  \/\/ First bottom sheet onClose callback (called after bottom sheet animation completes)\n  const onSheet1Close = () =&gt; setIsVisible1(false);\n  useEffect(() =&gt; {\n    if (isVisible1) {\n      \/\/ snapPoints\uc758 \uccab \ubc88\uc9f8 \uc9c0\uc810 (\uac00\uc7a5 \ub192\uc740 \ud37c\uc13c\ud14c\uc774\uc9c0\/\ud53d\uc140 \ub192\uc774)\uc73c\ub85c \uc5f4\uae30\n      \/\/ Open to the first point of snapPoints (highest percentage\/pixel height)\n      bottomSheetRef1.current?.open(0);\n    } else if (bottomSheetRef1.current) {\n      bottomSheetRef1.current.close();\n    }\n  }, &#91;isVisible1]);\n\n  \/\/======= \ub450\ubc88\uc9f8 \ubc14\ud140\uc2dc\ud2b8 \/ second bottom sheet =======\n\n  \/\/ \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc5f4\uae30 \/ Open the second bottom sheet\n  const openSheet2 = () =&gt; {\n    setIsVisible2(true);\n  };\n\n  \/\/ \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub2eb\uae30 (useEffect\uc5d0\uc11c isVisible2 \uc0c1\ud0dc \ubcc0\ud654\uc5d0 \ub530\ub77c \ud638\ucd9c\ub428)\n  \/\/ Close the second bottom sheet (called in useEffect when isVisible2 state changes)\n  const closeSheet2 = () =&gt; {\n    \/\/ isVisible \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uc5ec useEffect\uac00 close()\ub97c \ud638\ucd9c\ud558\ub3c4\ub85d \uc720\ub3c4\n    \/\/ Change the isVisible state to force useEffect to call close().\n    setIsVisible2(false);\n  };\n\n  \/\/ \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 onClose \ucf5c\ubc31 (\ubc14\ud140 \uc2dc\ud2b8 \uc560\ub2c8\uba54\uc774\uc158 \uc644\ub8cc \ud6c4 \ud638\ucd9c\ub428)\n  \/\/ Second bottom sheet onClose callback (called after bottom sheet animation completes)\n  const onSheet2Close = () =&gt; setIsVisible2(false);\n  useEffect(() =&gt; {\n    if (isVisible2) {\n      \/\/ snapPoints\uc758 \uccab \ubc88\uc9f8 \uc9c0\uc810 (\uac00\uc7a5 \ub192\uc740 \ud37c\uc13c\ud14c\uc774\uc9c0\/\ud53d\uc140 \ub192\uc774)\uc73c\ub85c \uc5f4\uae30\n      \/\/ Open to the first point of snapPoints (highest percentage\/pixel height)\n      bottomSheetRef2.current?.open(0);\n    } else if (bottomSheetRef2.current) {\n      bottomSheetRef2.current.close();\n    }\n  }, &#91;isVisible2]);\n\n  \/\/======= \uc138\ubc88\uc9f8 \ubc14\ud140\uc2dc\ud2b8 \/ Third bottom sheet =======\n\n  \/\/ \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \uc5f4\uae30\n  \/\/ Open the third bottom sheet\n  const openSheet3 = () =&gt; {\n    setIsVisible3(true);\n  };\n\n  \/\/ \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub2eb\uae30\n  \/\/ Close the third bottom sheet\n  const closeSheet3 = () =&gt; {\n    setIsVisible3(false);\n  };\n\n  \/\/ \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 onClose \ucf5c\ubc31\n  \/\/ Third bottom sheet onClose callback\n  const onSheet3Close = () =&gt; setIsVisible3(false);\n  useEffect(() =&gt; {\n    if (isVisible3) {\n      \/\/ \uace0\uc815 \ub192\uc774 600px\ub85c \uc5f4\uae30 \/ Open with fixed height 600px\n      bottomSheetRef3.current?.open(0);\n    } else if (bottomSheetRef3.current) {\n      bottomSheetRef3.current.close();\n    }\n  }, &#91;isVisible3]);\n\n  return (\n    &lt;GestureHandlerRootView style={{ flex: 1 }}&gt;\n      &lt;SafeAreaView style={styles.container}&gt;\n        &lt;ScrollView contentContainerStyle={styles.scrollContent}&gt;\n          {\/*\n            \ubc14\ud140 \uc2dc\ud2b8\ub294 \ubaa8\ub4e0 UI\ubcf4\ub2e4 \uc544\ub798\uc5d0 \uc704\uccb4 \ud574\uc57c \ud569\ub2c8\ub2e4.\n            \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 UI\uac00 \ubc14\ud140\uc2dc\ud2b8\ub098 \ubc14\ud140\uc2dc\ud2b8 \ubc30\uacbd\ubcf4\ub2e4 \uc704\uc5d0 \uc62c \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n            The bottom sheet must be positioned below all UI.\n            Otherwise, UI may be positioned above the bottom sheet or the bottom sheet background.\n          *\/}\n          &lt;FlmText style={styles.title}&gt;Flm \ub2e4\uc774\ub0b4\ubbf9 \ubc14\ud140 \uc2dc\ud2b8&lt;\/FlmText&gt;\n          &lt;FlmText style={styles.title}&gt;Flm dynamic bottom seat&lt;\/FlmText&gt;\n\n          {\/* \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ubc84\ud2bc \/ First bottom sheet button *\/}\n          &lt;FlmButton\n            title=\"\uccab \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\uae30\/Open first sheet\"\n            onPress={openSheet1}\n          \/&gt;\n\n          {\/* \ubc84\ud2bc \uac04 \uac04\uaca9 \/ Spacing between buttons *\/}\n          &lt;View style={styles.spacer} \/&gt;\n\n          {\/* \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ubc84\ud2bc \/ Second bottom sheet button *\/}\n          &lt;FlmButton\n            title=\"\ub450 \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\uae30\/Open second sheet\"\n            onPress={openSheet2}\n          \/&gt;\n\n          {\/* \ubc84\ud2bc \uac04 \uac04\uaca9 \/ Spacing between buttons *\/}\n          &lt;View style={styles.spacer} \/&gt;\n\n          {\/* \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ubc84\ud2bc \/ Third bottom sheet button *\/}\n          &lt;FlmButton\n            title=\"\uc138 \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\uae30\/Open third sheet\"\n            onPress={openSheet3}\n          \/&gt;\n        &lt;\/ScrollView&gt;\n\n        {\/*  \ubc14\ud140\uc2dc\ud2b8\ub294 ScrollView \uc678\ubd80\uc5d0\uc11c \ub80c\ub354\ub9c1 \/ Bottom sheet is rendered outside ScrollView *\/}\n        {isVisible1 &amp;&amp; (\n          &lt;FlmBottomSheet\n            ref={bottomSheetRef1}\n            snapPoints={&#91;\"30%\", \"60%\"]} \/\/ \uc2dc\ud2b8\uc704\uce58 \/ sheet location\n            \/\/ \uc2dc\ud2b8 \uc2dc\uc791\uc704\uce58(\ud654\uba74\uc544\ub798) \/ Sheet start position (bottom of screen)\n            \/\/ -1 : \ub79c\ub354\ub9c1\uc2dc \uc790\ub3d9\uc73c\ub85c \uc2dc\ud2b8 \uc5f4\uc9c0 \uc54a\uc74c \/ Do not automatically open sheets when rendering\n            \/\/ 0 : snapPoints 30% \uc2e4\ud589 \/ 30% of snapPoints are executed\n            \/\/ 1 : snapPoints 60% \uc2e4\ud589 \/ snapPoints 60% running\n            initialSnapIndex={-1}\n            enablePanDownToClose={true} \/\/ \uc544\ub798\ub85c \ub4dc\ub798\uadf8\ud574\uc11c \ub2eb\uae30 \uae30\ub2a5 \/ Drag down to close feature\n            onOpen={() =&gt; console.log(\"\uccab \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\ub9bc\/First sheet opened\")}\n            onClose={onSheet1Close} \/\/ \uc2dc\ud2b8\ub2eb\uae30 \/ sheet close\n          &gt;\n            &lt;ScrollView contentContainerStyle={styles.sheetContent}&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                \uccab \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub0b4\uc6a9\uc785\ub2c8\ub2e4.\n              &lt;\/FlmText&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                Here is the first bottom sheet content.\n              &lt;\/FlmText&gt;\n              &lt;FlmButton title=\"\ub2eb\uae30\/Close\" onPress={closeSheet1} \/&gt;\n            &lt;\/ScrollView&gt;\n          &lt;\/FlmBottomSheet&gt;\n        )}\n\n        {isVisible2 &amp;&amp; (\n          &lt;FlmBottomSheet\n            ref={bottomSheetRef2}\n            snapPoints={&#91;\"40%\", \"60%\"]} \/\/ \uc2dc\ud2b8\uc704\uce58 \/ sheet location\n            initialSnapIndex={-1}\n            enablePanDownToClose={true}\n            onOpen={() =&gt; console.log(\"\ub450 \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\ub9bc\/Second sheet open\")}\n            onClose={onSheet2Close}\n            \/\/ \uc2a4\ud0c0\uc77c \ucd94\uac00 \/ Add style\n            sheetStyle={{\n              backgroundColor: \"#e6e6fa\",\n              borderTopLeftRadius: 10,\n              borderTopRightRadius: 10,\n            }}\n            handleIndicatorStyle={{ backgroundColor: \"#6a5acd\", width: 50 }}\n            overlayStyle={{ backgroundColor: \"rgba(0,100,0,0.3)\" }}\n          &gt;\n            &lt;ScrollView contentContainerStyle={styles.sheetContent}&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                \ub450 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 \ub0b4\uc6a9\uc785\ub2c8\ub2e4. \ub2e4\ub978 \uc2a4\ud0c0\uc77c\uc774 \uc801\uc6a9\ub418\uc5c8\uc2b5\ub2c8\ub2e4!\n              &lt;\/FlmText&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                Here`s the second bottom sheet content, with a different style\n                applied!\n              &lt;\/FlmText&gt;\n              &lt;FlmButton title=\"\ub2eb\uae30\/Close\" onPress={closeSheet2} \/&gt;\n            &lt;\/ScrollView&gt;\n          &lt;\/FlmBottomSheet&gt;\n        )}\n\n        {\/*  \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8 - \uace0\uc815 \ub192\uc774 600px \/ Third bottom sheet - fixed height 600px *\/}\n        {isVisible3 &amp;&amp; (\n          &lt;FlmBottomSheet\n            ref={bottomSheetRef3}\n            \/\/ \uace0\uc815 \ub192\uc774 \uc124\uc815 \/ Set fixed height\n            snapPoints={&#91;600]}\n            initialSnapIndex={-1}\n            enablePanDownToClose={true}\n            onOpen={() =&gt; console.log(\"\uc138 \ubc88\uc9f8 \uc2dc\ud2b8 \uc5f4\ub9bc\/Third sheet open\")}\n            onClose={onSheet3Close}\n            \/\/ \uc2dc\ud2b8\uac00 \ud654\uba74 \uc544\ub798\uc11c \ubd80\ud130 \uc2dc\uc791\ub418\ub3c4\ub85d \uc14b\ud305\n            \/\/ Set the sheet to start from the bottom of the screen\n            sheetStyle={{\n              backgroundColor: \"#ffe4e1\",\n              borderTopLeftRadius: 16,\n              borderTopRightRadius: 16,\n              \/\/ \uc2dc\ud2b8 \ub192\uc774 \uac15\uc81c \uc9c0\uc815 \/ Force seat height\n              height: 600,\n              position: \"absolute\",\n              \/\/ \ud654\uba74 \uc544\ub798\uc5d0\uc11c \uc62c\ub77c\uc624\ub3c4\ub85d \uc124\uc815 \uc544\ub798\uc5d0 \uc5ec\ubc31\uc744 \uc8fc\uc9c0 \uc54a\uc74c.\n              \/\/ Set to rise from the bottom of the screen without leaving any margin below.\n              bottom: 0,\n              width: \"100%\", \/\/ \ud654\uba74 \ub108\ube44 \uc804\uccb4 \uc0ac\uc6a9 \/ Use full screen width\n            }}\n            handleIndicatorStyle={{ backgroundColor: \"#ff69b4\", width: 40 }}\n            overlayStyle={{ backgroundColor: \"rgba(255,192,203,0.4)\" }}\n          &gt;\n            &lt;ScrollView contentContainerStyle={styles.sheetContent}&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                \uc138 \ubc88\uc9f8 \ubc14\ud140 \uc2dc\ud2b8\uc785\ub2c8\ub2e4. \uace0\uc815 \ub192\uc774 600px\uc785\ub2c8\ub2e4.\n              &lt;\/FlmText&gt;\n              &lt;FlmText style={styles.sheetText}&gt;\n                This is the third bottom sheet. It has a fixed height of 600px.\n              &lt;\/FlmText&gt;\n              &lt;FlmButton title=\"\ub2eb\uae30\" onPress={closeSheet3} \/&gt;\n            &lt;\/ScrollView&gt;\n          &lt;\/FlmBottomSheet&gt;\n        )}\n      &lt;\/SafeAreaView&gt;\n    &lt;\/GestureHandlerRootView&gt;\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  scrollContent: {\n    padding: 20,\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n  title: {\n    fontSize: 24,\n    marginBottom: 20,\n  },\n  spacer: {\n    height: 20,\n  },\n  sheetContent: {\n    padding: 20,\n    alignItems: \"center\",\n  },\n  sheetText: {\n    fontSize: 18,\n    marginBottom: 15,\n    textAlign: \"center\",\n  },\n});\n<\/code><\/pre>\n\n\n\n<p><strong>5.\uc2a4\ud06c\ub9b0\uc0f7\/ScreenShot<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"\ubc14\ud140\uc2dc\ud2b8\/FlmBottomSheet-react-native-freelifemakers-ui\" width=\"473\" height=\"840\" src=\"https:\/\/www.youtube.com\/embed\/Ev8amSaaOrg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>1.react-native-freelifemakers-ui NPM \ubaa8\ub4c8 \uc124\uce58\ud558\uae30 \/ react-native-freelifemakers-ui NPM Module Instal 2.\uc758\uc874\uc131 \ubaa8\ub4c8 \uc124\uce58 \/ peerModule install &#8212; FlmBottomSheet\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c \ubc18\ub4dc\uc2dc \uc124\uce58\ud574\uc57c \ud558\ub294 \ubaa8\ub4c8\uc785\ub2c8\ub2e4.This is a module that must be installed to use FlmBottomSheet. 1)React-Native Expo \ud83c\udf0d &#8212; \u2757 react-native-freelifemakers-ui \uc774 \ubaa8\ub4c8\uc744 \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798 \ub450\uac1c\uc758 \ubaa8\ub4c8\uc744 \ubc18\ub4dc\uc2dc \uc124\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.To use this module, you must install [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,1],"tags":[],"class_list":["post-1594","post","type-post","status-publish","format-standard","hentry","category-rnuimodule","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=1594"}],"version-history":[{"count":14,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1594\/revisions"}],"predecessor-version":[{"id":2218,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1594\/revisions\/2218"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=1594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=1594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=1594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}