@maccesar/titools 4.23.1 → 5.1.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 (56) hide show
  1. package/README.md +26 -3
  2. package/package.json +1 -1
  3. package/skills/alloy-guides/references/MODELS.md +2 -2
  4. package/skills/alloy-guides/references/MODELS_ADVANCED.md +1 -1
  5. package/skills/alloy-guides/references/VIEWS_XML.md +13 -13
  6. package/skills/alloy-howtos/references/best_practices.md +2 -2
  7. package/skills/alloy-howtos/references/cli_reference.md +1 -1
  8. package/skills/alloy-howtos/references/debugging_troubleshooting.md +1 -1
  9. package/skills/purgetss/SKILL.md +27 -24
  10. package/skills/purgetss/references/EXAMPLES.md +52 -41
  11. package/skills/purgetss/references/adopting-purgetss.md +137 -0
  12. package/skills/purgetss/references/animation-advanced.md +18 -5
  13. package/skills/purgetss/references/animation-system.md +21 -9
  14. package/skills/purgetss/references/app-branding.md +36 -97
  15. package/skills/purgetss/references/appearance-module.md +70 -5
  16. package/skills/purgetss/references/apply-directive.md +14 -6
  17. package/skills/purgetss/references/arbitrary-values.md +59 -23
  18. package/skills/purgetss/references/brand-padding-geometry.md +105 -0
  19. package/skills/purgetss/references/class-categories.md +684 -272
  20. package/skills/purgetss/references/class-index-properties.md +713 -607
  21. package/skills/purgetss/references/class-index.md +149 -84
  22. package/skills/purgetss/references/classic-projects.md +2 -2
  23. package/skills/purgetss/references/cli-commands.md +27 -213
  24. package/skills/purgetss/references/color-commands.md +218 -0
  25. package/skills/purgetss/references/configurable-properties.md +17 -2
  26. package/skills/purgetss/references/custom-fonts.md +21 -16
  27. package/skills/purgetss/references/custom-rules.md +7 -7
  28. package/skills/purgetss/references/customization-deep-dive.md +14 -11
  29. package/skills/purgetss/references/dynamic-component-creation.md +104 -61
  30. package/skills/purgetss/references/grid-layout.md +21 -24
  31. package/skills/purgetss/references/icon-fonts.md +37 -20
  32. package/skills/purgetss/references/installation-setup.md +1 -1
  33. package/skills/purgetss/references/ios-large-titles.md +12 -11
  34. package/skills/purgetss/references/migration-guide.md +101 -10
  35. package/skills/purgetss/references/multi-density-images.md +44 -24
  36. package/skills/purgetss/references/opacity-modifier.md +1 -1
  37. package/skills/purgetss/references/performance-tips.md +5 -4
  38. package/skills/purgetss/references/platform-modifiers.md +2 -2
  39. package/skills/purgetss/references/purgetss-ui-classic.md +21 -5
  40. package/skills/purgetss/references/semantic-colors.md +20 -13
  41. package/skills/purgetss/references/smart-mappings.md +8 -7
  42. package/skills/purgetss/references/svg-pipeline.md +21 -13
  43. package/skills/purgetss/references/tikit-components.md +2 -2
  44. package/skills/purgetss/references/titanium-resets.md +27 -17
  45. package/skills/purgetss/references/ui-ux-design.md +38 -26
  46. package/skills/purgetss/references/values-and-units.md +1 -2
  47. package/skills/purgetss/references/version-history.md +32 -4
  48. package/skills/ti-api/references/api-data-network.md +1 -1
  49. package/skills/ti-api/references/api-media.md +1 -1
  50. package/skills/ti-api/references/api-services.md +8 -5
  51. package/skills/ti-api/references/api-ui-lists.md +3 -2
  52. package/skills/ti-api/references/api-ui-text-input.md +1 -1
  53. package/skills/ti-expert/references/feedback-surfaces.md +1 -1
  54. package/skills/ti-guides/references/resources.md +1 -1
  55. package/skills/ti-guides/references/sdk-release-notes.md +22 -11
  56. package/skills/ti-howtos/references/extending-titanium.md +77 -0
@@ -46,7 +46,7 @@ npm install -g purgetss
46
46
 
47
47
  ## Setting Up Your Project
48
48
 
49
- 1. Create a PurgeTSS project. If you haven't already, create a new Alloy project using PurgeTSS. Make sure you've configured the `app.idprefix` and `app.theme` settings as required by PurgeTSS:
49
+ 1. Create a PurgeTSS project. If you haven't already, create a new Alloy project using PurgeTSS. Make sure you've configured the `app.idprefix` and `app.workspace` settings in Titanium's `config.json`, as `purgetss create` requires:
50
50
 
51
51
  ```bash
52
52
  purgetss create myApp
@@ -488,7 +488,7 @@ To add popular free icon sets, run:
488
488
  purgetss icon-library --vendor=fa,mi,ms,f7
489
489
  ```
490
490
 
491
- This copies the font files and CSS into your project, ready to use.
491
+ This copies the font files into `app/assets/fonts/` (Alloy) or `Resources/fonts/` (Classic). Add `--module` for the CommonJS modules or `--styles` (Alloy only) for the `.tss` files.
492
492
 
493
493
  ### Adding Your Own Custom Icon Fonts
494
494
 
@@ -50,6 +50,8 @@ The most important reset is for the `View` element. By default, `View` is set to
50
50
 
51
51
  ### Practical Examples
52
52
 
53
+ Numeric values are unitless; Titanium resolves them with `ti.ui.defaultunit` in `tiapp.xml` (the Alloy template default is `dp`). See [Values and Units](./values-and-units.md).
54
+
53
55
  ```xml
54
56
  <!-- View without any classes = SIZE of its content -->
55
57
  <View>
@@ -61,19 +63,19 @@ The most important reset is for the `View` element. By default, `View` is set to
61
63
  <View class="h-32 w-64 bg-white">
62
64
  <Label text="Hello" />
63
65
  </View>
64
- <!-- Result: View is exactly 256px wide x 128px tall, label inside -->
66
+ <!-- Result: View is exactly 256dp wide x 128dp tall, label inside -->
65
67
 
66
68
  <!-- View with margins (expands to include margins) -->
67
69
  <View class="m-4 bg-blue-500">
68
70
  <Label text="Hello" />
69
71
  </View>
70
- <!-- Result: View is 16px larger on all sides (content + 16px margins) -->
72
+ <!-- Result: View is 16dp larger on all sides (content + 16dp margins) -->
71
73
 
72
74
  <!-- View with w-screen (fills parent) -->
73
75
  <View class="h-16 w-screen bg-red-500">
74
76
  <Label text="Full width banner" />
75
77
  </View>
76
- <!-- Result: View fills parent's width, 64px tall -->
78
+ <!-- Result: View fills parent's width, 64dp tall -->
77
79
  ```
