@souldi/try-on 0.1.89 → 0.1.91

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
@@ -39,7 +39,6 @@ Or load directly via CDN:
39
39
  VirtualTryOn.createButton({
40
40
  containerId: 'try-on-jacket',
41
41
  garmentUrl: 'https://your-cdn.com/images/jacket.png',
42
- targetImageId: 'product-image', // optional: auto-swaps this <img> with the result
43
42
  });
44
43
  </script>
45
44
  ```
@@ -54,10 +53,26 @@ That's it. Your customers can now try on clothes with AI.
54
53
  2. First-time users verify their email (magic link OTP — no passwords)
55
54
  3. They upload a photo of themselves
56
55
  4. AI generates a realistic try-on image in seconds
57
- 5. The result appears directly on your product page
56
+ 5. The result opens in the widget's own dialog, over your page
58
57
 
59
58
  Returning users skip straight to step 4 — their session and photo are remembered.
60
59
 
60
+ The result surface is the widget's and only the widget's: an accessible
61
+ `<dialog>` inside an isolated Shadow DOM, appended to `<body>`. It reads none of
62
+ your CSS selectors and never touches your product images, so a theme change
63
+ cannot break it — and there is nothing to point it at. It is also where the
64
+ customer decides: beside the render they are told their size (when the garment
65
+ has a size chart), can add that size to your cart (when you supply
66
+ [`onAddToCart`](#onaddtocart)), can open **Body fit** to see how that size sits
67
+ on their body, can open their profile to retake their photo, edit their
68
+ measurements or sign out, can refine the result, and can switch to the
69
+ garment's back view when there is one. The dialog can be reopened after
70
+ closing; the try-on button becomes **View try-on** once a result exists.
71
+
72
+ Everything optional is simply absent when it does not apply — no size, no
73
+ cart button, no fit detail on a garment without a chart — and nothing is
74
+ said about it. A customer is never told "we can't size this product".
75
+
61
76
  ---
62
77
 
63
78
  ## Configuration
@@ -75,6 +90,7 @@ Call once per page load to configure the widget.
75
90
  | `onError` | `function(message, info)` | No | Called when something goes wrong |
76
91
  | `onLogout` | `function` | No | Called when the user's session ends — by logout, or by a token the backend no longer honours |
77
92
  | `onAuthPrompt` | `function` | No | Called just before the widget takes the screen to ask the user to sign in |
93
+ | `onAddToCart` | `async function(intent)` | No | Called when the customer asks to add their recommended size to your cart. Absent, no cart control is drawn anywhere ([details](#onaddtocart)) |
78
94
 
79
95
  #### The `info` argument
80
96
 
@@ -107,6 +123,41 @@ and must not outlive the session.
107
123
  anything of yours that would cover it (a modal, a lightbox) out of the way. It
108
124
  says nothing about whether the previous session ended — that is `onLogout`.
109
125
 
126
+ #### `onAddToCart`
127
+
128
+ The widget knows a customer's size; only you know your cart. Supply
129
+ `onAddToCart` and the result dialog (and the size guide) draw an **Add size X
130
+ to cart** button. Leave it out and there is no cart control at all.
131
+
132
+ It is called with one `intent` and must **resolve** (never reject) to an
133
+ outcome:
134
+
135
+ ```js
136
+ onAddToCart: async ({ buttonId, size, sizeRun }) => {
137
+ // buttonId — the containerId of the button this is about
138
+ // size — the size the customer chose, e.g. "M"
139
+ // sizeRun — every size the garment's chart offers, e.g. ["S", "M", "L"]
140
+ const variant = resolveVariant(buttonId, size);
141
+ if (!variant) return { ok: false, message: 'That size is not available in this colour.' };
142
+ await addLineToCart(variant.id);
143
+ return { ok: true, cartUrl: '/cart' };
144
+ },
145
+ ```
146
+
147
+ | Field | Present on | Description |
148
+ |-------|-----------|-------------|
149
+ | `ok` | both | Whether the line item is now in the cart |
150
+ | `message` | `ok: false` | What to tell the customer, in their words — out of stock, no such size, a refused add |
151
+ | `cartUrl` | `ok: true` | Optional. A link the confirmation offers so the customer can see the cart |
152
+ | `quantity` | `ok: true` | Optional. How many of this line the cart now holds, for a repeat add |
153
+ | `notice` | `ok: true` | Optional. A caveat when the add was adjusted on the way in (short stock, a cart limit) |
154
+
155
+ Two rules the widget keeps for you: nothing is stated in the past tense until
156
+ you have resolved `{ ok: true }`, and nothing reaches your handler without a
157
+ click on the button — opening the dialog, a new result landing, and changing
158
+ size are never consent. Resolve to `{ ok: false, message }` for every failure
159
+ you can name; a rejection is shown as a generic failure.
160
+
110
161
  ### `createButton(options)`
111
162
 
112
163
  Add a try-on button for a specific garment. Call once per product on the page.
@@ -116,7 +167,11 @@ Add a try-on button for a specific garment. Call once per product on the page.
116
167
  | `containerId` | `string` | Yes | ID of the DOM element where the button will render |
117
168
  | `garmentUrl` | `string` | Yes | Public URL of the garment image |
118
169
  | `internalId` | `string` | No | Your internal/vendor id for this garment; correlated server-side |
119
- | `targetImageId` | `string` | No | ID of an `<img>` element to auto-swap with the try-on result |
170
+
171
+ > **Removed in 0.2.0:** `targetImageId`. It named an `<img>` on your page for the
172
+ > widget to overwrite with the result, and it is gone — the widget shows every
173
+ > result in its own dialog instead (see [How It Works](#how-it-works)). Passing
174
+ > it is harmless and ignored, and logs one console warning. Do not re-add it.
120
175
 
121
176
  ---
122
177
 
@@ -204,7 +259,6 @@ All UI is rendered inside a **Shadow DOM**, so your site's CSS will never leak i
204
259
  VirtualTryOn.createButton({
205
260
  containerId: 'try-on-btn',
206
261
  garmentUrl: 'https://your-cdn.com/images/jacket-flat.png',
207
- targetImageId: 'product-image',
208
262
  });
209
263
  </script>
210
264
  </body>