solid-tom-ui 1.0.11 → 1.0.15

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 (119) hide show
  1. package/README.md +246 -246
  2. package/dist/README.md +246 -246
  3. package/dist/components/avatar/avatar.js.map +1 -1
  4. package/dist/components/badge/badge.js.map +1 -1
  5. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  6. package/dist/components/button/button.js.map +1 -1
  7. package/dist/components/carousel/carousel.js.map +1 -1
  8. package/dist/components/chat-bubble/chatBubble.js.map +1 -1
  9. package/dist/components/checkbox/checkbox.js.map +1 -1
  10. package/dist/components/collapse/collapse.js.map +1 -1
  11. package/dist/components/context-menu/context-menu.js.map +1 -1
  12. package/dist/components/context-menu/context-menu.store.js.map +1 -1
  13. package/dist/components/divider/divider.js.map +1 -1
  14. package/dist/components/dropdown/dropdown.js.map +1 -1
  15. package/dist/components/dropdown/dropdown.store.js.map +1 -1
  16. package/dist/components/float-button/float-button.js.map +1 -1
  17. package/dist/components/hover-3d-image/hover-3d-image.js.map +1 -1
  18. package/dist/components/image-preview/image-preview.js.map +1 -1
  19. package/dist/components/input/input.js.map +1 -1
  20. package/dist/components/input/input.utils.js.map +1 -1
  21. package/dist/components/input/variants/input-color.js.map +1 -1
  22. package/dist/components/input/variants/input-date.js.map +1 -1
  23. package/dist/components/input/variants/input-number.d.ts.map +1 -1
  24. package/dist/components/input/variants/input-number.js +1 -1
  25. package/dist/components/input/variants/input-number.js.map +1 -1
  26. package/dist/components/input/variants/input-otp.js.map +1 -1
  27. package/dist/components/input/variants/input-password.js.map +1 -1
  28. package/dist/components/input/variants/input-radio.js.map +1 -1
  29. package/dist/components/input/variants/input-range.js.map +1 -1
  30. package/dist/components/input/variants/input-text.d.ts.map +1 -1
  31. package/dist/components/input/variants/input-text.js +1 -1
  32. package/dist/components/input/variants/input-text.js.map +1 -1
  33. package/dist/components/input/variants/input-textarea.js.map +1 -1
  34. package/dist/components/loading/loading.js.map +1 -1
  35. package/dist/components/mansory/mansory.js.map +1 -1
  36. package/dist/components/menu/menu.js.map +1 -1
  37. package/dist/components/modal/modal.js.map +1 -1
  38. package/dist/components/modal/modalContext.js.map +1 -1
  39. package/dist/components/pagination/pagination.js.map +1 -1
  40. package/dist/components/progress-bar/progress-bar.js.map +1 -1
  41. package/dist/components/qr-code/qr-code.js.map +1 -1
  42. package/dist/components/select/select.js +1 -1
  43. package/dist/components/select/select.js.map +1 -1
  44. package/dist/components/select-zone/select-zone.js.map +1 -1
  45. package/dist/components/skeleton/skeleton.js.map +1 -1
  46. package/dist/components/slider/slider.js.map +1 -1
  47. package/dist/components/splitter/splitter.js.map +1 -1
  48. package/dist/components/steps/steps.js.map +1 -1
  49. package/dist/components/swap/swap.js.map +1 -1
  50. package/dist/components/switch/switch.js.map +1 -1
  51. package/dist/components/tab/tab.js.map +1 -1
  52. package/dist/components/table/table.js.map +1 -1
  53. package/dist/components/timeline/timeline.js.map +1 -1
  54. package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
  55. package/dist/components/toast/icons/IconCircle.js.map +1 -1
  56. package/dist/components/toast/icons/InfoIcon.js.map +1 -1
  57. package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
  58. package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
  59. package/dist/components/toast/icons/WarningIcon.js.map +1 -1
  60. package/dist/components/toast/toast.js.map +1 -1
  61. package/dist/components/toast/toast.store.js.map +1 -1
  62. package/dist/components/tooltip/tooltip.js.map +1 -1
  63. package/dist/components/tour/tour.js.map +1 -1
  64. package/dist/components/upload/upload.js.map +1 -1
  65. package/dist/components/z-index/z-index.context.js.map +1 -1
  66. package/dist/components/z-index/z-index.js.map +1 -1
  67. package/dist/components/z-index/z-index.store.js.map +1 -1
  68. package/dist/components/z-index/z-index.types.js.map +1 -1
  69. package/dist/package.json +1 -1
  70. package/dist/skill/avatar.skill.md.txt +255 -255
  71. package/dist/skill/badge.skill.md.txt +223 -223
  72. package/dist/skill/breadcrumb.skill.md.txt +177 -177
  73. package/dist/skill/button.skill.md.txt +198 -198
  74. package/dist/skill/carousel.skill.md.txt +406 -406
  75. package/dist/skill/chat-bubble.skill.md.txt +342 -342
  76. package/dist/skill/checkbox.skill.md.txt +326 -326
  77. package/dist/skill/code-preview.skill.md.txt +240 -240
  78. package/dist/skill/collapse.skill.md.txt +329 -329
  79. package/dist/skill/context-menu.skill.md.txt +233 -233
  80. package/dist/skill/diff.skill.md.txt +244 -244
  81. package/dist/skill/divider.skill.md.txt +151 -151
  82. package/dist/skill/doc.skill.md.txt +191 -191
  83. package/dist/skill/drawer.skill.md.txt +157 -157
  84. package/dist/skill/dropdown.skill.md.txt +198 -198
  85. package/dist/skill/float-button.skill.md.txt +315 -315
  86. package/dist/skill/hover-3d-image.skill.md.txt +120 -120
  87. package/dist/skill/iframe.skill.md.txt +114 -114
  88. package/dist/skill/image-preview.skill.md.txt +162 -162
  89. package/dist/skill/indicator.skill.md.txt +60 -60
  90. package/dist/skill/input.skill.md.txt +489 -489
  91. package/dist/skill/loading.skill.md.txt +127 -127
  92. package/dist/skill/menu.skill.md.txt +476 -476
  93. package/dist/skill/modal.skill.md.txt +359 -359
  94. package/dist/skill/pagination.skill.md.txt +405 -405
  95. package/dist/skill/progress-bar.skill.md.txt +207 -207
  96. package/dist/skill/qr-code.skill.md.txt +136 -136
  97. package/dist/skill/rating.skill.md.txt +167 -167
  98. package/dist/skill/select-zone.skill.md.txt +93 -93
  99. package/dist/skill/select.skill.md.txt +663 -663
  100. package/dist/skill/skeleton.skill.md.txt +192 -192
  101. package/dist/skill/slider.skill.md.txt +404 -404
  102. package/dist/skill/splitter.skill.md.txt +411 -411
  103. package/dist/skill/steps.skill.md.txt +264 -264
  104. package/dist/skill/swap.skill.md.txt +139 -139
  105. package/dist/skill/switch.skill.md.txt +191 -191
  106. package/dist/skill/tab.skill.md.txt +484 -484
  107. package/dist/skill/table.example.header.md.txt +666 -666
  108. package/dist/skill/table.skill.md.txt +1407 -1407
  109. package/dist/skill/text-rotate.skill.md.txt +186 -186
  110. package/dist/skill/timeline.skill.md.txt +247 -247
  111. package/dist/skill/toast.skill.md.txt +531 -531
  112. package/dist/skill/tooltip.skill.md.txt +222 -222
  113. package/dist/skill/tour.skill.md.txt +156 -156
  114. package/dist/skill/upload.skill.md.txt +358 -358
  115. package/dist/utils/cn.js.map +1 -1
  116. package/dist/utils/element-tracker.js.map +1 -1
  117. package/dist/utils/helper.js.map +1 -1
  118. package/dist/utils/hoc.js.map +1 -1
  119. package/package.json +132 -133