78
80
 
79
81
  ### View in Different Layouts
@@ -187,7 +189,7 @@ PurgeTSS provides `wh-` shortcuts to set both width and height simultaneously. T
187
189
  | `.wh-full` | `width: '100%', height: '100%'` | Relative 100% sizing. |
188
190
 
189
191
  **The `wh-` Scale:**
190
- - **Numeric**: `wh-0` (0px) up to `wh-96` (384px) following the spacing scale.
192
+ - **Numeric**: `wh-0` (0dp) up to `wh-96` (384dp) following the spacing scale.
191
193
  - **Fractions**: `wh-1/2` (50%), `wh-1/3` (33%), up to `wh-11/12` (91%).
192
194
 
193
195
  > **💡 TIP**
@@ -224,7 +226,7 @@ This generates classes for ALL color properties:
224
226
 
225
227
  <!-- CORRECT: Explicitly set dimensions -->
226
228
  <View class="h-64 w-screen bg-blue-500">
227
- <!-- Fills parent width, 256px tall -->
229
+ <!-- Fills parent width, 256dp tall -->
228
230
  </View>
229
231
  ```
230
232
 
@@ -280,23 +282,24 @@ This generates classes for ALL color properties:
280
282
  When PurgeTSS generates your `app.tss`, these resets appear first:
281
283
 
282
284
  ```tss
283
- /* PurgeTSS v7.11.1 */
284
- /* Created by César Estrada */
285
- /* https://purgetss.com */
285
+ // PurgeTSS v7.17.1
286
+ // Created by César Estrada
287
+ // https://purgetss.com
286
288
 
287
289
  // Ti Elements
288
- 'View': { width: Ti.UI.SIZE, height: Ti.UI.SIZE }
289
290
  'ImageView[platform=ios]': { hires: true }
291
+ 'View': { width: Ti.UI.SIZE, height: Ti.UI.SIZE }
290
292
  'Window': { backgroundColor: '#FFFFFF' }
291
293
 
292
- /* Main Styles */
294
+ // Main Styles
293
295
  '.bg-white': { backgroundColor: '#ffffff' }
294
296
  '.h-screen': { height: Ti.UI.FILL }
295
297
  '.w-screen': { width: Ti.UI.FILL }
296
- // ... your custom classes
297
298
  ```
298
299
 
299
- These are **always included** - they're fundamental to how PurgeTSS works.
300
+ Content from `_app.tss`, if any, goes between the header and `// Ti Elements` under a `// _app.tss styles` comment.
301
+
302
+ A reset is included only when its element is actually used: with the default `purge.mode: 'all'`, PurgeTSS keeps `View`, `ImageView` or `Window` only if that tag appears in your XML views (or in `purge.options.safelist`). A project whose views contain only a `<Window>` gets only the `'Window'` reset.
300
303
 
301
304
  ## Default font family classes (v7.5.3+)
302
305
 
@@ -354,16 +357,23 @@ module.exports = {
354
357
  theme: {
355
358
  extend: {
356
359
  View: {
357
- width: Ti.UI.FILL,
358
- height: Ti.UI.SIZE
360
+ default: {
361
+ width: 'Ti.UI.FILL',
362
+ height: 'Ti.UI.SIZE'
363
+ }
359
364
  }
360
365
  }
361
366
  }
362
- }
367
+ };
363
368
  ```
364
369
 
365
- > **⚠️ DEPRECATED SHAPE (pre-v7.5.0)**
366
- > The older `theme.View.DEFAULT` shape is deprecated as of PurgeTSS v7.5.0. Migrate to `theme.extend.View` shown above. The same extend-based shape works for any Ti element default (`Window`, `Label`, `ImageView`, etc.).
370
+ Generated `utilities.tss`:
371
+ ```tss
372
+ 'View': { width: Ti.UI.FILL, height: Ti.UI.SIZE }
373
+ ```
374
+
375
+ > **⚠️ CAUTION**
376
+ > Wrap the properties in a `default` (or `DEFAULT`) block, or use `apply` (`View: { apply: 'w-screen h-auto' }`), and quote Titanium constants. Unquoted `Ti.UI.FILL` throws when Node loads `config.cjs`, and properties placed directly under `View` without a `default` wrapper generate broken rules such as `'View-width': { 0: 'T', 1: 'i', ... }`.
367
377
 
368
378
  > **💡 TIP**
369
379
  > Prefer `config.cjs` for custom defaults because they're preserved when PurgeTSS regenerates `app.tss`. For advanced overrides — including per-platform defaults, `apply` shorthand, and pseudo-class targeting — see `customization-deep-dive.md`.
@@ -85,24 +85,30 @@ The catalog below collects real-world UI patterns verified against Titanium's co
85
85
  ### Simple List Item
86
86
 
87
87
  ```xml
88
- <View class="border-b border-gray-200 bg-white">
88
+ <View class="w-screen bg-white">
89
89
  <Label class="mx-4 my-4 h-auto text-base text-gray-800" text="List item content" />
90
+ <!-- Titanium has no per-side border width: draw the divider as a 1px child -->
91
+ <View class="bottom-0 h-px w-screen bg-gray-200" />
90
92
  </View>
91
93
  ```
92
94
 
93
95
  ### List with Avatar
94
96
 
95
97
  ```xml
