From 49d16e8aa29dc43edffa1adc6f534c87771931e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 02:11:27 +0000 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=9C=9F=E7=94=BB=E9=9D=A2=E3=81=AEPu?= =?UTF-8?q?ll=20to=20Refresh=E5=AF=BE=E8=B1=A1=E3=82=92=E8=B7=AF=E7=B7=9A?= =?UTF-8?q?=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AB=E9=99=90=E5=AE=9A=E3=81=97?= =?UTF-8?q?=E3=81=9F=E5=A4=89=E6=9B=B4=E3=82=92=E3=83=AA=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=97=E3=81=A6=E5=85=83=E3=81=AE=E3=82=B9=E3=82=AF?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=AB=E6=8C=99=E5=8B=95=E3=81=AB=E6=88=BB?= =?UTF-8?q?=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Gu76E8vDn9ZheWEpmQj6Db --- src/screens/SelectLineScreen.render.test.tsx | 10 ++-- src/screens/SelectLineScreen.tsx | 60 ++++++++------------ 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/screens/SelectLineScreen.render.test.tsx b/src/screens/SelectLineScreen.render.test.tsx index c749030a2..c8c2b2038 100644 --- a/src/screens/SelectLineScreen.render.test.tsx +++ b/src/screens/SelectLineScreen.render.test.tsx @@ -282,18 +282,16 @@ describe('SelectLineScreen', () => { }); describe('ローディング状態', () => { - it('nearbyStationLoading=true のとき路線リストのスケルトンが表示される', () => { + it('nearbyStationLoading=true のときスケルトンが表示される', () => { setupDefaults({ nearbyStationLoading: true }); - const { getByTestId } = render(); + const { getByTestId, queryByTestId } = render(); expect(getByTestId('skeleton-placeholder')).toBeTruthy(); - // プリセットカードは上部固定表示になり最寄り駅のローディングとは独立したため、 - // ローディング中でも常に表示される - expect(getByTestId('presets')).toBeTruthy(); + expect(queryByTestId('presets')).toBeNull(); }); - it('nearbyStationLoading=false のとき路線リストのスケルトンは表示されない', () => { + it('nearbyStationLoading=false のときプリセットが表示される', () => { setupDefaults({ nearbyStationLoading: false }); const { getByTestId, queryByTestId } = render(); diff --git a/src/screens/SelectLineScreen.tsx b/src/screens/SelectLineScreen.tsx index ca79cfa37..d6cdebe11 100644 --- a/src/screens/SelectLineScreen.tsx +++ b/src/screens/SelectLineScreen.tsx @@ -45,7 +45,10 @@ import { SelectLineScreenPresets } from './SelectLineScreenPresets'; const styles = StyleSheet.create({ root: { paddingHorizontal: 24, flex: 1 }, - listScroll: { flex: 1 }, + listContainerStyle: { + paddingBottom: 24, + paddingHorizontal: 24, + }, heading: { fontSize: 24, fontWeight: 'bold', @@ -66,10 +69,6 @@ const styles = StyleSheet.create({ // https://github.com/facebook/react-native/issues/53987 const REFRESH_TINT_DELAY_MS = 500; -// 路線リストのスクロール領域下端の基本パディング。実際の下端余白はこれに -// フッタータブバーの高さ(useFooterHeight)を加算して算出する -const LIST_CONTENT_PADDING_BOTTOM = 24; - const NearbyStationLoader = () => ( @@ -153,10 +152,12 @@ const SelectLineScreen = () => { // --- 派生値 --- const footerHeight = useFooterHeight(); - const listPaddingBottom = useMemo( - () => LIST_CONTENT_PADDING_BOTTOM + footerHeight, - [footerHeight] - ); + const listPaddingBottom = useMemo(() => { + const flattened = StyleSheet.flatten(styles.listContainerStyle) as { + paddingBottom?: number; + }; + return (flattened?.paddingBottom ?? 24) + footerHeight; + }, [footerHeight]); const orientation = useDeviceOrientation(); const isPortraitOrientation = useMemo( @@ -302,47 +303,36 @@ const SelectLineScreen = () => { // --- JSX --- return ( <> - {/* - 上下のセーフエリアは絶対配置オーバーレイの NowHeader / FooterTabBar が - それぞれ処理するため上下インセットは無効化する。一方、横向き/タブレットの - ノッチでコンテンツが欠けないよう、左右インセットだけは SafeAreaView で確保する。 - */} - - {/* - プリセットカードは上部に固定表示し、Pull to Refresh の対象外にする。 - paddingTop で固定ヘッダー(NowHeader)の直下に配置する。 - */} - - - - - - - {/* プリセットカードより下の路線リストのみ Pull to Refresh の対象にする */} + } - contentContainerStyle={{ paddingBottom: listPaddingBottom }} + contentContainerStyle={[ + styles.listContainerStyle, + nowHeaderHeight ? { paddingTop: nowHeaderHeight } : null, + { paddingBottom: listPaddingBottom }, + ]} > {nearbyStationLoading && !refreshing ? ( ) : ( <> + + + {stationLines.length > 0 && (