@fluix-ui/vanilla 0.0.6 → 0.0.7

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Toaster, NOTCH_DEFAULTS, createNotchMachine, getNotchAttrs, animateSpring, FLUIX_SPRING, TOAST_DEFAULTS } from '@fluix-ui/core';
1
+ import { Toaster, NOTCH_DEFAULTS, createNotchMachine, getNotchAttrs, MENU_DEFAULTS, createMenuMachine, getMenuAttrs, connectMenu, FLUIX_SPRING, animateSpring, TOAST_DEFAULTS } from '@fluix-ui/core';
2
2
  export { fluix } from '@fluix-ui/core';
3
3
 
4
4
  // src/index.ts
@@ -1235,7 +1235,252 @@ function createNotch(container, options) {
1235
1235
  }
1236
1236
  };
1237
1237
  }
1238
+ var SVG_NS3 = "http://www.w3.org/2000/svg";
1239
+ var GOO_MATRIX = "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10";
1240
+ function applyAttrs3(el, attrs) {
1241
+ for (const [key, value] of Object.entries(attrs)) {
1242
+ el.setAttribute(key, value);
1243
+ }
1244
+ }
1245
+ function createMenu(container, options) {
1246
+ let {
1247
+ orientation = MENU_DEFAULTS.orientation,
1248
+ variant = "pill",
1249
+ theme = "dark",
1250
+ activeId: controlledActiveId,
1251
+ onActiveChange,
1252
+ spring,
1253
+ roundness = MENU_DEFAULTS.roundness,
1254
+ blur: blurProp,
1255
+ fill,
1256
+ items
1257
+ } = options;
1258
+ const springConfig = () => spring ?? FLUIX_SPRING;
1259
+ const resolvedBlur = () => blurProp ?? Math.min(10, Math.max(6, roundness * 0.45));
1260
+ const machine = createMenuMachine({
1261
+ orientation,
1262
+ variant,
1263
+ spring,
1264
+ roundness,
1265
+ blur: blurProp,
1266
+ fill,
1267
+ initialActiveId: controlledActiveId ?? null
1268
+ });
1269
+ let snapshot = machine.store.getSnapshot();
1270
+ let lastActiveNotified = snapshot.activeId;
1271
+ const attrs = getMenuAttrs({ orientation, theme, variant });
1272
+ const filterId = `fluix-menu-goo-${Math.random().toString(36).slice(2, 8)}`;
1273
+ const isTab = variant === "tab";
1274
+ const navEl = document.createElement("nav");
1275
+ applyAttrs3(navEl, attrs.root);
1276
+ navEl.setAttribute("aria-label", "Fluix menu");
1277
+ const canvasDiv = document.createElement("div");
1278
+ applyAttrs3(canvasDiv, attrs.canvas);
1279
+ const svg = document.createElementNS(SVG_NS3, "svg");
1280
+ svg.setAttribute("xmlns", SVG_NS3);
1281
+ svg.setAttribute("width", "1");
1282
+ svg.setAttribute("height", "1");
1283
+ svg.setAttribute("viewBox", "0 0 1 1");
1284
+ svg.setAttribute("aria-hidden", "true");
1285
+ let indicatorEl;
1286
+ if (isTab) {
1287
+ indicatorEl = document.createElementNS(SVG_NS3, "path");
1288
+ applyAttrs3(indicatorEl, attrs.indicator);
1289
+ indicatorEl.setAttribute("d", "");
1290
+ indicatorEl.setAttribute("opacity", "0");
1291
+ indicatorEl.setAttribute("fill", fill ?? "var(--fluix-menu-indicator)");
1292
+ svg.appendChild(indicatorEl);
1293
+ } else {
1294
+ const defs = document.createElementNS(SVG_NS3, "defs");
1295
+ const filter = document.createElementNS(SVG_NS3, "filter");
1296
+ filter.setAttribute("id", filterId);
1297
+ filter.setAttribute("x", "-20%");
1298
+ filter.setAttribute("y", "-20%");
1299
+ filter.setAttribute("width", "140%");
1300
+ filter.setAttribute("height", "140%");
1301
+ filter.setAttribute("color-interpolation-filters", "sRGB");
1302
+ const feBlur = document.createElementNS(SVG_NS3, "feGaussianBlur");
1303
+ feBlur.setAttribute("in", "SourceGraphic");
1304
+ feBlur.setAttribute("stdDeviation", String(resolvedBlur()));
1305
+ feBlur.setAttribute("result", "blur");
1306
+ const feCM = document.createElementNS(SVG_NS3, "feColorMatrix");
1307
+ feCM.setAttribute("in", "blur");
1308
+ feCM.setAttribute("type", "matrix");
1309
+ feCM.setAttribute("values", GOO_MATRIX);
1310
+ feCM.setAttribute("result", "goo");
1311
+ const feComp = document.createElementNS(SVG_NS3, "feComposite");
1312
+ feComp.setAttribute("in", "SourceGraphic");
1313
+ feComp.setAttribute("in2", "goo");
1314
+ feComp.setAttribute("operator", "atop");
1315
+ filter.appendChild(feBlur);
1316
+ filter.appendChild(feCM);
1317
+ filter.appendChild(feComp);
1318
+ defs.appendChild(filter);
1319
+ svg.appendChild(defs);
1320
+ const gGroup = document.createElementNS(SVG_NS3, "g");
1321
+ gGroup.setAttribute("filter", `url(#${filterId})`);
1322
+ indicatorEl = document.createElementNS(SVG_NS3, "rect");
1323
+ applyAttrs3(indicatorEl, attrs.indicator);
1324
+ indicatorEl.setAttribute("x", "0");
1325
+ indicatorEl.setAttribute("y", "0");
1326
+ indicatorEl.setAttribute("width", "0");
1327
+ indicatorEl.setAttribute("height", "0");
1328
+ indicatorEl.setAttribute("rx", "0");
1329
+ indicatorEl.setAttribute("ry", "0");
1330
+ indicatorEl.setAttribute("opacity", "0");
1331
+ indicatorEl.setAttribute("fill", fill ?? "var(--fluix-menu-indicator)");
1332
+ gGroup.appendChild(indicatorEl);
1333
+ svg.appendChild(gGroup);
1334
+ }
1335
+ canvasDiv.appendChild(svg);
1336
+ navEl.appendChild(canvasDiv);
1337
+ const listDiv = document.createElement("div");
1338
+ applyAttrs3(listDiv, attrs.list);
1339
+ const buttonMap = /* @__PURE__ */ new Map();
1340
+ function createItemButton(item) {
1341
+ const btn = document.createElement("button");
1342
+ btn.type = "button";
1343
+ const active = snapshot.activeId === item.id;
1344
+ const itemAttrs = attrs.item({ id: item.id, active, disabled: item.disabled });
1345
+ applyAttrs3(btn, itemAttrs);
1346
+ if (item.disabled) btn.disabled = true;
1347
+ btn.textContent = item.label;
1348
+ btn.addEventListener("click", () => {
1349
+ if (item.disabled) return;
1350
+ if (controlledActiveId === void 0) {
1351
+ machine.setActive(item.id);
1352
+ } else {
1353
+ onActiveChange?.(item.id);
1354
+ }
1355
+ });
1356
+ buttonMap.set(item.id, btn);
1357
+ listDiv.appendChild(btn);
1358
+ }
1359
+ for (const item of items) {
1360
+ createItemButton(item);
1361
+ }
1362
+ navEl.appendChild(listDiv);
1363
+ container.appendChild(navEl);
1364
+ let size = { width: 0, height: 0 };
1365
+ let measureRaf = 0;
1366
+ const measure = () => {
1367
+ const rect = navEl.getBoundingClientRect();
1368
+ const w = Math.ceil(rect.width);
1369
+ const h = Math.ceil(rect.height);
1370
+ if (size.width !== w || size.height !== h) {
1371
+ size = { width: w, height: h };
1372
+ updateSvgSize();
1373
+ connection?.sync(false);
1374
+ }
1375
+ };
1376
+ const resizeObs = new ResizeObserver(() => {
1377
+ cancelAnimationFrame(measureRaf);
1378
+ measureRaf = requestAnimationFrame(measure);
1379
+ });
1380
+ resizeObs.observe(navEl);
1381
+ function updateSvgSize() {
1382
+ const w = Math.max(1, size.width);
1383
+ const h = Math.max(1, size.height);
1384
+ svg.setAttribute("width", String(w));
1385
+ svg.setAttribute("height", String(h));
1386
+ svg.setAttribute("viewBox", `0 0 ${w} ${h}`);
1387
+ }
1388
+ let connection = connectMenu({
1389
+ root: navEl,
1390
+ indicator: indicatorEl,
1391
+ getActiveId: () => snapshot.activeId,
1392
+ onSelect(id) {
1393
+ if (controlledActiveId === void 0) {
1394
+ machine.setActive(id);
1395
+ } else {
1396
+ onActiveChange?.(id);
1397
+ }
1398
+ },
1399
+ spring: springConfig(),
1400
+ variant,
1401
+ orientation
1402
+ });
1403
+ requestAnimationFrame(() => {
1404
+ measure();
1405
+ connection.sync(false);
1406
+ });
1407
+ const unsubscribe = machine.store.subscribe(() => {
1408
+ const next = machine.store.getSnapshot();
1409
+ snapshot = next;
1410
+ for (const item of items) {
1411
+ const btn = buttonMap.get(item.id);
1412
+ if (btn) {
1413
+ const active = next.activeId === item.id;
1414
+ const itemAttrs = attrs.item({ id: item.id, active, disabled: item.disabled });
1415
+ applyAttrs3(btn, itemAttrs);
1416
+ }
1417
+ }
1418
+ if (next.activeId && lastActiveNotified !== next.activeId && onActiveChange) {
1419
+ onActiveChange(next.activeId);
1420
+ }
1421
+ lastActiveNotified = next.activeId;
1422
+ connection.sync(false);
1423
+ });
1424
+ return {
1425
+ setActive(id) {
1426
+ machine.setActive(id);
1427
+ },
1428
+ update(opts) {
1429
+ if (opts.orientation !== void 0) orientation = opts.orientation;
1430
+ if (opts.variant !== void 0) variant = opts.variant;
1431
+ if (opts.theme !== void 0) theme = opts.theme;
1432
+ if (opts.activeId !== void 0) controlledActiveId = opts.activeId;
1433
+ if (opts.onActiveChange !== void 0) onActiveChange = opts.onActiveChange;
1434
+ if (opts.spring !== void 0) spring = opts.spring;
1435
+ if (opts.roundness !== void 0) roundness = opts.roundness;
1436
+ if (opts.blur !== void 0) blurProp = opts.blur;
1437
+ if (opts.fill !== void 0) fill = opts.fill;
1438
+ machine.configure({ orientation, variant, spring, roundness, blur: blurProp, fill });
1439
+ if (controlledActiveId !== void 0) {
1440
+ machine.setActive(controlledActiveId ?? null);
1441
+ }
1442
+ const newAttrs = getMenuAttrs({ orientation, theme, variant });
1443
+ applyAttrs3(navEl, newAttrs.root);
1444
+ if (opts.items !== void 0) {
1445
+ items = opts.items;
1446
+ listDiv.innerHTML = "";
1447
+ buttonMap.clear();
1448
+ for (const item of items) {
1449
+ createItemButton(item);
1450
+ }
1451
+ }
1452
+ connection.destroy();
1453
+ connection = connectMenu({
1454
+ root: navEl,
1455
+ indicator: indicatorEl,
1456
+ getActiveId: () => snapshot.activeId,
1457
+ onSelect(id) {
1458
+ if (controlledActiveId === void 0) {
1459
+ machine.setActive(id);
1460
+ } else {
1461
+ onActiveChange?.(id);
1462
+ }
1463
+ },
1464
+ spring: springConfig(),
1465
+ variant,
1466
+ orientation
1467
+ });
1468
+ requestAnimationFrame(() => {
1469
+ measure();
1470
+ connection.sync(false);
1471
+ });
1472
+ },
1473
+ destroy() {
1474
+ unsubscribe();
1475
+ cancelAnimationFrame(measureRaf);
1476
+ resizeObs.disconnect();
1477
+ connection.destroy();
1478
+ machine.destroy();
1479
+ navEl.remove();
1480
+ }
1481
+ };
1482
+ }
1238
1483
 
1239
- export { createNotch, createToaster };
1484
+ export { createMenu, createNotch, createToaster };
1240
1485
  //# sourceMappingURL=index.js.map
1241
1486
  //# sourceMappingURL=index.js.map