@@ -1,244 +1,244 @@
1
- ## COMPONENT IDENTITY
2
- - **Import**: `import { Diff } from 'solid-tom-ui';`
3
- - **Export**: `Diff` (named export)
4
- - **Framework**: SolidJS
5
- - **Purpose**: Interactive image/content comparison slider — user drags a resizer to reveal left vs right panels; NOT a `ParentComponent`, content passed via `images` prop array
6
-
7
- ---
8
-
9
- ## TYPE SIGNATURE
10
-
11
- ```ts
12
- type DiffProps = {
13
- images: SolidComponent[]; // REQUIRED — must be exactly 2 elements
14
- class?: string; // extra classes on root <figure>
15
- };
16
- ```
17
-
18
- ## CLASS SLOTS
19
-
20
- `Diff` is a single-element component — the `class` prop targets the root `<figure>` only. There are no named slots.
21
-
22
- > **CSS encoding**: internal CSS classes follow the project convention using short encoded names (e.g. `df01`, `df02`). Do not reference DaisyUI's `diff-item-1` / `diff-item-2` class names directly in your own styles — use the `class` prop or wrap with your own container.
23
-
24
- ---
25
-
26
- ## PROP REFERENCE
27
-
28
- | Prop | Type | Required | Description |
29
- | -------- | ------------------ | -------- | ------------------------------------------------------------------------------------- |
30
- | `images` | `SolidComponent[]` | ✅ YES | Array of **exactly 2** JSX elements — index `0` = left panel, index `1` = right panel |
31
- | `class` | `string` | ❌ NO | Extra Tailwind classes appended to the root `<figure>` element |
32
-
33
- ---
34
-
35
- ## HARD CONSTRAINT: `images` must have exactly 2 elements
36
-
37
- - Passing fewer or more than 2 elements → component returns `<></>` (renders nothing) and fires `console.warn('You need to provide exactly 2 images')`
38
- - There is no partial rendering fallback — the entire component is suppressed
39
-
40
- ```ts
41
- // ✅ Valid
42
- images={[<img src="a.webp" />, <img src="b.webp" />]}
43
-
44
- // ❌ Invalid — renders nothing
45
- images={[<img src="a.webp" />]}
46
- images={[<img src="a.webp" />, <img src="b.webp" />, <img src="c.webp" />]}
47
- ```
48
-
49
- ---
50
-
51
- ## INTERNAL DOM STRUCTURE
52
-
53
- ```
54
- <figure class="diff aspect-video [class]" tabindex="0">
55
-
56
- ├── <div class="diff-item-1" role="img" tabindex="0">
57
- │ {images[0]} ← LEFT panel (revealed by dragging resizer right)
58
- │ </div>
59
-
60
- ├── <div class="diff-item-2" role="img">
61
- │ {images[1]} ← RIGHT panel (base/background layer)
62
- │ </div>
63
-
64
- └── <div class="diff-resizer"></div> ← invisible drag handle
65
- ```
66
-
67
- ### Layer rendering order
68
-
69
- - `diff-item-2` (right/background) renders behind — visible in full by default
70
- - `diff-item-1` (left/foreground) renders on top with `z-index: 1`, clipped by the resizer position
71
- - Dragging resizer RIGHT → reveals more of `images[0]` (left panel)
72
- - Dragging resizer LEFT → reveals more of `images[1]` (right panel)
73
-
74
- ---
75
-
76
- ## INTERACTION MECHANISM — CSS-only, no JS state
77
-
78
- The slider is driven entirely by CSS using a native `resize: horizontal` invisible div (`.diff-resizer`):
79
-
80
- - Default resizer position: `width: 50cqi` → panels shown 50/50
81
- - Resizer `min-width: 1rem`, `max-width: calc(100cqi - 1rem)` — cannot be dragged beyond edges
82
- - **Keyboard accessible**: `<figure tabindex="0">` and `<div class="diff-item-1" tabindex="0">` both focusable
83
- - Focus on `<figure>` → resizer snaps to `min-width: 95cqi` (left panel nearly full)
84
- - Focus on `diff-item-1` → resizer snaps to `min-width: 5cqi` (right panel nearly full)
85
- - Snap transitions animated with `transition: min-width 0.3s ease-out`
86
-
87
- Agents do NOT manage any open/close or drag state — it is fully CSS-driven.
88
-
89
- ---
90
-
91
- ## CONTENT RULES FOR `images[0]` AND `images[1]`
92
-
93
- Both slots accept **any JSX element**, not just `<img>`. Internal CSS applies to all direct children:
94
-
95
- ```css
96
- /* Applied to direct children of both diff-item-1 and diff-item-2 */
97
- position: absolute;
98
- top: 0;
99
- bottom: 0;
100
- left: 0;
101
- height: 100%;
102
- width: 100cqi;
103
- object-fit: cover;
104
- object-position: center;
105
- pointer-events: none;
106
- ```
107
-
108
- ### What this means for agents:
109
-
110
- - **`<img>`**: works perfectly — `object-fit: cover` is applied automatically
111
- - **`<div>`**: also works — div fills the full panel area. Use `grid place-content-center` or flex for internal layout
112
- - **Interactive elements inside panels**: will NOT work — `pointer-events: none` is applied to all children. Do NOT put buttons, links, or inputs inside `images`
113
- - **Do NOT add layout wrappers** around the img/div — children are positioned absolutely with `width: 100cqi`
114
-
115
- ---
116
-
117
- ## ASPECT RATIO
118
-
119
- - Root `<figure>` always has class `aspect-video` (16:9 ratio) applied by default
120
- - To change aspect ratio, override via `class` prop:
121
-
122
- ```tsx
123
- // Square
124
- <Diff images={[...]} class="aspect-square" />
125
-
126
- // Custom ratio
127
- <Diff images={[...]} class="aspect-4/3" />
128
-
129
- // Fixed height
130
- <Diff images={[...]} class="h-100" />
131
- ```
132
-
133
- ---
134
-
135
- ## USAGE PATTERNS
136
-
137
- ### Pattern 1 — Image vs image (most common)
138
-
139
- ```tsx
140
- <Diff
141
- images={[
142
- <img alt="before" src="/images/before.webp" />,
143
- <img alt="after" src="/images/after.webp" />,
144
- ]}
145
- />
146
- ```
147
-
148
- ### Pattern 2 — Image vs custom div content
149
-
150
- ```tsx
151
- <Diff
152
- images={[
153
- <img alt="photo" src="/images/photo.webp" />,
154
- <div class="bg-base-200 text-base-content grid place-content-center text-6xl font-black">
155
- BEFORE
156
- </div>,
157
- ]}
158
- />
159
- ```
160
-
161
- ### Pattern 3 — Custom aspect ratio
162
-
163
- ```tsx
164
- <Diff
165
- class="aspect-square w-100"
166
- images={[
167
- <img alt="original" src="/images/original.webp" />,
168
- <img alt="filtered" src="/images/filtered.webp" />,
169
- ]}
170
- />
171
- ```
172
-
173
- ### Pattern 4 — Two styled div panels
174
-
175
- ```tsx
176
- <Diff
177
- images={[
178
- <div class="bg-primary text-primary-content grid place-content-center text-4xl font-bold">
179
- Dark Mode
180
- </div>,
181
- <div class="bg-base-100 text-base-content grid place-content-center text-4xl font-bold">
182
- Light Mode
183
- </div>,
184
- ]}
185
- />
186
- ```
187
-
188
- ---
189
-
190
- ## BEHAVIOR NOTES FOR AGENTS
191
-
192
- 1. **`images[0]` = left (foreground), `images[1]` = right (background)** — the order determines which panel is clipped by the drag handle. Left panel sits on top and is revealed by dragging right.
193
-
194
- 2. **Component is a `<figure>` element** — semantically appropriate for media comparison. Root is not a `<div>`.
195
-
196
- 3. **`pointer-events: none` on all panel children** — nothing inside `images[0]` or `images[1]` can be clicked, hovered, or interacted with. Only the resizer handle is interactive.
197
-
198
- 4. **No JS drag state** — the drag interaction is entirely driven by the native browser `resize: horizontal` CSS property on `.diff-resizer`. No SolidJS signals or event handlers involved.
199
-
200
- 5. **`class` prop targets the root `<figure>` only** — cannot target internal `.diff-item-1`, `.diff-item-2`, or `.diff-resizer` via this prop.
201
-
202
- 6. **Width fills container** — root `<figure>` has `width: 100%`. Wrap in a sized container or use `class="w-[500px]"` to constrain.
203
-
204
- ---
205
-
206
- ## COMMON MISTAKES TO AVOID
207
-
208
- | Mistake | Correct approach |
209
- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
210
- | Passing 1 or 3+ items in `images` | Always pass exactly 2 elements — no more, no less |
211
- | Putting interactive elements (buttons, links) inside `images` | `pointer-events: none` blocks all interactions inside panels |
212
- | Wrapping `<img>` in an extra `<div>` | Pass `<img>` directly — children are already positioned absolutely to fill the panel |
213
- | Expecting `class` to style inner panels | `class` only applies to the root `<figure>` |
214
- | Assuming left panel is `images[1]` | `images[0]` = left/foreground (clipped), `images[1]` = right/background |
215
- | Using without a sized container | Add `w-full`, `w-[Npx]` or similar to control width |
216
-
217
- ---
218
-
219
- ## FULL EXAMPLE
220
-
221
- ```tsx
222
- import { Diff } from 'solid-tom-ui';
223
-
224
- // Image comparison
225
- <Diff
226
- images={[
227
- <img alt="sharp" src="/images/sharp.webp" />,
228
- <img alt="blurred" src="/images/blurred.webp" />,
229
- ]}
230
- />
231
-
232
- // Image vs label panel, square aspect
233
- <Diff
234
- class="aspect-square w-full max-w-lg"
235
- images={[
236
- <img alt="photo" src="/images/photo.webp" />,
237
- <div class="bg-neutral text-neutral-content grid place-content-center text-5xl font-black">
238
- Solid UI
239
- </div>,
240
- ]}
241
- />
242
- ```
243
-
244
- > **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
1
+ ## COMPONENT IDENTITY
2
+ - **Import**: `import { Diff } from 'solid-tom-ui';`
3
+ - **Export**: `Diff` (named export)
4
+ - **Framework**: SolidJS
5
+ - **Purpose**: Interactive image/content comparison slider — user drags a resizer to reveal left vs right panels; NOT a `ParentComponent`, content passed via `images` prop array
6
+
7
+ ---
8
+
9
+ ## TYPE SIGNATURE
10
+
11
+ ```ts
12
+ type DiffProps = {
13
+ images: SolidComponent[]; // REQUIRED — must be exactly 2 elements
14
+ class?: string; // extra classes on root <figure>
15
+ };
16
+ ```
17
+
18
+ ## CLASS SLOTS
19
+
20
+ `Diff` is a single-element component — the `class` prop targets the root `<figure>` only. There are no named slots.
21
+
22
+ > **CSS encoding**: internal CSS classes follow the project convention using short encoded names (e.g. `df01`, `df02`). Do not reference DaisyUI's `diff-item-1` / `diff-item-2` class names directly in your own styles — use the `class` prop or wrap with your own container.
23
+
24
+ ---
25
+
26
+ ## PROP REFERENCE
27
+
28
+ | Prop | Type | Required | Description |
29
+ | -------- | ------------------ | -------- | ------------------------------------------------------------------------------------- |
30
+ | `images` | `SolidComponent[]` | ✅ YES | Array of **exactly 2** JSX elements — index `0` = left panel, index `1` = right panel |
31
+ | `class` | `string` | ❌ NO | Extra Tailwind classes appended to the root `<figure>` element |
32
+
33
+ ---
34
+
35
+ ## HARD CONSTRAINT: `images` must have exactly 2 elements
36
+
37
+ - Passing fewer or more than 2 elements → component returns `<></>` (renders nothing) and fires `console.warn('You need to provide exactly 2 images')`
38
+ - There is no partial rendering fallback — the entire component is suppressed
39
+
40
+ ```ts
41
+ // ✅ Valid
42
+ images={[<img src="a.webp" />, <img src="b.webp" />]}
43
+
44
+ // ❌ Invalid — renders nothing
45
+ images={[<img src="a.webp" />]}
46
+ images={[<img src="a.webp" />, <img src="b.webp" />, <img src="c.webp" />]}
47
+ ```
48
+
49
+ ---
50
+
51
+ ## INTERNAL DOM STRUCTURE
52
+
53
+ ```
54
+ <figure class="diff aspect-video [class]" tabindex="0">
55
+
56
+ ├── <div class="diff-item-1" role="img" tabindex="0">
57
+ │ {images[0]} ← LEFT panel (revealed by dragging resizer right)
58
+ │ </div>
59
+
60
+ ├── <div class="diff-item-2" role="img">
61
+ │ {images[1]} ← RIGHT panel (base/background layer)
62
+ │ </div>
63
+
64
+ └── <div class="diff-resizer"></div> ← invisible drag handle
65
+ ```
66
+
67
+ ### Layer rendering order
68
+
69
+ - `diff-item-2` (right/background) renders behind — visible in full by default
70
+ - `diff-item-1` (left/foreground) renders on top with `z-index: 1`, clipped by the resizer position
71
+ - Dragging resizer RIGHT → reveals more of `images[0]` (left panel)
72
+ - Dragging resizer LEFT → reveals more of `images[1]` (right panel)
73
+
74
+ ---
75
+
76
+ ## INTERACTION MECHANISM — CSS-only, no JS state
77
+
78
+ The slider is driven entirely by CSS using a native `resize: horizontal` invisible div (`.diff-resizer`):
79
+
80
+ - Default resizer position: `width: 50cqi` → panels shown 50/50
81
+ - Resizer `min-width: 1rem`, `max-width: calc(100cqi - 1rem)` — cannot be dragged beyond edges
82
+ - **Keyboard accessible**: `<figure tabindex="0">` and `<div class="diff-item-1" tabindex="0">` both focusable
83
+ - Focus on `<figure>` → resizer snaps to `min-width: 95cqi` (left panel nearly full)
84
+ - Focus on `diff-item-1` → resizer snaps to `min-width: 5cqi` (right panel nearly full)
85
+ - Snap transitions animated with `transition: min-width 0.3s ease-out`
86
+
87
+ Agents do NOT manage any open/close or drag state — it is fully CSS-driven.
88
+
89
+ ---
90
+
91
+ ## CONTENT RULES FOR `images[0]` AND `images[1]`
92
+
93
+ Both slots accept **any JSX element**, not just `<img>`. Internal CSS applies to all direct children:
94
+
95
+ ```css
96
+ /* Applied to direct children of both diff-item-1 and diff-item-2 */
97
+ position: absolute;
98
+ top: 0;
99
+ bottom: 0;
100
+ left: 0;
101
+ height: 100%;
102
+ width: 100cqi;
103
+ object-fit: cover;
104
+ object-position: center;
105
+ pointer-events: none;
106
+ ```
107
+
108
+ ### What this means for agents:
109
+
110
+ - **`<img>`**: works perfectly — `object-fit: cover` is applied automatically
111
+ - **`<div>`**: also works — div fills the full panel area. Use `grid place-content-center` or flex for internal layout
112
+ - **Interactive elements inside panels**: will NOT work — `pointer-events: none` is applied to all children. Do NOT put buttons, links, or inputs inside `images`
113
+ - **Do NOT add layout wrappers** around the img/div — children are positioned absolutely with `width: 100cqi`
114
+
115
+ ---
116
+
117
+ ## ASPECT RATIO
118
+
119
+ - Root `<figure>` always has class `aspect-video` (16:9 ratio) applied by default
120
+ - To change aspect ratio, override via `class` prop:
121
+
122
+ ```tsx
123
+ // Square
124
+ <Diff images={[...]} class="aspect-square" />
125
+
126
+ // Custom ratio
127
+ <Diff images={[...]} class="aspect-4/3" />
128
+
129
+ // Fixed height
130
+ <Diff images={[...]} class="h-100" />
131
+ ```
132
+
133
+ ---
134
+
135
+ ## USAGE PATTERNS
136
+
137
+ ### Pattern 1 — Image vs image (most common)
138
+
139
+ ```tsx
140
+ <Diff
141
+ images={[
142
+ <img alt="before" src="/images/before.webp" />,
143
+ <img alt="after" src="/images/after.webp" />,
144
+ ]}
145
+ />
146
+ ```
147
+
148
+ ### Pattern 2 — Image vs custom div content
149
+
150
+ ```tsx
151
+ <Diff
152
+ images={[
153
+ <img alt="photo" src="/images/photo.webp" />,
154
+ <div class="bg-base-200 text-base-content grid place-content-center text-6xl font-black">
155
+ BEFORE
156
+ </div>,
157
+ ]}
158
+ />
159
+ ```
160
+
161
+ ### Pattern 3 — Custom aspect ratio
162
+
163
+ ```tsx
164
+ <Diff
165
+ class="aspect-square w-100"
166
+ images={[
167
+ <img alt="original" src="/images/original.webp" />,
168
+ <img alt="filtered" src="/images/filtered.webp" />,
169
+ ]}
170
+ />
171
+ ```
172
+
173
+ ### Pattern 4 — Two styled div panels
174
+
175
+ ```tsx
176
+ <Diff
177
+ images={[
178
+ <div class="bg-primary text-primary-content grid place-content-center text-4xl font-bold">
179
+ Dark Mode
180
+ </div>,
181
+ <div class="bg-base-100 text-base-content grid place-content-center text-4xl font-bold">
182
+ Light Mode
183
+ </div>,
184
+ ]}
185
+ />
186
+ ```
187
+
188
+ ---
189
+
190
+ ## BEHAVIOR NOTES FOR AGENTS
191
+
192
+ 1. **`images[0]` = left (foreground), `images[1]` = right (background)** — the order determines which panel is clipped by the drag handle. Left panel sits on top and is revealed by dragging right.
193
+
194
+ 2. **Component is a `<figure>` element** — semantically appropriate for media comparison. Root is not a `<div>`.
195
+
196
+ 3. **`pointer-events: none` on all panel children** — nothing inside `images[0]` or `images[1]` can be clicked, hovered, or interacted with. Only the resizer handle is interactive.
197
+
198
+ 4. **No JS drag state** — the drag interaction is entirely driven by the native browser `resize: horizontal` CSS property on `.diff-resizer`. No SolidJS signals or event handlers involved.
199
+
200
+ 5. **`class` prop targets the root `<figure>` only** — cannot target internal `.diff-item-1`, `.diff-item-2`, or `.diff-resizer` via this prop.
201
+
202
+ 6. **Width fills container** — root `<figure>` has `width: 100%`. Wrap in a sized container or use `class="w-[500px]"` to constrain.
203
+
204
+ ---
205
+
206
+ ## COMMON MISTAKES TO AVOID
207
+
208
+ | Mistake | Correct approach |
209
+ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
210
+ | Passing 1 or 3+ items in `images` | Always pass exactly 2 elements — no more, no less |
211
+ | Putting interactive elements (buttons, links) inside `images` | `pointer-events: none` blocks all interactions inside panels |
212
+ | Wrapping `<img>` in an extra `<div>` | Pass `<img>` directly — children are already positioned absolutely to fill the panel |
213
+ | Expecting `class` to style inner panels | `class` only applies to the root `<figure>` |
214
+ | Assuming left panel is `images[1]` | `images[0]` = left/foreground (clipped), `images[1]` = right/background |
215
+ | Using without a sized container | Add `w-full`, `w-[Npx]` or similar to control width |
216
+
217
+ ---
218
+
219
+ ## FULL EXAMPLE
220
+
221
+ ```tsx
222
+ import { Diff } from 'solid-tom-ui';
223
+
224
+ // Image comparison
225
+ <Diff
226
+ images={[
227
+ <img alt="sharp" src="/images/sharp.webp" />,
228
+ <img alt="blurred" src="/images/blurred.webp" />,
229
+ ]}
230
+ />
231
+
232
+ // Image vs label panel, square aspect
233
+ <Diff
234
+ class="aspect-square w-full max-w-lg"
235
+ images={[
236
+ <img alt="photo" src="/images/photo.webp" />,
237
+ <div class="bg-neutral text-neutral-content grid place-content-center text-5xl font-black">
238
+ Solid UI
239
+ </div>,
240
+ ]}
241
+ />
242
+ ```
243
+
244
+ > **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.