---
name: aswap
description: Add ASWAP (rytm-webflow) data attributes to DOM elements — view declarations, page-transition animations, and scroll-triggered animations. Use when the user says /aswap.
argument-hint: "<partial_view> <selector> [view|scroll] [animation params...]"
---

# ASWAP — Add rytm-webflow Data Attributes

Add ASWAP controller/view declarations and show/hide animation attributes to DOM elements in PHP partial views.

## Argument syntax

```
/aswap <partial_view> <css_selector> [mode] [params...]
```

- `<partial_view>` — partial view filename without extension. Accepts either snake_case (`item_main`) or kebab-case (`item-main`) — kebab input is converted to snake_case for file lookup.
- `<css_selector>` — CSS selector for the target element (e.g. `.block`)
- `[mode]` — one of: `webflow`, `list`, `scroll`, or omitted (see Mode resolution)
- `[params...]` — animation parameters and flags (see below)

### Mode resolution

| User input | Action |
|---|---|
| `webflow` | Add `data-as-view="webflow"` + `data-as-id` (WebflowView declaration) |
| `list` | Add `data-as-view="list"` + `data-as-id` + `data-webset` (WebflowListView declaration) |
| `scroll` | Add `data-webscroll-*` animation attributes |
| omitted | Add `data-webview-*` animation attributes (page transition) |
| animation params without mode keyword | Add `data-webview-*` animation attributes |

When the mode keyword is `scroll`, the prefix is `webscroll`. Otherwise (omitted or animation params only), the prefix is `webview`.

### Flags

| Flag | Effect |
|---|---|
| `params` | Use `$item->getAswapIdWithParams()` instead of `$item->getID()` for the ID |

### Shorthand: omitted or repeated selector

When the selector is omitted, or the selector argument starts with the same kebab-case value as `<partial_view>`, resolve the selector automatically:

| User input | Resolved partial view | Resolved selector |
|---|---|---|
| `/aswap calendar-main-header-headline` | `calendar_main_header_headline` | `.calendar-main-header-headline` |
| `/aswap calendar-main-header-headline calendar-main-header-headline` | `calendar_main_header_headline` | `.calendar-main-header-headline` |
| `/aswap calendar-main-header-headline calendar-main-header-headline > div` | `calendar_main_header_headline` | `.calendar-main-header-headline > div` |

In the third case, extra tokens after the repeated value are kept as-is — prepend `.` only to the first segment.

## Steps

### 1 — Locate the partial view

Convert `<partial_view>` from kebab-case to snake_case if needed (e.g. `calendar-main-header-headline` → `calendar_main_header_headline`), then find the matching file under `public/local/views/`. The file will be named `{partial_view}.php` in a type subdirectory (e.g. `item/item_main.php`).

If not found, ask the user for the full path.

### 2 — Find the target element

Read the partial view and locate the DOM element matching `<css_selector>`.

If the selector matches multiple elements, ask the user which one to use.
If no match, report and stop.

### 3 — Determine operation

Based on mode resolution (see table above), perform either:
- **A** — View declaration (step 4)
- **B** — Animation attributes (step 5)

### 4 — View declaration (mode: `webflow` or `list`)

#### 4.1 — Build the `data-as-id` value

The ID is composed of:
1. **Partial view prefix** — an abbreviation of the partial view name, built from the first letter of each word in the filename. Examples:
   - `item_main` → `im`
   - `content_footer` → `cf`
   - `main_header_top` → `mht`
   - `item_children_content` → `ichc`
2. **Item ID** — one of:
   - `<?= $item->getID() ?>` (default)
   - `<?= $item->getAswapIdWithParams() ?>` (when `params` flag is present)

Combined: `data-as-id="{prefix}<?= $item->getID() ?>"`

#### 4.2 — Add attributes to the element

**For `webflow` mode:**
```php
<div class="..." data-as-view="webflow" data-as-id="{prefix}<?= $item->getID() ?>">
```

**For `list` mode:**
```php
<div class="..."
    data-as-view="list"
    data-as-id="{prefix}<?= $item->getAswapIdWithParams() ?>"
    data-webset="selector:{child_selector},stagger:.07">
```

For `list` mode:
- Always use `getAswapIdWithParams()` (list views are typically filterable)
- Determine the `selector` value from the DOM structure: look at the direct children of the target element and pick the repeating child wrapper class (e.g. `.it-wrapper`). If unclear, use `.it-wrapper` as default.
- Default stagger: `.07`

#### 4.3 — Write the changes

Edit the partial view file with the updated element.

### 5 — Animation attributes (mode: default/`scroll`)

#### 5.1 — Parse animation parameters

Extract parameters from the user input. Parameters use the rytm-webflow shorthand:

| Code | Property | Example |
|---|---|---|
| `o` | opacity | `o:0` |
| `x` | translateX | `x:100` |
| `y` | translateY | `y:-50` |
| `s` | scale | `s:1.2` |
| `r` | rotation | `r:90` |
| `t` | duration | `t:.5` (seconds) |
| `d` | delay | `d:.2` (seconds) |
| `e` | ease | `e:power2` |

If no animation parameters are provided, use **defaults**: opacity fade — `o:0`, `t:.5`, `e:power2`.

#### 5.2 — Build the three attribute values

Determine the attribute prefix:
- `scroll` mode → `webscroll`
- default (no mode / webview) → `webview`

**Initial state** (`data-{prefix}-initial`):
- Contains the transform/visual properties at their "hidden" state
- Only include transform properties (o, x, y, s, r), NOT timing (t, d, e)
- Example: `o:0` or `o:0,x:100` or `y:20`
- If no transform properties besides opacity are specified, use `o:0`

**Show animation** (`data-{prefix}-show`):
- Properties animate TO their "visible" state (inverse of initial)
- `o:0` in initial → `o:1` in show
- `x:100` in initial → `x:0` in show
- `y:20` in initial → `y:0` in show
- `s:0.5` in initial → `s:1` in show
- Include timing parameters: `t` (duration), `d` (delay), `e` (ease)
- Ease in show gets `.out` suffix: `e:power2` → `e:power2.out`

**Hide animation** (`data-{prefix}-hide`):
- Properties return to their "hidden" state (same values as initial for transforms)
- For simple opacity-only animations: same as initial + timing
- For transforms (x, y, s, r): hide uses ONLY `o:0` (fade out), not the transform — to keep hide fast and simple
- Include timing: same `t` as show (but capped at `.8` max), ease gets `.in` suffix
- NEVER include `d` (delay) in hide unless user explicitly requests it

#### 5.3 — Examples of attribute construction

**Default (no params):**
```
data-webview-initial="o:0"
data-webview-show="o:1,t:.5,e:power2.out"
data-webview-hide="o:0,t:.5,e:power2.in"
```

**With opacity + x transform:**
Input: `o:0, x:100 t:.65 d:.1 e:power4`
```
data-webview-initial="o:0,x:100"
data-webview-show="o:1,x:0,t:.65,d:.1,e:power4.out"
data-webview-hide="o:0,x:100,t:.65,e:power4.in"
```

**Scroll with y transform:**
Input: `scroll y:20 t:1.2 d:.2 e:power3`
```
data-webscroll-initial="y:20"
data-webscroll-show="y:0,t:1.2,d:.2,e:power3.out"
data-webscroll-hide="o:0,t:.8,e:power3.in"
```
Note: hide uses `o:0` (not `y:20`) and time is capped at `.8`.

#### 5.4 — Handle printAttrValue wrappers

If the target element is output by `$item->printAttrValue(...)`, wrap it with a `<div>` that carries the animation attributes:

```php
<div data-webview-initial="o:0" data-webview-show="o:1,t:.5,e:power2.out" data-webview-hide="o:0,t:.5,e:power2.in">
  <?= $item->printAttrValue('attr', 'classes') ?>
</div>
```

#### 5.5 — Write the changes

Edit the partial view file with the updated element.

### 6 — Report

Show the user what was added, displaying the modified element with its new attributes.
