iteration-deck
Version:
AI-first prototyping web components for comparing interactive UI variations. Perfect for designers working with AI coding agents to create multiple design iterations in prototypes.
1,654 lines (1,637 loc) • 65.8 kB
JavaScript
import { jsxs, jsx } from "react/jsx-runtime";
import React, { useState, useEffect, useMemo, useCallback, useRef, forwardRef, Children, useImperativeHandle } from "react";
import { createPortal } from "react-dom";
function createStoreState() {
return {
activeDecks: {},
deckMetadata: {},
selectedDeckId: void 0
};
}
let globalState = createStoreState();
const listeners = /* @__PURE__ */ new Set();
function notifyListeners() {
const newState = {
...globalState,
activeDecks: { ...globalState.activeDecks },
deckMetadata: { ...globalState.deckMetadata }
};
console.log("[Store DEBUG] Notifying listeners:", {
listenerCount: listeners.size,
activeDecks: newState.activeDecks,
interactiveDeckCount: Object.values(newState.deckMetadata).filter((meta) => meta?.isInteractive === true).length
});
listeners.forEach((listener) => listener(newState));
}
const storeActions = {
setActiveSlide: (deckId, slideId) => {
globalState.activeDecks[deckId] = slideId;
if (globalState.deckMetadata[deckId]) {
globalState.deckMetadata[deckId].activeSlideId = slideId;
} else {
globalState.deckMetadata[deckId] = {
slideIds: [slideId],
slides: [{ id: slideId, label: slideId }],
activeSlideId: slideId,
isInteractive: true
};
}
notifyListeners();
},
registerDeck: (deckId, slideIds, label, isInteractive = true, slides) => {
const currentActive = globalState.activeDecks[deckId];
const validActiveSlide = slideIds.includes(currentActive) ? currentActive : slideIds[0];
const slideMetadata = slides || slideIds.map((id) => ({ id, label: id }));
globalState.activeDecks[deckId] = validActiveSlide;
globalState.deckMetadata[deckId] = {
slideIds: [...slideIds],
slides: slideMetadata,
activeSlideId: validActiveSlide,
label,
isInteractive
};
notifyListeners();
},
removeDeck: (deckId) => {
delete globalState.activeDecks[deckId];
delete globalState.deckMetadata[deckId];
if (globalState.selectedDeckId === deckId) {
const remainingDecks = Object.keys(globalState.activeDecks);
globalState.selectedDeckId = remainingDecks.length > 0 ? remainingDecks[0] : void 0;
}
notifyListeners();
},
setSelectedDeck: (deckId) => {
globalState.selectedDeckId = deckId;
notifyListeners();
},
getActiveSlide: (deckId) => {
return globalState.activeDecks[deckId];
},
getDeckSlides: (deckId) => {
return globalState.deckMetadata[deckId]?.slideIds || [];
},
getDeckMetadata: (deckId) => {
return globalState.deckMetadata[deckId];
},
getRegisteredDecks: () => {
return Object.keys(globalState.activeDecks);
},
getInteractiveDecks: () => {
return Object.keys(globalState.deckMetadata).filter(
(deckId) => globalState.deckMetadata[deckId]?.isInteractive === true
);
}
};
function useIterationStore() {
const [state, setState] = useState(() => globalState);
useEffect(() => {
const unsubscribe = (newState) => {
setState(newState);
};
listeners.add(unsubscribe);
setState(globalState);
return () => {
listeners.delete(unsubscribe);
};
}, []);
const result = useMemo(() => ({
...state,
...storeActions
}), [state]);
return result;
}
function useActiveSlide(deckId) {
const store = useIterationStore();
return store.activeDecks[deckId];
}
function useDeckNavigation(deckId) {
const store = useIterationStore();
const setActiveSlide = useCallback((slideId) => {
store.setActiveSlide(deckId, slideId);
}, [store, deckId]);
const navigateNext = useCallback(() => {
const metadata = store.getDeckMetadata(deckId);
if (!metadata) return false;
const currentIndex = metadata.slideIds.indexOf(metadata.activeSlideId);
if (currentIndex === -1) return false;
const nextIndex = (currentIndex + 1) % metadata.slideIds.length;
const nextSlideId = metadata.slideIds[nextIndex];
store.setActiveSlide(deckId, nextSlideId);
return true;
}, [store, deckId]);
const navigatePrev = useCallback(() => {
const metadata = store.getDeckMetadata(deckId);
if (!metadata) return false;
const currentIndex = metadata.slideIds.indexOf(metadata.activeSlideId);
if (currentIndex === -1) return false;
const prevIndex = currentIndex <= 0 ? metadata.slideIds.length - 1 : currentIndex - 1;
const prevSlideId = metadata.slideIds[prevIndex];
store.setActiveSlide(deckId, prevSlideId);
return true;
}, [store, deckId]);
return {
setActiveSlide,
navigateNext,
navigatePrev,
activeSlide: store.activeDecks[deckId],
slideCount: store.getDeckMetadata(deckId)?.slideIds.length || 0
};
}
function sheetForTag(tag) {
if (tag.sheet) {
return tag.sheet;
}
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].ownerNode === tag) {
return document.styleSheets[i];
}
}
return void 0;
}
function createStyleElement(options) {
var tag = document.createElement("style");
tag.setAttribute("data-emotion", options.key);
if (options.nonce !== void 0) {
tag.setAttribute("nonce", options.nonce);
}
tag.appendChild(document.createTextNode(""));
tag.setAttribute("data-s", "");
return tag;
}
var StyleSheet = /* @__PURE__ */ (function() {
function StyleSheet2(options) {
var _this = this;
this._insertTag = function(tag) {
var before;
if (_this.tags.length === 0) {
if (_this.insertionPoint) {
before = _this.insertionPoint.nextSibling;
} else if (_this.prepend) {
before = _this.container.firstChild;
} else {
before = _this.before;
}
} else {
before = _this.tags[_this.tags.length - 1].nextSibling;
}
_this.container.insertBefore(tag, before);
_this.tags.push(tag);
};
this.isSpeedy = options.speedy === void 0 ? true : options.speedy;
this.tags = [];
this.ctr = 0;
this.nonce = options.nonce;
this.key = options.key;
this.container = options.container;
this.prepend = options.prepend;
this.insertionPoint = options.insertionPoint;
this.before = null;
}
var _proto = StyleSheet2.prototype;
_proto.hydrate = function hydrate(nodes) {
nodes.forEach(this._insertTag);
};
_proto.insert = function insert(rule) {
if (this.ctr % (this.isSpeedy ? 65e3 : 1) === 0) {
this._insertTag(createStyleElement(this));
}
var tag = this.tags[this.tags.length - 1];
if (this.isSpeedy) {
var sheet = sheetForTag(tag);
try {
sheet.insertRule(rule, sheet.cssRules.length);
} catch (e) {
}
} else {
tag.appendChild(document.createTextNode(rule));
}
this.ctr++;
};
_proto.flush = function flush() {
this.tags.forEach(function(tag) {
var _tag$parentNode;
return (_tag$parentNode = tag.parentNode) == null ? void 0 : _tag$parentNode.removeChild(tag);
});
this.tags = [];
this.ctr = 0;
};
return StyleSheet2;
})();
var MS = "-ms-";
var MOZ = "-moz-";
var WEBKIT = "-webkit-";
var COMMENT = "comm";
var RULESET = "rule";
var DECLARATION = "decl";
var IMPORT = "@import";
var KEYFRAMES = "@keyframes";
var LAYER = "@layer";
var abs = Math.abs;
var from = String.fromCharCode;
var assign = Object.assign;
function hash(value, length2) {
return charat(value, 0) ^ 45 ? (((length2 << 2 ^ charat(value, 0)) << 2 ^ charat(value, 1)) << 2 ^ charat(value, 2)) << 2 ^ charat(value, 3) : 0;
}
function trim(value) {
return value.trim();
}
function match(value, pattern) {
return (value = pattern.exec(value)) ? value[0] : value;
}
function replace(value, pattern, replacement) {
return value.replace(pattern, replacement);
}
function indexof(value, search) {
return value.indexOf(search);
}
function charat(value, index) {
return value.charCodeAt(index) | 0;
}
function substr(value, begin, end) {
return value.slice(begin, end);
}
function strlen(value) {
return value.length;
}
function sizeof(value) {
return value.length;
}
function append(value, array) {
return array.push(value), value;
}
function combine(array, callback) {
return array.map(callback).join("");
}
var line = 1;
var column = 1;
var length = 0;
var position = 0;
var character = 0;
var characters = "";
function node(value, root, parent, type, props, children, length2) {
return { value, root, parent, type, props, children, line, column, length: length2, return: "" };
}
function copy(root, props) {
return assign(node("", null, null, "", null, null, 0), root, { length: -root.length }, props);
}
function char() {
return character;
}
function prev() {
character = position > 0 ? charat(characters, --position) : 0;
if (column--, character === 10)
column = 1, line--;
return character;
}
function next() {
character = position < length ? charat(characters, position++) : 0;
if (column++, character === 10)
column = 1, line++;
return character;
}
function peek() {
return charat(characters, position);
}
function caret() {
return position;
}
function slice(begin, end) {
return substr(characters, begin, end);
}
function token(type) {
switch (type) {
// \0 \t \n \r \s whitespace token
case 0:
case 9:
case 10:
case 13:
case 32:
return 5;
// ! + , / > @ ~ isolate token
case 33:
case 43:
case 44:
case 47:
case 62:
case 64:
case 126:
// ; { } breakpoint token
case 59:
case 123:
case 125:
return 4;
// : accompanied token
case 58:
return 3;
// " ' ( [ opening delimit token
case 34:
case 39:
case 40:
case 91:
return 2;
// ) ] closing delimit token
case 41:
case 93:
return 1;
}
return 0;
}
function alloc(value) {
return line = column = 1, length = strlen(characters = value), position = 0, [];
}
function dealloc(value) {
return characters = "", value;
}
function delimit(type) {
return trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)));
}
function whitespace(type) {
while (character = peek())
if (character < 33)
next();
else
break;
return token(type) > 2 || token(character) > 3 ? "" : " ";
}
function escaping(index, count) {
while (--count && next())
if (character < 48 || character > 102 || character > 57 && character < 65 || character > 70 && character < 97)
break;
return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32));
}
function delimiter(type) {
while (next())
switch (character) {
// ] ) " '
case type:
return position;
// " '
case 34:
case 39:
if (type !== 34 && type !== 39)
delimiter(character);
break;
// (
case 40:
if (type === 41)
delimiter(type);
break;
// \
case 92:
next();
break;
}
return position;
}
function commenter(type, index) {
while (next())
if (type + character === 47 + 10)
break;
else if (type + character === 42 + 42 && peek() === 47)
break;
return "/*" + slice(index, position - 1) + "*" + from(type === 47 ? type : next());
}
function identifier(index) {
while (!token(peek()))
next();
return slice(index, position);
}
function compile(value) {
return dealloc(parse("", null, null, null, [""], value = alloc(value), 0, [0], value));
}
function parse(value, root, parent, rule, rules, rulesets, pseudo, points, declarations) {
var index = 0;
var offset = 0;
var length2 = pseudo;
var atrule = 0;
var property = 0;
var previous = 0;
var variable = 1;
var scanning = 1;
var ampersand = 1;
var character2 = 0;
var type = "";
var props = rules;
var children = rulesets;
var reference = rule;
var characters2 = type;
while (scanning)
switch (previous = character2, character2 = next()) {
// (
case 40:
if (previous != 108 && charat(characters2, length2 - 1) == 58) {
if (indexof(characters2 += replace(delimit(character2), "&", "&\f"), "&\f") != -1)
ampersand = -1;
break;
}
// " ' [
case 34:
case 39:
case 91:
characters2 += delimit(character2);
break;
// \t \n \r \s
case 9:
case 10:
case 13:
case 32:
characters2 += whitespace(previous);
break;
// \
case 92:
characters2 += escaping(caret() - 1, 7);
continue;
// /
case 47:
switch (peek()) {
case 42:
case 47:
append(comment(commenter(next(), caret()), root, parent), declarations);
break;
default:
characters2 += "/";
}
break;
// {
case 123 * variable:
points[index++] = strlen(characters2) * ampersand;
// } ; \0
case 125 * variable:
case 59:
case 0:
switch (character2) {
// \0 }
case 0:
case 125:
scanning = 0;
// ;
case 59 + offset:
if (ampersand == -1) characters2 = replace(characters2, /\f/g, "");
if (property > 0 && strlen(characters2) - length2)
append(property > 32 ? declaration(characters2 + ";", rule, parent, length2 - 1) : declaration(replace(characters2, " ", "") + ";", rule, parent, length2 - 2), declarations);
break;
// @ ;
case 59:
characters2 += ";";
// { rule/at-rule
default:
append(reference = ruleset(characters2, root, parent, index, offset, rules, points, type, props = [], children = [], length2), rulesets);
if (character2 === 123)
if (offset === 0)
parse(characters2, root, reference, reference, props, rulesets, length2, points, children);
else
switch (atrule === 99 && charat(characters2, 3) === 110 ? 100 : atrule) {
// d l m s
case 100:
case 108:
case 109:
case 115:
parse(value, reference, reference, rule && append(ruleset(value, reference, reference, 0, 0, rules, points, type, rules, props = [], length2), children), rules, children, length2, points, rule ? props : children);
break;
default:
parse(characters2, reference, reference, reference, [""], children, 0, points, children);
}
}
index = offset = property = 0, variable = ampersand = 1, type = characters2 = "", length2 = pseudo;
break;
// :
case 58:
length2 = 1 + strlen(characters2), property = previous;
default:
if (variable < 1) {
if (character2 == 123)
--variable;
else if (character2 == 125 && variable++ == 0 && prev() == 125)
continue;
}
switch (characters2 += from(character2), character2 * variable) {
// &
case 38:
ampersand = offset > 0 ? 1 : (characters2 += "\f", -1);
break;
// ,
case 44:
points[index++] = (strlen(characters2) - 1) * ampersand, ampersand = 1;
break;
// @
case 64:
if (peek() === 45)
characters2 += delimit(next());
atrule = peek(), offset = length2 = strlen(type = characters2 += identifier(caret())), character2++;
break;
// -
case 45:
if (previous === 45 && strlen(characters2) == 2)
variable = 0;
}
}
return rulesets;
}
function ruleset(value, root, parent, index, offset, rules, points, type, props, children, length2) {
var post = offset - 1;
var rule = offset === 0 ? rules : [""];
var size = sizeof(rule);
for (var i = 0, j = 0, k = 0; i < index; ++i)
for (var x = 0, y = substr(value, post + 1, post = abs(j = points[i])), z = value; x < size; ++x)
if (z = trim(j > 0 ? rule[x] + " " + y : replace(y, /&\f/g, rule[x])))
props[k++] = z;
return node(value, root, parent, offset === 0 ? RULESET : type, props, children, length2);
}
function comment(value, root, parent) {
return node(value, root, parent, COMMENT, from(char()), substr(value, 2, -2), 0);
}
function declaration(value, root, parent, length2) {
return node(value, root, parent, DECLARATION, substr(value, 0, length2), substr(value, length2 + 1, -1), length2);
}
function serialize(children, callback) {
var output = "";
var length2 = sizeof(children);
for (var i = 0; i < length2; i++)
output += callback(children[i], i, children, callback) || "";
return output;
}
function stringify(element, index, children, callback) {
switch (element.type) {
case LAYER:
if (element.children.length) break;
case IMPORT:
case DECLARATION:
return element.return = element.return || element.value;
case COMMENT:
return "";
case KEYFRAMES:
return element.return = element.value + "{" + serialize(element.children, callback) + "}";
case RULESET:
element.value = element.props.join(",");
}
return strlen(children = serialize(element.children, callback)) ? element.return = element.value + "{" + children + "}" : "";
}
function middleware(collection) {
var length2 = sizeof(collection);
return function(element, index, children, callback) {
var output = "";
for (var i = 0; i < length2; i++)
output += collection[i](element, index, children, callback) || "";
return output;
};
}
function rulesheet(callback) {
return function(element) {
if (!element.root) {
if (element = element.return)
callback(element);
}
};
}
function memoize(fn) {
var cache = /* @__PURE__ */ Object.create(null);
return function(arg) {
if (cache[arg] === void 0) cache[arg] = fn(arg);
return cache[arg];
};
}
var identifierWithPointTracking = function identifierWithPointTracking2(begin, points, index) {
var previous = 0;
var character2 = 0;
while (true) {
previous = character2;
character2 = peek();
if (previous === 38 && character2 === 12) {
points[index] = 1;
}
if (token(character2)) {
break;
}
next();
}
return slice(begin, position);
};
var toRules = function toRules2(parsed, points) {
var index = -1;
var character2 = 44;
do {
switch (token(character2)) {
case 0:
if (character2 === 38 && peek() === 12) {
points[index] = 1;
}
parsed[index] += identifierWithPointTracking(position - 1, points, index);
break;
case 2:
parsed[index] += delimit(character2);
break;
case 4:
if (character2 === 44) {
parsed[++index] = peek() === 58 ? "&\f" : "";
points[index] = parsed[index].length;
break;
}
// fallthrough
default:
parsed[index] += from(character2);
}
} while (character2 = next());
return parsed;
};
var getRules = function getRules2(value, points) {
return dealloc(toRules(alloc(value), points));
};
var fixedElements = /* @__PURE__ */ new WeakMap();
var compat = function compat2(element) {
if (element.type !== "rule" || !element.parent || // positive .length indicates that this rule contains pseudo
// negative .length indicates that this rule has been already prefixed
element.length < 1) {
return;
}
var value = element.value;
var parent = element.parent;
var isImplicitRule = element.column === parent.column && element.line === parent.line;
while (parent.type !== "rule") {
parent = parent.parent;
if (!parent) return;
}
if (element.props.length === 1 && value.charCodeAt(0) !== 58 && !fixedElements.get(parent)) {
return;
}
if (isImplicitRule) {
return;
}
fixedElements.set(element, true);
var points = [];
var rules = getRules(value, points);
var parentRules = parent.props;
for (var i = 0, k = 0; i < rules.length; i++) {
for (var j = 0; j < parentRules.length; j++, k++) {
element.props[k] = points[i] ? rules[i].replace(/&\f/g, parentRules[j]) : parentRules[j] + " " + rules[i];
}
}
};
var removeLabel = function removeLabel2(element) {
if (element.type === "decl") {
var value = element.value;
if (
// charcode for l
value.charCodeAt(0) === 108 && // charcode for b
value.charCodeAt(2) === 98
) {
element["return"] = "";
element.value = "";
}
}
};
function prefix(value, length2) {
switch (hash(value, length2)) {
// color-adjust
case 5103:
return WEBKIT + "print-" + value + value;
// animation, animation-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function)
case 5737:
case 4201:
case 3177:
case 3433:
case 1641:
case 4457:
case 2921:
// text-decoration, filter, clip-path, backface-visibility, column, box-decoration-break
case 5572:
case 6356:
case 5844:
case 3191:
case 6645:
case 3005:
// mask, mask-image, mask-(mode|clip|size), mask-(repeat|origin), mask-position, mask-composite,
case 6391:
case 5879:
case 5623:
case 6135:
case 4599:
case 4855:
// background-clip, columns, column-(count|fill|gap|rule|rule-color|rule-style|rule-width|span|width)
case 4215:
case 6389:
case 5109:
case 5365:
case 5621:
case 3829:
return WEBKIT + value + value;
// appearance, user-select, transform, hyphens, text-size-adjust
case 5349:
case 4246:
case 4810:
case 6968:
case 2756:
return WEBKIT + value + MOZ + value + MS + value + value;
// flex, flex-direction
case 6828:
case 4268:
return WEBKIT + value + MS + value + value;
// order
case 6165:
return WEBKIT + value + MS + "flex-" + value + value;
// align-items
case 5187:
return WEBKIT + value + replace(value, /(\w+).+(:[^]+)/, WEBKIT + "box-$1$2" + MS + "flex-$1$2") + value;
// align-self
case 5443:
return WEBKIT + value + MS + "flex-item-" + replace(value, /flex-|-self/, "") + value;
// align-content
case 4675:
return WEBKIT + value + MS + "flex-line-pack" + replace(value, /align-content|flex-|-self/, "") + value;
// flex-shrink
case 5548:
return WEBKIT + value + MS + replace(value, "shrink", "negative") + value;
// flex-basis
case 5292:
return WEBKIT + value + MS + replace(value, "basis", "preferred-size") + value;
// flex-grow
case 6060:
return WEBKIT + "box-" + replace(value, "-grow", "") + WEBKIT + value + MS + replace(value, "grow", "positive") + value;
// transition
case 4554:
return WEBKIT + replace(value, /([^-])(transform)/g, "$1" + WEBKIT + "$2") + value;
// cursor
case 6187:
return replace(replace(replace(value, /(zoom-|grab)/, WEBKIT + "$1"), /(image-set)/, WEBKIT + "$1"), value, "") + value;
// background, background-image
case 5495:
case 3959:
return replace(value, /(image-set\([^]*)/, WEBKIT + "$1$`$1");
// justify-content
case 4968:
return replace(replace(value, /(.+:)(flex-)?(.*)/, WEBKIT + "box-pack:$3" + MS + "flex-pack:$3"), /s.+-b[^;]+/, "justify") + WEBKIT + value + value;
// (margin|padding)-inline-(start|end)
case 4095:
case 3583:
case 4068:
case 2532:
return replace(value, /(.+)-inline(.+)/, WEBKIT + "$1$2") + value;
// (min|max)?(width|height|inline-size|block-size)
case 8116:
case 7059:
case 5753:
case 5535:
case 5445:
case 5701:
case 4933:
case 4677:
case 5533:
case 5789:
case 5021:
case 4765:
if (strlen(value) - 1 - length2 > 6) switch (charat(value, length2 + 1)) {
// (m)ax-content, (m)in-content
case 109:
if (charat(value, length2 + 4) !== 45) break;
// (f)ill-available, (f)it-content
case 102:
return replace(value, /(.+:)(.+)-([^]+)/, "$1" + WEBKIT + "$2-$3$1" + MOZ + (charat(value, length2 + 3) == 108 ? "$3" : "$2-$3")) + value;
// (s)tretch
case 115:
return ~indexof(value, "stretch") ? prefix(replace(value, "stretch", "fill-available"), length2) + value : value;
}
break;
// position: sticky
case 4949:
if (charat(value, length2 + 1) !== 115) break;
// display: (flex|inline-flex)
case 6444:
switch (charat(value, strlen(value) - 3 - (~indexof(value, "!important") && 10))) {
// stic(k)y
case 107:
return replace(value, ":", ":" + WEBKIT) + value;
// (inline-)?fl(e)x
case 101:
return replace(value, /(.+:)([^;!]+)(;|!.+)?/, "$1" + WEBKIT + (charat(value, 14) === 45 ? "inline-" : "") + "box$3$1" + WEBKIT + "$2$3$1" + MS + "$2box$3") + value;
}
break;
// writing-mode
case 5936:
switch (charat(value, length2 + 11)) {
// vertical-l(r)
case 114:
return WEBKIT + value + MS + replace(value, /[svh]\w+-[tblr]{2}/, "tb") + value;
// vertical-r(l)
case 108:
return WEBKIT + value + MS + replace(value, /[svh]\w+-[tblr]{2}/, "tb-rl") + value;
// horizontal(-)tb
case 45:
return WEBKIT + value + MS + replace(value, /[svh]\w+-[tblr]{2}/, "lr") + value;
}
return WEBKIT + value + MS + value + value;
}
return value;
}
var prefixer = function prefixer2(element, index, children, callback) {
if (element.length > -1) {
if (!element["return"]) switch (element.type) {
case DECLARATION:
element["return"] = prefix(element.value, element.length);
break;
case KEYFRAMES:
return serialize([copy(element, {
value: replace(element.value, "@", "@" + WEBKIT)
})], callback);
case RULESET:
if (element.length) return combine(element.props, function(value) {
switch (match(value, /(::plac\w+|:read-\w+)/)) {
// :read-(only|write)
case ":read-only":
case ":read-write":
return serialize([copy(element, {
props: [replace(value, /:(read-\w+)/, ":" + MOZ + "$1")]
})], callback);
// :placeholder
case "::placeholder":
return serialize([copy(element, {
props: [replace(value, /:(plac\w+)/, ":" + WEBKIT + "input-$1")]
}), copy(element, {
props: [replace(value, /:(plac\w+)/, ":" + MOZ + "$1")]
}), copy(element, {
props: [replace(value, /:(plac\w+)/, MS + "input-$1")]
})], callback);
}
return "";
});
}
}
};
var defaultStylisPlugins = [prefixer];
var createCache = function createCache2(options) {
var key = options.key;
if (key === "css") {
var ssrStyles = document.querySelectorAll("style[data-emotion]:not([data-s])");
Array.prototype.forEach.call(ssrStyles, function(node2) {
var dataEmotionAttribute = node2.getAttribute("data-emotion");
if (dataEmotionAttribute.indexOf(" ") === -1) {
return;
}
document.head.appendChild(node2);
node2.setAttribute("data-s", "");
});
}
var stylisPlugins = options.stylisPlugins || defaultStylisPlugins;
var inserted = {};
var container;
var nodesToHydrate = [];
{
container = options.container || document.head;
Array.prototype.forEach.call(
// this means we will ignore elements which don't have a space in them which
// means that the style elements we're looking at are only Emotion 11 server-rendered style elements
document.querySelectorAll('style[data-emotion^="' + key + ' "]'),
function(node2) {
var attrib = node2.getAttribute("data-emotion").split(" ");
for (var i = 1; i < attrib.length; i++) {
inserted[attrib[i]] = true;
}
nodesToHydrate.push(node2);
}
);
}
var _insert;
var omnipresentPlugins = [compat, removeLabel];
{
var currentSheet;
var finalizingPlugins = [stringify, rulesheet(function(rule) {
currentSheet.insert(rule);
})];
var serializer = middleware(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins));
var stylis = function stylis2(styles) {
return serialize(compile(styles), serializer);
};
_insert = function insert(selector, serialized, sheet, shouldCache) {
currentSheet = sheet;
stylis(selector ? selector + "{" + serialized.styles + "}" : serialized.styles);
if (shouldCache) {
cache.inserted[serialized.name] = true;
}
};
}
var cache = {
key,
sheet: new StyleSheet({
key,
container,
nonce: options.nonce,
speedy: options.speedy,
prepend: options.prepend,
insertionPoint: options.insertionPoint
}),
nonce: options.nonce,
inserted,
registered: {},
insert: _insert
};
cache.sheet.hydrate(nodesToHydrate);
return cache;
};
function murmur2(str) {
var h = 0;
var k, i = 0, len = str.length;
for (; len >= 4; ++i, len -= 4) {
k = str.charCodeAt(i) & 255 | (str.charCodeAt(++i) & 255) << 8 | (str.charCodeAt(++i) & 255) << 16 | (str.charCodeAt(++i) & 255) << 24;
k = /* Math.imul(k, m): */
(k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16);
k ^= /* k >>> r: */
k >>> 24;
h = /* Math.imul(k, m): */
(k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16) ^ /* Math.imul(h, m): */
(h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
}
switch (len) {
case 3:
h ^= (str.charCodeAt(i + 2) & 255) << 16;
case 2:
h ^= (str.charCodeAt(i + 1) & 255) << 8;
case 1:
h ^= str.charCodeAt(i) & 255;
h = /* Math.imul(h, m): */
(h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
}
h ^= h >>> 13;
h = /* Math.imul(h, m): */
(h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
return ((h ^ h >>> 15) >>> 0).toString(36);
}
var unitlessKeys = {
animationIterationCount: 1,
aspectRatio: 1,
borderImageOutset: 1,
borderImageSlice: 1,
borderImageWidth: 1,
boxFlex: 1,
boxFlexGroup: 1,
boxOrdinalGroup: 1,
columnCount: 1,
columns: 1,
flex: 1,
flexGrow: 1,
flexPositive: 1,
flexShrink: 1,
flexNegative: 1,
flexOrder: 1,
gridRow: 1,
gridRowEnd: 1,
gridRowSpan: 1,
gridRowStart: 1,
gridColumn: 1,
gridColumnEnd: 1,
gridColumnSpan: 1,
gridColumnStart: 1,
msGridRow: 1,
msGridRowSpan: 1,
msGridColumn: 1,
msGridColumnSpan: 1,
fontWeight: 1,
lineHeight: 1,
opacity: 1,
order: 1,
orphans: 1,
scale: 1,
tabSize: 1,
widows: 1,
zIndex: 1,
zoom: 1,
WebkitLineClamp: 1,
// SVG-related properties
fillOpacity: 1,
floodOpacity: 1,
stopOpacity: 1,
strokeDasharray: 1,
strokeDashoffset: 1,
strokeMiterlimit: 1,
strokeOpacity: 1,
strokeWidth: 1
};
var hyphenateRegex = /[A-Z]|^ms/g;
var animationRegex = /_EMO_([^_]+?)_([^]*?)_EMO_/g;
var isCustomProperty = function isCustomProperty2(property) {
return property.charCodeAt(1) === 45;
};
var isProcessableValue = function isProcessableValue2(value) {
return value != null && typeof value !== "boolean";
};
var processStyleName = /* @__PURE__ */ memoize(function(styleName) {
return isCustomProperty(styleName) ? styleName : styleName.replace(hyphenateRegex, "-$&").toLowerCase();
});
var processStyleValue = function processStyleValue2(key, value) {
switch (key) {
case "animation":
case "animationName": {
if (typeof value === "string") {
return value.replace(animationRegex, function(match2, p1, p2) {
cursor = {
name: p1,
styles: p2,
next: cursor
};
return p1;
});
}
}
}
if (unitlessKeys[key] !== 1 && !isCustomProperty(key) && typeof value === "number" && value !== 0) {
return value + "px";
}
return value;
};
function handleInterpolation(mergedProps, registered, interpolation) {
if (interpolation == null) {
return "";
}
var componentSelector = interpolation;
if (componentSelector.__emotion_styles !== void 0) {
return componentSelector;
}
switch (typeof interpolation) {
case "boolean": {
return "";
}
case "object": {
var keyframes = interpolation;
if (keyframes.anim === 1) {
cursor = {
name: keyframes.name,
styles: keyframes.styles,
next: cursor
};
return keyframes.name;
}
var serializedStyles = interpolation;
if (serializedStyles.styles !== void 0) {
var next2 = serializedStyles.next;
if (next2 !== void 0) {
while (next2 !== void 0) {
cursor = {
name: next2.name,
styles: next2.styles,
next: cursor
};
next2 = next2.next;
}
}
var styles = serializedStyles.styles + ";";
return styles;
}
return createStringFromObject(mergedProps, registered, interpolation);
}
}
var asString = interpolation;
if (registered == null) {
return asString;
}
var cached = registered[asString];
return cached !== void 0 ? cached : asString;
}
function createStringFromObject(mergedProps, registered, obj) {
var string = "";
if (Array.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
string += handleInterpolation(mergedProps, registered, obj[i]) + ";";
}
} else {
for (var key in obj) {
var value = obj[key];
if (typeof value !== "object") {
var asString = value;
if (registered != null && registered[asString] !== void 0) {
string += key + "{" + registered[asString] + "}";
} else if (isProcessableValue(asString)) {
string += processStyleName(key) + ":" + processStyleValue(key, asString) + ";";
}
} else {
if (Array.isArray(value) && typeof value[0] === "string" && (registered == null || registered[value[0]] === void 0)) {
for (var _i = 0; _i < value.length; _i++) {
if (isProcessableValue(value[_i])) {
string += processStyleName(key) + ":" + processStyleValue(key, value[_i]) + ";";
}
}
} else {
var interpolated = handleInterpolation(mergedProps, registered, value);
switch (key) {
case "animation":
case "animationName": {
string += processStyleName(key) + ":" + interpolated + ";";
break;
}
default: {
string += key + "{" + interpolated + "}";
}
}
}
}
}
}
return string;
}
var labelPattern = /label:\s*([^\s;{]+)\s*(;|$)/g;
var cursor;
function serializeStyles(args, registered, mergedProps) {
if (args.length === 1 && typeof args[0] === "object" && args[0] !== null && args[0].styles !== void 0) {
return args[0];
}
var stringMode = true;
var styles = "";
cursor = void 0;
var strings = args[0];
if (strings == null || strings.raw === void 0) {
stringMode = false;
styles += handleInterpolation(mergedProps, registered, strings);
} else {
var asTemplateStringsArr = strings;
styles += asTemplateStringsArr[0];
}
for (var i = 1; i < args.length; i++) {
styles += handleInterpolation(mergedProps, registered, args[i]);
if (stringMode) {
var templateStringsArr = strings;
styles += templateStringsArr[i];
}
}
labelPattern.lastIndex = 0;
var identifierName = "";
var match2;
while ((match2 = labelPattern.exec(styles)) !== null) {
identifierName += "-" + match2[1];
}
var name = murmur2(styles) + identifierName;
return {
name,
styles,
next: cursor
};
}
function getRegisteredStyles(registered, registeredStyles, classNames) {
var rawClassName = "";
classNames.split(" ").forEach(function(className) {
if (registered[className] !== void 0) {
registeredStyles.push(registered[className] + ";");
} else if (className) {
rawClassName += className + " ";
}
});
return rawClassName;
}
var registerStyles = function registerStyles2(cache, serialized, isStringTag) {
var className = cache.key + "-" + serialized.name;
if (
// we only need to add the styles to the registered cache if the
// class name could be used further down
// the tree but if it's a string tag, we know it won't
// so we don't have to add it to registered cache.
// this improves memory usage since we can avoid storing the whole style string
cache.registered[className] === void 0
) {
cache.registered[className] = serialized.styles;
}
};
var insertStyles = function insertStyles2(cache, serialized, isStringTag) {
registerStyles(cache, serialized);
var className = cache.key + "-" + serialized.name;
if (cache.inserted[serialized.name] === void 0) {
var current = serialized;
do {
cache.insert(serialized === current ? "." + className : "", current, cache.sheet, true);
current = current.next;
} while (current !== void 0);
}
};
function insertWithoutScoping(cache, serialized) {
if (cache.inserted[serialized.name] === void 0) {
return cache.insert("", serialized, cache.sheet, true);
}
}
function merge(registered, css2, className) {
var registeredStyles = [];
var rawClassName = getRegisteredStyles(registered, registeredStyles, className);
if (registeredStyles.length < 2) {
return className;
}
return rawClassName + css2(registeredStyles);
}
var createEmotion = function createEmotion2(options) {
var cache = createCache(options);
cache.sheet.speedy = function(value) {
this.isSpeedy = value;
};
cache.compat = true;
var css2 = function css3() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var serialized = serializeStyles(args, cache.registered, void 0);
insertStyles(cache, serialized);
return cache.key + "-" + serialized.name;
};
var keyframes = function keyframes2() {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var serialized = serializeStyles(args, cache.registered);
var animation = "animation-" + serialized.name;
insertWithoutScoping(cache, {
name: serialized.name,
styles: "@keyframes " + animation + "{" + serialized.styles + "}"
});
return animation;
};
var injectGlobal = function injectGlobal2() {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
var serialized = serializeStyles(args, cache.registered);
insertWithoutScoping(cache, serialized);
};
var cx = function cx2() {
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return merge(cache.registered, css2, classnames(args));
};
return {
css: css2,
cx,
injectGlobal,
keyframes,
hydrate: function hydrate(ids) {
ids.forEach(function(key) {
cache.inserted[key] = true;
});
},
flush: function flush() {
cache.registered = {};
cache.inserted = {};
cache.sheet.flush();
},
sheet: cache.sheet,
cache,
getRegisteredStyles: getRegisteredStyles.bind(null, cache.registered),
merge: merge.bind(null, cache.registered, css2)
};
};
var classnames = function classnames2(args) {
var cls = "";
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (arg == null) continue;
var toAdd = void 0;
switch (typeof arg) {
case "boolean":
break;
case "object": {
if (Array.isArray(arg)) {
toAdd = classnames2(arg);
} else {
toAdd = "";
for (var k in arg) {
if (arg[k] && k) {
toAdd && (toAdd += " ");
toAdd += k;
}
}
}
break;
}
default: {
toAdd = arg;
}
}
if (toAdd) {
cls && (cls += " ");
cls += toAdd;
}
}
return cls;
};
var _createEmotion = createEmotion({
key: "css"
}), css = _createEmotion.css;
const toolbarStyles = css`
position: fixed;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
display: flex;
align-items: center;
min-width: 320px;
gap: 8px;
padding: 8px;
border-radius: 40px;
backdrop-filter: blur(12px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
font-weight: 500;
font-size: 14px;
line-height: 1;
color: #374151;
background-color: rgba(229, 231, 235, 0.8);
border: 1px solid rgba(156, 163, 175, 0.3);
@media (prefers-color-scheme: dark) {
color: #e5e7eb;
background-color: rgba(39, 39, 42, 0.8);
border: 1px solid rgba(75, 85, 99, 0.3);
}
`;
const separatorStyles = css`
width: 1px;
height: 20px;
background-color: rgba(156, 163, 175, 0.6);
@media (prefers-color-scheme: dark) {
background-color: rgba(107, 114, 128, 0.7);
}
`;
const navContainerStyles = css`
display: flex;
align-items: center;
gap: 0;
`;
const selectorContainerStyles = css`
position: relative;
display: flex;
align-items: center;
`;
const hiddenSelectStyles = css`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
z-index: 2;
`;
const selectorDisplayStyles = css`
display: flex;
align-items: center;
justify-content: space-between;
height: 28px;
min-width: 120px;
gap: 12px;
padding: 0 12px;
background-color: white;
border: 2px solid #d1d5db;
border-radius: 24px;
font-size: 14px;
font-weight: normal;
color: #374151;
cursor: pointer;
user-select: none;
&:hover {
background-color: #f9fafb;
}
@media (prefers-color-scheme: dark) {
background-color: #1f2937;
border: 2px solid #4b5563;
color: #e5e7eb;
&:hover {
background-color: #374151;
}
}
`;
const selectorLabelStyles = css`
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const dropdownArrowStyles = css`
font-size: 8px;
color: #6b7280;
pointer-events: none;
@media (prefers-color-scheme: dark) {
color: #9ca3af;
}
`;
const navigationContainerStyles = css`
display: flex;
align-items: center;
border-radius: 24px;
border: 2px solid #d1d5db;
overflow: hidden;
height: 28px;
background-color: #e5e7eb;
@media (prefers-color-scheme: dark) {
border: 2px solid #4b5563;
background-color: #4b5563;
}
`;
const navigationButtonStyles = css`
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 100%;
background-color: white;
border: none;
color: #6b7280;
font-size: 14px;
cursor: pointer;
user-select: none;
transition: all 0.15s ease-out;
&:hover:not(:disabled) {
background-color: #f3f4f6;
color: #374151;
}
&:active:not(:disabled) {
background-color: #e5e7eb;
transform: scale(0.95);
}
&:disabled {
opacity: 0.4;
cursor: not-allowed;
}
@media (prefers-color-scheme: dark) {
background-color: #1f2937;
color: #d1d5db;
&:hover:not(:disabled) {
background-color: #374151;
color: #e5e7eb;
}
&:active:not(:disabled) {
background-color: #4b5563;
}
&:disabled {
background-color: #374151;
color: #6b7280;
}
}
`;
const previousButtonStyles = css`
${navigationButtonStyles};
border-top-left-radius: 24px;
border-bottom-left-radius: 24px;
`;
const nextButtonStyles = css`
${navigationButtonStyles};
border-top-right-radius: 24px;
border-bottom-right-radius: 24px;
`;
const slideInfoStyles = css`
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
padding: 0 8px;
max-width: 320px;
`;
const slideLabelStyles = css`
color: #374151;
font-size: 14px;
font-weight: 500;
line-height: 16px;
min-width: 20em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@media (prefers-color-scheme: dark) {
color: #e5e7eb;
}
`;
const slideIndicatorsStyles = css`
display: flex;
align-items: center;
justify-content: flex-start;
gap: 4px;
width: 100%;
`;
const noSlidesStyles = css`
font-size: 8px;
color: #ef4444;
@media (prefers-color-scheme: dark) {
color: #f87171;
}
`;
const slideDotStyles = css`
width: 4px;
height: 4px;
border-radius: 50%;
background-color: #9ca3af;
transition: opacity 0.2s;
`;
const slideDotActiveStyles = css`
${slideDotStyles};
opacity: 0.9;
`;
const slideDotInactiveStyles = css`
${slideDotStyles};
opacity: 0.5;
`;
const iterationDeckStyles = {
toolbar: toolbarStyles,
separator: separatorStyles,
navContainer: navContainerStyles,
selectorContainer: selectorContainerStyles,
hiddenSelect: hiddenSelectStyles,
selectorDisplay: selectorDisplayStyles,
selectorLabel: selectorLabelStyles,
dropdownArrow: dropdownArrowStyles,
navigationContainer: navigationContainerStyles,
previousButton: previousButtonStyles,
nextButton: nextButtonStyles,
slideInfo: slideInfoStyles,
slideLabel: slideLabelStyles,
slideIndicators: slideIndicatorsStyles,
noSlides: noSlidesStyles,
slideDotActive: slideDotActiveStyles,
slideDotInactive: slideDotInactiveStyles
};
const DeckSelector = ({ decks, selectedDeckId, onSelect }) => {
const selectedDeck = decks.find((d) => d.id === selectedDeckId);
const displayLabel = selectedDeck ? selectedDeck.label || selectedDeck.id : "Select Deck";
if (decks.length <= 1) return null;
return /* @__PURE__ */ jsxs("div", { className: iterationDeckStyles.selectorContainer, children: [
/* @__PURE__ */ jsx(
"select",
{
className: iterationDeckStyles.hiddenSelect,
onChange: (e) => onSelect(e.target.value),
value: selectedDeckId || "",
"aria-label": "Select iteration deck",
children: decks.map((deck) => /* @__PURE__ */ jsx(
"option",
{
value: deck.id,
children: deck.label || deck.id
},
deck.id
))
}
),
/* @__PURE__ */ jsxs("div", { className: iterationDeckStyles.selectorDisplay, children: [
/* @__PURE__ */ jsx("span", { className: iterationDeckStyles.selectorLabel, children: displayLabel }),
/* @__PURE__ */ jsx("span", { className: iterationDeckStyles.dropdownArrow, children: "▼" })
] })
] });
};
const SlideNavigation = ({ onPrevious, onNext, canGoPrevious, canGoNext }) => {
return /* @__PURE__ */ jsxs("div", { className: iterationDeckStyles.navigationContainer, children: [
/* @__PURE__ */ jsx(
"button",
{
onClick: onPrevious,
disabled: !canGoPrevious,
className: iterationDeckStyles.previousButton,
"aria-label": "Previous slide (Ctrl/Cmd+Alt+[)",
title: "Previous slide (Ctrl/Cmd+Alt+[)",
children: /* @__PURE__ */ jsx("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M7 6l6-4v8l-6-4z" }) })
}
),
/* @__PURE__ */ jsx(
"button",
{
onClick: onNext,
disabled: !canGoNext,
className: iterationDeckStyles.nextButton,
"aria-label": "Next slide (Ctrl/Cmd+Alt+])",
title: "Next slide (Ctrl/Cmd+Alt+])",
children: /* @__PURE__ */ jsx("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M11 6l-6 4V2l6 4z" }) })
}
)
] });
};
const SlideInfo = ({ currentSlide, totalSlides }) => {
return /* @__PURE__ */ jsxs("div", { className: iterationDeckStyles.slideInfo, children: [
/* @__PURE__ */ jsx("span", { className: iterationDeckStyles.slideLabel, children: currentSlide?.label || "No slide selected" }),
/* @__PURE__ */ jsx("div", { className: iterationDeckStyles.slideIndicators, children: totalSlides === 0 ? /* @__PURE__ */ jsxs("span", { className: iterationDeckStyles.noSlides, children: [
"No slides (totalSlides: ",
totalSlides,
")"
] }) : Array.from({ length: totalSlides }, (_, i) => {
const isActive = i === (currentSlide?.index || 0);
return /* @__PURE__ */ jsx(
"div",
{
className: isActive ? iterationDeckStyles.slideDotActive : iterationDeckStyles.slideDotInactive,
title: `Dot ${i} - ${isActive ? "active" : "inactive"}`
},
i
);
}) })
] });
};
const IterationDeckToolbar = ({
className
}) => {
const store = useIterationStore();
const [isVisible, setIsVisible] = useState(false);
const glowStylesInjected = useRef(false);
React.useEffect(() => {
}, []);
console.log("[IterationDeckToolbar DEBUG] Rendering toolbar:", { isVisible });
const interactiveDecks = store.getInteractiveDecks().map((id) => ({
id,
label: store.deckMetadata[id]?.label
}));
const selectedDeckId = store.selectedDeckId || interactiveDecks[0]?.id;
const selectedDeck = store.deckMetadata[selectedDeckId];
const currentSlideId = selectedDeckId ? store.activeDecks[selectedDeckId] : void 0;
const slideIds = selectedDeck?.slideIds || [];
const currentSlideIndex = currentSlideId ? slideIds.indexOf(currentSlideId) : 0;
const totalSlides = slideIds.length;
const currentSlideLabel = selectedDeck?.slides?.find((slide) => slide.id === currentSlideId)?.label;
useEffect(() => {
setIsVisible(interactiveDecks.length > 0);
}, [interactiveDecks.length]);
useEffect(() => {
const handleKeyDown = (event) => {