96
- <View class="horizontal border-b border-gray-200 bg-white">
97
- <View class="ml-4 my-4 rounded-full-12 bg-blue-500">
98
- <!-- A child with no top/left centers itself in a composite parent -->
99
- <Label class="text-lg font-bold text-white" text="JD" />
100
- </View>
98
+ <View class="w-screen bg-white">
99
+ <View class="horizontal">
100
+ <View class="ml-4 my-4 rounded-full-12 bg-blue-500">
101
+ <!-- A child with no top/left centers itself in a composite parent -->
102
+ <Label class="text-lg font-bold text-white" text="JD" />
103
+ </View>
101
104
 
102
- <View class="vertical ml-3 my-4">
103
- <Label class="text-base font-semibold text-gray-800" text="John Doe" />
104
- <Label class="text-sm text-gray-500" text="john.doe@example.com" />
105
+ <View class="vertical ml-3 my-4">
106
+ <Label class="text-base font-semibold text-gray-800" text="John Doe" />
107
+ <Label class="text-sm text-gray-500" text="john.doe@example.com" />
108
+ </View>
105
109
  </View>
110
+
111
+ <View class="bottom-0 h-px w-screen bg-gray-200" />
106
112
  </View>
107
113
  ```
108
114
 
@@ -163,7 +169,7 @@ The catalog below collects real-world UI patterns verified against Titanium's co
163
169
  ```
164
170
 
165
171
  > **⚠️ Input Padding**
166
- > Padding utilities (`p-`, `px-`, `py-`) work on `TextField` and `TextArea`, but NOT on `Button` (especially iOS/Mac) and NOT on container views (`View`, `Window`, `ScrollView`, `TableView`). Use margins on children to simulate internal spacing on containers.
172
+ > Padding utilities (`p-`, `px-`, `py-`) set the `padding` property, which the Titanium API defines only on `TextField` and `TextArea` (Android and iOS; `TextArea` honors left and right only) and `Ti.UI.Android.CardView` (apidoc 13_4_1_GA). `utilities.tss` labels the block "Android Only", which is inaccurate for the two text inputs. They are NOT for `Button` (especially iOS/Mac) and NOT on container views (`View`, `Window`, `ScrollView`, `TableView`). Use margins on children to simulate internal spacing on containers.
167
173
 
168
174
  ## Buttons
169
175
 
@@ -210,30 +216,35 @@ For an icon-with-text pair, use a horizontal `View` containing an icon `Label` a
210
216
  ### Top Bar with Title and Action
211
217
 
212
218
  ```xml
213
- <View class="h-14 w-screen bg-white border-b border-gray-200">
219
+ <View class="h-14 w-screen bg-white">
214
220
  <!-- Omitting top/bottom lets each child center vertically in the composite bar -->
215
221
  <Label class="left-4 text-lg font-bold text-gray-800" text="Dashboard" />
216
222
  <Label class="right-4 fas fa-bars text-gray-700" />
223
+ <View class="bottom-0 h-px w-screen bg-gray-200" />
217
224
  </View>
218
225
  ```
219
226
 
220
227
  ### Bottom Tab Bar
221
228
 
222
229
  ```xml
223
- <View class="bottom-0 h-16 w-screen bg-white border-t border-gray-200 horizontal">
224
- <View class="vertical w-1/3">
225
- <Label class="mx-auto mt-2 fas fa-home text-blue-500" />
226
- <Label class="mx-auto mt-1 text-xs text-blue-500" text="Home" />
227
- </View>
230
+ <View class="bottom-0 h-16 w-screen bg-white">
231
+ <View class="top-0 h-px w-screen bg-gray-200" />
228
232
 
229
- <View class="vertical w-1/3">
230
- <Label class="mx-auto mt-2 fas fa-search text-gray-400" />
231
- <Label class="mx-auto mt-1 text-xs text-gray-400" text="Search" />
232
- </View>
233
+ <View class="horizontal w-screen">
234
+ <View class="vertical w-1/3">
235
+ <Label class="mx-auto mt-2 fas fa-home text-blue-500" />
236
+ <Label class="mx-auto mt-1 text-xs text-blue-500" text="Home" />
237
+ </View>
233
238
 
234
- <View class="vertical w-1/3">
235
- <Label class="mx-auto mt-2 fas fa-user text-gray-400" />
236
- <Label class="mx-auto mt-1 text-xs text-gray-400" text="Profile" />
239
+ <View class="vertical w-1/3">
240
+ <Label class="mx-auto mt-2 fas fa-search text-gray-400" />
241
+ <Label class="mx-auto mt-1 text-xs text-gray-400" text="Search" />
242
+ </View>
243
+
244
+ <View class="vertical w-1/3">
245
+ <Label class="mx-auto mt-2 fas fa-user text-gray-400" />
246
+ <Label class="mx-auto mt-1 text-xs text-gray-400" text="Profile" />
247
+ </View>
237
248
  </View>
238
249
  </View>
239
250
  ```
@@ -288,8 +299,9 @@ For an icon-with-text pair, use a horizontal `View` containing an icon `Label` a
288
299
  ```xml
289
300
  <Window class="bg-gray-100">
290
301
  <View class="vertical h-screen w-screen">
291
- <View class="h-14 w-screen border-b border-gray-200 bg-white">
302
+ <View class="h-14 w-screen bg-white">
292
303
  <Label class="left-4 text-xl font-bold text-gray-800" text="Screen Title" />
304
+ <View class="bottom-0 h-px w-screen bg-gray-200" />
293
305
  </View>
294
306
 
295
307
  <ScrollView class="vertical content-w-screen content-h-auto">
@@ -299,7 +311,7 @@ For an icon-with-text pair, use a horizontal `View` containing an icon `Label` a
299
311
  </Window>
300
312
  ```
301
313
 
302
- > **ScrollView sizing (PurgeTSS v7.3+)**
314
+ > **ScrollView sizing**
303
315
  > The recommended pattern for a vertically scrolling `ScrollView` is `class="vertical content-w-screen content-h-auto"`. This sets `layout=vertical`, `contentWidth=Ti.UI.FILL`, and `contentHeight=Ti.UI.SIZE` so the content region grows to fit its children. Older examples using `h-screen w-screen` on the `ScrollView` itself describe the viewport, not the content — use the `content-*` variants to describe how the scrollable content flows.
304
316
  >
305
317
  > For iOS windows with large titles, also apply `extendEdges`, `autoAdjustScrollViewInsets`, and `largeTitleEnabled` on the `Window`. See `ios-large-titles.md`.
