@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
@@ -83,31 +83,28 @@ The official source organizes the grid utilities into these categories. The stru
83
83
 
84
84
  ### Row Placement Utilities
85
85
 
86
- Control horizontal placement of children inside a row:
86
+ The official docs list these as `start`, `end`, and `center`, but no classes with those names exist in `utilities.tss`. The grid alignment classes PurgeTSS generates are:
87
87
 
88
- | Class | Effect |
89
- | -------- | --------------------------------- |
90
- | `start` | Align to the start of the row |
91
- | `end` | Align to the end of the row |
92
- | `center` | Align to the center of the row |
88
+ | Class | Generated rule |
89
+ | -------------- | ----------------------------------------------- |
90
+ | `items-start` | `{ top: 0 }` |
91
+ | `items-end` | `{ bottom: 0 }` |
92
+ | `items-center` | `{ width: Ti.UI.FILL, height: Ti.UI.FILL }` |
93
93
 
94
- These apply to child views inside a `grid-cols-*` container and control horizontal placement within the grid cell.
94
+ ## Row Span Use Cases
95
95
 
96
- ## Row Placement Use Cases
96
+ `grid-rows-{n}` and `row-span-{n}` both set a percentage `height` on the view that carries them; neither one declares a row count for its children. `grid-rows-{n}` gives `100/n %` (`grid-rows-2` → `50%`), and `row-span-{n}` always gives `n/12` of the parent (`row-span-3` → `25%`), whatever `grid-rows-*` class appears elsewhere. To stack the children vertically, give the parent `grid-flow-row` (`layout: 'vertical'`, `height: '100%'`).
97
97
 
98
- Combining `row-span-{n}` with `grid-rows-{n}` lets you describe how an element occupies vertical space inside a grid column. The table below covers the most common combinations a Titanium UI tends to need. Every entry is verified against the `grid-rows-{n}` and `row-span-{n}` utilities described in the official source.
99
-
100
- | Pattern | Example classes | Result |
101
- | ---------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------- |
102
- | Full-height column item | `grid-rows-1` + `row-span-1` | One element fills the entire vertical space of the column. |
103
- | Two equal stacked items | `grid-rows-2` + two children no span | Two views stack vertically, each taking 50% of the column height. |
104
- | Tall hero on top, short footer at bottom | `grid-rows-12` + `row-span-9`, `row-span-3` | Hero takes 75% of the column height, footer takes 25%. |
105
- | 3-6-3 vertical split | `grid-rows-12` + `row-span-3`, `row-span-6`, `row-span-3` | Header / body / footer split. Mirrors the 3-6-3 horizontal split shown for `col-span-{n}`. |
106
- | Sidebar that spans every row | `grid-rows-4` + child with `row-span-4` | Element occupies the full height of a 4-row column. Useful for vertical separators or full-height nav. |
107
- | Two short rows above a tall row | `grid-rows-12` + `row-span-3`, `row-span-3`, `row-span-6` | Two preview cards above a larger detail panel. |
98
+ | Pattern | Children of a `grid-flow-row` parent | Result |
99
+ | ---------------------------------------- | ----------------------------------------------- | ------------------------------- |
100
+ | Full-height item | `grid-rows-1` or `row-span-12` | One view at `100%` |
101
+ | Two equal stacked items | `grid-rows-2` on each child | `50%` + `50%` |
102
+ | Tall hero on top, short footer at bottom | `row-span-9`, `row-span-3` | `75%` + `25%` |
103
+ | 3-6-3 vertical split | `row-span-3`, `row-span-6`, `row-span-3` | `25%` + `50%` + `25%` |
104
+ | Two short rows above a tall row | `row-span-3`, `row-span-3`, `row-span-6` | `25%` + `25%` + `50%` |
108
105
 
109
106
  > **Note**
110
- > Just like `col-span-{n}`, the spans you write must add up to the value declared in `grid-rows-{n}` for the layout to fill the column without leftover space.
107
+ > Just like `col-span-{n}` in a row, the `row-span-{n}` values in a column must add up to 12 to fill it without leftover space.
111
108
 
112
109
  ## Community-Discovered Patterns
113
110
 
@@ -118,8 +115,8 @@ The following notes come from community experience using the PurgeTSS grid syste
118
115
 
119
116
  ### Common Use Cases for Row Placement
120
117
 
121
- | Class | Use case |
122
- | -------- | --------------------------------- |
123
- | `start` | Left-aligned content |
124
- | `end` | Right-aligned buttons or labels |
125
- | `center` | Centered content blocks |
118
+ | Class | Use case |
119
+ | -------------- | --------------------------------------------------------------- |
120
+ | `items-start` | Pin a view to the top of its cell (`top: 0`) |
121
+ | `items-end` | Pin a view to the bottom of its cell (`bottom: 0`) |
122
+ | `items-center` | Fill the cell (`width` and `height` set to `Ti.UI.FILL`) |
@@ -27,10 +27,25 @@ Each family ships one or more variant classes, each pointing to a specific font
27
27
  | Font Awesome | Regular | `.far` | `FontAwesome7Free-Regular` |
