Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:48:55 +08:00
commit f28999f19c
127 changed files with 62038 additions and 0 deletions

View File

@@ -0,0 +1,348 @@
#!/bin/bash
# Apple HIG Designer - iOS Component Generator
# Generate SwiftUI and UIKit components following Apple Human Interface Guidelines
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Helper functions
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
prompt_input() {
local prompt="$1"
local var_name="$2"
local required="${3:-false}"
while true; do
echo -e "${BLUE}${prompt}${NC}"
read -r input
if [ -z "$input" ] && [ "$required" = true ]; then
print_error "This field is required."
continue
fi
eval "$var_name='$input'"
break
done
}
prompt_select() {
local prompt="$1"
local var_name="$2"
shift 2
local options=("$@")
echo -e "${BLUE}${prompt}${NC}"
PS3="Select (1-${#options[@]}): "
select opt in "${options[@]}"; do
if [ -n "$opt" ]; then
eval "$var_name='$opt'"
break
else
print_error "Invalid selection. Try again."
fi
done
}
# Banner
echo ""
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ Apple HIG Designer - Component Generator ║"
echo "║ ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
# Step 1: Framework
print_info "Step 1/6: Framework"
prompt_select "Which framework?" FRAMEWORK \
"SwiftUI" \
"UIKit"
# Step 2: Component Type
print_info "Step 2/6: Component Type"
prompt_select "What type of component?" COMPONENT_TYPE \
"Button" \
"List/TableView" \
"Card" \
"Sheet/Modal" \
"Form" \
"NavigationView" \
"TabView" \
"Custom"
# Step 3: Component Name
print_info "Step 3/6: Component Name"
prompt_input "Component name (e.g., UserProfileView):" COMPONENT_NAME true
# Step 4: Features
print_info "Step 4/6: Features (comma-separated)"
echo -e "${BLUE}Select features to include:${NC}"
echo " - accessibility (VoiceOver, Dynamic Type)"
echo " - darkmode (Semantic colors)"
echo " - animations (Standard iOS animations)"
echo " - haptics (Haptic feedback)"
read -r FEATURES
# Step 5: Platform
print_info "Step 5/6: Platform"
prompt_select "Target platform?" PLATFORM \
"iOS" \
"iOS + iPadOS" \
"iOS + watchOS" \
"All (iOS, iPadOS, macOS, watchOS)"
# Step 6: Output Directory
print_info "Step 6/6: Output Location"
prompt_input "Output directory (default: ./Components):" OUTPUT_DIR
OUTPUT_DIR=${OUTPUT_DIR:-"./Components"}
# Create output directory
mkdir -p "$OUTPUT_DIR"
# Generate based on framework
case $FRAMEWORK in
"SwiftUI")
generate_swiftui_component
;;
"UIKit")
generate_uikit_component
;;
esac
generate_swiftui_component() {
local file_path="$OUTPUT_DIR/$COMPONENT_NAME.swift"
cat > "$file_path" << 'EOF'
import SwiftUI
/// COMPONENT_NAME
///
/// Description of what this component does
/// Follows Apple Human Interface Guidelines
struct COMPONENT_NAME: View {
PROPERTIES
var body: some View {
COMPONENT_BODY
}
}
PREVIEW
EOF
# Add properties based on component type
case $COMPONENT_TYPE in
"Button")
sed -i 's/PROPERTIES/\/\/ Button properties\n let title: String\n let action: () -> Void/' "$file_path"
sed -i 's/COMPONENT_BODY/Button(action: action) {\n Text(title)\n }\n .buttonStyle(.borderedProminent)\n ACCESSIBILITY_MODIFIERS/' "$file_path"
;;
"List/TableView")
sed -i 's/PROPERTIES/\/\/ List properties\n let items: [String]/' "$file_path"
sed -i 's/COMPONENT_BODY/List(items, id: \\.self) { item in\n Text(item)\n }\n .listStyle(.insetGrouped)\n ACCESSIBILITY_MODIFIERS/' "$file_path"
;;
"Card")
sed -i 's/PROPERTIES/\/\/ Card properties\n let title: String\n let description: String/' "$file_path"
sed -i 's/COMPONENT_BODY/VStack(alignment: .leading, spacing: 12) {\n Text(title)\n .font(.headline)\n \n Text(description)\n .font(.subheadline)\n .foregroundColor(.secondary)\n }\n .padding()\n .background(Color(.systemBackground))\n .cornerRadius(12)\n .shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)\n ACCESSIBILITY_MODIFIERS/' "$file_path"
;;
"Sheet/Modal")
sed -i 's/PROPERTIES/@State private var isPresented = false/' "$file_path"
sed -i 's/COMPONENT_BODY/Button("Show Sheet") {\n isPresented = true\n }\n .sheet(isPresented: $isPresented) {\n NavigationStack {\n Text("Sheet Content")\n .navigationTitle("Title")\n .navigationBarTitleDisplayMode(.inline)\n .toolbar {\n ToolbarItem(placement: .cancellationAction) {\n Button("Cancel") {\n isPresented = false\n }\n }\n }\n }\n .presentationDetents([.medium, .large])\n }/' "$file_path"
;;
"NavigationView")
sed -i 's/PROPERTIES/\/\/ Navigation properties\n @State private var path = NavigationPath()/' "$file_path"
sed -i 's/COMPONENT_BODY/NavigationStack(path: $path) {\n List {\n NavigationLink("Item 1", value: "Detail 1")\n NavigationLink("Item 2", value: "Detail 2")\n }\n .navigationTitle("Title")\n .navigationBarTitleDisplayMode(.large)\n .navigationDestination(for: String.self) { value in\n Text(value)\n }\n }/' "$file_path"
;;
"TabView")
sed -i 's/PROPERTIES/@State private var selectedTab = 0/' "$file_path"
sed -i 's/COMPONENT_BODY/TabView(selection: $selectedTab) {\n Text("Home")\n .tabItem {\n Label("Home", systemImage: "house")\n }\n .tag(0)\n \n Text("Search")\n .tabItem {\n Label("Search", systemImage: "magnifyingglass")\n }\n .tag(1)\n \n Text("Profile")\n .tabItem {\n Label("Profile", systemImage: "person")\n }\n .tag(2)\n }/' "$file_path"
;;
*)
sed -i 's/PROPERTIES/\/\/ Component properties/' "$file_path"
sed -i 's/COMPONENT_BODY/Text("Custom Component")\n .font(.body)\n ACCESSIBILITY_MODIFIERS/' "$file_path"
;;
esac
# Add accessibility modifiers if requested
if [[ $FEATURES == *"accessibility"* ]]; then
sed -i 's/ACCESSIBILITY_MODIFIERS/.accessibilityLabel("Component label")\n .accessibilityHint("Component hint")/' "$file_path"
else
sed -i 's/ACCESSIBILITY_MODIFIERS//' "$file_path"
fi
# Add preview
sed -i "s/PREVIEW/#Preview {\n COMPONENT_NAME()\n}/" "$file_path"
# Replace component name
sed -i "s/COMPONENT_NAME/$COMPONENT_NAME/g" "$file_path"
print_success "Created SwiftUI component: $file_path"
# Generate test file if needed
if [[ $FEATURES == *"testing"* ]]; then
generate_test_file_swiftui
fi
}
generate_uikit_component() {
local file_path="$OUTPUT_DIR/$COMPONENT_NAME.swift"
cat > "$file_path" << 'EOF'
import UIKit
/// COMPONENT_NAME
///
/// Description of what this component does
/// Follows Apple Human Interface Guidelines
class COMPONENT_NAME: UIView {
// MARK: - Properties
PROPERTIES
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
// MARK: - Setup
private func setupView() {
SETUP_CODE
setupAccessibility()
}
private func setupAccessibility() {
ACCESSIBILITY_SETUP
}
// MARK: - Layout
override func layoutSubviews() {
super.layoutSubviews()
// Layout code here
}
}
EOF
# Add properties based on component type
case $COMPONENT_TYPE in
"Button")
sed -i 's/PROPERTIES/private let button: UIButton = {\n let button = UIButton(type: .system)\n button.translatesAutoresizingMaskIntoConstraints = false\n button.configuration = .filled()\n return button\n }()/' "$file_path"
sed -i 's/SETUP_CODE/addSubview(button)\n \n NSLayoutConstraint.activate([\n button.centerXAnchor.constraint(equalTo: centerXAnchor),\n button.centerYAnchor.constraint(equalTo: centerYAnchor),\n button.heightAnchor.constraint(greaterThanOrEqualToConstant: 44)\n ])/' "$file_path"
;;
"List/TableView")
sed -i 's/PROPERTIES/private let tableView: UITableView = {\n let table = UITableView(frame: .zero, style: .insetGrouped)\n table.translatesAutoresizingMaskIntoConstraints = false\n return table\n }()\n \n private var items: [String] = []/' "$file_path"
sed -i 's/SETUP_CODE/addSubview(tableView)\n tableView.delegate = self\n tableView.dataSource = self\n \n NSLayoutConstraint.activate([\n tableView.topAnchor.constraint(equalTo: topAnchor),\n tableView.leadingAnchor.constraint(equalTo: leadingAnchor),\n tableView.trailingAnchor.constraint(equalTo: trailingAnchor),\n tableView.bottomAnchor.constraint(equalTo: bottomAnchor)\n ])/' "$file_path"
;;
*)
sed -i 's/PROPERTIES/\/\/ Add component properties here/' "$file_path"
sed -i 's/SETUP_CODE/\/\/ Setup UI components/' "$file_path"
;;
esac
# Add accessibility setup
if [[ $FEATURES == *"accessibility"* ]]; then
sed -i 's/ACCESSIBILITY_SETUP/isAccessibilityElement = true\n accessibilityLabel = "Component label"\n accessibilityHint = "Component hint"\n accessibilityTraits = .button/' "$file_path"
else
sed -i 's/ACCESSIBILITY_SETUP/\/\/ Configure accessibility/' "$file_path"
fi
# Replace component name
sed -i "s/COMPONENT_NAME/$COMPONENT_NAME/g" "$file_path"
print_success "Created UIKit component: $file_path"
}
generate_test_file_swiftui() {
local test_file="$OUTPUT_DIR/${COMPONENT_NAME}Tests.swift"
cat > "$test_file" << 'EOF'
import XCTest
import SwiftUI
@testable import YourApp
final class COMPONENT_NAMETests: XCTestCase {
func testComponentRenders() {
let view = COMPONENT_NAME()
XCTAssertNotNil(view)
}
func testAccessibility() {
// Test VoiceOver labels
// Test Dynamic Type support
}
}
EOF
sed -i "s/COMPONENT_NAME/$COMPONENT_NAME/g" "$test_file"
print_success "Created test file: $test_file"
}
# Summary
echo ""
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ Generation Complete ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
print_success "Component: $COMPONENT_NAME"
print_success "Framework: $FRAMEWORK"
print_success "Type: $COMPONENT_TYPE"
print_success "Platform: $PLATFORM"
print_success "Location: $OUTPUT_DIR"
echo ""
print_info "Files created:"
echo " - $COMPONENT_NAME.swift"
if [[ $FEATURES == *"testing"* ]]; then
echo " - ${COMPONENT_NAME}Tests.swift"
fi
echo ""
print_info "Apple HIG Guidelines Applied:"
echo " ✓ Minimum tap target: 44x44 points"
echo " ✓ System fonts (San Francisco)"
echo " ✓ Semantic colors (dark mode support)"
if [[ $FEATURES == *"accessibility"* ]]; then
echo " ✓ VoiceOver support"
echo " ✓ Dynamic Type support"
fi
if [[ $FEATURES == *"haptics"* ]]; then
echo " ✓ Haptic feedback"
fi
echo ""
print_info "Next steps:"
echo " 1. Review generated code"
echo " 2. Add component to your Xcode project"
echo " 3. Customize properties and logic"
echo " 4. Test with VoiceOver"
echo " 5. Test in light and dark mode"
echo " 6. Test with different Dynamic Type sizes"
echo ""