purgetss 7.3.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,62 +56,116 @@ npm install -g purgetss@latest
56
56
 
57
57
  ---
58
58
 
59
- ## What's New in v7.2.x
59
+ Here are its main functionalities:
60
60
 
61
- FontAwesome 7 support and major internal cleanup. PurgeTSS v7.2 adds full support for FontAwesome 7, including the new CSS custom properties format. It also reduces installation size and reorganizes the codebase for better performance and maintainability.
61
+ - **Utility-First Classes**: PurgeTSS ships with 21,000+ utility classes, so you get a lot of styling options out of the box.
62
+ - **Efficient style management**: It parses all XML files to create a clean `app.tss` containing only the classes used in your project, reducing size and improving performance.
63
+ - **Customization and JIT classes**: You can customize default classes via a config file and use JIT classes for arbitrary values inside views.
64
+ - **Icon fonts integration**: Use icon fonts such as Font Awesome, Material Icons, Material Symbols, and Framework7-Icons in Buttons and Labels.
65
+ - **`fonts.tss` generation**: The `build-fonts` command creates a `fonts.tss` file with class definitions and fontFamily selectors for regular and icon fonts, with simplified options for filenames and icon prefixes.
66
+ - **`shades` command**: Generate custom color shades from a hex color without external tools.
67
+ - **Animation module**: Apply basic 2D matrix animations or transformations to elements or arrays of elements.
68
+ - **Grid system**: A two-dimensional grid system to align and distribute elements within views.
62
69
 
63
- ### Breaking changes
70
+ ---
64
71
 
65
- - Node.js 20+ required (due to the `inquirer` v13 upgrade)
66
- - Removed deprecated commands:
67
- - `copy-fonts` (use `icon-library` instead)
68
- - `build-legacy` (legacy Tailwind build removed)
69
- - Complete legacy mode removal:
70
- - All legacy-related code and conditional checks eliminated
71
- - Legacy mode no longer supported anywhere in the codebase
72
+ ## Animation Module (`purgetss.ui.js`)
72
73
 
73
- ### Major improvements
74
+ Install with `purgetss module` (or `purgetss m`). This places `purgetss.ui.js` in your project's `lib` folder.
74
75
 
75
- - FontAwesome 7 support: Works with the new `--fa:` custom properties while staying compatible with version 6.
76
- - Reduced installation size: About 45MB smaller by moving non-essential assets to dev dependencies.
77
- - Improved Unicode extraction: Better handling of short hex codes, ASCII symbols, and direct character mappings.
78
- - Optimized internal structure: Codebase split into focused modules for readability and speed.
79
- - Enhanced CLI experience: Commands grouped by purpose, with better error handling and smarter suggestions.
76
+ ### Declaring an Animation object
80
77
 
81
- ### Command improvements
78
+ ```xml
79
+ <Animation id="myAnimation" module="purgetss.ui" class="opacity-0 duration-300 ease-in" />
80
+ ```
82
81
 
83
- - `build-fonts` simplified:
84
- - Automatically detects and handles both FontAwesome 6 and 7 formats.
85
- - The `-f` flag now controls both font class names and icon prefixes using filenames.
86
- - `tailwind init`: Removed redundant flags for a cleaner initialization process.
87
- - `shades` command: Better precision when generating custom color shades.
88
- - CLI categories: Commands grouped by purpose: Setup, Development, Assets, Utilities, and Maintenance.
82
+ You can use any position, size, color, opacity, or transformation class from `utilities.tss`.
83
+
84
+ ### Available methods
85
+
86
+ | Method | Description |
87
+ | --------------------------------------- | --------------------------------------------------------------------------------------------- |
88
+ | `play(views, cb)` / `toggle(views, cb)` | Animate views from current state to the animation state. Toggles `open`/`close` on each call. |
89
+ | `open(views, cb)` | Explicitly run the `open` state animation. |
90
+ | `close(views, cb)` | Explicitly run the `close` state animation. |
91
+ | `apply(views, cb)` | Apply properties instantly without animation. |
92
+ | `draggable(views)` | Make a view or array of views draggable inside their parent. |
93
+
94
+ ### Callback event object
95
+
96
+ All callbacks (`play`, `open`, `close`, `apply`) receive an enriched event object:
97
+
98
+ ```js
99
+ {
100
+ type: String, // event type ('complete' or 'applied')
101
+ bubbles: Boolean,
102
+ cancelBubble: Boolean,
103
+ action: String, // 'play' or 'apply'
104
+ state: String, // 'open' or 'close'
105
+ id: String, // Animation object ID
106
+ targetId: String, // ID of the animated view
107
+ index: Number, // position in array (0-based)
108
+ total: Number, // total views in array
109
+ getTarget: Function // returns the animated view object
110
+ }
111
+ ```
89
112
 
