Updated SKILL.md
This commit is contained in:
@@ -348,6 +348,124 @@ def mk_content(self):
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### DEV-CONTROL-20: HTMX Ajax Requests
|
||||||
|
|
||||||
|
**Always specify a `target` in HTMX ajax requests.**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// ❌ INCORRECT: Without target, HTMX doesn't know where to swap the response
|
||||||
|
htmx.ajax('POST', '/url', {
|
||||||
|
values: {param: value}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ CORRECT: Explicitly specify the target
|
||||||
|
htmx.ajax('POST', '/url', {
|
||||||
|
target: '#element-id',
|
||||||
|
values: {param: value}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exception:** Response contains elements with `hx-swap-oob="true"`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DEV-CONTROL-21: HTMX Swap Modes and Event Listeners
|
||||||
|
|
||||||
|
**`hx-on::after-settle` only works when the swapped element replaces the target (`outerHTML`).**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// ❌ INCORRECT: innerHTML (default) nests the returned element
|
||||||
|
// The hx-on::after-settle attribute on the returned element is never processed
|
||||||
|
htmx.ajax('POST', '/url', {
|
||||||
|
target: '#my-element'
|
||||||
|
// swap: 'innerHTML' is the default
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ CORRECT: outerHTML replaces the entire element
|
||||||
|
// The hx-on::after-settle attribute on the returned element works
|
||||||
|
htmx.ajax('POST', '/url', {
|
||||||
|
target: '#my-element',
|
||||||
|
swap: 'outerHTML'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why:**
|
||||||
|
- `innerHTML`: replaces **content** → `<div id="X"><div id="X" hx-on::...>new</div></div>` (duplicate ID)
|
||||||
|
- `outerHTML`: replaces **element** → `<div id="X" hx-on::...>new</div>` (correct)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DEV-CONTROL-22: Reinitializing Event Listeners
|
||||||
|
|
||||||
|
**After an HTMX swap, event listeners attached via JavaScript are lost and must be reinitialized.**
|
||||||
|
|
||||||
|
**Recommended pattern:**
|
||||||
|
|
||||||
|
1. Create a reusable initialization function:
|
||||||
|
```javascript
|
||||||
|
function initMyControl(controlId) {
|
||||||
|
const element = document.getElementById(controlId);
|
||||||
|
// Attach event listeners
|
||||||
|
element.addEventListener('click', handleClick);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Call this function after swap via `hx-on::after-settle`:
|
||||||
|
```python
|
||||||
|
extra_attr = {
|
||||||
|
"hx-on::after-settle": f"initMyControl('{self._id}');"
|
||||||
|
}
|
||||||
|
element.attrs.update(extra_attr)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Alternative:** Use event delegation on a stable parent element.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DEV-CONTROL-23: Avoiding Duplicate IDs with HTMX
|
||||||
|
|
||||||
|
**If the element returned by the server has the same ID as the HTMX target, use `swap: 'outerHTML'`.**
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Server returns an element with id="my-element"
|
||||||
|
def render_partial(self):
|
||||||
|
return Div(id="my-element", ...) # Same ID as target
|
||||||
|
|
||||||
|
# JavaScript must use outerHTML
|
||||||
|
htmx.ajax('POST', '/url', {
|
||||||
|
target: '#my-element',
|
||||||
|
swap: 'outerHTML' # ✅ Replaces the entire element
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why:** `innerHTML` would create `<div id="X"><div id="X">...</div></div>` (invalid duplicate ID).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### DEV-CONTROL-24: Pattern extra_attr for HTMX
|
||||||
|
|
||||||
|
**Use the `extra_attr` pattern to add post-swap behaviors.**
|
||||||
|
|
||||||
|
```python
|
||||||
|
def render_partial(self, fragment="default"):
|
||||||
|
extra_attr = {
|
||||||
|
"hx-on::after-settle": f"initControl('{self._id}');",
|
||||||
|
# Other HTMX attributes if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
element = self.mk_element()
|
||||||
|
element.attrs.update(extra_attr)
|
||||||
|
return element
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use cases:**
|
||||||
|
- Reinitialize event listeners
|
||||||
|
- Execute animations
|
||||||
|
- Update other DOM elements
|
||||||
|
- Logging or tracking events
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Complete Control Template
|
## Complete Control Template
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|||||||
21
.claude/skills/reset/SKILL.md
Normal file
21
.claude/skills/reset/SKILL.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
name: reset
|
||||||
|
description: Reset to Default Mode - return to standard Claude Code behavior without personas
|
||||||
|
disable-model-invocation: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reset to Default Mode
|
||||||
|
|
||||||
|
You are now back to **default Claude Code mode**.
|
||||||
|
|
||||||
|
Follow the standard Claude Code guidelines without any specific persona or specialized behavior.
|
||||||
|
|
||||||
|
Refer to CLAUDE.md for project-specific architecture and patterns.
|
||||||
|
|
||||||
|
## Available Personas
|
||||||
|
|
||||||
|
You can switch to specialized modes:
|
||||||
|
- `/developer` - Full development mode with validation workflow
|
||||||
|
- `/developer-control` - Control development mode with DEV-CONTROL rules
|
||||||
|
- `/technical-writer` - User documentation writing mode
|
||||||
|
- `/unit-tester` - Unit testing mode
|
||||||
Reference in New Issue
Block a user