melta-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/THIRD_PARTY_LICENSES.md +198 -0
- package/lib/module/components/ActionSheet.js +87 -0
- package/lib/module/components/ActionSheet.js.map +1 -0
- package/lib/module/components/Alert.js +93 -0
- package/lib/module/components/Alert.js.map +1 -0
- package/lib/module/components/Avatar.js +93 -0
- package/lib/module/components/Avatar.js.map +1 -0
- package/lib/module/components/BottomSheet.js +69 -0
- package/lib/module/components/BottomSheet.js.map +1 -0
- package/lib/module/components/Card.js +93 -0
- package/lib/module/components/Card.js.map +1 -0
- package/lib/module/components/Checkbox.js +115 -0
- package/lib/module/components/Checkbox.js.map +1 -0
- package/lib/module/components/EmptyState.js +70 -0
- package/lib/module/components/EmptyState.js.map +1 -0
- package/lib/module/components/Header.js +53 -0
- package/lib/module/components/Header.js.map +1 -0
- package/lib/module/components/Image.js +67 -0
- package/lib/module/components/Image.js.map +1 -0
- package/lib/module/components/Modal.js +95 -0
- package/lib/module/components/Modal.js.map +1 -0
- package/lib/module/components/Progress.js +113 -0
- package/lib/module/components/Progress.js.map +1 -0
- package/lib/module/components/Radio.js +134 -0
- package/lib/module/components/Radio.js.map +1 -0
- package/lib/module/components/Screen.js +57 -0
- package/lib/module/components/Screen.js.map +1 -0
- package/lib/module/components/Skeleton.js +169 -0
- package/lib/module/components/Skeleton.js.map +1 -0
- package/lib/module/components/Surface.js +49 -0
- package/lib/module/components/Surface.js.map +1 -0
- package/lib/module/components/TextField.js +84 -0
- package/lib/module/components/TextField.js.map +1 -0
- package/lib/module/components/Toast.js +105 -0
- package/lib/module/components/Toast.js.map +1 -0
- package/lib/module/components/Toggle.js +77 -0
- package/lib/module/components/Toggle.js.map +1 -0
- package/lib/module/components/action-sheet.styles.js +70 -0
- package/lib/module/components/action-sheet.styles.js.map +1 -0
- package/lib/module/components/alert.styles.js +80 -0
- package/lib/module/components/alert.styles.js.map +1 -0
- package/lib/module/components/avatar.styles.js +94 -0
- package/lib/module/components/avatar.styles.js.map +1 -0
- package/lib/module/components/bottom-sheet.styles.js +55 -0
- package/lib/module/components/bottom-sheet.styles.js.map +1 -0
- package/lib/module/components/card.styles.js +50 -0
- package/lib/module/components/card.styles.js.map +1 -0
- package/lib/module/components/checkbox.styles.js +55 -0
- package/lib/module/components/checkbox.styles.js.map +1 -0
- package/lib/module/components/empty-state.styles.js +60 -0
- package/lib/module/components/empty-state.styles.js.map +1 -0
- package/lib/module/components/header.styles.js +33 -0
- package/lib/module/components/header.styles.js.map +1 -0
- package/lib/module/components/image.styles.js +37 -0
- package/lib/module/components/image.styles.js.map +1 -0
- package/lib/module/components/index.js +26 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/components/modal.styles.js +68 -0
- package/lib/module/components/modal.styles.js.map +1 -0
- package/lib/module/components/progress.styles.js +55 -0
- package/lib/module/components/progress.styles.js.map +1 -0
- package/lib/module/components/radio.styles.js +96 -0
- package/lib/module/components/radio.styles.js.map +1 -0
- package/lib/module/components/screen.styles.js +38 -0
- package/lib/module/components/screen.styles.js.map +1 -0
- package/lib/module/components/skeleton.styles.js +114 -0
- package/lib/module/components/skeleton.styles.js.map +1 -0
- package/lib/module/components/surface.styles.js +37 -0
- package/lib/module/components/surface.styles.js.map +1 -0
- package/lib/module/components/textfield.styles.js +121 -0
- package/lib/module/components/textfield.styles.js.map +1 -0
- package/lib/module/components/toast.styles.js +81 -0
- package/lib/module/components/toast.styles.js.map +1 -0
- package/lib/module/components/toggle.styles.js +69 -0
- package/lib/module/components/toggle.styles.js.map +1 -0
- package/lib/module/contracts/contract-types.js +192 -0
- package/lib/module/contracts/contract-types.js.map +1 -0
- package/lib/module/icons/Icon.js +57 -0
- package/lib/module/icons/Icon.js.map +1 -0
- package/lib/module/icons/glyphs.js +257 -0
- package/lib/module/icons/glyphs.js.map +1 -0
- package/lib/module/icons/icon.styles.js +28 -0
- package/lib/module/icons/icon.styles.js.map +1 -0
- package/lib/module/icons/index.js +14 -0
- package/lib/module/icons/index.js.map +1 -0
- package/lib/module/index.js +20 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/primitives/Button.js +105 -0
- package/lib/module/primitives/Button.js.map +1 -0
- package/lib/module/primitives/Metric.js +68 -0
- package/lib/module/primitives/Metric.js.map +1 -0
- package/lib/module/primitives/Row.js +43 -0
- package/lib/module/primitives/Row.js.map +1 -0
- package/lib/module/primitives/Stack.js +39 -0
- package/lib/module/primitives/Stack.js.map +1 -0
- package/lib/module/primitives/Tag.js +160 -0
- package/lib/module/primitives/Tag.js.map +1 -0
- package/lib/module/primitives/Text.js +54 -0
- package/lib/module/primitives/Text.js.map +1 -0
- package/lib/module/primitives/_internal/focus-ring.js +57 -0
- package/lib/module/primitives/_internal/focus-ring.js.map +1 -0
- package/lib/module/primitives/button.styles.js +88 -0
- package/lib/module/primitives/button.styles.js.map +1 -0
- package/lib/module/primitives/index.js +11 -0
- package/lib/module/primitives/index.js.map +1 -0
- package/lib/module/primitives/metric.styles.js +54 -0
- package/lib/module/primitives/metric.styles.js.map +1 -0
- package/lib/module/primitives/row.styles.js +53 -0
- package/lib/module/primitives/row.styles.js.map +1 -0
- package/lib/module/primitives/stack.styles.js +37 -0
- package/lib/module/primitives/stack.styles.js.map +1 -0
- package/lib/module/primitives/tag.styles.js +56 -0
- package/lib/module/primitives/tag.styles.js.map +1 -0
- package/lib/module/primitives/text.styles.js +33 -0
- package/lib/module/primitives/text.styles.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +41 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/index.js +19 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/native-theme.js +201 -0
- package/lib/module/theme/native-theme.js.map +1 -0
- package/lib/module/theme/types.js +4 -0
- package/lib/module/theme/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/components/ActionSheet.d.ts +45 -0
- package/lib/typescript/src/components/ActionSheet.d.ts.map +1 -0
- package/lib/typescript/src/components/Alert.d.ts +43 -0
- package/lib/typescript/src/components/Alert.d.ts.map +1 -0
- package/lib/typescript/src/components/Avatar.d.ts +45 -0
- package/lib/typescript/src/components/Avatar.d.ts.map +1 -0
- package/lib/typescript/src/components/BottomSheet.d.ts +36 -0
- package/lib/typescript/src/components/BottomSheet.d.ts.map +1 -0
- package/lib/typescript/src/components/Card.d.ts +46 -0
- package/lib/typescript/src/components/Card.d.ts.map +1 -0
- package/lib/typescript/src/components/Checkbox.d.ts +40 -0
- package/lib/typescript/src/components/Checkbox.d.ts.map +1 -0
- package/lib/typescript/src/components/EmptyState.d.ts +36 -0
- package/lib/typescript/src/components/EmptyState.d.ts.map +1 -0
- package/lib/typescript/src/components/Header.d.ts +34 -0
- package/lib/typescript/src/components/Header.d.ts.map +1 -0
- package/lib/typescript/src/components/Image.d.ts +41 -0
- package/lib/typescript/src/components/Image.d.ts.map +1 -0
- package/lib/typescript/src/components/Modal.d.ts +46 -0
- package/lib/typescript/src/components/Modal.d.ts.map +1 -0
- package/lib/typescript/src/components/Progress.d.ts +39 -0
- package/lib/typescript/src/components/Progress.d.ts.map +1 -0
- package/lib/typescript/src/components/Radio.d.ts +52 -0
- package/lib/typescript/src/components/Radio.d.ts.map +1 -0
- package/lib/typescript/src/components/Screen.d.ts +42 -0
- package/lib/typescript/src/components/Screen.d.ts.map +1 -0
- package/lib/typescript/src/components/Skeleton.d.ts +37 -0
- package/lib/typescript/src/components/Skeleton.d.ts.map +1 -0
- package/lib/typescript/src/components/Surface.d.ts +31 -0
- package/lib/typescript/src/components/Surface.d.ts.map +1 -0
- package/lib/typescript/src/components/TextField.d.ts +45 -0
- package/lib/typescript/src/components/TextField.d.ts.map +1 -0
- package/lib/typescript/src/components/Toast.d.ts +45 -0
- package/lib/typescript/src/components/Toast.d.ts.map +1 -0
- package/lib/typescript/src/components/Toggle.d.ts +39 -0
- package/lib/typescript/src/components/Toggle.d.ts.map +1 -0
- package/lib/typescript/src/components/action-sheet.styles.d.ts +65 -0
- package/lib/typescript/src/components/action-sheet.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/alert.styles.d.ts +61 -0
- package/lib/typescript/src/components/alert.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/avatar.styles.d.ts +60 -0
- package/lib/typescript/src/components/avatar.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/bottom-sheet.styles.d.ts +50 -0
- package/lib/typescript/src/components/bottom-sheet.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/card.styles.d.ts +27 -0
- package/lib/typescript/src/components/card.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/checkbox.styles.d.ts +55 -0
- package/lib/typescript/src/components/checkbox.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/empty-state.styles.d.ts +58 -0
- package/lib/typescript/src/components/empty-state.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/header.styles.d.ts +30 -0
- package/lib/typescript/src/components/header.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/image.styles.d.ts +28 -0
- package/lib/typescript/src/components/image.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +23 -0
- package/lib/typescript/src/components/index.d.ts.map +1 -0
- package/lib/typescript/src/components/modal.styles.d.ts +66 -0
- package/lib/typescript/src/components/modal.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/progress.styles.d.ts +44 -0
- package/lib/typescript/src/components/progress.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/radio.styles.d.ts +91 -0
- package/lib/typescript/src/components/radio.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/screen.styles.d.ts +34 -0
- package/lib/typescript/src/components/screen.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/skeleton.styles.d.ts +105 -0
- package/lib/typescript/src/components/skeleton.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/surface.styles.d.ts +31 -0
- package/lib/typescript/src/components/surface.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/textfield.styles.d.ts +75 -0
- package/lib/typescript/src/components/textfield.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/toast.styles.d.ts +62 -0
- package/lib/typescript/src/components/toast.styles.d.ts.map +1 -0
- package/lib/typescript/src/components/toggle.styles.d.ts +53 -0
- package/lib/typescript/src/components/toggle.styles.d.ts.map +1 -0
- package/lib/typescript/src/contracts/contract-types.d.ts +193 -0
- package/lib/typescript/src/contracts/contract-types.d.ts.map +1 -0
- package/lib/typescript/src/icons/Icon.d.ts +40 -0
- package/lib/typescript/src/icons/Icon.d.ts.map +1 -0
- package/lib/typescript/src/icons/glyphs.d.ts +259 -0
- package/lib/typescript/src/icons/glyphs.d.ts.map +1 -0
- package/lib/typescript/src/icons/icon.styles.d.ts +20 -0
- package/lib/typescript/src/icons/icon.styles.d.ts.map +1 -0
- package/lib/typescript/src/icons/index.d.ts +12 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +12 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Button.d.ts +48 -0
- package/lib/typescript/src/primitives/Button.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Metric.d.ts +38 -0
- package/lib/typescript/src/primitives/Metric.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Row.d.ts +37 -0
- package/lib/typescript/src/primitives/Row.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Stack.d.ts +33 -0
- package/lib/typescript/src/primitives/Stack.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Tag.d.ts +43 -0
- package/lib/typescript/src/primitives/Tag.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Text.d.ts +45 -0
- package/lib/typescript/src/primitives/Text.d.ts.map +1 -0
- package/lib/typescript/src/primitives/_internal/focus-ring.d.ts +31 -0
- package/lib/typescript/src/primitives/_internal/focus-ring.d.ts.map +1 -0
- package/lib/typescript/src/primitives/button.styles.d.ts +29 -0
- package/lib/typescript/src/primitives/button.styles.d.ts.map +1 -0
- package/lib/typescript/src/primitives/index.d.ts +8 -0
- package/lib/typescript/src/primitives/index.d.ts.map +1 -0
- package/lib/typescript/src/primitives/metric.styles.d.ts +43 -0
- package/lib/typescript/src/primitives/metric.styles.d.ts.map +1 -0
- package/lib/typescript/src/primitives/row.styles.d.ts +50 -0
- package/lib/typescript/src/primitives/row.styles.d.ts.map +1 -0
- package/lib/typescript/src/primitives/stack.styles.d.ts +34 -0
- package/lib/typescript/src/primitives/stack.styles.d.ts.map +1 -0
- package/lib/typescript/src/primitives/tag.styles.d.ts +32 -0
- package/lib/typescript/src/primitives/tag.styles.d.ts.map +1 -0
- package/lib/typescript/src/primitives/text.styles.d.ts +26 -0
- package/lib/typescript/src/primitives/text.styles.d.ts.map +1 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts +32 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/src/theme/index.d.ts +15 -0
- package/lib/typescript/src/theme/index.d.ts.map +1 -0
- package/lib/typescript/src/theme/native-theme.d.ts +3 -0
- package/lib/typescript/src/theme/native-theme.d.ts.map +1 -0
- package/lib/typescript/src/theme/types.d.ts +121 -0
- package/lib/typescript/src/theme/types.d.ts.map +1 -0
- package/package.json +120 -0
- package/src/components/ActionSheet.tsx +112 -0
- package/src/components/Alert.tsx +84 -0
- package/src/components/Avatar.tsx +110 -0
- package/src/components/BottomSheet.tsx +81 -0
- package/src/components/Card.tsx +102 -0
- package/src/components/Checkbox.tsx +107 -0
- package/src/components/EmptyState.tsx +64 -0
- package/src/components/Header.tsx +51 -0
- package/src/components/Image.tsx +89 -0
- package/src/components/Modal.tsx +113 -0
- package/src/components/Progress.tsx +124 -0
- package/src/components/Radio.tsx +151 -0
- package/src/components/Screen.tsx +62 -0
- package/src/components/Skeleton.tsx +154 -0
- package/src/components/Surface.tsx +37 -0
- package/src/components/TextField.tsx +102 -0
- package/src/components/Toast.tsx +103 -0
- package/src/components/Toggle.tsx +94 -0
- package/src/components/action-sheet.styles.ts +102 -0
- package/src/components/alert.styles.ts +115 -0
- package/src/components/avatar.styles.ts +110 -0
- package/src/components/bottom-sheet.styles.ts +78 -0
- package/src/components/card.styles.ts +56 -0
- package/src/components/checkbox.styles.ts +83 -0
- package/src/components/empty-state.styles.ts +98 -0
- package/src/components/header.styles.ts +44 -0
- package/src/components/image.styles.ts +36 -0
- package/src/components/index.ts +23 -0
- package/src/components/modal.styles.ts +106 -0
- package/src/components/progress.styles.ts +74 -0
- package/src/components/radio.styles.ts +132 -0
- package/src/components/screen.styles.ts +44 -0
- package/src/components/skeleton.styles.ts +155 -0
- package/src/components/surface.styles.ts +50 -0
- package/src/components/textfield.styles.ts +135 -0
- package/src/components/toast.styles.ts +115 -0
- package/src/components/toggle.styles.ts +73 -0
- package/src/contracts/contract-types.ts +199 -0
- package/src/icons/Icon.tsx +65 -0
- package/src/icons/glyphs.ts +54 -0
- package/src/icons/icon.styles.ts +37 -0
- package/src/icons/index.ts +12 -0
- package/src/index.ts +24 -0
- package/src/primitives/Button.tsx +114 -0
- package/src/primitives/Metric.tsx +67 -0
- package/src/primitives/Row.tsx +54 -0
- package/src/primitives/Stack.tsx +42 -0
- package/src/primitives/Tag.tsx +126 -0
- package/src/primitives/Text.tsx +71 -0
- package/src/primitives/_internal/focus-ring.tsx +59 -0
- package/src/primitives/button.styles.ts +69 -0
- package/src/primitives/index.ts +8 -0
- package/src/primitives/metric.styles.ts +75 -0
- package/src/primitives/row.styles.ts +66 -0
- package/src/primitives/stack.styles.ts +47 -0
- package/src/primitives/tag.styles.ts +65 -0
- package/src/primitives/text.styles.ts +42 -0
- package/src/theme/ThemeProvider.tsx +60 -0
- package/src/theme/index.ts +18 -0
- package/src/theme/native-theme.ts +215 -0
- package/src/theme/types.ts +137 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Modal — フォーカストラップとバックドロップを備えたモーダルダイアログ。
|
|
5
|
+
* contract: modal(feedback)。RN core Modal(transparent + fade)に overlay + panel を載せる。
|
|
6
|
+
*
|
|
7
|
+
* - variant(confirmation/form/alert)は意味分類で style は共通(contract / recipe と同じ)。
|
|
8
|
+
* - size は panel の maxWidth(タブレット以上で効く。モバイルは width 100% - overlay padding が先)。
|
|
9
|
+
* - 契約の対応物: focus trap → accessibilityViewIsModal(iOS のフォーカス閉じ込め)、
|
|
10
|
+
* Escape → Android back(onRequestClose)、open/closing state → RN Modal の visible + animationType。
|
|
11
|
+
* - overlay tap で閉じる(MODAL_OVERLAY_REQUIRED)。panel 側は onStartShouldSetResponder で
|
|
12
|
+
* touch を claim し、overlay への伝播を止める(panel 内 tap では閉じない)。
|
|
13
|
+
* - title 行の右端に閉じるボタン「×」(MODAL_CLOSE_REQUIRED、accessibilityLabel="閉じる")。
|
|
14
|
+
* title は melta の Text ではなく titleStyle 直(recipe が typography を持つ)。
|
|
15
|
+
* - style の決定は pure resolver(modal.styles.ts)に分離 — recipe との機械照合対象。
|
|
16
|
+
* title 行の row layout と × の見た目は recipe 外の構造 glue(token 経由で解決)。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { useMemo } from "react";
|
|
20
|
+
import { Modal as RNModal, Pressable, Text as RNText, View } from "react-native";
|
|
21
|
+
import { useTheme } from "../theme/index.js";
|
|
22
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
23
|
+
import { resolveModalStyle } from "./modal.styles.js";
|
|
24
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
+
export function Modal({
|
|
26
|
+
visible,
|
|
27
|
+
onClose,
|
|
28
|
+
title,
|
|
29
|
+
variant = "confirmation",
|
|
30
|
+
size = "medium",
|
|
31
|
+
footer,
|
|
32
|
+
testID,
|
|
33
|
+
children
|
|
34
|
+
}) {
|
|
35
|
+
const {
|
|
36
|
+
theme,
|
|
37
|
+
mode,
|
|
38
|
+
colors
|
|
39
|
+
} = useTheme();
|
|
40
|
+
const styles = useMemo(() => resolveModalStyle(theme, mode, {
|
|
41
|
+
variant,
|
|
42
|
+
size
|
|
43
|
+
}), [theme, mode, variant, size]);
|
|
44
|
+
return /*#__PURE__*/_jsx(RNModal, {
|
|
45
|
+
visible: visible,
|
|
46
|
+
transparent: true,
|
|
47
|
+
animationType: "fade",
|
|
48
|
+
onRequestClose: onClose,
|
|
49
|
+
statusBarTranslucent: true,
|
|
50
|
+
children: /*#__PURE__*/_jsx(Pressable, {
|
|
51
|
+
style: styles.overlayStyle,
|
|
52
|
+
onPress: onClose,
|
|
53
|
+
accessible: false,
|
|
54
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
55
|
+
style: [styles.panelStyle, styles.panelElevation],
|
|
56
|
+
accessibilityViewIsModal: true,
|
|
57
|
+
onStartShouldSetResponder: () => true,
|
|
58
|
+
testID: testID,
|
|
59
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
60
|
+
style: {
|
|
61
|
+
flexDirection: "row",
|
|
62
|
+
alignItems: "flex-start"
|
|
63
|
+
},
|
|
64
|
+
children: [/*#__PURE__*/_jsx(RNText, {
|
|
65
|
+
style: [styles.titleStyle, {
|
|
66
|
+
flex: 1
|
|
67
|
+
}],
|
|
68
|
+
accessibilityRole: "header",
|
|
69
|
+
children: title
|
|
70
|
+
}), /*#__PURE__*/_jsx(Pressable, {
|
|
71
|
+
onPress: onClose,
|
|
72
|
+
accessibilityRole: "button",
|
|
73
|
+
accessibilityLabel: "\u9589\u3058\u308B",
|
|
74
|
+
hitSlop: theme.spacing["2"],
|
|
75
|
+
children: /*#__PURE__*/_jsx(RNText, {
|
|
76
|
+
style: {
|
|
77
|
+
fontSize: theme.typography.fontSize.xl.fontSize,
|
|
78
|
+
color: colors["text-muted"]
|
|
79
|
+
},
|
|
80
|
+
children: "\xD7"
|
|
81
|
+
})
|
|
82
|
+
})]
|
|
83
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
84
|
+
style: styles.bodyStyle,
|
|
85
|
+
children: children
|
|
86
|
+
}), footer != null && /*#__PURE__*/_jsx(View, {
|
|
87
|
+
style: styles.footerStyle,
|
|
88
|
+
children: footer
|
|
89
|
+
})]
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
Modal.__contract = CONTRACTS.modal;
|
|
95
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","Modal","RNModal","Pressable","Text","RNText","View","useTheme","CONTRACTS","resolveModalStyle","jsx","_jsx","jsxs","_jsxs","visible","onClose","title","variant","size","footer","testID","children","theme","mode","colors","styles","transparent","animationType","onRequestClose","statusBarTranslucent","style","overlayStyle","onPress","accessible","panelStyle","panelElevation","accessibilityViewIsModal","onStartShouldSetResponder","flexDirection","alignItems","titleStyle","flex","accessibilityRole","accessibilityLabel","hitSlop","spacing","fontSize","typography","xl","color","bodyStyle","footerStyle","__contract","modal"],"sourceRoot":"../../../src","sources":["components/Modal.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Progress — リニアプログレスバー(feedback)。contract: progress。
|
|
5
|
+
* track の中を fill が value%(determinate)または往復アニメ(indeterminate variant)で埋める。
|
|
6
|
+
*
|
|
7
|
+
* - variant: primary / success(determinate、value 0〜100 を clamp)/ indeterminate(幅 40% の fill を
|
|
8
|
+
* Animated.loop の translateX 往復で流す。duration は theme.motion.duration.slow 基準)。
|
|
9
|
+
* - MOTION_REDUCED_MOTION_REQUIRED(contract rule): AccessibilityInfo.isReduceMotionEnabled() を
|
|
10
|
+
* 初期読取り + reduceMotionChanged 購読で追従し、reduce motion 時は indeterminate のアニメを
|
|
11
|
+
* 止めて静止 40% にする。translateX は 0 初期化なので同期起動でも一瞬動く事故は無い
|
|
12
|
+
* (Skeleton の順序ハザード対策と同趣旨)。
|
|
13
|
+
* - a11y: accessibilityRole="progressbar" + accessibilityValue {min:0, max:100, now}
|
|
14
|
+
* (indeterminate は now を渡さない)+ accessibilityLabel=label(契約 required)。
|
|
15
|
+
* - 色・寸法の決定は pure resolver(progress.styles.ts)に分離。track の semantic 色は dark 側解決。
|
|
16
|
+
* recipes/app/progress.recipe.json との機械照合は scripts/lib/progress-conformance.test.ts が行う。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
20
|
+
import { AccessibilityInfo, Animated, View } from "react-native";
|
|
21
|
+
import { useTheme } from "../theme/index.js";
|
|
22
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
23
|
+
import { PROGRESS_INDETERMINATE_FILL_RATIO, clampProgressValue, resolveProgressStyles } from "./progress.styles.js";
|
|
24
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
25
|
+
export function Progress({
|
|
26
|
+
variant = "primary",
|
|
27
|
+
value,
|
|
28
|
+
label,
|
|
29
|
+
style,
|
|
30
|
+
testID
|
|
31
|
+
}) {
|
|
32
|
+
const {
|
|
33
|
+
theme,
|
|
34
|
+
mode
|
|
35
|
+
} = useTheme();
|
|
36
|
+
const styles = useMemo(() => resolveProgressStyles(theme, mode, variant), [theme, mode, variant]);
|
|
37
|
+
const indeterminate = variant === "indeterminate";
|
|
38
|
+
const clamped = clampProgressValue(value ?? 0);
|
|
39
|
+
|
|
40
|
+
// indeterminate の往復アニメ: 0〜1 の進行値を track 実測幅で translateX に interpolate する。
|
|
41
|
+
const progress = useRef(new Animated.Value(0)).current;
|
|
42
|
+
const [trackWidth, setTrackWidth] = useState(0);
|
|
43
|
+
const [reduceMotion, setReduceMotion] = useState(false);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
let cancelled = false;
|
|
46
|
+
AccessibilityInfo.isReduceMotionEnabled().then(enabled => {
|
|
47
|
+
if (!cancelled) setReduceMotion(enabled);
|
|
48
|
+
});
|
|
49
|
+
const sub = AccessibilityInfo.addEventListener("reduceMotionChanged", setReduceMotion);
|
|
50
|
+
return () => {
|
|
51
|
+
cancelled = true;
|
|
52
|
+
sub.remove();
|
|
53
|
+
};
|
|
54
|
+
}, []);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
// reduce motion ON / determinate / 幅未計測 → アニメ無し(fill は左端 40% で静止)。
|
|
57
|
+
if (!indeterminate || reduceMotion || trackWidth <= 0) {
|
|
58
|
+
progress.setValue(0);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const duration = theme.motion.duration.slow;
|
|
62
|
+
const loop = Animated.loop(Animated.sequence([Animated.timing(progress, {
|
|
63
|
+
toValue: 1,
|
|
64
|
+
duration,
|
|
65
|
+
useNativeDriver: true
|
|
66
|
+
}), Animated.timing(progress, {
|
|
67
|
+
toValue: 0,
|
|
68
|
+
duration,
|
|
69
|
+
useNativeDriver: true
|
|
70
|
+
})]));
|
|
71
|
+
loop.start();
|
|
72
|
+
return () => loop.stop();
|
|
73
|
+
}, [indeterminate, reduceMotion, trackWidth, progress, theme]);
|
|
74
|
+
const onLayout = indeterminate ? e => setTrackWidth(e.nativeEvent.layout.width) : undefined;
|
|
75
|
+
|
|
76
|
+
// fill(40%) が track 内を左端 → 右端で往復する移動量。
|
|
77
|
+
const translateX = progress.interpolate({
|
|
78
|
+
inputRange: [0, 1],
|
|
79
|
+
outputRange: [0, Math.max(0, trackWidth * (1 - PROGRESS_INDETERMINATE_FILL_RATIO))]
|
|
80
|
+
});
|
|
81
|
+
return /*#__PURE__*/_jsx(View, {
|
|
82
|
+
accessible: true,
|
|
83
|
+
accessibilityRole: "progressbar",
|
|
84
|
+
accessibilityValue: indeterminate ? {
|
|
85
|
+
min: 0,
|
|
86
|
+
max: 100
|
|
87
|
+
} : {
|
|
88
|
+
min: 0,
|
|
89
|
+
max: 100,
|
|
90
|
+
now: clamped
|
|
91
|
+
},
|
|
92
|
+
accessibilityLabel: label,
|
|
93
|
+
testID: testID,
|
|
94
|
+
onLayout: onLayout,
|
|
95
|
+
style: [styles.trackStyle, style],
|
|
96
|
+
children: indeterminate ? /*#__PURE__*/_jsx(Animated.View, {
|
|
97
|
+
style: [styles.fillStyle, {
|
|
98
|
+
width: `${PROGRESS_INDETERMINATE_FILL_RATIO * 100}%`,
|
|
99
|
+
transform: [{
|
|
100
|
+
translateX
|
|
101
|
+
}]
|
|
102
|
+
}]
|
|
103
|
+
}) : /*#__PURE__*/_jsx(View, {
|
|
104
|
+
style: [styles.fillStyle, {
|
|
105
|
+
width: `${clamped}%`
|
|
106
|
+
}]
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Phase 2 conformance test 用の contract メタ(§2 A-3)。
|
|
112
|
+
Progress.__contract = CONTRACTS.progress;
|
|
113
|
+
//# sourceMappingURL=Progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useMemo","useRef","useState","AccessibilityInfo","Animated","View","useTheme","CONTRACTS","PROGRESS_INDETERMINATE_FILL_RATIO","clampProgressValue","resolveProgressStyles","jsx","_jsx","Progress","variant","value","label","style","testID","theme","mode","styles","indeterminate","clamped","progress","Value","current","trackWidth","setTrackWidth","reduceMotion","setReduceMotion","cancelled","isReduceMotionEnabled","then","enabled","sub","addEventListener","remove","setValue","duration","motion","slow","loop","sequence","timing","toValue","useNativeDriver","start","stop","onLayout","e","nativeEvent","layout","width","undefined","translateX","interpolate","inputRange","outputRange","Math","max","accessible","accessibilityRole","accessibilityValue","min","now","accessibilityLabel","trackStyle","children","fillStyle","transform","__contract"],"sourceRoot":"../../../src","sources":["components/Progress.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Radio — 単一選択フォームコントロール。contract: radio。
|
|
5
|
+
*
|
|
6
|
+
* - 契約どおり fieldset 相当の RadioGroup として実装する(コンポーネント名は Radio、
|
|
7
|
+
* recipe description 参照)。groupLabel(= legend 相当の label prop)必須
|
|
8
|
+
* (FORM_FIELDSET_LEGEND_REQUIRED を props 型で強制)。
|
|
9
|
+
* - variant はレイアウト: vertical(標準)/ horizontal(wrap する横並び)/ card-style
|
|
10
|
+
* (各 option を枠付きカードにする。web の grid 2col は RN では縦積みに読み替え)。
|
|
11
|
+
* - RN にネイティブ radio が無いため各 option は Pressable + 描画(circle + 内側 dot)。
|
|
12
|
+
* - states(contract → prop の写像): selected/unselected → value との一致、
|
|
13
|
+
* error → error?: string(circle の borderColor 差分 + errorText 表示。selected と併用時は
|
|
14
|
+
* error を優先 = 契約 stateSpecs)、disabled → グループ全体 or option 個別(opacity 0.5 + 非活性)。
|
|
15
|
+
* focus は Phase1 非対応(recipe にも focus 差分なし)。
|
|
16
|
+
* - a11y: グループに accessibilityRole="radiogroup"、各 option に "radio" +
|
|
17
|
+
* accessibilityState={{ checked, disabled }}。
|
|
18
|
+
* - 色・寸法の決定は pure resolver(radio.styles.ts)に分離。
|
|
19
|
+
* recipes/app/radio.recipe.json との機械照合は scripts/lib/radio-conformance.test.ts が行う。
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { useMemo } from "react";
|
|
23
|
+
import { Pressable, View } from "react-native";
|
|
24
|
+
import { Text } from "../primitives/Text.js";
|
|
25
|
+
import { useTheme } from "../theme/index.js";
|
|
26
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
27
|
+
import { RADIO_SPEC, resolveRadioCircleStyle, resolveRadioGroupStyle } from "./radio.styles.js";
|
|
28
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
29
|
+
export function Radio({
|
|
30
|
+
label,
|
|
31
|
+
options,
|
|
32
|
+
value,
|
|
33
|
+
onChange,
|
|
34
|
+
variant = "vertical",
|
|
35
|
+
error,
|
|
36
|
+
disabled = false,
|
|
37
|
+
testID
|
|
38
|
+
}) {
|
|
39
|
+
const {
|
|
40
|
+
theme,
|
|
41
|
+
mode
|
|
42
|
+
} = useTheme();
|
|
43
|
+
const hasError = error != null && error !== "";
|
|
44
|
+
const group = useMemo(() => resolveRadioGroupStyle(theme, mode, variant), [theme, mode, variant]);
|
|
45
|
+
// circle は selected × error の 2 値。option ごとに再計算しないよう両方を先に解決しておく。
|
|
46
|
+
const circles = useMemo(() => ({
|
|
47
|
+
unselected: resolveRadioCircleStyle(theme, mode, {
|
|
48
|
+
selected: false,
|
|
49
|
+
error: hasError
|
|
50
|
+
}),
|
|
51
|
+
selected: resolveRadioCircleStyle(theme, mode, {
|
|
52
|
+
selected: true,
|
|
53
|
+
error: hasError
|
|
54
|
+
})
|
|
55
|
+
}), [theme, mode, hasError]);
|
|
56
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
57
|
+
testID: testID,
|
|
58
|
+
style: disabled ? {
|
|
59
|
+
opacity: RADIO_SPEC.disabledOpacity
|
|
60
|
+
} : undefined,
|
|
61
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
62
|
+
variant: "sm",
|
|
63
|
+
weight: "medium",
|
|
64
|
+
color: "text-heading",
|
|
65
|
+
style: {
|
|
66
|
+
marginBottom: group.groupLabelStyle.marginBottom
|
|
67
|
+
},
|
|
68
|
+
children: label
|
|
69
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
70
|
+
accessibilityRole: "radiogroup",
|
|
71
|
+
style: group.containerStyle,
|
|
72
|
+
children: options.map(option => {
|
|
73
|
+
const selected = option.value === value;
|
|
74
|
+
const optionDisabled = disabled || option.disabled === true;
|
|
75
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
76
|
+
onPress: () => onChange(option.value),
|
|
77
|
+
disabled: optionDisabled,
|
|
78
|
+
accessibilityRole: "radio",
|
|
79
|
+
accessibilityState: {
|
|
80
|
+
checked: selected,
|
|
81
|
+
disabled: optionDisabled
|
|
82
|
+
},
|
|
83
|
+
accessibilityLabel: option.label,
|
|
84
|
+
style: [variant === "card-style" ? [group.cardStyle, selected ? group.cardSelectedStyle : null] : null,
|
|
85
|
+
// グループ disabled は外側 View の opacity で表現済み。二重にしない。
|
|
86
|
+
option.disabled === true && !disabled ? {
|
|
87
|
+
opacity: RADIO_SPEC.disabledOpacity
|
|
88
|
+
} : null],
|
|
89
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
90
|
+
style: {
|
|
91
|
+
flexDirection: "row",
|
|
92
|
+
// description 付きは複数行になるので circle を先頭行に寄せる。
|
|
93
|
+
alignItems: option.description != null ? "flex-start" : "center",
|
|
94
|
+
gap: group.optionGap
|
|
95
|
+
},
|
|
96
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
97
|
+
style: selected ? circles.selected : circles.unselected,
|
|
98
|
+
children: selected ? /*#__PURE__*/_jsx(View, {
|
|
99
|
+
style: group.dotStyle
|
|
100
|
+
}) : null
|
|
101
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
102
|
+
style: {
|
|
103
|
+
flexShrink: 1
|
|
104
|
+
},
|
|
105
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
106
|
+
variant: "base",
|
|
107
|
+
color: "text-default",
|
|
108
|
+
children: option.label
|
|
109
|
+
}), option.description != null ? /*#__PURE__*/_jsx(Text, {
|
|
110
|
+
variant: "sm",
|
|
111
|
+
color: "text-muted",
|
|
112
|
+
children: option.description
|
|
113
|
+
}) : null]
|
|
114
|
+
})]
|
|
115
|
+
})
|
|
116
|
+
}, option.value);
|
|
117
|
+
})
|
|
118
|
+
}), hasError ?
|
|
119
|
+
/*#__PURE__*/
|
|
120
|
+
// danger.text-light は SemanticColors 外なので style で上書き(Button の textColor と同じ扱い)。
|
|
121
|
+
_jsx(Text, {
|
|
122
|
+
variant: "xs",
|
|
123
|
+
style: {
|
|
124
|
+
color: group.errorTextStyle.color,
|
|
125
|
+
marginTop: group.errorTextStyle.marginTop
|
|
126
|
+
},
|
|
127
|
+
children: error
|
|
128
|
+
}) : null]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Phase 2 conformance test 用の contract メタ(§2 A-3)。
|
|
133
|
+
Radio.__contract = CONTRACTS.radio;
|
|
134
|
+
//# sourceMappingURL=Radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","Pressable","View","Text","useTheme","CONTRACTS","RADIO_SPEC","resolveRadioCircleStyle","resolveRadioGroupStyle","jsx","_jsx","jsxs","_jsxs","Radio","label","options","value","onChange","variant","error","disabled","testID","theme","mode","hasError","group","circles","unselected","selected","style","opacity","disabledOpacity","undefined","children","weight","color","marginBottom","groupLabelStyle","accessibilityRole","containerStyle","map","option","optionDisabled","onPress","accessibilityState","checked","accessibilityLabel","cardStyle","cardSelectedStyle","flexDirection","alignItems","description","gap","optionGap","dotStyle","flexShrink","errorTextStyle","marginTop","__contract","radio"],"sourceRoot":"../../../src","sources":["components/Radio.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Screen — 画面骨格 primitive(SafeArea + bg-page + content padding)。
|
|
5
|
+
* contract: screen(app 先行定義、melta-contracts)。dogfood 不足-3(SafeAreaView + ScrollView +
|
|
6
|
+
* ヘッダーの毎画面手書き)の解消。
|
|
7
|
+
*
|
|
8
|
+
* - variant="scroll"(default)は content を ScrollView に、"fixed" は flex:1 の View に載せる。
|
|
9
|
+
* - header slot は scroll の外(SafeArea 直下)に固定する。
|
|
10
|
+
* - padding は spacing token キー限定 | "none"(default "4")。
|
|
11
|
+
* - 決定ロジックは pure resolver(screen.styles.ts)に分離 — recipe との機械照合対象。
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ SafeArea は RN core の SafeAreaView(deprecated / iOS のみの最小対応)を意図的に使う。
|
|
14
|
+
* 依存ゼロ方針(P1)を安全域の精度より優先した判断。Android の edge-to-edge や notch 精度が
|
|
15
|
+
* 必要になったら react-native-safe-area-context への adapter 化を再検討する(optional peer の
|
|
16
|
+
* 前例は Icon × react-native-svg)。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { useMemo } from "react";
|
|
20
|
+
import { SafeAreaView, ScrollView, View } from "react-native";
|
|
21
|
+
import { useTheme } from "../theme/index.js";
|
|
22
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
23
|
+
import { resolveScreenStyle } from "./screen.styles.js";
|
|
24
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
+
export function Screen({
|
|
26
|
+
variant = "scroll",
|
|
27
|
+
padding = "4",
|
|
28
|
+
header,
|
|
29
|
+
style,
|
|
30
|
+
testID,
|
|
31
|
+
children
|
|
32
|
+
}) {
|
|
33
|
+
const {
|
|
34
|
+
theme,
|
|
35
|
+
mode
|
|
36
|
+
} = useTheme();
|
|
37
|
+
const {
|
|
38
|
+
safeAreaStyle,
|
|
39
|
+
contentStyle
|
|
40
|
+
} = useMemo(() => resolveScreenStyle(theme, mode, {
|
|
41
|
+
variant,
|
|
42
|
+
padding
|
|
43
|
+
}), [theme, mode, variant, padding]);
|
|
44
|
+
return /*#__PURE__*/_jsxs(SafeAreaView, {
|
|
45
|
+
style: [safeAreaStyle, style],
|
|
46
|
+
testID: testID,
|
|
47
|
+
children: [header, variant === "scroll" ? /*#__PURE__*/_jsx(ScrollView, {
|
|
48
|
+
contentContainerStyle: contentStyle,
|
|
49
|
+
children: children
|
|
50
|
+
}) : /*#__PURE__*/_jsx(View, {
|
|
51
|
+
style: contentStyle,
|
|
52
|
+
children: children
|
|
53
|
+
})]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
Screen.__contract = CONTRACTS.screen;
|
|
57
|
+
//# sourceMappingURL=Screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","SafeAreaView","ScrollView","View","useTheme","CONTRACTS","resolveScreenStyle","jsx","_jsx","jsxs","_jsxs","Screen","variant","padding","header","style","testID","children","theme","mode","safeAreaStyle","contentStyle","contentContainerStyle","__contract","screen"],"sourceRoot":"../../../src","sources":["components/Screen.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAwB,OAAO;AAC/C,SAASC,YAAY,EAAEC,UAAU,EAAEC,IAAI,QAAwC,cAAc;AAC7F,SAASC,QAAQ,QAAQ,mBAAU;AACnC,SAASC,SAAS,QAAwB,gCAA6B;AACvE,SAASC,kBAAkB,QAA8C,oBAAiB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAc3F,OAAO,SAASC,MAAMA,CAAC;EACrBC,OAAO,GAAG,QAAQ;EAClBC,OAAO,GAAG,GAAG;EACbC,MAAM;EACNC,KAAK;EACLC,MAAM;EACNC;AACW,CAAC,EAAE;EACd,MAAM;IAAEC,KAAK;IAAEC;EAAK,CAAC,GAAGf,QAAQ,CAAC,CAAC;EAElC,MAAM;IAAEgB,aAAa;IAAEC;EAAa,CAAC,GAAGrB,OAAO,CAC7C,MAAMM,kBAAkB,CAACY,KAAK,EAAEC,IAAI,EAAE;IAAEP,OAAO;IAAEC;EAAQ,CAAC,CAAC,EAC3D,CAACK,KAAK,EAAEC,IAAI,EAAEP,OAAO,EAAEC,OAAO,CAChC,CAAC;EAED,oBACEH,KAAA,CAACT,YAAY;IAACc,KAAK,EAAE,CAACK,aAAa,EAAEL,KAAK,CAAE;IAACC,MAAM,EAAEA,MAAO;IAAAC,QAAA,GACzDH,MAAM,EACNF,OAAO,KAAK,QAAQ,gBACnBJ,IAAA,CAACN,UAAU;MAACoB,qBAAqB,EAAED,YAAa;MAAAJ,QAAA,EAAEA;IAAQ,CAAa,CAAC,gBAExET,IAAA,CAACL,IAAI;MAACY,KAAK,EAAEM,YAAa;MAAAJ,QAAA,EAAEA;IAAQ,CAAO,CAC5C;EAAA,CACW,CAAC;AAEnB;AAEAN,MAAM,CAACY,UAAU,GAAGlB,SAAS,CAACmB,MAAM","ignoreList":[]}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Skeleton — ローディングプレースホルダー(設計書 §1)。contract: skeleton。
|
|
5
|
+
*
|
|
6
|
+
* - variant: text(行バー)/ circle(アバター)/ card(Surface 土台 + 中にバー)。
|
|
7
|
+
* - a11y: accessibilityState={{busy:true}} + accessibilityLabel(default "読み込み中")。
|
|
8
|
+
* - 色・寸法の決定は pure resolver(skeleton.styles.ts)に分離。card の Surface props も
|
|
9
|
+
* CARD_SURFACE_SPEC(同ファイル)を SSOT として共有し、
|
|
10
|
+
* recipes/app/skeleton.recipe.json との機械照合は scripts/lib/skeleton-conformance.test.ts が行う。
|
|
11
|
+
* - bg: text/circle は border-default。card は Surface 土台(bg-surface+border+elevation.sm)
|
|
12
|
+
* の上に border-default のバーを置く(contract に忠実、§1 Agent m2)。
|
|
13
|
+
* - pulse の reduce-motion 順序ハザード(§1): Animated.Value を opacityFrom(= 非アニメ状態)で
|
|
14
|
+
* 初期化し、effect 内で AccessibilityInfo.isReduceMotionEnabled() を await した後にのみ loop 開始する。
|
|
15
|
+
* 同期的に loop を start すると reduce-motion ON でも一瞬光るため。ON 時は pulse 完全停止 + busy 維持。
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
19
|
+
import { AccessibilityInfo, Animated, View } from "react-native";
|
|
20
|
+
import { Surface } from "./Surface.js";
|
|
21
|
+
import { useTheme } from "../theme/index.js";
|
|
22
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
23
|
+
import { CARD_SURFACE_SPEC, PULSE_OPACITY, SKELETON_METRICS, resolveSkeletonStates, resolveSkeletonVariants } from "./skeleton.styles.js";
|
|
24
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
+
export function Skeleton({
|
|
26
|
+
variant = "text",
|
|
27
|
+
width = "100%",
|
|
28
|
+
lines = 1,
|
|
29
|
+
accessibilityLabel = "読み込み中",
|
|
30
|
+
style,
|
|
31
|
+
testID
|
|
32
|
+
}) {
|
|
33
|
+
const {
|
|
34
|
+
theme,
|
|
35
|
+
mode
|
|
36
|
+
} = useTheme();
|
|
37
|
+
const styles = useMemo(() => resolveSkeletonVariants(theme, mode), [theme, mode]);
|
|
38
|
+
// 初期値 opacityFrom = 非アニメ(reduce-motion でも光らない)。reduce-motion OFF を確認後にのみ loop で揺らす。
|
|
39
|
+
const opacity = useRef(new Animated.Value(PULSE_OPACITY.from)).current;
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
let loop = null;
|
|
43
|
+
// pulse の値(opacity 振れ幅 / duration)は resolver 側が SSOT(recipe states.loading と照合される)。
|
|
44
|
+
const anim = resolveSkeletonStates(theme).loading.animation;
|
|
45
|
+
AccessibilityInfo.isReduceMotionEnabled().then(reduce => {
|
|
46
|
+
if (cancelled || reduce) return;
|
|
47
|
+
loop = Animated.loop(Animated.sequence([Animated.timing(opacity, {
|
|
48
|
+
toValue: anim.opacityTo,
|
|
49
|
+
duration: anim.duration,
|
|
50
|
+
useNativeDriver: true
|
|
51
|
+
}), Animated.timing(opacity, {
|
|
52
|
+
toValue: anim.opacityFrom,
|
|
53
|
+
duration: anim.duration,
|
|
54
|
+
useNativeDriver: true
|
|
55
|
+
})]));
|
|
56
|
+
loop.start();
|
|
57
|
+
});
|
|
58
|
+
return () => {
|
|
59
|
+
cancelled = true;
|
|
60
|
+
loop?.stop();
|
|
61
|
+
};
|
|
62
|
+
}, [opacity, theme]);
|
|
63
|
+
|
|
64
|
+
// contract a11y role は web の "status"。RN の accessibilityRole に status は無いため、
|
|
65
|
+
// busy state + label で status 相当を表現する(§2 web→RN mapping、skeleton は busy で扱う)。
|
|
66
|
+
const a11y = {
|
|
67
|
+
accessible: true,
|
|
68
|
+
accessibilityState: {
|
|
69
|
+
busy: true
|
|
70
|
+
},
|
|
71
|
+
accessibilityLabel
|
|
72
|
+
};
|
|
73
|
+
if (variant === "circle") {
|
|
74
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
75
|
+
...a11y,
|
|
76
|
+
testID: testID,
|
|
77
|
+
style: [styles.circle.style, {
|
|
78
|
+
opacity
|
|
79
|
+
}, style]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (variant === "card") {
|
|
83
|
+
const {
|
|
84
|
+
barStyle
|
|
85
|
+
} = styles.card;
|
|
86
|
+
const {
|
|
87
|
+
borderWidth,
|
|
88
|
+
borderColor
|
|
89
|
+
} = styles.card.style;
|
|
90
|
+
return /*#__PURE__*/_jsx(Surface, {
|
|
91
|
+
...CARD_SURFACE_SPEC,
|
|
92
|
+
// contract skeleton.card は border-default を要求(Surface は border を出さないので Skeleton で付与)。
|
|
93
|
+
style: [{
|
|
94
|
+
borderWidth,
|
|
95
|
+
borderColor
|
|
96
|
+
}, style],
|
|
97
|
+
testID: testID,
|
|
98
|
+
children: /*#__PURE__*/_jsxs(Animated.View, {
|
|
99
|
+
...a11y,
|
|
100
|
+
style: {
|
|
101
|
+
opacity,
|
|
102
|
+
gap: theme.spacing["3"]
|
|
103
|
+
},
|
|
104
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
105
|
+
style: {
|
|
106
|
+
flexDirection: "row",
|
|
107
|
+
alignItems: "center",
|
|
108
|
+
gap: theme.spacing["3"]
|
|
109
|
+
},
|
|
110
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
111
|
+
style: {
|
|
112
|
+
width: SKELETON_METRICS.circleSize,
|
|
113
|
+
height: SKELETON_METRICS.circleSize,
|
|
114
|
+
borderRadius: theme.radius.full,
|
|
115
|
+
backgroundColor: barStyle.backgroundColor
|
|
116
|
+
}
|
|
117
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
118
|
+
style: {
|
|
119
|
+
flex: 1,
|
|
120
|
+
gap: theme.spacing["2"]
|
|
121
|
+
},
|
|
122
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
123
|
+
style: [barStyle, {
|
|
124
|
+
width: "60%"
|
|
125
|
+
}]
|
|
126
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
127
|
+
style: [barStyle, {
|
|
128
|
+
width: "40%"
|
|
129
|
+
}]
|
|
130
|
+
})]
|
|
131
|
+
})]
|
|
132
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
133
|
+
style: barStyle
|
|
134
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
135
|
+
style: [barStyle, {
|
|
136
|
+
width: "80%"
|
|
137
|
+
}]
|
|
138
|
+
})]
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// text(行バー): recipe は 1 slot(style)に行バー + 行間 gap を併記 → gap はコンテナへ分離。
|
|
144
|
+
const {
|
|
145
|
+
gap,
|
|
146
|
+
...textBar
|
|
147
|
+
} = styles.text.style;
|
|
148
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
149
|
+
...a11y,
|
|
150
|
+
testID: testID,
|
|
151
|
+
style: [{
|
|
152
|
+
gap,
|
|
153
|
+
opacity
|
|
154
|
+
}, style],
|
|
155
|
+
children: Array.from({
|
|
156
|
+
length: lines
|
|
157
|
+
}, (_unused, i) => /*#__PURE__*/_jsx(View, {
|
|
158
|
+
style: [textBar,
|
|
159
|
+
// 最終行だけ短く(自然な見た目)。
|
|
160
|
+
{
|
|
161
|
+
width: lines > 1 && i === lines - 1 ? "70%" : width
|
|
162
|
+
}]
|
|
163
|
+
}, i))
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Phase 2 conformance test 用の contract メタ(§2 A-3)。
|
|
168
|
+
Skeleton.__contract = CONTRACTS.skeleton;
|
|
169
|
+
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useMemo","useRef","AccessibilityInfo","Animated","View","Surface","useTheme","CONTRACTS","CARD_SURFACE_SPEC","PULSE_OPACITY","SKELETON_METRICS","resolveSkeletonStates","resolveSkeletonVariants","jsx","_jsx","jsxs","_jsxs","Skeleton","variant","width","lines","accessibilityLabel","style","testID","theme","mode","styles","opacity","Value","from","current","cancelled","loop","anim","loading","animation","isReduceMotionEnabled","then","reduce","sequence","timing","toValue","opacityTo","duration","useNativeDriver","opacityFrom","start","stop","a11y","accessible","accessibilityState","busy","circle","barStyle","card","borderWidth","borderColor","children","gap","spacing","flexDirection","alignItems","circleSize","height","borderRadius","radius","full","backgroundColor","flex","textBar","text","Array","length","_unused","i","__contract","skeleton"],"sourceRoot":"../../../src","sources":["components/Skeleton.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Surface — Card / Skeleton / EmptyState の共通土台となる「箱」(設計書 §1)。
|
|
5
|
+
* contract: surface(app 先行定義)。
|
|
6
|
+
*
|
|
7
|
+
* - 公開 P1 で正式 export に昇格(契約 surface.contract.json + recipe を持つ implemented のため)。
|
|
8
|
+
* セマンティクスを持つ箱が必要なら Card を優先し、Surface は素の土台が要る時だけ使う。
|
|
9
|
+
* - elevation[key] は iOS shadow* + Android elevation を 1 ViewStyle に同居させた値なので
|
|
10
|
+
* そのまま spread すれば両 OS に効く(types.ts ElevationStyle)。
|
|
11
|
+
* - 色・寸法の決定は pure resolver(surface.styles.ts)に分離。デフォルト値
|
|
12
|
+
* (bg=bg-surface / radius=lg / elevation=none)も resolver 側が持ち、
|
|
13
|
+
* recipes/app/surface.recipe.json との機械照合は scripts/lib/surface-conformance.test.ts が行う。
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { View } from "react-native";
|
|
17
|
+
import { useTheme } from "../theme/index.js";
|
|
18
|
+
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
19
|
+
import { resolveSurfaceStyle } from "./surface.styles.js";
|
|
20
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
|
+
export function Surface({
|
|
22
|
+
bg,
|
|
23
|
+
radius,
|
|
24
|
+
elevation,
|
|
25
|
+
padding,
|
|
26
|
+
style,
|
|
27
|
+
testID,
|
|
28
|
+
children
|
|
29
|
+
}) {
|
|
30
|
+
const {
|
|
31
|
+
theme,
|
|
32
|
+
mode
|
|
33
|
+
} = useTheme();
|
|
34
|
+
const resolved = resolveSurfaceStyle(theme, mode, {
|
|
35
|
+
bg,
|
|
36
|
+
radius,
|
|
37
|
+
elevation,
|
|
38
|
+
padding
|
|
39
|
+
});
|
|
40
|
+
return /*#__PURE__*/_jsx(View, {
|
|
41
|
+
testID: testID,
|
|
42
|
+
style: [resolved.base, resolved.elevation, style],
|
|
43
|
+
children: children
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Phase 2 conformance test 用の contract メタ(§2 A-3)。
|
|
48
|
+
Surface.__contract = CONTRACTS.surface;
|
|
49
|
+
//# sourceMappingURL=Surface.js.map
|