ui-mobile
Mobile UI patterns - React Native, iOS/Android, touch targets
DeepseekModel
キュレーション済みスキル
品質 優秀 · 90
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=alinaqi-maggy-skills-ui-mobile-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name ui-mobile description Mobile UI patterns - React Native, iOS/Android, touch targets when-to-use When building mobile UI components user-invocable false paths ["**/*.tsx","**/*.jsx","ios/**","android/**","**/*.dart"] effort medium Mobile UI Design Skill (React Native) MANDATORY: Mobile Accessibility Standards These rules are NON-NEGOTIABLE. Every UI element must pass these checks. 1. Touch Targets (CRITICAL) // MINIMUM 44x44 points for ALL interactive elements const MINIMUM_TOUCH_SIZE = 44 ; // EVERY button, link, icon button must meet this const styles = StyleSheet . create ({ button : { minHeight : MINIMUM_TOUCH_SIZE , minWidth : MINIMUM_TOUCH_SIZE , paddingVertical : 12 , paddingHorizontal : 16 , }, iconButton : { width : MINIMUM_TOUCH_SIZE , height : MINIMUM_TOUCH_SIZE , justifyContent : 'center' , alignItems : 'center' , }, }); // NEVER DO THIS: style={{ height : 30 }} // ✗ TOO SMALL style={{ padding : 4 }} // ✗ RESULTS IN TINY TARGET 2. Color Contrast (CRITICAL) // WCAG 2.1 AA: 4.5:1 for text, 3:1 for large text/UI // SAFE COMBINATIONS: const colors = { // Light mode textPrimary : '#000000' , // on white = 21:1 ✓ textSecondary : '#374151' , // gray-700 on white = 9.2:1 ✓ // Dark mode textPrimaryDark : '#FFFFFF' , // on gray-900 = 16:1 ✓ textSecondaryDark : '#E5E7EB' , // gray-200 on gray-900 = 11:1 ✓ }; // FORBIDDEN - FAILS CONTRAST: // ✗ '#9CA3AF' (gray-400) on white = 2.6:1 // ✗ '#6B7280' (gray-500) on '#111827' = 4.0:1 // ✗ Any text below 4.5:1 ratio 3. Visibility Rules // ALL BUTTONS MUST HAVE visible boundaries // PRIMARY: Solid background with contrasting text < Pressable style={styles. primaryButton }> < Text style = {{ color: '# FFFFFF ' }}> Submit </ Text > </ Pressable > const styles = StyleSheet . create ({ primaryButton : { backgroundColor : '#1F2937' , // gray-800 paddingVertical : 16 , paddingHorizontal : 24 , borderRadius : 12 , minHeight : 44 , }, }); // SECONDARY: Visible background < Pressable style = {styles.secondaryButton} > < Text style = {{ color: '# 1F2937 ' }}> Cancel </ Text > </ Pressable > const styles = StyleSheet . create ({ secondaryButton : { backgroundColor : '#F3F4F6' , // gray-100 minHeight : 44 , }, }); // GHOST: MUST have visible border < Pressable style = {styles.ghostButton} > < Text style = {{ color: '# 374151 ' }}> Skip </ Text > </ Pressable > const styles = StyleSheet . create ({ ghostButton : { borderWidth : 1 , borderColor : '#D1D5DB' , // gray-300 minHeight : 44 , }, }); // NEVER CREATE invisible buttons: // ✗ backgroundColor: 'transparent' without border // ✗ Text color matching background 4. Accessibility Labels (REQUIRED) // EVERY interactive element needs accessibility props // Buttons < Pressable accessible={ true } accessibilityRole= "button" accessibilityLabel= "Submit form" accessibilityHint= "Double tap to submit your information" > < Text > Submit </ Text > </ Pressable > // Icon buttons (NO visible text = MUST have label) < Pressable accessible = {true} accessibilityRole = "button" accessibilityLabel = "Close menu" > < CloseIcon /> </ Pressable > // Images < Image accessible = {true} accessibilityRole = "image" accessibilityLabel = "User profile photo" source = {...} /> 5. Focus/Selection States // EVERY Pressable needs visible pressed state < Pressable style={ ( { pressed } ) => [ styles. button , pressed && styles. buttonPressed , ]} > {children} </ Pressable > const styles = StyleSheet . create ({ button : { backgroundColor : '#1F2937' , }, buttonPressed : { opacity : 0.7 , // OR backgroundColor : '#374151' , }, }); Core Philosophy Mobile UI is about touch, speed, and focus. No hover states, smaller screens, thumb-friendly targets. Design for one-handed use and interruption recovery. Platform Differences iOS vs Android import { Platform } from 'react-native' ; // Platform-specific values const styles = StyleSheet . create ({ shadow : Platform . select ({ ios : { shadowColor : '#000' , shadowOffset : { width : 0 , height : 2 }, shadowOpacity : 0.1 , shadowRadius : 8 , }, android : { elevation : 4 , }, }), // iOS uses SF Pro, Android uses Roboto text : { fontFamily : Platform . OS === 'ios' ? 'System' : 'Roboto' , }, }); Design Language iOS (Human Interface Guidelines) ───────────────────────────────── - Flat design with subtle depth - SF Symbols for icons - Large titles (34pt) - Rounded corners (10-14pt) - Blue as default tint Android (Material Design 3) ───────────────────────────────── - Material You dynamic color - Outlined/filled icons - Medium titles (22pt) - Rounded corners (12-28pt) - Primary color from theme Spacing System 4px Base Grid // React Native spacing - consistent scale const spacing = { xs : 4 , sm : 8 , md : 16 , lg : 24 , xl : 32 , '2xl' : 48 , } as const ; // Usage const styles = StyleSheet . create ({ container : { padding : spacing. md , gap : spacing. sm , }, }); Safe Areas import { useSafeAreaInsets } from 'react-native-safe-area-context' ; const Screen = ( { children } ) => { const insets = useSafeAreaInsets (); return ( < View style = {{ flex: 1 , paddingTop: insets.top , paddingBottom: insets.bottom , paddingLeft: Math.max ( insets.left , 16 ), paddingRight: Math.max ( insets.right , 16 ), }}> {children} </ View > ); }; Typography Type Scale const typography = { // Large titles (iOS style) largeTitle : { fontSize : 34 , fontWeight : '700' as const , letterSpacing : 0.37 , }, // Section headers title : { fontSize : 22 , fontWeight : '700' as const , letterSpacing : 0.35 , }, // Card titles headline : { fontSize : 17 , fontWeight : '600' as const , letterSpacing : - 0.41 , }, // Body text body : { fontSize : 17 , fontWeight : '400' as const , letterSpacing : - 0.41 , lineHeight : 22 , }, // Secondary text callout : { fontSize : 16 , fontWeight : '400' as const , letterSpacing : - 0.32 , }, // Small labels caption : { fontSize : 12 , fontWeight : '400' as const , letterSpacing : 0 , }, }; Color System Semantic Colors // Use semantic names, not literal colors const colors = { // Backgrounds background : '#FFFFFF' , backgroundSecondary : '#F2F2F7' , backgroundTertiary : '#FFFFFF' , // Surfaces surface : '#FFFFFF' , surfaceElevated : '#FFFFFF' , // Text label : '#000000' , labelSecondary : '#3C3C43' , // 60% opacity labelTertiary : '#3C3C43' , // 30% opacity // Actions primary : '#007AFF' , destructive : '#FF3B30' , success : '#34C759' , warning : '#FF9500' , // Separators separator : '#3C3C43' , // 29% opacity opaqueSeparator : '#C6C6C8' , }; // Dark mode variants const darkColors = { background : '#000000' , backgroundSecondary : '#1C1C1E' , label : '#FFFFFF' , labelSecondary : '#EBEBF5' , // 60% opacity separator : '#545458' , }; Dynamic Colors (React Native) import { useColorScheme } from 'react-native' ; const useColors = ( ) => { const scheme = useColorScheme (); return scheme === 'dark' ? darkColors : colors; }; // Usage const MyComponent = ( ) => { const colors = useColors (); return ( < View style = {{ backgroundColor: colors.background }}> < Text style = {{ color: colors.label }}> Hello </ Text > </ View > ); }; Touch Targets Minimum Sizes // CRITICAL: Minimum 44pt touch targets const touchable = { minHeight : 44 , minWidth : 44 , }; // Button with proper sizing const styles = StyleSheet . create ({ button : { minHeight : 44 , paddingHorizontal : 16 , paddingVertical : 12 , justifyContent : 'center' , alignItems : 'center' , }, // Icon button (square) iconButton : { width : 44 , height : 44 , justifyContent : 'center' , alignItems : 'center' , }, // List row listRow : { minHeight : 44 , paddingVertical : 12 , paddingHorizontal : 16 , }, }); Touch Feedback import { Pressable } from 'react-native' ; // iOS-style opacity feedback const Button = ( { children, onPress } ) => ( < Pressable onPress = {onPress} style = {({ pressed }) => [ styles.button, pressed && { opacity: 0.7 }, ]} > {children} </ Pressable > ); // Android-style ripple const AndroidButton = ( { children, onPress } ) => ( < Pressable onPress = {onPress} android_ripple = {{ color: ' rgba ( 0 , 0 , 0 , 0.1 )', borderless: false , }} style = {styles.button} > {children} </ Pressable > ); Component Patterns Cards const Card = ( { children, style } ) => ( < View style = {[styles.card, style ]}> {children} </ View > ); const styles = StyleSheet . create ({ card : { backgroundColor : '#FFFFFF' , borderRadius : 12 , padding : 16 , ... Platform . select ({ ios : { shadowColor : '#000' , shadowOffset : { width : 0 , height : 2 }, shadowOpacity : 0.08 , shadowRadius : 8 , }, android : { elevation : 2 , }, }), }, }); Buttons // Primary button const PrimaryButton = ( { title, onPress, disabled } ) => ( < Pressable onPress = {onPress} disabled = {disabled} style = {({ pressed }) => [ styles.primaryButton, pressed && styles.primaryButtonPressed, disabled && styles.buttonDisabled, ]} > < Text style = {styles.primaryButtonText} > {title} </ Text > </ Pressable > ); const styles = StyleSheet . create ({ primaryButton : { backgroundColor : '#007AFF' , borderRadius : 12 , paddingVertical : 16 , paddingHorizontal : 24 , alignItems : 'center' , }, primaryButtonPressed : { backgroundColor : '#0056B3' , }, primaryButtonText : { color : '#FFFFFF' , fontSize : 17 , fontWeight : '600' , }, buttonDisabled : {
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |