@fluix-ui/vanilla 0.0.4 → 0.0.6

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.
@@ -105,8 +105,6 @@ var Fluix = (function (exports) {
105
105
  };
106
106
  var TOAST_DEFAULTS = {
107
107
  duration: 6e3,
108
- lightFill: "#FFFFFF",
109
- darkFill: "#141416",
110
108
  roundness: 16,
111
109
  theme: "light",
112
110
  position: "top-right",
@@ -159,7 +157,7 @@ var Fluix = (function (exports) {
159
157
  theme,
160
158
  position: merged.position ?? fallbackPosition ?? getConfig().position ?? TOAST_DEFAULTS.position,
161
159
  duration,
162
- fill: merged.fill ?? (theme === "dark" ? TOAST_DEFAULTS.darkFill : TOAST_DEFAULTS.lightFill),
160
+ fill: merged.fill,
163
161
  roundness: merged.roundness ?? TOAST_DEFAULTS.roundness,
164
162
  exiting: false,
165
163
  autoExpandDelayMs: auto.expandDelayMs,
@@ -460,6 +458,69 @@ var Fluix = (function (exports) {
460
458
  getViewportAttrs,
461
459
  connect: connectToast
462
460
  };
461
+ var NOTCH_DEFAULTS = {
462
+ roundness: 20,
463
+ pillHeight: 40,
464
+ pillMinWidth: 40
465
+ };
466
+ function createNotchMachine(initialConfig) {
467
+ const store = createStore({
468
+ open: false,
469
+ config: { ...initialConfig },
470
+ contentSize: { w: 0, h: 0 },
471
+ baseSize: { w: NOTCH_DEFAULTS.pillMinWidth, h: NOTCH_DEFAULTS.pillHeight }
472
+ });
473
+ function open() {
474
+ store.update((prev) => prev.open ? prev : { ...prev, open: true });
475
+ }
476
+ function close() {
477
+ store.update((prev) => prev.open ? { ...prev, open: false } : prev);
478
+ }
479
+ function toggle() {
480
+ store.update((prev) => ({ ...prev, open: !prev.open }));
481
+ }
482
+ function setContentSize(size) {
483
+ store.update((prev) => {
484
+ if (prev.contentSize.w === size.w && prev.contentSize.h === size.h) return prev;
485
+ return { ...prev, contentSize: size };
486
+ });
487
+ }
488
+ function setBaseSize(size) {
489
+ store.update((prev) => {
490
+ if (prev.baseSize.w === size.w && prev.baseSize.h === size.h) return prev;
491
+ return { ...prev, baseSize: size };
492
+ });
493
+ }
494
+ function configure(config) {
495
+ store.update((prev) => ({ ...prev, config: { ...prev.config, ...config } }));
496
+ }
497
+ function destroy() {
498
+ }
499
+ return { store, open, close, toggle, setContentSize, setBaseSize, configure, destroy };
500
+ }
501
+ function getNotchAttrs(context) {
502
+ const root = {
503
+ "data-fluix-notch": "",
504
+ "data-open": String(context.open),
505
+ "data-position": context.position
506
+ };
507
+ if (context.theme) {
508
+ root["data-theme"] = context.theme;
509
+ }
510
+ return {
511
+ root,
512
+ canvas: {
513
+ "data-fluix-notch-canvas": ""
514
+ },
515
+ pill: {
516
+ "data-fluix-notch-pill": ""
517
+ },
518
+ content: {
519
+ "data-fluix-notch-content": "",
520
+ "data-open": String(context.open)
521
+ }
522
+ };
523
+ }
463
524
 
464
525
  // src/toast.ts
465
526
  var WIDTH = 350;
@@ -746,7 +807,7 @@ var Fluix = (function (exports) {
746
807
  pillEl.setAttribute("height", String(HEIGHT));
747
808
  pillEl.setAttribute("rx", String(roundness));
748
809
  pillEl.setAttribute("ry", String(roundness));
749
- pillEl.setAttribute("fill", item.fill ?? "#FFFFFF");
810
+ pillEl.setAttribute("fill", item.fill ?? "var(--fluix-surface-contrast)");
750
811
  const bodyEl = document.createElementNS(SVG_NS, "rect");
751
812
  bodyEl.setAttribute("data-fluix-body", "");
752
813
  bodyEl.setAttribute("x", "0");
@@ -755,7 +816,7 @@ var Fluix = (function (exports) {
755
816
  bodyEl.setAttribute("height", "0");
756
817
  bodyEl.setAttribute("rx", String(roundness));
757
818
  bodyEl.setAttribute("ry", String(roundness));
758
- bodyEl.setAttribute("fill", item.fill ?? "#FFFFFF");
819
+ bodyEl.setAttribute("fill", item.fill ?? "var(--fluix-surface-contrast)");
759
820
  bodyEl.setAttribute("opacity", "0");
760
821
  g.appendChild(pillEl);
761
822
  g.appendChild(bodyEl);
@@ -911,11 +972,11 @@ var Fluix = (function (exports) {
911
972
  () => {
912
973
  inst.localState.ready = true;
913
974
  applyUpdate(inst, inst.item);
975
+ setupAutopilot(inst, inst.item);
914
976
  },
915
977
  32
916
978
  );
917
979
  setupAutoDismiss(inst, item, machine2);
918
- setupAutopilot(inst, item);
919
980
  measurePillWidth(inst);
920
981
  return inst;
921
982
  }
@@ -1007,7 +1068,6 @@ var Fluix = (function (exports) {
1007
1068
  );
1008
1069
  }
1009
1070
  function setupAutopilot(inst, item, machine2) {
1010
- if (!inst.localState.ready) return;
1011
1071
  if (item.autoExpandDelayMs != null && item.autoExpandDelayMs > 0) {
1012
1072
  setTimer(
1013
1073
  inst,
@@ -1050,14 +1110,59 @@ var Fluix = (function (exports) {
1050
1110
  applyAttrs(titleEl, attrs.title);
1051
1111
  if (item.styles?.title) titleEl.className = item.styles.title;
1052
1112
  }
1113
+ const hasDesc = Boolean(item.description) || Boolean(item.button);
1114
+ if (hasDesc && !inst.contentEl) {
1115
+ const contentEl = document.createElement("div");
1116
+ const descriptionEl = document.createElement("div");
1117
+ contentEl.appendChild(descriptionEl);
1118
+ inst.el.appendChild(contentEl);
1119
+ inst.contentEl = contentEl;
1120
+ inst.descriptionEl = descriptionEl;
1121
+ inst.contentRo = new ResizeObserver(() => {
1122
+ requestAnimationFrame(() => {
1123
+ const h = descriptionEl.scrollHeight;
1124
+ if (h !== inst.contentHeight) {
1125
+ inst.contentHeight = h;
1126
+ applyVars(inst, inst.item);
1127
+ }
1128
+ });
1129
+ });
1130
+ inst.contentRo.observe(descriptionEl);
1131
+ }
1053
1132
  if (inst.contentEl) applyAttrs(inst.contentEl, attrs.content);
1054
- if (inst.descriptionEl) applyAttrs(inst.descriptionEl, attrs.description);
1055
- if (item.button && inst.descriptionEl) {
1056
- const btnEl = inst.descriptionEl.querySelector("button");
1057
- if (btnEl) applyAttrs(btnEl, attrs.button);
1133
+ if (inst.descriptionEl) {
1134
+ applyAttrs(inst.descriptionEl, attrs.description);
1135
+ if (item.styles?.description) {
1136
+ inst.descriptionEl.className = item.styles.description;
1137
+ }
1138
+ const existingBtn = inst.descriptionEl.querySelector("[data-fluix-button]");
1139
+ inst.descriptionEl.textContent = "";
1140
+ if (item.description != null) {
1141
+ if (typeof item.description === "string") {
1142
+ inst.descriptionEl.textContent = item.description;
1143
+ } else if (item.description instanceof HTMLElement) {
1144
+ inst.descriptionEl.appendChild(item.description);
1145
+ }
1146
+ }
1147
+ if (item.button) {
1148
+ let btnEl = existingBtn;
1149
+ if (!btnEl) {
1150
+ btnEl = document.createElement("button");
1151
+ btnEl.type = "button";
1152
+ }
1153
+ btnEl.textContent = item.button.title;
1154
+ if (item.styles?.button) btnEl.className = item.styles.button;
1155
+ applyAttrs(btnEl, attrs.button);
1156
+ const newBtn = btnEl.cloneNode(true);
1157
+ newBtn.addEventListener("click", (e) => {
1158
+ e.stopPropagation();
1159
+ item.button?.onClick();
1160
+ });
1161
+ inst.descriptionEl.appendChild(newBtn);
1162
+ }
1058
1163
  }
1059
- inst.pillEl.setAttribute("fill", item.fill ?? "#FFFFFF");
1060
- inst.bodyEl.setAttribute("fill", item.fill ?? "#FFFFFF");
1164
+ inst.pillEl.setAttribute("fill", item.fill ?? "var(--fluix-surface-contrast)");
1165
+ inst.bodyEl.setAttribute("fill", item.fill ?? "var(--fluix-surface-contrast)");
1061
1166
  const newHeaderKey = `${item.state}-${item.title ?? item.state}`;
1062
1167
  if (newHeaderKey !== inst.headerKey) {
1063
1168
  crossfadeHeader(inst, item, attrs);
@@ -1198,6 +1303,462 @@ var Fluix = (function (exports) {
1198
1303
  };
1199
1304
  }
1200
1305
 
1306
+ // src/notch.ts
1307
+ var SVG_NS2 = "http://www.w3.org/2000/svg";
1308
+ function applyAttrs2(el, attrs) {
1309
+ for (const [key, value] of Object.entries(attrs)) {
1310
+ el.setAttribute(key, value);
1311
+ }
1312
+ }
1313
+ function resolveContent(source) {
1314
+ if (source instanceof HTMLElement) return source;
1315
+ const span = document.createElement("span");
1316
+ span.textContent = source;
1317
+ return span;
1318
+ }
1319
+ function createNotch(container, options) {
1320
+ let {
1321
+ trigger = "click",
1322
+ position = "top-center",
1323
+ spring,
1324
+ dotSize = 36,
1325
+ roundness = NOTCH_DEFAULTS.roundness,
1326
+ theme = "dark",
1327
+ fill,
1328
+ open: controlledOpen,
1329
+ onOpenChange
1330
+ } = options;
1331
+ const springConfig = () => spring ?? FLUIX_SPRING;
1332
+ const machine2 = createNotchMachine({
1333
+ position,
1334
+ trigger,
1335
+ roundness,
1336
+ fill,
1337
+ spring
1338
+ });
1339
+ let snapshot = machine2.store.getSnapshot();
1340
+ let prevOpenVal;
1341
+ const blur = () => Math.min(10, Math.max(6, roundness * 0.45));
1342
+ const collapsedW = () => dotSize;
1343
+ const collapsedH = () => dotSize;
1344
+ let contentSize = { w: 200, h: 44 };
1345
+ const hlPad = 12;
1346
+ const expandedW = () => contentSize.w + hlPad * 2;
1347
+ const expandedH = () => Math.max(contentSize.h + hlPad, dotSize);
1348
+ const targetW = () => snapshot.open ? expandedW() : collapsedW();
1349
+ const targetH = () => snapshot.open ? expandedH() : collapsedH();
1350
+ const rootW = () => Math.max(expandedW(), collapsedW());
1351
+ const rootH = () => Math.max(expandedH(), collapsedH());
1352
+ const prev = { w: 0, h: 0, initialized: false };
1353
+ let currentAnim = null;
1354
+ let highlightAnim = null;
1355
+ const hlPrev = { x: 0, y: 0, w: 0, h: 0, visible: false };
1356
+ const measureEl = document.createElement("div");
1357
+ measureEl.setAttribute("data-fluix-notch-measure", "");
1358
+ measureEl.appendChild(resolveContent(options.content).cloneNode(true));
1359
+ container.appendChild(measureEl);
1360
+ const rootEl = document.createElement("div");
1361
+ const attrs = getNotchAttrs({ open: snapshot.open, position, theme });
1362
+ applyAttrs2(rootEl, attrs.root);
1363
+ rootEl.style.width = `${rootW()}px`;
1364
+ rootEl.style.height = `${rootH()}px`;
1365
+ const canvasDiv = document.createElement("div");
1366
+ applyAttrs2(canvasDiv, attrs.canvas);
1367
+ const svg = document.createElementNS(SVG_NS2, "svg");
1368
+ svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
1369
+ svg.setAttribute("width", String(rootW()));
1370
+ svg.setAttribute("height", String(rootH()));
1371
+ svg.setAttribute("viewBox", `0 0 ${rootW()} ${rootH()}`);
1372
+ svg.setAttribute("aria-hidden", "true");
1373
+ const defs = document.createElementNS(SVG_NS2, "defs");
1374
+ const filter = document.createElementNS(SVG_NS2, "filter");
1375
+ filter.setAttribute("id", "fluix-notch-goo");
1376
+ filter.setAttribute("x", "-20%");
1377
+ filter.setAttribute("y", "-20%");
1378
+ filter.setAttribute("width", "140%");
1379
+ filter.setAttribute("height", "140%");
1380
+ filter.setAttribute("color-interpolation-filters", "sRGB");
1381
+ const feBlur = document.createElementNS(SVG_NS2, "feGaussianBlur");
1382
+ feBlur.setAttribute("in", "SourceGraphic");
1383
+ feBlur.setAttribute("stdDeviation", String(blur()));
1384
+ feBlur.setAttribute("result", "blur");
1385
+ const feCM = document.createElementNS(SVG_NS2, "feColorMatrix");
1386
+ feCM.setAttribute("in", "blur");
1387
+ feCM.setAttribute("type", "matrix");
1388
+ feCM.setAttribute("values", "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10");
1389
+ feCM.setAttribute("result", "goo");
1390
+ const feComp = document.createElementNS(SVG_NS2, "feComposite");
1391
+ feComp.setAttribute("in", "SourceGraphic");
1392
+ feComp.setAttribute("in2", "goo");
1393
+ feComp.setAttribute("operator", "atop");
1394
+ filter.appendChild(feBlur);
1395
+ filter.appendChild(feCM);
1396
+ filter.appendChild(feComp);
1397
+ defs.appendChild(filter);
1398
+ svg.appendChild(defs);
1399
+ const gGroup = document.createElementNS(SVG_NS2, "g");
1400
+ gGroup.setAttribute("filter", "url(#fluix-notch-goo)");
1401
+ const svgRectEl = document.createElementNS(SVG_NS2, "rect");
1402
+ const cw = collapsedW();
1403
+ const ch = collapsedH();
1404
+ svgRectEl.setAttribute("x", String((rootW() - cw) / 2));
1405
+ svgRectEl.setAttribute("y", String((rootH() - ch) / 2));
1406
+ svgRectEl.setAttribute("width", String(cw));
1407
+ svgRectEl.setAttribute("height", String(ch));
1408
+ svgRectEl.setAttribute("rx", String(cw / 2));
1409
+ svgRectEl.setAttribute("ry", String(ch / 2));
1410
+ svgRectEl.setAttribute("fill", fill ?? "var(--fluix-notch-bg)");
1411
+ gGroup.appendChild(svgRectEl);
1412
+ svg.appendChild(gGroup);
1413
+ const hoverBlobEl = document.createElementNS(SVG_NS2, "rect");
1414
+ hoverBlobEl.setAttribute("x", String((rootW() - cw) / 2));
1415
+ hoverBlobEl.setAttribute("y", String((rootH() - ch) / 2));
1416
+ hoverBlobEl.setAttribute("width", "0");
1417
+ hoverBlobEl.setAttribute("height", "0");
1418
+ hoverBlobEl.setAttribute("rx", "0");
1419
+ hoverBlobEl.setAttribute("ry", "0");
1420
+ hoverBlobEl.setAttribute("opacity", "0");
1421
+ hoverBlobEl.setAttribute("fill", fill ?? "var(--fluix-notch-bg)");
1422
+ gGroup.appendChild(hoverBlobEl);
1423
+ canvasDiv.appendChild(svg);
1424
+ rootEl.appendChild(canvasDiv);
1425
+ const pillDiv = document.createElement("div");
1426
+ applyAttrs2(pillDiv, attrs.pill);
1427
+ pillDiv.style.width = `${dotSize}px`;
1428
+ pillDiv.style.height = `${dotSize}px`;
1429
+ pillDiv.appendChild(resolveContent(options.pill));
1430
+ rootEl.appendChild(pillDiv);
1431
+ const contentDiv = document.createElement("div");
1432
+ applyAttrs2(contentDiv, attrs.content);
1433
+ contentDiv.appendChild(resolveContent(options.content));
1434
+ rootEl.appendChild(contentDiv);
1435
+ container.appendChild(rootEl);
1436
+ prev.w = cw;
1437
+ prev.h = ch;
1438
+ prev.initialized = true;
1439
+ let measureRaf = 0;
1440
+ const measureObs = new ResizeObserver(() => {
1441
+ cancelAnimationFrame(measureRaf);
1442
+ measureRaf = requestAnimationFrame(() => {
1443
+ const r = measureEl.getBoundingClientRect();
1444
+ if (r.width > 0 && r.height > 0) {
1445
+ const newSize = { w: Math.ceil(r.width), h: Math.ceil(r.height) };
1446
+ if (newSize.w !== contentSize.w || newSize.h !== contentSize.h) {
1447
+ contentSize = newSize;
1448
+ updateLayout();
1449
+ }
1450
+ }
1451
+ });
1452
+ });
1453
+ measureObs.observe(measureEl);
1454
+ function onItemEnter(e) {
1455
+ const target = e.target.closest("a, button");
1456
+ if (!target || !snapshot.open) return;
1457
+ const rootRect = rootEl.getBoundingClientRect();
1458
+ const itemW = target.offsetWidth;
1459
+ const itemH = target.offsetHeight;
1460
+ const itemRect = target.getBoundingClientRect();
1461
+ const itemCenterX = itemRect.left + itemRect.width / 2;
1462
+ const itemCenterY = itemRect.top + itemRect.height / 2;
1463
+ const padX = 8;
1464
+ const padY = 4;
1465
+ const blobOvershoot = Math.max(6, roundness * 0.35);
1466
+ const toW = itemW + padX * 2;
1467
+ const toH = Math.max(itemH + padY * 2, rootRect.height + blobOvershoot * 2);
1468
+ const toX = itemCenterX - rootRect.left - toW / 2;
1469
+ const toY = itemCenterY - rootRect.top - toH / 2;
1470
+ const toRx = toH / 2;
1471
+ const fromX = hlPrev.visible ? hlPrev.x : toX + toW / 2;
1472
+ const fromY = hlPrev.visible ? hlPrev.y : toY + toH / 2;
1473
+ const fromW = hlPrev.visible ? hlPrev.w : 0;
1474
+ const fromH = hlPrev.visible ? hlPrev.h : 0;
1475
+ const fromR = hlPrev.visible ? hlPrev.h / 2 : 0;
1476
+ if (highlightAnim) {
1477
+ highlightAnim.cancel();
1478
+ highlightAnim = null;
1479
+ }
1480
+ const sc = springConfig();
1481
+ const a = animateSpring(
1482
+ hoverBlobEl,
1483
+ {
1484
+ x: { from: fromX, to: toX, unit: "px" },
1485
+ y: { from: fromY, to: toY, unit: "px" },
1486
+ width: { from: fromW, to: toW, unit: "px" },
1487
+ height: { from: fromH, to: toH, unit: "px" },
1488
+ rx: { from: fromR, to: toRx, unit: "px" },
1489
+ ry: { from: fromR, to: toRx, unit: "px" }
1490
+ },
1491
+ { ...sc, stiffness: (sc.stiffness ?? 300) * 1.2 }
1492
+ );
1493
+ hlPrev.x = toX;
1494
+ hlPrev.y = toY;
1495
+ hlPrev.w = toW;
1496
+ hlPrev.h = toH;
1497
+ if (a) {
1498
+ highlightAnim = a;
1499
+ a.onfinish = () => {
1500
+ highlightAnim = null;
1501
+ hoverBlobEl.setAttribute("x", String(toX));
1502
+ hoverBlobEl.setAttribute("y", String(toY));
1503
+ hoverBlobEl.setAttribute("width", String(toW));
1504
+ hoverBlobEl.setAttribute("height", String(toH));
1505
+ hoverBlobEl.setAttribute("rx", String(toRx));
1506
+ hoverBlobEl.setAttribute("ry", String(toRx));
1507
+ hoverBlobEl.setAttribute("opacity", "1");
1508
+ };
1509
+ } else {
1510
+ hoverBlobEl.setAttribute("x", String(toX));
1511
+ hoverBlobEl.setAttribute("y", String(toY));
1512
+ hoverBlobEl.setAttribute("width", String(toW));
1513
+ hoverBlobEl.setAttribute("height", String(toH));
1514
+ hoverBlobEl.setAttribute("rx", String(toRx));
1515
+ hoverBlobEl.setAttribute("ry", String(toRx));
1516
+ hoverBlobEl.setAttribute("opacity", "1");
1517
+ }
1518
+ hoverBlobEl.setAttribute("opacity", "1");
1519
+ hlPrev.visible = true;
1520
+ }
1521
+ function resetHoverBlobImmediate() {
1522
+ if (highlightAnim) {
1523
+ highlightAnim.cancel();
1524
+ highlightAnim = null;
1525
+ }
1526
+ hoverBlobEl.setAttribute("x", String(rootW() / 2));
1527
+ hoverBlobEl.setAttribute("y", String(rootH() / 2));
1528
+ hoverBlobEl.setAttribute("width", "0");
1529
+ hoverBlobEl.setAttribute("height", "0");
1530
+ hoverBlobEl.setAttribute("rx", "0");
1531
+ hoverBlobEl.setAttribute("ry", "0");
1532
+ hoverBlobEl.setAttribute("opacity", "0");
1533
+ hlPrev.visible = false;
1534
+ }
1535
+ function onItemLeave() {
1536
+ if (!hlPrev.visible) return;
1537
+ const cx = hlPrev.x + hlPrev.w / 2;
1538
+ const cy = hlPrev.y + hlPrev.h / 2;
1539
+ const sc = springConfig();
1540
+ const a = animateSpring(
1541
+ hoverBlobEl,
1542
+ {
1543
+ x: { from: hlPrev.x, to: cx, unit: "px" },
1544
+ y: { from: hlPrev.y, to: cy, unit: "px" },
1545
+ width: { from: hlPrev.w, to: 0, unit: "px" },
1546
+ height: { from: hlPrev.h, to: 0, unit: "px" },
1547
+ rx: { from: hlPrev.h / 2, to: 0, unit: "px" },
1548
+ ry: { from: hlPrev.h / 2, to: 0, unit: "px" }
1549
+ },
1550
+ { ...sc, stiffness: (sc.stiffness ?? 300) * 1.2 }
1551
+ );
1552
+ if (a) {
1553
+ highlightAnim = a;
1554
+ a.onfinish = () => {
1555
+ highlightAnim = null;
1556
+ hoverBlobEl.setAttribute("x", String(cx));
1557
+ hoverBlobEl.setAttribute("y", String(cy));
1558
+ hoverBlobEl.setAttribute("width", "0");
1559
+ hoverBlobEl.setAttribute("height", "0");
1560
+ hoverBlobEl.setAttribute("rx", "0");
1561
+ hoverBlobEl.setAttribute("ry", "0");
1562
+ hoverBlobEl.setAttribute("opacity", "0");
1563
+ };
1564
+ } else {
1565
+ hoverBlobEl.setAttribute("x", String(cx));
1566
+ hoverBlobEl.setAttribute("y", String(cy));
1567
+ hoverBlobEl.setAttribute("width", "0");
1568
+ hoverBlobEl.setAttribute("height", "0");
1569
+ hoverBlobEl.setAttribute("rx", "0");
1570
+ hoverBlobEl.setAttribute("ry", "0");
1571
+ hoverBlobEl.setAttribute("opacity", "0");
1572
+ }
1573
+ hlPrev.visible = false;
1574
+ }
1575
+ function handleOpen() {
1576
+ if (controlledOpen === void 0) machine2.open();
1577
+ else onOpenChange?.(true);
1578
+ }
1579
+ function handleClose() {
1580
+ if (controlledOpen === void 0) machine2.close();
1581
+ else onOpenChange?.(false);
1582
+ }
1583
+ function handleToggle() {
1584
+ if (controlledOpen === void 0) machine2.toggle();
1585
+ else onOpenChange?.(!snapshot.open);
1586
+ }
1587
+ function onMouseEnter() {
1588
+ if (trigger === "hover") handleOpen();
1589
+ }
1590
+ function onMouseLeave() {
1591
+ if (trigger === "hover") {
1592
+ handleClose();
1593
+ resetHoverBlobImmediate();
1594
+ return;
1595
+ }
1596
+ onItemLeave();
1597
+ }
1598
+ function onClick() {
1599
+ if (trigger === "click") handleToggle();
1600
+ }
1601
+ rootEl.addEventListener("mouseenter", onMouseEnter);
1602
+ rootEl.addEventListener("mouseleave", onMouseLeave);
1603
+ rootEl.addEventListener("mouseover", onItemEnter);
1604
+ rootEl.addEventListener("click", onClick);
1605
+ function animateRect() {
1606
+ const tw = targetW();
1607
+ const th = targetH();
1608
+ if (tw === prev.w && th === prev.h) return;
1609
+ if (currentAnim) {
1610
+ currentAnim.cancel();
1611
+ currentAnim = null;
1612
+ }
1613
+ const rw = rootW();
1614
+ const rh = rootH();
1615
+ const fromW = prev.w;
1616
+ const fromH = prev.h;
1617
+ const fromX = (rw - fromW) / 2;
1618
+ const fromY = (rh - fromH) / 2;
1619
+ const toX = (rw - tw) / 2;
1620
+ const toY = (rh - th) / 2;
1621
+ prev.w = tw;
1622
+ prev.h = th;
1623
+ const isCollapsing = tw === collapsedW() && th === collapsedH();
1624
+ const wasCollapsed = fromW === collapsedW() && fromH === collapsedH();
1625
+ const fromRx = wasCollapsed ? collapsedW() / 2 : roundness;
1626
+ const toRx = isCollapsing ? collapsedW() / 2 : roundness;
1627
+ const a = animateSpring(
1628
+ svgRectEl,
1629
+ {
1630
+ width: { from: fromW, to: tw, unit: "px" },
1631
+ height: { from: fromH, to: th, unit: "px" },
1632
+ x: { from: fromX, to: toX, unit: "px" },
1633
+ y: { from: fromY, to: toY, unit: "px" },
1634
+ rx: { from: fromRx, to: toRx, unit: "px" },
1635
+ ry: { from: fromRx, to: toRx, unit: "px" }
1636
+ },
1637
+ springConfig()
1638
+ );
1639
+ if (a) {
1640
+ currentAnim = a;
1641
+ a.onfinish = () => {
1642
+ currentAnim = null;
1643
+ svgRectEl.setAttribute("width", String(tw));
1644
+ svgRectEl.setAttribute("height", String(th));
1645
+ svgRectEl.setAttribute("x", String(toX));
1646
+ svgRectEl.setAttribute("y", String(toY));
1647
+ svgRectEl.setAttribute("rx", String(toRx));
1648
+ svgRectEl.setAttribute("ry", String(toRx));
1649
+ };
1650
+ } else {
1651
+ svgRectEl.setAttribute("width", String(tw));
1652
+ svgRectEl.setAttribute("height", String(th));
1653
+ svgRectEl.setAttribute("x", String(toX));
1654
+ svgRectEl.setAttribute("y", String(toY));
1655
+ svgRectEl.setAttribute("rx", String(toRx));
1656
+ svgRectEl.setAttribute("ry", String(toRx));
1657
+ }
1658
+ }
1659
+ function updateLayout() {
1660
+ const isOpen = snapshot.open;
1661
+ const newAttrs = getNotchAttrs({ open: isOpen, position, theme });
1662
+ applyAttrs2(rootEl, newAttrs.root);
1663
+ rootEl.style.width = `${rootW()}px`;
1664
+ rootEl.style.height = `${rootH()}px`;
1665
+ svg.setAttribute("width", String(rootW()));
1666
+ svg.setAttribute("height", String(rootH()));
1667
+ svg.setAttribute("viewBox", `0 0 ${rootW()} ${rootH()}`);
1668
+ feBlur.setAttribute("stdDeviation", String(blur()));
1669
+ svgRectEl.setAttribute("fill", fill ?? "var(--fluix-notch-bg)");
1670
+ hoverBlobEl.setAttribute("fill", fill ?? "var(--fluix-notch-bg)");
1671
+ applyAttrs2(contentDiv, newAttrs.content);
1672
+ animateRect();
1673
+ if (!isOpen) {
1674
+ resetHoverBlobImmediate();
1675
+ }
1676
+ document.documentElement.style.setProperty(
1677
+ "--fluix-notch-offset",
1678
+ `${rootH()}px`
1679
+ );
1680
+ }
1681
+ const unsubscribe = machine2.store.subscribe(() => {
1682
+ const next = machine2.store.getSnapshot();
1683
+ snapshot = next;
1684
+ if (controlledOpen !== void 0) {
1685
+ if (controlledOpen && !next.open) machine2.open();
1686
+ else if (!controlledOpen && next.open) machine2.close();
1687
+ }
1688
+ if (prevOpenVal !== void 0 && prevOpenVal !== next.open) {
1689
+ onOpenChange?.(next.open);
1690
+ }
1691
+ prevOpenVal = next.open;
1692
+ updateLayout();
1693
+ });
1694
+ updateLayout();
1695
+ document.documentElement.style.setProperty(
1696
+ "--fluix-notch-offset",
1697
+ `${rootH()}px`
1698
+ );
1699
+ return {
1700
+ open() {
1701
+ handleOpen();
1702
+ },
1703
+ close() {
1704
+ handleClose();
1705
+ },
1706
+ toggle() {
1707
+ handleToggle();
1708
+ },
1709
+ destroy() {
1710
+ unsubscribe();
1711
+ cancelAnimationFrame(measureRaf);
1712
+ measureObs.disconnect();
1713
+ currentAnim?.cancel();
1714
+ highlightAnim?.cancel();
1715
+ rootEl.removeEventListener("mouseenter", onMouseEnter);
1716
+ rootEl.removeEventListener("mouseleave", onMouseLeave);
1717
+ rootEl.removeEventListener("mouseover", onItemEnter);
1718
+ rootEl.removeEventListener("click", onClick);
1719
+ measureEl.remove();
1720
+ rootEl.remove();
1721
+ document.documentElement.style.removeProperty("--fluix-notch-offset");
1722
+ },
1723
+ update(opts) {
1724
+ if (opts.trigger !== void 0) trigger = opts.trigger;
1725
+ if (opts.position !== void 0) position = opts.position;
1726
+ if (opts.spring !== void 0) spring = opts.spring;
1727
+ if (opts.dotSize !== void 0) dotSize = opts.dotSize;
1728
+ if (opts.roundness !== void 0) roundness = opts.roundness;
1729
+ if (opts.theme !== void 0) theme = opts.theme;
1730
+ if (opts.fill !== void 0) fill = opts.fill;
1731
+ if (opts.open !== void 0) controlledOpen = opts.open;
1732
+ if (opts.onOpenChange !== void 0) onOpenChange = opts.onOpenChange;
1733
+ if (opts.pill !== void 0) {
1734
+ pillDiv.textContent = "";
1735
+ pillDiv.appendChild(resolveContent(opts.pill));
1736
+ }
1737
+ if (opts.content !== void 0) {
1738
+ contentDiv.textContent = "";
1739
+ contentDiv.appendChild(resolveContent(opts.content));
1740
+ measureEl.textContent = "";
1741
+ measureEl.appendChild(resolveContent(opts.content).cloneNode(true));
1742
+ }
1743
+ pillDiv.style.width = `${dotSize}px`;
1744
+ pillDiv.style.height = `${dotSize}px`;
1745
+ machine2.configure({ position, trigger, roundness, fill, spring });
1746
+ if (controlledOpen !== void 0) {
1747
+ if (controlledOpen && !snapshot.open) machine2.open();
1748
+ else if (!controlledOpen && snapshot.open) machine2.close();
1749
+ }
1750
+ rootEl.removeEventListener("mouseenter", onMouseEnter);
1751
+ rootEl.removeEventListener("mouseleave", onMouseLeave);
1752
+ rootEl.removeEventListener("click", onClick);
1753
+ rootEl.addEventListener("mouseenter", onMouseEnter);
1754
+ rootEl.addEventListener("mouseleave", onMouseLeave);
1755
+ rootEl.addEventListener("click", onClick);
1756
+ updateLayout();
1757
+ }
1758
+ };
1759
+ }
1760
+
1761
+ exports.createNotch = createNotch;
1201
1762
  exports.createToaster = createToaster;
1202
1763
  exports.fluix = fluix;
1203
1764