@@ -382,7 +394,7 @@ Example:
382
394
  | Row of actions | `horizontal` |
383
395
  | Fill space in overlay/modal | `h-screen w-screen` |
384
396
  | Card spacing | Margins on children |
385
- | Input inner spacing | `px-*`, `py-*` on input controls |
397
+ | Input inner spacing | `px-*`, `py-*` on `TextField` / `TextArea` |
386
398
  | Tablet adaptation | `tablet:*`, `handheld:*` |
387
399
  | Overlay background | `bg-(#88000000)` |
388
400
 
@@ -41,7 +41,6 @@ This applies to every utility class that sets a dimension:
41
41
  | Typography | `text-*` (font size), `letter-spacing-*`, `line-spacing-*` |
42
42
  | Shadows | `drop-shadow-*`, `shadow-radius-*` |
43
43
  | Elevation | `elevation-*`, `max-elevation-*` |
44
- | Transforms | `translate-*`, `move-by-*` |
45
44
  | Offsets | `x-offset-*`, `y-offset-*` |
46
45
 
47
46
  ## Valid values for `ti.ui.defaultunit`
@@ -115,6 +114,6 @@ If that property is missing, Titanium falls back to `system`. That means iOS and
115
114
 
116
115
  ## Related
117
116
 
118
- - [Arbitrary Values](./arbitrary-values.md) — parentheses notation `(20px)`, `(2rem)`, `(#ff0000)` for one-off values.
117
+ - [Arbitrary Values](./arbitrary-values.md) — parentheses notation `(20)`, `(2rem)`, `(#ff0000)` for one-off values.
119
118
  - [Customization Deep Dive](./customization-deep-dive.md) — defining your own spacing scale via `theme.spacing`.
120
119
  - [Class Index](./class-index.md) — the full set of generated classes and their numeric vs. percentage vs. constant outputs.
@@ -8,9 +8,11 @@ When in doubt about whether a class, flag, or config key exists in the user's in
8
8
 
9
9
  ---
10
10
 
11
+ ## Unreleased (after v7.17.1)
12
+ - The comment above the opt-in pieces in the generated config now names each consumer instead of claiming both are inert without hand-edited XML. Only `splash_icon` is.
13
+
11
14
  ## v7.17.1
12
15
  - **The `notification-icon` piece writes `notificationicon.png`, not `ic_stat_notify.png`.** `firebase.cloudmessaging` hardcodes that name — `TiFirebaseMessagingService.showNotification()` calls `getResource("notificationicon")` — and it is the only path a **data** message has. The `default_notification_icon` meta-data is the configurable one and covers **notification** messages alone, so under the old name no manifest entry could rescue a data message: the module fell back to the opaque `appicon`, which the status bar renders as a white blob. The filename is fixed rather than a config key, for the same reason `appicon.png` and `DefaultIcon.png` are. Projects that wired `@drawable/ic_stat_notify` by hand need to update that one meta-data line and delete the five stale files. See [app-branding.md](app-branding.md).
13
- - The comment above the opt-in pieces in the generated config now names each consumer instead of claiming both are inert without hand-edited XML. Only `splash_icon` is.
14
16
 
15
17
  ## v7.17.0
16
18
  - The `images:` section rejects unknown keys instead of ignoring them, at both levels: the five top-level keys (`quality`, `format`, `autoSync`, `confirmOverwrites`, `files`) and the three inside each `files[]` entry (`filename`, `width`, `height`, with `filename` required). Nothing is generated when validation fails. Never suggest `width`, `opacity`, `padding` or `output` as config keys — they are CLI flags and now abort the run. See [multi-density-images.md](multi-density-images.md).
@@ -84,7 +86,7 @@ When in doubt about whether a class, flag, or config key exists in the user's in
84
86
  - SVG-aware compile-time image pipeline runs as a `purgetss` post-step. When XML/controllers reference `image="/images/x.svg"` (or `backgroundImage`) alongside utility classes that resolve to numeric width/height (`w-32`, `w-(300)`, `h-auto`), purge compiles the SVG into the 8 Titanium density PNGs (5 Android + 3 iPhone) using dimensions resolved from `app.tss`. Titanium loads the generated `.png` at runtime; the `.svg` attribute in your source is never rewritten. Cache: `purgetss/.cache/svg-images.json` (add to `.gitignore`). See [multi-density-images.md](multi-density-images.md).
85
87
  - `images.files` array in `config.cjs` — per-file width/height override: `[{ filename: 'images/logos/logo.png', width: 128, height: 52 }]`. CLI `--width` still wins over entries. SVGs detected by the pipeline populate entries automatically (subject to `images.autoSync`); hand-added raster entries survive untouched.
86
88
  - `images.autoSync` boolean (default `true`) — opt-out for devs managing `images.files` by hand. When `false`, purge still computes dimensions and generates PNGs but never writes back to `config.cjs`.
87
- - `config.cjs` syntax validator emits a formatted `Config Syntax Error` block (file, JSON path, context, issue, fix snippet) for type mismatches in known fields, currently `theme.fontFamily.*` — must be a **string** — replacing cryptic crashes like `rule.startsWith is not a function`.
89
+ - `config.cjs` syntax validator emits a formatted `Config Syntax Error` block (file, JSON path, context, issue, fix snippet) for type mismatches in known fields, currently `theme.fontFamily.*` and `theme.extend.fontFamily.*` — each value must be a **string** — replacing cryptic crashes like `rule.startsWith is not a function`.
88
90
 
89
91
  ## v7.10.2
90
92
  - Pre-v7.7.0 `brand:` configs (flat layout: `brand.padding: <number>`, `brand.iosPadding`, `brand.bgColor`, top-level `brand.notification`/`brand.splash`) auto-migrate to the grouped layout in memory. A one-time per-session notice lists the migrated keys.
@@ -100,7 +102,7 @@ When in doubt about whether a class, flag, or config key exists in the user's in
100
102
  - Fix: `brand --padding <n>` shortcut applies to BOTH Android paddings.
101
103
 
102
104
  ## v7.9.0