28
28
  | Font Awesome | Brands | `.fab` | `FontAwesome7Brands-Regular` |
29
29
  | **Material Icons** | Regular | `.mi` | `MaterialIcons-Regular` |
30
+ | Material Icons | Round | `.mir` | `MaterialIconsRound-Regular` |
31
+ | Material Icons | Sharp | `.mis` | `MaterialIconsSharp-Regular` |
32
+ | Material Icons | Two Tone | `.mit` | `MaterialIconsTwoTone-Regular` |
33
+ | Material Icons | Outlined | `.mio` | `MaterialIconsOutlined-Regular` |
30
34
  | **Framework 7** | Regular | `.f7` | `Framework7-Icons` |
31
35
 
32
36
  > 💡 **TIP — Icon class names**
33
37
  > Across a family, the icon class is shared by every variant. For Material Symbols, there is one `ms-home` class; pair it with `.ms`, `.mso`, `.msr`, or `.mss` to pick the shape (outlined, rounded, or sharp). FontAwesome works the same way: `fa-home` pairs with `.fa`/`.fas` (Solid) or `.far` (Regular), while brand icons like `fa-github` need `.fab`. **The variant class chooses the font file. The icon class chooses the glyph.**
38
+ >
39
+ > Long-form aliases set the same `fontFamily`: `.fa-solid`, `.fa-regular`, `.fa-brands`, `.fontawesome`, `.fontawesome-solid`, `.fontawesome-regular`, `.fontawesome-brands`; `.material-icons`, `.material-icons-round`, `.material-icons-sharp`, `.material-icons-two-tone`, `.material-icons-outlined`; `.materialsymbol`, `.materialsymbol-rounded`, `.materialsymbol-sharp`, `.materialsymbol-outlined` (and the same names spelled `.material-symbol*`); `.f7i` and `.framework7`.
40
+
41
+ ### Size and color helpers
42
+
43
+ | Family | Classes |
44
+ |---|---|
45
+ | Font Awesome | `.fa-xs` (12), `.fa-sm` (14), `.fa-1x` (16), `.fa-lg` (21), `.fa-2x` … `.fa-10x` (32 … 160, in steps of 16) |
46
+ | Material Icons | `.mi-18`, `.mi-24`, `.mi-36`, `.mi-48`; `.mi-dark`, `.mi-dark-inactive`, `.mi-light`, `.mi-light-inactive` |
47
+ | Material Symbols | `.ms-18`, `.ms-24`, `.ms-36`, `.ms-48`; `.ms-dark`, `.ms-dark-inactive`, `.ms-light`, `.ms-light-inactive` |
48
+ | Framework 7 | `.size-14`, `.size-20`, `.size-24`, `.size-28`, `.size-32`, `.size-56`, `.size-112` |
34
49
 
35
50
  ### Full class lists
36
51
 
@@ -83,7 +98,7 @@ $ purgetss il -m -s
83
98
 
84
99
  ### CommonJS modules in Classic
85
100
 
86
- Each module exposes its existing icon lookup API plus a `families` object with `families.default`. Direct aliases are also available:
101
+ Each module exposes an `icons` map with camel-cased keys (`icons.home`, `icons.arrowLeft`), the helpers `getIcon(name)`, `setText(name, view)`, `setTitle(name, view)`, `getRandomKey()`, and `getRandomValue()`, plus a `families` object with `families.default`. `getIcon`, `setText`, and `setTitle` fall back to `'N/A'` for an unknown name. Direct aliases are also available:
87
102
 
88
103
  | Module | Direct aliases |
89
104
  | --- | --- |
@@ -188,27 +203,27 @@ To use this file:
188
203
 
189
204
  Generated `app.tss` excerpt:
190
205
  ```css
191
- // PurgeTSS v7.10.2
206
+ // PurgeTSS v7.17.1
192
207
  // Created by César Estrada
193
208
  // https://purgetss.com
194
209
 
195
- /* Ti Elements */
210
+ // Ti Elements
196
211
  'View': { width: Ti.UI.SIZE, height: Ti.UI.SIZE }
197
212
  'Window': { backgroundColor: '#FFFFFF' }
198
213
 
199
- /* Default Font Awesome */
214
+ // Default Font Awesome
200
215
  '.fa': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
201
- '.fa-home': { text: '', title: '' }
216
+ '.fa-home': { text: '\uf015', title: '\uf015' }
202
217
 
203
- /* Material Icons */
218
+ // Material Icons
204
219
  '.mi': { font: { fontFamily: 'MaterialIcons-Regular' } }
205
- '.mi-home': { text: '', title: '' }
220
+ '.mi-home': { text: '\ue88a', title: '\ue88a' }
206
221
 
207
- /* Material Symbols */
222
+ // Material Symbols
208
223
  '.ms': { font: { fontFamily: 'MaterialSymbolsOutlined-Regular' } }
209
- '.ms-home': { text: '', title: '' }
224
+ '.ms-home': { text: '\ue88a', title: '\ue88a' }
210
225
 
211
- /* Framework7 */
226
+ // Framework7
212
227
  '.f7': { font: { fontFamily: 'Framework7-Icons' } }
213
228
  '.f7-house': { text: 'house', title: 'house' }
214
229
  ```
