solid-tom-ui 1.0.10 → 1.0.14

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 (120) 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/menu/menu.types.d.ts +2 -3
  38. package/dist/components/menu/menu.types.d.ts.map +1 -1
  39. package/dist/components/modal/modal.js.map +1 -1
  40. package/dist/components/modal/modalContext.js.map +1 -1
  41. package/dist/components/pagination/pagination.js.map +1 -1
  42. package/dist/components/progress-bar/progress-bar.js.map +1 -1
  43. package/dist/components/qr-code/qr-code.js.map +1 -1
  44. package/dist/components/select/select.js.map +1 -1
  45. package/dist/components/select-zone/select-zone.js.map +1 -1
  46. package/dist/components/skeleton/skeleton.js.map +1 -1
  47. package/dist/components/slider/slider.js.map +1 -1
  48. package/dist/components/splitter/splitter.js.map +1 -1
  49. package/dist/components/steps/steps.js.map +1 -1
  50. package/dist/components/swap/swap.js.map +1 -1
  51. package/dist/components/switch/switch.js.map +1 -1
  52. package/dist/components/tab/tab.js.map +1 -1
  53. package/dist/components/table/table.js.map +1 -1
  54. package/dist/components/timeline/timeline.js.map +1 -1
  55. package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
  56. package/dist/components/toast/icons/IconCircle.js.map +1 -1
  57. package/dist/components/toast/icons/InfoIcon.js.map +1 -1
  58. package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
  59. package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
  60. package/dist/components/toast/icons/WarningIcon.js.map +1 -1
  61. package/dist/components/toast/toast.js.map +1 -1
  62. package/dist/components/toast/toast.store.js.map +1 -1
  63. package/dist/components/tooltip/tooltip.js.map +1 -1
  64. package/dist/components/tour/tour.js.map +1 -1
  65. package/dist/components/upload/upload.js.map +1 -1
  66. package/dist/components/z-index/z-index.context.js.map +1 -1
  67. package/dist/components/z-index/z-index.js.map +1 -1
  68. package/dist/components/z-index/z-index.store.js.map +1 -1
  69. package/dist/components/z-index/z-index.types.js.map +1 -1
  70. package/dist/package.json +1 -1
  71. package/dist/skill/avatar.skill.md.txt +255 -255
  72. package/dist/skill/badge.skill.md.txt +223 -223
  73. package/dist/skill/breadcrumb.skill.md.txt +177 -177
  74. package/dist/skill/button.skill.md.txt +198 -198
  75. package/dist/skill/carousel.skill.md.txt +406 -406
  76. package/dist/skill/chat-bubble.skill.md.txt +342 -342
  77. package/dist/skill/checkbox.skill.md.txt +326 -326
  78. package/dist/skill/code-preview.skill.md.txt +240 -240
  79. package/dist/skill/collapse.skill.md.txt +329 -329
  80. package/dist/skill/context-menu.skill.md.txt +233 -233
  81. package/dist/skill/diff.skill.md.txt +244 -244
  82. package/dist/skill/divider.skill.md.txt +151 -151
  83. package/dist/skill/doc.skill.md.txt +191 -191
  84. package/dist/skill/drawer.skill.md.txt +157 -157
  85. package/dist/skill/dropdown.skill.md.txt +198 -198
  86. package/dist/skill/float-button.skill.md.txt +315 -315
  87. package/dist/skill/hover-3d-image.skill.md.txt +120 -120
  88. package/dist/skill/iframe.skill.md.txt +114 -114
  89. package/dist/skill/image-preview.skill.md.txt +162 -162
  90. package/dist/skill/indicator.skill.md.txt +60 -60
  91. package/dist/skill/input.skill.md.txt +489 -489
  92. package/dist/skill/loading.skill.md.txt +127 -127
  93. package/dist/skill/menu.skill.md.txt +476 -476
  94. package/dist/skill/modal.skill.md.txt +359 -359
  95. package/dist/skill/pagination.skill.md.txt +405 -405
  96. package/dist/skill/progress-bar.skill.md.txt +207 -207
  97. package/dist/skill/qr-code.skill.md.txt +136 -136
  98. package/dist/skill/rating.skill.md.txt +167 -167
  99. package/dist/skill/select-zone.skill.md.txt +93 -93
  100. package/dist/skill/select.skill.md.txt +663 -663
  101. package/dist/skill/skeleton.skill.md.txt +192 -192
  102. package/dist/skill/slider.skill.md.txt +404 -404
  103. package/dist/skill/splitter.skill.md.txt +411 -411
  104. package/dist/skill/steps.skill.md.txt +264 -264
  105. package/dist/skill/swap.skill.md.txt +139 -139
  106. package/dist/skill/switch.skill.md.txt +191 -191
  107. package/dist/skill/tab.skill.md.txt +484 -484
  108. package/dist/skill/table.example.header.md.txt +666 -666
  109. package/dist/skill/table.skill.md.txt +1407 -1407
  110. package/dist/skill/text-rotate.skill.md.txt +186 -186
  111. package/dist/skill/timeline.skill.md.txt +247 -247
  112. package/dist/skill/toast.skill.md.txt +531 -531
  113. package/dist/skill/tooltip.skill.md.txt +222 -222
  114. package/dist/skill/tour.skill.md.txt +156 -156
  115. package/dist/skill/upload.skill.md.txt +358 -358
  116. package/dist/utils/cn.js.map +1 -1
  117. package/dist/utils/element-tracker.js.map +1 -1
  118. package/dist/utils/helper.js.map +1 -1
  119. package/dist/utils/hoc.js.map +1 -1
  120. 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()`.