@flonix/ig-embed 0.0.0-stage → 0.1.0

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/dist/index.mjs ADDED
@@ -0,0 +1,1313 @@
1
+ // src/logo-data.ts
2
+ var FLONIX_LOGO_PNG = "data:image/png;base64,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";
3
+
4
+ // src/branding.ts
5
+ function escapeHtml(value) {
6
+ return value.replace(
7
+ /[&<>"']/g,
8
+ (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : c === ">" ? "&gt;" : c === '"' ? "&quot;" : "&#39;"
9
+ );
10
+ }
11
+ var WORDMARK_FONT = "Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif";
12
+ function flonixLogo(size = 20) {
13
+ return `<span class="flxig-brand" style="--flxig-logo-size:${size}px" role="img" aria-label="Flonix">
14
+ <span class="flxig-brand__chip">
15
+ <img class="flxig-brand__img" src="${FLONIX_LOGO_PNG}" alt="" draggable="false" />
16
+ </span>
17
+ <svg class="flxig-brand__wordmark" viewBox="0 0 55 22" fill="currentColor" aria-hidden="true">
18
+ <text x="0" y="19" font-size="22" font-weight="700" letter-spacing="-0.4" font-family="${WORDMARK_FONT}" textLength="55" lengthAdjust="spacingAndGlyphs">flonix</text>
19
+ </svg>
20
+ </span>`;
21
+ }
22
+ function cobrandLockup(partner) {
23
+ const name = escapeHtml(partner.name);
24
+ const light = escapeHtml(partner.logo);
25
+ const dark = partner.logoDark ? escapeHtml(partner.logoDark) : "";
26
+ const partnerImgs = dark ? `<img class="flxig-partner__img flxig-partner__img--light" src="${light}" alt="${name}" draggable="false" />
27
+ <img class="flxig-partner__img flxig-partner__img--dark" src="${dark}" alt="${name}" draggable="false" />` : `<img class="flxig-partner__img" src="${light}" alt="${name}" draggable="false" />`;
28
+ return `<span class="flxig-cobrand">
29
+ <span class="flxig-partner" data-has-dark="${dark ? "true" : "false"}">${partnerImgs}</span>
30
+ <span class="flxig-cobrand__x">\xD7</span>
31
+ ${flonixLogo(18)}
32
+ </span>`;
33
+ }
34
+ var icons = {
35
+ instagram: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
36
+ <rect x="2" y="2" width="20" height="20" rx="5" ry="5"/>
37
+ <path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/>
38
+ <line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/>
39
+ </svg>`,
40
+ comment: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
41
+ <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
42
+ </svg>`,
43
+ dm: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
44
+ <line x1="22" y1="2" x2="11" y2="13"/>
45
+ <polygon points="22 2 15 22 11 13 2 9 22 2"/>
46
+ </svg>`,
47
+ check: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
48
+ <polyline points="20 6 9 17 4 12"/>
49
+ </svg>`,
50
+ close: (size = 18) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
51
+ <line x1="18" y1="6" x2="6" y2="18"/>
52
+ <line x1="6" y1="6" x2="18" y2="18"/>
53
+ </svg>`,
54
+ plus: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
55
+ <line x1="12" y1="5" x2="12" y2="19"/>
56
+ <line x1="5" y1="12" x2="19" y2="12"/>
57
+ </svg>`,
58
+ link: (size = 15) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
59
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
60
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
61
+ </svg>`,
62
+ bolt: (size = 16) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
63
+ <path d="M13 2 4.5 13.5H11L10 22l8.5-11.5H12L13 2Z"/>
64
+ </svg>`,
65
+ spinner: (size = 18) => `<svg class="flxig-spin" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true">
66
+ <path d="M21 12a9 9 0 1 1-6.219-8.56"/>
67
+ </svg>`,
68
+ video: (size = 14) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
69
+ <path d="M8 5v14l11-7L8 5Z"/>
70
+ </svg>`,
71
+ layers: (size = 14) => `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
72
+ <polygon points="12 2 2 7 12 12 22 7 12 2"/>
73
+ <polyline points="2 17 12 22 22 17"/>
74
+ <polyline points="2 12 12 17 22 12"/>
75
+ </svg>`
76
+ };
77
+
78
+ // src/client.ts
79
+ function authHeaders(token) {
80
+ return {
81
+ "Content-Type": "application/json",
82
+ Authorization: `Bearer ${token}`
83
+ };
84
+ }
85
+ function createHttpTransport(baseUrl) {
86
+ const base = baseUrl.replace(/\/+$/, "");
87
+ async function call(path, init) {
88
+ let res;
89
+ try {
90
+ res = await fetch(`${base}${path}`, init);
91
+ } catch {
92
+ throw new Error("Network error \u2014 please try again.");
93
+ }
94
+ const json = await res.json().catch(() => null);
95
+ if (!res.ok) {
96
+ throw new Error((json == null ? void 0 : json.error) || `Request failed (${res.status})`);
97
+ }
98
+ return json;
99
+ }
100
+ return {
101
+ session: ({ apiKey, user }) => call("/api/embed/session", {
102
+ method: "POST",
103
+ headers: authHeaders(apiKey),
104
+ body: JSON.stringify({ user })
105
+ }),
106
+ connectStart: ({ token, returnUrl }) => call("/api/embed/connect/start", {
107
+ method: "POST",
108
+ headers: authHeaders(token),
109
+ body: JSON.stringify({ returnUrl })
110
+ }),
111
+ posts: ({ token, cursor }) => call(
112
+ `/api/embed/posts${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ""}`,
113
+ { method: "GET", headers: authHeaders(token) }
114
+ ),
115
+ createAutomation: ({ token, data }) => call("/api/embed/automations", {
116
+ method: "POST",
117
+ headers: authHeaders(token),
118
+ body: JSON.stringify(data)
119
+ })
120
+ };
121
+ }
122
+
123
+ // src/dom.ts
124
+ function el(tag, attrs = {}, ...children) {
125
+ const node = document.createElement(tag);
126
+ if (attrs.class) node.className = attrs.class;
127
+ if (attrs.text != null) node.textContent = attrs.text;
128
+ if (attrs.html != null) node.innerHTML = attrs.html;
129
+ if (attrs.style) node.setAttribute("style", attrs.style);
130
+ if (attrs.dataset) {
131
+ for (const [key, value] of Object.entries(attrs.dataset)) {
132
+ node.dataset[key] = value;
133
+ }
134
+ }
135
+ if (attrs.attrs) {
136
+ for (const [key, value] of Object.entries(attrs.attrs)) {
137
+ if (value == null || value === false) continue;
138
+ node.setAttribute(key, value === true ? "" : String(value));
139
+ }
140
+ }
141
+ if (attrs.on) {
142
+ for (const [event, handler] of Object.entries(attrs.on)) {
143
+ node.addEventListener(event, handler);
144
+ }
145
+ }
146
+ append(node, children);
147
+ return node;
148
+ }
149
+ function append(parent, children) {
150
+ for (const child of children) {
151
+ if (child == null || child === false) continue;
152
+ parent.appendChild(
153
+ child instanceof Node ? child : document.createTextNode(String(child))
154
+ );
155
+ }
156
+ }
157
+ function clear(node) {
158
+ while (node.firstChild) node.removeChild(node.firstChild);
159
+ }
160
+ function fromMarkup(markup) {
161
+ var _a;
162
+ const wrapper = document.createElement("div");
163
+ wrapper.innerHTML = markup.trim();
164
+ return (_a = wrapper.firstElementChild) != null ? _a : wrapper;
165
+ }
166
+
167
+ // src/components.ts
168
+ function button(opts) {
169
+ var _a;
170
+ const classes = [
171
+ "flxig-btn",
172
+ `flxig-btn--${(_a = opts.variant) != null ? _a : "primary"}`,
173
+ opts.block ? "flxig-btn--block" : "",
174
+ opts.large ? "flxig-btn--lg" : ""
175
+ ].filter(Boolean).join(" ");
176
+ const btn = el("button", {
177
+ class: classes,
178
+ attrs: { type: "button", disabled: opts.disabled },
179
+ on: opts.onClick ? { click: opts.onClick } : void 0
180
+ });
181
+ if (opts.icon) btn.appendChild(fromMarkup(opts.icon));
182
+ append(btn, [el("span", { text: opts.label })]);
183
+ return btn;
184
+ }
185
+ function field(label, control, hint) {
186
+ return el(
187
+ "div",
188
+ { class: "flxig-field" },
189
+ el("span", { class: "flxig-label", text: label }),
190
+ control,
191
+ hint ? el("span", { class: "flxig-hint", text: hint }) : null
192
+ );
193
+ }
194
+ function textInput(opts) {
195
+ var _a, _b;
196
+ return el("input", {
197
+ class: "flxig-input",
198
+ attrs: { type: "text", value: (_a = opts.value) != null ? _a : "", placeholder: (_b = opts.placeholder) != null ? _b : "" }
199
+ });
200
+ }
201
+ function textArea(opts) {
202
+ var _a, _b, _c;
203
+ const ta = el("textarea", {
204
+ class: "flxig-textarea",
205
+ attrs: { placeholder: (_a = opts.placeholder) != null ? _a : "", rows: (_b = opts.rows) != null ? _b : 3 }
206
+ });
207
+ ta.value = (_c = opts.value) != null ? _c : "";
208
+ return ta;
209
+ }
210
+ function switchToggle(opts) {
211
+ const input = el("input", { attrs: { type: "checkbox" } });
212
+ input.checked = opts.checked;
213
+ if (opts.onChange) {
214
+ input.addEventListener("change", () => opts.onChange(input.checked));
215
+ }
216
+ const element = el(
217
+ "span",
218
+ { class: "flxig-switch" },
219
+ input,
220
+ el("span", { class: "flxig-switch__track" }),
221
+ el("span", { class: "flxig-switch__thumb" })
222
+ );
223
+ return { element, input };
224
+ }
225
+ function chipsInput(opts) {
226
+ var _a;
227
+ let values = [...opts.values];
228
+ const list = el("span", { class: "flxig-chips" });
229
+ const input = el("input", {
230
+ attrs: { type: "text", placeholder: (_a = opts.placeholder) != null ? _a : "Add keyword\u2026" }
231
+ });
232
+ const render = () => {
233
+ while (list.firstChild && list.firstChild !== input) {
234
+ list.removeChild(list.firstChild);
235
+ }
236
+ const chips = values.map(
237
+ (value, index) => el(
238
+ "span",
239
+ { class: "flxig-chip" },
240
+ el("span", { text: value }),
241
+ el("button", {
242
+ attrs: { type: "button", "aria-label": `Remove ${value}` },
243
+ html: icons.close(12),
244
+ on: {
245
+ click: () => {
246
+ values.splice(index, 1);
247
+ render();
248
+ }
249
+ }
250
+ })
251
+ )
252
+ );
253
+ list.prepend(...chips);
254
+ };
255
+ const commit = () => {
256
+ const raw = input.value.trim().replace(/,$/, "").trim();
257
+ if (raw && !values.includes(raw)) {
258
+ values.push(raw);
259
+ render();
260
+ }
261
+ input.value = "";
262
+ };
263
+ input.addEventListener("keydown", (ev) => {
264
+ if (ev.key === "Enter" || ev.key === ",") {
265
+ ev.preventDefault();
266
+ commit();
267
+ } else if (ev.key === "Backspace" && !input.value && values.length) {
268
+ values.pop();
269
+ render();
270
+ }
271
+ });
272
+ input.addEventListener("blur", commit);
273
+ list.appendChild(input);
274
+ render();
275
+ return { element: list, getValues: () => [...values] };
276
+ }
277
+ function linkButtonsEditor(opts) {
278
+ const rows = el("div", { class: "flxig-links" });
279
+ const addBtn = button({
280
+ label: "Add link",
281
+ variant: "ghost",
282
+ icon: icons.plus(15),
283
+ onClick: () => {
284
+ if (rows.querySelectorAll(".flxig-link").length >= opts.max) return;
285
+ addRow({ label: "", url: "" });
286
+ syncAdd();
287
+ }
288
+ });
289
+ addBtn.classList.add("flxig-links__add");
290
+ function syncAdd() {
291
+ addBtn.disabled = rows.querySelectorAll(".flxig-link").length >= opts.max;
292
+ }
293
+ function addRow(value) {
294
+ const label = textInput({ value: value.label, placeholder: "Button label" });
295
+ label.classList.add("flxig-link__label");
296
+ const url = el("input", {
297
+ class: "flxig-input flxig-link__url",
298
+ attrs: { type: "url", value: value.url, placeholder: "https://\u2026", inputmode: "url" }
299
+ });
300
+ const row = el(
301
+ "div",
302
+ { class: "flxig-link" },
303
+ fromMarkup(`<span class="flxig-link__ic">${icons.link(15)}</span>`),
304
+ el("div", { class: "flxig-link__inputs" }, label, url),
305
+ el("button", {
306
+ class: "flxig-iconbtn",
307
+ attrs: { type: "button", "aria-label": "Remove link" },
308
+ html: icons.close(16),
309
+ on: {
310
+ click: () => {
311
+ row.remove();
312
+ syncAdd();
313
+ }
314
+ }
315
+ })
316
+ );
317
+ rows.appendChild(row);
318
+ }
319
+ const seed = opts.values.length ? opts.values : [{ label: "", url: "" }];
320
+ seed.slice(0, opts.max).forEach(addRow);
321
+ syncAdd();
322
+ const element = el("div", { class: "flxig-links__wrap" }, rows, addBtn);
323
+ return {
324
+ element,
325
+ getValues: () => [...rows.querySelectorAll(".flxig-link")].map((row) => ({
326
+ label: row.querySelector(".flxig-link__label").value.trim(),
327
+ url: row.querySelector(".flxig-link__url").value.trim()
328
+ })).filter((b) => b.label || b.url)
329
+ };
330
+ }
331
+ function stateBlock(opts) {
332
+ var _a;
333
+ return el(
334
+ "div",
335
+ { class: "flxig-state" },
336
+ opts.icon ? fromMarkup(opts.icon) : null,
337
+ el("p", { class: "flxig-h2", text: opts.title }),
338
+ opts.detail ? el("p", { class: "flxig-muted", text: opts.detail }) : null,
339
+ (_a = opts.action) != null ? _a : null
340
+ );
341
+ }
342
+
343
+ // src/screens/connect.ts
344
+ function renderConnect(opts) {
345
+ const cta = button({
346
+ label: opts.connecting ? "Redirecting\u2026" : "Connect Instagram",
347
+ variant: "primary",
348
+ large: true,
349
+ block: true,
350
+ disabled: opts.connecting,
351
+ icon: opts.connecting ? icons.spinner() : icons.instagram(),
352
+ onClick: opts.onConnect
353
+ });
354
+ return el(
355
+ "div",
356
+ { class: "flxig-connect" },
357
+ el(
358
+ "div",
359
+ { class: "flxig-connect__copy" },
360
+ el("h1", { class: "flxig-h1", text: "Connect your Instagram with Flonix" }),
361
+ el("p", {
362
+ class: "flxig-muted",
363
+ text: "Link your Instagram account to set up comment and DM automations on your posts \u2014 directly from here."
364
+ })
365
+ ),
366
+ el("div", { class: "flxig-connect__cta" }, cta),
367
+ fromMarkup(`<div class="flxig-connect__foot">${cobrandLockup(opts.partner)}</div>`)
368
+ );
369
+ }
370
+
371
+ // src/screens/posts.ts
372
+ var TYPE_META = {
373
+ IMAGE: { label: "Image", icon: icons.instagram(12) },
374
+ VIDEO: { label: "Video", icon: icons.video() },
375
+ REELS: { label: "Reel", icon: icons.video() },
376
+ CAROUSEL: { label: "Album", icon: icons.layers() }
377
+ };
378
+ function postTile(post, onAutomate) {
379
+ var _a, _b, _c;
380
+ const meta = (_a = TYPE_META[post.mediaType]) != null ? _a : TYPE_META.IMAGE;
381
+ const media = el("div", { class: "flxig-tile__media" });
382
+ if (post.media) {
383
+ append(media, [
384
+ el("img", {
385
+ attrs: { src: post.media, alt: (_b = post.caption) != null ? _b : "Instagram post", loading: "lazy" }
386
+ })
387
+ ]);
388
+ } else {
389
+ append(media, [fromMarkup(`<div class="flxig-tile__ph">${icons.instagram(28)}</div>`)]);
390
+ }
391
+ append(media, [
392
+ fromMarkup(
393
+ `<span class="flxig-tile__type">${meta.icon}<span>${meta.label}</span></span>`
394
+ )
395
+ ]);
396
+ return el(
397
+ "div",
398
+ { class: "flxig-tile" },
399
+ media,
400
+ el(
401
+ "div",
402
+ { class: "flxig-tile__body" },
403
+ el("p", {
404
+ class: "flxig-tile__cap",
405
+ text: ((_c = post.caption) == null ? void 0 : _c.trim()) || "No caption"
406
+ }),
407
+ button({
408
+ label: "Automate",
409
+ variant: "secondary",
410
+ block: true,
411
+ icon: icons.bolt(),
412
+ onClick: () => onAutomate(post)
413
+ })
414
+ )
415
+ );
416
+ }
417
+ function renderPosts(opts) {
418
+ var _a;
419
+ const username = (_a = opts.account) == null ? void 0 : _a.username;
420
+ const grid = el("div", { class: "flxig-grid" });
421
+ const sentinel = el("div", { class: "flxig-sentinel" });
422
+ const loadMore = el("div", { class: "flxig-loadmore" });
423
+ const header = el(
424
+ "div",
425
+ { class: "flxig-header" },
426
+ el(
427
+ "div",
428
+ { class: "flxig-header__id" },
429
+ fromMarkup(`<span class="flxig-avatar">${icons.instagram(18)}</span>`),
430
+ el(
431
+ "div",
432
+ {},
433
+ el("div", { class: "flxig-h2", text: username ? `@${username}` : "Instagram" }),
434
+ el("div", { class: "flxig-muted", text: "Pick a post to automate" })
435
+ )
436
+ ),
437
+ fromMarkup(
438
+ `<span class="flxig-badge">${icons.check(13)}<span>Connected</span></span>`
439
+ )
440
+ );
441
+ const attribution = fromMarkup(
442
+ `<div class="flxig-attrib"><span>Automations by</span>${flonixLogo(15)}</div>`
443
+ );
444
+ const root = el(
445
+ "div",
446
+ {},
447
+ header,
448
+ grid,
449
+ loadMore,
450
+ sentinel,
451
+ attribution
452
+ );
453
+ let hasMore = true;
454
+ let loading = false;
455
+ let empty = false;
456
+ const observer = typeof IntersectionObserver !== "undefined" ? new IntersectionObserver(
457
+ (entries) => {
458
+ if (entries.some((e) => e.isIntersecting) && hasMore && !loading && !empty) {
459
+ opts.onLoadMore();
460
+ }
461
+ },
462
+ { rootMargin: "240px" }
463
+ ) : null;
464
+ observer == null ? void 0 : observer.observe(sentinel);
465
+ const renderLoadMore = () => {
466
+ clear(loadMore);
467
+ if (loading) {
468
+ append(loadMore, [fromMarkup(icons.spinner(20))]);
469
+ } else if (hasMore && !observer) {
470
+ append(loadMore, [
471
+ button({ label: "Load more", variant: "ghost", onClick: opts.onLoadMore })
472
+ ]);
473
+ }
474
+ };
475
+ return {
476
+ element: root,
477
+ appendPosts(posts) {
478
+ empty = false;
479
+ append(
480
+ grid,
481
+ posts.map((post) => postTile(post, opts.onAutomate))
482
+ );
483
+ },
484
+ setLoadingMore(value) {
485
+ loading = value;
486
+ renderLoadMore();
487
+ },
488
+ setHasMore(value) {
489
+ hasMore = value;
490
+ renderLoadMore();
491
+ if (!value) observer == null ? void 0 : observer.disconnect();
492
+ },
493
+ showEmpty() {
494
+ empty = true;
495
+ hasMore = false;
496
+ observer == null ? void 0 : observer.disconnect();
497
+ clear(grid);
498
+ grid.replaceWith(
499
+ stateBlock({
500
+ icon: icons.instagram(30),
501
+ title: "No posts yet",
502
+ detail: "Publish a post on Instagram, then come back to automate it."
503
+ })
504
+ );
505
+ },
506
+ destroy() {
507
+ observer == null ? void 0 : observer.disconnect();
508
+ }
509
+ };
510
+ }
511
+
512
+ // src/prefill.ts
513
+ function profileUrl(account) {
514
+ if (account == null ? void 0 : account.username) return `https://instagram.com/${account.username}`;
515
+ return "https://instagram.com/";
516
+ }
517
+ function buildPrefill(post, account, type) {
518
+ const handle = (account == null ? void 0 : account.username) ? `@${account.username}` : "us";
519
+ const common = {
520
+ postId: post.id,
521
+ type,
522
+ entryButtonLabel: "Send me the link",
523
+ deliveryMessage: "Thanks for reaching out! \u{1F64C} Here's the link you asked for \u{1F447}",
524
+ // One link button prefilled; the merchant fills in their own URL.
525
+ linkButtons: [{ label: "Shop now", url: "" }],
526
+ // Follow-gate is ON and prefilled by default, per product spec.
527
+ followGate: {
528
+ enabled: true,
529
+ followProfileUrl: profileUrl(account),
530
+ followButtonLabel: `Follow ${handle}`,
531
+ followConfirmButtonLabel: "I'm following \u2705",
532
+ followUpMessage: "Awesome \u2014 thanks for following! \u{1F499} Here's your link \u{1F447}"
533
+ }
534
+ };
535
+ if (type === "COMMENT") {
536
+ return {
537
+ ...common,
538
+ name: "Comment \u2192 DM automation",
539
+ keywords: ["link", "price", "info"],
540
+ commentReply: "Just sent you a DM! \u{1F4E9}"
541
+ };
542
+ }
543
+ return {
544
+ ...common,
545
+ name: "DM keyword automation",
546
+ keywords: ["link", "info"],
547
+ commentReply: null
548
+ };
549
+ }
550
+
551
+ // src/types.ts
552
+ var MAX_LINK_BUTTONS = 3;
553
+
554
+ // src/screens/automate-dialog.ts
555
+ var TYPE_OPTIONS = [
556
+ {
557
+ type: "COMMENT",
558
+ title: "Comment automation",
559
+ detail: "Reply + DM when someone comments a keyword",
560
+ icon: icons.comment(20)
561
+ },
562
+ {
563
+ type: "DM",
564
+ title: "DM automation",
565
+ detail: "Auto-reply when someone DMs a keyword",
566
+ icon: icons.dm(20)
567
+ }
568
+ ];
569
+ function openAutomateDialog(opts) {
570
+ var _a;
571
+ let type = "COMMENT";
572
+ let draft = buildPrefill(opts.post, opts.account, type);
573
+ let submitting = false;
574
+ const body = el("div", { class: "flxig-dialog__body" });
575
+ const overlay = el("div", { class: "flxig-overlay" });
576
+ const close = () => {
577
+ document.removeEventListener("keydown", onKey);
578
+ overlay.remove();
579
+ };
580
+ const onKey = (ev) => {
581
+ if (ev.key === "Escape" && !submitting) close();
582
+ };
583
+ document.addEventListener("keydown", onKey);
584
+ overlay.addEventListener("click", (ev) => {
585
+ if (ev.target === overlay && !submitting) close();
586
+ });
587
+ const picker = el("div", { class: "flxig-seg" });
588
+ const renderPicker = () => {
589
+ picker.replaceChildren(
590
+ ...TYPE_OPTIONS.map(
591
+ (opt) => el(
592
+ "div",
593
+ {
594
+ class: "flxig-seg__opt",
595
+ dataset: { active: String(opt.type === type) },
596
+ attrs: { role: "button", tabindex: "0" },
597
+ on: {
598
+ click: () => {
599
+ if (opt.type === type) return;
600
+ type = opt.type;
601
+ draft = buildPrefill(opts.post, opts.account, type);
602
+ renderPicker();
603
+ renderForm();
604
+ }
605
+ }
606
+ },
607
+ fromMarkup(`<span class="flxig-seg__ic">${opt.icon}</span>`),
608
+ el(
609
+ "div",
610
+ {},
611
+ el("div", { class: "flxig-seg__t", text: opt.title }),
612
+ el("div", { class: "flxig-seg__d", text: opt.detail })
613
+ )
614
+ )
615
+ )
616
+ );
617
+ };
618
+ let readForm = () => draft;
619
+ const renderForm = () => {
620
+ var _a2;
621
+ const keywords = chipsInput({
622
+ values: draft.keywords,
623
+ placeholder: "Add keyword\u2026"
624
+ });
625
+ const commentReply = textInput({ value: (_a2 = draft.commentReply) != null ? _a2 : "" });
626
+ const deliveryMessage = textArea({ value: draft.deliveryMessage, rows: 3 });
627
+ const entryButtonLabel = textInput({ value: draft.entryButtonLabel });
628
+ const links = linkButtonsEditor({
629
+ values: draft.linkButtons,
630
+ max: MAX_LINK_BUTTONS
631
+ });
632
+ const followUpMessage = textArea({ value: draft.followGate.followUpMessage, rows: 2 });
633
+ const followButtonLabel = textInput({ value: draft.followGate.followButtonLabel });
634
+ const followProfileUrl = textInput({ value: draft.followGate.followProfileUrl });
635
+ const followConfirmLabel = textInput({ value: draft.followGate.followConfirmButtonLabel });
636
+ const gateFields = el(
637
+ "div",
638
+ { class: "flxig-gate__fields", dataset: { off: String(!draft.followGate.enabled) } },
639
+ field("Follow profile URL", followProfileUrl),
640
+ field("Follow button label", followButtonLabel),
641
+ field("Confirm button label", followConfirmLabel),
642
+ field("Message after they follow", followUpMessage)
643
+ );
644
+ const gateSwitch = switchToggle({
645
+ checked: draft.followGate.enabled,
646
+ onChange: (checked) => {
647
+ gateFields.dataset.off = String(!checked);
648
+ }
649
+ });
650
+ const gate = el(
651
+ "div",
652
+ { class: "flxig-gate" },
653
+ el(
654
+ "div",
655
+ { class: "flxig-gate__top" },
656
+ el(
657
+ "div",
658
+ {},
659
+ el("div", { class: "flxig-label", text: "Follow gate" }),
660
+ el("div", {
661
+ class: "flxig-hint",
662
+ text: "Require users to follow before they get the link."
663
+ })
664
+ ),
665
+ gateSwitch.element
666
+ ),
667
+ gateFields
668
+ );
669
+ const fields = [
670
+ field(
671
+ type === "COMMENT" ? "Trigger keywords (in comments)" : "Trigger keywords (in DMs)",
672
+ keywords.element,
673
+ "Press Enter or comma to add. The automation fires on these words."
674
+ )
675
+ ];
676
+ if (type === "COMMENT") {
677
+ fields.push(field("Public comment reply", commentReply, "Posted under the comment."));
678
+ }
679
+ fields.push(
680
+ field("DM message", deliveryMessage, "The direct message delivered to the user."),
681
+ field(
682
+ "Link buttons",
683
+ links.element,
684
+ `Where they enter the link(s). Up to ${MAX_LINK_BUTTONS} \u2014 each has a label and a URL.`
685
+ ),
686
+ field("Opt-in button label", entryButtonLabel, "Button users tap in the first DM."),
687
+ gate
688
+ );
689
+ body.replaceChildren(...fields);
690
+ readForm = () => ({
691
+ postId: opts.post.id,
692
+ type,
693
+ name: draft.name,
694
+ keywords: keywords.getValues(),
695
+ commentReply: type === "COMMENT" ? commentReply.value.trim() || null : null,
696
+ entryButtonLabel: entryButtonLabel.value.trim(),
697
+ deliveryMessage: deliveryMessage.value.trim(),
698
+ linkButtons: links.getValues(),
699
+ followGate: {
700
+ enabled: gateSwitch.input.checked,
701
+ followProfileUrl: followProfileUrl.value.trim(),
702
+ followButtonLabel: followButtonLabel.value.trim(),
703
+ followConfirmButtonLabel: followConfirmLabel.value.trim(),
704
+ followUpMessage: followUpMessage.value.trim()
705
+ }
706
+ });
707
+ body.prepend(
708
+ el("div", { class: "flxig-field" }, el("span", { class: "flxig-label", text: "Automation type" }), picker)
709
+ );
710
+ };
711
+ const saveBtn = button({
712
+ label: "Create automation",
713
+ variant: "primary",
714
+ icon: icons.bolt(),
715
+ onClick: async () => {
716
+ if (submitting) return;
717
+ const data = readForm();
718
+ if (!data.keywords.length) {
719
+ opts.onToast("Add at least one keyword");
720
+ return;
721
+ }
722
+ if (!data.deliveryMessage) {
723
+ opts.onToast("Add a DM message");
724
+ return;
725
+ }
726
+ submitting = true;
727
+ saveBtn.disabled = true;
728
+ saveBtn.replaceChildren(fromMarkup(icons.spinner()), el("span", { text: "Creating\u2026" }));
729
+ try {
730
+ await opts.onSubmit(data);
731
+ close();
732
+ } catch (error) {
733
+ opts.onToast(error instanceof Error ? error.message : "Something went wrong");
734
+ submitting = false;
735
+ saveBtn.disabled = false;
736
+ saveBtn.replaceChildren(fromMarkup(icons.bolt()), el("span", { text: "Create automation" }));
737
+ }
738
+ }
739
+ });
740
+ const dialog = el(
741
+ "div",
742
+ { class: "flxig-dialog", attrs: { role: "dialog", "aria-modal": "true" } },
743
+ el(
744
+ "div",
745
+ { class: "flxig-dialog__head" },
746
+ el(
747
+ "div",
748
+ {},
749
+ el("div", { class: "flxig-h2", text: "Automate this post" }),
750
+ el("div", {
751
+ class: "flxig-muted",
752
+ text: ((_a = opts.post.caption) == null ? void 0 : _a.trim()) ? truncate(opts.post.caption.trim(), 70) : "Set up comment & DM replies"
753
+ })
754
+ ),
755
+ el("button", {
756
+ class: "flxig-iconbtn",
757
+ attrs: { type: "button", "aria-label": "Close" },
758
+ html: icons.close(),
759
+ on: { click: () => !submitting && close() }
760
+ })
761
+ ),
762
+ body,
763
+ el(
764
+ "div",
765
+ { class: "flxig-dialog__foot" },
766
+ button({ label: "Cancel", variant: "ghost", onClick: () => !submitting && close() }),
767
+ saveBtn
768
+ )
769
+ );
770
+ renderPicker();
771
+ renderForm();
772
+ append(overlay, [dialog]);
773
+ opts.mount.appendChild(overlay);
774
+ return { close };
775
+ }
776
+ function truncate(value, max) {
777
+ return value.length > max ? `${value.slice(0, max - 1)}\u2026` : value;
778
+ }
779
+
780
+ // src/theme.ts
781
+ var DEFAULT_FONT_FAMILY = '"Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
782
+ var DEFAULT_RADIUS = "12px";
783
+ var DEFAULT_TOKENS = {
784
+ light: {
785
+ background: "#ffffff",
786
+ foreground: "#0a0a0b",
787
+ card: "#ffffff",
788
+ cardForeground: "#0a0a0b",
789
+ popover: "#ffffff",
790
+ popoverForeground: "#0a0a0b",
791
+ primary: "#2563eb",
792
+ primaryForeground: "#ffffff",
793
+ secondary: "#f4f4f5",
794
+ secondaryForeground: "#18181b",
795
+ muted: "#f4f4f5",
796
+ mutedForeground: "#71717a",
797
+ accent: "#eef2ff",
798
+ accentForeground: "#1e3a8a",
799
+ destructive: "#ef4444",
800
+ destructiveForeground: "#ffffff",
801
+ border: "#e4e4e7",
802
+ input: "#e4e4e7",
803
+ ring: "#2563eb"
804
+ },
805
+ dark: {
806
+ background: "#0a0a0b",
807
+ foreground: "#fafafa",
808
+ card: "#131316",
809
+ cardForeground: "#fafafa",
810
+ popover: "#131316",
811
+ popoverForeground: "#fafafa",
812
+ primary: "#3b82f6",
813
+ primaryForeground: "#ffffff",
814
+ secondary: "#27272a",
815
+ secondaryForeground: "#fafafa",
816
+ muted: "#1b1b1f",
817
+ mutedForeground: "#a1a1aa",
818
+ accent: "#1e293b",
819
+ accentForeground: "#bfdbfe",
820
+ destructive: "#f87171",
821
+ destructiveForeground: "#0a0a0b",
822
+ border: "#27272a",
823
+ input: "#2a2a2e",
824
+ ring: "#3b82f6"
825
+ }
826
+ };
827
+ function resolveTheme(config = {}) {
828
+ var _a, _b, _c, _d, _e, _f, _g;
829
+ return {
830
+ mode: (_a = config.mode) != null ? _a : "auto",
831
+ fontFamily: (_b = config.fontFamily) != null ? _b : DEFAULT_FONT_FAMILY,
832
+ radius: (_c = config.radius) != null ? _c : DEFAULT_RADIUS,
833
+ light: { ...DEFAULT_TOKENS.light, ...(_e = (_d = config.tokens) == null ? void 0 : _d.light) != null ? _e : {} },
834
+ dark: { ...DEFAULT_TOKENS.dark, ...(_g = (_f = config.tokens) == null ? void 0 : _f.dark) != null ? _g : {} }
835
+ };
836
+ }
837
+ var camelToKebab = (key) => key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
838
+ function tokensToVars(tokens) {
839
+ return Object.keys(tokens).map((key) => ` --flxig-${camelToKebab(key)}: ${tokens[key]};`).join("\n");
840
+ }
841
+ function buildThemeVars(theme) {
842
+ return `:host {
843
+ ${tokensToVars(theme.light)}
844
+ --flxig-radius: ${theme.radius};
845
+ --flxig-font: ${theme.fontFamily};
846
+ }
847
+ :host(.flxig-dark) {
848
+ ${tokensToVars(theme.dark)}
849
+ }`;
850
+ }
851
+ function isDarkActive(mode) {
852
+ if (mode === "dark") return true;
853
+ if (mode === "light") return false;
854
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
855
+ }
856
+
857
+ // src/styles.ts
858
+ var STYLES = `
859
+ *, *::before, *::after { box-sizing: border-box; }
860
+
861
+ .flxig-root {
862
+ font-family: var(--flxig-font);
863
+ color: var(--flxig-foreground);
864
+ background: var(--flxig-background);
865
+ border: 1px solid var(--flxig-border);
866
+ border-radius: var(--flxig-radius);
867
+ padding: clamp(20px, 4vw, 36px);
868
+ line-height: 1.5;
869
+ -webkit-font-smoothing: antialiased;
870
+ text-rendering: optimizeLegibility;
871
+ container-type: inline-size;
872
+ }
873
+
874
+ /* ---- typography ---- */
875
+ .flxig-h1 { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.015em; margin: 0; }
876
+ .flxig-h2 { font-size: 1.05rem; font-weight: 650; letter-spacing: -0.01em; margin: 0; }
877
+ .flxig-muted { color: var(--flxig-muted-foreground); font-size: 0.9rem; margin: 0; }
878
+ .flxig-label { display: block; font-size: 0.8rem; font-weight: 600; margin-bottom: 6px; }
879
+ .flxig-hint { font-size: 0.75rem; color: var(--flxig-muted-foreground); margin-top: 4px; }
880
+
881
+ /* ---- buttons ---- */
882
+ .flxig-btn {
883
+ appearance: none; border: 1px solid transparent; cursor: pointer;
884
+ font-family: inherit; font-size: 0.9rem; font-weight: 600;
885
+ border-radius: calc(var(--flxig-radius) - 4px);
886
+ padding: 10px 16px; display: inline-flex; align-items: center; justify-content: center;
887
+ gap: 8px; transition: filter .15s ease, background .15s ease, border-color .15s ease, opacity .15s ease;
888
+ text-decoration: none; white-space: nowrap;
889
+ }
890
+ .flxig-btn:disabled { opacity: .55; cursor: not-allowed; }
891
+ .flxig-btn--primary { background: var(--flxig-primary); color: var(--flxig-primary-foreground); }
892
+ .flxig-btn--primary:hover:not(:disabled) { filter: brightness(1.07); }
893
+ .flxig-btn--secondary { background: var(--flxig-secondary); color: var(--flxig-secondary-foreground); border-color: var(--flxig-border); }
894
+ .flxig-btn--secondary:hover:not(:disabled) { background: var(--flxig-muted); }
895
+ .flxig-btn--ghost { background: transparent; color: var(--flxig-foreground); }
896
+ .flxig-btn--ghost:hover:not(:disabled) { background: var(--flxig-muted); }
897
+ .flxig-btn--block { width: 100%; }
898
+ .flxig-btn--lg { padding: 13px 20px; font-size: 0.98rem; }
899
+
900
+ /* ---- brand logo: delta chip (light) / bare delta (dark) + wordmark ---- */
901
+ .flxig-brand { display: inline-flex; align-items: center; gap: 7px; color: var(--flxig-foreground); }
902
+ .flxig-brand__chip { display: inline-flex; align-items: center; justify-content: center; background: var(--flxig-primary); border-radius: 6px; padding: 3px; }
903
+ .flxig-brand__img { display: block; width: var(--flxig-logo-size, 18px); height: var(--flxig-logo-size, 18px); object-fit: contain; }
904
+ .flxig-brand__wordmark { display: block; height: var(--flxig-logo-size, 18px); width: auto; }
905
+ :host(.flxig-dark) .flxig-brand__chip { background: transparent; padding: 0; }
906
+
907
+ /* ---- co-brand lockup: "<partner logo> \xD7 flonix" ---- */
908
+ .flxig-cobrand { display: inline-flex; align-items: center; gap: 9px; font-size: 0.9rem; }
909
+ .flxig-cobrand__x { color: var(--flxig-muted-foreground); font-weight: 400; }
910
+ .flxig-partner { display: inline-flex; align-items: center; }
911
+ .flxig-partner__img { display: block; height: 18px; width: auto; max-width: 120px; object-fit: contain; }
912
+ .flxig-partner[data-has-dark="true"] .flxig-partner__img--dark { display: none; }
913
+ :host(.flxig-dark) .flxig-partner[data-has-dark="true"] .flxig-partner__img--light { display: none; }
914
+ :host(.flxig-dark) .flxig-partner[data-has-dark="true"] .flxig-partner__img--dark { display: block; }
915
+
916
+ /* ---- connect screen ---- */
917
+ .flxig-connect { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 18px; padding: clamp(20px, 6cqw, 52px) 8px; }
918
+ .flxig-connect__copy { display: flex; flex-direction: column; gap: 8px; max-width: 420px; }
919
+ .flxig-connect__cta { width: 100%; max-width: 340px; margin-top: 4px; }
920
+ .flxig-connect__foot { margin-top: 6px; }
921
+
922
+ /* ---- posts header ---- */
923
+ .flxig-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
924
+ .flxig-header__id { display: flex; align-items: center; gap: 10px; min-width: 0; }
925
+ .flxig-avatar { width: 38px; height: 38px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--flxig-accent); color: var(--flxig-accent-foreground); flex: none; }
926
+ .flxig-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 0.72rem; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--flxig-accent); color: var(--flxig-accent-foreground); }
927
+
928
+ /* ---- posts grid ---- */
929
+ .flxig-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
930
+ @container (min-width: 520px) { .flxig-grid { grid-template-columns: repeat(3, 1fr); } }
931
+ @container (min-width: 760px) { .flxig-grid { grid-template-columns: repeat(4, 1fr); } }
932
+
933
+ .flxig-tile { border: 1px solid var(--flxig-border); border-radius: var(--flxig-radius); overflow: hidden; background: var(--flxig-card); display: flex; flex-direction: column; }
934
+ .flxig-tile__media { position: relative; aspect-ratio: 1 / 1; background: var(--flxig-muted); overflow: hidden; }
935
+ .flxig-tile__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
936
+ .flxig-tile__ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: var(--flxig-muted-foreground); }
937
+ .flxig-tile__type { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; gap: 4px; font-size: 0.68rem; font-weight: 600; padding: 3px 7px; border-radius: 999px; background: color-mix(in srgb, #000 55%, transparent); color: #fff; backdrop-filter: blur(4px); }
938
+ .flxig-tile__body { padding: 10px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
939
+ .flxig-tile__cap { font-size: 0.78rem; color: var(--flxig-muted-foreground); margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.1em; }
940
+
941
+ .flxig-sentinel { height: 1px; }
942
+ .flxig-loadmore { display: flex; justify-content: center; padding: 18px 0 2px; color: var(--flxig-muted-foreground); }
943
+
944
+ /* ---- empty / error / loading ---- */
945
+ .flxig-state { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; text-align: center; padding: 48px 16px; color: var(--flxig-muted-foreground); }
946
+
947
+ /* ---- dialog ---- */
948
+ .flxig-overlay { position: fixed; inset: 0; background: color-mix(in srgb, #000 55%, transparent); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 2147483000; animation: flxig-fade .15s ease; }
949
+ .flxig-dialog { background: var(--flxig-popover); color: var(--flxig-popover-foreground); border: 1px solid var(--flxig-border); border-radius: var(--flxig-radius); width: min(560px, 100%); max-height: min(88vh, 760px); display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 24px 60px -20px rgba(0,0,0,.5); animation: flxig-pop .18s cubic-bezier(.2,.8,.2,1); }
950
+ .flxig-dialog__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--flxig-border); }
951
+ .flxig-dialog__body { padding: 18px 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
952
+ .flxig-dialog__foot { padding: 14px 20px; border-top: 1px solid var(--flxig-border); display: flex; gap: 10px; justify-content: flex-end; }
953
+ .flxig-iconbtn { appearance: none; background: transparent; border: none; color: var(--flxig-muted-foreground); cursor: pointer; padding: 4px; border-radius: 8px; display: inline-flex; }
954
+ .flxig-iconbtn:hover { background: var(--flxig-muted); color: var(--flxig-foreground); }
955
+
956
+ /* ---- type picker (segmented) ---- */
957
+ .flxig-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
958
+ .flxig-seg__opt { border: 1px solid var(--flxig-border); border-radius: calc(var(--flxig-radius) - 2px); padding: 12px; cursor: pointer; display: flex; gap: 10px; align-items: flex-start; background: var(--flxig-card); transition: border-color .15s, background .15s; }
959
+ .flxig-seg__opt:hover { border-color: var(--flxig-ring); }
960
+ .flxig-seg__opt[data-active="true"] { border-color: var(--flxig-primary); background: var(--flxig-accent); }
961
+ .flxig-seg__ic { color: var(--flxig-primary); margin-top: 2px; }
962
+ .flxig-seg__t { font-weight: 650; font-size: 0.88rem; }
963
+ .flxig-seg__d { font-size: 0.74rem; color: var(--flxig-muted-foreground); margin-top: 2px; }
964
+
965
+ /* ---- form fields ---- */
966
+ .flxig-field { display: block; }
967
+ .flxig-input, .flxig-textarea {
968
+ width: 100%; font-family: inherit; font-size: 0.88rem; color: var(--flxig-foreground);
969
+ background: var(--flxig-background); border: 1px solid var(--flxig-input);
970
+ border-radius: calc(var(--flxig-radius) - 4px); padding: 9px 11px; transition: border-color .15s, box-shadow .15s;
971
+ }
972
+ .flxig-input:focus, .flxig-textarea:focus { outline: none; border-color: var(--flxig-ring); box-shadow: 0 0 0 3px color-mix(in srgb, var(--flxig-ring) 25%, transparent); }
973
+ .flxig-textarea { resize: vertical; min-height: 72px; }
974
+
975
+ /* ---- follow-gate card + switch ---- */
976
+ .flxig-gate { border: 1px solid var(--flxig-border); border-radius: calc(var(--flxig-radius) - 2px); padding: 14px; display: flex; flex-direction: column; gap: 12px; background: var(--flxig-card); }
977
+ .flxig-gate__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
978
+ .flxig-gate__fields { display: flex; flex-direction: column; gap: 12px; }
979
+ .flxig-gate__fields[data-off="true"] { opacity: .5; pointer-events: none; }
980
+
981
+ .flxig-switch { position: relative; width: 40px; height: 23px; flex: none; }
982
+ .flxig-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
983
+ .flxig-switch__track { position: absolute; inset: 0; background: var(--flxig-input); border-radius: 999px; transition: background .15s; }
984
+ .flxig-switch__thumb { position: absolute; top: 2px; left: 2px; width: 19px; height: 19px; border-radius: 999px; background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0,0,0,.3); }
985
+ .flxig-switch input:checked ~ .flxig-switch__track { background: var(--flxig-primary); }
986
+ .flxig-switch input:checked ~ .flxig-switch__thumb { transform: translateX(17px); }
987
+
988
+ /* ---- chips (keywords) ---- */
989
+ .flxig-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px; border: 1px solid var(--flxig-input); border-radius: calc(var(--flxig-radius) - 4px); background: var(--flxig-background); }
990
+ .flxig-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--flxig-secondary); color: var(--flxig-secondary-foreground); font-size: 0.78rem; font-weight: 600; padding: 4px 8px; border-radius: 999px; }
991
+ .flxig-chip button { appearance: none; border: none; background: transparent; color: inherit; cursor: pointer; opacity: .6; padding: 0; display: inline-flex; }
992
+ .flxig-chip button:hover { opacity: 1; }
993
+ .flxig-chips input { flex: 1; min-width: 80px; border: none; outline: none; background: transparent; color: var(--flxig-foreground); font-family: inherit; font-size: 0.82rem; padding: 4px; }
994
+
995
+ /* ---- link buttons editor ---- */
996
+ .flxig-links__wrap { display: flex; flex-direction: column; gap: 10px; }
997
+ .flxig-links { display: flex; flex-direction: column; gap: 10px; }
998
+ .flxig-link { display: flex; align-items: center; gap: 8px; }
999
+ .flxig-link__ic { color: var(--flxig-muted-foreground); flex: none; display: inline-flex; }
1000
+ .flxig-link__inputs { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr); gap: 8px; flex: 1; min-width: 0; }
1001
+ .flxig-links__add { align-self: flex-start; padding-left: 8px; padding-right: 12px; }
1002
+ @container (max-width: 440px) { .flxig-link__inputs { grid-template-columns: 1fr; } }
1003
+
1004
+ /* ---- toast ---- */
1005
+ .flxig-toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--flxig-foreground); color: var(--flxig-background); font-size: 0.85rem; font-weight: 600; padding: 10px 16px; border-radius: 999px; display: inline-flex; align-items: center; gap: 8px; z-index: 2147483001; box-shadow: 0 10px 30px -10px rgba(0,0,0,.5); animation: flxig-pop .2s ease; }
1006
+
1007
+ /* ---- footer attribution ---- */
1008
+ .flxig-attrib { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--flxig-border); display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 0.72rem; color: var(--flxig-muted-foreground); }
1009
+
1010
+ /* ---- animations ---- */
1011
+ .flxig-spin { animation: flxig-rotate .8s linear infinite; }
1012
+ @keyframes flxig-rotate { to { transform: rotate(360deg); } }
1013
+ @keyframes flxig-fade { from { opacity: 0; } to { opacity: 1; } }
1014
+ @keyframes flxig-pop { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: scale(1); } }
1015
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; } }
1016
+ `;
1017
+
1018
+ // src/widget.ts
1019
+ var RETURN_FLAG = "flxig_connected";
1020
+ var DEFAULT_BASE_URL = "https://flonix.pro";
1021
+ var Widget = class {
1022
+ constructor(target, config) {
1023
+ this.mediaQuery = null;
1024
+ this.token = null;
1025
+ this.account = null;
1026
+ this.postsView = null;
1027
+ this.cursor = null;
1028
+ this.connecting = false;
1029
+ this.destroyed = false;
1030
+ // ---- lifecycle ----
1031
+ this.onSchemeChange = (ev) => this.applyMode(ev.matches);
1032
+ var _a, _b;
1033
+ this.config = config;
1034
+ this.transport = (_b = config.transport) != null ? _b : createHttpTransport((_a = config.baseUrl) != null ? _a : DEFAULT_BASE_URL);
1035
+ this.host = document.createElement("div");
1036
+ this.host.setAttribute("data-flonix-ig", "");
1037
+ target.appendChild(this.host);
1038
+ this.shadow = this.host.attachShadow({ mode: "open" });
1039
+ const theme = resolveTheme(config.theme);
1040
+ this.shadow.appendChild(
1041
+ el("style", { text: `${buildThemeVars(theme)}
1042
+ ${STYLES}` })
1043
+ );
1044
+ this.root = el("div", { class: "flxig-root" });
1045
+ this.content = el("div", { class: "flxig-content" });
1046
+ this.root.appendChild(this.content);
1047
+ this.shadow.appendChild(this.root);
1048
+ this.applyMode(isDarkActive(theme.mode));
1049
+ if (theme.mode === "auto" && typeof window.matchMedia === "function") {
1050
+ this.mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1051
+ this.mediaQuery.addEventListener("change", this.onSchemeChange);
1052
+ }
1053
+ void this.init();
1054
+ }
1055
+ applyMode(dark) {
1056
+ this.host.classList.toggle("flxig-dark", dark);
1057
+ }
1058
+ refresh() {
1059
+ this.cursor = null;
1060
+ void this.init();
1061
+ }
1062
+ unmount() {
1063
+ var _a, _b;
1064
+ this.destroyed = true;
1065
+ (_a = this.postsView) == null ? void 0 : _a.destroy();
1066
+ (_b = this.mediaQuery) == null ? void 0 : _b.removeEventListener("change", this.onSchemeChange);
1067
+ this.host.remove();
1068
+ }
1069
+ fail(error) {
1070
+ var _a, _b;
1071
+ const err = error instanceof Error ? error : new Error(String(error));
1072
+ (_b = (_a = this.config).onError) == null ? void 0 : _b.call(_a, err);
1073
+ return err;
1074
+ }
1075
+ // ---- flow ----
1076
+ async init() {
1077
+ var _a, _b, _c;
1078
+ this.renderLoading();
1079
+ try {
1080
+ const session = await this.transport.session({
1081
+ apiKey: this.config.apiKey,
1082
+ user: this.config.user
1083
+ });
1084
+ if (this.destroyed) return;
1085
+ this.token = session.token;
1086
+ this.account = session.account;
1087
+ if (session.connected) {
1088
+ this.clearReturnFlag();
1089
+ (_c = (_b = this.config).onConnected) == null ? void 0 : _c.call(_b, (_a = session.account) != null ? _a : { instagramId: null, username: null });
1090
+ await this.renderPosts();
1091
+ } else {
1092
+ this.renderConnect();
1093
+ }
1094
+ } catch (error) {
1095
+ this.renderError(this.fail(error).message);
1096
+ }
1097
+ }
1098
+ async startConnect() {
1099
+ if (!this.token || this.connecting) return;
1100
+ this.connecting = true;
1101
+ this.renderConnect();
1102
+ try {
1103
+ const { authorizeUrl } = await this.transport.connectStart({
1104
+ token: this.token,
1105
+ returnUrl: this.resolveReturnUrl()
1106
+ });
1107
+ window.location.href = authorizeUrl;
1108
+ } catch (error) {
1109
+ this.connecting = false;
1110
+ this.renderConnect();
1111
+ this.toast(this.fail(error).message);
1112
+ }
1113
+ }
1114
+ async renderPosts() {
1115
+ const view = renderPosts({
1116
+ account: this.account,
1117
+ onAutomate: (post) => this.openDialog(post),
1118
+ onLoadMore: () => void this.loadMore()
1119
+ });
1120
+ this.postsView = view;
1121
+ this.swap(view.element);
1122
+ await this.loadMore(true);
1123
+ }
1124
+ async loadMore(initial = false) {
1125
+ const view = this.postsView;
1126
+ if (!view || !this.token) return;
1127
+ view.setLoadingMore(true);
1128
+ try {
1129
+ const { posts, nextCursor } = await this.transport.posts({
1130
+ token: this.token,
1131
+ cursor: this.cursor
1132
+ });
1133
+ if (this.destroyed) return;
1134
+ if (initial && posts.length === 0) {
1135
+ view.showEmpty();
1136
+ return;
1137
+ }
1138
+ view.appendPosts(posts);
1139
+ this.cursor = nextCursor;
1140
+ view.setHasMore(Boolean(nextCursor));
1141
+ } catch (error) {
1142
+ this.toast(this.fail(error).message);
1143
+ } finally {
1144
+ view.setLoadingMore(false);
1145
+ }
1146
+ }
1147
+ openDialog(post) {
1148
+ if (!this.token) return;
1149
+ openAutomateDialog({
1150
+ mount: this.shadow,
1151
+ post,
1152
+ account: this.account,
1153
+ onToast: (message) => this.toast(message),
1154
+ onSubmit: (data) => this.createAutomation(data)
1155
+ });
1156
+ }
1157
+ async createAutomation(data) {
1158
+ var _a, _b;
1159
+ if (!this.token) throw new Error("Not connected");
1160
+ const result = await this.transport.createAutomation({ token: this.token, data });
1161
+ (_b = (_a = this.config).onAutomationCreated) == null ? void 0 : _b.call(_a, result);
1162
+ this.toast("Automation created \u2713");
1163
+ }
1164
+ // ---- rendering helpers ----
1165
+ swap(node) {
1166
+ clear(this.content);
1167
+ this.content.appendChild(node);
1168
+ }
1169
+ renderConnect() {
1170
+ this.swap(
1171
+ renderConnect({
1172
+ connecting: this.connecting,
1173
+ partner: this.config.partner,
1174
+ onConnect: () => void this.startConnect()
1175
+ })
1176
+ );
1177
+ }
1178
+ renderLoading() {
1179
+ this.swap(stateBlock({ icon: icons.spinner(26), title: "Loading\u2026" }));
1180
+ }
1181
+ renderError(message) {
1182
+ this.swap(
1183
+ stateBlock({
1184
+ icon: icons.close(26),
1185
+ title: "Couldn't load",
1186
+ detail: message
1187
+ })
1188
+ );
1189
+ }
1190
+ toast(message) {
1191
+ const toast = fromMarkup(
1192
+ `<div class="flxig-toast">${icons.bolt(14)}<span></span></div>`
1193
+ );
1194
+ toast.querySelector("span").textContent = message;
1195
+ this.shadow.appendChild(toast);
1196
+ setTimeout(() => toast.remove(), 2600);
1197
+ }
1198
+ // ---- return-from-OAuth handling ----
1199
+ resolveReturnUrl() {
1200
+ if (this.config.returnUrl) return this.config.returnUrl;
1201
+ if (typeof window === "undefined") return "";
1202
+ return window.location.href;
1203
+ }
1204
+ clearReturnFlag() {
1205
+ var _a;
1206
+ if (typeof window === "undefined" || !((_a = window.history) == null ? void 0 : _a.replaceState)) return;
1207
+ const url = new URL(window.location.href);
1208
+ if (url.searchParams.has(RETURN_FLAG)) {
1209
+ url.searchParams.delete(RETURN_FLAG);
1210
+ window.history.replaceState({}, "", url.toString());
1211
+ }
1212
+ }
1213
+ };
1214
+
1215
+ // src/mock.ts
1216
+ var delay = (ms) => new Promise((r) => setTimeout(r, ms));
1217
+ var TYPES = ["IMAGE", "CAROUSEL", "REELS", "VIDEO", "IMAGE"];
1218
+ var CAPTIONS = [
1219
+ "New drop is live \u{1F525} comment LINK for the shop",
1220
+ "Behind the scenes of today's shoot",
1221
+ "Our bestseller is back in stock \u2728",
1222
+ "How to style this 3 ways \u{1F447}",
1223
+ "Limited edition \u2014 only 50 made",
1224
+ "Weekend sale starts now \u{1F6CD}\uFE0F",
1225
+ null,
1226
+ "Tag a friend who needs this \u{1F499}"
1227
+ ];
1228
+ function makePage(page, perPage) {
1229
+ return Array.from({ length: perPage }, (_, i) => {
1230
+ var _a, _b;
1231
+ const n = page * perPage + i;
1232
+ return {
1233
+ id: `mock_${n}`,
1234
+ caption: (_a = CAPTIONS[n % CAPTIONS.length]) != null ? _a : null,
1235
+ media: `https://picsum.photos/seed/flonix${n}/600/600`,
1236
+ mediaType: (_b = TYPES[n % TYPES.length]) != null ? _b : "IMAGE",
1237
+ permalink: null,
1238
+ timestamp: new Date(Date.now() - n * 864e5).toISOString()
1239
+ };
1240
+ });
1241
+ }
1242
+ function createMockTransport(options = {}) {
1243
+ var _a, _b, _c;
1244
+ const totalPages = (_a = options.totalPages) != null ? _a : 3;
1245
+ const perPage = (_b = options.perPage) != null ? _b : 8;
1246
+ const storageKey = `flxig.mock.connected.${(_c = options.namespace) != null ? _c : "default"}`;
1247
+ const isConnected = () => {
1248
+ try {
1249
+ return localStorage.getItem(storageKey) === "1";
1250
+ } catch {
1251
+ return false;
1252
+ }
1253
+ };
1254
+ return {
1255
+ async session() {
1256
+ await delay(400);
1257
+ const connected = isConnected();
1258
+ return {
1259
+ connected,
1260
+ token: "mock-session-token",
1261
+ account: connected ? { instagramId: "17890000000", username: "your_brand" } : null
1262
+ };
1263
+ },
1264
+ async connectStart({ returnUrl }) {
1265
+ await delay(500);
1266
+ try {
1267
+ localStorage.setItem(storageKey, "1");
1268
+ } catch {
1269
+ }
1270
+ const url = new URL(returnUrl, window.location.href);
1271
+ url.searchParams.set("flxig_connected", "1");
1272
+ return { authorizeUrl: url.toString() };
1273
+ },
1274
+ async posts({ cursor }) {
1275
+ await delay(500);
1276
+ const page = cursor ? Number(cursor) : 0;
1277
+ const posts = makePage(page, perPage);
1278
+ const next = page + 1;
1279
+ return { posts, nextCursor: next < totalPages ? String(next) : null };
1280
+ },
1281
+ async createAutomation() {
1282
+ await delay(700);
1283
+ return { id: `mock_automation_${Date.now()}` };
1284
+ }
1285
+ };
1286
+ }
1287
+
1288
+ // src/index.ts
1289
+ var version = "0.1.0";
1290
+ function mount(target, config) {
1291
+ var _a, _b, _c;
1292
+ const element = typeof target === "string" ? document.querySelector(target) : target;
1293
+ if (!element) {
1294
+ throw new Error(`FlonixIG.mount: target not found: ${String(target)}`);
1295
+ }
1296
+ if (!(config == null ? void 0 : config.apiKey)) {
1297
+ throw new Error("FlonixIG.mount: config.apiKey is required");
1298
+ }
1299
+ if (!((_a = config == null ? void 0 : config.user) == null ? void 0 : _a.id)) {
1300
+ throw new Error("FlonixIG.mount: config.user.id is required");
1301
+ }
1302
+ if (!((_b = config == null ? void 0 : config.partner) == null ? void 0 : _b.logo) || !((_c = config == null ? void 0 : config.partner) == null ? void 0 : _c.name)) {
1303
+ throw new Error(
1304
+ "FlonixIG.mount: config.partner.name and config.partner.logo are required"
1305
+ );
1306
+ }
1307
+ return new Widget(element, config);
1308
+ }
1309
+ var FlonixIG = { mount, version };
1310
+
1311
+ export { DEFAULT_TOKENS, FlonixIG, createHttpTransport, createMockTransport, mount, version };
1312
+ //# sourceMappingURL=index.mjs.map
1313
+ //# sourceMappingURL=index.mjs.map