@@ -268,20 +283,22 @@ For the underlying mechanics (how `build-fonts` reads the `.css`, options like `
268
283
  '.boxicons': { font: { fontFamily: 'boxicons' } }
269
284
  '.lineicons': { font: { fontFamily: 'LineIcons' } }
270
285
 
271
- /* Unicode Characters */
272
- /* To use your Icon Fonts in Buttons AND Labels each class sets 'text' and 'title' properties */
286
+ // Unicode Characters
287
+ // To use your Icon Fonts in Buttons AND Labels each class sets 'text' and 'title' properties
273
288
 
274
- /* boxicons.css */
275
- '.bxl-meta': { text: '', title: '' }
276
- '.bx-lemon': { text: '', title: '' }
277
- /* ... */
289
+ // boxicons.css
290
+ '.bxl-meta': { text: '\uef27', title: '\uef27' }
291
+ '.bx-lemon': { text: '\uef28', title: '\uef28' }
292
+ // ...
278
293
 
279
- /* lineicons.css */
280
- '.lni-500px': { text: '', title: '' }
281
- '.lni-add-files': { text: '', title: '' }
282
- /* ... */
294
+ // lineicons.css
295
+ '.lni-500px': { text: '\uea03', title: '\uea03' }
296
+ '.lni-add-files': { text: '\uea01', title: '\uea01' }
297
+ // ...
283
298
  ```
284
299
 
300
+ The codepoints come from whatever `.css` you place in the folder; the values above are from Boxicons 2.1.4 and LineIcons 3.0.
301
+
285
302
  ## Community-Discovered Patterns
286
303
 
287
304
  The following note reflects community experience working with icon fonts that depend on multiple glyphs per icon.
@@ -210,7 +210,7 @@ To use the example files:
210
210
  '.fas': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
211
211
  ```
212
212
 
213
- More examples in the [Tailwind TSS Sample App](https://github.com/macCesar/utilities.tss-sample-app).
213
+ More examples in the [Utilities TSS Sample App](https://github.com/macCesar/tailwind.tss-sample-app).
214
214
 
215
215
  > **WARNING: `Label`, `Button`, and `Switch` with opposite margins**
216
216
  > In Titanium, `Label`, `Button`, and `Switch` can stretch when opposite margins pin both sides of the same axis and the dimension is still implicit.
@@ -4,11 +4,10 @@ Enabling Large Titles on a Window is not a single-property change. When you pair
4
4
 
5
5
  ## The problem
6
6
 
7
- Setting `largeTitleEnabled: true` in isolation looks like it should be enough — Apple's docs suggest a single switch. In practice, omitting the two companion properties produces three distinct visual bugs that are easy to attribute to "iOS being weird" but really come from the layout engine not having enough information:
7
+ On iOS, enabling `largeTitleEnabled` by itself can cause two issues:
8
8
 
9
9
  1. **Content overlaps behind the nav bar.** The ScrollView starts at `y=0`, hidden under the translucent navigation bar. Users see the top of the list cut off and assume content is missing. This happens when `largeTitleEnabled` is set but `autoAdjustScrollViewInsets` is not.
10
- 2. **The large title flashes / renders with a delay.** On window open, the nav bar region paints empty for a frame or two, then the title pops in. With all three properties present, iOS has the layout it needs *before* the first paint, so the title is there from frame zero. Without `extendEdges`, there is a measurable shadow flash as the system recomputes the layout.
11
- 3. **Collapse glitches on scroll.** The large title shrinks to standard size as the user scrolls down — that is the whole point. But if `extendEdges` is missing, the collapse animation can stutter or skip frames because iOS has to recompute the safe-area inset for every scroll event instead of treating the nav bar as part of the content area.
10
+ 2. **The large title renders with a visible delay.** On window open, the nav bar area appears empty for a moment before the title draws. With all three properties present, iOS calculates the layout before displaying the window.
12
11
 
13
12
  The fix is not to pick the "right" property. It is to set all three together.
14
13
 
@@ -17,14 +16,14 @@ The fix is not to pick the "right" property. It is to set all three together.
17
16
  | Property | Value | What it does |
18
17
  | ---------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
19
18
  | `autoAdjustScrollViewInsets` | `true` | iOS automatically adjusts the ScrollView content insets so content starts below the nav bar instead of behind it. Without this, the ScrollView's first item sits hidden behind the translucent nav bar. |
20
- | `extendEdges` | `[Ti.UI.EXTEND_EDGE_ALL]` | Content extends under the nav and tab bars, producing the translucent blur/refraction effect Large Titles depend on. Skipping this causes the shadow flash on open and stutters the collapse animation. |
19
+ | `extendEdges` | `[Ti.UI.EXTEND_EDGE_ALL]` | Content extends behind the bars, creating the blur/translucent effect. Without it (and `autoAdjustScrollViewInsets`), the large title renders with a visible delay. |
21
20
  | `largeTitleEnabled` | `true` | Shows the oversized title in the navigation bar that collapses to standard size as the user scrolls. This is the master switch — the other two are required for it to render correctly. |
22
21
 
23
22
  Without `autoAdjustScrollViewInsets`, `extendEdges` pushes the content behind the nav bar without compensating the ScrollView insets. Without `extendEdges` + `autoAdjustScrollViewInsets`, using only `largeTitleEnabled` causes the large title to render with a visible delay: the empty nav bar area appears first, then the title draws. With all three properties, iOS calculates the layout before displaying the window.
24
23
 
25
24
  ## iOS-only — use the `ios:` modifier
26
25
 
27
- Large Title properties are iOS-only. On Android they either do nothing or raise compile-time errors. Always scope them with the `ios:` platform block in `config.cjs`, not as defaults that leak to Android.
26
+ Large Title properties are iOS-only. Scope them with the `ios:` platform block in `config.cjs`, as the official recipe does, so they are not emitted as defaults for Android.
28
27
 
29
28
  ## Global defaults in `config.cjs`
30
29
 
@@ -51,7 +50,7 @@ Generated style in `./purgetss/styles/utilities.tss`:
51
50
 
52
51
  Individual windows now only need to override `largeTitleDisplayMode` when they want different collapse behavior (e.g. detail windows).
53
52
 
54
- > **Why an `ios:` block and not an inline `ios:` prefix?** `auto-adjust-scroll-view-insets` and `extend-edges-all` are platform-specific classes — they only exist with `[platform=ios]` suffix in `utilities.tss`. The `ios:` block ensures PurgeTSS resolves the platform-suffixed version. See [apply-directive.md](./apply-directive.md) → "Platform-Specific Classes".
53
+ > **Why an `ios:` block?** The block is what produces the `'Window[platform=ios]'` selector above. The three classes themselves carry no platform suffix in `utilities.tss` (`'.auto-adjust-scroll-view-insets'`, `'.extend-edges-all'`, `'.large-title-enabled'`), so without the block the defaults would apply to every platform. Only the `large-title-display-mode-*` classes ship with `[platform=ios]`. See [apply-directive.md](./apply-directive.md) → "Platform-Specific Classes".
55
54
 
56
55
  ## NavigationWindow example
57
56
 
@@ -113,7 +112,7 @@ This overrides only the display mode, so the window still benefits from the inhe
113
112
 
114
113
  ## ScrollView pairing: `content-w-screen content-h-auto`
115
114
 
116
- When Large Titles are active, the paired ScrollView needs its content area sized so iOS can shrink/grow the title as the user scrolls. The canonical pattern:
115
+ The official NavigationWindow and TabGroup examples pair the Window with this ScrollView:
117
116
 
118
117
  ```xml
119
118
  <ScrollView class="vertical content-w-screen content-h-auto">
@@ -124,17 +123,19 @@ When Large Titles are active, the paired ScrollView needs its content area sized
124
123
  - `content-w-screen` → `contentWidth: Ti.UI.FILL`
125
124
  - `content-h-auto` → `contentHeight: Ti.UI.SIZE`
126
125
 
127
- Sizing the content height to `Ti.UI.SIZE` is what lets iOS determine whether there is enough content to allow the large title to collapse on scroll.
128
-
129
126
  ## Quick reference — class to property map
130
127
 
131
128
  | Class | Property | Value |
132
129
  | --- | --- | --- |
133
130
  | `auto-adjust-scroll-view-insets` | `autoAdjustScrollViewInsets` | `true` |
131
+ | `auto-adjust-scroll-view-insets-false` | `autoAdjustScrollViewInsets` | `false` |
134
132
  | `extend-edges-all` | `extendEdges` | `[Ti.UI.EXTEND_EDGE_ALL]` |
133
+ | `extend-edges-none` | `extendEdges` | `[Ti.UI.EXTEND_EDGE_NONE]` |
135
134
  | `large-title-enabled` | `largeTitleEnabled` | `true` |
136
135
  | `large-title-enabled-false` | `largeTitleEnabled` | `false` |
137
- | `large-title-display-mode-never` | `largeTitleDisplayMode` | `Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_NEVER` |
136
+ | `large-title-display-mode-automatic` (iOS only) | `largeTitleDisplayMode` | `Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_AUTOMATIC` |
137
+ | `large-title-display-mode-always` (iOS only) | `largeTitleDisplayMode` | `Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_ALWAYS` |
138
+ | `large-title-display-mode-never` (iOS only) | `largeTitleDisplayMode` | `Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_NEVER` |
138
139
  | `content-w-screen` | `contentWidth` | `Ti.UI.FILL` |
139
140
  | `content-h-auto` | `contentHeight` | `Ti.UI.SIZE` |
140
141
 
@@ -150,7 +151,7 @@ A recurring source of confusion: iOS `TabGroup` already wraps each `Tab` in an i
150
151
 
151
152
  ### Detail windows should opt out, not opt in
152
153
 
153
- When `theme.Window.ios.apply` sets `large-title-enabled` as a default, every pushed window inherits it. Apply `large-title-display-mode-never` on detail windows pushed via `openWindow()` so the parent keeps the collapse animation while detail screens render with a standard title. This mirrors Apple's own first-party app conventions (Settings, Mail).
154
+ When `theme.Window.ios.apply` sets `large-title-enabled` as a default, every pushed window inherits it. Apply `large-title-display-mode-never` on detail windows pushed via `openWindow()` so the parent keeps the collapse animation while detail screens render with a standard title.
154
155
 
155
156
  ### Cross-reference
156
157
 
@@ -1,14 +1,18 @@
1
1
  # Migration Guide
2
2
 
3
- This guide mirrors the official PurgeTSS changelog (see the project `README.md` / `docs/index.md`). It walks through the upgrade-relevant changes from v7.2.6 through v7.13.x, flags breaking changes, and links each section to the reference files that cover the new surface area in depth.
3
+ This guide summarizes the official PurgeTSS changelog: `CHANGELOG.md` in the package repository and the docs changelog page (`src/pages/changelog.md`, published at <https://purgetss.com/changelog>). It walks through the upgrade-relevant changes from v7.2.6 through v7.17.1, flags breaking changes, and links each section to the reference files that cover the new surface area in depth.
4
4
 
5
- Changelog source of truth: [https://github.com/macCesar/purgeTSS](https://github.com/macCesar/purgeTSS).
5
+ Changelog source of truth: [CHANGELOG.md](https://github.com/macCesar/purgetss/blob/main/CHANGELOG.md).
6
6
 
7
7
  ---
8
8
 
9
9
  <!-- TOC-START -->
10
10
  ## Contents
11
11
 
12
+ - [Upgrade to v7.17.x](#upgrade-to-v717x)
13
+ - [Upgrade to v7.16.x](#upgrade-to-v716x)
14
+ - [Upgrade to v7.15.0](#upgrade-to-v7150)
15
+ - [Upgrade to v7.14.0](#upgrade-to-v7140)
12
16
  - [Upgrade to v7.13.x](#upgrade-to-v713x)
13
17
  - [Upgrade to v7.12.x](#upgrade-to-v712x)
14
18
  - [Upgrade to v7.11.x](#upgrade-to-v711x)
@@ -16,6 +20,7 @@ Changelog source of truth: [https://github.com/macCesar/purgeTSS](https://github
16
20
  - [Upgrade to v7.9.0](#upgrade-to-v790)
17
21
  - [Upgrade to v7.8.0](#upgrade-to-v780)
18
22
  - [Upgrade to v7.7.0](#upgrade-to-v770)
23
+ - [Upgrade to v7.6.1 and v7.6.2](#upgrade-to-v761-and-v762)
19
24
  - [Upgrade to v7.6.0](#upgrade-to-v760)
20
25
  - [Upgrade to v7.5.3](#upgrade-to-v753)
21
26
  - [Upgrade to v7.5.0](#upgrade-to-v750)
@@ -28,9 +33,76 @@ Changelog source of truth: [https://github.com/macCesar/purgeTSS](https://github
28
33
 
29
34
  <!-- TOC-END -->
30
35
 
36
+ ## Upgrade to v7.17.x
37
+
38
+ v7.17.0 and v7.17.1 change two things an existing project can trip over: unknown keys in `images:` now abort the run, and the notification icon has a new filename. Full release notes in [`version-history.md`](./version-history.md).
39
+
40
+ ### Changed in v7.17.1 — `notificationicon.png` replaces `ic_stat_notify.png`
41
+
42
+ The `notification-icon` piece now writes `notificationicon.png`. `firebase.cloudmessaging` hardcodes that name (`getResource("notificationicon")`) and falls back to the opaque `appicon` when it is missing, which the status bar renders as a white blob. The meta-data snippet printed after a run now points at `@drawable/notificationicon`. See [`app-branding.md` → FCM notification icon](./app-branding.md#fcm-notification-icon).
43
+
44
+ ### Added in v7.17.0 — `images:` rejects unknown keys
45
+
46
+ The section accepts exactly five top-level keys (`quality`, `format`, `autoSync`, `confirmOverwrites`, `files`) and three keys inside each `files[]` entry (`filename`, `width`, `height`, with `filename` required). Any other key, including `width`, `opacity`, `padding` or `output` (which are CLI flags), aborts the run before anything is generated. See [`multi-density-images.md` → Unknown keys are an error](./multi-density-images.md#unknown-keys-are-an-error-v7170).
47
+
48
+ ### Fixed in v7.17.0 — ESLint scaffolding
49
+
50
+ `install-dependencies` and `create --dependencies` now install only `eslint` and `@eslint/js` and copy a flat `eslint.config.mjs`. The previous `.eslintrc.js` extending `eslint-config-axway/env-alloy` could not run under ESLint 9, so projects scaffolded since December 2025 had a lint that never ran. See [`cli-commands.md` → install-dependencies](./cli-commands.md#install-dependencies-command).
51
+
52
+ ### What to review
53
+
54
+ - If you wired `@drawable/ic_stat_notify` into `tiapp.xml` by hand, change that meta-data line to `@drawable/notificationicon` and delete the five stale `ic_stat_notify.png` files.
55
+ - Remove any misspelled or unsupported key from `images:` in `config.cjs`; the next `purgetss images` run lists every problem in one pass.
56
+ - In Alloy projects with the old `.eslintrc.js`, re-run `purgetss install-dependencies` to replace it.
57
+
58
+ ---
59
+
60
+ ## Upgrade to v7.16.x
61
+
62
+ v7.16.0 through v7.16.2 are additive — **no breaking changes**. Full release notes in [`version-history.md`](./version-history.md).
63
+
64
+ - **Rounded non-icon artwork (v7.16.0).** `brand.artworkCornerRadius` (default `'0%'`, which keeps previous output unchanged) rounds the iPhone launch images, Android legacy splashes, Feature Graphic and LaunchLogo; those four pieces also accept `cornerRadius`, and `brand.splashCornerRadius` is a splash-only shared override. Six matching CLI flags exist. `cornerRadius` on any other piece, or outside `0–50`, stops the run before writing. See [`cli-commands.md` → brand](./cli-commands.md#brand-command).
65
+ - **`--appicon-padding <n>` (v7.16.0)** — one-run override for `brand.appicon.padding` (default `10%`).
66
+ - **Alloy hook diagnostics (v7.16.1).** The synchronous `alloy.jmk` hook inherits PurgeTSS output, so validation details appear before Alloy's generic `Command failed: purgetss`, followed by a hint to run `purgetss` from the project root. Existing active or disabled hooks are updated automatically without changing their enabled state.
67
+ - **`build-fonts --module` (v7.16.2)** exports every processed TTF/OTF PostScript name through `families`, including text-only collections. See [`custom-fonts.md` → Using `--module`](./custom-fonts.md#using---module).
68
+ - **Classic color commands (v7.16.2)** — `shades` and `color-module` no longer create empty `purgetss/brand/`, `purgetss/fonts/`, or `purgetss/images/` folders in Classic.
69
+
70
+ ---
71
+
72
+ ## Upgrade to v7.15.0
73
+
74
+ v7.15.0 opens the standalone commands to Titanium Classic and changes one default for `images`. Full release notes in [`version-history.md`](./version-history.md).
75
+
76
+ - **Classic support** — `images`, `semantic`, `shades`, `color-module`, `module`, `icon-library`, and `build-fonts` detect the project layout and write to native `Resources/` paths without installing the Alloy hook. See [`classic-projects.md`](./classic-projects.md).
77
+ - **Behavior change — `images` follows `<deployment-targets>` in `tiapp.xml`.** A normal run skips disabled platforms; `--android` and `--ios` remain explicit overrides.
78
+ - **Icon-font modules expose font-family aliases** — every module exports `families.default` plus variant aliases; existing `icons`, `getIcon`, `setText` APIs are unchanged. See [`icon-fonts.md`](./icon-fonts.md).
79
+
80
+ ### What to review
81
+
82
+ - If a project disables one platform in `tiapp.xml` but relied on `purgetss images` generating both, pass `--android` or `--ios` explicitly.
83
+
84
+ ---
85
+
86
+ ## Upgrade to v7.14.0
87
+
88
+ v7.14.0 changes generated icon output on upgrade. Full release notes in [`version-history.md`](./version-history.md).
89
+
90
+ - **Behavior change — square iOS/store artwork is full-bleed by default.** `icon`, `dark`, `tinted` and `marketplace` now default to `0%` padding instead of `4%`. `--ios-padding` still adjusts all four.
91
+ - **Fix that changes output — `brand.legacyIcon.padding` is the real per-side inset.** The generator used to multiply the value by 60%, so the documented `10%` rendered as `6%`.
92
+ - **Fix that changes output — `DefaultIcon.png` uses `brand.icon.padding`** instead of inheriting the adaptive `18%`; both root icon files are flattened to opaque output.
93
+ - **Behavior change — `brand` follows `<deployment-targets>` in `tiapp.xml`.** iOS pieces are skipped when both `iphone` and `ipad` are disabled, Android pieces when `android` is disabled; `--only` remains an explicit override.
94
+ - **Standalone Classic `brand`** creates `purgetss/config.cjs` when missing, and Classic Android keeps the 11 `Resources/android/images/res-*` splash variants.
95
+ - **Visible-frame warning** when a padded icon piece would expose a background that contrasts with the artwork's edge.
96
+
97
+ ### What to review
98
+
99
+ - Compare regenerated `DefaultIcon*.png`, `iTunesConnect.png`, `MarketplaceArtwork.png` and `ic_launcher.png` against the previous set. If your iOS source is a logo that needs breathing room, raise `brand.icon.padding` or pass `--ios-padding`.
100
+
101
+ ---
102
+
31
103
  ## Upgrade to v7.13.x
32
104
 
33
- **This is the one release in the 7.x line with breaking changes.** They are confined to `purgetss brand`: its flags, the names of the files in `purgetss/brand/`, and the shape of the `brand:` config block. Nothing outside branding is affected — utility classes, `apply:`, `theme`, `images` and the SVG pipeline are untouched. Full release notes in [`version-history.md`](./version-history.md).
105
+ **Breaking changes, confined to `purgetss brand`:** its flags, the names of the files in `purgetss/brand/`, and the shape of the `brand:` config block. Nothing outside branding is affected — utility classes, `apply:`, `theme`, `images` and the SVG pipeline are untouched. Full release notes in [`version-history.md`](./version-history.md).
34
106
 
35
107
  ### Breaking — `brand` flags renamed, no aliases kept
36
108
 
@@ -317,6 +389,21 @@ brand: {
317
389
 
318
390
  ---
319
391
 
392
+ ## Upgrade to v7.6.1 and v7.6.2
393
+
394
+ Both releases are additive — **no breaking changes**.
395
+
396
+ - **Confirmation prompt (v7.6.1).** `brand` and `images` ask `Continue? [y/N/a]` before overwriting project files. `a` persists `confirmOverwrites: false` in the matching config section; the prompt is skipped when `stdin` is not a TTY, with `-y` / `--yes`, or with `PURGETSS_YES=1`.
397
+ - **Disproportionate-viewBox warning (v7.6.1)** for SVGs above 4096 pt on any side, with adaptive rasterization density so Affinity/Illustrator exports no longer exceed Sharp's pixel limit.
398
+ - **`init` creates `purgetss/{fonts,brand,images}/` (v7.6.1)** from the first run.
399
+ - **`semantic` works in Classic (v7.6.2)** — writes `Resources/semantic.colors.json`; Alloy keeps `app/assets/semantic.colors.json`. Unrelated existing entries are preserved.
400
+
401
+ ### What to review
402
+
403
+ - CI jobs or scripts that run `brand` or `images` in a TTY need `-y` or `PURGETSS_YES=1` to avoid waiting on the prompt.
404
+
405
+ ---
406
+
320
407
  ## Upgrade to v7.6.0
321
408
 
322
409
  v7.6.0 introduces three new CLI commands for app-asset generation plus two new `config.cjs` sections. None of the additions are breaking — existing projects continue to work untouched, and the new config sections are auto-injected on first run.
@@ -331,8 +418,8 @@ v7.6.0 introduces three new CLI commands for app-asset generation plus two new `
331
418
 
332
419
  ### New `config.cjs` sections
333
420
 
334
- - **`brand:` section** — configures padding percentages, background colors, and platform targets for the `brand` command.
335
- - **`images:` section** — configures scale factors and output density mapping for the `images` command.
421
+ - **`brand:` section** — configures padding percentages, background colors, the dark-icon background, and the opt-in splash and notification icons for the `brand` command.
422
+ - **`images:` section** — configures output `quality` and `format` for the `images` command.
336
423
 
337
424
  Percentages can be written as self-documenting strings (e.g. `'15%'`) or plain numbers. Both are accepted. These sections are auto-injected into older `config.cjs` files on the first run of v7.6.0.
338
425
 
@@ -348,7 +435,7 @@ Percentages can be written as self-documenting strings (e.g. `'15%'`) or plain n
348
435
  - [`semantic-colors.md`](./semantic-colors.md) — palette vs single-color modes, alpha handling, and config mapping.
349
436
  - [`cli-commands.md#brand-command`](./cli-commands.md#brand-command)
350
437
  - [`cli-commands.md#images-command`](./cli-commands.md#images-command)
351
- - [`cli-commands.md#semantic-command`](./cli-commands.md#semantic-command)
438
+ - [`color-commands.md#semantic-command`](./color-commands.md#semantic-command)
352
439
 
353
440
  ---
354
441
 
@@ -359,7 +446,7 @@ v7.5.3 is a feature-and-polish release. No breaking changes.
359
446
  ### Added
360
447
 
361
448
  - **Appearance module** — a new `Appearance` export for Light/Dark/System mode switching with persistence. Exposed methods: `init()`, `set(mode)`, `get()`, `toggle()`.
362
- - **Default font family classes** — `font-sans`, `font-serif`, and `font-mono` are generated automatically with platform-appropriate values (system sans, serif, and monospace stacks for iOS and Android).
449
+ - **Default font family classes** — `font-sans`, `font-serif`, and `font-mono` are generated automatically with platform-appropriate values (`Helvetica Neue` / `sans-serif`, `Georgia` / `serif`, and `monospace` on iOS / Android).
363
450
  - **XML validation** — the pre-validation pass now detects illegal `--` sequences inside XML comments, which previously produced cryptic downstream errors.
364
451
 
365
452
  ### What to review
@@ -379,7 +466,7 @@ v7.5.0 adds `extend` support for component defaults and improves how `apply` dir
379
466
 
380
467
  ### Added
381
468
 
382
- - **`extend` support for Window, View, and ImageView** — customize component defaults from `theme.extend` in `config.cjs`. Previously only a subset of components supported `extend`.
469
+ - **`extend` support for Window, View, and ImageView** — customize component defaults from `theme.extend` in `config.cjs`. Previously `theme.extend.Window` (and `View`, `ImageView`) was silently ignored; only `theme.Window` worked.
383
470
  - **Shorthand `apply`** — `{ apply: '...' }` is automatically normalized, so the `default:` wrapper is now optional.
384
471
  - **Property deduplication** — values pulled in via `apply` now win over static defaults instead of producing duplicate property entries in the generated TSS.
385
472
  - **Automatic platform resolution** — classes referenced inside `ios:` / `android:` blocks automatically find their platform-specific version instead of requiring explicit disambiguation.
@@ -516,16 +603,20 @@ If you previously worked around this by inlining the gradient directly in TSS, r
516
603
  ## Quick Checklist
517
604
 
518
605
  - Replace every legacy `tailwind.tss` reference with `utilities.tss`.
519
- - Verify Node.js 20+ before upgrading past v7.3.0.
606
+ - Verify Node.js 20+ before upgrading to v7.2.7 or later.
520
607
  - Rebuild after updating `config.cjs` or custom gradient rules.
521
608
  - Re-test any Classic Titanium code that depends on `deviceInfo()`.
522
609
  - After v7.5.0: diff generated `utilities.tss` to confirm property deduplication produces the expected output.
523
610
  - After v7.5.3: consider wiring `Appearance.init()` at app boot if you want runtime Light/Dark switching.
524
611
  - After v7.6.0: run `brand`, `images`, and `semantic` once in a scratch project before pointing them at production assets, so you can preview the output layout.
525
612
  - After v7.7.0: migrate the `brand:` block in `config.cjs` to the grouped schema (`logos`, `padding`, `android`, `ios`, `colors`). v7.10.2 auto-migrates flat configs in memory. Moot from v7.13.0, which rewrites the block on disk to the per-piece structure by itself.
526
- - After v7.8.0: run the build once and address every `Class Syntax Error` it surfaces. Update CI to handle the new hard-fail on malformed class names. Migrate any `top-[10px]` style square brackets to `top-(10px)` parentheses.
613
+ - After v7.8.0: run the build once and address every `Class Syntax Error` it surfaces. Update CI to handle the new hard-fail on malformed class names. Migrate any `top-[10px]` style square brackets to unitless parentheses, `top-(10)`.
527
614
  - After v7.9.0: search for any `purgetss/experimental/tailwind-classes/` references in tooling/CI and update to `purgetss/glossary/tailwind-classes/`. If a project used top-level `theme.Window` / `View` / `ImageView` and depended on framework defaults being merged in, decide between moving the config under `theme.extend.*` or adding the previously-implicit utilities to the `apply` string.
528
615
  - After v7.10.0: deeply nested color families (`theme.extend.colors.brand.primary.500`) now emit recursively — restructure by domain if it improves readability. `apply:` with bundled icon fonts (`fas`, `mi-*`, `ms-*`, `f7-*`) no longer requires `build-fonts` first. The Google Play Feature Graphic ships automatically with `purgetss brand`.
529
616
  - After v7.11.0: reference `.svg` images with numeric `w-*`/`h-*` classes to opt into the compile-time SVG pipeline (add `purgetss/.cache/` to `.gitignore`). Ensure every `theme.fontFamily.*` value is a string, not a Tailwind-style array, or the new config validator hard-fails. Use `images.files` to pin per-file sizes and `images.autoSync: false` to stop the pipeline writing back to `config.cjs`.
530
617
  - After v7.12.1: re-run `purgetss brand --notes` if you had copied an earlier Android splash snippet — the theme now belongs on the launcher Activity, not on `<application>`. Run `purgetss icon-library -v=fa` to pick up Font Awesome 7.3.1.
531
618
  - After v7.13.0: grep build scripts, `alloy.jmk` and CI for the renamed `brand` flags (`--splash`, `--notification`, `--splash-logo`, `--feature-logo`, `--legacy-splash`) — no aliases were kept. Rename any `logo-icon.*` used as the Android launcher mark to `logo-adaptive.*`, or the launcher icons silently fall back to the main logo. Let `config.cjs` rewrite its own `brand:` block, then read the diff.
619
+ - After v7.14.0: compare the regenerated iOS/store icons (now full-bleed `0%`) and `ic_launcher.png` (real `10%` inset) against the previous set.
620
+ - After v7.15.0: if one platform is disabled in `tiapp.xml`, pass `--android` or `--ios` to `purgetss images` when you still need that platform's densities.
621
+ - After v7.17.0: remove unknown keys from `images:` and re-run `purgetss install-dependencies` in Alloy projects that still have `.eslintrc.js`.
622
+ - After v7.17.1: point the FCM meta-data at `@drawable/notificationicon` and delete the old `ic_stat_notify.png` files.