@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.
Files changed (120) hide show
  1. package/AGENTS-TEMPLATE.md +173 -0
  2. package/README.md +867 -0
  3. package/agents/ti-researcher.md +108 -0
  4. package/bin/titools.js +53 -0
  5. package/lib/commands/agents.js +126 -0
  6. package/lib/commands/install.js +188 -0
  7. package/lib/commands/uninstall.js +215 -0
  8. package/lib/commands/update.js +159 -0
  9. package/lib/config.js +119 -0
  10. package/lib/downloader.js +153 -0
  11. package/lib/installer.js +253 -0
  12. package/lib/platform.js +108 -0
  13. package/lib/symlink.js +142 -0
  14. package/lib/utils.js +270 -0
  15. package/package.json +67 -0
  16. package/skills/alloy-expert/SKILL.md +247 -0
  17. package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
  18. package/skills/alloy-expert/references/alloy-structure.md +381 -0
  19. package/skills/alloy-expert/references/anti-patterns.md +133 -0
  20. package/skills/alloy-expert/references/code-conventions.md +469 -0
  21. package/skills/alloy-expert/references/contracts.md +280 -0
  22. package/skills/alloy-expert/references/controller-patterns.md +520 -0
  23. package/skills/alloy-expert/references/error-handling.md +484 -0
  24. package/skills/alloy-expert/references/examples.md +735 -0
  25. package/skills/alloy-expert/references/migration-patterns.md +298 -0
  26. package/skills/alloy-expert/references/patterns.md +448 -0
  27. package/skills/alloy-expert/references/performance-patterns.md +855 -0
  28. package/skills/alloy-expert/references/security-patterns.md +847 -0
  29. package/skills/alloy-expert/references/state-management.md +779 -0
  30. package/skills/alloy-expert/references/testing.md +872 -0
  31. package/skills/alloy-guides/SKILL.md +214 -0
  32. package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
  33. package/skills/alloy-guides/references/CONCEPTS.md +191 -0
  34. package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
  35. package/skills/alloy-guides/references/MODELS.md +1028 -0
  36. package/skills/alloy-guides/references/PURGETSS.md +56 -0
  37. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
  38. package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
  39. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
  40. package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
  41. package/skills/alloy-guides/references/WIDGETS.md +176 -0
  42. package/skills/alloy-howtos/SKILL.md +203 -0
  43. package/skills/alloy-howtos/references/best_practices.md +138 -0
  44. package/skills/alloy-howtos/references/cli_reference.md +253 -0
  45. package/skills/alloy-howtos/references/config_files.md +87 -0
  46. package/skills/alloy-howtos/references/custom_tags.md +147 -0
  47. package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
  48. package/skills/alloy-howtos/references/samples.md +167 -0
  49. package/skills/purgetss/SKILL.md +442 -0
  50. package/skills/purgetss/assets/purgetss.config.cjs +17 -0
  51. package/skills/purgetss/references/EXAMPLES.md +247 -0
  52. package/skills/purgetss/references/animation-system.md +1294 -0
  53. package/skills/purgetss/references/apply-directive.md +375 -0
  54. package/skills/purgetss/references/arbitrary-values.md +612 -0
  55. package/skills/purgetss/references/class-index.md +1350 -0
  56. package/skills/purgetss/references/cli-commands.md +948 -0
  57. package/skills/purgetss/references/configurable-properties.md +654 -0
  58. package/skills/purgetss/references/custom-rules.md +161 -0
  59. package/skills/purgetss/references/customization-deep-dive.md +722 -0
  60. package/skills/purgetss/references/dynamic-component-creation.md +489 -0
  61. package/skills/purgetss/references/grid-layout.md +455 -0
  62. package/skills/purgetss/references/icon-fonts.md +609 -0
  63. package/skills/purgetss/references/installation-setup.md +366 -0
  64. package/skills/purgetss/references/opacity-modifier.md +291 -0
  65. package/skills/purgetss/references/platform-modifiers.md +479 -0
  66. package/skills/purgetss/references/smart-mappings.md +42 -0
  67. package/skills/purgetss/references/titanium-resets.md +359 -0
  68. package/skills/purgetss/references/ui-ux-design.md +1526 -0
  69. package/skills/ti-guides/SKILL.md +94 -0
  70. package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
  71. package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
  72. package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
  73. package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
  74. package/skills/ti-guides/references/android-manifest.md +97 -0
  75. package/skills/ti-guides/references/app-distribution.md +258 -0
  76. package/skills/ti-guides/references/application-frameworks.md +377 -0
  77. package/skills/ti-guides/references/cli-reference.md +402 -0
  78. package/skills/ti-guides/references/coding-best-practices.md +102 -0
  79. package/skills/ti-guides/references/commonjs-advanced.md +134 -0
  80. package/skills/ti-guides/references/hello-world.md +100 -0
  81. package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
  82. package/skills/ti-guides/references/javascript-primer.md +411 -0
  83. package/skills/ti-guides/references/reserved-words.md +36 -0
  84. package/skills/ti-guides/references/resources.md +183 -0
  85. package/skills/ti-guides/references/style-and-conventions.md +48 -0
  86. package/skills/ti-guides/references/tiapp-config.md +609 -0
  87. package/skills/ti-howtos/SKILL.md +174 -0
  88. package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
  89. package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
  90. package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
  91. package/skills/ti-howtos/references/cross-platform-development.md +348 -0
  92. package/skills/ti-howtos/references/debugging-profiling.md +543 -0
  93. package/skills/ti-howtos/references/extending-titanium.md +723 -0
  94. package/skills/ti-howtos/references/google-maps-v2.md +169 -0
  95. package/skills/ti-howtos/references/ios-map-kit.md +143 -0
  96. package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
  97. package/skills/ti-howtos/references/local-data-sources.md +301 -0
  98. package/skills/ti-howtos/references/location-and-maps.md +252 -0
  99. package/skills/ti-howtos/references/media-apis.md +210 -0
  100. package/skills/ti-howtos/references/notification-services.md +599 -0
  101. package/skills/ti-howtos/references/remote-data-sources.md +349 -0
  102. package/skills/ti-howtos/references/tutorials.md +502 -0
  103. package/skills/ti-howtos/references/using-modules.md +237 -0
  104. package/skills/ti-howtos/references/web-content-integration.md +307 -0
  105. package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
  106. package/skills/ti-ui/SKILL.md +179 -0
  107. package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
  108. package/skills/ti-ui/references/animation-and-matrices.md +599 -0
  109. package/skills/ti-ui/references/application-structures.md +655 -0
  110. package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
  111. package/skills/ti-ui/references/event-handling.md +393 -0
  112. package/skills/ti-ui/references/gestures.md +473 -0
  113. package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
  114. package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
  115. package/skills/ti-ui/references/listviews-and-performance.md +619 -0
  116. package/skills/ti-ui/references/orientation.md +362 -0
  117. package/skills/ti-ui/references/platform-ui-android.md +635 -0
  118. package/skills/ti-ui/references/platform-ui-ios.md +469 -0
  119. package/skills/ti-ui/references/scrolling-views.md +252 -0
  120. package/skills/ti-ui/references/tableviews.md +568 -0