103
- - Opacity modifiers work on semantic colors: `bg-surface/65` auto-derives `surface_65` in `semantic.colors.json` with light/dark + alpha. **Native rebuild required** (Liveview alone does not refresh `semantic.colors.json`). See [semantic-colors.md](semantic-colors.md).
105
+ - Opacity modifiers work on semantic colors: `bg-surface/65` (mapped to `surfaceColor`) auto-derives `<originalKey>_<alphaPercent>` — here `surfaceColor_65` — in `semantic.colors.json` with light/dark + alpha. **Native rebuild required** (Liveview alone does not refresh `semantic.colors.json`). See [semantic-colors.md](semantic-colors.md).
104
106
  - `theme.Window` / `theme.View` / `theme.ImageView` at top level = **replace mode** (no framework defaults). Use `theme.extend.Window` for **extend mode** (merge with defaults). See [apply-directive.md](apply-directive.md).
105
107
  - **Breaking:** glossary path renamed `purgetss/experimental/tailwind-classes/` → `purgetss/glossary/tailwind-classes/`. No transition shim.
106
108
 
@@ -112,7 +114,7 @@ When in doubt about whether a class, flag, or config key exists in the user's in
112
114
  - `brand:` config restructured into grouped sections: `brand.logos`, `brand.padding`, `brand.android`, `brand.ios`, `brand.colors`. Old projects keep working; new configs use grouped form. See [app-branding.md](app-branding.md).
113
115
  - Separate Android brand inputs: `logos.androidLauncher` / `--icon-logo` and `logos.androidSplash` / `--splash-logo`.
114
116
  - Android splash fallback `default.png` regenerated (Alloy: `app/assets/android/`, Classic: `Resources/android/`). `cleanup-legacy` preserves it.
115
- - New ref: [values-and-units.md](values-and-units.md) — `ti.ui.defaultunit` interpretation of unitless PurgeTSS values.
117
+ - Related docs page (not a release change): [values-and-units.md](values-and-units.md) — `ti.ui.defaultunit` interpretation of unitless PurgeTSS values.
116
118
 
117
119
  ## v7.6.x
118
120
  - `purgetss brand` (v7.6.0) — full Titanium branding set from `purgetss/brand/` logos. See [app-branding.md](app-branding.md).
@@ -125,6 +127,11 @@ When in doubt about whether a class, flag, or config key exists in the user's in
125
127
  - `Appearance` module — Light/Dark/System mode switching with persistence (`init()`, `set()`, `get()`, `toggle()`). See [appearance-module.md](appearance-module.md).
126
128
  - Default font family classes (`font-sans`, `font-serif`, `font-mono`) auto-generated with platform-appropriate values.
127
129
 
130
+ ## v7.5.1
131
+ - Fix: `dist/purgetss.ui.js` shipped in v7.5.0 without `pulse()`, the latest `transition()` improvements, and delta-based drag for transformed views; rebuilt from the template. Re-run `purgetss module` to get them.
132
+ - Fix: `snap-back`, `snap-center`, `snap-magnet`, and `keep-z-index` classes are now generated in `utilities.tss`.
133
+ - Font Awesome updated to 7.2.0.
134
+
128
135
  ## v7.5.0
129
136
  - `theme.extend.Window` / `theme.extend.View` / `theme.extend.ImageView` — customize Ti element defaults.
130
137
  - Shorthand `apply:` directive — `{ apply: '...' }` auto-normalizes; `default:` wrapper optional.
@@ -135,3 +142,24 @@ When in doubt about whether a class, flag, or config key exists in the user's in
135
142
  - Animation module: 9 new methods (`transition`, `pulse`, `sequence`, `swap`, `shake`, `snapTo`, `reorder`, `undraggable`, `detectCollisions`). 15 methods total. See [animation-system.md](animation-system.md).
136
143
  - New utility classes: `snap-back`, `snap-center`, `snap-magnet`, `keep-z-index`.
137
144
  - Delta-based drag for transformed views; property inheritance from Animation object.