90
- ### Migration guide
113
+ When animating an **array of views**, the callback is called once per view with the corresponding `index` and `total` values.
91
114
 
92
- For most users, upgrading is straightforward:
93
- ```bash
94
- npm install -g purgetss@latest
115
+ ```js
116
+ $.myAnimation.play([$.card1, $.card2, $.card3], (e) => {
117
+ console.log(`Animated ${e.index + 1} of ${e.total}`) // "Animated 1 of 3", etc.
118
+ if (e.index === e.total - 1) {
119
+ console.log('All done!')
120
+ }
121
+ })
95
122
  ```
96
123
 
97
- Key changes to note:
98
- - Node.js 20 or higher is now required.
99
- - FontAwesome 7: If you use FA7, PurgeTSS will automatically handle the new `--fa:` properties.
100
- - VS Code extension: We recommend `KevinYouu.tailwind-raw-reorder-tw4` for better compatibility with modern Tailwind versions and XML reordering.
101
- - Clean reinstall: If you run into issues, try `npm uninstall -g purgetss && npm install -g purgetss`.
124
+ ### Multi-state animations
102
125
 
103
- ---
126
+ Use `open`, `close`, and `complete` modifiers inside `animationProperties` to define different states:
104
127
 
105
- Here are its main functionalities:
128
+ ```xml
129
+ <Animation id="fadeToggle" module="purgetss.ui" class="duration-300"
130
+ animationProperties="{
131
+ open: { opacity: 1 },
132
+ close: { opacity: 0 }
133
+ }"
134
+ />
135
+ ```
106
136
 
107
- - **Utility-First Classes**: PurgeTSS ships with 21,000+ utility classes, so you get a lot of styling options out of the box.
108
- - **Efficient style management**: It parses all XML files to create a clean `app.tss` containing only the classes used in your project, reducing size and improving performance.
109
- - **Customization and JIT classes**: You can customize default classes via a config file and use JIT classes for arbitrary values inside views.
110
- - **Icon fonts integration**: Use icon fonts such as Font Awesome, Material Icons, Material Symbols, and Framework7-Icons in Buttons and Labels.
111
- - **`fonts.tss` generation**: The `build-fonts` command creates a `fonts.tss` file with class definitions and fontFamily selectors for regular and icon fonts, with simplified options for filenames and icon prefixes.
112
- - **`shades` command**: Generate custom color shades from a hex color without external tools.
113
- - **Animation module**: Apply basic 2D matrix animations or transformations to elements or arrays of elements.
114
- - **Grid system**: A two-dimensional grid system to align and distribute elements within views.
137
+ ### Draggable views
138
+
139
+ ```js
140
+ $.myAnimation.draggable($.myView)
141
+ // or with constraints:
142
+ $.myAnimation.draggable([$.card1, $.card2])
143
+ ```
144
+
145
+ Use `bounds` to restrict movement, and `drag`/`drop` modifiers for drag-state animations. Use `vertical-constraint` or `horizontal-constraint` classes to limit the drag axis.
146
+
147
+ ### Utility classes for animations
148
+
149
+ | Class pattern | Description |
150
+ | --------------------------------------------------- | ----------------------------- |
151
+ | `duration-{n}` | Animation duration in ms |
152
+ | `delay-{n}` | Delay before animation starts |
153
+ | `rotate-{n}` | 2D rotation in degrees |
154
+ | `scale-{n}` | Scale factor |
155
+ | `repeat-{n}` | Number of repeats |
156
+ | `ease-in`, `ease-out`, `ease-linear`, `ease-in-out` | Timing curve |
157
+ | `zoom-in-{n}`, `zoom-out-{n}` | Zoom animations |
158
+ | `drag-apply`, `drag-animate` | Drag interaction style |
159
+ | `vertical-constraint`, `horizontal-constraint` | Constrain drag axis |
160
+
161
+ ### Utility functions
162
+
163
+ | Function | Description |
164
+ | -------------------------------------- | -------------------------------------------------------------------------------------------------------- |
165
+ | `deviceInfo()` | Logs detailed platform and display information to the console. Works in both Alloy and Classic projects. |
166
+ | `saveComponent({ source, directory })` | Saves a view snapshot as PNG to the photo gallery. |
167
+
168
+ See the full documentation at [purgetss.com/docs/animation-module/introduction](https://purgetss.com/docs/animation-module/introduction).
115
169
 
116
170
  In short, PurgeTSS keeps styling consistent and removes a lot of repetitive UI setup work.
117
171
 
@@ -7,16 +7,16 @@
7
7
  '.fa':{ font: { fontFamily: 'FontAwesome7Free-Solid' } }
8
8
  '.fas': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
9
9
  '.far': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
10
- '.fab': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
10
+ '.fab': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
11
11
 
12
12
  '.fa-solid': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
13
13
  '.fa-regular': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
14
- '.fa-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
14
+ '.fa-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
15
15
 
16
16
  '.fontawesome': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
17
17
  '.fontawesome-solid': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
18
18
  '.fontawesome-regular': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
19
- '.fontawesome-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
19
+ '.fontawesome-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
20
20
 
21
21
  // Font Sizes
22
22
  '.fa-lg': { font: { fontSize: 21 } }
@@ -1,4 +1,4 @@
1
- // PurgeTSS v7.3.0
1
+ // PurgeTSS v7.3.1
2
2
  // Created by César Estrada
3
3
  // https://purgetss.com
4
4
 
@@ -4,20 +4,20 @@
4
4
  '.fas': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
5
5
  '.fal': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
6
6
  '.far': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
7
- '.fab': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
7
+ '.fab': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
8
8
 
9
9
  '.fa-thin': { font: { fontFamily: 'FontAwesome6Pro-Thin' } }
10
10
  '.fa-solid': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
11
11
  '.fa-light': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
12
12
  '.fa-regular': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
13
- '.fa-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
13
+ '.fa-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
14
14
 
15
15
  '.fontawesome': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
16
16
  '.fontawesome-thin': { font: { fontFamily: 'FontAwesome6Pro-Thin' } }
17
17
  '.fontawesome-solid': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
18
18
  '.fontawesome-light': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
19
19
  '.fontawesome-regular': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
20
- '.fontawesome-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
20
+ '.fontawesome-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
21
21
 
22
22
  // Font Sizes
23
23
  '.fa-1x': { font: { fontSize: 16 } }
@@ -2,16 +2,16 @@
2
2
  '.fa':{ font: { fontFamily: 'FontAwesome7Free-Solid' } }
3
3
  '.fas': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
4
4
  '.far': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
5
- '.fab': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
5
+ '.fab': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
6
6
 
7
7
  '.fa-solid': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
8
8
  '.fa-regular': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
9
- '.fa-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
9
+ '.fa-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
10
10
 
11
11
  '.fontawesome': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
12
12
  '.fontawesome-solid': { font: { fontFamily: 'FontAwesome7Free-Solid' } }
13
13
  '.fontawesome-regular': { font: { fontFamily: 'FontAwesome7Free-Regular' } }
14
- '.fontawesome-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
14
+ '.fontawesome-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
15
15
 
16
16
  // Font Sizes
17
17
  '.fa-lg': { font: { fontSize: 21 } }
@@ -4,20 +4,20 @@
4
4
  '.fas': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
5
5
  '.fal': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
6
6
  '.far': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
7
- '.fab': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
7
+ '.fab': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
8
8
 
9
9
  '.fa-thin': { font: { fontFamily: 'FontAwesome6Pro-Thin' } }
10
10
  '.fa-solid': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
11
11
  '.fa-light': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
12
12
  '.fa-regular': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
13
- '.fa-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
13
+ '.fa-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
14
14
 
15
15
  '.fontawesome': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
16
16
  '.fontawesome-thin': { font: { fontFamily: 'FontAwesome6Pro-Thin' } }
17
17
  '.fontawesome-solid': { font: { fontFamily: 'FontAwesome6Pro-Solid' } }
18
18
  '.fontawesome-light': { font: { fontFamily: 'FontAwesome6Pro-Light' } }
19
19
  '.fontawesome-regular': { font: { fontFamily: 'FontAwesome6Pro-Regular' } }
20
- '.fontawesome-brands': { font: { fontFamily: 'FontAwesome6Brands-Regular' } }
20
+ '.fontawesome-brands': { font: { fontFamily: 'FontAwesome7Brands-Regular' } }
21
21
 
22
22
  // Font Sizes
23
23
  '.fa-lg': { font: { fontSize: 21 } }
@@ -299,18 +299,18 @@ function Animation(args = {}) {
299
299
  params.playing = false
300
300
  if (typeof _cb === 'function') {
301
301
  const enrichedEvent = {
302
- // Solo propiedades seguras del event original
302
+ // Safe properties from the original event
303
303
  type: event.type,
304
304
  bubbles: event.bubbles,
305
305
  cancelBubble: event.cancelBubble,
306
- // Nuestras propiedades añadidas (solo primitivos)
306
+ // Added properties (primitives only)
307
307
  action, // 'play'
308
308
  state: params.open ? 'open' : 'close',
309
309
  id: params.id,
310
- targetId: view.id || 'unknown', // Solo el ID del view, no el objeto
310
+ targetId: view.id || 'unknown', // View ID only, not the object
311
311
  index,
312
312
  total,
313
- // Método helper para obtener el view
313
+ // Helper method to get the view
314
314
  getTarget: () => view
315
315
  }
316
316
  _cb(enrichedEvent)
@@ -340,14 +340,14 @@ function Animation(args = {}) {
340
340
  type: 'applied',
341
341
  bubbles: false,
342
342
  cancelBubble: false,
343
- // Nuestras propiedades (solo primitivos)
343
+ // Added properties (primitives only)
344
344
  action, // 'apply'
345
345
  state: params.open ? 'open' : 'close',
346
346
  id: params.id,
347
- targetId: view.id || 'unknown', // Solo el ID del view
347
+ targetId: view.id || 'unknown', // View ID only, not the object
348
348
  index,
349
349
  total,
350
- // Método helper para obtener el view
350
+ // Helper method to get the view
351
351
  getTarget: () => view
352
352
  }
353
353
  _cb(enrichedEvent)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "purgetss",
4
- "version": "7.3.0",
4
+ "version": "7.4.0",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
7
  "purgetss": "bin/purgetss"
@@ -59,7 +59,7 @@ export function dependencies(options) {
59
59
 
60
60
  // Install Tailwind CSS
61
61
  logger.info(`Installing ${chalk.green('Tailwind CSS')}`)
62
- execSync(`cd "${cwd}" && npm i -D tailwindcss && npx tailwindcss init`)
62
+ execSync(`cd "${cwd}" && npm i -D tailwindcss@3 && npx tailwindcss init`)
63
63
 
64
64
  logger.info('The dependencies and config files have been installed successfully!')
65
65
 
@@ -374,6 +374,26 @@ export function fixInvalidValues(invalidValues, currentValue) {
374
374
  return invalidValues[currentValue] || currentValue
375
375
  }
376
376
 
377
+ /**
378
+ * Recursively serialize a value for TSS output.
379
+ * Handles primitives, plain objects, and arrays of objects.
380
+ * @param {*} val - Value to serialize
381
+ * @returns {string} TSS-compatible string representation
382
+ */
383
+ function serializeValue(val) {
384
+ if (Array.isArray(val)) {
385
+ const items = val.map(item => serializeValue(item))
386
+ return `[ ${items.join(', ')} ]`
387
+ }
388
+ if (typeof val === 'object' && val !== null) {
389
+ const entries = Object.entries(val)
390
+ .map(([k, v]) => `${k}: ${serializeValue(v)}`)
391
+ .join(', ')
392
+ return `{ ${entries} }`
393
+ }
394
+ return parseValue(val)
395
+ }
396
+
377
397
  /**
378
398
  * Generate custom rules for Titanium styles
379
399
  * @param {Object} _value - Value object containing rules
@@ -399,27 +419,7 @@ export function customRules(_value, _key, changeToDash = false) {
399
419
 
400
420
  customProperties += ' {_applyProperties_},'
401
421
  } else {
402
- customProperties += ` ${theModifier}: {`
403
-
404
- let extraCustomProperties = ''
405
-
406
- _.each(theValue, (extraValue, extraModifier) => {
407
- if (typeof (extraValue) === 'object' && extraValue !== null) {
408
- customProperties += ` ${extraModifier}: {`
409
-
410
- let moreExtraCustomProperties = ''
411
-
412
- _.each(extraValue, (moreExtraValue, moreModifier) => {
413
- moreExtraCustomProperties += ` ${moreModifier}: ${parseValue(moreExtraValue)},`
414
- })
415
-
416
- customProperties += `${removeLastCharacter(moreExtraCustomProperties)} },`
417
- } else {
418
- extraCustomProperties += ` ${extraModifier}: ${parseValue(extraValue)},`
419
- }
420
- })
421
-
422
- customProperties += `${removeLastCharacter(extraCustomProperties)} },`
422
+ customProperties += ` ${theModifier}: ${serializeValue(theValue)},`
423
423
  }
424
424
  } else {
425
425
  if (theModifier === 'apply') {