@@ -0,0 +1,722 @@
1
+ # PurgeTSS Deep Customization
2
+
3
+ PurgeTSS allows for extreme customization through its configuration file, custom rules for Ti Elements, and advanced class syntaxes.
4
+
5
+ :::info What's New in v7.2.x
6
+ **Configuration File Change**: The configuration file has been renamed from `config.js` to `config.cjs` for better CommonJS compatibility. The content structure remains exactly the same.
7
+
8
+ **Legacy Mode Removed**: Legacy mode has been completely removed from PurgeTSS v7.2.x. All legacy-related options have been eliminated for a cleaner, modern codebase.
9
+ :::
10
+
11
+ ## Table of Contents
12
+
13
+ - [PurgeTSS Deep Customization](#purgetss-deep-customization)
14
+ - [Table of Contents](#table-of-contents)
15
+ - [The `config.cjs` File](#the-configcjs-file)
16
+ - [File Structure](#file-structure)
17
+ - [Creating a Fresh config.cjs](#creating-a-fresh-configcjs)
18
+ - [The `purge` Section](#the-purge-section)
19
+ - [`mode` Property](#mode-property)
20
+ - [`method` Property](#method-property)
21
+ - [`options` Properties](#options-properties)
22
+ - [The `theme` Section](#the-theme-section)
23
+ - [Overriding vs Extending](#overriding-vs-extending)
24
+ - [Customizing Colors](#customizing-colors)
25
+ - [Color Object Syntax](#color-object-syntax)
26
+ - [Overriding Default Colors](#overriding-default-colors)
27
+ - [Extending the Palette](#extending-the-palette)
28
+ - [Customizing Spacing](#customizing-spacing)
29
+ - [Shared Spacing Behavior](#shared-spacing-behavior)
30
+ - [List of Customizable Properties](#list-of-customizable-properties)
31
+ - [Global Properties](#global-properties)
32
+ - [Color Properties (50+ properties)](#color-properties-50-properties)
33
+ - [Configurable Properties (80+ properties)](#configurable-properties-80-properties)
34
+ - [Custom Rules \& Ti Elements](#custom-rules--ti-elements)
35
+ - [Modifier Key](#modifier-key)
36
+ - [Default, Platform, Device, or Conditional Blocks](#default-platform-device-or-conditional-blocks)
37
+ - [Property Values](#property-values)
38
+ - [Complete Example](#complete-example)
39
+ - [The `@apply` Directive](#the-apply-directive)
40
+ - [Platform-Specific Classes with `@apply`](#platform-specific-classes-with-apply)
41
+ - [Correct Usage - With Platform Variant](#correct-usage---with-platform-variant)
42
+ - [Wrong Usage - Omitting Platform Variant](#wrong-usage---omitting-platform-variant)
43
+ - [Why Platform Variants Are Required](#why-platform-variants-are-required)
44
+ - [Combining Platform Variants](#combining-platform-variants)
45
+ - [String vs Array Syntax](#string-vs-array-syntax)
46
+ - [Platform \& Device Modifiers in XML](#platform--device-modifiers-in-xml)
47
+ - [Platform Modifiers](#platform-modifiers)
48
+ - [Device Modifiers](#device-modifiers)
49
+ - [Custom Conditional Modifiers](#custom-conditional-modifiers)
50
+ - [Icon Font Support](#icon-font-support)
51
+ - [Theme Extension Best Practices](#theme-extension-best-practices)
52
+ - [1. Use `extend` for Additions](#1-use-extend-for-additions)
53
+ - [2. Use Direct Properties for Overrides](#2-use-direct-properties-for-overrides)
54
+ - [3. Mix Both When Needed](#3-mix-both-when-needed)
55
+ - [Summary Checklist](#summary-checklist)
56
+ - [Related References](#related-references)
57
+
58
+ ---
59
+
60
+ ## The `config.cjs` File
61
+
62
+ By default, **PurgeTSS** will look for a `./purgetss/config.cjs` file where you can define customizations.
63
+
64
+ ### File Structure
65
+
66
+ The config file consists of two main sections: `purge` and `theme`.
67
+
68
+ ```javascript
69
+ module.exports = {
70
+ purge: {
71
+ mode: 'all',
72
+ method: 'sync',
73
+ options: {
74
+ missing: true,
75
+ widgets: false,
76
+ safelist: [],
77
+ plugins: []
78
+ }
79
+ },
80
+ theme: {
81
+ extend: {}
82
+ }
83
+ }
84
+ ```
85
+
86
+ :::info
87
+ Every section of the config file is optional, so you only need to specify what you'd like to change. Any missing sections will fall back to the default configuration.
88
+ :::
89
+
90
+ ### Creating a Fresh config.cjs
91
+
92
+ If you need to start with a fresh `config.cjs` file, delete the existing one and run:
93
+
94
+ ```bash
95
+ purgetss init
96
+ ```
97
+
98
+ ## The `purge` Section
99
+
100
+ The `purge` section controls how **PurgeTSS** will remove unused classes or keep the ones you want.
101
+
102
+ ### `mode` Property
103
+
104
+ ```javascript
105
+ purge: {
106
+ mode: 'all', // or 'class'
107
+ method: 'sync' // or 'async'
108
+ }
109
+ ```
110
+
111
+ **`mode: 'all'` (default)**
112
+ - Scans EVERYWHERE in XML files (comments, attributes, classes, IDs, Ti Elements)
113
+ - **REQUIRED** if you want PurgeTSS to parse any Ti Elements styled in `config.cjs`
114
+ - Most comprehensive but slightly slower
115
+
116
+ **`mode: 'class'`**
117
+ - Searches only in `class` and ID attributes in XML files
118
+ - Faster processing
119
+ - Cannot parse Ti Elements from `config.cjs`
120
+
121
+ :::info
122
+ **This mode is necessary if you want PurgeTSS to parse any Ti Elements that you've styled in `config.cjs`.**
123
+ :::
124
+
125
+ ### `method` Property
126
+
127
+ Determines how the **auto-purge** task will be executed: `sync` (default) or `async`.
128
+
129
+ :::tip
130
+ If you don't see any changes reflected when changing and rebuilding a project with TiKit Components and LiveView, set the compile method to `async`.
131
+ :::
132
+
133
+ ### `options` Properties
134
+
135
+ ```javascript
136
+ purge: {
137
+ options: {
138
+ missing: true, // Reports missing classes
139
+ widgets: false, // Purges widgets folder too
140
+ safelist: [], // Array of classes to keep
141
+ plugins: [] // Array of properties to disable
142
+ }
143
+ }
144
+ ```
145
+
146
+ **`options.missing`**
147
+
148
+ Set to `true` to get a list of missing or misspelled classes at the end of `app.tss`.
149
+
150
+ :::info
151
+ This is very useful if you want to check if you forgot to add a class definition or if you forgot to remove non-existing classes from your views, especially if you have upgraded from PurgeTSS v5 to v6.
152
+ :::
153
+
154
+ **`options.widgets`**
155
+
156
+ Set to `true` to also parse all XML files found in the **Widgets** folder.
157
+
158
+ **`options.safelist`**
159
+
160
+ Array of classes and Ti Elements to keep regardless of purge mode or usage in XML files.
161
+
162
+ For large safelists, create a separate module:
163
+
164
+ ```javascript
165
+ // ./purgetss/safelist.js
166
+ exports.safelist = [
167
+ 'Label', 'Button', 'Window',
168
+ 'bg-indigo-50', 'bg-indigo-100', /* ... */
169
+ 'bg-indigo-800', 'bg-indigo-900',
170
+ ];
171
+
172
+ // ./purgetss/config.cjs
173
+ module.exports = {
174
+ purge: {
175
+ options: {
176
+ safelist: require('./safelist')
177
+ }
178
+ }
179
+ }
180
+ ```
181
+
182
+ :::tip
183
+ You should put the safelist inside the `purgetss` folder to keep everything organized.
184
+ :::
185
+
186
+ **`options.plugins`**
187
+
188
+ Array of properties (plugins) to completely disable:
189
+
190
+ ```javascript
191
+ plugins: [
192
+ 'opacity', // Disable all opacity classes
193
+ 'borderRadius' // Disable all border-radius classes
194
+ ]
195
+ ```
196
+
197
+ ## The `theme` Section
198
+
199
+ The `theme` section is where you define your project's design system - colors, spacing, typography, borders, and more.
200
+
201
+ ### Overriding vs Extending
202
+
203
+ **Overriding** - Replaces default values:
204
+
205
+ ```javascript
206
+ theme: {
207
+ opacity: {
208
+ 15: '0.15',
209
+ 35: '0.35',
210
+ 65: '0.65',
211
+ 85: '0.85'
212
+ }
213
+ }
214
+ ```
215
+
216
+ This completely replaces the original default `opacity` values.
217
+
218
+ :::info
219
+ Note that any keys you do not provide will be inherited from the default theme, so in the above example, the default theme configuration for things like colors, spacing, border radius, background position, etc. will be preserved.
220
+ :::
221
+
222
+ **Extending** - Adds to default values:
223
+
224
+ ```javascript
225
+ theme: {
226
+ extend: {
227
+ colors: {
228
+ primary: '#002359',
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ This adds `primary` in addition to all default colors.
235
+
236
+ You can both override and extend in the same config:
237
+
238
+ ```javascript
239
+ theme: {
240
+ opacity: { /* ... */ }, // Override
241
+ extend: {
242
+ colors: { /* ... */ } // Extend
243
+ }
244
+ }
245
+ ```
246
+
247
+ ## Customizing Colors
248
+
249
+ ### Color Object Syntax
250
+
251
+ Colors can be defined as simple key-value pairs or nested objects:
252
+
253
+ ```javascript
254
+ theme: {
255
+ colors: {
256
+ // Simple values
257
+ transparent: 'transparent',
258
+ white: '#ffffff',
259
+ purple: '#3f3cbb',
260
+
261
+ // Nested objects (modifiers)
262
+ primary: {
263
+ solid: '#002359',
264
+ dark: '#000030',
265
+ transparent: '#D9002359'
266
+ },
267
+
268
+ // Shade scales
269
+ brand: {
270
+ 50: '#edfaff',
271
+ 100: '#d6f2ff',
272
+ 200: '#b5eaff',
273
+ 300: '#83dfff',
274
+ 400: '#48cbff',
275
+ 500: '#1eacff',
276
+ 600: '#068eff',
277
+ 700: '#007aff',
278
+ 800: '#085dc5',
279
+ 900: '#0d519b',
280
+ 950: '#0e315d',
281
+ default: '#007aff'
282
+ }
283
+ }
284
+ }
285
+ ```
286
+
287
+ Nested keys are combined with parent to form classes like `bg-primary-solid` or `text-brand-600`.
288
+
289
+ ### Overriding Default Colors
290
+
291
+ To override a default color while preserving others:
292
+
293
+ ```javascript
294
+ theme: {
295
+ extend: {
296
+ colors: {
297
+ gray: {
298
+ 50: '#f7f7f7',
299
+ 100: '#ededed',
300
+ 200: '#dfdfdf',
301
+ 300: '#c8c8c8',
302
+ 400: '#adadad',
303
+ 500: '#9e9e9e',
304
+ 600: '#888888',
305
+ 700: '#7b7b7b',
306
+ 800: '#676767',
307
+ 900: '#545454'
308
+ }
309
+ }
310
+ }
311
+ }
312
+ ```
313
+
314
+ ### Extending the Palette
315
+
316
+ Add new colors without modifying defaults:
317
+
318
+ ```javascript
319
+ theme: {
320
+ extend: {
321
+ colors: {
322
+ 'regal-blue': '#243c5a',
323
+ }
324
+ }
325
+ }
326
+ ```
327
+
328
+ :::info
329
+ You can use the `shades` command to generate a range of shades for a given color, automatically adding them to your `config.cjs` file.
330
+ :::
331
+
332
+ ## Customizing Spacing
333
+
334
+ The `spacing` section is shared by `padding`, `margin`, `width`, `height`, and `gap` properties.
335
+
336
+ ```javascript
337
+ theme: {
338
+ spacing: {
339
+ sm: 8,
340
+ md: 12,
341
+ lg: 16,
342
+ xl: 24,
343
+ }
344
+ }
345
+ ```
346
+
347
+ ### Shared Spacing Behavior
348
+
349
+ :::info
350
+ When you include the `spacing` section, PurgeTSS will automatically generate all spacing-related properties and merge them with any other spacing-related properties present in the configuration file.
351
+ :::
352
+
353
+ For example:
354
+
355
+ ```javascript
356
+ theme: {
357
+ spacing: {
358
+ tight: '0.25rem',
359
+ loose: '1.0rem'
360
+ },
361
+ width: {
362
+ banner: '5rem'
363
+ },
364
+ height: {
365
+ xl: '3rem',
366
+ '1/3': '33.333333%'
367
+ }
368
+ }
369
+ ```
370
+
371
+ This generates:
372
+ - `m-tight`, `m-loose`, `p-tight`, `p-loose`, etc.
373
+ - `w-banner`
374
+ - `h-xl`, `h-1/3`
375
+
376
+ ## List of Customizable Properties
377
+
378
+ ### Global Properties
379
+
380
+ All color properties inherit from `theme.colors`. All spacing properties inherit from `theme.spacing`.
381
+
382
+ ### Color Properties (50+ properties)
383
+
384
+ All of these support your custom colors:
385
+ - `activeTintColor`, `activeTitleColor`, `backgroundColor`, `backgroundDisabledColor`, `backgroundFocusedColor`, `backgroundSelectedColor`, `backgroundSelectedGradient`, `badgeColor`, `barColor`, `borderColor`, `color`, `colors`, `contentScrimColor`, `currentPageIndicatorColor`, `dateTimeColor`, `disabledColor`, `highlightedColor`, `hintTextColor`, `iconColor`, `imageTouchFeedbackColor`, `indicatorColor`, `keyboardToolbarColor`, `lightColor`, `navigationIconColor`, `navTintColor`, `onTintColor`, `pageIndicatorColor`, `pagingControlColor`, `pullBackgroundColor`, `resultsBackgroundColor`, `resultsSeparatorColor`, `selectedBackgroundColor`, `selectedButtonColor`, `selectedColor`, `selectedSubtitleColor`, `selectedTextColor`, `separatorColor`, `shadowColor`, `statusBarBackgroundColor`, `subtitleColor`, `subtitleTextColor`, `tabsBackgroundColor`, `tabsBackgroundSelectedColor`, `thumbTintColor`, `tint`, `tintColor`, `titleAttributes`, `titleColor`, `titleTextColor`, `touchFeedbackColor`, `trackTintColor`, `viewShadowColor`
386
+
387
+ ### Configurable Properties (80+ properties)
388
+
389
+ - `activeTab`, `backgroundLeftCap`, `backgroundPaddingBottom`, `backgroundPaddingLeft`, `backgroundPaddingRight`, `backgroundPaddingTop`, `backgroundTopCap`, `borderRadius`, `borderWidth`, `bottom`, `cacheSize`, `columnCount`, `contentHeight`, `contentWidth`, `countDownDuration`, `delay`, `duration`, `elevation`, `fontFamily`, `fontSize`, `horizontalMargin`, `indentionLevel`, `keyboardToolbarHeight`, `left`, `leftButtonPadding`, `leftTrackLeftCap`, `leftTrackTopCap`, `leftWidth`, `lineHeightMultiple`, `lines`, `lineSpacing`, `maxElevation`, `maximumLineHeight`, `maxLines`, `maxRowHeight`, `maxZoomScale`, `minimumFontSize`, `minimumLineHeight`, `minRowHeight`, `minZoomScale`, `opacity`, `padding`, `paddingBottom`, `paddingLeft`, `paddingRight`, `paddingTop`, `pageHeight`, `pageWidth`, `pagingControlAlpha`, `pagingControlHeight`, `pagingControlTimeout`, `paragraphSpacingAfter`, `paragraphSpacingBefore`, `repeat`, `repeatCount`, `right`, `rightButtonPadding`, `rightTrackLeftCap`, `rightTrackTopCap`, `rightWidth`, `rotate`, `rowCount`, `rowHeight`, `scale`, `scalesPageToFit`, `scaleX`, `scaleY`, `sectionHeaderTopPadding`, `separatorHeight`, `shadowRadius`, `shiftMode`, `timeout`, `top`, `uprightHeight`, `uprightWidth`, `verticalMargin`, `width`, `xOffset`, `yOffset`, `zIndex`, `zoomScale`
390
+
391
+ ## Custom Rules & Ti Elements
392
+
393
+ Style any **Ti Element**, **ID**, or **class** with platform/device specificity.
394
+
395
+ ### Modifier Key
396
+
397
+ - **Ti Elements**: Use exact name: `Label`, `Button`, `ScrollView`
398
+ - **IDs**: Use `camelCase`: `#mainBanner`, `sidebarWidget`
399
+ - **Classes**: Use `kebab-case`: `.my-custom-class`, `.feature-card` (required for PurgeTSS v6.x+)
400
+
401
+ :::caution PurgeTSS v5 or earlier projects
402
+ For projects created with PurgeTSS v5 or earlier that are now using version 7.x.x or above, please set `purge.options.missing` to true in `config.cjs` to get a report (at the end of `app.tss`) of any missing classes so you can update them to the new naming convention.
403
+ :::
404
+
405
+ ### Default, Platform, Device, or Conditional Blocks
406
+
407
+ - **`DEFAULT` or `default`**: Global style
408
+ - **`ios`** or **`android`**: Platform-specific
409
+ - **`tablet`** or **`handheld`**: Device-specific
410
+ - **`[if=globalVariableName]`**: Conditional with global variable
411
+
412
+ ### Property Values
413
+
414
+ - **Titanium constants**: Enclose in quotes: `'Ti.UI.SIZE'`, `'Ti.UI.FILL'`
415
+ - **Alloy Configuration Values**: Enclose in quotes: `'Alloy.CFG.someValue'`
416
+ - **Global Variables**: Enclose in quotes: `'Alloy.Globals.someValue'`
417
+ - **Colors**: Use `hex`, `8-digit hex`, `rgb(R,G,B)`, `rgba(R,G,B,A)`, `transparent`, or color names
418
+ - **Spacing values**: Use `em`, `rem`, `%`, `px`, `dp`, `cm`, `in`
419
+
420
+ **Unit conversions:**
421
+ - `%`, `px`, `cm`, `in` - Passed without conversion
422
+ - `em` or `rem` - Converted: `value * 16`
423
+ - `dp` - Unit removed, value remains intact
424
+
425
+ ### Complete Example
426
+
427
+ ```javascript
428
+ module.exports = {
429
+ theme: {
430
+ // Custom ID with platform variants
431
+ '#main-banner': {
432
+ DEFAULT: {
433
+ width: '300px',
434
+ height: '80px'
435
+ },
436
+ ios: {
437
+ clipMode: 'Ti.UI.iOS.CLIP_MODE_DISABLED'
438
+ }
439
+ },
440
+
441
+ // Custom class with device variants
442
+ '.gallery': {
443
+ DEFAULT: {
444
+ height: 'Ti.UI.SIZE'
445
+ },
446
+ ios: {
447
+ clipMode: 'Ti.UI.iOS.CLIP_MODE_ENABLED'
448
+ },
449
+ android: {
450
+ hiddenBehavior: 'Ti.UI.HIDDEN_BEHAVIOR_GONE'
451
+ },
452
+ handheld: {
453
+ width: '250px'
454
+ },
455
+ tablet: {
456
+ width: '500px'
457
+ }
458
+ },
459
+
460
+ // Ti Element styling
461
+ TextField: {
462
+ DEFAULT: {
463
+ top: 10,
464
+ left: 20,
465
+ right: 20,
466
+ bottom: 0
467
+ },
468
+ '[if=Alloy.Globals.iPhoneX]': {
469
+ bottom: 'Alloy.CFG.iPhoneXNotchSize'
470
+ },
471
+ android: {
472
+ touchFeedback: true
473
+ }
474
+ }
475
+ }
476
+ }
477
+ ```
478
+
479
+ ## The `@apply` Directive
480
+
481
+ Extract repetitive patterns into reusable classes.
482
+
483
+ ```javascript
484
+ '.btn-primary': {
485
+ apply: 'bg-blue-600 text-white rounded-lg px-4 py-2 font-bold'
486
+ }
487
+
488
+ '.card-shadow': {
489
+ apply: 'shadow-md'
490
+ }
491
+ ```
492
+
493
+ :::tip
494
+ The `apply` directive is perfect for creating component-specific utility classes that combine multiple PurgeTSS utilities into a single, semantic class name.
495
+ :::
496
+
497
+ ### Platform-Specific Classes with `@apply`
498
+
499
+ Several classes in `utilities.tss` are platform-specific to prevent polluting objects with properties that are not specific to a particular platform.
500
+
501
+ :::caution IMPORTANT!
502
+ To properly apply these platform styles when creating custom rules, you must specify the platform variant in the `apply` directive.
503
+
504
+ **Even if you are not targeting a specific platform, you must specify the platform variant.**
505
+ :::
506
+
507
+ #### Correct Usage - With Platform Variant
508
+
509
+ ```javascript
510
+ module.exports = {
511
+ theme: {
512
+ '.my-view': {
513
+ // Targeting iOS with platform variant
514
+ 'ios': {
515
+ 'apply': 'bg-green-500 wh-32 ios:clip-enabled'
516
+ }
517
+ }
518
+ },
519
+ }
520
+ ```
521
+
522
+ **Generated output:**
523
+ ```tss
524
+ /* Custom Classes */
525
+ '.my-view[platform=ios]': { backgroundColor: '#22c55e', clipMode: Ti.UI.iOS.CLIP_MODE_ENABLED, width: 128, height: 128 }
526
+ ```
527
+
528
+ #### Wrong Usage - Omitting Platform Variant
529
+
530
+ ```javascript
531
+ module.exports = {
532
+ theme: {
533
+ // Missing platform variant in clip-enabled
534
+ '.my-view': {
535
+ 'apply': 'wh-32 clip-enabled bg-green-500'
536
+ }
537
+ },
538
+ }
539
+ ```
540
+
541
+ **Generated output (MISSING the clipMode property):**
542
+ ```tss
543
+ /* Omitting the platform variant in config.cjs will not generate the corresponding property. */
544
+ /* Missing the property related to `clip-enabled`. */
545
+ '.my-view': { backgroundColor: '#22c55e', width: 128, height: 128 }
546
+ ```
547
+
548
+ #### Why Platform Variants Are Required
549
+
550
+ Certain Titanium properties are platform-specific and will only work when properly scoped:
551
+
552
+ | Property | Platform | Class |
553
+ | --------------- | -------------------- | --------------------------------------- |
554
+ | `clipMode` | iOS only | `ios:clip-enabled`, `ios:clip-disabled` |
555
+ | `touchFeedback` | Android only | `android:touch-feedback` |
556
+ | `hires` | iOS only (ImageView) | `ios:hires` |
557
+
558
+ When using `@apply` with these properties, you MUST specify the platform variant in the `apply` string so PurgeTSS knows which platform's property to include.
559
+
560
+ #### Combining Platform Variants
561
+
562
+ ```javascript
563
+ module.exports = {
564
+ theme: {
565
+ '.responsive-card': {
566
+ DEFAULT: {
567
+ apply: 'bg-white rounded-lg p-4'
568
+ },
569
+ ios: {
570
+ apply: 'shadow-md ios:clip-enabled'
571
+ },
572
+ android: {
573
+ apply: 'android:touch-feedback'
574
+ },
575
+ handheld: {
576
+ apply: 'w-full'
577
+ },
578
+ tablet: {
579
+ apply: 'w-3/4'
580
+ }
581
+ }
582
+ }
583
+ }
584
+ ```
585
+
586
+ **Generated output:**
587
+ ```tss
588
+ /* Platform and device specific styles */
589
+ '.responsive-card': { backgroundColor: '#ffffff', borderRadius: 8, top: 16, right: 16, bottom: 16, left: 16 }
590
+ '.responsive-card[platform=ios]': { clipMode: Ti.UI.iOS.CLIP_MODE_ENABLED }
591
+ '.responsive-card[platform=android]': { touchFeedback: true }
592
+ '.responsive-card[formFactor=handheld]': { width: '100%' }
593
+ '.responsive-card[formFactor=tablet]': { width: '75%' }
594
+ ```
595
+
596
+ ### String vs Array Syntax
597
+
598
+ You can use either a string or an array for the `apply` directive:
599
+
600
+ ```javascript
601
+ // String syntax
602
+ '.btn': {
603
+ apply: 'font-bold border-2 rounded wh-auto my-0.5'
604
+ }
605
+
606
+ // Array syntax (easier to read for long lists)
607
+ '.btn-corporate': {
608
+ apply: [
609
+ 'bg-corporate-500',
610
+ 'text-corporate-100',
611
+ 'border-corporate-200'
612
+ ]
613
+ }
614
+ ```
615
+
616
+ ## Platform & Device Modifiers in XML
617
+
618
+ Conditional styling directly in the `class` attribute using colon notation.
619
+
620
+ ### Platform Modifiers
621
+
622
+ ```xml
623
+ <!-- iOS-specific styling -->
624
+ <Label class="ios:text-blue-600 android:text-gray-600" />
625
+
626
+ <!-- Multiple platforms -->
627
+ <View class="ios:bg-blue-100 android:bg-gray-100" />
628
+ ```
629
+
630
+ ### Device Modifiers
631
+
632
+ ```xml
633
+ <!-- Tablet vs handheld -->
634
+ <View class="tablet:w-3/4 handheld:w-full" />
635
+ ```
636
+
637
+ ### Custom Conditional Modifiers
638
+
639
+ ```xml
640
+ <!-- Using global variables -->
641
+ <View class="[if=Alloy.Globals.isIPhoneX]:pb-24" />
642
+ ```
643
+
644
+ ## Icon Font Support
645
+
646
+ PurgeTSS automatically maps icon classes to both `text` and `title` properties, making them work on both Labels and Buttons.
647
+
648
+ ```tss
649
+ /* Auto-generated for FontAwesome */
650
+ '.fa-home': { text: '\uf015', title: '\uf015' }
651
+ '.fas': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
652
+ ```
653
+
654
+ This allows:
655
+ ```xml
656
+ <!-- Works on Labels -->
657
+ <Label class="fas fa-home" />
658
+
659
+ <!-- Works on Buttons too! -->
660
+ <Button class="fas fa-home" />
661
+ ```
662
+
663
+ ## Theme Extension Best Practices
664
+
665
+ ### 1. Use `extend` for Additions
666
+
667
+ ```javascript
668
+ theme: {
669
+ extend: {
670
+ colors: {
671
+ brand: '#007AFF', // Adds to existing colors
672
+ }
673
+ }
674
+ }
675
+ ```
676
+
677
+ ### 2. Use Direct Properties for Overrides
678
+
679
+ ```javascript
680
+ theme: {
681
+ colors: {
682
+ // Completely replaces default grays
683
+ gray: {
684
+ 50: '#f7f7f7',
685
+ // ... etc
686
+ }
687
+ }
688
+ }
689
+ ```
690
+
691
+ ### 3. Mix Both When Needed
692
+
693
+ ```javascript
694
+ theme: {
695
+ // Override some
696
+ opacity: { /* custom values */ },
697
+
698
+ // Extend others
699
+ extend: {
700
+ colors: { /* additional colors */ }
701
+ }
702
+ }
703
+ ```
704
+
705
+ ## Summary Checklist
706
+
707
+ - [ ] Set `mode: 'all'` if styling Ti Elements in `config.cjs`
708
+ - [ ] Use `method: 'async'` for LiveView compatibility issues
709
+ - [ ] Enable `missing: true` during development to catch typos
710
+ - [ ] Use `kebab-case` for custom class names (v6.x+ requirement)
711
+ - [ ] Use `camelCase` for IDs
712
+ - [ ] Use exact names for Ti Elements
713
+ - [ ] Prefer `extend` over overriding for colors/spacing
714
+ - [ ] Use `@apply` for component-specific utility combinations
715
+
716
+ ## Related References
717
+
718
+ - [Opacity Modifier](opacity-modifier.md) - Add transparency to ANY color with `/50` syntax
719
+ - [Configurable Properties](configurable-properties.md) - Complete list of 80+ customizable properties
720
+ - [Custom Rules](custom-rules.md) - Styling Ti Elements, IDs, and classes
721
+ - [Apply Directive](apply-directive.md) - Extracting utility combinations into reusable classes
722
+ - [Platform Modifiers](platform-modifiers.md) - ios:, android:, tablet:, handheld: prefixes