@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,479 @@
|
|
|
1
|
+
# Platform and Device Modifiers
|
|
2
|
+
|
|
3
|
+
Platform and Device modifiers (also called variants or prefixes) allow you to specify different styles for an element depending on the platform (iOS or Android) and device (tablet or handheld) that the app is running on.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Platform and Device Modifiers](#platform-and-device-modifiers)
|
|
8
|
+
- [Table of Contents](#table-of-contents)
|
|
9
|
+
- [🚨 CRITICAL: Platform-Specific Properties Require Modifiers](#-critical-platform-specific-properties-require-modifiers)
|
|
10
|
+
- [Available Modifiers](#available-modifiers)
|
|
11
|
+
- [Platform Modifiers](#platform-modifiers)
|
|
12
|
+
- [Device (Form Factor) Modifiers](#device-form-factor-modifiers)
|
|
13
|
+
- [Usage in XML](#usage-in-xml)
|
|
14
|
+
- [Basic Platform Targeting](#basic-platform-targeting)
|
|
15
|
+
- [Combining with Arbitrary Values](#combining-with-arbitrary-values)
|
|
16
|
+
- [Multiple Modifiers on Same Element](#multiple-modifiers-on-same-element)
|
|
17
|
+
- [Generated TSS Output](#generated-tss-output)
|
|
18
|
+
- [Custom Conditional Modifiers](#custom-conditional-modifiers)
|
|
19
|
+
- [Syntax](#syntax)
|
|
20
|
+
- [Example with iPhone X Notch](#example-with-iphone-x-notch)
|
|
21
|
+
- [Setting Up Conditional Variables](#setting-up-conditional-variables)
|
|
22
|
+
- [Modifiers in config.cjs](#modifiers-in-configcjs)
|
|
23
|
+
- [Custom Class with Platform Variants](#custom-class-with-platform-variants)
|
|
24
|
+
- [Ti Element with Platform and Device Variants](#ti-element-with-platform-and-device-variants)
|
|
25
|
+
- [Complex Example with All Variants](#complex-example-with-all-variants)
|
|
26
|
+
- [Platform-Specific Properties](#platform-specific-properties)
|
|
27
|
+
- [iOS-Specific Properties](#ios-specific-properties)
|
|
28
|
+
- [Android-Specific Properties](#android-specific-properties)
|
|
29
|
+
- [Interaction Modifiers](#interaction-modifiers)
|
|
30
|
+
- [Active State Modifier](#active-state-modifier)
|
|
31
|
+
- [Best Practices](#best-practices)
|
|
32
|
+
- [1. Use Modifiers for Platform Differences](#1-use-modifiers-for-platform-differences)
|
|
33
|
+
- [2. Combine with Default Styles](#2-combine-with-default-styles)
|
|
34
|
+
- [3. Use Device Modifiers for Layout Adaptation](#3-use-device-modifiers-for-layout-adaptation)
|
|
35
|
+
- [4. Leverage config.cjs for Complex Platform Logic](#4-leverage-configcjs-for-complex-platform-logic)
|
|
36
|
+
- [Common Patterns](#common-patterns)
|
|
37
|
+
- [iOS Shadow / Android Elevation](#ios-shadow--android-elevation)
|
|
38
|
+
- [Different Font Sizes per Platform](#different-font-sizes-per-platform)
|
|
39
|
+
- [Safe Area Handling for iPhone X](#safe-area-handling-for-iphone-x)
|
|
40
|
+
- [Adaptive Spacing](#adaptive-spacing)
|
|
41
|
+
- [Platform-Specific Colors](#platform-specific-colors)
|
|
42
|
+
- [Troubleshooting](#troubleshooting)
|
|
43
|
+
- [Modifiers Not Applying](#modifiers-not-applying)
|
|
44
|
+
- [Conditional Modifiers Not Working](#conditional-modifiers-not-working)
|
|
45
|
+
- [Platform Detection Issues](#platform-detection-issues)
|
|
46
|
+
- [Modifier Reference Table](#modifier-reference-table)
|
|
47
|
+
- [Complete Example](#complete-example)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🚨 CRITICAL: Platform-Specific Properties Require Modifiers
|
|
52
|
+
|
|
53
|
+
:::danger NEVER use platform-specific properties directly
|
|
54
|
+
**Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties WITHOUT modifiers will:**
|
|
55
|
+
|
|
56
|
+
1. **Add iOS code to Android builds** → compilation failures
|
|
57
|
+
2. **Add Android code to iOS builds** → compilation failures
|
|
58
|
+
3. **Create invalid cross-platform code**
|
|
59
|
+
4. **Confuse developers** who don't understand the error
|
|
60
|
+
|
|
61
|
+
**REAL EXAMPLE of the damage:**
|
|
62
|
+
```javascript
|
|
63
|
+
// ❌ WRONG - Adds Ti.UI.iOS to Android project
|
|
64
|
+
"#mainWindow": {
|
|
65
|
+
statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT // FAILS on Android!
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Error message:**
|
|
70
|
+
```
|
|
71
|
+
[ERROR] Ti.UI iOS is not defined
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**CORRECT approaches:**
|
|
75
|
+
|
|
76
|
+
**Option 1 - TSS modifier (RECOMMENDED for PurgeTSS):**
|
|
77
|
+
```tss
|
|
78
|
+
// ✅ CORRECT - Only adds to iOS
|
|
79
|
+
"#mainWindow[platform=ios]": {
|
|
80
|
+
statusBarStyle: Ti.UI.iOS.StatusBar.LIST_VIEW_EDIT_ACTION_STYLE_NORMAL
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Option 2 - Platform modifier classes:**
|
|
85
|
+
```xml
|
|
86
|
+
<!-- ✅ CORRECT -->
|
|
87
|
+
<Window class="ios:status-bar-light android:status-bar-dark">
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Option 3 - Conditional controller logic:**
|
|
91
|
+
```javascript
|
|
92
|
+
if (OS_IOS) {
|
|
93
|
+
$.mainWindow.statusBarStyle = Ti.UI.iOS.StatusBar.LIGHT_CONTENT
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Common platform-specific properties that REQUIRE modifiers:**
|
|
98
|
+
- iOS: `statusBarStyle`, `modalStyle`, `modalTransitionStyle`, `systemButton`, any `Ti.UI.iOS.*`
|
|
99
|
+
- Android: `actionBar` config, any `Ti.Android.*` constant
|
|
100
|
+
|
|
101
|
+
**When suggesting platform-specific code, ALWAYS:**
|
|
102
|
+
1. Check if user's project supports that platform
|
|
103
|
+
2. Use `[platform=ios]` or `[platform=android]` TSS modifier
|
|
104
|
+
3. OR use PurgeTSS platform classes: `ios:prop-*`, `android:prop-*`
|
|
105
|
+
4. OR use conditional `OS_IOS` / `OS_ANDROID` checks in controllers
|
|
106
|
+
|
|
107
|
+
:::
|
|
108
|
+
|
|
109
|
+
## Available Modifiers
|
|
110
|
+
|
|
111
|
+
### Platform Modifiers
|
|
112
|
+
|
|
113
|
+
Target specific OS engines directly in the XML:
|
|
114
|
+
|
|
115
|
+
- **`ios:`** - Applies only to Apple devices (iPhone, iPad)
|
|
116
|
+
- **`android:`** - Applies only to Android devices
|
|
117
|
+
|
|
118
|
+
```xml
|
|
119
|
+
<View class="ios:mt-10 android:mt-5 mt-4" />
|
|
120
|
+
<Label class="ios:text-blue-600 android:text-gray-600" />
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Device (Form Factor) Modifiers
|
|
124
|
+
|
|
125
|
+
Target device categories based on screen size:
|
|
126
|
+
|
|
127
|
+
- **`tablet:`** - iPads and Android Tablets
|
|
128
|
+
- **`handheld:`** - Phones (iPhone and Android phones)
|
|
129
|
+
|
|
130
|
+
```xml
|
|
131
|
+
<View class="tablet:w-1/2 handheld:w-full w-screen" />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Usage in XML
|
|
135
|
+
|
|
136
|
+
### Basic Platform Targeting
|
|
137
|
+
|
|
138
|
+
```xml
|
|
139
|
+
<Alloy>
|
|
140
|
+
<Window class="tablet:bg-green-500 handheld:bg-blue-500">
|
|
141
|
+
<View class="tablet:bg-green-100 handheld:bg-blue-100 h-32">
|
|
142
|
+
<Label class="ios:text-blue-800 ios:text-xl android:text-green-800 android:text-2xl h-auto w-screen text-center">
|
|
143
|
+
This is a Test
|
|
144
|
+
</Label>
|
|
145
|
+
</View>
|
|
146
|
+
</Window>
|
|
147
|
+
</Alloy>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Combining with Arbitrary Values
|
|
151
|
+
|
|
152
|
+
You can combine platform/device modifiers with arbitrary values for precise control:
|
|
153
|
+
|
|
154
|
+
```xml
|
|
155
|
+
<Label class="ios:bg-(#53606b) ios:text-(20px) android:bg-(#8fb63e) android:text-(24px)" />
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Multiple Modifiers on Same Element
|
|
159
|
+
|
|
160
|
+
```xml
|
|
161
|
+
<View class="ios:tablet:bg-white ios:handheld:bg-gray-100 android:bg-gray-200" />
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Generated TSS Output
|
|
165
|
+
|
|
166
|
+
PurgeTSS generates platform-specific selectors in `app.tss`:
|
|
167
|
+
|
|
168
|
+
```tss
|
|
169
|
+
/* Platform and Device Modifiers */
|
|
170
|
+
'.android:text-2xl[platform=android]': { font: { fontSize: 24 } }
|
|
171
|
+
'.android:text-green-800[platform=android]': { color: '#166534', textColor: '#166534' }
|
|
172
|
+
'.handheld:bg-blue-100[formFactor=handheld]': { backgroundColor: '#dbeafe' }
|
|
173
|
+
'.handheld:bg-blue-500[formFactor=handheld]': { backgroundColor: '#3b82f6' }
|
|
174
|
+
'.ios:text-blue-800[platform=ios]': { color: '#1e40af', textColor: '#1e40af' }
|
|
175
|
+
'.ios:text-xl[platform=ios]': { font: { fontSize: 20 } }
|
|
176
|
+
'.tablet:bg-green-100[formFactor=tablet]': { backgroundColor: '#dcfce7' }
|
|
177
|
+
'.tablet:bg-green-500[formFactor=tablet]': { backgroundColor: '#22c55e' }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Custom Conditional Modifiers
|
|
181
|
+
|
|
182
|
+
You can create custom conditional modifiers using global variables:
|
|
183
|
+
|
|
184
|
+
### Syntax
|
|
185
|
+
|
|
186
|
+
```xml
|
|
187
|
+
<View class="[if=Alloy.Globals.isIPhoneX]:pb-24" />
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The `[if=...]` syntax evaluates Alloy.Globals or controller arguments.
|
|
191
|
+
|
|
192
|
+
### Example with iPhone X Notch
|
|
193
|
+
|
|
194
|
+
```xml
|
|
195
|
+
<View class="[if=Alloy.Globals.iPhoneX]:bottom-(34) [if=Alloy.Globals.iPhoneX]:bg-white" />
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Setting Up Conditional Variables
|
|
199
|
+
|
|
200
|
+
In your controller or `alloy.js`:
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// Detect iPhone X
|
|
204
|
+
if (OS_IOS && Ti.Platform.displayCaps.platformHeight === 812 && Ti.Platform.displayCaps.platformWidth === 375) {
|
|
205
|
+
Alloy.Globals.isIPhoneX = true;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Modifiers in config.cjs
|
|
210
|
+
|
|
211
|
+
Platform and device modifiers can also be defined within `config.cjs` for centralized theme logic.
|
|
212
|
+
|
|
213
|
+
### Custom Class with Platform Variants
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
'.my-view': {
|
|
217
|
+
DEFAULT: {
|
|
218
|
+
apply: 'bg-white'
|
|
219
|
+
},
|
|
220
|
+
ios: {
|
|
221
|
+
apply: 'shadow-lg'
|
|
222
|
+
},
|
|
223
|
+
android: {
|
|
224
|
+
apply: 'elevation-4'
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Ti Element with Platform and Device Variants
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
TextField: {
|
|
233
|
+
DEFAULT: {
|
|
234
|
+
top: 10,
|
|
235
|
+
left: 20,
|
|
236
|
+
right: 20,
|
|
237
|
+
bottom: 0
|
|
238
|
+
},
|
|
239
|
+
'[if=Alloy.Globals.iPhoneX]': {
|
|
240
|
+
bottom: 'Alloy.CFG.iPhoneXNotchSize'
|
|
241
|
+
},
|
|
242
|
+
android: {
|
|
243
|
+
touchFeedback: true
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Complex Example with All Variants
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
module.exports = {
|
|
252
|
+
theme: {
|
|
253
|
+
'.feature-card': {
|
|
254
|
+
DEFAULT: {
|
|
255
|
+
width: 'Ti.UI.FILL',
|
|
256
|
+
height: '100px',
|
|
257
|
+
backgroundColor: '#ffffff'
|
|
258
|
+
},
|
|
259
|
+
ios: {
|
|
260
|
+
borderRadius: 12
|
|
261
|
+
},
|
|
262
|
+
android: {
|
|
263
|
+
borderRadius: 8
|
|
264
|
+
},
|
|
265
|
+
tablet: {
|
|
266
|
+
width: '50%'
|
|
267
|
+
},
|
|
268
|
+
handheld: {
|
|
269
|
+
width: '100%'
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Platform-Specific Properties
|
|
277
|
+
|
|
278
|
+
Some Titanium properties are platform-specific and should be used with platform modifiers:
|
|
279
|
+
|
|
280
|
+
### iOS-Specific Properties
|
|
281
|
+
|
|
282
|
+
```xml
|
|
283
|
+
<View class="ios:clip-mode-disabled" />
|
|
284
|
+
<Label class="ios:adjusts-font-size-to-fit" />
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Android-Specific Properties
|
|
288
|
+
|
|
289
|
+
```xml
|
|
290
|
+
<View class="android:touch-feedback" />
|
|
291
|
+
<TextField class="android:soft-keyboard-hide-on-focus" />
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Interaction Modifiers
|
|
295
|
+
|
|
296
|
+
### Active State Modifier
|
|
297
|
+
|
|
298
|
+
Style applied while the element is being touched/clicked:
|
|
299
|
+
|
|
300
|
+
```xml
|
|
301
|
+
<Button class="active:bg-brand-700 active:scale-95" />
|
|
302
|
+
<View class="active:opacity-80" onTouchstart="doSomething" />
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
:::info
|
|
306
|
+
The `active:` modifier works with elements that have touch event handlers. The style is applied during the touch interaction and removed when the touch ends.
|
|
307
|
+
:::
|
|
308
|
+
|
|
309
|
+
## Best Practices
|
|
310
|
+
|
|
311
|
+
### 1. Use Modifiers for Platform Differences
|
|
312
|
+
|
|
313
|
+
```xml
|
|
314
|
+
<!-- Good: Platform-specific styling -->
|
|
315
|
+
<View class="ios:shadow-lg android:elevation-4 bg-white" />
|
|
316
|
+
|
|
317
|
+
<!-- Avoid: Creating separate views -->
|
|
318
|
+
<Window>
|
|
319
|
+
<View platform="ios" class="bg-white shadow-lg" />
|
|
320
|
+
<View platform="android" class="elevation-4 bg-white" />
|
|
321
|
+
</Window>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 2. Combine with Default Styles
|
|
325
|
+
|
|
326
|
+
Always provide a default style, then override with modifiers:
|
|
327
|
+
|
|
328
|
+
```xml
|
|
329
|
+
<!-- Good: Default + overrides -->
|
|
330
|
+
<Label class="ios:text-xl android:text-2xl text-lg text-gray-800" />
|
|
331
|
+
|
|
332
|
+
<!-- Less clear: Only modifiers -->
|
|
333
|
+
<Label class="ios:text-xl android:text-2xl ios:text-gray-800 android:text-gray-800" />
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 3. Use Device Modifiers for Layout Adaptation
|
|
337
|
+
|
|
338
|
+
```xml
|
|
339
|
+
<!-- Adaptive layout based on form factor -->
|
|
340
|
+
<View class="horizontal w-screen">
|
|
341
|
+
<View class="tablet:w-1/3 handheld:w-full bg-white">
|
|
342
|
+
<!-- Sidebar on tablet, full content on phone -->
|
|
343
|
+
</View>
|
|
344
|
+
<View class="tablet:w-2/3 handheld:w-full bg-gray-100">
|
|
345
|
+
<!-- Main content -->
|
|
346
|
+
</View>
|
|
347
|
+
</View>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### 4. Leverage config.cjs for Complex Platform Logic
|
|
351
|
+
|
|
352
|
+
For complex platform-specific rules, define them in `config.cjs` rather than cluttering XML:
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
// In config.cjs
|
|
356
|
+
'.navigation-header': {
|
|
357
|
+
DEFAULT: { height: 56 },
|
|
358
|
+
ios: { height: 44 },
|
|
359
|
+
tablet: { height: 64 }
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// In XML - clean and simple
|
|
363
|
+
<View class="navigation-header" />
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Common Patterns
|
|
367
|
+
|
|
368
|
+
### iOS Shadow / Android Elevation
|
|
369
|
+
|
|
370
|
+
```xml
|
|
371
|
+
<View class="ios:shadow-md android:elevation-2 rounded-lg bg-white" />
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Different Font Sizes per Platform
|
|
375
|
+
|
|
376
|
+
```xml
|
|
377
|
+
<Label class="ios:text-base android:text-sm font-semibold text-gray-800" />
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Safe Area Handling for iPhone X
|
|
381
|
+
|
|
382
|
+
```xml
|
|
383
|
+
<View class="[if=Alloy.Globals.isIPhoneX]:pt-12 pt-4" />
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Adaptive Spacing
|
|
387
|
+
|
|
388
|
+
```xml
|
|
389
|
+
<View class="tablet:p-8 handheld:p-4 p-4" />
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Platform-Specific Colors
|
|
393
|
+
|
|
394
|
+
```xml
|
|
395
|
+
<Button class="bg-brand-500 ios:bg-blue-600 android:bg-green-600 text-white" />
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Troubleshooting
|
|
399
|
+
|
|
400
|
+
### Modifiers Not Applying
|
|
401
|
+
|
|
402
|
+
**Problem**: Platform modifier classes not generating in `app.tss`
|
|
403
|
+
|
|
404
|
+
**Solution**: Ensure `purge.mode` is set to `'all'` in `config.cjs`:
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
module.exports = {
|
|
408
|
+
purge: {
|
|
409
|
+
mode: 'all' // Required to parse all class attributes
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Conditional Modifiers Not Working
|
|
415
|
+
|
|
416
|
+
**Problem**: `[if=Alloy.Globals...]` modifiers not applying
|
|
417
|
+
|
|
418
|
+
**Solution**: Verify the global variable exists before the view is created:
|
|
419
|
+
|
|
420
|
+
```javascript
|
|
421
|
+
// In alloy.js or controller
|
|
422
|
+
Alloy.Globals.isIPhoneX = /* detection logic */;
|
|
423
|
+
|
|
424
|
+
console.log(Alloy.Globals.isIPhoneX); // Should be true/false
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Platform Detection Issues
|
|
428
|
+
|
|
429
|
+
**Problem**: Styles applying to wrong platform
|
|
430
|
+
|
|
431
|
+
**Solution**: Check generated `app.tss` for correct selector:
|
|
432
|
+
|
|
433
|
+
```tss
|
|
434
|
+
/* Should be platform-specific selector */
|
|
435
|
+
'.ios:bg-blue-500[platform=ios]': { backgroundColor: '#3b82f6' }
|
|
436
|
+
'.android:bg-blue-500[platform=android]': { backgroundColor: '#3b82f6' }
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## Modifier Reference Table
|
|
440
|
+
|
|
441
|
+
| Modifier | Target | Example | Generated Selector |
|
|
442
|
+
| --------------- | -------------------- | ------------------------------------ | ------------------------------ |
|
|
443
|
+
| `ios:` | iOS devices only | `ios:bg-blue-500` | `[platform=ios]` |
|
|
444
|
+
| `android:` | Android devices only | `android:bg-green-500` | `[platform=android]` |
|
|
445
|
+
| `tablet:` | Tablets only | `tablet:w-1/2` | `[formFactor=tablet]` |
|
|
446
|
+
| `handheld:` | Phones only | `handheld:w-full` | `[formFactor=handheld]` |
|
|
447
|
+
| `[if=varName]:` | Custom conditional | `[if=Alloy.Globals.isIPhoneX]:pt-12` | `[if=Alloy.Globals.isIPhoneX]` |
|
|
448
|
+
| `active:` | Touch interaction | `active:opacity-80` | `active` state |
|
|
449
|
+
|
|
450
|
+
## Complete Example
|
|
451
|
+
|
|
452
|
+
```xml
|
|
453
|
+
<Alloy>
|
|
454
|
+
<Window class="bg-white">
|
|
455
|
+
<!-- Header with platform-specific styling -->
|
|
456
|
+
<View class="ios:shadow-sm android:elevation-2 h-16 bg-white">
|
|
457
|
+
<Label class="ios:text-xl android:text-lg h-auto w-screen text-center font-bold text-gray-800">
|
|
458
|
+
Platform Demo
|
|
459
|
+
</Label>
|
|
460
|
+
</View>
|
|
461
|
+
|
|
462
|
+
<!-- Adaptive content layout -->
|
|
463
|
+
<View class="tablet:p-8 p-4">
|
|
464
|
+
<View class="horizontal w-screen">
|
|
465
|
+
<!-- Tablet: sidebar, Phone: full width cards -->
|
|
466
|
+
<View class="tablet:w-1/3 handheld:w-full rounded-lg bg-gray-100 p-4">
|
|
467
|
+
<Label text="Sidebar" class="text-center" />
|
|
468
|
+
</View>
|
|
469
|
+
<View class="tablet:w-2/3 handheld:w-full ml-4 rounded-lg bg-white p-4">
|
|
470
|
+
<Label text="Main Content" class="text-center" />
|
|
471
|
+
</View>
|
|
472
|
+
</View>
|
|
473
|
+
</View>
|
|
474
|
+
|
|
475
|
+
<!-- iPhone X safe area handling -->
|
|
476
|
+
<View class="[if=Alloy.Globals.isIPhoneX]:h-8 bg-transparent" />
|
|
477
|
+
</Window>
|
|
478
|
+
</Alloy>
|
|
479
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Smart Mappings & Platform Realities
|
|
2
|
+
|
|
3
|
+
PurgeTSS maps CSS-like utilities to native Titanium properties. Understanding these "Smart Mappings" is key to predictable layouts and cross-platform consistency.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Smart Mappings \& Platform Realities](#smart-mappings--platform-realities)
|
|
8
|
+
- [Table of Contents](#table-of-contents)
|
|
9
|
+
- [1. The "Gap" Utility (Double Spacing)](#1-the-gap-utility-double-spacing)
|
|
10
|
+
- [2. Hybrid Shadows (iOS vs. Android)](#2-hybrid-shadows-ios-vs-android)
|
|
11
|
+
- [3. Grid Container Width](#3-grid-container-width)
|
|
12
|
+
- [4. Native Rotations](#4-native-rotations)
|
|
13
|
+
- [5. Z-Index vs Stacking Order](#5-z-index-vs-stacking-order)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. The "Gap" Utility (Double Spacing)
|
|
18
|
+
In PurgeTSS, `gap` is mapped to **external margins** (`top`, `right`, `bottom`, `left`) because Titanium lacks a native CSS-style gap property.
|
|
19
|
+
- **Behavior**: `.gap-4` adds 16dp to **all** sides of the element.
|
|
20
|
+
- **Critical Difference**: In web CSS, gap only exists *between* elements. In PurgeTSS, two siblings with `.gap-4` will have **32dp** of space between them (16dp from each).
|
|
21
|
+
- **Solution**: Use `.gap-x-` or `.gap-y-` for more granular control, or use specific margins (`ml-`, `mt-`) if you need exact CSS-style spacing.
|
|
22
|
+
|
|
23
|
+
## 2. Hybrid Shadows (iOS vs. Android)
|
|
24
|
+
Shadow utilities (`.shadow-md`, etc.) provide a cross-platform visual depth by mapping different native properties in a single class:
|
|
25
|
+
- **iOS**: Uses `viewShadowOffset`, `viewShadowRadius`, and `viewShadowColor`.
|
|
26
|
+
- **Android**: Uses the `elevation` property.
|
|
27
|
+
- **Z-Order Warning**: On Android, `elevation` also affects the **Z-order** (stacking) of the view, causing it to appear on top of siblings without elevation. This behavior does **not** happen on iOS.
|
|
28
|
+
|
|
29
|
+
## 3. Grid Container Width
|
|
30
|
+
The `.grid` and `.grid-flow-col` classes automatically include `width: '100%'`.
|
|
31
|
+
- **Why**: Since PurgeTSS resets `View` to `SIZE`, a grid container must be forced to `100%` (or `FILL`) so that children using percentage widths (like `.col-span-6`) have a parent dimension to calculate against.
|
|
32
|
+
- **Manual Overrides**: If you need a grid that only occupies the size of its content, you must explicitly use `wh-auto`.
|
|
33
|
+
|
|
34
|
+
## 4. Native Rotations
|
|
35
|
+
The `.rotate-X` utilities map directly to Titanium's `rotate` property.
|
|
36
|
+
- **Anchor**: By default, Titanium rotates around the **center** of the component.
|
|
37
|
+
- **Matrix**: Unlike web CSS where transformations are often chained (e.g., `transform: rotate(45deg) scale(1.5)`), PurgeTSS/Titanium treats these as direct, separate properties of the view.
|
|
38
|
+
|
|
39
|
+
## 5. Z-Index vs Stacking Order
|
|
40
|
+
- **Class**: `.z-10`, `.z-50`, etc.
|
|
41
|
+
- **Mapping**: Maps directly to Titanium's `zIndex` property.
|
|
42
|
+
- **Note**: In Titanium, the order in which views are **added** to a parent determines their base stacking order (last added is on top). `zIndex` should be used sparingly for explicit overlays.
|