145
+
146
+ ## v7.3.1
147
+ - Fix: draggable views positioned at `left: 0` / `top: 0` (also `right` / `bottom`) no longer jump on drag start.
148
+
149
+ ## v7.3.0
150
+ - **Breaking:** `tailwind.tss` renamed to `utilities.tss` — generated file is `purgetss/styles/utilities.tss`, distribution file is `dist/utilities.tss`. Never reference `tailwind.tss`. See [migration-guide.md](migration-guide.md#upgrade-to-v73x).
151
+ - XML syntax pre-validation for Alloy views (for example `Label id=` missing its `<`), with line numbers, context, and a suggested fix.
152
+ - `deviceInfo()` no longer depends on `Alloy.isTablet` / `Alloy.isHandheld`, so it works in Classic too.
153
+
154
+ ## v7.2.7
155
+ - **Node.js 20+ required** (`inquirer` v13). Security fixes for transitive `glob` (command injection) and `js-yaml` (prototype pollution).
156
+ - Install size reduced by ~45MB: `@fortawesome/fontawesome-free`, `framework7-icons`, and `junk` moved to devDependencies; font files still ship pre-built.
157
+ - Titanium SDK 13.1.0.GA definitions: new utility classes for `navBarColor`, `forceBottomPosition`, and `multipleWindows`.
158
+ - Recommended class-reordering VS Code extension is now `KevinYouu.tailwind-raw-reorder-tw4`.
159
+
160
+ ## v7.2.6
161
+ - Font Awesome updated to 7.1.0.
162
+ - Flag property names in `utilities.tss` simplified and renamed for consistency.
163
+
164
+ ## v7.1.10
165
+ - Animation module: `play` and `apply` callbacks receive an enriched event object instead of the raw native event — `type`, `bubbles`, `cancelBubble`, plus `action` (`'play'` / `'apply'`), `state` (`'open'` / `'close'`), `id`, `targetId`, `index`, `total`, and a `getTarget()` helper. See [animation-system.md](animation-system.md).
@@ -107,7 +107,7 @@ On the iOS platform, closing the database also closes the result set, that is, y
107
107
  > Platforms: both
108
108
  > Type: module
109
109
 
110
- For examples of using the Filesystem APIs, refer to the [Filesystem Access and Storage guide](https://titaniumsdk.com/guide/Titanium_SDK/Titanium_SDK_How-tos/Working_with_Local_Data_Sources/Filesystem_Access_and_Storage.html) as well as the other Filesystem submodule API documentation.
110
+ For examples of using the Filesystem APIs, refer to the [Filesystem Access and Storage guide](https://titaniumsdk.com/docs/build/data) as well as the other Filesystem submodule API documentation.
111
111
 
112
112
  ### Properties (unique: 11/21)
113
113
  | Property | Type | Default | Platform | Description |
@@ -21,7 +21,7 @@
21
21
  > Platforms: both
22
22
  > Type: module
23
23
 
24
- The Media module is used to access the device's media-related functionality, such as using the device's camera and photo gallery, playing media files, or recording audio or video. For examples of using the Media APIs, refer to the [Working with Media APIs guide](https://titaniumsdk.com/guide/Titanium_SDK/Titanium_SDK_How-tos/Working_with_Media_APIs/) in addition to the other media submodule API documentation. **Note**: Some third party Android camera apps may choose to ignore video recording quality settings. If you wish to specifically set the video quality, don't assume `EXTRA_VIDEO_QUALITY` intent will be respected by the camera app and use Titanium's built-in camera window which can be used to assign the `overlay` property when calling the `showCamera()` method.
24
+ The Media module is used to access the device's media-related functionality, such as using the device's camera and photo gallery, playing media files, or recording audio or video. For examples of using the Media APIs, refer to the [Working with Media APIs guide](https://titaniumsdk.com/docs/build/media) in addition to the other media submodule API documentation. **Note**: Some third party Android camera apps may choose to ignore video recording quality settings. If you wish to specifically set the video quality, don't assume `EXTRA_VIDEO_QUALITY` intent will be respected by the camera app and use Titanium's built-in camera window which can be used to assign the `overlay` property when calling the `showCamera()` method.
25
25
 
26
26
  ### Properties (unique: 28/178)
27
27
  | Property | Type | Default | Platform | Description |
@@ -108,15 +108,18 @@ to request runtime permissions.
108
108
 
109
109
  The API supports retrieving information about the attendee of an event.
110
110
 
111
- ### Properties (unique: 6/8)
111
+ The type declares `platforms: [iphone, ipad, macos]`, but four of its properties declare Android as well. Read the per-property column, not the type header.
112
+
113
+ ### Properties (unique: 7/9)
112
114
  | Property | Type | Default | Platform | Description |
113
115
  |----------|------|---------|----------|-------------|
114
116
  | isOrganizer | Boolean | — | ios | Indicates whether this attendee is the event organizer. |
115
- | name | String | — | ios | The attendee name. |
116
- | email | String | — | ios | The attendee email. |
117
+ | name | String | — | both | The attendee name. |
118
+ | email | String | — | both | The attendee email. |
119
+ | relationship | Number | — | android | The relationship of the attendee to the user. Read-only. Values come from the `Ti.Calendar.RELATIONSHIP_*` constants. Since 6.2.0. |
117
120
  | role | Number | — | ios | The role of the attendee. |
118
- | type | Number | — | ios | The type of the attendee. |
119
- | status | Number | — | ios | The status of the attendee. |
121
+ | type | Number | — | both | The type of the attendee. |
122
+ | status | Number | — | both | The status of the attendee. |
120
123
 
121
124
 
122
125
 
@@ -336,7 +336,7 @@ A `TableView` object is a container for [TableViewSection](Titanium.UI.TableView
336
336
 
337
337
  Use the <Titanium.UI.createTableView> method or **`<TableView>`** Alloy element to create a `TableView`.
338
338
 
339
- Also see the [TableViews guide](https://titaniumsdk.com/guide/Titanium_SDK/Titanium_SDK_How-tos/User_Interface_Deep_Dives/TableViews.html).
339
+ Also see the [TableViews guide](https://titaniumsdk.com/docs/build/ui/lists).
340
340
 
341
341
  ### Creating Tables
342
342
 
@@ -564,12 +564,13 @@ Rows may be created using the properties directly available on the `TableViewRow
564
564
 
565
565
 
566
566
 
567
- ### Events (4)
567
+ ### Events (5)
568
568
  | Event | Platform | Description |
569
569
  |-------|----------|-------------|
570
570
  | click | both | Fired when a table row is clicked by the user. |
571
571
  | touchcancel | ios | Fired when a touch gesture is interrupted by the device. |
572
572
  | touchend | ios | Fired when a touch gesture is complete. |
573
+ | touchmove | ios | Fired as soon as the device detects movement of a touch. A row touch event and a table `scroll` event cannot occur concurrently: if the table begins to scroll during a touch, `touchcancel` fires before `scroll` begins. |
573
574
  | touchstart | ios | Fired as soon as the device detects a touch gesture against this view. |
574
575
 
575
576
  ### Related Types
@@ -337,7 +337,7 @@ The AttributedString proxy is created with the <Titanium.UI.createAttributedStri
337
337
 
338
338
  The `text` property must be set initially in the constructor when creating an attributed string. The [attributes](Titanium.UI.AttributedString.attributes) can either be set in the constructor or after it has been created.
339
339
 
340
- For examples of Attributed Strings, see the [Attributed Strings guide](https://titaniumsdk.com/guide/Titanium_SDK/Titanium_SDK_How-tos/User_Interface_Deep_Dives/Attributed_Strings.html).
340
+ For examples of Attributed Strings, see the [Attributed Strings guide](https://titaniumsdk.com/docs/build/ui).
341
341
 
342
342
  ### Properties (unique: 2/5)
343
343
  | Property | Type | Default | Platform | Description |
@@ -102,7 +102,7 @@ Standardize buttons, cards, badges, chips, skeletons, and coach marks only when
102
102
 
103
103
  ## References
104
104
 
105
- - [Titanium Alloy Widgets](https://titaniumsdk.com/guide/Alloy_Framework/Alloy_Guide/Alloy_Widgets.html)
105
+ - [Titanium Alloy Widgets](https://titaniumsdk.com/docs/alloy/widgets)
106
106
  - [Apple Human Interface Guidelines: Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts)
107
107
  - [Apple Human Interface Guidelines: Modality](https://developer.apple.com/design/human-interface-guidelines/modality)
108
108
  - [Material Design 3: Snackbar](https://m3.material.io/components/snackbar/overview)
@@ -19,7 +19,7 @@ Community resources, support channels, tools, and learning materials for Titaniu
19
19
  ### Documentation
20
20
 
21
21
  - Titanium SDK Docs: https://titaniumsdk.com/
22
- - Alloy Framework Docs: https://titaniumsdk.com/guide/Alloy_Framework/
22
+ - Alloy Framework Docs: https://titaniumsdk.com/docs/alloy
23
23
  - This skill (`ti-guides`): `../SKILL.md`
24
24
 
25
25
  ---
@@ -8,11 +8,12 @@ Each GA release desupports the previous patch release. Running an unsupported ve
8
8
  ## Contents
9
9
 
10
10
  - [1. Version timeline](#1-version-timeline)
11
- - [2. 13.4.0 — Android target SDK 36 groundwork](#2-1340--android-target-sdk-36-groundwork)
12
- - [3. 13.3.1 — patch](#3-1331--patch)
13
- - [4. 13.3.0 — Xcode 27, iOS 27, multi-scene](#4-1330--xcode-27-ios-27-multi-scene)
14
- - [5. 13.2.0 — ViewPager2, keepHardwareMode](#5-1320--viewpager2-keephardwaremode)
15
- - [6. Bundled module versions](#6-bundled-module-versions)
11
+ - [2. 13.4.1 — patch](#2-1341--patch)
12
+ - [3. 13.4.0 — Android target SDK 36 groundwork](#3-1340--android-target-sdk-36-groundwork)
13
+ - [4. 13.3.1 — patch](#4-1331--patch)
14
+ - [5. 13.3.0 — Xcode 27, iOS 27, multi-scene](#5-1330--xcode-27-ios-27-multi-scene)
15
+ - [6. 13.2.0 — ViewPager2, keepHardwareMode](#6-1320--viewpager2-keephardwaremode)
16
+ - [7. Bundled module versions](#7-bundled-module-versions)
16
17
 
17
18
  <!-- TOC-END -->
18
19
 
@@ -20,6 +21,7 @@ Each GA release desupports the previous patch release. Running an unsupported ve
20
21
 
21
22
  | Version | Date | Headline |
22
23
  |---|---|---|
24
+ | 13.4.1.GA | 25 August 2026 | Patch — BottomNavigation keyboard and androidback (Android), window-open deadlock (iOS) |
23
25
  | 13.4.0.GA | 28 July 2026 | Prepares the SDK for Android target SDK 36; v8 memory cleanup |
24
26
  | 13.3.1.GA | 20 July 2026 | Patch — iOS restart and LiveView fixes |
25
27
  | 13.3.0.GA | 01 July 2026 | Xcode 27 and iOS 27, Hyperloop 8.0.0, iOS multi-scene apps |
@@ -27,7 +29,16 @@ Each GA release desupports the previous patch release. Running an unsupported ve
27
29
  | 13.1.0.GA | — | Minor release, high-priority fixes |
28
30
  | 13.0.0.GA | — | Major release: iOS 26 / Xcode 26, Android 16 KB page size |
29
31
 
30
- ## 2. 13.4.0 — Android target SDK 36 groundwork
32
+ ## 2. 13.4.1 — patch
33
+
34
+ Released 25 August 2026. Two fixes, both to crashes and input handling rather than to any API:
35
+
36
+ - **Android:** keyboard issues in `BottomNavigation`, and the `androidback` event.
37
+ - **iOS:** a possible deadlock when opening a window.
38
+
39
+ Desupports 13.4.0. No API surface changed, so code written against 13.4.0 needs no edit.
40
+
41
+ ## 3. 13.4.0 — Android target SDK 36 groundwork
31
42
 
32
43
  - **Prepares the SDK for Android target SDK 36.** Groundwork only; the compatibility matrix still lists API 35 as the maximum target. See [compatibility-matrix.md](compatibility-matrix.md) § Android.
33
44
  - v8 memory cleanup (Android).
@@ -36,11 +47,11 @@ Each GA release desupports the previous patch release. Running an unsupported ve
36
47
  - iOS: fixed the dimming area in a TableView SearchBar.
37
48
  - The debug-only selector for `Ti.App._restart()` was removed, making the method callable outside debug builds.
38
49
 
39
- ## 3. 13.3.1 — patch
50
+ ## 4. 13.3.1 — patch
40
51
 
41
52
  iOS-only fixes: the `restart` method, and LiveView restart. Hyperloop bumped to 8.0.1.
42
53
 
43
- ## 4. 13.3.0 — Xcode 27, iOS 27, multi-scene
54
+ ## 5. 13.3.0 — Xcode 27, iOS 27, multi-scene
44
55
 
45
56
  - **Xcode 27 and iOS 27 support.** This postdates the Xcode/iOS rows in the compatibility matrix, which still cap at Xcode 16.x.
46
57
  - **iOS multi-scene applications** are supported.
@@ -51,7 +62,7 @@ iOS-only fixes: the `restart` method, and LiveView restart. Hyperloop bumped to
51
62
  - `borderWidth` no longer renders at double thickness when `borderRadius` is an array (iOS).
52
63
  - Android: Material 3 BottomNavigation theme and dark/light switching fixes, CameraX rotation fix under orientation lock, WebView fix for URLs carrying large GET data, `Ti.Preferences` optimized.
53
64
 
54
- ## 5. 13.2.0 — ViewPager2, keepHardwareMode
65
+ ## 6. 13.2.0 — ViewPager2, keepHardwareMode
55
66
 
56
67
  - **ScrollableView moved to ViewPager2 on Android.** A backing-widget swap; verify paging, nested scrolling and any custom paging control against it.
57
68
  - **`keepHardwareMode` added to `Ti.UI.View`** (Android) — controls the view's render mode.
@@ -63,7 +74,7 @@ iOS-only fixes: the `restart` method, and LiveView restart. Hyperloop bumped to
63
74
  - Node.js 24 support; core-js upgraded, removing the `baseline-browser-mapping` warning.
64
75
  - iOS: Mac Catalyst fixes for `Ti.UI.Button` styling and events, and module builds with `mac=true`.
65
76
 
66
- ## 6. Bundled module versions
77
+ ## 7. Bundled module versions
67
78
 
68
79
  Versions shipped with each SDK. Unchanged rows are omitted.
69
80
 
@@ -72,4 +83,4 @@ Versions shipped with each SDK. Unchanged rows are omitted.
72
83
  | facebook | 14.0.0 / 15.0.0 | 15.0.0 / 16.0.0 |
73
84
  | hyperloop | 7.1.0 / 7.1.0 | 8.0.1 / 8.0.1 (8.0.0 in 13.3.0) |
74
85
 
75
- Stable across 13.2.0–13.4.0: `ti.map` 5.7.0 / 7.3.1, `ti.webdialog` 2.5.0 / 3.0.2, `ti.playservices` 18.6.0 (Android only), `ti.identity` 3.2.0 / 5.0.0, `urlSession` 4.0.1 (iOS only), `ti.coremotion` 4.0.1 (iOS only), `ti.applesignin` 3.1.2 (iOS only).
86
+ Stable across 13.2.0–13.4.1: `ti.map` 5.7.0 / 7.3.1, `ti.webdialog` 2.5.0 / 3.0.2, `ti.playservices` 18.6.0 (Android only), `ti.identity` 3.2.0 / 5.0.0, `urlSession` 4.0.1 (iOS only), `ti.coremotion` 4.0.1 (iOS only), `ti.applesignin` 3.1.2 (iOS only).
@@ -8,6 +8,7 @@
8
8
  - [3. Upgrading to SDK 9.0.0+ (Android)](#3-upgrading-to-sdk-900-android)
9
9
  - [4. Hyperloop](#4-hyperloop)
10
10
  - [3. Native module development](#3-native-module-development)
11
+ - [Swift Package Manager dependencies (iOS)](#swift-package-manager-dependencies-ios)
11
12
  - [4. Choosing between Hyperloop and native modules](#4-choosing-between-hyperloop-and-native-modules)
12
13
  - [5. Finding and using third-party modules](#5-finding-and-using-third-party-modules)
13
14
  - [Best practices summary](#best-practices-summary)
@@ -601,6 +602,82 @@ View proxies (custom UI components):
601
602
  @end
602
603
  ```
603
604
 
605
+ ### Swift Package Manager dependencies (iOS)
606
+
607
+ Since Titanium SDK 13.1.0, an iOS module declares Swift package dependencies in an `spm.json` file and the CLI wires them into the consuming app. This replaces vendoring pre-built `.xcframework` files in `ios/platform` and replaces the legacy `hooks/ti.spm.js` hook.
608
+
609
+ Add the package to your module's Xcode project as usual so the module compiles against it, then declare the same package in `spm.json`, next to the module `manifest`:
610
+
611
+ ```
612
+ mymodule/
613
+ └── ios/
614
+ ├── manifest
615
+ ├── spm.json
616
+ ├── MyModule.xcodeproj
617
+ └── Classes/
618
+ ```
619
+
620
+ ```json
621
+ {
622
+ "dependencies": [
623
+ {
624
+ "remotePackageReference": "Parse-SDK-iOS-OSX",
625
+ "repositoryURL": "https://github.com/parse-community/Parse-SDK-iOS-OSX",
626
+ "requirementKind": "upToNextMajorVersion",
627
+ "requirementMinimumVersion": "5.1.1",
628
+ "products": [
629
+ { "productName": "ParseObjC", "frameworkName": "ParseObjC", "linkage": "host" },
630
+ { "productName": "ParseLiveQuery", "frameworkName": "ParseLiveQuery", "linkage": "embedded" }
631
+ ]
632
+ }
633
+ ]
634
+ }
635
+ ```
636
+
637
+ #### Dependency fields
638
+
639
+ | Field | Required | Default | Description |
640
+ |---|---|---|---|
641
+ | `repositoryURL` | yes | — | Git URL of the Swift package. A dependency without it is skipped with a warning. |
642
+ | `remotePackageReference` | no | last path segment of `repositoryURL` | Reference name in the generated Xcode project. |
643
+ | `requirementKind` | no | `upToNextMajorVersion` | Version resolution rule, e.g. `upToNextMajorVersion`, `upToNextMinorVersion`. |
644
+ | `requirementMinimumVersion` | no | `1.0.0` | Minimum package version to resolve. |
645
+ | `linkage` | no | `embedded` | Default linkage for every product of this dependency. |
646
+ | `products` | yes | — | Non-empty array of products to link. A dependency with no valid product is skipped with a warning. |
647
+
648
+ #### Product fields
649
+
650
+ | Field | Required | Default | Description |
651
+ |---|---|---|---|
652
+ | `productName` | yes | — | Product name as the Swift package declares it. |
653
+ | `frameworkName` | no | `productName` | Framework name in the Frameworks build phase, when it differs. |
654
+ | `linkage` | no | the dependency's `linkage` | Per-product override: `embedded` or `host`. |
655
+
656
+ #### embedded vs host
657
+
658
+ `embedded` bakes the product into the module binary. The module stays self-contained and the app's Xcode project is untouched. Use it for small, module-private dependencies.
659
+
660
+ `host` makes the CLI add the package to the app's Xcode project at build time, so the dependency exists once in the app. Use it when several modules share the same package, or when the package ships resources or dynamic frameworks the app must embed.
661
+
662
+ If two modules request the same package, it is added once. If they request conflicting version requirements, the CLI warns and uses the first requirement it sees.
663
+
664
+ #### Building
665
+
666
+ ```bash
667
+ cd mymodule/ios
668
+ ti build -p ios --build-only
669
+ ```
670
+
671
+ The zip in `dist/` now carries the package information in its `metadata.json`. App developers install the module normally; nothing extra is required of them. During an app build, lines prefixed with `[SPM]` say what was added:
672
+
673
+ ```
674
+ [INFO] [SPM] Will add 1 Swift package(s) to the app project
675
+ ```
676
+
677
+ #### Migrating off ti.spm.js
678
+
679
+ A module that ships both `spm.json` and `hooks/ti.spm.js` has the hook excluded from its packaged zip automatically. A module that still ships only the hook makes the app build log a warning. To migrate, translate the hook's package information into `spm.json`, delete `hooks/ti.spm.js`, and rebuild.
680
+
604
681
  ### Module distribution
605
682
 
606
683
  #### Packaging