@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/README.md +106 -2
- package/dist/index.cjs +246 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -3
- package/dist/index.d.ts +35 -3
- package/dist/index.global.js +954 -0
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +247 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Toaster, NOTCH_DEFAULTS, createNotchMachine, getNotchAttrs,
|
|
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
|