@maccesar/titools 2.0.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/AGENTS-TEMPLATE.md +173 -0
- package/README.md +867 -0
- package/agents/ti-researcher.md +108 -0
- package/bin/titools.js +53 -0
- package/lib/commands/agents.js +126 -0
- package/lib/commands/install.js +188 -0
- package/lib/commands/uninstall.js +215 -0
- package/lib/commands/update.js +159 -0
- package/lib/config.js +119 -0
- package/lib/downloader.js +153 -0
- package/lib/installer.js +253 -0
- package/lib/platform.js +108 -0
- package/lib/symlink.js +142 -0
- package/lib/utils.js +270 -0
- package/package.json +67 -0
- package/skills/alloy-expert/SKILL.md +247 -0
- package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
- package/skills/alloy-expert/references/alloy-structure.md +381 -0
- package/skills/alloy-expert/references/anti-patterns.md +133 -0
- package/skills/alloy-expert/references/code-conventions.md +469 -0
- package/skills/alloy-expert/references/contracts.md +280 -0
- package/skills/alloy-expert/references/controller-patterns.md +520 -0
- package/skills/alloy-expert/references/error-handling.md +484 -0
- package/skills/alloy-expert/references/examples.md +735 -0
- package/skills/alloy-expert/references/migration-patterns.md +298 -0
- package/skills/alloy-expert/references/patterns.md +448 -0
- package/skills/alloy-expert/references/performance-patterns.md +855 -0
- package/skills/alloy-expert/references/security-patterns.md +847 -0
- package/skills/alloy-expert/references/state-management.md +779 -0
- package/skills/alloy-expert/references/testing.md +872 -0
- package/skills/alloy-guides/SKILL.md +214 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
- package/skills/alloy-guides/references/CONCEPTS.md +191 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
- package/skills/alloy-guides/references/MODELS.md +1028 -0
- package/skills/alloy-guides/references/PURGETSS.md +56 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
- package/skills/alloy-guides/references/WIDGETS.md +176 -0
- package/skills/alloy-howtos/SKILL.md +203 -0
- package/skills/alloy-howtos/references/best_practices.md +138 -0
- package/skills/alloy-howtos/references/cli_reference.md +253 -0
- package/skills/alloy-howtos/references/config_files.md +87 -0
- package/skills/alloy-howtos/references/custom_tags.md +147 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
- package/skills/alloy-howtos/references/samples.md +167 -0
- package/skills/purgetss/SKILL.md +442 -0
- package/skills/purgetss/assets/purgetss.config.cjs +17 -0
- package/skills/purgetss/references/EXAMPLES.md +247 -0
- package/skills/purgetss/references/animation-system.md +1294 -0
- package/skills/purgetss/references/apply-directive.md +375 -0
- package/skills/purgetss/references/arbitrary-values.md +612 -0
- package/skills/purgetss/references/class-index.md +1350 -0
- package/skills/purgetss/references/cli-commands.md +948 -0
- package/skills/purgetss/references/configurable-properties.md +654 -0
- package/skills/purgetss/references/custom-rules.md +161 -0
- package/skills/purgetss/references/customization-deep-dive.md +722 -0
- package/skills/purgetss/references/dynamic-component-creation.md +489 -0
- package/skills/purgetss/references/grid-layout.md +455 -0
- package/skills/purgetss/references/icon-fonts.md +609 -0
- package/skills/purgetss/references/installation-setup.md +366 -0
- package/skills/purgetss/references/opacity-modifier.md +291 -0
- package/skills/purgetss/references/platform-modifiers.md +479 -0
- package/skills/purgetss/references/smart-mappings.md +42 -0
- package/skills/purgetss/references/titanium-resets.md +359 -0
- package/skills/purgetss/references/ui-ux-design.md +1526 -0
- package/skills/ti-guides/SKILL.md +94 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
- package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
- package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
- package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +258 -0
- package/skills/ti-guides/references/application-frameworks.md +377 -0
- package/skills/ti-guides/references/cli-reference.md +402 -0
- package/skills/ti-guides/references/coding-best-practices.md +102 -0
- package/skills/ti-guides/references/commonjs-advanced.md +134 -0
- package/skills/ti-guides/references/hello-world.md +100 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
- package/skills/ti-guides/references/javascript-primer.md +411 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +183 -0
- package/skills/ti-guides/references/style-and-conventions.md +48 -0
- package/skills/ti-guides/references/tiapp-config.md +609 -0
- package/skills/ti-howtos/SKILL.md +174 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
- package/skills/ti-howtos/references/cross-platform-development.md +348 -0
- package/skills/ti-howtos/references/debugging-profiling.md +543 -0
- package/skills/ti-howtos/references/extending-titanium.md +723 -0
- package/skills/ti-howtos/references/google-maps-v2.md +169 -0
- package/skills/ti-howtos/references/ios-map-kit.md +143 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
- package/skills/ti-howtos/references/local-data-sources.md +301 -0
- package/skills/ti-howtos/references/location-and-maps.md +252 -0
- package/skills/ti-howtos/references/media-apis.md +210 -0
- package/skills/ti-howtos/references/notification-services.md +599 -0
- package/skills/ti-howtos/references/remote-data-sources.md +349 -0
- package/skills/ti-howtos/references/tutorials.md +502 -0
- package/skills/ti-howtos/references/using-modules.md +237 -0
- package/skills/ti-howtos/references/web-content-integration.md +307 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
- package/skills/ti-ui/SKILL.md +179 -0
- package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
- package/skills/ti-ui/references/animation-and-matrices.md +599 -0
- package/skills/ti-ui/references/application-structures.md +655 -0
- package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
- package/skills/ti-ui/references/event-handling.md +393 -0
- package/skills/ti-ui/references/gestures.md +473 -0
- package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
- package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
- package/skills/ti-ui/references/listviews-and-performance.md +619 -0
- package/skills/ti-ui/references/orientation.md +362 -0
- package/skills/ti-ui/references/platform-ui-android.md +635 -0
- package/skills/ti-ui/references/platform-ui-ios.md +469 -0
- package/skills/ti-ui/references/scrolling-views.md +252 -0
- package/skills/ti-ui/references/tableviews.md +568 -0
|
@@ -0,0 +1,1526 @@
|
|
|
1
|
+
# UI/UX Design Patterns for Titanium SDK with PurgeTSS
|
|
2
|
+
|
|
3
|
+
A comprehensive guide to building beautiful, accessible, and performant mobile UIs using Titanium SDK and PurgeTSS utility classes.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [UI/UX Design Patterns for Titanium SDK with PurgeTSS](#uiux-design-patterns-for-titanium-sdk-with-purgetss)
|
|
8
|
+
- [Table of Contents](#table-of-contents)
|
|
9
|
+
- [1. Common UI Components](#1-common-ui-components)
|
|
10
|
+
- [Cards](#cards)
|
|
11
|
+
- [Elevated Card](#elevated-card)
|
|
12
|
+
- [Outlined Card](#outlined-card)
|
|
13
|
+
- [Card with Image Overlay](#card-with-image-overlay)
|
|
14
|
+
- [Horizontal Card](#horizontal-card)
|
|
15
|
+
- [Lists](#lists)
|
|
16
|
+
- [Simple List Item](#simple-list-item)
|
|
17
|
+
- [List with Avatar](#list-with-avatar)
|
|
18
|
+
- [List with Actions](#list-with-actions)
|
|
19
|
+
- [List with Dividers](#list-with-dividers)
|
|
20
|
+
- [ListView with Custom Template](#listview-with-custom-template)
|
|
21
|
+
- [Forms](#forms)
|
|
22
|
+
- [Text Input](#text-input)
|
|
23
|
+
- [Text Area](#text-area)
|
|
24
|
+
- [Password Input](#password-input)
|
|
25
|
+
- [Select/Dropdown (using Picker)](#selectdropdown-using-picker)
|
|
26
|
+
- [Switch Toggle](#switch-toggle)
|
|
27
|
+
- [Slider](#slider)
|
|
28
|
+
- [Form with Validation States](#form-with-validation-states)
|
|
29
|
+
- [Form Section](#form-section)
|
|
30
|
+
- [Buttons](#buttons)
|
|
31
|
+
- [Primary Button](#primary-button)
|
|
32
|
+
- [Secondary Button](#secondary-button)
|
|
33
|
+
- [Outline Button](#outline-button)
|
|
34
|
+
- [Text Button](#text-button)
|
|
35
|
+
- [Icon Button](#icon-button)
|
|
36
|
+
- [Floating Action Button (FAB)](#floating-action-button-fab)
|
|
37
|
+
- [Button with Icon](#button-with-icon)
|
|
38
|
+
- [Button Group](#button-group)
|
|
39
|
+
- [Button Sizes](#button-sizes)
|
|
40
|
+
- [Navigation Bars](#navigation-bars)
|
|
41
|
+
- [Top Navigation Bar with Title](#top-navigation-bar-with-title)
|
|
42
|
+
- [Navigation Bar with Actions](#navigation-bar-with-actions)
|
|
43
|
+
- [Tab Bar (Bottom)](#tab-bar-bottom)
|
|
44
|
+
- [Segment Control](#segment-control)
|
|
45
|
+
- [Breadcrumb Navigation](#breadcrumb-navigation)
|
|
46
|
+
- [Modals and Dialogs](#modals-and-dialogs)
|
|
47
|
+
- [Alert Dialog](#alert-dialog)
|
|
48
|
+
- [Full Screen Modal (iOS)](#full-screen-modal-ios)
|
|
49
|
+
- [Bottom Sheet (Android-style)](#bottom-sheet-android-style)
|
|
50
|
+
- [Toasts and Snackbars](#toasts-and-snackbars)
|
|
51
|
+
- [Simple Toast](#simple-toast)
|
|
52
|
+
- [Custom Snackbar](#custom-snackbar)
|
|
53
|
+
- [Success Toast](#success-toast)
|
|
54
|
+
- [Error Toast](#error-toast)
|
|
55
|
+
- [2. Layout Patterns](#2-layout-patterns)
|
|
56
|
+
- [Screen Structure](#screen-structure)
|
|
57
|
+
- [Standard Screen Layout](#standard-screen-layout)
|
|
58
|
+
- [Tab Bar Screen Structure](#tab-bar-screen-structure)
|
|
59
|
+
- [Spacing System](#spacing-system)
|
|
60
|
+
- [Margin Examples](#margin-examples)
|
|
61
|
+
- [Padding Examples](#padding-examples)
|
|
62
|
+
- [Gap (Spacing between children)](#gap-spacing-between-children)
|
|
63
|
+
- [Responsive Patterns](#responsive-patterns)
|
|
64
|
+
- [Responsive Grid](#responsive-grid)
|
|
65
|
+
- [Adaptive Layout (Tablet vs Phone)](#adaptive-layout-tablet-vs-phone)
|
|
66
|
+
- [Percentage-Based Widths](#percentage-based-widths)
|
|
67
|
+
- [3. Typography](#3-typography)
|
|
68
|
+
- [Font Scales](#font-scales)
|
|
69
|
+
- [Typography Examples](#typography-examples)
|
|
70
|
+
- [Font Weights](#font-weights)
|
|
71
|
+
- [Text Alignment and Truncation](#text-alignment-and-truncation)
|
|
72
|
+
- [Text Alignment](#text-alignment)
|
|
73
|
+
- [Text Truncation](#text-truncation)
|
|
74
|
+
- [Text Transformations](#text-transformations)
|
|
75
|
+
- [4. Colors and Themes](#4-colors-and-themes)
|
|
76
|
+
- [Semantic Color Naming](#semantic-color-naming)
|
|
77
|
+
- [Primary Colors](#primary-colors)
|
|
78
|
+
- [Semantic Colors](#semantic-colors)
|
|
79
|
+
- [Dark Mode Considerations](#dark-mode-considerations)
|
|
80
|
+
- [Platform-Specific Colors](#platform-specific-colors)
|
|
81
|
+
- [iOS System Colors](#ios-system-colors)
|
|
82
|
+
- [Material Design Colors](#material-design-colors)
|
|
83
|
+
- [5. Icons](#5-icons)
|
|
84
|
+
- [Font Awesome 7 Icon Fonts](#font-awesome-7-icon-fonts)
|
|
85
|
+
- [Icon Sizing and Alignment](#icon-sizing-and-alignment)
|
|
86
|
+
- [Icon Sizes](#icon-sizes)
|
|
87
|
+
- [Icon Colors](#icon-colors)
|
|
88
|
+
- [Icon with Text Patterns](#icon-with-text-patterns)
|
|
89
|
+
- [Icon with Label](#icon-with-label)
|
|
90
|
+
- [Circular Icon Button](#circular-icon-button)
|
|
91
|
+
- [Header with Icon Buttons](#header-with-icon-buttons)
|
|
92
|
+
- [Icon Badge](#icon-badge)
|
|
93
|
+
- [Icon Group](#icon-group)
|
|
94
|
+
- [6. Accessibility](#6-accessibility)
|
|
95
|
+
- [Accessibility Labels](#accessibility-labels)
|
|
96
|
+
- [Touch Target Sizes](#touch-target-sizes)
|
|
97
|
+
- [Color Contrast](#color-contrast)
|
|
98
|
+
- [Screen Reader Support](#screen-reader-support)
|
|
99
|
+
- [7. Performance Best Practices](#7-performance-best-practices)
|
|
100
|
+
- [ListView Performance](#listview-performance)
|
|
101
|
+
- [View Recycling](#view-recycling)
|
|
102
|
+
- [Batch Updates](#batch-updates)
|
|
103
|
+
- [Minimize Template Count](#minimize-template-count)
|
|
104
|
+
- [8. Platform-Specific Patterns](#8-platform-specific-patterns)
|
|
105
|
+
- [iOS Patterns](#ios-patterns)
|
|
106
|
+
- [Navigation Window](#navigation-window)
|
|
107
|
+
- [Tab Bar](#tab-bar)
|
|
108
|
+
- [iOS Swipe Actions](#ios-swipe-actions)
|
|
109
|
+
- [Android Patterns](#android-patterns)
|
|
110
|
+
- [Action Bar](#action-bar)
|
|
111
|
+
- [Back Button Handling](#back-button-handling)
|
|
112
|
+
- [Material Design Theme](#material-design-theme)
|
|
113
|
+
- [Notifications](#notifications)
|
|
114
|
+
- [Quick Reference Card](#quick-reference-card)
|
|
115
|
+
- [Common PurgeTSS Classes](#common-purgetss-classes)
|
|
116
|
+
- [Platform Modifiers](#platform-modifiers)
|
|
117
|
+
- [Best Practices Summary](#best-practices-summary)
|
|
118
|
+
- [Additional Resources](#additional-resources)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 1. Common UI Components
|
|
123
|
+
|
|
124
|
+
### Cards
|
|
125
|
+
|
|
126
|
+
Cards are versatile containers for content and actions on a single subject.
|
|
127
|
+
|
|
128
|
+
#### Elevated Card
|
|
129
|
+
|
|
130
|
+
```xml
|
|
131
|
+
<View class="mb-4 rounded-xl bg-white shadow-lg">
|
|
132
|
+
<ImageView class="mb-4 h-48 w-full rounded-lg" image="/images/card-image.jpg" />
|
|
133
|
+
<Label class="mb-2 text-xl font-bold text-gray-800" text="Card Title" />
|
|
134
|
+
<Label class="mb-4 text-sm text-gray-600" text="Card description goes here with details about the content." />
|
|
135
|
+
<View class="horizontal mt-4">
|
|
136
|
+
<Button class="bg-brand-500 mr-2 rounded-lg px-4 py-2 text-white" title="Action" />
|
|
137
|
+
<Button class="rounded-lg bg-gray-200 px-4 py-2 text-gray-700" title="Learn More" />
|
|
138
|
+
</View>
|
|
139
|
+
</View>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Outlined Card
|
|
143
|
+
|
|
144
|
+
```xml
|
|
145
|
+
<View class="mb-4 rounded-xl border border-gray-300 bg-white">
|
|
146
|
+
<Label class="mb-2 text-lg font-semibold text-gray-800" text="Outlined Card" />
|
|
147
|
+
<Label class="text-sm text-gray-600" text="Clean borders without elevation" />
|
|
148
|
+
</View>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Card with Image Overlay
|
|
152
|
+
|
|
153
|
+
```xml
|
|
154
|
+
<View class="relative mb-4 h-64 overflow-hidden rounded-xl">
|
|
155
|
+
<ImageView class="absolute left-0 top-0 h-full w-full" image="/images/cover.jpg" />
|
|
156
|
+
<View class="absolute bottom-0 left-0 w-full bg-gradient-to-t from-black to-transparent">
|
|
157
|
+
<Label class="mb-4 ml-4 text-xl font-bold text-white" text="Overlay Title" />
|
|
158
|
+
<Label class="mb-4 ml-4 text-sm text-gray-200" text="Subtitle text" />
|
|
159
|
+
</View>
|
|
160
|
+
</View>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Horizontal Card
|
|
164
|
+
|
|
165
|
+
```xml
|
|
166
|
+
<View class="horizontal mb-3 rounded-lg bg-white shadow">
|
|
167
|
+
<ImageView class="ml-3 mr-4 h-20 w-20 rounded-lg" image="/images/thumbnail.jpg" />
|
|
168
|
+
<View class="vertical mr-3 w-full">
|
|
169
|
+
<Label class="text-lg font-semibold text-gray-800" text="Title" />
|
|
170
|
+
<Label class="text-sm text-gray-600" text="Description text that wraps to multiple lines if needed" />
|
|
171
|
+
<Label class="text-brand-500 mt-1 text-xs" text="Read more →" />
|
|
172
|
+
</View>
|
|
173
|
+
</View>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Lists
|
|
177
|
+
|
|
178
|
+
Lists display multiple items vertically and are essential for mobile UIs.
|
|
179
|
+
|
|
180
|
+
#### Simple List Item
|
|
181
|
+
|
|
182
|
+
```xml
|
|
183
|
+
<View class="border-b border-gray-200 bg-white">
|
|
184
|
+
<Label class="mx-4 my-4 text-base text-gray-800" text="List item content" />
|
|
185
|
+
</View>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### List with Avatar
|
|
189
|
+
|
|
190
|
+
```xml
|
|
191
|
+
<View class="horizontal border-b border-gray-200 bg-white">
|
|
192
|
+
<View class="bg-brand-500 ml-4 mr-4 h-12 w-12 rounded-full">
|
|
193
|
+
<Label class="center text-lg font-bold text-white" text="JD" />
|
|
194
|
+
</View>
|
|
195
|
+
<View class="vertical mr-4">
|
|
196
|
+
<Label class="text-base font-semibold text-gray-800" text="John Doe" />
|
|
197
|
+
<Label class="text-sm text-gray-500" text="john.doe@example.com" />
|
|
198
|
+
</View>
|
|
199
|
+
</View>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### List with Actions
|
|
203
|
+
|
|
204
|
+
```xml
|
|
205
|
+
<View class="border-b border-gray-200 bg-white">
|
|
206
|
+
<View class="horizontal">
|
|
207
|
+
<View class="horizontal">
|
|
208
|
+
<View class="ml-4 mr-4 h-12 w-12 rounded-lg bg-blue-100">
|
|
209
|
+
<Label class="center fas fa-folder text-xl text-blue-500" />
|
|
210
|
+
</View>
|
|
211
|
+
<View class="vertical">
|
|
212
|
+
<Label class="text-base font-semibold text-gray-800" text="Project Folder" />
|
|
213
|
+
<Label class="text-sm text-gray-500" text="24 files" />
|
|
214
|
+
</View>
|
|
215
|
+
</View>
|
|
216
|
+
<Label class="fas fa-chevron-right mr-4 text-gray-400" />
|
|
217
|
+
</View>
|
|
218
|
+
</View>
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### List with Dividers
|
|
222
|
+
|
|
223
|
+
```xml
|
|
224
|
+
<View class="bg-white">
|
|
225
|
+
<!-- Item 1 -->
|
|
226
|
+
<View class="border-b border-gray-100">
|
|
227
|
+
<Label class="mx-4 my-4 text-base text-gray-800" text="Item 1" />
|
|
228
|
+
</View>
|
|
229
|
+
<!-- Item 2 -->
|
|
230
|
+
<View class="border-b border-gray-100">
|
|
231
|
+
<Label class="mx-4 my-4 text-base text-gray-800" text="Item 2" />
|
|
232
|
+
</View>
|
|
233
|
+
<!-- Item 3 -->
|
|
234
|
+
<View>
|
|
235
|
+
<Label class="mx-4 my-4 text-base text-gray-800" text="Item 3" />
|
|
236
|
+
</View>
|
|
237
|
+
</View>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### ListView with Custom Template
|
|
241
|
+
|
|
242
|
+
```xml
|
|
243
|
+
<ListView id="myList" defaultItemTemplate="cardTemplate">
|
|
244
|
+
<Templates>
|
|
245
|
+
<ItemTemplate name="cardTemplate" class="h-auto">
|
|
246
|
+
<View bindId="container" class="mx-4 mb-2 rounded-lg bg-white shadow">
|
|
247
|
+
<View class="horizontal">
|
|
248
|
+
<View bindId="iconContainer" class="bg-brand-100 mr-3 h-10 w-10 rounded-full">
|
|
249
|
+
<Label bindId="icon" class="center fas fa-home text-brand-500" />
|
|
250
|
+
</View>
|
|
251
|
+
<View class="vertical">
|
|
252
|
+
<Label bindId="title" class="text-base font-semibold text-gray-800" />
|
|
253
|
+
<Label bindId="subtitle" class="text-sm text-gray-500" />
|
|
254
|
+
</View>
|
|
255
|
+
</View>
|
|
256
|
+
</View>
|
|
257
|
+
</ItemTemplate>
|
|
258
|
+
</Templates>
|
|
259
|
+
<ListSection/>
|
|
260
|
+
</ListView>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
// Controller
|
|
265
|
+
const items = [
|
|
266
|
+
{
|
|
267
|
+
container: {},
|
|
268
|
+
icon: { text: "\uf015" }, // fa-home
|
|
269
|
+
title: { text: "Item 1" },
|
|
270
|
+
subtitle: { text: "First item description" }
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
container: {},
|
|
274
|
+
icon: { text: "\uf007" }, // fa-user
|
|
275
|
+
title: { text: "Item 2" },
|
|
276
|
+
subtitle: { text: "Second item description" }
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
$.myList.sections[0].setItems(items)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Forms
|
|
284
|
+
|
|
285
|
+
Forms collect user input through various controls.
|
|
286
|
+
|
|
287
|
+
#### Text Input
|
|
288
|
+
|
|
289
|
+
```xml
|
|
290
|
+
<View class="mb-4">
|
|
291
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Email Address" />
|
|
292
|
+
<TextField class="focus:border-brand-500 w-full rounded-lg border border-gray-300 bg-white px-4 py-3 text-base text-gray-800" hintText="you@example.com" keyboardType="Ti.UI.KEYBOARD_TYPE_EMAIL" autocapitalization="Ti.UI.TEXT_AUTOCAPITALIZATION_NONE" autocorrect="false" />
|
|
293
|
+
</View>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### Text Area
|
|
297
|
+
|
|
298
|
+
```xml
|
|
299
|
+
<View class="mb-4">
|
|
300
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Message" />
|
|
301
|
+
<TextArea class="h-32 w-full rounded-lg border border-gray-300 bg-white px-4 py-3 text-base text-gray-800" hintText="Type your message here..." autocapitalization="Ti.UI.TEXT_AUTOCAPITALIZATION_SENTENCES" />
|
|
302
|
+
</View>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Password Input
|
|
306
|
+
|
|
307
|
+
```xml
|
|
308
|
+
<View class="mb-4">
|
|
309
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Password" />
|
|
310
|
+
<TextField class="w-full rounded-lg border border-gray-300 bg-white px-4 py-3 text-base text-gray-800" passwordMask="true" hintText="Enter password" />
|
|
311
|
+
</View>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### Select/Dropdown (using Picker)
|
|
315
|
+
|
|
316
|
+
```xml
|
|
317
|
+
<View class="mb-4">
|
|
318
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Category" />
|
|
319
|
+
<Picker class="w-full rounded-lg border border-gray-300 bg-white" selectionIndicator="true">
|
|
320
|
+
<PickerRow title="Option 1" />
|
|
321
|
+
<PickerRow title="Option 2" />
|
|
322
|
+
<PickerRow title="Option 3" />
|
|
323
|
+
</Picker>
|
|
324
|
+
</View>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### Switch Toggle
|
|
328
|
+
|
|
329
|
+
```xml
|
|
330
|
+
<View class="horizontal mb-4 rounded-lg border border-gray-200 bg-white">
|
|
331
|
+
<View class="vertical">
|
|
332
|
+
<Label class="text-base font-medium text-gray-800" text="Notifications" />
|
|
333
|
+
<Label class="text-sm text-gray-500" text="Receive push notifications" />
|
|
334
|
+
</View>
|
|
335
|
+
<Switch class="ml-4" value="true" />
|
|
336
|
+
</View>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### Slider
|
|
340
|
+
|
|
341
|
+
```xml
|
|
342
|
+
<View class="mb-4">
|
|
343
|
+
<View class="horizontal mb-2">
|
|
344
|
+
<Label class="text-sm font-medium text-gray-700" text="Volume" />
|
|
345
|
+
<Label id="sliderValue" class="ml-auto text-sm text-gray-500" text="50%" />
|
|
346
|
+
</View>
|
|
347
|
+
<Slider class="w-full" min="0" max="100" value="50" />
|
|
348
|
+
</View>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### Form with Validation States
|
|
352
|
+
|
|
353
|
+
```xml
|
|
354
|
+
<!-- Error State -->
|
|
355
|
+
<View class="mb-4">
|
|
356
|
+
<Label class="mb-2 text-sm font-medium text-red-600" text="Email Address" />
|
|
357
|
+
<TextField class="w-full rounded-lg border border-red-500 bg-white px-4 py-3 text-base" hintText="Invalid email" />
|
|
358
|
+
<Label class="mt-1 text-xs text-red-500" text="Please enter a valid email address" />
|
|
359
|
+
</View>
|
|
360
|
+
|
|
361
|
+
<!-- Success State -->
|
|
362
|
+
<View class="mb-4">
|
|
363
|
+
<Label class="mb-2 text-sm font-medium text-green-600" text="Email Address" />
|
|
364
|
+
<TextField class="w-full rounded-lg border border-green-500 bg-white px-4 py-3 text-base" hintText="Valid email" />
|
|
365
|
+
<Label class="fas fa-check-circle mt-1 text-xs text-green-500" text=" Valid email" />
|
|
366
|
+
</View>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### Form Section
|
|
370
|
+
|
|
371
|
+
```xml
|
|
372
|
+
<View class="mb-6 rounded-lg bg-white shadow">
|
|
373
|
+
<Label class="mx-6 mb-6 mt-6 text-xl font-bold text-gray-800" text="Account Information" />
|
|
374
|
+
|
|
375
|
+
<View class="mb-4">
|
|
376
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Full Name" />
|
|
377
|
+
<TextField class="w-full rounded-lg border border-gray-300 bg-white px-4 py-3" hintText="John Doe" />
|
|
378
|
+
</View>
|
|
379
|
+
|
|
380
|
+
<View class="mb-4">
|
|
381
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Email" />
|
|
382
|
+
<TextField class="w-full rounded-lg border border-gray-300 bg-white px-4 py-3" hintText="john@example.com" keyboardType="Ti.UI.KEYBOARD_TYPE_EMAIL" />
|
|
383
|
+
</View>
|
|
384
|
+
|
|
385
|
+
<View class="mb-6">
|
|
386
|
+
<Label class="mb-2 text-sm font-medium text-gray-700" text="Phone" />
|
|
387
|
+
<TextField class="w-full rounded-lg border border-gray-300 bg-white px-4 py-3" hintText="+1 (555) 000-0000" keyboardType="Ti.UI.KEYBOARD_TYPE_PHONE" />
|
|
388
|
+
</View>
|
|
389
|
+
|
|
390
|
+
<Button class="bg-brand-500 w-full rounded-lg py-3 text-base font-semibold text-white" title="Save Changes" />
|
|
391
|
+
</View>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Buttons
|
|
395
|
+
|
|
396
|
+
Buttons trigger actions and are primary interactive elements.
|
|
397
|
+
|
|
398
|
+
#### Primary Button
|
|
399
|
+
|
|
400
|
+
```xml
|
|
401
|
+
<Button class="bg-brand-500 rounded-lg px-6 py-3 text-base font-semibold text-white shadow-md" title="Primary Action" />
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### Secondary Button
|
|
405
|
+
|
|
406
|
+
```xml
|
|
407
|
+
<Button class="rounded-lg border border-gray-300 bg-white px-6 py-3 text-base font-semibold text-gray-700" title="Secondary Action" />
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### Outline Button
|
|
411
|
+
|
|
412
|
+
```xml
|
|
413
|
+
<Button class="border-brand-500 text-brand-500 rounded-lg border-2 bg-transparent px-6 py-3 text-base font-semibold" title="Outline" />
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### Text Button
|
|
417
|
+
|
|
418
|
+
```xml
|
|
419
|
+
<Button class="text-brand-500 bg-transparent text-base font-semibold" title="Text Only" />
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
#### Icon Button
|
|
423
|
+
|
|
424
|
+
```xml
|
|
425
|
+
<!-- EFFICIENT: Single Label with icon, size, and styling -->
|
|
426
|
+
<Label class="rounded-full-12 bg-brand-500 fa-solid fa-plus text-center text-xl text-white" />
|
|
427
|
+
|
|
428
|
+
<!-- ALTERNATIVE: View + Label (more verbose) -->
|
|
429
|
+
<View class="bg-brand-500 h-12 w-12 rounded-full">
|
|
430
|
+
<Label class="center fas fa-plus text-xl text-white" />
|
|
431
|
+
</View>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
:::tip SINGLE-LABEL ICON BUTTONS
|
|
435
|
+
For circular icon buttons, you can use a single `Label` with:
|
|
436
|
+
- `rounded-full-XX` (includes size) - Creates the circle and sets dimensions
|
|
437
|
+
- Font Awesome icon class (e.g., `fa-solid fa-plus`)
|
|
438
|
+
- `text-center` - Centers the icon
|
|
439
|
+
- Background color and text color
|
|
440
|
+
|
|
441
|
+
This eliminates the need for a wrapper `View`, reducing DOM depth.
|
|
442
|
+
:::
|
|
443
|
+
|
|
444
|
+
#### Floating Action Button (FAB)
|
|
445
|
+
|
|
446
|
+
```xml
|
|
447
|
+
<!-- SIMPLIFIED: Single Label with positioning -->
|
|
448
|
+
<Label class="rounded-full-14 bg-brand-500 fa-solid fa-plus absolute bottom-6 right-6 text-center text-2xl text-white shadow-lg" />
|
|
449
|
+
|
|
450
|
+
<!-- ALTERNATIVE: View wrapper approach -->
|
|
451
|
+
<View class="absolute bottom-6 right-6">
|
|
452
|
+
<View class="bg-brand-500 h-14 w-14 rounded-full shadow-lg">
|
|
453
|
+
<Label class="center fas fa-plus text-2xl text-white" />
|
|
454
|
+
</View>
|
|
455
|
+
</View>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### Button with Icon
|
|
459
|
+
|
|
460
|
+
```xml
|
|
461
|
+
<View class="horizontal bg-brand-500 rounded-lg px-6 py-3 shadow-md">
|
|
462
|
+
<Label class="fas fa-arrow-left mr-2 text-lg text-white" />
|
|
463
|
+
<Label class="text-base font-semibold text-white" text="Back" />
|
|
464
|
+
</View>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
#### Button Group
|
|
468
|
+
|
|
469
|
+
```xml
|
|
470
|
+
<View class="horizontal rounded-lg bg-gray-200">
|
|
471
|
+
<View class="w-1/3 rounded-md bg-white py-2 shadow-sm">
|
|
472
|
+
<Label class="text-center text-sm font-semibold text-gray-800" text="Day" />
|
|
473
|
+
</View>
|
|
474
|
+
<View class="w-1/3 py-2">
|
|
475
|
+
<Label class="text-center text-sm font-medium text-gray-500" text="Week" />
|
|
476
|
+
</View>
|
|
477
|
+
<View class="w-1/3 py-2">
|
|
478
|
+
<Label class="text-center text-sm font-medium text-gray-500" text="Month" />
|
|
479
|
+
</View>
|
|
480
|
+
</View>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
#### Button Sizes
|
|
484
|
+
|
|
485
|
+
```xml
|
|
486
|
+
<!-- Small -->
|
|
487
|
+
<Button class="bg-brand-500 rounded px-4 py-2 text-sm font-semibold text-white" title="Small" />
|
|
488
|
+
|
|
489
|
+
<!-- Medium (Default) -->
|
|
490
|
+
<Button class="bg-brand-500 rounded-lg px-6 py-3 text-base font-semibold text-white" title="Medium" />
|
|
491
|
+
|
|
492
|
+
<!-- Large -->
|
|
493
|
+
<Button class="bg-brand-500 rounded-xl px-8 py-4 text-lg font-semibold text-white" title="Large" />
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Navigation Bars
|
|
497
|
+
|
|
498
|
+
Navigation bars provide hierarchy and navigation context.
|
|
499
|
+
|
|
500
|
+
#### Top Navigation Bar with Title
|
|
501
|
+
|
|
502
|
+
```xml
|
|
503
|
+
<View class="horizontal h-14 border-b border-gray-200 bg-white">
|
|
504
|
+
<Label class="fas fa-arrow-left ml-4 text-xl text-gray-600" />
|
|
505
|
+
<Label class="w-screen text-center text-lg font-semibold text-gray-800" text="Screen Title" />
|
|
506
|
+
<Label class="fas fa-ellipsis-v mr-4 text-xl text-gray-600" />
|
|
507
|
+
</View>
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### Navigation Bar with Actions
|
|
511
|
+
|
|
512
|
+
```xml
|
|
513
|
+
<View class="bg-brand-500 horizontal h-14">
|
|
514
|
+
<Label class="fas fa-bars ml-4 text-xl text-white" />
|
|
515
|
+
<Label class="w-screen text-center text-lg font-semibold text-white" text="Dashboard" />
|
|
516
|
+
<View class="horizontal mr-4">
|
|
517
|
+
<Label class="fas fa-search mr-4 text-xl text-white" />
|
|
518
|
+
<Label class="fas fa-bell text-xl text-white" />
|
|
519
|
+
</View>
|
|
520
|
+
</View>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
#### Tab Bar (Bottom)
|
|
524
|
+
|
|
525
|
+
```xml
|
|
526
|
+
<View class="horizontal h-16 border-t border-gray-200 bg-white">
|
|
527
|
+
<View class="vertical w-1/3">
|
|
528
|
+
<Label class="fas fa-home text-brand-500 mx-auto mb-1 text-xl" />
|
|
529
|
+
<Label class="text-brand-500 text-center text-xs font-medium" text="Home" />
|
|
530
|
+
</View>
|
|
531
|
+
<View class="vertical w-1/3">
|
|
532
|
+
<Label class="fas fa-search mx-auto mb-1 text-xl text-gray-400" />
|
|
533
|
+
<Label class="text-center text-xs text-gray-400" text="Search" />
|
|
534
|
+
</View>
|
|
535
|
+
<View class="vertical w-1/3">
|
|
536
|
+
<Label class="fas fa-user mx-auto mb-1 text-xl text-gray-400" />
|
|
537
|
+
<Label class="text-center text-xs text-gray-400" text="Profile" />
|
|
538
|
+
</View>
|
|
539
|
+
</View>
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
#### Segment Control
|
|
543
|
+
|
|
544
|
+
```xml
|
|
545
|
+
<View class="horizontal mx-4 my-4 rounded-lg bg-gray-200">
|
|
546
|
+
<View id="segment1" class="w-1/2 rounded-md bg-white py-2 shadow-sm">
|
|
547
|
+
<Label class="text-center text-sm font-semibold text-gray-800" text="Active" />
|
|
548
|
+
</View>
|
|
549
|
+
<View id="segment2" class="w-1/2 py-2">
|
|
550
|
+
<Label class="text-center text-sm font-medium text-gray-500" text="Inactive" />
|
|
551
|
+
</View>
|
|
552
|
+
</View>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### Breadcrumb Navigation
|
|
556
|
+
|
|
557
|
+
```xml
|
|
558
|
+
<View class="horizontal bg-gray-50">
|
|
559
|
+
<Label class="text-brand-500 text-sm" text="Home" />
|
|
560
|
+
<Label class="fas fa-chevron-right mx-2 my-3 text-xs text-gray-400" />
|
|
561
|
+
<Label class="text-brand-500 text-sm" text="Products" />
|
|
562
|
+
<Label class="fas fa-chevron-right mx-2 my-3 text-xs text-gray-400" />
|
|
563
|
+
<Label class="my-3 text-sm font-medium text-gray-800" text="Category" />
|
|
564
|
+
</View>
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Modals and Dialogs
|
|
568
|
+
|
|
569
|
+
Modals focus user attention on specific content or actions.
|
|
570
|
+
|
|
571
|
+
#### Alert Dialog
|
|
572
|
+
|
|
573
|
+
```javascript
|
|
574
|
+
const dialog = Ti.UI.createAlertDialog({
|
|
575
|
+
cancel: 0,
|
|
576
|
+
title: 'Delete Item',
|
|
577
|
+
buttonNames: ['Cancel', 'Delete'],
|
|
578
|
+
message: 'Are you sure you want to delete this item? This action cannot be undone.'
|
|
579
|
+
})
|
|
580
|
+
|
|
581
|
+
dialog.addEventListener('click', (e) => {
|
|
582
|
+
if (e.index === 1) {
|
|
583
|
+
// Delete action
|
|
584
|
+
}
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
dialog.show()
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
#### Full Screen Modal (iOS)
|
|
591
|
+
|
|
592
|
+
```xml
|
|
593
|
+
<!-- modal.xml -->
|
|
594
|
+
<Window class="bg-white" modal="true">
|
|
595
|
+
<View class="vertical h-full">
|
|
596
|
+
<!-- Header -->
|
|
597
|
+
<View class="horizontal border-b border-gray-200 bg-white">
|
|
598
|
+
<Label id="closeBtn" class="text-brand-500 text-base font-semibold" text="Cancel" />
|
|
599
|
+
<Label class="w-screen text-center text-lg font-semibold text-gray-800" text="Modal Title" />
|
|
600
|
+
<Label id="saveBtn" class="text-brand-500 text-base font-semibold" text="Save" />
|
|
601
|
+
</View>
|
|
602
|
+
|
|
603
|
+
<!-- Content -->
|
|
604
|
+
<ScrollView class="h-full">
|
|
605
|
+
<View>
|
|
606
|
+
<Label class="mx-4 my-4 text-base text-gray-800" text="Modal content goes here..." />
|
|
607
|
+
</View>
|
|
608
|
+
</ScrollView>
|
|
609
|
+
</View>
|
|
610
|
+
</Window>
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
```javascript
|
|
614
|
+
// Open modal
|
|
615
|
+
const modal = Alloy.createController('modal').getView()
|
|
616
|
+
modal.open({ modal: true })
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
#### Bottom Sheet (Android-style)
|
|
620
|
+
|
|
621
|
+
```xml
|
|
622
|
+
<View class="absolute bottom-0 left-0 w-full rounded-t-xl bg-white shadow-2xl">
|
|
623
|
+
<View class="mx-auto mb-4 mt-3 h-1 w-12 rounded-full bg-gray-300" />
|
|
624
|
+
<View>
|
|
625
|
+
<Label class="mx-4 mb-4 mt-4 text-lg font-semibold text-gray-800" text="Choose Action" />
|
|
626
|
+
<View class="vertical">
|
|
627
|
+
<View class="border-b border-gray-100">
|
|
628
|
+
<Label class="mx-4 my-3 text-base text-gray-800" text="Action 1" />
|
|
629
|
+
</View>
|
|
630
|
+
<View class="border-b border-gray-100">
|
|
631
|
+
<Label class="mx-4 my-3 text-base text-gray-800" text="Action 2" />
|
|
632
|
+
</View>
|
|
633
|
+
<View>
|
|
634
|
+
<Label class="mx-4 my-3 text-base font-semibold text-red-500" text="Delete" />
|
|
635
|
+
</View>
|
|
636
|
+
</View>
|
|
637
|
+
</View>
|
|
638
|
+
</View>
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Toasts and Snackbars
|
|
642
|
+
|
|
643
|
+
Brief notifications that provide feedback.
|
|
644
|
+
|
|
645
|
+
#### Simple Toast
|
|
646
|
+
|
|
647
|
+
```javascript
|
|
648
|
+
// Native toast (Android only)
|
|
649
|
+
var toast = Ti.UI.createNotification({
|
|
650
|
+
message: "Operation successful",
|
|
651
|
+
duration: Ti.UI.NOTIFICATION_DURATION_SHORT
|
|
652
|
+
})
|
|
653
|
+
toast.show()
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
#### Custom Snackbar
|
|
657
|
+
|
|
658
|
+
```xml
|
|
659
|
+
<View id="snackbar" class="absolute bottom-4 left-4 right-4 hidden rounded-lg bg-gray-800 shadow-lg">
|
|
660
|
+
<View class="horizontal">
|
|
661
|
+
<Label class="w-screen text-base text-white" text="File deleted successfully" />
|
|
662
|
+
<Label id="undoBtn" class="text-brand-400 text-base font-semibold" text="UNDO" />
|
|
663
|
+
</View>
|
|
664
|
+
</View>
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
```javascript
|
|
668
|
+
// Show snackbar
|
|
669
|
+
$.snackbar.setVisible(true)
|
|
670
|
+
setTimeout(() => {
|
|
671
|
+
$.snackbar.setVisible(false)
|
|
672
|
+
}, 3000)
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
#### Success Toast
|
|
676
|
+
|
|
677
|
+
```xml
|
|
678
|
+
<View class="horizontal absolute left-4 right-4 top-4 rounded-lg bg-green-500 shadow-lg">
|
|
679
|
+
<Label class="fas fa-check-circle mr-3 text-xl text-white" />
|
|
680
|
+
<Label class="text-base font-medium text-white" text="Changes saved successfully!" />
|
|
681
|
+
</View>
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
#### Error Toast
|
|
685
|
+
|
|
686
|
+
```xml
|
|
687
|
+
<View class="horizontal absolute left-4 right-4 top-4 rounded-lg bg-red-500 shadow-lg">
|
|
688
|
+
<Label class="fas fa-exclamation-circle mr-3 text-xl text-white" />
|
|
689
|
+
<Label class="text-base font-medium text-white" text="An error occurred. Please try again." />
|
|
690
|
+
</View>
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
695
|
+
## 2. Layout Patterns
|
|
696
|
+
|
|
697
|
+
### Screen Structure
|
|
698
|
+
|
|
699
|
+
#### Standard Screen Layout
|
|
700
|
+
|
|
701
|
+
```xml
|
|
702
|
+
<Window class="bg-gray-100">
|
|
703
|
+
<ScrollView class="h-full w-full">
|
|
704
|
+
<!-- Header -->
|
|
705
|
+
<View class="border-b border-gray-200 bg-white">
|
|
706
|
+
<Label class="mx-4 my-4 text-2xl font-bold text-gray-800" text="Screen Title" />
|
|
707
|
+
</View>
|
|
708
|
+
|
|
709
|
+
<!-- Content -->
|
|
710
|
+
<View>
|
|
711
|
+
<!-- Main content goes here -->
|
|
712
|
+
</View>
|
|
713
|
+
|
|
714
|
+
<!-- Footer -->
|
|
715
|
+
<View class="border-t border-gray-200 bg-white">
|
|
716
|
+
<Label class="text-center text-sm text-gray-500" text="Footer content" />
|
|
717
|
+
</View>
|
|
718
|
+
</ScrollView>
|
|
719
|
+
</Window>
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
#### Tab Bar Screen Structure
|
|
723
|
+
|
|
724
|
+
```xml
|
|
725
|
+
<TabGroup>
|
|
726
|
+
<!-- Tab 1 -->
|
|
727
|
+
<Tab>
|
|
728
|
+
<Window class="bg-gray-100">
|
|
729
|
+
<ScrollView class="h-full w-full">
|
|
730
|
+
<Label class="mb-4 text-lg font-semibold text-gray-800" text="Home" />
|
|
731
|
+
<!-- Content -->
|
|
732
|
+
</ScrollView>
|
|
733
|
+
</Window>
|
|
734
|
+
</Tab>
|
|
735
|
+
|
|
736
|
+
<!-- Tab 2 -->
|
|
737
|
+
<Tab>
|
|
738
|
+
<Window class="bg-gray-100">
|
|
739
|
+
<ScrollView class="h-full w-full">
|
|
740
|
+
<Label class="mb-4 text-lg font-semibold text-gray-800" text="Search" />
|
|
741
|
+
<!-- Content -->
|
|
742
|
+
</ScrollView>
|
|
743
|
+
</Window>
|
|
744
|
+
</Tab>
|
|
745
|
+
|
|
746
|
+
<!-- Tab 3 -->
|
|
747
|
+
<Tab>
|
|
748
|
+
<Window class="bg-gray-100">
|
|
749
|
+
<ScrollView class="h-full w-full">
|
|
750
|
+
<Label class="mb-4 text-lg font-semibold text-gray-800" text="Profile" />
|
|
751
|
+
<!-- Content -->
|
|
752
|
+
</ScrollView>
|
|
753
|
+
</Window>
|
|
754
|
+
</Tab>
|
|
755
|
+
</TabGroup>
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Spacing System
|
|
759
|
+
|
|
760
|
+
PurgeTSS uses a consistent spacing scale based on 4px increments:
|
|
761
|
+
|
|
762
|
+
| Class | Spacing | Usage |
|
|
763
|
+
| ----- | ------- | ----------- |
|
|
764
|
+
| `p-0` | 0px | No padding |
|
|
765
|
+
| `p-1` | 4px | Extra small |
|
|
766
|
+
| `p-2` | 8px | Small |
|
|
767
|
+
| `p-3` | 12px | Medium |
|
|
768
|
+
| `p-4` | 16px | Standard |
|
|
769
|
+
| `p-5` | 20px | Large |
|
|
770
|
+
| `p-6` | 24px | Extra large |
|
|
771
|
+
| `p-8` | 32px | Double |
|
|
772
|
+
|
|
773
|
+
**Note:** Padding classes (`p-*`) work on some elements like TextField, TextArea, Button, and Label, but do NOT work on View. For View spacing, use margin classes on child elements instead.
|
|
774
|
+
|
|
775
|
+
#### Margin Examples
|
|
776
|
+
|
|
777
|
+
```xml
|
|
778
|
+
<!-- All sides -->
|
|
779
|
+
<View class="m-4">...</View>
|
|
780
|
+
|
|
781
|
+
<!-- Horizontal -->
|
|
782
|
+
<View class="mx-4">...</View>
|
|
783
|
+
|
|
784
|
+
<!-- Vertical -->
|
|
785
|
+
<View class="my-4">...</View>
|
|
786
|
+
|
|
787
|
+
<!-- Individual sides -->
|
|
788
|
+
<View class="mb-4 ml-2 mr-4 mt-2">...</View>
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
#### Padding Examples
|
|
792
|
+
|
|
793
|
+
```xml
|
|
794
|
+
<!-- All sides (works on TextField, TextArea, Button, Label) -->
|
|
795
|
+
<TextField class="p-4" hintText="Input with padding" />
|
|
796
|
+
|
|
797
|
+
<!-- Horizontal (works on TextField, TextArea, Button, Label) -->
|
|
798
|
+
<TextField class="px-4" hintText="Input with horizontal padding" />
|
|
799
|
+
|
|
800
|
+
<!-- Vertical (works on TextField, TextArea, Button, Label) -->
|
|
801
|
+
<TextField class="py-4" hintText="Input with vertical padding" />
|
|
802
|
+
|
|
803
|
+
<!-- Individual sides (works on TextField, TextArea, Button, Label) -->
|
|
804
|
+
<TextField class="pb-4 pl-2 pr-4 pt-2" hintText="Input with individual padding" />
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
#### Gap (Spacing between children)
|
|
808
|
+
|
|
809
|
+
```xml
|
|
810
|
+
<View class="gap-2"> <!-- 8px between all children -->
|
|
811
|
+
<View class="h-10 bg-red-500" />
|
|
812
|
+
<View class="h-10 bg-blue-500" />
|
|
813
|
+
<View class="h-10 bg-green-500" />
|
|
814
|
+
</View>
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Responsive Patterns
|
|
818
|
+
|
|
819
|
+
#### Responsive Grid
|
|
820
|
+
|
|
821
|
+
```xml
|
|
822
|
+
<!-- Two columns on large screens, one column on small -->
|
|
823
|
+
<View class="grid">
|
|
824
|
+
<View class="col-span-6 md:col-span-12">
|
|
825
|
+
<Label text="Responsive Item" />
|
|
826
|
+
</View>
|
|
827
|
+
</View>
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
#### Adaptive Layout (Tablet vs Phone)
|
|
831
|
+
|
|
832
|
+
```xml
|
|
833
|
+
<!-- Use platform modifiers for adaptive layouts -->
|
|
834
|
+
<View class="horizontal">
|
|
835
|
+
<!-- Sidebar on tablets, full width on phones -->
|
|
836
|
+
<View class="w-1/4 md:w-full">
|
|
837
|
+
<Label text="Sidebar" />
|
|
838
|
+
</View>
|
|
839
|
+
|
|
840
|
+
<!-- Main content -->
|
|
841
|
+
<View class="w-3/4 md:w-full">
|
|
842
|
+
<Label text="Main Content" />
|
|
843
|
+
</View>
|
|
844
|
+
</View>
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
#### Percentage-Based Widths
|
|
848
|
+
|
|
849
|
+
```xml
|
|
850
|
+
<!-- Half width -->
|
|
851
|
+
<View class="w-(50%)">...</View>
|
|
852
|
+
|
|
853
|
+
<!-- One-third width -->
|
|
854
|
+
<View class="w-(33.33%)">...</View>
|
|
855
|
+
|
|
856
|
+
<!-- Custom percentage -->
|
|
857
|
+
<View class="w-(75%)">...</View>
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
---
|
|
861
|
+
|
|
862
|
+
## 3. Typography
|
|
863
|
+
|
|
864
|
+
### Font Scales
|
|
865
|
+
|
|
866
|
+
PurgeTSS provides consistent font size utilities:
|
|
867
|
+
|
|
868
|
+
| Class | Size | Usage |
|
|
869
|
+
| ----------- | ---- | ------------------- |
|
|
870
|
+
| `text-xs` | 12px | Captions, labels |
|
|
871
|
+
| `text-sm` | 14px | Secondary text |
|
|
872
|
+
| `text-base` | 16px | Body text (default) |
|
|
873
|
+
| `text-lg` | 18px | Subheadings |
|
|
874
|
+
| `text-xl` | 20px | Headings |
|
|
875
|
+
| `text-2xl` | 24px | Large headings |
|
|
876
|
+
| `text-3xl` | 30px | Display headings |
|
|
877
|
+
| `text-4xl` | 36px | Hero text |
|
|
878
|
+
|
|
879
|
+
#### Typography Examples
|
|
880
|
+
|
|
881
|
+
```xml
|
|
882
|
+
<!-- Display heading -->
|
|
883
|
+
<Label class="text-4xl font-bold text-gray-900" text="Hero Title" />
|
|
884
|
+
|
|
885
|
+
<!-- Page heading -->
|
|
886
|
+
<Label class="text-2xl font-bold text-gray-800" text="Page Title" />
|
|
887
|
+
|
|
888
|
+
<!-- Section heading -->
|
|
889
|
+
<Label class="text-xl font-semibold text-gray-800" text="Section Title" />
|
|
890
|
+
|
|
891
|
+
<!-- Body text -->
|
|
892
|
+
<Label class="text-base text-gray-600" text="Regular body text content" />
|
|
893
|
+
|
|
894
|
+
<!-- Caption -->
|
|
895
|
+
<Label class="text-xs text-gray-500" text="Caption text" />
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### Font Weights
|
|
899
|
+
|
|
900
|
+
```xml
|
|
901
|
+
<Label class="font-light" text="Light weight (300)" />
|
|
902
|
+
<Label class="font-normal" text="Normal weight (400)" />
|
|
903
|
+
<Label class="font-medium" text="Medium weight (500)" />
|
|
904
|
+
<Label class="font-semibold" text="Semibold weight (600)" />
|
|
905
|
+
<Label class="font-bold" text="Bold weight (700)" />
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
### Text Alignment and Truncation
|
|
909
|
+
|
|
910
|
+
#### Text Alignment
|
|
911
|
+
|
|
912
|
+
```xml
|
|
913
|
+
<Label class="text-left" text="Left aligned" />
|
|
914
|
+
<Label class="text-center" text="Center aligned" />
|
|
915
|
+
<Label class="text-right" text="Right aligned" />
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
#### Text Truncation
|
|
919
|
+
|
|
920
|
+
```xml
|
|
921
|
+
<!-- Single line truncation -->
|
|
922
|
+
<Label class="truncate" text="Very long text that will be truncated with ellipsis..." />
|
|
923
|
+
|
|
924
|
+
<!-- Multi-line truncation -->
|
|
925
|
+
<Label class="line-clamp-2" text="Long text that will truncate after 2 lines with ellipsis..." />
|
|
926
|
+
<Label class="line-clamp-3" text="Long text that will truncate after 3 lines with ellipsis..." />
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
#### Text Transformations
|
|
930
|
+
|
|
931
|
+
```xml
|
|
932
|
+
<Label class="uppercase" text="uppercase text" />
|
|
933
|
+
<Label class="lowercase" text="LOWERCASE TEXT" />
|
|
934
|
+
<Label class="capitalize" text="capitalize each word" />
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
---
|
|
938
|
+
|
|
939
|
+
## 4. Colors and Themes
|
|
940
|
+
|
|
941
|
+
### Semantic Color Naming
|
|
942
|
+
|
|
943
|
+
Use semantic color names for better maintainability:
|
|
944
|
+
|
|
945
|
+
#### Primary Colors
|
|
946
|
+
|
|
947
|
+
```xml
|
|
948
|
+
<!-- Brand colors -->
|
|
949
|
+
<View class="bg-brand-500">...</View>
|
|
950
|
+
<View class="bg-brand-600">...</View>
|
|
951
|
+
<View class="bg-brand-700">...</View>
|
|
952
|
+
|
|
953
|
+
<!-- Gray scale -->
|
|
954
|
+
<View class="bg-gray-50">...</View>
|
|
955
|
+
<View class="bg-gray-100">...</View>
|
|
956
|
+
<View class="bg-gray-200">...</View>
|
|
957
|
+
<View class="bg-gray-300">...</View>
|
|
958
|
+
<View class="bg-gray-400">...</View>
|
|
959
|
+
<View class="bg-gray-500">...</View>
|
|
960
|
+
<View class="bg-gray-600">...</View>
|
|
961
|
+
<View class="bg-gray-700">...</View>
|
|
962
|
+
<View class="bg-gray-800">...</View>
|
|
963
|
+
<View class="bg-gray-900">...</View>
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
#### Semantic Colors
|
|
967
|
+
|
|
968
|
+
```xml
|
|
969
|
+
<!-- Success -->
|
|
970
|
+
<View class="bg-green-500">...</View>
|
|
971
|
+
<Label class="text-green-500" text="Success message" />
|
|
972
|
+
|
|
973
|
+
<!-- Warning -->
|
|
974
|
+
<View class="bg-yellow-500">...</View>
|
|
975
|
+
<Label class="text-yellow-500" text="Warning message" />
|
|
976
|
+
|
|
977
|
+
<!-- Error -->
|
|
978
|
+
<View class="bg-red-500">...</View>
|
|
979
|
+
<Label class="text-red-500" text="Error message" />
|
|
980
|
+
|
|
981
|
+
<!-- Info -->
|
|
982
|
+
<View class="bg-blue-500">...</View>
|
|
983
|
+
<Label class="text-blue-500" text="Info message" />
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
### Dark Mode Considerations
|
|
987
|
+
|
|
988
|
+
Use semantic color names that adapt to theme:
|
|
989
|
+
|
|
990
|
+
```xml
|
|
991
|
+
<!-- Adaptive background -->
|
|
992
|
+
<View class="bg-white dark:bg-gray-900">...</View>
|
|
993
|
+
|
|
994
|
+
<!-- Adaptive text -->
|
|
995
|
+
<Label class="text-gray-800 dark:text-gray-100" text="Adaptive text" />
|
|
996
|
+
|
|
997
|
+
<!-- Adaptive borders -->
|
|
998
|
+
<View class="border-gray-200 dark:border-gray-700">...</View>
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
### Platform-Specific Colors
|
|
1002
|
+
|
|
1003
|
+
#### iOS System Colors
|
|
1004
|
+
|
|
1005
|
+
```xml
|
|
1006
|
+
<!-- iOS blue -->
|
|
1007
|
+
<Button class="bg-ios-blue text-white" title="iOS Button" />
|
|
1008
|
+
|
|
1009
|
+
<!-- iOS system background -->
|
|
1010
|
+
<Window class="bg-ios-system-background">
|
|
1011
|
+
<View class="bg-ios-secondary-system-background">
|
|
1012
|
+
<Label class="text-ios-label" text="iOS Text" />
|
|
1013
|
+
</View>
|
|
1014
|
+
</Window>
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
#### Material Design Colors
|
|
1018
|
+
|
|
1019
|
+
```xml
|
|
1020
|
+
<!-- Material primary -->
|
|
1021
|
+
<Button class="bg-material-primary text-white" title="Material Button" />
|
|
1022
|
+
|
|
1023
|
+
<!-- Material surface -->
|
|
1024
|
+
<View class="bg-material-surface">
|
|
1025
|
+
<Label class="text-material-on-surface" text="Material Text" />
|
|
1026
|
+
</View>
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
---
|
|
1030
|
+
|
|
1031
|
+
## 5. Icons
|
|
1032
|
+
|
|
1033
|
+
### Font Awesome 7 Icon Fonts
|
|
1034
|
+
|
|
1035
|
+
Font Awesome 7 uses style prefixes for different icon sets:
|
|
1036
|
+
|
|
1037
|
+
```xml
|
|
1038
|
+
<!-- Solid icons (free) -->
|
|
1039
|
+
<Label class="fas fa-home" />
|
|
1040
|
+
<Label class="fas fa-user" />
|
|
1041
|
+
<Label class="fas fa-envelope" />
|
|
1042
|
+
|
|
1043
|
+
<!-- Regular icons (free) -->
|
|
1044
|
+
<Label class="far fa-heart" />
|
|
1045
|
+
<Label class="far fa-star" />
|
|
1046
|
+
<Label class="far fa-bookmark" />
|
|
1047
|
+
|
|
1048
|
+
<!-- Brand icons (free) -->
|
|
1049
|
+
<Label class="fab fa-twitter" />
|
|
1050
|
+
<Label class="fab fa-facebook" />
|
|
1051
|
+
<Label class="fab fa-github" />
|
|
1052
|
+
|
|
1053
|
+
<!-- Pro-only styles (require Font Awesome Pro) -->
|
|
1054
|
+
<Label class="fal fa-camera" /> <!-- Light -->
|
|
1055
|
+
<Label class="fass fa-star" /> <!-- Sharp Solid -->
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
### Icon Sizing and Alignment
|
|
1059
|
+
|
|
1060
|
+
#### Icon Sizes
|
|
1061
|
+
|
|
1062
|
+
```xml
|
|
1063
|
+
<Label class="fas fa-home text-xs" /> <!-- 12px -->
|
|
1064
|
+
<Label class="fas fa-home text-sm" /> <!-- 14px -->
|
|
1065
|
+
<Label class="fas fa-home text-base" /> <!-- 16px -->
|
|
1066
|
+
<Label class="fas fa-home text-lg" /> <!-- 18px -->
|
|
1067
|
+
<Label class="fas fa-home text-xl" /> <!-- 20px -->
|
|
1068
|
+
<Label class="fas fa-home text-2xl" /> <!-- 24px -->
|
|
1069
|
+
<Label class="fas fa-home text-3xl" /> <!-- 30px -->
|
|
1070
|
+
<Label class="fas fa-home text-4xl" /> <!-- 36px -->
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
#### Icon Colors
|
|
1074
|
+
|
|
1075
|
+
```xml
|
|
1076
|
+
<Label class="fas fa-home text-gray-500" />
|
|
1077
|
+
<Label class="fas fa-home text-brand-500" />
|
|
1078
|
+
<Label class="fas fa-home text-(#FF5733)" /> <!-- Arbitrary color -->
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
### Icon with Text Patterns
|
|
1082
|
+
|
|
1083
|
+
#### Icon with Label
|
|
1084
|
+
|
|
1085
|
+
```xml
|
|
1086
|
+
<View class="horizontal">
|
|
1087
|
+
<Label class="fas fa-envelope mr-2 text-gray-600" />
|
|
1088
|
+
<Label class="text-gray-800" text="Email" />
|
|
1089
|
+
</View>
|
|
1090
|
+
```
|
|
1091
|
+
|
|
1092
|
+
#### Circular Icon Button
|
|
1093
|
+
|
|
1094
|
+
```xml
|
|
1095
|
+
<!-- EFFICIENT: Single Label approach -->
|
|
1096
|
+
<Label class="rounded-full-12 bg-brand-500 fa-solid fa-plus text-center text-xl text-white" />
|
|
1097
|
+
|
|
1098
|
+
<!-- ALTERNATIVE: View wrapper (more verbose) -->
|
|
1099
|
+
<View class="bg-brand-500 h-12 w-12 rounded-full">
|
|
1100
|
+
<Label class="center fas fa-plus text-xl text-white" />
|
|
1101
|
+
</View>
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
#### Header with Icon Buttons
|
|
1105
|
+
|
|
1106
|
+
```xml
|
|
1107
|
+
<!-- Container with auto width - items will be centered -->
|
|
1108
|
+
<View class="horizontal mx-3 mt-3 w-auto">
|
|
1109
|
+
<!-- Icon buttons with horizontal spacing -->
|
|
1110
|
+
<Label id="backButton" class="rounded-full-12 fa-solid fa-arrow-left mx-1 bg-white/20 text-center text-xl text-white" />
|
|
1111
|
+
<Label id="shareButton" class="rounded-full-12 fa-solid fa-share-nodes mx-1 bg-white/20 text-center text-xl text-white" />
|
|
1112
|
+
<Label id="favoriteButton" class="rounded-full-12 fa-solid fa-heart mx-1 bg-white/20 text-center text-xl text-white" />
|
|
1113
|
+
</View>
|
|
1114
|
+
|
|
1115
|
+
<!-- To shift all items to one side, add ml-xx or mr-xx to the container -->
|
|
1116
|
+
<View class="horizontal ml-0 mr-3 mt-3 w-auto">
|
|
1117
|
+
<Label class="rounded-full-12 fa-solid fa-arrow-left ... mx-1 bg-white/20" />
|
|
1118
|
+
<Label class="rounded-full-12 fa-solid fa-share-nodes ... mx-1 bg-white/20" />
|
|
1119
|
+
</View>
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
**Key pattern:**
|
|
1123
|
+
- `horizontal w-auto` - Container takes width of children, centers them in available space
|
|
1124
|
+
- `mx-1` on each child - Consistent horizontal spacing between icons
|
|
1125
|
+
- `ml-0`/`mr-3` on container - Shifts the entire group to left/right edge
|
|
1126
|
+
|
|
1127
|
+
#### Icon Badge
|
|
1128
|
+
|
|
1129
|
+
```xml
|
|
1130
|
+
<View class="relative">
|
|
1131
|
+
<Label class="fas fa-bell text-xl" />
|
|
1132
|
+
<View class="absolute -right-1 -top-1 h-4 w-4 rounded-full bg-red-500">
|
|
1133
|
+
<Label class="center text-xs font-bold text-white" text="3" />
|
|
1134
|
+
</View>
|
|
1135
|
+
</View>
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
#### Icon Group
|
|
1139
|
+
|
|
1140
|
+
```xml
|
|
1141
|
+
<View class="horizontal">
|
|
1142
|
+
<Label class="fab fa-twitter mr-4 text-2xl text-blue-400" />
|
|
1143
|
+
<Label class="fab fa-facebook mr-4 text-2xl text-blue-600" />
|
|
1144
|
+
<Label class="fab fa-instagram mr-4 text-2xl text-pink-500" />
|
|
1145
|
+
<Label class="fab fa-github text-2xl text-gray-800" />
|
|
1146
|
+
</View>
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
---
|
|
1150
|
+
|
|
1151
|
+
## 6. Accessibility
|
|
1152
|
+
|
|
1153
|
+
### Accessibility Labels
|
|
1154
|
+
|
|
1155
|
+
All interactive elements should have accessibility labels:
|
|
1156
|
+
|
|
1157
|
+
```xml
|
|
1158
|
+
<!-- Button with label -->
|
|
1159
|
+
<Button class="bg-brand-500 text-white" title="Save" accessibilityLabel="Save changes" />
|
|
1160
|
+
|
|
1161
|
+
<!-- Icon button with label (simplified) -->
|
|
1162
|
+
<Label class="rounded-full-12 bg-brand-500 fa-solid fa-plus text-center text-white" accessibilityLabel="Add new item" />
|
|
1163
|
+
|
|
1164
|
+
<!-- Image with label -->
|
|
1165
|
+
<ImageView image="/images/avatar.jpg" accessibilityLabel="User avatar" />
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
### Touch Target Sizes
|
|
1169
|
+
|
|
1170
|
+
Ensure touch targets are at least 44dp for iOS and 48dp for Android:
|
|
1171
|
+
|
|
1172
|
+
```xml
|
|
1173
|
+
<!-- Minimum touch target (44dp) -->
|
|
1174
|
+
<Button class="min-w-44 min-h-44 bg-brand-500" title="Button" />
|
|
1175
|
+
|
|
1176
|
+
<!-- Icon button with proper touch target (simplified) -->
|
|
1177
|
+
<Label class="rounded-full-12 fa-solid fa-cog text-center text-xl" accessibilityLabel="Settings" />
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
### Color Contrast
|
|
1181
|
+
|
|
1182
|
+
Ensure sufficient color contrast for text:
|
|
1183
|
+
|
|
1184
|
+
```xml
|
|
1185
|
+
<!-- Good contrast examples -->
|
|
1186
|
+
<View class="bg-white">
|
|
1187
|
+
<Label class="text-gray-900" text="Dark text on white background" />
|
|
1188
|
+
</View>
|
|
1189
|
+
|
|
1190
|
+
<View class="bg-gray-900">
|
|
1191
|
+
<Label class="text-white" text="White text on dark background" />
|
|
1192
|
+
</View>
|
|
1193
|
+
|
|
1194
|
+
<View class="bg-brand-500">
|
|
1195
|
+
<Label class="font-semibold text-white" text="White text on brand color" />
|
|
1196
|
+
</View>
|
|
1197
|
+
```
|
|
1198
|
+
|
|
1199
|
+
### Screen Reader Support
|
|
1200
|
+
|
|
1201
|
+
```xml
|
|
1202
|
+
<!-- Hide decorative elements -->
|
|
1203
|
+
<View class="absolute right-0 top-0" accessibilityHidden="true">
|
|
1204
|
+
<Label class="fas fa-star text-yellow-500" />
|
|
1205
|
+
</View>
|
|
1206
|
+
|
|
1207
|
+
<!-- Provide hints for complex controls -->
|
|
1208
|
+
<Slider accessibilityLabel="Volume" accessibilityHint="Adjust the volume level" accessibilityValue="50 percent" />
|
|
1209
|
+
|
|
1210
|
+
<!-- State changes -->
|
|
1211
|
+
<Switch id="notificationSwitch" accessibilityLabel="Enable notifications" />
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
```javascript
|
|
1215
|
+
// Update accessibility value on state change
|
|
1216
|
+
$.notificationSwitch.addEventListener('change', (e) => {
|
|
1217
|
+
$.notificationSwitch.accessibilityValue = e.value ? 'On' : 'Off'
|
|
1218
|
+
})
|
|
1219
|
+
```
|
|
1220
|
+
|
|
1221
|
+
---
|
|
1222
|
+
|
|
1223
|
+
## 7. Performance Best Practices
|
|
1224
|
+
|
|
1225
|
+
### ListView Performance
|
|
1226
|
+
|
|
1227
|
+
**CRITICAL**: Never use `Ti.UI.SIZE` in ListView templates - causes jerky scrolling.
|
|
1228
|
+
|
|
1229
|
+
```xml
|
|
1230
|
+
<!-- BAD - Causes performance issues -->
|
|
1231
|
+
<ItemTemplate name="bad">
|
|
1232
|
+
<Label bindId="title" height="Ti.UI.SIZE" />
|
|
1233
|
+
</ItemTemplate>
|
|
1234
|
+
|
|
1235
|
+
<!-- GOOD - Use fixed heights -->
|
|
1236
|
+
<ItemTemplate name="good">
|
|
1237
|
+
<Label bindId="title" height="40" />
|
|
1238
|
+
</ItemTemplate>
|
|
1239
|
+
```
|
|
1240
|
+
|
|
1241
|
+
### View Recycling
|
|
1242
|
+
|
|
1243
|
+
ListViews recycle views. Always update via data, not direct access:
|
|
1244
|
+
|
|
1245
|
+
```javascript
|
|
1246
|
+
// BAD - Direct modification
|
|
1247
|
+
function handleClick(e) {
|
|
1248
|
+
e.source.text = "Updated"
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// GOOD - Update via data
|
|
1252
|
+
function handleClick(e) {
|
|
1253
|
+
const item = e.section.getItemAt(e.itemIndex)
|
|
1254
|
+
item.title.text = "Updated"
|
|
1255
|
+
e.section.updateItemAt(e.itemIndex, item)
|
|
1256
|
+
}
|
|
1257
|
+
```
|
|
1258
|
+
|
|
1259
|
+
### Batch Updates
|
|
1260
|
+
|
|
1261
|
+
Use `applyProperties` to reduce bridge crossings:
|
|
1262
|
+
|
|
1263
|
+
```javascript
|
|
1264
|
+
// BAD - Multiple property updates
|
|
1265
|
+
view.backgroundColor = 'red'
|
|
1266
|
+
view.width = 100
|
|
1267
|
+
view.height = 50
|
|
1268
|
+
|
|
1269
|
+
// GOOD - Single batch update
|
|
1270
|
+
view.applyProperties({
|
|
1271
|
+
backgroundColor: 'red',
|
|
1272
|
+
width: 100,
|
|
1273
|
+
height: 50
|
|
1274
|
+
})
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
### Minimize Template Count
|
|
1278
|
+
|
|
1279
|
+
Fewer templates = better native cell reuse:
|
|
1280
|
+
|
|
1281
|
+
```xml
|
|
1282
|
+
<!-- GOOD - One flexible template -->
|
|
1283
|
+
<ItemTemplate name="flexible">
|
|
1284
|
+
<ImageView bindId="icon" />
|
|
1285
|
+
<Label bindId="title" />
|
|
1286
|
+
<Label bindId="subtitle" /> <!-- Hidden if not needed -->
|
|
1287
|
+
</ItemTemplate>
|
|
1288
|
+
|
|
1289
|
+
<!-- BAD - Multiple similar templates -->
|
|
1290
|
+
<ItemTemplate name="withIcon">...</ItemTemplate>
|
|
1291
|
+
<ItemTemplate name="withoutIcon">...</ItemTemplate>
|
|
1292
|
+
<ItemTemplate name="withSubtitle">...</ItemTemplate>
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
---
|
|
1296
|
+
|
|
1297
|
+
## 8. Platform-Specific Patterns
|
|
1298
|
+
|
|
1299
|
+
### iOS Patterns
|
|
1300
|
+
|
|
1301
|
+
#### Navigation Window
|
|
1302
|
+
|
|
1303
|
+
```xml
|
|
1304
|
+
<NavigationWindow id="navWindow">
|
|
1305
|
+
<Window class="bg-white">
|
|
1306
|
+
<View>
|
|
1307
|
+
<Label class="text-lg font-semibold" text="Main Screen" />
|
|
1308
|
+
<Button id="pushBtn" class="mt-4" title="Push Next Screen" />
|
|
1309
|
+
</View>
|
|
1310
|
+
</Window>
|
|
1311
|
+
</NavigationWindow>
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
```javascript
|
|
1315
|
+
// Push new window
|
|
1316
|
+
$.pushBtn.addEventListener('click', () => {
|
|
1317
|
+
const nextWin = Ti.UI.createWindow({
|
|
1318
|
+
title: 'Next Screen',
|
|
1319
|
+
backgroundColor: 'white'
|
|
1320
|
+
})
|
|
1321
|
+
$.navWindow.openWindow(nextWin, { animated: true })
|
|
1322
|
+
})
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
#### Tab Bar
|
|
1326
|
+
|
|
1327
|
+
```xml
|
|
1328
|
+
<TabGroup id="tabGroup">
|
|
1329
|
+
<Tab id="homeTab" icon="fa-home.png" title="Home">
|
|
1330
|
+
<Window class="bg-white">
|
|
1331
|
+
<ScrollView class="h-full w-full">
|
|
1332
|
+
<Label class="text-lg font-semibold" text="Home Screen" />
|
|
1333
|
+
</ScrollView>
|
|
1334
|
+
</Window>
|
|
1335
|
+
</Tab>
|
|
1336
|
+
|
|
1337
|
+
<Tab id="searchTab" icon="fa-search.png" title="Search">
|
|
1338
|
+
<Window class="bg-white">
|
|
1339
|
+
<ScrollView class="h-full w-full">
|
|
1340
|
+
<Label class="text-lg font-semibold" text="Search Screen" />
|
|
1341
|
+
</ScrollView>
|
|
1342
|
+
</Window>
|
|
1343
|
+
</Tab>
|
|
1344
|
+
|
|
1345
|
+
<Tab id="profileTab" icon="fa-user.png" title="Profile">
|
|
1346
|
+
<Window class="bg-white">
|
|
1347
|
+
<ScrollView class="h-full w-full">
|
|
1348
|
+
<Label class="text-lg font-semibold" text="Profile Screen" />
|
|
1349
|
+
</ScrollView>
|
|
1350
|
+
</Window>
|
|
1351
|
+
</Tab>
|
|
1352
|
+
</TabGroup>
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
#### iOS Swipe Actions
|
|
1356
|
+
|
|
1357
|
+
```javascript
|
|
1358
|
+
const section = $.myList.sections[0]
|
|
1359
|
+
|
|
1360
|
+
// Define edit actions
|
|
1361
|
+
const deleteAction = Ti.UI.iOS.createListViewDeleteOptions({
|
|
1362
|
+
title: 'Delete'
|
|
1363
|
+
})
|
|
1364
|
+
|
|
1365
|
+
const moreAction = Ti.UI.iOS.createListViewEditAction({
|
|
1366
|
+
title: 'More',
|
|
1367
|
+
backgroundColor: 'blue',
|
|
1368
|
+
style: Ti.UI.iOS.LIST_VIEW_EDIT_ACTION_STYLE_NORMAL
|
|
1369
|
+
})
|
|
1370
|
+
|
|
1371
|
+
// Enable editing
|
|
1372
|
+
section.editActions = [deleteAction, moreAction]
|
|
1373
|
+
section.canEdit = true
|
|
1374
|
+
|
|
1375
|
+
// Handle actions
|
|
1376
|
+
$.myList.addEventListener('editaction', (e) => {
|
|
1377
|
+
if (e.action === deleteAction) {
|
|
1378
|
+
section.deleteItemsAt(e.itemIndex, 1)
|
|
1379
|
+
} else if (e.action === moreAction) {
|
|
1380
|
+
// Handle more action
|
|
1381
|
+
}
|
|
1382
|
+
})
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
### Android Patterns
|
|
1386
|
+
|
|
1387
|
+
#### Action Bar
|
|
1388
|
+
|
|
1389
|
+
```javascript
|
|
1390
|
+
const activity = Ti.Android.currentActivity
|
|
1391
|
+
|
|
1392
|
+
activity.onCreateOptionsMenu = (e) => {
|
|
1393
|
+
const menu = e.menu
|
|
1394
|
+
|
|
1395
|
+
const searchItem = menu.add({
|
|
1396
|
+
title: 'Search',
|
|
1397
|
+
icon: Ti.Android.R.drawable.ic_menu_search,
|
|
1398
|
+
showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
|
|
1399
|
+
})
|
|
1400
|
+
|
|
1401
|
+
const settingsItem = menu.add({
|
|
1402
|
+
title: 'Settings',
|
|
1403
|
+
icon: Ti.Android.R.drawable.ic_menu_preferences,
|
|
1404
|
+
showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
|
|
1405
|
+
})
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
activity.onOptionsItemSelected = (e) => {
|
|
1409
|
+
switch (e.itemId) {
|
|
1410
|
+
case 0:
|
|
1411
|
+
// Handle search
|
|
1412
|
+
return true
|
|
1413
|
+
case 1:
|
|
1414
|
+
// Handle settings
|
|
1415
|
+
return true
|
|
1416
|
+
}
|
|
1417
|
+
return false
|
|
1418
|
+
}
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
#### Back Button Handling
|
|
1422
|
+
|
|
1423
|
+
```javascript
|
|
1424
|
+
$.window.addEventListener('androidback', (e) => {
|
|
1425
|
+
e.cancelBubble = true
|
|
1426
|
+
|
|
1427
|
+
if (canGoBack()) {
|
|
1428
|
+
closeCurrentWindow()
|
|
1429
|
+
} else {
|
|
1430
|
+
showExitConfirmation()
|
|
1431
|
+
}
|
|
1432
|
+
})
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
#### Material Design Theme
|
|
1436
|
+
|
|
1437
|
+
```xml
|
|
1438
|
+
<!-- tiapp.xml -->
|
|
1439
|
+
<android xmlns:android="http://schemas.android.com/apk/res/android">
|
|
1440
|
+
<manifest>
|
|
1441
|
+
<application android:theme="@style/Theme.Titanium.Material3.DayNight"/>
|
|
1442
|
+
</manifest>
|
|
1443
|
+
</android>
|
|
1444
|
+
```
|
|
1445
|
+
|
|
1446
|
+
#### Notifications
|
|
1447
|
+
|
|
1448
|
+
```javascript
|
|
1449
|
+
// Create notification channel (Android 8.0+)
|
|
1450
|
+
const channel = Ti.Android.createNotificationChannel({
|
|
1451
|
+
name: 'My Channel',
|
|
1452
|
+
id: 'my_channel_id',
|
|
1453
|
+
importance: Ti.Android.NOTIFICATION_IMPORTANCE_HIGH
|
|
1454
|
+
})
|
|
1455
|
+
|
|
1456
|
+
Ti.Android.NotificationManager.createNotificationChannel(channel)
|
|
1457
|
+
|
|
1458
|
+
// Create and show notification
|
|
1459
|
+
const notification = Ti.Android.createNotification({
|
|
1460
|
+
number: 1,
|
|
1461
|
+
channelId: 'my_channel_id',
|
|
1462
|
+
contentTitle: 'New Message',
|
|
1463
|
+
contentText: 'You have a new message'
|
|
1464
|
+
})
|
|
1465
|
+
|
|
1466
|
+
Ti.Android.NotificationManager.notify(1, notification)
|
|
1467
|
+
```
|
|
1468
|
+
|
|
1469
|
+
---
|
|
1470
|
+
|
|
1471
|
+
## Quick Reference Card
|
|
1472
|
+
|
|
1473
|
+
### Common PurgeTSS Classes
|
|
1474
|
+
|
|
1475
|
+
| Category | Classes | Examples |
|
|
1476
|
+
| --------------- | -------------------------------------------- | ------------------------------- |
|
|
1477
|
+
| **Spacing** | `p-{0-8}`, `m-{0-8}`, `px-{0-8}`, `py-{0-8}` | `p-4`, `mx-2`, `py-6` |
|
|
1478
|
+
| **Colors** | `bg-{color}-{shade}`, `text-{color}-{shade}` | `bg-brand-500`, `text-gray-800` |
|
|
1479
|
+
| **Typography** | `text-{xs,sm,base,lg,xl,2xl,3xl,4xl}` | `text-xl`, `text-2xl` |
|
|
1480
|
+
| **Font Weight** | `font-{light,normal,medium,semibold,bold}` | `font-semibold`, `font-bold` |
|
|
1481
|
+
| **Borders** | `border`, `border-{color}`, `rounded-{size}` | `border-gray-300`, `rounded-lg` |
|
|
1482
|
+
| **Shadows** | `shadow-{sm,md,lg,xl,2xl}` | `shadow-md`, `shadow-lg` |
|
|
1483
|
+
| **Width** | `w-{size}`, `w-{percentage}` | `w-full`, `w-(50%)` |
|
|
1484
|
+
| **Height** | `h-{size}`, `h-screen` | `h-10`, `h-screen` |
|
|
1485
|
+
| **Display** | `hidden`, `visible` | `hidden`, `visible` |
|
|
1486
|
+
| **Icons** | `fas`, `far`, `fab fa-{icon}` | `fas fa-home`, `fab fa-twitter` |
|
|
1487
|
+
|
|
1488
|
+
### Platform Modifiers
|
|
1489
|
+
|
|
1490
|
+
```xml
|
|
1491
|
+
<!-- iOS-only -->
|
|
1492
|
+
<View class="ios:p-4 ios:bg-white">...</View>
|
|
1493
|
+
|
|
1494
|
+
<!-- Android-only -->
|
|
1495
|
+
<View class="android:p-4 android:bg-gray-100">...</View>
|
|
1496
|
+
|
|
1497
|
+
<!-- Platform-specific values -->
|
|
1498
|
+
<View class="ios:bg-white android:bg-gray-100 p-4">...</View>
|
|
1499
|
+
```
|
|
1500
|
+
|
|
1501
|
+
---
|
|
1502
|
+
|
|
1503
|
+
## Best Practices Summary
|
|
1504
|
+
|
|
1505
|
+
1. **Use `dp` units** for cross-platform consistency
|
|
1506
|
+
2. **Prefer ListView over TableView** for large datasets
|
|
1507
|
+
3. **Avoid `Ti.UI.SIZE` in ListViews** - use fixed heights
|
|
1508
|
+
4. **Provide accessibility labels** for all interactive elements
|
|
1509
|
+
5. **Ensure minimum touch target size** of 44dp (iOS) / 48dp (Android)
|
|
1510
|
+
6. **Use semantic color names** for better theming support
|
|
1511
|
+
7. **Test on both platforms** to ensure consistent experience
|
|
1512
|
+
8. **Follow platform conventions** - iOS NavigationWindow, Android Action Bar
|
|
1513
|
+
9. **Use PurgeTSS utility classes** for consistent styling
|
|
1514
|
+
10. **Batch property updates** using `applyProperties()` for better performance
|
|
1515
|
+
11. **Padding classes do NOT work on View** - use margin on children instead
|
|
1516
|
+
12. **Always specify Font Awesome icons** - `fas fa-home`, not just `fas`
|
|
1517
|
+
|
|
1518
|
+
---
|
|
1519
|
+
|
|
1520
|
+
## Additional Resources
|
|
1521
|
+
|
|
1522
|
+
- [PurgeTSS Documentation](https://purgetss.com)
|
|
1523
|
+
- [Titanium SDK Documentation](https://docs.appcelerator.com)
|
|
1524
|
+
- [iOS Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)
|
|
1525
|
+
- [Material Design Guidelines](https://material.io/design)
|
|
1526
|
+
- [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/WAI/WCAG21/quickref/)
|