@primestyleai/tryon 5.7.8 → 5.7.9
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.
|
@@ -9992,7 +9992,7 @@ function isImperial(locale) {
|
|
|
9992
9992
|
function cx(base, override) {
|
|
9993
9993
|
return override ? `${base} ${override}` : base;
|
|
9994
9994
|
}
|
|
9995
|
-
const STYLES = `
|
|
9995
|
+
const STYLES$1 = `
|
|
9996
9996
|
/* Variable defaults must live on BOTH the root (for the trigger button)
|
|
9997
9997
|
and the overlay (which is React-portaled to <body> and therefore not
|
|
9998
9998
|
a descendant of .ps-tryon-root, so the cascade is broken). Without
|
|
@@ -19604,7 +19604,7 @@ if (typeof document !== "undefined") {
|
|
|
19604
19604
|
if (!document.getElementById(id2)) {
|
|
19605
19605
|
const el2 = document.createElement("style");
|
|
19606
19606
|
el2.id = id2;
|
|
19607
|
-
el2.textContent = STYLES;
|
|
19607
|
+
el2.textContent = STYLES$1;
|
|
19608
19608
|
document.head.appendChild(el2);
|
|
19609
19609
|
}
|
|
19610
19610
|
}
|
|
@@ -20991,6 +20991,339 @@ function PrimeStyleTryonInner({
|
|
|
20991
20991
|
function PrimeStyleTryon(props) {
|
|
20992
20992
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(PrimeStyleTryonInner, { ...props });
|
|
20993
20993
|
}
|
|
20994
|
+
const STYLES = `
|
|
20995
|
+
.ps-sg-btn {
|
|
20996
|
+
display: inline-flex;
|
|
20997
|
+
align-items: center;
|
|
20998
|
+
gap: 6px;
|
|
20999
|
+
padding: 8px 14px;
|
|
21000
|
+
margin: 0 0 10px 0;
|
|
21001
|
+
background: transparent;
|
|
21002
|
+
border: 1px solid rgba(0, 0, 0, 0.12);
|
|
21003
|
+
border-radius: 8px;
|
|
21004
|
+
color: var(--ps-sg-accent, #2154EF);
|
|
21005
|
+
font-size: 13px;
|
|
21006
|
+
font-weight: 600;
|
|
21007
|
+
font-family: inherit;
|
|
21008
|
+
cursor: pointer;
|
|
21009
|
+
transition: background 0.15s, border-color 0.15s;
|
|
21010
|
+
}
|
|
21011
|
+
.ps-sg-btn:hover {
|
|
21012
|
+
background: rgba(33, 84, 239, 0.04);
|
|
21013
|
+
border-color: var(--ps-sg-accent, #2154EF);
|
|
21014
|
+
}
|
|
21015
|
+
.ps-sg-btn svg { width: 14px; height: 14px; }
|
|
21016
|
+
.ps-sg-overlay {
|
|
21017
|
+
position: fixed; inset: 0;
|
|
21018
|
+
background: rgba(15, 23, 42, 0.55);
|
|
21019
|
+
display: flex; align-items: center; justify-content: center;
|
|
21020
|
+
z-index: 99999;
|
|
21021
|
+
padding: 16px;
|
|
21022
|
+
opacity: 0;
|
|
21023
|
+
animation: ps-sg-fadein 0.18s ease forwards;
|
|
21024
|
+
}
|
|
21025
|
+
@keyframes ps-sg-fadein { to { opacity: 1; } }
|
|
21026
|
+
.ps-sg-modal {
|
|
21027
|
+
background: #FFFFFF;
|
|
21028
|
+
border-radius: 14px;
|
|
21029
|
+
width: 100%;
|
|
21030
|
+
max-width: 720px;
|
|
21031
|
+
max-height: 88vh;
|
|
21032
|
+
overflow: hidden;
|
|
21033
|
+
display: flex;
|
|
21034
|
+
flex-direction: column;
|
|
21035
|
+
box-shadow: 0 24px 60px rgba(15, 23, 42, 0.25);
|
|
21036
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
21037
|
+
color: #1f2937;
|
|
21038
|
+
}
|
|
21039
|
+
.ps-sg-header {
|
|
21040
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
21041
|
+
padding: 18px 22px 14px;
|
|
21042
|
+
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
|
|
21043
|
+
}
|
|
21044
|
+
.ps-sg-title {
|
|
21045
|
+
margin: 0;
|
|
21046
|
+
font-size: 17px;
|
|
21047
|
+
font-weight: 700;
|
|
21048
|
+
}
|
|
21049
|
+
.ps-sg-toggle {
|
|
21050
|
+
display: inline-flex;
|
|
21051
|
+
background: rgba(15, 23, 42, 0.06);
|
|
21052
|
+
border-radius: 8px;
|
|
21053
|
+
padding: 3px;
|
|
21054
|
+
margin-right: 12px;
|
|
21055
|
+
}
|
|
21056
|
+
.ps-sg-toggle button {
|
|
21057
|
+
padding: 5px 14px;
|
|
21058
|
+
background: transparent;
|
|
21059
|
+
border: none;
|
|
21060
|
+
border-radius: 6px;
|
|
21061
|
+
font-size: 11px;
|
|
21062
|
+
font-weight: 700;
|
|
21063
|
+
cursor: pointer;
|
|
21064
|
+
color: rgba(15, 23, 42, 0.55);
|
|
21065
|
+
text-transform: uppercase;
|
|
21066
|
+
letter-spacing: 0.04em;
|
|
21067
|
+
font-family: inherit;
|
|
21068
|
+
}
|
|
21069
|
+
.ps-sg-toggle button.ps-sg-active {
|
|
21070
|
+
background: #FFFFFF;
|
|
21071
|
+
color: #1f2937;
|
|
21072
|
+
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08);
|
|
21073
|
+
}
|
|
21074
|
+
.ps-sg-close {
|
|
21075
|
+
background: transparent;
|
|
21076
|
+
border: none;
|
|
21077
|
+
color: rgba(15, 23, 42, 0.55);
|
|
21078
|
+
cursor: pointer;
|
|
21079
|
+
padding: 4px;
|
|
21080
|
+
border-radius: 6px;
|
|
21081
|
+
font-family: inherit;
|
|
21082
|
+
}
|
|
21083
|
+
.ps-sg-close:hover { background: rgba(15, 23, 42, 0.06); }
|
|
21084
|
+
.ps-sg-close svg { width: 18px; height: 18px; }
|
|
21085
|
+
.ps-sg-body {
|
|
21086
|
+
padding: 18px 22px 22px;
|
|
21087
|
+
overflow-y: auto;
|
|
21088
|
+
flex: 1;
|
|
21089
|
+
}
|
|
21090
|
+
.ps-sg-section { margin-bottom: 22px; }
|
|
21091
|
+
.ps-sg-section:last-child { margin-bottom: 0; }
|
|
21092
|
+
.ps-sg-section-title {
|
|
21093
|
+
margin: 0 0 6px;
|
|
21094
|
+
font-size: 14px;
|
|
21095
|
+
font-weight: 700;
|
|
21096
|
+
color: #0f172a;
|
|
21097
|
+
}
|
|
21098
|
+
.ps-sg-section-desc {
|
|
21099
|
+
margin: 0 0 10px;
|
|
21100
|
+
font-size: 12px;
|
|
21101
|
+
color: rgba(15, 23, 42, 0.6);
|
|
21102
|
+
}
|
|
21103
|
+
.ps-sg-table-wrap {
|
|
21104
|
+
overflow-x: auto;
|
|
21105
|
+
border: 1px solid rgba(15, 23, 42, 0.08);
|
|
21106
|
+
border-radius: 10px;
|
|
21107
|
+
}
|
|
21108
|
+
.ps-sg-table {
|
|
21109
|
+
width: 100%;
|
|
21110
|
+
border-collapse: collapse;
|
|
21111
|
+
font-size: 13px;
|
|
21112
|
+
}
|
|
21113
|
+
.ps-sg-table thead th {
|
|
21114
|
+
background: rgba(15, 23, 42, 0.04);
|
|
21115
|
+
padding: 10px 12px;
|
|
21116
|
+
text-align: left;
|
|
21117
|
+
font-weight: 700;
|
|
21118
|
+
font-size: 11px;
|
|
21119
|
+
text-transform: uppercase;
|
|
21120
|
+
letter-spacing: 0.04em;
|
|
21121
|
+
color: rgba(15, 23, 42, 0.6);
|
|
21122
|
+
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
|
|
21123
|
+
}
|
|
21124
|
+
.ps-sg-table tbody td {
|
|
21125
|
+
padding: 10px 12px;
|
|
21126
|
+
border-bottom: 1px solid rgba(15, 23, 42, 0.05);
|
|
21127
|
+
}
|
|
21128
|
+
.ps-sg-table tbody tr:last-child td { border-bottom: none; }
|
|
21129
|
+
.ps-sg-htm {
|
|
21130
|
+
margin-top: 18px;
|
|
21131
|
+
padding: 14px 16px;
|
|
21132
|
+
background: rgba(33, 84, 239, 0.05);
|
|
21133
|
+
border-radius: 10px;
|
|
21134
|
+
border: 1px solid rgba(33, 84, 239, 0.12);
|
|
21135
|
+
}
|
|
21136
|
+
.ps-sg-htm-title {
|
|
21137
|
+
font-size: 12px;
|
|
21138
|
+
font-weight: 700;
|
|
21139
|
+
text-transform: uppercase;
|
|
21140
|
+
letter-spacing: 0.04em;
|
|
21141
|
+
color: var(--ps-sg-accent, #2154EF);
|
|
21142
|
+
margin-bottom: 8px;
|
|
21143
|
+
}
|
|
21144
|
+
.ps-sg-htm ul {
|
|
21145
|
+
margin: 0;
|
|
21146
|
+
padding-left: 18px;
|
|
21147
|
+
font-size: 12px;
|
|
21148
|
+
line-height: 1.6;
|
|
21149
|
+
color: #1f2937;
|
|
21150
|
+
}
|
|
21151
|
+
`;
|
|
21152
|
+
let stylesInjected = false;
|
|
21153
|
+
function injectStyles() {
|
|
21154
|
+
if (stylesInjected) return;
|
|
21155
|
+
const tag = document.createElement("style");
|
|
21156
|
+
tag.id = "ps-sg-styles";
|
|
21157
|
+
tag.textContent = STYLES;
|
|
21158
|
+
document.head.appendChild(tag);
|
|
21159
|
+
stylesInjected = true;
|
|
21160
|
+
}
|
|
21161
|
+
const RULER_ICON = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/></svg>`;
|
|
21162
|
+
const X_ICON = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>`;
|
|
21163
|
+
function cmToInch(value) {
|
|
21164
|
+
return value.replace(/[\d]+(?:\.\d+)?/g, (m2) => {
|
|
21165
|
+
const n2 = parseFloat(m2);
|
|
21166
|
+
if (isNaN(n2)) return m2;
|
|
21167
|
+
const inches = n2 / 2.54;
|
|
21168
|
+
return inches % 1 === 0 ? inches.toFixed(0) : inches.toFixed(1);
|
|
21169
|
+
}).replace(/\s*cm\s*/gi, "");
|
|
21170
|
+
}
|
|
21171
|
+
function inchToCm(value) {
|
|
21172
|
+
return value.replace(/[\d]+(?:\.\d+)?/g, (m2) => {
|
|
21173
|
+
const n2 = parseFloat(m2);
|
|
21174
|
+
return isNaN(n2) ? m2 : String(Math.round(n2 * 2.54));
|
|
21175
|
+
}).replace(/[\u0022\u2033\u201D″"]/g, "").trim();
|
|
21176
|
+
}
|
|
21177
|
+
function normalizeToSections(guide) {
|
|
21178
|
+
if (Array.isArray(guide.sections) && guide.sections.length > 0) {
|
|
21179
|
+
return guide.sections;
|
|
21180
|
+
}
|
|
21181
|
+
if (guide.headers && guide.rows) {
|
|
21182
|
+
return [
|
|
21183
|
+
{
|
|
21184
|
+
name: guide.title || "Size Guide",
|
|
21185
|
+
headers: guide.headers,
|
|
21186
|
+
rows: guide.rows
|
|
21187
|
+
}
|
|
21188
|
+
];
|
|
21189
|
+
}
|
|
21190
|
+
return [];
|
|
21191
|
+
}
|
|
21192
|
+
function buildSectionTable(section, unit, sourceUnit) {
|
|
21193
|
+
const allKeys = section.headers && section.headers.length > 0 ? section.headers : Object.keys(section.rows[0] || {});
|
|
21194
|
+
const colKeys = allKeys.filter((k2) => {
|
|
21195
|
+
const lower = k2.toLowerCase();
|
|
21196
|
+
const hasIn = lower.includes("(in)") || lower.endsWith(" in");
|
|
21197
|
+
const hasCm = lower.includes("(cm)") || lower.endsWith(" cm");
|
|
21198
|
+
if (hasIn) {
|
|
21199
|
+
const base = lower.replace(/\s*\(in\)\s*/, "").replace(/\s+in$/, "").trim();
|
|
21200
|
+
const cmExists = allKeys.some((o) => {
|
|
21201
|
+
const ol2 = o.toLowerCase();
|
|
21202
|
+
return ol2 !== lower && ol2.includes(base) && (ol2.includes("(cm)") || ol2.endsWith(" cm"));
|
|
21203
|
+
});
|
|
21204
|
+
return cmExists ? unit === "in" : true;
|
|
21205
|
+
}
|
|
21206
|
+
if (hasCm) {
|
|
21207
|
+
const base = lower.replace(/\s*\(cm\)\s*/, "").replace(/\s+cm$/, "").trim();
|
|
21208
|
+
const inExists = allKeys.some((o) => {
|
|
21209
|
+
const ol2 = o.toLowerCase();
|
|
21210
|
+
return ol2 !== lower && ol2.includes(base) && (ol2.includes("(in)") || ol2.endsWith(" in"));
|
|
21211
|
+
});
|
|
21212
|
+
return inExists ? unit === "cm" : true;
|
|
21213
|
+
}
|
|
21214
|
+
return true;
|
|
21215
|
+
});
|
|
21216
|
+
const escapeHtml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
21217
|
+
const displayHeader = (key) => escapeHtml(key.replace(/\s*\((cm|in)\)\s*$/i, "").trim());
|
|
21218
|
+
const convertCell = (value, key) => {
|
|
21219
|
+
const keyLower = key.toLowerCase();
|
|
21220
|
+
const headerHasUnit = /\((cm|in)\)|\s+(cm|in)$/.test(keyLower);
|
|
21221
|
+
if (headerHasUnit) return value;
|
|
21222
|
+
if (/^[a-z\s]+$/i.test(value)) return value;
|
|
21223
|
+
if (sourceUnit === "cm" && unit === "in") return cmToInch(value);
|
|
21224
|
+
if (sourceUnit === "in" && unit === "cm") return inchToCm(value);
|
|
21225
|
+
return value;
|
|
21226
|
+
};
|
|
21227
|
+
const head = colKeys.map((k2) => `<th>${displayHeader(k2)}</th>`).join("");
|
|
21228
|
+
const body = section.rows.map((row) => {
|
|
21229
|
+
const cells = colKeys.map((k2) => {
|
|
21230
|
+
const raw = row[k2] ?? row[k2.toLowerCase()] ?? "";
|
|
21231
|
+
return `<td>${escapeHtml(convertCell(String(raw), k2))}</td>`;
|
|
21232
|
+
}).join("");
|
|
21233
|
+
return `<tr>${cells}</tr>`;
|
|
21234
|
+
}).join("");
|
|
21235
|
+
return `
|
|
21236
|
+
<div class="ps-sg-section">
|
|
21237
|
+
<h3 class="ps-sg-section-title">${escapeHtml(section.name)}</h3>
|
|
21238
|
+
${section.description ? `<p class="ps-sg-section-desc">${escapeHtml(section.description)}</p>` : ""}
|
|
21239
|
+
<div class="ps-sg-table-wrap">
|
|
21240
|
+
<table class="ps-sg-table"><thead><tr>${head}</tr></thead><tbody>${body}</tbody></table>
|
|
21241
|
+
</div>
|
|
21242
|
+
</div>
|
|
21243
|
+
`;
|
|
21244
|
+
}
|
|
21245
|
+
function createSizeGuideButton(parent, sizeGuide, options = {}) {
|
|
21246
|
+
injectStyles();
|
|
21247
|
+
const sections = normalizeToSections(sizeGuide);
|
|
21248
|
+
if (sections.length === 0) {
|
|
21249
|
+
console.log("[primestyle-tryon] size guide has no sections, skipping button");
|
|
21250
|
+
return () => {
|
|
21251
|
+
};
|
|
21252
|
+
}
|
|
21253
|
+
const sourceUnit = sizeGuide.unit === "in" ? "in" : "cm";
|
|
21254
|
+
const btn = document.createElement("button");
|
|
21255
|
+
btn.type = "button";
|
|
21256
|
+
btn.className = "ps-sg-btn";
|
|
21257
|
+
btn.innerHTML = `${RULER_ICON}<span>${options.label || "Size Guide"}</span>`;
|
|
21258
|
+
if (options.accentColor) {
|
|
21259
|
+
btn.style.setProperty("--ps-sg-accent", options.accentColor);
|
|
21260
|
+
}
|
|
21261
|
+
let unit = sourceUnit;
|
|
21262
|
+
let overlayEl = null;
|
|
21263
|
+
function renderModal() {
|
|
21264
|
+
const overlay = document.createElement("div");
|
|
21265
|
+
overlay.className = "ps-sg-overlay";
|
|
21266
|
+
overlay.innerHTML = `
|
|
21267
|
+
<div class="ps-sg-modal" role="dialog" aria-modal="true">
|
|
21268
|
+
<div class="ps-sg-header">
|
|
21269
|
+
<h2 class="ps-sg-title">${(sizeGuide.title || "Size Guide").replace(/</g, "<")}</h2>
|
|
21270
|
+
<div style="display:flex;align-items:center">
|
|
21271
|
+
<div class="ps-sg-toggle" role="group" aria-label="Unit">
|
|
21272
|
+
<button type="button" data-unit="cm" class="${unit === "cm" ? "ps-sg-active" : ""}">CM</button>
|
|
21273
|
+
<button type="button" data-unit="in" class="${unit === "in" ? "ps-sg-active" : ""}">IN</button>
|
|
21274
|
+
</div>
|
|
21275
|
+
<button class="ps-sg-close" type="button" aria-label="Close">${X_ICON}</button>
|
|
21276
|
+
</div>
|
|
21277
|
+
</div>
|
|
21278
|
+
<div class="ps-sg-body">
|
|
21279
|
+
${sections.map((s) => buildSectionTable(s, unit, sourceUnit)).join("")}
|
|
21280
|
+
${sizeGuide.howToMeasure && sizeGuide.howToMeasure.length > 0 ? `<div class="ps-sg-htm">
|
|
21281
|
+
<div class="ps-sg-htm-title">How to measure</div>
|
|
21282
|
+
<ul>${sizeGuide.howToMeasure.map((h) => `<li>${h.replace(/</g, "<")}</li>`).join("")}</ul>
|
|
21283
|
+
</div>` : ""}
|
|
21284
|
+
</div>
|
|
21285
|
+
</div>
|
|
21286
|
+
`;
|
|
21287
|
+
if (options.accentColor) {
|
|
21288
|
+
overlay.style.setProperty("--ps-sg-accent", options.accentColor);
|
|
21289
|
+
}
|
|
21290
|
+
document.body.appendChild(overlay);
|
|
21291
|
+
overlayEl = overlay;
|
|
21292
|
+
document.body.style.overflow = "hidden";
|
|
21293
|
+
overlay.addEventListener("click", (e) => {
|
|
21294
|
+
if (e.target === overlay) close();
|
|
21295
|
+
});
|
|
21296
|
+
overlay.querySelector(".ps-sg-close")?.addEventListener("click", close);
|
|
21297
|
+
overlay.querySelectorAll(".ps-sg-toggle button").forEach((b) => {
|
|
21298
|
+
b.addEventListener("click", () => {
|
|
21299
|
+
const next = b.getAttribute("data-unit");
|
|
21300
|
+
if (next === unit) return;
|
|
21301
|
+
unit = next;
|
|
21302
|
+
close();
|
|
21303
|
+
renderModal();
|
|
21304
|
+
});
|
|
21305
|
+
});
|
|
21306
|
+
const onKey = (e) => {
|
|
21307
|
+
if (e.key === "Escape") close();
|
|
21308
|
+
};
|
|
21309
|
+
document.addEventListener("keydown", onKey);
|
|
21310
|
+
overlay.__onKey = onKey;
|
|
21311
|
+
}
|
|
21312
|
+
function close() {
|
|
21313
|
+
if (!overlayEl) return;
|
|
21314
|
+
const onKey = overlayEl.__onKey;
|
|
21315
|
+
if (onKey) document.removeEventListener("keydown", onKey);
|
|
21316
|
+
overlayEl.remove();
|
|
21317
|
+
overlayEl = null;
|
|
21318
|
+
document.body.style.overflow = "";
|
|
21319
|
+
}
|
|
21320
|
+
btn.addEventListener("click", renderModal);
|
|
21321
|
+
parent.parentElement?.insertBefore(btn, parent);
|
|
21322
|
+
return () => {
|
|
21323
|
+
btn.remove();
|
|
21324
|
+
close();
|
|
21325
|
+
};
|
|
21326
|
+
}
|
|
20994
21327
|
const TAG = "[primestyle-tryon]";
|
|
20995
21328
|
console.log(`${TAG} bundle loaded — version 5.7.x storefront entry`);
|
|
20996
21329
|
const MOUNTED = /* @__PURE__ */ new WeakMap();
|
|
@@ -21073,6 +21406,17 @@ async function mount(el2) {
|
|
|
21073
21406
|
props.sizeGuideData = fetched;
|
|
21074
21407
|
}
|
|
21075
21408
|
}
|
|
21409
|
+
if (props.sizeGuideData) {
|
|
21410
|
+
try {
|
|
21411
|
+
const buttonStyles = props.buttonStyles;
|
|
21412
|
+
createSizeGuideButton(el2, props.sizeGuideData, {
|
|
21413
|
+
accentColor: buttonStyles?.backgroundColor
|
|
21414
|
+
});
|
|
21415
|
+
console.log(`${TAG} ✓ size guide button mounted`);
|
|
21416
|
+
} catch (err) {
|
|
21417
|
+
console.warn(`${TAG} size guide button failed`, err);
|
|
21418
|
+
}
|
|
21419
|
+
}
|
|
21076
21420
|
try {
|
|
21077
21421
|
const root = createRoot(el2);
|
|
21078
21422
|
root.render(reactExports.createElement(PrimeStyleTryon, props));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanilla JS size-guide button + modal for the Shopify storefront.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the prime-main SizeGuideModal design but built without React
|
|
5
|
+
* so it can attach next to (not inside) the React-mounted SDK root.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* createSizeGuideButton(parentEl, sizeGuide, { buttonStyles, ... });
|
|
9
|
+
*
|
|
10
|
+
* The button is inserted as a sibling above the React root. Clicking
|
|
11
|
+
* it appends a modal to <body> with a size-chart table, cm/in toggle,
|
|
12
|
+
* and "How to measure" hints.
|
|
13
|
+
*/
|
|
14
|
+
interface RawSection {
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
headers: string[];
|
|
18
|
+
rows: Array<Record<string, string>>;
|
|
19
|
+
}
|
|
20
|
+
interface RawSizeGuide {
|
|
21
|
+
title?: string;
|
|
22
|
+
headers?: string[];
|
|
23
|
+
rows?: Array<Record<string, string>>;
|
|
24
|
+
unit?: "cm" | "in";
|
|
25
|
+
sections?: RawSection[];
|
|
26
|
+
howToMeasure?: string[];
|
|
27
|
+
}
|
|
28
|
+
interface ButtonOptions {
|
|
29
|
+
label?: string;
|
|
30
|
+
accentColor?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a "Size Guide" button and insert it as a sibling above the
|
|
34
|
+
* given parent element. Returns a teardown function that removes the
|
|
35
|
+
* button + any open modal.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createSizeGuideButton(parent: Element, sizeGuide: RawSizeGuide, options?: ButtonOptions): () => void;
|
|
38
|
+
export {};
|