@abydahana/aksara-ui 1.1.7 → 1.2.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/aksara.esm.js +131 -20
- package/dist/aksara.js +131 -20
- package/dist/aksara.min.js +1 -1
- package/package.json +1 -1
package/dist/aksara.esm.js
CHANGED
|
@@ -1339,9 +1339,22 @@ function getArbitrarySheet() {
|
|
|
1339
1339
|
return null;
|
|
1340
1340
|
if (!arbitrarySheet) {
|
|
1341
1341
|
if ("adoptedStyleSheets" in document && typeof CSSStyleSheet !== "undefined") {
|
|
1342
|
-
|
|
1343
|
-
|
|
1342
|
+
try {
|
|
1343
|
+
arbitrarySheet = new CSSStyleSheet();
|
|
1344
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, arbitrarySheet];
|
|
1345
|
+
return arbitrarySheet;
|
|
1346
|
+
}
|
|
1347
|
+
catch {
|
|
1348
|
+
// Fallback to style tag below
|
|
1349
|
+
}
|
|
1344
1350
|
}
|
|
1351
|
+
let styleEl = document.getElementById("aksara-arbitrary-styles");
|
|
1352
|
+
if (!styleEl) {
|
|
1353
|
+
styleEl = document.createElement("style");
|
|
1354
|
+
styleEl.id = "aksara-arbitrary-styles";
|
|
1355
|
+
document.head?.appendChild(styleEl);
|
|
1356
|
+
}
|
|
1357
|
+
arbitrarySheet = styleEl.sheet;
|
|
1345
1358
|
}
|
|
1346
1359
|
return arbitrarySheet;
|
|
1347
1360
|
}
|
|
@@ -1388,6 +1401,8 @@ const runtimeArbitraryPropertyMap = {
|
|
|
1388
1401
|
bottom: (v) => `inset-block-end:${v}`,
|
|
1389
1402
|
start: (v) => `inset-inline-start:${v}`,
|
|
1390
1403
|
end: (v) => `inset-inline-end:${v}`,
|
|
1404
|
+
left: (v) => `left:${v}`,
|
|
1405
|
+
right: (v) => `right:${v}`,
|
|
1391
1406
|
inset: (v) => `inset:${v}`,
|
|
1392
1407
|
"inset-x": (v) => `inset-inline:${v}`,
|
|
1393
1408
|
"inset-y": (v) => `inset-block:${v}`,
|
|
@@ -1395,17 +1410,66 @@ const runtimeArbitraryPropertyMap = {
|
|
|
1395
1410
|
"translate-y": (v) => `transform:translateY(${v})`,
|
|
1396
1411
|
rotate: (v) => `transform:rotate(${v})`,
|
|
1397
1412
|
scale: (v) => `transform:scale(${v})`,
|
|
1413
|
+
"skew-x": (v) => `transform:skewX(${v})`,
|
|
1414
|
+
"skew-y": (v) => `transform:skewY(${v})`,
|
|
1398
1415
|
rounded: (v) => `border-radius:${v}`,
|
|
1399
1416
|
border: (v) => `border-width:${v}`,
|
|
1417
|
+
"border-t": (v) => `border-top-width:${v}`,
|
|
1418
|
+
"border-b": (v) => `border-bottom-width:${v}`,
|
|
1419
|
+
"border-s": (v) => `border-inline-start-width:${v}`,
|
|
1420
|
+
"border-e": (v) => `border-inline-end-width:${v}`,
|
|
1421
|
+
"border-x": (v) => `border-inline-width:${v}`,
|
|
1422
|
+
"border-y": (v) => `border-block-width:${v}`,
|
|
1400
1423
|
opacity: (v) => `opacity:${v}`,
|
|
1401
1424
|
z: (v) => `z-index:${v}`,
|
|
1402
1425
|
leading: (v) => `line-height:${v}`,
|
|
1403
1426
|
tracking: (v) => `letter-spacing:${v}`,
|
|
1404
|
-
text: (v) =>
|
|
1427
|
+
text: (v) => {
|
|
1428
|
+
if (/^(start|center|end|justify|left|right|inline-start|inline-end)$/i.test(v)) {
|
|
1429
|
+
return `text-align:${v}`;
|
|
1430
|
+
}
|
|
1431
|
+
return /^(#[0-9a-fA-F]+|rgb|hsl|var\(--|currentColor|transparent)/i.test(v) ? `color:${v}` : `font-size:${v}`;
|
|
1432
|
+
},
|
|
1405
1433
|
bg: (v) => `background-color:${v}`,
|
|
1434
|
+
"bg-color": (v) => `background-color:${v}`,
|
|
1406
1435
|
overscroll: (v) => `overscroll-behavior:${v}`,
|
|
1407
1436
|
"overscroll-x": (v) => `overscroll-behavior-x:${v}`,
|
|
1408
|
-
"overscroll-y": (v) => `overscroll-behavior-y:${v}
|
|
1437
|
+
"overscroll-y": (v) => `overscroll-behavior-y:${v}`,
|
|
1438
|
+
fw: (v) => `font-weight:${v}`,
|
|
1439
|
+
"font-weight": (v) => `font-weight:${v}`,
|
|
1440
|
+
fs: (v) => `font-size:${v}`,
|
|
1441
|
+
"font-size": (v) => `font-size:${v}`,
|
|
1442
|
+
lh: (v) => `line-height:${v}`,
|
|
1443
|
+
"line-height": (v) => `line-height:${v}`,
|
|
1444
|
+
"text-align": (v) => `text-align:${v}`,
|
|
1445
|
+
align: (v) => `vertical-align:${v}`,
|
|
1446
|
+
"vertical-align": (v) => `vertical-align:${v}`,
|
|
1447
|
+
items: (v) => `align-items:${v}`,
|
|
1448
|
+
"align-items": (v) => `align-items:${v}`,
|
|
1449
|
+
justify: (v) => `justify-content:${v}`,
|
|
1450
|
+
"justify-content": (v) => `justify-content:${v}`,
|
|
1451
|
+
self: (v) => `align-self:${v}`,
|
|
1452
|
+
"align-self": (v) => `align-self:${v}`,
|
|
1453
|
+
content: (v) => `align-content:${v}`,
|
|
1454
|
+
"align-content": (v) => `align-content:${v}`,
|
|
1455
|
+
d: (v) => `display:${v}`,
|
|
1456
|
+
display: (v) => `display:${v}`,
|
|
1457
|
+
pos: (v) => `position:${v}`,
|
|
1458
|
+
position: (v) => `position:${v}`,
|
|
1459
|
+
aspect: (v) => `aspect-ratio:${v}`,
|
|
1460
|
+
"aspect-ratio": (v) => `aspect-ratio:${v}`,
|
|
1461
|
+
cursor: (v) => `cursor:${v}`,
|
|
1462
|
+
select: (v) => `user-select:${v}`,
|
|
1463
|
+
"user-select": (v) => `user-select:${v}`,
|
|
1464
|
+
pointer: (v) => `pointer-events:${v}`,
|
|
1465
|
+
"pointer-events": (v) => `pointer-events:${v}`,
|
|
1466
|
+
fit: (v) => `object-fit:${v}`,
|
|
1467
|
+
"object-fit": (v) => `object-fit:${v}`,
|
|
1468
|
+
overflow: (v) => `overflow:${v}`,
|
|
1469
|
+
"overflow-x": (v) => `overflow-x:${v}`,
|
|
1470
|
+
"overflow-y": (v) => `overflow-y:${v}`,
|
|
1471
|
+
shadow: (v) => `box-shadow:${v}`,
|
|
1472
|
+
"box-shadow": (v) => `box-shadow:${v}`
|
|
1409
1473
|
};
|
|
1410
1474
|
const runtimeBreakpoints = {
|
|
1411
1475
|
sm: "36rem",
|
|
@@ -1428,39 +1492,86 @@ const runtimeStateSelectors = {
|
|
|
1428
1492
|
odd: ":nth-child(odd)",
|
|
1429
1493
|
even: ":nth-child(even)"
|
|
1430
1494
|
};
|
|
1495
|
+
function parseModifiersAndUtility(className) {
|
|
1496
|
+
const parts = [];
|
|
1497
|
+
let bracketDepth = 0;
|
|
1498
|
+
let current = "";
|
|
1499
|
+
for (let i = 0; i < className.length; i++) {
|
|
1500
|
+
const ch = className[i];
|
|
1501
|
+
if (ch === "[")
|
|
1502
|
+
bracketDepth++;
|
|
1503
|
+
else if (ch === "]")
|
|
1504
|
+
bracketDepth--;
|
|
1505
|
+
if (ch === ":" && bracketDepth === 0) {
|
|
1506
|
+
parts.push(current);
|
|
1507
|
+
current = "";
|
|
1508
|
+
}
|
|
1509
|
+
else {
|
|
1510
|
+
current += ch;
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
parts.push(current);
|
|
1514
|
+
const utility = parts.pop() ?? "";
|
|
1515
|
+
return { modifiers: parts, utility };
|
|
1516
|
+
}
|
|
1431
1517
|
function injectArbitraryClass(className) {
|
|
1432
1518
|
if (injectedArbitraryRules.has(className))
|
|
1433
1519
|
return;
|
|
1434
1520
|
injectedArbitraryRules.add(className);
|
|
1435
|
-
const
|
|
1436
|
-
const utility = parts.pop();
|
|
1521
|
+
const { modifiers, utility } = parseModifiersAndUtility(className);
|
|
1437
1522
|
if (!utility)
|
|
1438
1523
|
return;
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
const
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1524
|
+
let prop;
|
|
1525
|
+
let val;
|
|
1526
|
+
let isNegative = false;
|
|
1527
|
+
const bracketMatch = utility.match(/^\[([a-zA-Z0-9_-]+):(.+)\]$/);
|
|
1528
|
+
if (bracketMatch) {
|
|
1529
|
+
prop = bracketMatch[1];
|
|
1530
|
+
if (!prop.startsWith("-")) {
|
|
1531
|
+
prop = prop.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1532
|
+
}
|
|
1533
|
+
val = bracketMatch[2];
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
const match = utility.match(/^(-)?([a-zA-Z0-9_-]+)-\[(.+)\]$/);
|
|
1537
|
+
if (!match)
|
|
1538
|
+
return;
|
|
1539
|
+
isNegative = Boolean(match[1]);
|
|
1540
|
+
prop = match[2];
|
|
1541
|
+
val = match[3];
|
|
1542
|
+
// If leading hyphen was part of a vendor prefix (-webkit-, -moz-, -ms-, -o-), treat it as part of prop
|
|
1543
|
+
if (isNegative && /^(webkit|moz|ms|o)-/i.test(prop)) {
|
|
1544
|
+
prop = `-${prop}`;
|
|
1545
|
+
isNegative = false;
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
prop = prop.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
// Convert unescaped underscores to spaces (e.g. shadow-[0_4px_6px_rgba(...)])
|
|
1552
|
+
val = val
|
|
1553
|
+
.replace(/(?<!\\)_/g, " ")
|
|
1554
|
+
.replace(/\\_/g, "_")
|
|
1555
|
+
.trim();
|
|
1448
1556
|
if (isNegative && !val.startsWith("-")) {
|
|
1449
1557
|
val = `-${val}`;
|
|
1450
1558
|
}
|
|
1451
|
-
const
|
|
1559
|
+
const resolver = runtimeArbitraryPropertyMap[prop];
|
|
1560
|
+
const declarations = resolver ? resolver(val) : `${prop}:${val}`;
|
|
1452
1561
|
const escaped = escapeArbitraryClass(className);
|
|
1453
1562
|
let selector = `.${escaped}`;
|
|
1454
1563
|
let stateSelector = "";
|
|
1455
1564
|
let themeVariant = "";
|
|
1456
1565
|
let breakpointVariant = "";
|
|
1457
|
-
for (const v of
|
|
1566
|
+
for (const v of modifiers) {
|
|
1458
1567
|
if (v === "dark" || v === "light")
|
|
1459
1568
|
themeVariant = v;
|
|
1460
1569
|
else if (runtimeBreakpoints[v])
|
|
1461
1570
|
breakpointVariant = v;
|
|
1462
1571
|
else if (runtimeStateSelectors[v])
|
|
1463
1572
|
stateSelector += runtimeStateSelectors[v];
|
|
1573
|
+
else if (v === "group-hover")
|
|
1574
|
+
selector = `.group:hover .${escaped}`;
|
|
1464
1575
|
}
|
|
1465
1576
|
selector += stateSelector;
|
|
1466
1577
|
let rule = `${selector}{${declarations}}`;
|
|
@@ -1485,11 +1596,11 @@ function injectArbitraryClass(className) {
|
|
|
1485
1596
|
}
|
|
1486
1597
|
function processElementClasses(el) {
|
|
1487
1598
|
const classAttr = el.getAttribute("class");
|
|
1488
|
-
if (!classAttr || !classAttr.includes("
|
|
1599
|
+
if (!classAttr || !classAttr.includes("["))
|
|
1489
1600
|
return;
|
|
1490
1601
|
const tokens = classAttr.split(/\s+/);
|
|
1491
1602
|
for (const token of tokens) {
|
|
1492
|
-
if (token.includes("
|
|
1603
|
+
if (token.includes("[") && token.endsWith("]")) {
|
|
1493
1604
|
injectArbitraryClass(token);
|
|
1494
1605
|
}
|
|
1495
1606
|
}
|
|
@@ -1500,7 +1611,7 @@ function scanArbitraryDom(root = document) {
|
|
|
1500
1611
|
if (root instanceof Element) {
|
|
1501
1612
|
processElementClasses(root);
|
|
1502
1613
|
}
|
|
1503
|
-
root.querySelectorAll('[class*="
|
|
1614
|
+
root.querySelectorAll('[class*="["]').forEach(processElementClasses);
|
|
1504
1615
|
}
|
|
1505
1616
|
let mutationObserverStarted = false;
|
|
1506
1617
|
function setupArbitraryObserver() {
|
package/dist/aksara.js
CHANGED
|
@@ -1340,9 +1340,22 @@ function getArbitrarySheet() {
|
|
|
1340
1340
|
return null;
|
|
1341
1341
|
if (!arbitrarySheet) {
|
|
1342
1342
|
if ("adoptedStyleSheets" in document && typeof CSSStyleSheet !== "undefined") {
|
|
1343
|
-
|
|
1344
|
-
|
|
1343
|
+
try {
|
|
1344
|
+
arbitrarySheet = new CSSStyleSheet();
|
|
1345
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, arbitrarySheet];
|
|
1346
|
+
return arbitrarySheet;
|
|
1347
|
+
}
|
|
1348
|
+
catch {
|
|
1349
|
+
// Fallback to style tag below
|
|
1350
|
+
}
|
|
1345
1351
|
}
|
|
1352
|
+
let styleEl = document.getElementById("aksara-arbitrary-styles");
|
|
1353
|
+
if (!styleEl) {
|
|
1354
|
+
styleEl = document.createElement("style");
|
|
1355
|
+
styleEl.id = "aksara-arbitrary-styles";
|
|
1356
|
+
document.head?.appendChild(styleEl);
|
|
1357
|
+
}
|
|
1358
|
+
arbitrarySheet = styleEl.sheet;
|
|
1346
1359
|
}
|
|
1347
1360
|
return arbitrarySheet;
|
|
1348
1361
|
}
|
|
@@ -1389,6 +1402,8 @@ const runtimeArbitraryPropertyMap = {
|
|
|
1389
1402
|
bottom: (v) => `inset-block-end:${v}`,
|
|
1390
1403
|
start: (v) => `inset-inline-start:${v}`,
|
|
1391
1404
|
end: (v) => `inset-inline-end:${v}`,
|
|
1405
|
+
left: (v) => `left:${v}`,
|
|
1406
|
+
right: (v) => `right:${v}`,
|
|
1392
1407
|
inset: (v) => `inset:${v}`,
|
|
1393
1408
|
"inset-x": (v) => `inset-inline:${v}`,
|
|
1394
1409
|
"inset-y": (v) => `inset-block:${v}`,
|
|
@@ -1396,17 +1411,66 @@ const runtimeArbitraryPropertyMap = {
|
|
|
1396
1411
|
"translate-y": (v) => `transform:translateY(${v})`,
|
|
1397
1412
|
rotate: (v) => `transform:rotate(${v})`,
|
|
1398
1413
|
scale: (v) => `transform:scale(${v})`,
|
|
1414
|
+
"skew-x": (v) => `transform:skewX(${v})`,
|
|
1415
|
+
"skew-y": (v) => `transform:skewY(${v})`,
|
|
1399
1416
|
rounded: (v) => `border-radius:${v}`,
|
|
1400
1417
|
border: (v) => `border-width:${v}`,
|
|
1418
|
+
"border-t": (v) => `border-top-width:${v}`,
|
|
1419
|
+
"border-b": (v) => `border-bottom-width:${v}`,
|
|
1420
|
+
"border-s": (v) => `border-inline-start-width:${v}`,
|
|
1421
|
+
"border-e": (v) => `border-inline-end-width:${v}`,
|
|
1422
|
+
"border-x": (v) => `border-inline-width:${v}`,
|
|
1423
|
+
"border-y": (v) => `border-block-width:${v}`,
|
|
1401
1424
|
opacity: (v) => `opacity:${v}`,
|
|
1402
1425
|
z: (v) => `z-index:${v}`,
|
|
1403
1426
|
leading: (v) => `line-height:${v}`,
|
|
1404
1427
|
tracking: (v) => `letter-spacing:${v}`,
|
|
1405
|
-
text: (v) =>
|
|
1428
|
+
text: (v) => {
|
|
1429
|
+
if (/^(start|center|end|justify|left|right|inline-start|inline-end)$/i.test(v)) {
|
|
1430
|
+
return `text-align:${v}`;
|
|
1431
|
+
}
|
|
1432
|
+
return /^(#[0-9a-fA-F]+|rgb|hsl|var\(--|currentColor|transparent)/i.test(v) ? `color:${v}` : `font-size:${v}`;
|
|
1433
|
+
},
|
|
1406
1434
|
bg: (v) => `background-color:${v}`,
|
|
1435
|
+
"bg-color": (v) => `background-color:${v}`,
|
|
1407
1436
|
overscroll: (v) => `overscroll-behavior:${v}`,
|
|
1408
1437
|
"overscroll-x": (v) => `overscroll-behavior-x:${v}`,
|
|
1409
|
-
"overscroll-y": (v) => `overscroll-behavior-y:${v}
|
|
1438
|
+
"overscroll-y": (v) => `overscroll-behavior-y:${v}`,
|
|
1439
|
+
fw: (v) => `font-weight:${v}`,
|
|
1440
|
+
"font-weight": (v) => `font-weight:${v}`,
|
|
1441
|
+
fs: (v) => `font-size:${v}`,
|
|
1442
|
+
"font-size": (v) => `font-size:${v}`,
|
|
1443
|
+
lh: (v) => `line-height:${v}`,
|
|
1444
|
+
"line-height": (v) => `line-height:${v}`,
|
|
1445
|
+
"text-align": (v) => `text-align:${v}`,
|
|
1446
|
+
align: (v) => `vertical-align:${v}`,
|
|
1447
|
+
"vertical-align": (v) => `vertical-align:${v}`,
|
|
1448
|
+
items: (v) => `align-items:${v}`,
|
|
1449
|
+
"align-items": (v) => `align-items:${v}`,
|
|
1450
|
+
justify: (v) => `justify-content:${v}`,
|
|
1451
|
+
"justify-content": (v) => `justify-content:${v}`,
|
|
1452
|
+
self: (v) => `align-self:${v}`,
|
|
1453
|
+
"align-self": (v) => `align-self:${v}`,
|
|
1454
|
+
content: (v) => `align-content:${v}`,
|
|
1455
|
+
"align-content": (v) => `align-content:${v}`,
|
|
1456
|
+
d: (v) => `display:${v}`,
|
|
1457
|
+
display: (v) => `display:${v}`,
|
|
1458
|
+
pos: (v) => `position:${v}`,
|
|
1459
|
+
position: (v) => `position:${v}`,
|
|
1460
|
+
aspect: (v) => `aspect-ratio:${v}`,
|
|
1461
|
+
"aspect-ratio": (v) => `aspect-ratio:${v}`,
|
|
1462
|
+
cursor: (v) => `cursor:${v}`,
|
|
1463
|
+
select: (v) => `user-select:${v}`,
|
|
1464
|
+
"user-select": (v) => `user-select:${v}`,
|
|
1465
|
+
pointer: (v) => `pointer-events:${v}`,
|
|
1466
|
+
"pointer-events": (v) => `pointer-events:${v}`,
|
|
1467
|
+
fit: (v) => `object-fit:${v}`,
|
|
1468
|
+
"object-fit": (v) => `object-fit:${v}`,
|
|
1469
|
+
overflow: (v) => `overflow:${v}`,
|
|
1470
|
+
"overflow-x": (v) => `overflow-x:${v}`,
|
|
1471
|
+
"overflow-y": (v) => `overflow-y:${v}`,
|
|
1472
|
+
shadow: (v) => `box-shadow:${v}`,
|
|
1473
|
+
"box-shadow": (v) => `box-shadow:${v}`
|
|
1410
1474
|
};
|
|
1411
1475
|
const runtimeBreakpoints = {
|
|
1412
1476
|
sm: "36rem",
|
|
@@ -1429,39 +1493,86 @@ const runtimeStateSelectors = {
|
|
|
1429
1493
|
odd: ":nth-child(odd)",
|
|
1430
1494
|
even: ":nth-child(even)"
|
|
1431
1495
|
};
|
|
1496
|
+
function parseModifiersAndUtility(className) {
|
|
1497
|
+
const parts = [];
|
|
1498
|
+
let bracketDepth = 0;
|
|
1499
|
+
let current = "";
|
|
1500
|
+
for (let i = 0; i < className.length; i++) {
|
|
1501
|
+
const ch = className[i];
|
|
1502
|
+
if (ch === "[")
|
|
1503
|
+
bracketDepth++;
|
|
1504
|
+
else if (ch === "]")
|
|
1505
|
+
bracketDepth--;
|
|
1506
|
+
if (ch === ":" && bracketDepth === 0) {
|
|
1507
|
+
parts.push(current);
|
|
1508
|
+
current = "";
|
|
1509
|
+
}
|
|
1510
|
+
else {
|
|
1511
|
+
current += ch;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
parts.push(current);
|
|
1515
|
+
const utility = parts.pop() ?? "";
|
|
1516
|
+
return { modifiers: parts, utility };
|
|
1517
|
+
}
|
|
1432
1518
|
function injectArbitraryClass(className) {
|
|
1433
1519
|
if (injectedArbitraryRules.has(className))
|
|
1434
1520
|
return;
|
|
1435
1521
|
injectedArbitraryRules.add(className);
|
|
1436
|
-
const
|
|
1437
|
-
const utility = parts.pop();
|
|
1522
|
+
const { modifiers, utility } = parseModifiersAndUtility(className);
|
|
1438
1523
|
if (!utility)
|
|
1439
1524
|
return;
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
const
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1525
|
+
let prop;
|
|
1526
|
+
let val;
|
|
1527
|
+
let isNegative = false;
|
|
1528
|
+
const bracketMatch = utility.match(/^\[([a-zA-Z0-9_-]+):(.+)\]$/);
|
|
1529
|
+
if (bracketMatch) {
|
|
1530
|
+
prop = bracketMatch[1];
|
|
1531
|
+
if (!prop.startsWith("-")) {
|
|
1532
|
+
prop = prop.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1533
|
+
}
|
|
1534
|
+
val = bracketMatch[2];
|
|
1535
|
+
}
|
|
1536
|
+
else {
|
|
1537
|
+
const match = utility.match(/^(-)?([a-zA-Z0-9_-]+)-\[(.+)\]$/);
|
|
1538
|
+
if (!match)
|
|
1539
|
+
return;
|
|
1540
|
+
isNegative = Boolean(match[1]);
|
|
1541
|
+
prop = match[2];
|
|
1542
|
+
val = match[3];
|
|
1543
|
+
// If leading hyphen was part of a vendor prefix (-webkit-, -moz-, -ms-, -o-), treat it as part of prop
|
|
1544
|
+
if (isNegative && /^(webkit|moz|ms|o)-/i.test(prop)) {
|
|
1545
|
+
prop = `-${prop}`;
|
|
1546
|
+
isNegative = false;
|
|
1547
|
+
}
|
|
1548
|
+
else {
|
|
1549
|
+
prop = prop.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
// Convert unescaped underscores to spaces (e.g. shadow-[0_4px_6px_rgba(...)])
|
|
1553
|
+
val = val
|
|
1554
|
+
.replace(/(?<!\\)_/g, " ")
|
|
1555
|
+
.replace(/\\_/g, "_")
|
|
1556
|
+
.trim();
|
|
1449
1557
|
if (isNegative && !val.startsWith("-")) {
|
|
1450
1558
|
val = `-${val}`;
|
|
1451
1559
|
}
|
|
1452
|
-
const
|
|
1560
|
+
const resolver = runtimeArbitraryPropertyMap[prop];
|
|
1561
|
+
const declarations = resolver ? resolver(val) : `${prop}:${val}`;
|
|
1453
1562
|
const escaped = escapeArbitraryClass(className);
|
|
1454
1563
|
let selector = `.${escaped}`;
|
|
1455
1564
|
let stateSelector = "";
|
|
1456
1565
|
let themeVariant = "";
|
|
1457
1566
|
let breakpointVariant = "";
|
|
1458
|
-
for (const v of
|
|
1567
|
+
for (const v of modifiers) {
|
|
1459
1568
|
if (v === "dark" || v === "light")
|
|
1460
1569
|
themeVariant = v;
|
|
1461
1570
|
else if (runtimeBreakpoints[v])
|
|
1462
1571
|
breakpointVariant = v;
|
|
1463
1572
|
else if (runtimeStateSelectors[v])
|
|
1464
1573
|
stateSelector += runtimeStateSelectors[v];
|
|
1574
|
+
else if (v === "group-hover")
|
|
1575
|
+
selector = `.group:hover .${escaped}`;
|
|
1465
1576
|
}
|
|
1466
1577
|
selector += stateSelector;
|
|
1467
1578
|
let rule = `${selector}{${declarations}}`;
|
|
@@ -1486,11 +1597,11 @@ function injectArbitraryClass(className) {
|
|
|
1486
1597
|
}
|
|
1487
1598
|
function processElementClasses(el) {
|
|
1488
1599
|
const classAttr = el.getAttribute("class");
|
|
1489
|
-
if (!classAttr || !classAttr.includes("
|
|
1600
|
+
if (!classAttr || !classAttr.includes("["))
|
|
1490
1601
|
return;
|
|
1491
1602
|
const tokens = classAttr.split(/\s+/);
|
|
1492
1603
|
for (const token of tokens) {
|
|
1493
|
-
if (token.includes("
|
|
1604
|
+
if (token.includes("[") && token.endsWith("]")) {
|
|
1494
1605
|
injectArbitraryClass(token);
|
|
1495
1606
|
}
|
|
1496
1607
|
}
|
|
@@ -1501,7 +1612,7 @@ function scanArbitraryDom(root = document) {
|
|
|
1501
1612
|
if (root instanceof Element) {
|
|
1502
1613
|
processElementClasses(root);
|
|
1503
1614
|
}
|
|
1504
|
-
root.querySelectorAll('[class*="
|
|
1615
|
+
root.querySelectorAll('[class*="["]').forEach(processElementClasses);
|
|
1505
1616
|
}
|
|
1506
1617
|
let mutationObserverStarted = false;
|
|
1507
1618
|
function setupArbitraryObserver() {
|
package/dist/aksara.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(){ const registry=new Map();const instances=new Set();const focusableSelector=["a[href]","area[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","iframe","object","embed","[contenteditable]","[tabindex]:not([tabindex='-1'])"].join(",");function toElements(target){ if(!target)return[];if(typeof target==="string")return Array.from(document.querySelectorAll(target));if(target instanceof HTMLElement)return[target];if(target instanceof Element)return[target];if(target instanceof NodeList || Array.isArray(target)){ return Array.from(target).filter((item)=>item instanceof HTMLElement);} return[];} function resolveArgs(target,options,defaultSelector){ if(target && typeof target==="object" && !(target instanceof Element)&& !(target instanceof NodeList)&& !Array.isArray(target)){ const opts=target;const resolvedTarget=opts.target || opts.selector || defaultSelector;return { target:resolvedTarget,options:opts };} return { target:target || defaultSelector,options:(options || {})};} function dataName(name){ return name.replace(/[A-Z]/g,(match)=>`-${match.toLowerCase()}`);} function getData(element,component,name){ return element?.getAttribute(`data-${component}-${dataName(name)}`)??null;} function getOption(options,element,component,name,fallback){ if(options[name]!==undefined)return options[name];const value=getData(element,component,name);return value !==null?value:fallback;} function getBooleanOption(options,element,component,name,fallback){ const value=getOption(options,element,component,name,fallback);if(value==="true" || value===true)return true;if(value==="false" || value===false)return false;return Boolean(value);} function getNumberOption(options,element,component,name,fallback){ const value=getOption(options,element,component,name,fallback);const number=Number(value);return Number.isNaN(number)?fallback:number;} function clamp(value,min,max){ return Math.min(Math.max(value,min),max);} function emit(element,name,detail={}){ element.dispatchEvent(new CustomEvent(`aksara:${name}`,{ bubbles:true,detail }));} function getInstance(element,Type,options={}){ const key=Type.componentName;let map=registry.get(key);if(!map){ map=new WeakMap();registry.set(key,map);} if(!map.has(element)){ const instance=new Type(element,options);map.set(element,instance);instances.add(instance);} else if(options && Object.keys(options).length){ const instance=map.get(element);if(instance && typeof instance.updateOptions==="function"){ instance.updateOptions(options);} } return map.get(element);} function createInstanceList(instanceArray){ return new Proxy(instanceArray,{ get(target,prop){ if(prop in target){ const val=target[prop];return typeof val==="function"?val.bind(target):val;} return(...args)=>{ target.forEach((inst)=>{ const fn=inst[prop];if(typeof fn==="function"){ fn(...args);} });return createInstanceList(target);};} });} function createAll(target,Type,options={}){ const items=toElements(target);const insts=items.map((element)=>getInstance(element,Type,options));if(insts.length===1)return insts[0];return createInstanceList(insts);} class Component { element;options;cleanups;constructor(element,options={}){ this.element=element;this.options=options;this.cleanups=[];} updateOptions(options={}){ this.options={...this.options,...options };return this;} on(target,type,handler,options){ target.addEventListener(type,handler,options);this.cleanups.push(()=>target.removeEventListener(type,handler,options));} destroy(){ this.cleanups.splice(0).forEach((cleanup)=>cleanup());instances.delete(this);const ctor=this.constructor;emit(this.element,`${ctor.componentName || "component"}:destroy`,{ instance:this });} } class Modal extends Component { static componentName="modal";isOpen;previousFocus=null;dialog;dragState=null;backdrop;keyboard;focus;scrollLock;draggable;constructor(element,options={}){ super(element,options);this.isOpen=element.classList.contains("modal-open");this.dialog=element.querySelector(".modal-dialog");this.updateOptions(options);this.element.setAttribute("role",this.element.getAttribute("role")|| "dialog");this.element.setAttribute("aria-modal","true");this.element.setAttribute("aria-hidden",this.isOpen?"false":"true");this.on(this.element,"click",(event)=>{ if(event.target===this.element){ if(this.backdrop==="static"){ const staticClass=`${this.constructor.componentName}-static`;this.element.classList.add(staticClass);setTimeout(()=>this.element.classList.remove(staticClass),150);} else if(this.backdrop){ this.hide();} } });this.on(document,"keydown",(event)=>this.onKeydown(event));this.bindDrag();} updateOptions(options={}){ super.updateOptions(options);const component=this.constructor.componentName;const backdrop=getOption(this.options,this.element,component,"backdrop",true);this.backdrop=backdrop==="static"?"static":!(backdrop===false || backdrop==="false");this.keyboard=getBooleanOption(this.options,this.element,component,"keyboard",true);this.focus=getBooleanOption(this.options,this.element,component,"focus",true);this.scrollLock=getBooleanOption(this.options,this.element,component,"scrollLock",true);this.draggable=getBooleanOption(this.options,this.element,component,"draggable",true);return this;} bindDrag(){ if(!this.dialog)return;const header=this.dialog.querySelector(".modal-header");if(!header)return;this.on(header,"pointerdown",(event)=>this.startDrag(event));} startDrag(event){ if(!this.isOpen || !this.draggable || !this.dialog || event.button !==0)return;const target=event.target instanceof Element?event.target:null;if(target?.closest("button,a,input,select,textarea,label,[data-modal-close],[data-no-drag]"))return;const originX=Number.parseFloat(this.dialog.style.getPropertyValue("--aksara-modal-x"))|| 0;const originY=Number.parseFloat(this.dialog.style.getPropertyValue("--aksara-modal-y"))|| 0;const rect=this.dialog.getBoundingClientRect();const baseLeft=rect.left-originX;const baseTop=rect.top-originY;const padding=8;const move=(moveEvent)=>this.drag(moveEvent);const end=()=>{ document.removeEventListener("pointermove",move);document.removeEventListener("pointerup",end);document.removeEventListener("pointercancel",end);this.dialog?.classList.remove("is-dragging");this.dragState=null;};this.dragState={ originX,originY,pointerX:event.clientX,pointerY:event.clientY,minX:padding-baseLeft,maxX:window.innerWidth-padding-rect.width-baseLeft,minY:padding-baseTop,maxY:window.innerHeight-padding-rect.height-baseTop };this.dialog.classList.add("is-dragging");document.addEventListener("pointermove",move);document.addEventListener("pointerup",end);document.addEventListener("pointercancel",end);event.preventDefault();} drag(event){ if(!this.dialog || !this.dragState)return;const nextX=clamp(this.dragState.originX+event.clientX-this.dragState.pointerX,this.dragState.minX,this.dragState.maxX);const nextY=clamp(this.dragState.originY+event.clientY-this.dragState.pointerY,this.dragState.minY,this.dragState.maxY);this.dialog.style.setProperty("--aksara-modal-x",`${nextX}px`);this.dialog.style.setProperty("--aksara-modal-y",`${nextY}px`);} resetPosition(){ if(!this.dialog)return;this.dialog.style.removeProperty("--aksara-modal-x");this.dialog.style.removeProperty("--aksara-modal-y");this.dialog.classList.remove("is-dragging");} show(){ if(this.isOpen)return this;this.previousFocus=document.activeElement;this.isOpen=true;this.element.classList.add("modal-open");this.element.setAttribute("aria-hidden","false");if(this.scrollLock)document.documentElement.style.overflow="hidden";if(this.focus)this.focusFirst();emit(this.element,"modal:show",{ instance:this });return this;} hide(){ if(!this.isOpen)return this;this.isOpen=false;this.element.classList.remove("modal-open");this.element.setAttribute("aria-hidden","true");this.resetPosition();if(this.scrollLock)document.documentElement.style.overflow="";if(this.previousFocus && typeof this.previousFocus.focus==="function")this.previousFocus.focus();emit(this.element,"modal:hide",{ instance:this });return this;} toggle(){ return this.isOpen?this.hide():this.show();} focusFirst(){ const focusable=Array.from(this.element.querySelectorAll(focusableSelector));const first=focusable[0]|| this.element;if(!this.element.hasAttribute("tabindex"))this.element.setAttribute("tabindex","-1");first.focus({ preventScroll:true });} onKeydown(event){ if(!this.isOpen)return;if(event.key==="Escape"){ if(this.keyboard){ event.preventDefault();this.hide();} else if(this.backdrop==="static"){ const staticClass=`${this.constructor.componentName}-static`;this.element.classList.add(staticClass);setTimeout(()=>this.element.classList.remove(staticClass),150);} return;} if(event.key !=="Tab")return;const focusable=Array.from(this.element.querySelectorAll(focusableSelector));if(!focusable.length){ event.preventDefault();this.element.focus();return;} const first=focusable[0];const last=focusable[focusable.length-1];if(event.shiftKey && document.activeElement===first){ event.preventDefault();last.focus();} else if(!event.shiftKey && document.activeElement===last){ event.preventDefault();first.focus();} } } class Dropdown extends Component { static componentName="dropdown";trigger;menu;isOpen;originalParent;originalSibling;scrollHandler;placement;container;offset;keyboard;closeOnSelect;closeOnOutside;constructor(element,options={}){ super(element,options);let trigger;let menu=null;if(element.matches("[data-dropdown]")){ trigger=element;} else if(element.classList.contains("dropdown")){ trigger=element.querySelector("[data-dropdown]")|| element.querySelector("button,a");menu=element.querySelector(".dropdown-menu");} else { trigger=element;} this.trigger=trigger;if(!menu){ const menuSelector=options.menu || options.target ||(trigger &&(trigger.getAttribute("data-dropdown")|| trigger.getAttribute("data-target")));if(menuSelector && typeof menuSelector==="string"){ menu=document.querySelector(menuSelector);} else if(menuSelector instanceof HTMLElement){ menu=menuSelector;} if(!menu && trigger){ if(trigger.nextElementSibling && trigger.nextElementSibling.classList.contains("dropdown-menu")){ menu=trigger.nextElementSibling;} else { menu=trigger.parentElement?.querySelector(".dropdown-menu")|| null;} } } this.menu=menu;this.isOpen=false;this.originalParent=null;this.originalSibling=null;this.scrollHandler=null;this.updateOptions(options);if(this.trigger?.matches(".btn-sm,.input-sm,.form-control-sm,.form-select-sm")|| this.element.classList.contains("dropdown-sm")){ this.menu?.classList.add("dropdown-menu-sm");} if(this.trigger){ this.trigger.setAttribute("aria-haspopup","true");this.trigger.setAttribute("aria-expanded","false");this.on(this.trigger,"click",(event)=>{ const customEvent=event;if(customEvent.__aksaraDropdownHandled)return;customEvent.__aksaraDropdownHandled=true;event.preventDefault();this.toggle(event);});} this.on(document,"click",(event)=>{ if(!this.closeOnOutside)return;const target=event.target;if(!this.element.contains(target)&& !this.menu?.contains(target)){ this.hide();} });this.on(document,"keydown",(event)=>{ if(this.keyboard && event.key==="Escape")this.hide();});if(this.menu){ this.on(this.menu,"click",(event)=>{ const target=event.target;const item=target.closest(".dropdown-item");if(this.closeOnSelect && item && !item.disabled && !item.classList.contains("disabled")){ this.hide();} });} } updateOptions(options={}){ super.updateOptions(options);this.placement=getOption(this.options,this.trigger,"dropdown","placement",getData(this.element,"dropdown","placement")|| "bottom");this.container=getOption(this.options,this.trigger,"dropdown","container",getData(this.element,"dropdown","container")|| "body");this.offset=getNumberOption(this.options,this.trigger,"dropdown","offset",getNumberOption({},this.element,"dropdown","offset",4));this.keyboard=getBooleanOption(this.options,this.trigger,"dropdown","keyboard",getBooleanOption({},this.element,"dropdown","keyboard",true));this.closeOnSelect=getBooleanOption(this.options,this.trigger,"dropdown","closeOnSelect",getBooleanOption({},this.element,"dropdown","closeOnSelect",true));this.closeOnOutside=getBooleanOption(this.options,this.trigger,"dropdown","closeOnOutside",getBooleanOption({},this.element,"dropdown","closeOnOutside",true));return this;} position(){ if(!this.menu || !this.isOpen || !this.trigger)return;this.menu.style.display="block";this.menu.style.position="absolute";this.menu.style.zIndex="1000";const triggerRect=this.trigger.getBoundingClientRect();if(this.trigger.classList.contains("form-select")|| this.element.classList.contains("variant-form-select")|| this.element.hasAttribute("data-dropdown-select")){ this.menu.style.width=`${triggerRect.width}px`;this.menu.style.minWidth=`${triggerRect.width}px`;} const menuRect=this.menu.getBoundingClientRect();const gap=this.offset;let top;let left;let placement=this.placement;if(placement==="auto"){ const spaceBelow=window.innerHeight-triggerRect.bottom;const spaceAbove=triggerRect.top;placement=spaceBelow>=menuRect.height || spaceBelow>=spaceAbove?"bottom":"top";} this.menu.classList.remove("dropdown-top","dropdown-bottom","dropdown-start","dropdown-end");this.menu.classList.add(`dropdown-${placement}`);const isRtl=document.documentElement.getAttribute("dir")==="rtl" || document.body?.getAttribute("dir")==="rtl";if(placement==="top"){ top=triggerRect.top-menuRect.height-gap;left=isRtl?triggerRect.right-menuRect.width:triggerRect.left;} else if(placement==="start"){ top=triggerRect.top;left=isRtl?triggerRect.right+gap:triggerRect.left-menuRect.width-gap;} else if(placement==="end"){ top=triggerRect.top;left=isRtl?triggerRect.left-menuRect.width-gap:triggerRect.right+gap;} else { top=triggerRect.bottom+gap;left=isRtl?triggerRect.right-menuRect.width:triggerRect.left;} const viewportWidth=window.innerWidth;left=Math.max(8,Math.min(left,viewportWidth-menuRect.width-8));this.menu.style.top=`${top+window.scrollY}px`;this.menu.style.left=`${left+window.scrollX}px`;this.menu.style.bottom="auto";this.menu.style.right="auto";} show(){ if(!this.menu || this.isOpen)return this;this.isOpen=true;this.originalParent=this.menu.parentNode;this.originalSibling=this.menu.nextSibling;let containerEl=document.body;if(typeof this.container==="string" && this.container !=="body"){ containerEl=document.querySelector(this.container)|| document.body;} else if(this.container instanceof HTMLElement){ containerEl=this.container;} containerEl.appendChild(this.menu);this.menu.classList.add("dropdown-open");this.trigger?.setAttribute("aria-expanded","true");this.position();this.scrollHandler=()=>this.position();window.addEventListener("scroll",this.scrollHandler,{ passive:true });window.addEventListener("resize",this.scrollHandler);emit(this.element,"dropdown:show",{ instance:this });return this;} hide(){ if(!this.menu || !this.isOpen)return this;this.isOpen=false;if(this.scrollHandler){ window.removeEventListener("scroll",this.scrollHandler);window.removeEventListener("resize",this.scrollHandler);this.scrollHandler=null;} this.menu.classList.remove("dropdown-open","dropdown-top","dropdown-bottom","dropdown-start","dropdown-end");this.trigger?.setAttribute("aria-expanded","false");if(this.originalParent){ this.originalParent.insertBefore(this.menu,this.originalSibling);} this.menu.style.display="";this.menu.style.position="";this.menu.style.top="";this.menu.style.left="";this.menu.style.zIndex="";emit(this.element,"dropdown:hide",{ instance:this });return this;} toggle(event){ const clickEvent=(event || window.event);if(clickEvent && clickEvent.type==="click"){ if(clickEvent.__aksaraDropdownHandled && !event){ return this;} clickEvent.__aksaraDropdownHandled=true;} return this.isOpen?this.hide():this.show();} destroy(){ this.hide();super.destroy();} } class FloatingText extends Component { static dataAttribute="data-floating";static role="tooltip";static componentName="floating";tip;showTimeout;hideTimeout;container;html;content;placement;trigger;offset;showDelay;hideDelay;keyboard;constructor(element,options={}){ super(element,options);this.tip=null;this.showTimeout=null;this.hideTimeout=null;this.updateOptions(options);this.bindTriggers();this.on(document,"keydown",(event)=>{ if(this.keyboard && event.key==="Escape")this.hide();});} updateOptions(options={}){ super.updateOptions(options);const ctor=this.constructor;const component=ctor.componentName;const rawContent=(this.options.content??this.options.text??getData(this.element,component,"content")??this.element.getAttribute(ctor.dataAttribute)??"");this.container=getOption(this.options,this.element,component,"container",this.element.getAttribute("data-container")|| "body");this.html=getBooleanOption(this.options,this.element,component,"html",this.element.getAttribute("data-html")==="true");this.content=rawContent;this.placement=getOption(this.options,this.element,component,"placement",this.element.getAttribute("data-placement")|| "top");this.trigger=getOption(this.options,this.element,component,"trigger","hover focus");this.offset=getNumberOption(this.options,this.element,component,"offset",8);this.showDelay=getNumberOption(this.options,this.element,component,"showDelay",0);this.hideDelay=getNumberOption(this.options,this.element,component,"hideDelay",0);this.keyboard=getBooleanOption(this.options,this.element,component,"keyboard",true);if(this.tip){ if(this.html){ this.tip.innerHTML=this.content;} else { this.tip.textContent=this.content;} this.position();} return this;} bindTriggers(){ const triggers=String(this.trigger).split(/\s+/).filter(Boolean);if(triggers.includes("hover")){ this.on(this.element,"mouseenter",()=>this.scheduleShow());this.on(this.element,"mouseleave",()=>this.scheduleHide());} if(triggers.includes("focus")){ this.on(this.element,"focus",()=>this.scheduleShow());this.on(this.element,"blur",()=>this.scheduleHide());} if(triggers.includes("click")){ this.on(this.element,"click",(event)=>{ event.preventDefault();this.toggle();});} } scheduleShow(){ if(this.hideTimeout)clearTimeout(this.hideTimeout);if(this.showTimeout)clearTimeout(this.showTimeout);this.showTimeout=setTimeout(()=>this.show(),this.showDelay);} scheduleHide(){ if(this.showTimeout)clearTimeout(this.showTimeout);if(this.hideTimeout)clearTimeout(this.hideTimeout);this.hideTimeout=setTimeout(()=>this.hide(),this.hideDelay);} show(){ if(this.tip || !this.content)return this;const ctor=this.constructor;this.tip=document.createElement("div");this.tip.className=ctor.componentName;if(this.html){ this.tip.innerHTML=this.content;} else { this.tip.textContent=this.content;} this.tip.setAttribute("role",ctor.role);let containerEl=document.body;if(typeof this.container==="string" && this.container !=="body"){ containerEl=document.querySelector(this.container)|| document.body;} else if(this.container instanceof HTMLElement){ containerEl=this.container;} containerEl.append(this.tip);this.position();emit(this.element,`${ctor.componentName}:show`,{ instance:this });return this;} toggle(){ return this.tip?this.hide():this.show();} hide(){ if(!this.tip)return this;const ctor=this.constructor;this.tip.remove();this.tip=null;emit(this.element,`${ctor.componentName}:hide`,{ instance:this });return this;} position(){ if(!this.tip)return;const rect=this.element.getBoundingClientRect();const tipRect=this.tip.getBoundingClientRect();const gap=this.offset;const isRtl=document.documentElement.getAttribute("dir")==="rtl" || document.body?.getAttribute("dir")==="rtl";let placement=this.placement;if(placement==="auto"){ const spaceBelow=window.innerHeight-rect.bottom;const spaceAbove=rect.top;placement=spaceAbove>=tipRect.height || spaceAbove>=spaceBelow?"top":"bottom";} let physicalPlacement=placement;if(placement==="start"){ physicalPlacement=isRtl?"right":"left";} else if(placement==="end"){ physicalPlacement=isRtl?"left":"right";} const ctor=this.constructor;this.tip.className=`${ctor.componentName} ${ctor.componentName}-${placement}`;const topMap={ top:rect.top-tipRect.height-gap,bottom:rect.bottom+gap,left:rect.top+rect.height/2-tipRect.height/2,right:rect.top+rect.height/2-tipRect.height/2 };const top=topMap[physicalPlacement]??rect.top-tipRect.height-gap;const leftMap={ top:rect.left+rect.width/2-tipRect.width/2,bottom:rect.left+rect.width/2-tipRect.width/2,left:rect.left-tipRect.width-gap,right:rect.right+gap };const left=leftMap[physicalPlacement]??rect.left;this.tip.style.top=`${Math.max(4,top+window.scrollY)}px`;this.tip.style.left=`${Math.max(4,left+window.scrollX)}px`;} destroy(){ if(this.showTimeout)clearTimeout(this.showTimeout);if(this.hideTimeout)clearTimeout(this.hideTimeout);this.hide();super.destroy();} } class Tooltip extends FloatingText { static componentName="tooltip";static dataAttribute="data-tooltip";static role="tooltip";} class Popover extends FloatingText { static componentName="popover";static dataAttribute="data-popover";static role="dialog";} function collapsePanel(panel,duration=250){ const animatedPanel=panel;if(animatedPanel._aksaraCollapseTimer){ clearTimeout(animatedPanel._aksaraCollapseTimer);delete animatedPanel._aksaraCollapseTimer;} if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} if(duration<=0 ||(typeof window !=="undefined" && window.matchMedia?.("(prefers-reduced-motion:reduce)").matches)){ panel.hidden=true;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");return;} const computed=window.getComputedStyle(panel);const currentHeight=panel.getBoundingClientRect().height;const currentPaddingTop=computed.paddingTop;const currentPaddingBottom=computed.paddingBottom;panel.style.overflow="hidden";panel.style.height=`${currentHeight}px`;panel.style.paddingTop=currentPaddingTop;panel.style.paddingBottom=currentPaddingBottom;panel.style.opacity="1";panel.style.transition=`height ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-top ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-bottom ${duration}ms cubic-bezier(0.4,0,0.2,1),opacity ${Math.round(duration*0.7)}ms ease`;void panel.offsetHeight;panel.style.height="0px";panel.style.paddingTop="0px";panel.style.paddingBottom="0px";panel.style.opacity="0";const cleanup=()=>{ panel.hidden=true;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} delete animatedPanel._aksaraCollapseTimer;};const onEnd=(e)=>{ if(e.target===panel && e.propertyName==="height"){ cleanup();} };animatedPanel._aksaraCollapseEnd=onEnd;panel.addEventListener("transitionend",onEnd);animatedPanel._aksaraCollapseTimer=setTimeout(cleanup,duration+60);} function expandPanel(panel,duration=250){ const animatedPanel=panel;if(animatedPanel._aksaraCollapseTimer){ clearTimeout(animatedPanel._aksaraCollapseTimer);delete animatedPanel._aksaraCollapseTimer;} if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} if(duration<=0 ||(typeof window !=="undefined" && window.matchMedia?.("(prefers-reduced-motion:reduce)").matches)){ panel.hidden=false;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");return;} panel.hidden=false;panel.style.removeProperty("height");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");const computed=window.getComputedStyle(panel);const targetPaddingTop=computed.paddingTop;const targetPaddingBottom=computed.paddingBottom;const targetHeight=panel.getBoundingClientRect().height;panel.style.overflow="hidden";panel.style.height="0px";panel.style.paddingTop="0px";panel.style.paddingBottom="0px";panel.style.opacity="0";void panel.offsetHeight;panel.style.transition=`height ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-top ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-bottom ${duration}ms cubic-bezier(0.4,0,0.2,1),opacity ${duration}ms ease`;panel.style.height=`${targetHeight}px`;panel.style.paddingTop=targetPaddingTop;panel.style.paddingBottom=targetPaddingBottom;panel.style.opacity="1";const cleanup=()=>{ panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} delete animatedPanel._aksaraCollapseTimer;};const onEnd=(e)=>{ if(e.target===panel && e.propertyName==="height"){ cleanup();} };animatedPanel._aksaraCollapseEnd=onEnd;panel.addEventListener("transitionend",onEnd);animatedPanel._aksaraCollapseTimer=setTimeout(cleanup,duration+60);} class Accordion extends Component { static componentName="accordion";parent;collapsible;buttonSelector;duration;constructor(element,options={}){ super(element,options);this.updateOptions(options);this.on(element,"click",(event)=>{ const target=event.target;const button=target.closest(this.buttonSelector);if(!button || !element.contains(button))return;const panelSelector=button.getAttribute("data-accordion");if(!panelSelector)return;const panel=document.querySelector(panelSelector);if(!panel)return;const expanded=button.getAttribute("aria-expanded")==="true";if(expanded && !this.collapsible)return;const parentScope=this.getParentScope();if(!expanded && parentScope){ parentScope.querySelectorAll(this.buttonSelector).forEach((otherButton)=>{ if(otherButton===button)return;otherButton.setAttribute("aria-expanded","false");const otherPanelSelector=otherButton.getAttribute("data-accordion");if(otherPanelSelector){ const otherPanel=document.querySelector(otherPanelSelector);if(otherPanel &&(!otherPanel.hidden || otherPanel.offsetHeight>0)){ collapsePanel(otherPanel,this.duration);} } });} button.setAttribute("aria-expanded",String(!expanded));if(expanded){ collapsePanel(panel,this.duration);} else { expandPanel(panel,this.duration);} emit(element,"accordion:toggle",{ button,panel,expanded:!expanded });});} updateOptions(options={}){ super.updateOptions(options);const parentVal=getOption(this.options,this.element,"accordion","parent",true);if(parentVal==="true")this.parent=true;else if(parentVal==="false")this.parent=false;else this.parent=parentVal;this.collapsible=getBooleanOption(this.options,this.element,"accordion","collapsible",true);this.buttonSelector=getOption(this.options,this.element,"accordion","buttonSelector","[data-accordion]");this.duration=getNumberOption(this.options,this.element,"accordion","duration",250);return this;} getParentScope(){ if(this.parent===false)return null;if(this.parent===true)return this.element;if(this.parent instanceof Element)return this.parent;if(typeof this.parent==="string")return document.querySelector(this.parent)|| this.element;return this.element;} } class Tabs extends Component { static componentName="tabs";tabSelector;panelSelector;active;activeIndex;keyboard;loop;orientation;constructor(element,options={}){ super(element,options);this.updateOptions(options);this.on(element,"click",(event)=>{ const target=event.target;const tab=target.closest(this.tabSelector);if(!tab || !element.contains(tab))return;event.preventDefault();this.show(tab);});this.on(element,"keydown",(event)=>{ if(!this.keyboard)return;const keyEvent=event;const keys=this.orientation==="vertical"?["ArrowUp","ArrowDown"]:["ArrowLeft","ArrowRight"];if(!keys.includes(keyEvent.key))return;const tabs=Array.from(element.querySelectorAll(this.tabSelector));const index=tabs.indexOf(document.activeElement);if(index<0)return;event.preventDefault();const isNext=keyEvent.key==="ArrowRight" || keyEvent.key==="ArrowDown";const fallback=this.loop?(isNext?tabs[0]:tabs[tabs.length-1]):tabs[index];const next=isNext?tabs[index+1]|| fallback:tabs[index-1]|| fallback;if(next){ next.focus();this.show(next);} });this.activateInitial();} updateOptions(options={}){ const shouldActivate=(options.active !==undefined || options.activeIndex !==undefined)&& this.cleanups.length>0;super.updateOptions(options);this.tabSelector=getOption(this.options,this.element,"tabs","tabSelector","[data-tabs]");this.panelSelector=getOption(this.options,this.element,"tabs","panelSelector",null);this.active=getOption(this.options,this.element,"tabs","active",null);this.activeIndex=getNumberOption(this.options,this.element,"tabs","activeIndex",-1);this.keyboard=getBooleanOption(this.options,this.element,"tabs","keyboard",true);this.loop=getBooleanOption(this.options,this.element,"tabs","loop",true);this.orientation=getOption(this.options,this.element,"tabs","orientation",this.element.getAttribute("aria-orientation")|| "horizontal");this.element.setAttribute("role",this.element.getAttribute("role")|| "tablist");this.element.setAttribute("aria-orientation",this.orientation);if(shouldActivate)this.activateInitial();return this;} activateInitial(){ const tabs=Array.from(this.element.querySelectorAll(this.tabSelector));if(!tabs.length)return;let initial=null;if(this.active instanceof HTMLElement){ initial=this.active;} else if(typeof this.active==="string"){ initial=this.element.querySelector(this.active)|| document.querySelector(this.active);} if(!initial && this.activeIndex>=0){ initial=tabs[this.activeIndex]|| null;} if(!initial){ initial=tabs.find((tab)=>tab.getAttribute("aria-selected")==="true")|| tabs[0];} if(initial)this.show(initial);} show(tab){ const selector=tab.getAttribute("data-tabs");const panel=selector?document.querySelector(selector):null;if(!panel)return this;this.element.querySelectorAll(this.tabSelector).forEach((item)=>{ const selected=item===tab;item.setAttribute("role",item.getAttribute("role")|| "tab");item.setAttribute("aria-selected",String(selected));item.tabIndex=selected?0:-1;const targetSelector=item.getAttribute("data-tabs");const target=targetSelector?document.querySelector(targetSelector):null;if(target)target.hidden=!selected;});if(this.panelSelector){ document.querySelectorAll(this.panelSelector).forEach((item)=>{ if(item !==panel)item.hidden=true;});} panel.setAttribute("role",panel.getAttribute("role")|| "tabpanel");emit(this.element,"tabs:show",{ tab,panel,instance:this });return this;} } class Toast extends Component { static componentName="toast";timeout=null;delay;autohide;constructor(element,options={}){ super(element,options);this.updateOptions(options);element.setAttribute("role",element.getAttribute("role")|| "status");element.setAttribute("aria-live",element.getAttribute("aria-live")|| "polite");} updateOptions(options={}){ super.updateOptions(options);this.delay=getNumberOption(this.options,this.element,"toast","delay",5000);this.autohide=getBooleanOption(this.options,this.element,"toast","autohide",true);return this;} show(){ this.element.classList.add("toast-show");if(this.timeout)clearTimeout(this.timeout);if(this.autohide && this.delay>0)this.timeout=setTimeout(()=>this.hide(),this.delay);emit(this.element,"toast:show",{ instance:this });return this;} hide(){ this.element.classList.remove("toast-show");if(this.timeout)clearTimeout(this.timeout);emit(this.element,"toast:hide",{ instance:this });return this;} destroy(){ if(this.timeout)clearTimeout(this.timeout);super.destroy();} } class Carousel extends Component { static componentName="carousel";timeout=null;items;index;interval;autoplay;pauseOnHover;keyboard;loop;constructor(element,options={}){ super(element,options);this.items=Array.from(element.querySelectorAll("[data-carousel-item]"));this.index=this.resolveInitialIndex();this.updateOptions(options);this.show(this.index);this.on(element,"click",(event)=>{ const target=event.target;const action=target.closest("[data-carousel]");if(!action)return;const value=action.getAttribute("data-carousel");if(value==="next")this.next();if(value==="prev")this.prev();if(value !=="next" && value !=="prev" && value !=="")this.show(Number(value));});this.on(element,"keydown",(event)=>{ const keyEvent=event;if(!this.keyboard || !["ArrowLeft","ArrowRight"].includes(keyEvent.key))return;event.preventDefault();if(keyEvent.key==="ArrowRight")this.next();if(keyEvent.key==="ArrowLeft")this.prev();});if(this.pauseOnHover){ this.on(element,"mouseenter",()=>this.pause());this.on(element,"mouseleave",()=>this.play());} if(this.autoplay)this.play();} updateOptions(options={}){ super.updateOptions(options);this.interval=getNumberOption(this.options,this.element,"carousel","interval",5000);this.autoplay=getBooleanOption(this.options,this.element,"carousel","autoplay",false);this.pauseOnHover=getBooleanOption(this.options,this.element,"carousel","pauseOnHover",true);this.keyboard=getBooleanOption(this.options,this.element,"carousel","keyboard",true);this.loop=getBooleanOption(this.options,this.element,"carousel","loop",true);const activeIndex=getNumberOption(this.options,this.element,"carousel","activeIndex",-1);if(activeIndex>=0)this.show(activeIndex);if(this.autoplay)this.play();if(!this.autoplay)this.pause();return this;} resolveInitialIndex(){ const configured=getNumberOption(this.options,this.element,"carousel","activeIndex",-1);if(configured>=0)return configured;return Math.max(0,this.items.findIndex((item)=>!item.hidden));} show(index){ if(!this.items.length)return this;if(!this.loop &&(index<0 || index>=this.items.length))return this;this.index=(index+this.items.length)% this.items.length;this.items.forEach((item,itemIndex)=>{ item.hidden=itemIndex !==this.index;});emit(this.element,"carousel:show",{ index:this.index,instance:this });return this;} next(){ return this.show(this.index+1);} prev(){ return this.show(this.index-1);} play(){ if(this.timeout)clearInterval(this.timeout);if(this.autoplay && this.interval>0){ this.timeout=setInterval(()=>this.next(),this.interval);} return this;} pause(){ if(this.timeout)clearInterval(this.timeout);this.timeout=null;return this;} destroy(){ this.pause();super.destroy();} } class Offcanvas extends Modal { static componentName="offcanvas";show(){ if(this.isOpen)return this;this.previousFocus=document.activeElement;this.isOpen=true;this.element.classList.add("offcanvas-open");this.element.setAttribute("aria-hidden","false");if(this.scrollLock)document.documentElement.style.overflow="hidden";if(this.focus)this.focusFirst();emit(this.element,"offcanvas:show",{ instance:this });return this;} hide(){ if(!this.isOpen)return this;this.isOpen=false;this.element.classList.remove("offcanvas-open");this.element.setAttribute("aria-hidden","true");if(this.scrollLock)document.documentElement.style.overflow="";if(this.previousFocus && typeof this.previousFocus.focus==="function")this.previousFocus.focus();emit(this.element,"offcanvas:hide",{ instance:this });return this;} } function readTriggerOptions(trigger,component,names){ return names.reduce((options,name)=>{ const value=getData(trigger,component,name);if(value !==null)options[name]=value;return options;},{});} function dismissTarget(target){ if(!target)return;if(target.classList.contains("modal")){ getInstance(target,Modal).hide();} else if(target.classList.contains("offcanvas")){ getInstance(target,Offcanvas).hide();} else if(target.classList.contains("toast")){ getInstance(target,Toast).hide();} else if(target.classList.contains("dropdown")|| target.matches("[data-dropdown]")){ getInstance(target,Dropdown).hide();} else { target.remove();} } function resolveDismissTargets(trigger){ const selector=trigger.getAttribute("data-dismiss");if(selector){ try { return Array.from(document.querySelectorAll(selector));} catch { return[];} } const localTarget=trigger.closest(".alert,.toast,.modal,.offcanvas,.dropdown,.popover,.tooltip");return localTarget?[localTarget]:[];} function bindDataApi(){ document.querySelectorAll("[data-dismiss]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraDismissTrigger)return;customTrigger.__aksaraDismissTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();resolveDismissTargets(trigger).forEach((target)=>dismissTarget(target));});});document.querySelectorAll("[data-modal-close]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraModalCloseTrigger)return;customTrigger.__aksaraModalCloseTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-modal-close");const modal=targetSelector?document.querySelector(targetSelector):trigger.closest(".modal");if(modal)getInstance(modal,Modal).hide();});});document.querySelectorAll("[data-modal]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraModalTrigger)return;customTrigger.__aksaraModalTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-modal");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"modal",["backdrop","keyboard","focus","scrollLock","draggable"]);getInstance(target,Modal,options).show();} } });});document.querySelectorAll("[data-offcanvas-close]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraOffcanvasCloseTrigger)return;customTrigger.__aksaraOffcanvasCloseTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-offcanvas-close");const panel=targetSelector?document.querySelector(targetSelector):trigger.closest(".offcanvas");if(panel)getInstance(panel,Offcanvas).hide();});});document.querySelectorAll("[data-offcanvas]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraOffcanvasTrigger)return;customTrigger.__aksaraOffcanvasTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-offcanvas");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"offcanvas",["backdrop","keyboard","focus","scrollLock"]);getInstance(target,Offcanvas,options).show();} } });});document.querySelectorAll("[data-toast]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraToastTrigger)return;customTrigger.__aksaraToastTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-toast");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"toast",["delay","autohide"]);getInstance(target,Toast,options).show();} } });});} const injectedArbitraryRules=new Set();let arbitrarySheet=null;let arbitraryRuleIndex=0;function getArbitrarySheet(){ if(typeof document==="undefined")return null;if(!arbitrarySheet){ if("adoptedStyleSheets" in document && typeof CSSStyleSheet !=="undefined"){ arbitrarySheet=new CSSStyleSheet();document.adoptedStyleSheets=[...document.adoptedStyleSheets,arbitrarySheet];} } return arbitrarySheet;} function escapeArbitraryClass(className){ return Array.from(className).map((char,index)=>{ if(/^[a-zA-Z_-]$/.test(char))return char;if(/^[0-9]$/.test(char)){ return index===0?`\\${char.charCodeAt(0).toString(16).padStart(6,"0")}`:char;} return `\\${char}`;}).join("");} const runtimeArbitraryPropertyMap={ m:(v)=>`margin:${v}`,mt:(v)=>`margin-block-start:${v}`,mb:(v)=>`margin-block-end:${v}`,ms:(v)=>`margin-inline-start:${v}`,me:(v)=>`margin-inline-end:${v}`,mx:(v)=>`margin-inline:${v}`,my:(v)=>`margin-block:${v}`,p:(v)=>`padding:${v}`,pt:(v)=>`padding-block-start:${v}`,pb:(v)=>`padding-block-end:${v}`,ps:(v)=>`padding-inline-start:${v}`,pe:(v)=>`padding-inline-end:${v}`,px:(v)=>`padding-inline:${v}`,py:(v)=>`padding-block:${v}`,gap:(v)=>`gap:${v}`,"row-gap":(v)=>`row-gap:${v}`,"col-gap":(v)=>`column-gap:${v}`,g:(v)=>`--aksara-gutter-x:${v};--aksara-gutter-y:${v}`,gx:(v)=>`--aksara-gutter-x:${v}`,gy:(v)=>`--aksara-gutter-y:${v}`,w:(v)=>`width:${v}`,h:(v)=>`height:${v}`,"min-w":(v)=>`min-width:${v}`,"max-w":(v)=>`max-width:${v}`,"min-h":(v)=>`min-height:${v}`,"max-h":(v)=>`max-height:${v}`,top:(v)=>`inset-block-start:${v}`,bottom:(v)=>`inset-block-end:${v}`,start:(v)=>`inset-inline-start:${v}`,end:(v)=>`inset-inline-end:${v}`,inset:(v)=>`inset:${v}`,"inset-x":(v)=>`inset-inline:${v}`,"inset-y":(v)=>`inset-block:${v}`,"translate-x":(v)=>`transform:translateX(${v})`,"translate-y":(v)=>`transform:translateY(${v})`,rotate:(v)=>`transform:rotate(${v})`,scale:(v)=>`transform:scale(${v})`,rounded:(v)=>`border-radius:${v}`,border:(v)=>`border-width:${v}`,opacity:(v)=>`opacity:${v}`,z:(v)=>`z-index:${v}`,leading:(v)=>`line-height:${v}`,tracking:(v)=>`letter-spacing:${v}`,text:(v)=>(/^(#[0-9a-fA-F]+|rgb|hsl)/.test(v)?`color:${v}`:`font-size:${v}`),bg:(v)=>`background-color:${v}`,overscroll:(v)=>`overscroll-behavior:${v}`,"overscroll-x":(v)=>`overscroll-behavior-x:${v}`,"overscroll-y":(v)=>`overscroll-behavior-y:${v}` };const runtimeBreakpoints={ sm:"36rem",md:"48rem",lg:"62rem",xl:"75rem","2xl":"87.5rem","3xl":"100rem" };const runtimeStateSelectors={ hover:":hover",focus:":focus",active:":active",disabled:":disabled",checked:":checked",selected:'[aria-selected="true"]',visited:":visited",first:":first-child",last:":last-child",odd:":nth-child(odd)",even:":nth-child(even)" };function injectArbitraryClass(className){ if(injectedArbitraryRules.has(className))return;injectedArbitraryRules.add(className);const parts=className.split(":");const utility=parts.pop();if(!utility)return;const match=utility.match(/^(-)?([a-zA-Z0-9_-]+)-\[(.+)\]$/);if(!match)return;const isNegative=Boolean(match[1]);const prop=match[2];let val=match[3];const resolver=runtimeArbitraryPropertyMap[prop];if(!resolver)return;if(isNegative && !val.startsWith("-")){ val=`-${val}`;} const declarations=resolver(val);const escaped=escapeArbitraryClass(className);let selector=`.${escaped}`;let stateSelector="";let themeVariant="";let breakpointVariant="";for(const v of parts){ if(v==="dark" || v==="light")themeVariant=v;else if(runtimeBreakpoints[v])breakpointVariant=v;else if(runtimeStateSelectors[v])stateSelector+=runtimeStateSelectors[v];} selector+=stateSelector;let rule=`${selector}{${declarations}}`;if(themeVariant){ rule=themeVariant==="dark"?`[data-theme="dark"]${selector},.dark ${selector}{${declarations}}`:`[data-theme="light"]${selector},.light ${selector}{${declarations}}`;} if(breakpointVariant){ rule=`@media(min-width:${runtimeBreakpoints[breakpointVariant]}){${rule}}`;} const sheet=getArbitrarySheet();if(sheet){ try { sheet.insertRule(rule,arbitraryRuleIndex++);} catch { } } } function processElementClasses(el){ const classAttr=el.getAttribute("class");if(!classAttr || !classAttr.includes("-["))return;const tokens=classAttr.split(/\s+/);for(const token of tokens){ if(token.includes("-[")&& token.endsWith("]")){ injectArbitraryClass(token);} } } function scanArbitraryDom(root=document){ if(typeof document==="undefined")return;if(root instanceof Element){ processElementClasses(root);} root.querySelectorAll('[class*="-["]').forEach(processElementClasses);} let mutationObserverStarted=false;function setupArbitraryObserver(){ if(mutationObserverStarted || typeof MutationObserver==="undefined" || typeof document==="undefined")return;mutationObserverStarted=true;const observer=new MutationObserver((mutations)=>{ for(const m of mutations){ if(m.type==="attributes" && m.target instanceof Element){ processElementClasses(m.target);} else if(m.type==="childList"){ m.addedNodes.forEach((node)=>{ if(node instanceof Element){ scanArbitraryDom(node);} });} } });observer.observe(document.documentElement,{ subtree:true,childList:true,attributes:true,attributeFilter:["class"]});} let currentTheme="system";function getSystemTheme(){ if(typeof window !=="undefined" && window.matchMedia && window.matchMedia("(prefers-color-scheme:dark)").matches){ return "dark";} return "light";} function applyTheme(theme){ if(typeof document==="undefined")return;const root=document.documentElement;const effectiveTheme=theme==="system"?getSystemTheme():theme;root.setAttribute("data-theme",effectiveTheme);if(effectiveTheme==="dark"){ root.classList.add("dark");root.classList.remove("light");} else { root.classList.add("light");root.classList.remove("dark");} } function setupClipboard(root=document){ if(typeof document==="undefined")return;root.querySelectorAll("[data-clipboard]").forEach((trigger)=>{ if(trigger.dataset.aksaraClipboardBound)return;trigger.dataset.aksaraClipboardBound="true";trigger.addEventListener("click",async(e)=>{ e.preventDefault();const targetSelector=trigger.getAttribute("data-clipboard");let textToCopy="";if(targetSelector && targetSelector.startsWith("#")){ const targetEl=document.querySelector(targetSelector);if(targetEl){ textToCopy=targetEl.value??targetEl.textContent??"";} } else if(targetSelector){ textToCopy=targetSelector;} else { textToCopy=trigger.getAttribute("data-clipboard-text")|| trigger.textContent || "";} if(navigator.clipboard && textToCopy){ try { await navigator.clipboard.writeText(textToCopy);const originalText=trigger.getAttribute("data-clipboard-original")|| trigger.innerHTML;const successText=trigger.getAttribute("data-clipboard-success");if(successText){ if(!trigger.hasAttribute("data-clipboard-original")){ trigger.setAttribute("data-clipboard-original",originalText);} trigger.innerHTML=successText;setTimeout(()=>{ trigger.innerHTML=originalText;},2000);} trigger.classList.add("is-copied");setTimeout(()=>trigger.classList.remove("is-copied"),2000);emit(trigger,"clipboard:copy",{ text:textToCopy });} catch { } } });});} const Aksara={ Modal,Tooltip,Popover,Accordion,Dropdown,Tabs,Toast,Carousel,Offcanvas,modal:(target,options)=>{ const args=resolveArgs(target,options,"[data-modal],.modal");return createAll(args.target,Modal,args.options);},tooltip:(target,options)=>{ const args=resolveArgs(target,options,"[data-tooltip]");return createAll(args.target,Tooltip,args.options);},popover:(target,options)=>{ const args=resolveArgs(target,options,"[data-popover]");return createAll(args.target,Popover,args.options);},accordion:(target,options)=>{ const args=resolveArgs(target,options,".accordion");return createAll(args.target,Accordion,args.options);},dropdown:(target,options)=>{ const args=resolveArgs(target,options,"[data-dropdown],.dropdown");return createAll(args.target,Dropdown,args.options);},tabs:(target,options)=>{ const args=resolveArgs(target,options,".tabs");return createAll(args.target,Tabs,args.options);},toast:(target,options)=>{ const args=resolveArgs(target,options,".toast");return createAll(args.target,Toast,args.options);},carousel:(target,options)=>{ const args=resolveArgs(target,options,".carousel");return createAll(args.target,Carousel,args.options);},offcanvas:(target,options)=>{ const args=resolveArgs(target,options,".offcanvas");return createAll(args.target,Offcanvas,args.options);},setTheme(theme){ currentTheme=theme;if(typeof localStorage !=="undefined"){ try { localStorage.setItem("aksara-theme",theme);} catch { } } applyTheme(theme);if(typeof document !=="undefined"){ emit(document.documentElement,"theme:change",{ theme });} return theme;},getTheme(){ return currentTheme;},initTheme(){ if(typeof localStorage !=="undefined"){ try { const saved=(localStorage.getItem("aksara-theme")|| localStorage.getItem("aksara-docs-theme"));if(saved &&(saved==="light" || saved==="dark" || saved==="system")){ currentTheme=saved;} } catch { } } applyTheme(currentTheme);if(typeof window !=="undefined" && window.matchMedia){ window.matchMedia("(prefers-color-scheme:dark)").addEventListener("change",()=>{ if(currentTheme==="system"){ applyTheme("system");} });} return currentTheme;},confirm(options){ if(typeof document==="undefined")return Promise.resolve(false);let host=document.getElementById("aksara-dialog-host");if(!host){ host=document.createElement("div");host.id="aksara-dialog-host";document.body.appendChild(host);} const tone=options.tone??"danger";const confirmLabel=options.confirmLabel??"Confirm";const cancelLabel=options.cancelLabel??"Cancel";const icon=options.icon??(tone==="danger"?"mdi-alert-circle-outline":"mdi-alert-outline");host.innerHTML=`<div class="modal fade modal-sm" id="aksaraConfirmModal" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="aksara-confirm-title"><div class="modal-dialog modal-dialog-centered"><div class="modal-content overflow-hidden border-0 shadow-lg"><div class="modal-body text-center p-4"><i class="mdi ${escapeHtmlStr(icon)} text-${escapeHtmlStr(tone)} fs-1 d-block mb-2" aria-hidden="true"></i><h5 id="aksara-confirm-title" class="fs-5 font-bold mb-2 text-body">${escapeHtmlStr(options.title)}</h5><p class="text-muted mb-0">${escapeHtmlStr(options.message)}</p></div><div class="modal-footer p-0 overflow-hidden m-0 w-100 gap-0 d-flex border-top"><button class="btn btn-ghost text-body rounded-0 py-3 m-0 text-center w-[50%]" type="button" data-aksara-confirm-cancel>${escapeHtmlStr(cancelLabel)}</button><button class="btn btn-ghost border-start text-${escapeHtmlStr(tone)} rounded-0 py-3 m-0 text-center w-[50%]" type="button" data-aksara-confirm-accept><i class="mdi mdi-check me-1" aria-hidden="true"></i>${escapeHtmlStr(confirmLabel)}</button></div></div></div></div>`;const modalEl=host.querySelector("#aksaraConfirmModal");if(!modalEl)return Promise.resolve(false);const modalInstance=Aksara.modal(modalEl);modalInstance.show();return new Promise((resolve)=>{ let settled=false;const finish=(value)=>{ if(settled)return;settled=true;modalInstance.hide();setTimeout(()=>{ if(host)host.innerHTML="";},200);resolve(value);};modalEl.addEventListener("modal:hide",()=>finish(false),{ once:true });host?.querySelector("[data-aksara-confirm-cancel]")?.addEventListener("click",()=>finish(false),{ once:true });host?.querySelector("[data-aksara-confirm-accept]")?.addEventListener("click",()=>finish(true),{ once:true });});},alert(options){ if(typeof document==="undefined")return Promise.resolve();let host=document.getElementById("aksara-dialog-host");if(!host){ host=document.createElement("div");host.id="aksara-dialog-host";document.body.appendChild(host);} const tone=options.tone??"primary";const buttonLabel=options.buttonLabel??"OK";const icon=options.icon??(tone==="danger"?"mdi-alert-circle-outline":tone==="warning"?"mdi-alert-outline":"mdi-information-outline");host.innerHTML=`<div class="modal fade modal-sm" id="aksaraAlertModal" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="aksara-alert-title"><div class="modal-dialog modal-dialog-centered"><div class="modal-content overflow-hidden border-0 shadow-lg"><div class="modal-body text-center p-4"><i class="mdi ${escapeHtmlStr(icon)} text-${escapeHtmlStr(tone)} fs-1 d-block mb-2" aria-hidden="true"></i><h5 id="aksara-alert-title" class="fs-5 font-bold mb-2 text-body">${escapeHtmlStr(options.title)}</h5><p class="text-muted mb-0">${escapeHtmlStr(options.message)}</p></div><div class="modal-footer p-0 overflow-hidden m-0 w-100 gap-0 d-flex border-top"><button class="btn btn-ghost text-body rounded-0 py-3 m-0 text-center w-100" type="button" data-aksara-alert-dismiss>${escapeHtmlStr(buttonLabel)}</button></div></div></div></div>`;const modalEl=host.querySelector("#aksaraAlertModal");if(!modalEl)return Promise.resolve();const modalInstance=Aksara.modal(modalEl);modalInstance.show();return new Promise((resolve)=>{ let settled=false;const finish=()=>{ if(settled)return;settled=true;modalInstance.hide();setTimeout(()=>{ if(host)host.innerHTML="";},200);resolve();};modalEl.addEventListener("modal:hide",()=>finish(),{ once:true });host?.querySelector("[data-aksara-alert-dismiss]")?.addEventListener("click",()=>finish(),{ once:true });});},notify(message,options={}){ if(typeof document==="undefined")return;let container=document.getElementById("aksara-toast-container");if(!container){ container=document.createElement("div");container.id="aksara-toast-container";container.className="aksara-toast-container";document.body.appendChild(container);} const toast=document.createElement("div");toast.className="aksara-toast-pill";const iconClass=options.icon??"mdi-information-outline";toast.innerHTML=`<i class="mdi ${escapeHtmlStr(iconClass)} text-primary" style="font-size:1.15rem;line-height:1;"></i><span>${escapeHtmlStr(message)}</span>`;container.appendChild(toast);const duration=options.duration??2500;setTimeout(()=>{ toast.style.opacity="0";toast.style.transform="translateY(8px)";setTimeout(()=>toast.remove(),250);},duration);},async clipboard(target,text){ if(typeof navigator==="undefined" || !navigator.clipboard)return false;let textToCopy=text??"";if(!textToCopy && typeof document !=="undefined"){ const el=typeof target==="string"?document.querySelector(target):target;if(el){ textToCopy=el.value??el.textContent??"";} } if(!textToCopy)return false;try { await navigator.clipboard.writeText(textToCopy);return true;} catch { return false;} },init(root=document){ if(root===document){ this.initTheme();} setupClipboard(root);scanArbitraryDom(root);setupArbitraryObserver();createAll(root.querySelectorAll("[data-tooltip]"),Tooltip);createAll(root.querySelectorAll("[data-popover]"),Popover);const dropdowns=new Set();root.querySelectorAll(".dropdown").forEach((el)=>dropdowns.add(el));root.querySelectorAll("[data-dropdown]").forEach((el)=>{ if(!el.closest(".dropdown")){ dropdowns.add(el);} });createAll(Array.from(dropdowns),Dropdown);createAll(root.querySelectorAll(".accordion"),Accordion);createAll(root.querySelectorAll(".tabs"),Tabs);createAll(root.querySelectorAll(".toast"),Toast);createAll(root.querySelectorAll(".carousel"),Carousel);createAll(root.querySelectorAll(".modal"),Modal);createAll(root.querySelectorAll(".offcanvas"),Offcanvas);bindDataApi();emit(document.documentElement,"init",{ root });return this;},destroy(){ Array.from(instances).forEach((instance)=>instance.destroy());registry.clear();emit(document.documentElement,"destroy");return this;} };if(typeof document !=="undefined"){ document.addEventListener("DOMContentLoaded",()=>Aksara.init());} function classNames(...classes){ return classes.filter(Boolean).join(" ").trim();} function toAttributes(attributes){ if(!attributes)return "";const parts=[];for(const[key,value]of Object.entries(attributes)){ if(value===true){ parts.push(key);} else if(value !==false && value !==null && value !==undefined){ parts.push(`${key}="${escapeHtmlStr(value)}"`);} } return parts.length>0?` ${parts.join(" ")}`:"";} function escapeHtmlStr(value){ return String(value??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");} function SidebarNav(props){ const { items=[],title="",subtitle="",brandIcon="",className="",attributes }=props;const baseAttrs=toAttributes(attributes);const brandHtml=title?`<div class="sidebar-nav-brand">${brandIcon?`<span class="sidebar-nav-icon">${brandIcon}</span>`:""}<div><span class="sidebar-nav-brand-title">${escapeHtmlStr(title)}</span>${subtitle?`<span class="sidebar-nav-brand-subtitle">${escapeHtmlStr(subtitle)}</span>`:""}</div></div>`:"";const itemsHtml=items.map((item)=>{ const isLink=Boolean(item.href);const isTab=Boolean(item.panelTarget)&& !isLink;const Tag=isLink?"a":"button";const itemClasses=classNames("sidebar-nav-item",item.active && "active",item.disabled && "disabled",item.className);const itemAttrs=toAttributes({ href:isLink?item.href:undefined,type:!isLink?"button":undefined,"data-tabs":isTab?item.panelTarget:undefined,role:isTab?"tab":undefined,"aria-selected":isTab?(item.active?"true":"false"):undefined,tabindex:isTab?(item.active?"0":"-1"):undefined,id:isTab && item.id?`sidebar-tab-${item.id}`:item.id,"aria-controls":isTab && item.id?item.id:undefined,disabled:!isLink && item.disabled?true:undefined,"aria-disabled":item.disabled?"true":undefined,"aria-current":isLink && item.active?"page":undefined,...item.attributes });const iconHtml=item.icon?`<span class="sidebar-nav-icon" aria-hidden="true">${item.icon}</span>`:"";const badgeHtml=item.badge?`<span class="sidebar-nav-badge">${escapeHtmlStr(item.badge)}</span>`:"";return `<${Tag} class="${itemClasses}"${itemAttrs}>${iconHtml}<span class="sidebar-nav-label">${escapeHtmlStr(item.label)}</span>${badgeHtml}</${Tag}>`;}).join("");return `<nav class="${classNames("sidebar-nav",className)}"${baseAttrs}>${brandHtml}${itemsHtml}</nav>`.trim();} export const sidebarNav=SidebarNav;function SidebarNavHeader(props){ const { label,className="" }=props;return `<span class="${classNames("sidebar-nav-header",className)}">${escapeHtmlStr(label)}</span>`;} export const sidebarNavHeader=SidebarNavHeader;function SidebarLayout(props){ const { sidebar,content,className="",attributes }=props;const baseAttrs=toAttributes(attributes);return `<div class="${classNames("sidebar-layout",className)}"${baseAttrs}><div class="sidebar-pane">${sidebar}</div><div class="sidebar-content">${content}</div></div>`.trim();} export const sidebarLayout=SidebarLayout;function ListGroup(props={}){ const { children="",flush=false,numbered=false,horizontal=false,className="",attributes }=props;const horizontalClass=horizontal===true?"list-group-horizontal":typeof horizontal==="string"?`list-group-horizontal-${horizontal}`:null;const classes=classNames("list-group",flush && "list-group-flush",numbered && "list-group-numbered",horizontalClass,className);const Tag=numbered?"ol":"div";const baseAttrs=toAttributes(attributes);return `<${Tag} class="${classes}"${baseAttrs}>${children}</${Tag}>`.trim();} export const listGroup=ListGroup;function ListGroupItem(props={}){ const { content="",active=false,disabled=false,action=false,href,variant,className="",attributes }=props;const isLink=Boolean(href);const Tag=isLink?"a":action?"button":"div";const classes=classNames("list-group-item",(action || isLink)&& "list-group-item-action",active && "active",disabled && "disabled",variant && `list-group-item-${variant}`,className);const baseAttrs=toAttributes({ href,type:Tag==="button"?"button":undefined,disabled:Tag==="button" && disabled?true:undefined,"aria-current":active?"true":undefined,"aria-disabled":disabled?"true":undefined,...attributes });return `<${Tag} class="${classes}"${baseAttrs}>${content}</${Tag}>`.trim();} export const listGroupItem=ListGroupItem;function SettingsGroup(props={}){ const { children="",title="",className="",attributes }=props;const baseAttrs=toAttributes(attributes);const groupHtml=`<div class="${classNames("list-group",className)}"${baseAttrs}>${children}</div>`;if(!title)return groupHtml.trim();return `<div><p class="text-xs font-800 uppercase tracking-wider text-subtle mb-2 px-1">${escapeHtmlStr(title)}</p><div class="${classNames("list-group",className)}">${children}</div></div>`.trim();} export const settingsGroup=SettingsGroup;function SettingsItem(props){ const { label,description="",icon="",value="",trailing="",href,action=false,showChevron=false,active=false,disabled=false,className="",attributes }=props;const isLink=Boolean(href);const Tag=isLink?"a":action?"button":"div";const classes=classNames("list-group-item",(action || isLink)&& "list-group-item-action",active && "active",disabled && "disabled",className);const baseAttrs=toAttributes({ href,type:Tag==="button"?"button":undefined,disabled:Tag==="button" && disabled?true:undefined,"aria-current":active?"true":undefined,"aria-disabled":disabled?"true":undefined,...attributes });const iconHtml=icon?`<span class="flex items-center justify-center w-7 h-7 shrink-0 text-lg" aria-hidden="true">${icon}</span>`:"";const labelBlock=description?`<span class="flex-1 min-w-0"><span class="font-600 block">${escapeHtmlStr(label)}</span><span class="text-subtle text-sm block mt-1">${escapeHtmlStr(description)}</span></span>`:`<span class="flex-1 font-600">${escapeHtmlStr(label)}</span>`;const valueHtml=value?`<span class="text-subtle text-sm">${escapeHtmlStr(value)}</span>`:"";const chevronHtml=showChevron?`<span class="text-subtle opacity-50 text-sm ms-1" aria-hidden="true">›</span>`:"";return `<${Tag} class="${classes}"${baseAttrs}><div class="flex items-center gap-3">${iconHtml}${labelBlock}${valueHtml}${trailing}${chevronHtml}</div></${Tag}>`.trim();} export const settingsItem=SettingsItem;window.Aksara=Aksara;})();
|
|
1
|
+
(function(){ const registry=new Map();const instances=new Set();const focusableSelector=["a[href]","area[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","iframe","object","embed","[contenteditable]","[tabindex]:not([tabindex='-1'])"].join(",");function toElements(target){ if(!target)return[];if(typeof target==="string")return Array.from(document.querySelectorAll(target));if(target instanceof HTMLElement)return[target];if(target instanceof Element)return[target];if(target instanceof NodeList || Array.isArray(target)){ return Array.from(target).filter((item)=>item instanceof HTMLElement);} return[];} function resolveArgs(target,options,defaultSelector){ if(target && typeof target==="object" && !(target instanceof Element)&& !(target instanceof NodeList)&& !Array.isArray(target)){ const opts=target;const resolvedTarget=opts.target || opts.selector || defaultSelector;return { target:resolvedTarget,options:opts };} return { target:target || defaultSelector,options:(options || {})};} function dataName(name){ return name.replace(/[A-Z]/g,(match)=>`-${match.toLowerCase()}`);} function getData(element,component,name){ return element?.getAttribute(`data-${component}-${dataName(name)}`)??null;} function getOption(options,element,component,name,fallback){ if(options[name]!==undefined)return options[name];const value=getData(element,component,name);return value !==null?value:fallback;} function getBooleanOption(options,element,component,name,fallback){ const value=getOption(options,element,component,name,fallback);if(value==="true" || value===true)return true;if(value==="false" || value===false)return false;return Boolean(value);} function getNumberOption(options,element,component,name,fallback){ const value=getOption(options,element,component,name,fallback);const number=Number(value);return Number.isNaN(number)?fallback:number;} function clamp(value,min,max){ return Math.min(Math.max(value,min),max);} function emit(element,name,detail={}){ element.dispatchEvent(new CustomEvent(`aksara:${name}`,{ bubbles:true,detail }));} function getInstance(element,Type,options={}){ const key=Type.componentName;let map=registry.get(key);if(!map){ map=new WeakMap();registry.set(key,map);} if(!map.has(element)){ const instance=new Type(element,options);map.set(element,instance);instances.add(instance);} else if(options && Object.keys(options).length){ const instance=map.get(element);if(instance && typeof instance.updateOptions==="function"){ instance.updateOptions(options);} } return map.get(element);} function createInstanceList(instanceArray){ return new Proxy(instanceArray,{ get(target,prop){ if(prop in target){ const val=target[prop];return typeof val==="function"?val.bind(target):val;} return(...args)=>{ target.forEach((inst)=>{ const fn=inst[prop];if(typeof fn==="function"){ fn(...args);} });return createInstanceList(target);};} });} function createAll(target,Type,options={}){ const items=toElements(target);const insts=items.map((element)=>getInstance(element,Type,options));if(insts.length===1)return insts[0];return createInstanceList(insts);} class Component { element;options;cleanups;constructor(element,options={}){ this.element=element;this.options=options;this.cleanups=[];} updateOptions(options={}){ this.options={...this.options,...options };return this;} on(target,type,handler,options){ target.addEventListener(type,handler,options);this.cleanups.push(()=>target.removeEventListener(type,handler,options));} destroy(){ this.cleanups.splice(0).forEach((cleanup)=>cleanup());instances.delete(this);const ctor=this.constructor;emit(this.element,`${ctor.componentName || "component"}:destroy`,{ instance:this });} } class Modal extends Component { static componentName="modal";isOpen;previousFocus=null;dialog;dragState=null;backdrop;keyboard;focus;scrollLock;draggable;constructor(element,options={}){ super(element,options);this.isOpen=element.classList.contains("modal-open");this.dialog=element.querySelector(".modal-dialog");this.updateOptions(options);this.element.setAttribute("role",this.element.getAttribute("role")|| "dialog");this.element.setAttribute("aria-modal","true");this.element.setAttribute("aria-hidden",this.isOpen?"false":"true");this.on(this.element,"click",(event)=>{ if(event.target===this.element){ if(this.backdrop==="static"){ const staticClass=`${this.constructor.componentName}-static`;this.element.classList.add(staticClass);setTimeout(()=>this.element.classList.remove(staticClass),150);} else if(this.backdrop){ this.hide();} } });this.on(document,"keydown",(event)=>this.onKeydown(event));this.bindDrag();} updateOptions(options={}){ super.updateOptions(options);const component=this.constructor.componentName;const backdrop=getOption(this.options,this.element,component,"backdrop",true);this.backdrop=backdrop==="static"?"static":!(backdrop===false || backdrop==="false");this.keyboard=getBooleanOption(this.options,this.element,component,"keyboard",true);this.focus=getBooleanOption(this.options,this.element,component,"focus",true);this.scrollLock=getBooleanOption(this.options,this.element,component,"scrollLock",true);this.draggable=getBooleanOption(this.options,this.element,component,"draggable",true);return this;} bindDrag(){ if(!this.dialog)return;const header=this.dialog.querySelector(".modal-header");if(!header)return;this.on(header,"pointerdown",(event)=>this.startDrag(event));} startDrag(event){ if(!this.isOpen || !this.draggable || !this.dialog || event.button !==0)return;const target=event.target instanceof Element?event.target:null;if(target?.closest("button,a,input,select,textarea,label,[data-modal-close],[data-no-drag]"))return;const originX=Number.parseFloat(this.dialog.style.getPropertyValue("--aksara-modal-x"))|| 0;const originY=Number.parseFloat(this.dialog.style.getPropertyValue("--aksara-modal-y"))|| 0;const rect=this.dialog.getBoundingClientRect();const baseLeft=rect.left-originX;const baseTop=rect.top-originY;const padding=8;const move=(moveEvent)=>this.drag(moveEvent);const end=()=>{ document.removeEventListener("pointermove",move);document.removeEventListener("pointerup",end);document.removeEventListener("pointercancel",end);this.dialog?.classList.remove("is-dragging");this.dragState=null;};this.dragState={ originX,originY,pointerX:event.clientX,pointerY:event.clientY,minX:padding-baseLeft,maxX:window.innerWidth-padding-rect.width-baseLeft,minY:padding-baseTop,maxY:window.innerHeight-padding-rect.height-baseTop };this.dialog.classList.add("is-dragging");document.addEventListener("pointermove",move);document.addEventListener("pointerup",end);document.addEventListener("pointercancel",end);event.preventDefault();} drag(event){ if(!this.dialog || !this.dragState)return;const nextX=clamp(this.dragState.originX+event.clientX-this.dragState.pointerX,this.dragState.minX,this.dragState.maxX);const nextY=clamp(this.dragState.originY+event.clientY-this.dragState.pointerY,this.dragState.minY,this.dragState.maxY);this.dialog.style.setProperty("--aksara-modal-x",`${nextX}px`);this.dialog.style.setProperty("--aksara-modal-y",`${nextY}px`);} resetPosition(){ if(!this.dialog)return;this.dialog.style.removeProperty("--aksara-modal-x");this.dialog.style.removeProperty("--aksara-modal-y");this.dialog.classList.remove("is-dragging");} show(){ if(this.isOpen)return this;this.previousFocus=document.activeElement;this.isOpen=true;this.element.classList.add("modal-open");this.element.setAttribute("aria-hidden","false");if(this.scrollLock)document.documentElement.style.overflow="hidden";if(this.focus)this.focusFirst();emit(this.element,"modal:show",{ instance:this });return this;} hide(){ if(!this.isOpen)return this;this.isOpen=false;this.element.classList.remove("modal-open");this.element.setAttribute("aria-hidden","true");this.resetPosition();if(this.scrollLock)document.documentElement.style.overflow="";if(this.previousFocus && typeof this.previousFocus.focus==="function")this.previousFocus.focus();emit(this.element,"modal:hide",{ instance:this });return this;} toggle(){ return this.isOpen?this.hide():this.show();} focusFirst(){ const focusable=Array.from(this.element.querySelectorAll(focusableSelector));const first=focusable[0]|| this.element;if(!this.element.hasAttribute("tabindex"))this.element.setAttribute("tabindex","-1");first.focus({ preventScroll:true });} onKeydown(event){ if(!this.isOpen)return;if(event.key==="Escape"){ if(this.keyboard){ event.preventDefault();this.hide();} else if(this.backdrop==="static"){ const staticClass=`${this.constructor.componentName}-static`;this.element.classList.add(staticClass);setTimeout(()=>this.element.classList.remove(staticClass),150);} return;} if(event.key !=="Tab")return;const focusable=Array.from(this.element.querySelectorAll(focusableSelector));if(!focusable.length){ event.preventDefault();this.element.focus();return;} const first=focusable[0];const last=focusable[focusable.length-1];if(event.shiftKey && document.activeElement===first){ event.preventDefault();last.focus();} else if(!event.shiftKey && document.activeElement===last){ event.preventDefault();first.focus();} } } class Dropdown extends Component { static componentName="dropdown";trigger;menu;isOpen;originalParent;originalSibling;scrollHandler;placement;container;offset;keyboard;closeOnSelect;closeOnOutside;constructor(element,options={}){ super(element,options);let trigger;let menu=null;if(element.matches("[data-dropdown]")){ trigger=element;} else if(element.classList.contains("dropdown")){ trigger=element.querySelector("[data-dropdown]")|| element.querySelector("button,a");menu=element.querySelector(".dropdown-menu");} else { trigger=element;} this.trigger=trigger;if(!menu){ const menuSelector=options.menu || options.target ||(trigger &&(trigger.getAttribute("data-dropdown")|| trigger.getAttribute("data-target")));if(menuSelector && typeof menuSelector==="string"){ menu=document.querySelector(menuSelector);} else if(menuSelector instanceof HTMLElement){ menu=menuSelector;} if(!menu && trigger){ if(trigger.nextElementSibling && trigger.nextElementSibling.classList.contains("dropdown-menu")){ menu=trigger.nextElementSibling;} else { menu=trigger.parentElement?.querySelector(".dropdown-menu")|| null;} } } this.menu=menu;this.isOpen=false;this.originalParent=null;this.originalSibling=null;this.scrollHandler=null;this.updateOptions(options);if(this.trigger?.matches(".btn-sm,.input-sm,.form-control-sm,.form-select-sm")|| this.element.classList.contains("dropdown-sm")){ this.menu?.classList.add("dropdown-menu-sm");} if(this.trigger){ this.trigger.setAttribute("aria-haspopup","true");this.trigger.setAttribute("aria-expanded","false");this.on(this.trigger,"click",(event)=>{ const customEvent=event;if(customEvent.__aksaraDropdownHandled)return;customEvent.__aksaraDropdownHandled=true;event.preventDefault();this.toggle(event);});} this.on(document,"click",(event)=>{ if(!this.closeOnOutside)return;const target=event.target;if(!this.element.contains(target)&& !this.menu?.contains(target)){ this.hide();} });this.on(document,"keydown",(event)=>{ if(this.keyboard && event.key==="Escape")this.hide();});if(this.menu){ this.on(this.menu,"click",(event)=>{ const target=event.target;const item=target.closest(".dropdown-item");if(this.closeOnSelect && item && !item.disabled && !item.classList.contains("disabled")){ this.hide();} });} } updateOptions(options={}){ super.updateOptions(options);this.placement=getOption(this.options,this.trigger,"dropdown","placement",getData(this.element,"dropdown","placement")|| "bottom");this.container=getOption(this.options,this.trigger,"dropdown","container",getData(this.element,"dropdown","container")|| "body");this.offset=getNumberOption(this.options,this.trigger,"dropdown","offset",getNumberOption({},this.element,"dropdown","offset",4));this.keyboard=getBooleanOption(this.options,this.trigger,"dropdown","keyboard",getBooleanOption({},this.element,"dropdown","keyboard",true));this.closeOnSelect=getBooleanOption(this.options,this.trigger,"dropdown","closeOnSelect",getBooleanOption({},this.element,"dropdown","closeOnSelect",true));this.closeOnOutside=getBooleanOption(this.options,this.trigger,"dropdown","closeOnOutside",getBooleanOption({},this.element,"dropdown","closeOnOutside",true));return this;} position(){ if(!this.menu || !this.isOpen || !this.trigger)return;this.menu.style.display="block";this.menu.style.position="absolute";this.menu.style.zIndex="1000";const triggerRect=this.trigger.getBoundingClientRect();if(this.trigger.classList.contains("form-select")|| this.element.classList.contains("variant-form-select")|| this.element.hasAttribute("data-dropdown-select")){ this.menu.style.width=`${triggerRect.width}px`;this.menu.style.minWidth=`${triggerRect.width}px`;} const menuRect=this.menu.getBoundingClientRect();const gap=this.offset;let top;let left;let placement=this.placement;if(placement==="auto"){ const spaceBelow=window.innerHeight-triggerRect.bottom;const spaceAbove=triggerRect.top;placement=spaceBelow>=menuRect.height || spaceBelow>=spaceAbove?"bottom":"top";} this.menu.classList.remove("dropdown-top","dropdown-bottom","dropdown-start","dropdown-end");this.menu.classList.add(`dropdown-${placement}`);const isRtl=document.documentElement.getAttribute("dir")==="rtl" || document.body?.getAttribute("dir")==="rtl";if(placement==="top"){ top=triggerRect.top-menuRect.height-gap;left=isRtl?triggerRect.right-menuRect.width:triggerRect.left;} else if(placement==="start"){ top=triggerRect.top;left=isRtl?triggerRect.right+gap:triggerRect.left-menuRect.width-gap;} else if(placement==="end"){ top=triggerRect.top;left=isRtl?triggerRect.left-menuRect.width-gap:triggerRect.right+gap;} else { top=triggerRect.bottom+gap;left=isRtl?triggerRect.right-menuRect.width:triggerRect.left;} const viewportWidth=window.innerWidth;left=Math.max(8,Math.min(left,viewportWidth-menuRect.width-8));this.menu.style.top=`${top+window.scrollY}px`;this.menu.style.left=`${left+window.scrollX}px`;this.menu.style.bottom="auto";this.menu.style.right="auto";} show(){ if(!this.menu || this.isOpen)return this;this.isOpen=true;this.originalParent=this.menu.parentNode;this.originalSibling=this.menu.nextSibling;let containerEl=document.body;if(typeof this.container==="string" && this.container !=="body"){ containerEl=document.querySelector(this.container)|| document.body;} else if(this.container instanceof HTMLElement){ containerEl=this.container;} containerEl.appendChild(this.menu);this.menu.classList.add("dropdown-open");this.trigger?.setAttribute("aria-expanded","true");this.position();this.scrollHandler=()=>this.position();window.addEventListener("scroll",this.scrollHandler,{ passive:true });window.addEventListener("resize",this.scrollHandler);emit(this.element,"dropdown:show",{ instance:this });return this;} hide(){ if(!this.menu || !this.isOpen)return this;this.isOpen=false;if(this.scrollHandler){ window.removeEventListener("scroll",this.scrollHandler);window.removeEventListener("resize",this.scrollHandler);this.scrollHandler=null;} this.menu.classList.remove("dropdown-open","dropdown-top","dropdown-bottom","dropdown-start","dropdown-end");this.trigger?.setAttribute("aria-expanded","false");if(this.originalParent){ this.originalParent.insertBefore(this.menu,this.originalSibling);} this.menu.style.display="";this.menu.style.position="";this.menu.style.top="";this.menu.style.left="";this.menu.style.zIndex="";emit(this.element,"dropdown:hide",{ instance:this });return this;} toggle(event){ const clickEvent=(event || window.event);if(clickEvent && clickEvent.type==="click"){ if(clickEvent.__aksaraDropdownHandled && !event){ return this;} clickEvent.__aksaraDropdownHandled=true;} return this.isOpen?this.hide():this.show();} destroy(){ this.hide();super.destroy();} } class FloatingText extends Component { static dataAttribute="data-floating";static role="tooltip";static componentName="floating";tip;showTimeout;hideTimeout;container;html;content;placement;trigger;offset;showDelay;hideDelay;keyboard;constructor(element,options={}){ super(element,options);this.tip=null;this.showTimeout=null;this.hideTimeout=null;this.updateOptions(options);this.bindTriggers();this.on(document,"keydown",(event)=>{ if(this.keyboard && event.key==="Escape")this.hide();});} updateOptions(options={}){ super.updateOptions(options);const ctor=this.constructor;const component=ctor.componentName;const rawContent=(this.options.content??this.options.text??getData(this.element,component,"content")??this.element.getAttribute(ctor.dataAttribute)??"");this.container=getOption(this.options,this.element,component,"container",this.element.getAttribute("data-container")|| "body");this.html=getBooleanOption(this.options,this.element,component,"html",this.element.getAttribute("data-html")==="true");this.content=rawContent;this.placement=getOption(this.options,this.element,component,"placement",this.element.getAttribute("data-placement")|| "top");this.trigger=getOption(this.options,this.element,component,"trigger","hover focus");this.offset=getNumberOption(this.options,this.element,component,"offset",8);this.showDelay=getNumberOption(this.options,this.element,component,"showDelay",0);this.hideDelay=getNumberOption(this.options,this.element,component,"hideDelay",0);this.keyboard=getBooleanOption(this.options,this.element,component,"keyboard",true);if(this.tip){ if(this.html){ this.tip.innerHTML=this.content;} else { this.tip.textContent=this.content;} this.position();} return this;} bindTriggers(){ const triggers=String(this.trigger).split(/\s+/).filter(Boolean);if(triggers.includes("hover")){ this.on(this.element,"mouseenter",()=>this.scheduleShow());this.on(this.element,"mouseleave",()=>this.scheduleHide());} if(triggers.includes("focus")){ this.on(this.element,"focus",()=>this.scheduleShow());this.on(this.element,"blur",()=>this.scheduleHide());} if(triggers.includes("click")){ this.on(this.element,"click",(event)=>{ event.preventDefault();this.toggle();});} } scheduleShow(){ if(this.hideTimeout)clearTimeout(this.hideTimeout);if(this.showTimeout)clearTimeout(this.showTimeout);this.showTimeout=setTimeout(()=>this.show(),this.showDelay);} scheduleHide(){ if(this.showTimeout)clearTimeout(this.showTimeout);if(this.hideTimeout)clearTimeout(this.hideTimeout);this.hideTimeout=setTimeout(()=>this.hide(),this.hideDelay);} show(){ if(this.tip || !this.content)return this;const ctor=this.constructor;this.tip=document.createElement("div");this.tip.className=ctor.componentName;if(this.html){ this.tip.innerHTML=this.content;} else { this.tip.textContent=this.content;} this.tip.setAttribute("role",ctor.role);let containerEl=document.body;if(typeof this.container==="string" && this.container !=="body"){ containerEl=document.querySelector(this.container)|| document.body;} else if(this.container instanceof HTMLElement){ containerEl=this.container;} containerEl.append(this.tip);this.position();emit(this.element,`${ctor.componentName}:show`,{ instance:this });return this;} toggle(){ return this.tip?this.hide():this.show();} hide(){ if(!this.tip)return this;const ctor=this.constructor;this.tip.remove();this.tip=null;emit(this.element,`${ctor.componentName}:hide`,{ instance:this });return this;} position(){ if(!this.tip)return;const rect=this.element.getBoundingClientRect();const tipRect=this.tip.getBoundingClientRect();const gap=this.offset;const isRtl=document.documentElement.getAttribute("dir")==="rtl" || document.body?.getAttribute("dir")==="rtl";let placement=this.placement;if(placement==="auto"){ const spaceBelow=window.innerHeight-rect.bottom;const spaceAbove=rect.top;placement=spaceAbove>=tipRect.height || spaceAbove>=spaceBelow?"top":"bottom";} let physicalPlacement=placement;if(placement==="start"){ physicalPlacement=isRtl?"right":"left";} else if(placement==="end"){ physicalPlacement=isRtl?"left":"right";} const ctor=this.constructor;this.tip.className=`${ctor.componentName} ${ctor.componentName}-${placement}`;const topMap={ top:rect.top-tipRect.height-gap,bottom:rect.bottom+gap,left:rect.top+rect.height/2-tipRect.height/2,right:rect.top+rect.height/2-tipRect.height/2 };const top=topMap[physicalPlacement]??rect.top-tipRect.height-gap;const leftMap={ top:rect.left+rect.width/2-tipRect.width/2,bottom:rect.left+rect.width/2-tipRect.width/2,left:rect.left-tipRect.width-gap,right:rect.right+gap };const left=leftMap[physicalPlacement]??rect.left;this.tip.style.top=`${Math.max(4,top+window.scrollY)}px`;this.tip.style.left=`${Math.max(4,left+window.scrollX)}px`;} destroy(){ if(this.showTimeout)clearTimeout(this.showTimeout);if(this.hideTimeout)clearTimeout(this.hideTimeout);this.hide();super.destroy();} } class Tooltip extends FloatingText { static componentName="tooltip";static dataAttribute="data-tooltip";static role="tooltip";} class Popover extends FloatingText { static componentName="popover";static dataAttribute="data-popover";static role="dialog";} function collapsePanel(panel,duration=250){ const animatedPanel=panel;if(animatedPanel._aksaraCollapseTimer){ clearTimeout(animatedPanel._aksaraCollapseTimer);delete animatedPanel._aksaraCollapseTimer;} if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} if(duration<=0 ||(typeof window !=="undefined" && window.matchMedia?.("(prefers-reduced-motion:reduce)").matches)){ panel.hidden=true;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");return;} const computed=window.getComputedStyle(panel);const currentHeight=panel.getBoundingClientRect().height;const currentPaddingTop=computed.paddingTop;const currentPaddingBottom=computed.paddingBottom;panel.style.overflow="hidden";panel.style.height=`${currentHeight}px`;panel.style.paddingTop=currentPaddingTop;panel.style.paddingBottom=currentPaddingBottom;panel.style.opacity="1";panel.style.transition=`height ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-top ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-bottom ${duration}ms cubic-bezier(0.4,0,0.2,1),opacity ${Math.round(duration*0.7)}ms ease`;void panel.offsetHeight;panel.style.height="0px";panel.style.paddingTop="0px";panel.style.paddingBottom="0px";panel.style.opacity="0";const cleanup=()=>{ panel.hidden=true;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} delete animatedPanel._aksaraCollapseTimer;};const onEnd=(e)=>{ if(e.target===panel && e.propertyName==="height"){ cleanup();} };animatedPanel._aksaraCollapseEnd=onEnd;panel.addEventListener("transitionend",onEnd);animatedPanel._aksaraCollapseTimer=setTimeout(cleanup,duration+60);} function expandPanel(panel,duration=250){ const animatedPanel=panel;if(animatedPanel._aksaraCollapseTimer){ clearTimeout(animatedPanel._aksaraCollapseTimer);delete animatedPanel._aksaraCollapseTimer;} if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} if(duration<=0 ||(typeof window !=="undefined" && window.matchMedia?.("(prefers-reduced-motion:reduce)").matches)){ panel.hidden=false;panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");return;} panel.hidden=false;panel.style.removeProperty("height");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");const computed=window.getComputedStyle(panel);const targetPaddingTop=computed.paddingTop;const targetPaddingBottom=computed.paddingBottom;const targetHeight=panel.getBoundingClientRect().height;panel.style.overflow="hidden";panel.style.height="0px";panel.style.paddingTop="0px";panel.style.paddingBottom="0px";panel.style.opacity="0";void panel.offsetHeight;panel.style.transition=`height ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-top ${duration}ms cubic-bezier(0.4,0,0.2,1),padding-bottom ${duration}ms cubic-bezier(0.4,0,0.2,1),opacity ${duration}ms ease`;panel.style.height=`${targetHeight}px`;panel.style.paddingTop=targetPaddingTop;panel.style.paddingBottom=targetPaddingBottom;panel.style.opacity="1";const cleanup=()=>{ panel.style.removeProperty("height");panel.style.removeProperty("overflow");panel.style.removeProperty("padding-top");panel.style.removeProperty("padding-bottom");panel.style.removeProperty("opacity");panel.style.removeProperty("transition");if(animatedPanel._aksaraCollapseEnd){ panel.removeEventListener("transitionend",animatedPanel._aksaraCollapseEnd);delete animatedPanel._aksaraCollapseEnd;} delete animatedPanel._aksaraCollapseTimer;};const onEnd=(e)=>{ if(e.target===panel && e.propertyName==="height"){ cleanup();} };animatedPanel._aksaraCollapseEnd=onEnd;panel.addEventListener("transitionend",onEnd);animatedPanel._aksaraCollapseTimer=setTimeout(cleanup,duration+60);} class Accordion extends Component { static componentName="accordion";parent;collapsible;buttonSelector;duration;constructor(element,options={}){ super(element,options);this.updateOptions(options);this.on(element,"click",(event)=>{ const target=event.target;const button=target.closest(this.buttonSelector);if(!button || !element.contains(button))return;const panelSelector=button.getAttribute("data-accordion");if(!panelSelector)return;const panel=document.querySelector(panelSelector);if(!panel)return;const expanded=button.getAttribute("aria-expanded")==="true";if(expanded && !this.collapsible)return;const parentScope=this.getParentScope();if(!expanded && parentScope){ parentScope.querySelectorAll(this.buttonSelector).forEach((otherButton)=>{ if(otherButton===button)return;otherButton.setAttribute("aria-expanded","false");const otherPanelSelector=otherButton.getAttribute("data-accordion");if(otherPanelSelector){ const otherPanel=document.querySelector(otherPanelSelector);if(otherPanel &&(!otherPanel.hidden || otherPanel.offsetHeight>0)){ collapsePanel(otherPanel,this.duration);} } });} button.setAttribute("aria-expanded",String(!expanded));if(expanded){ collapsePanel(panel,this.duration);} else { expandPanel(panel,this.duration);} emit(element,"accordion:toggle",{ button,panel,expanded:!expanded });});} updateOptions(options={}){ super.updateOptions(options);const parentVal=getOption(this.options,this.element,"accordion","parent",true);if(parentVal==="true")this.parent=true;else if(parentVal==="false")this.parent=false;else this.parent=parentVal;this.collapsible=getBooleanOption(this.options,this.element,"accordion","collapsible",true);this.buttonSelector=getOption(this.options,this.element,"accordion","buttonSelector","[data-accordion]");this.duration=getNumberOption(this.options,this.element,"accordion","duration",250);return this;} getParentScope(){ if(this.parent===false)return null;if(this.parent===true)return this.element;if(this.parent instanceof Element)return this.parent;if(typeof this.parent==="string")return document.querySelector(this.parent)|| this.element;return this.element;} } class Tabs extends Component { static componentName="tabs";tabSelector;panelSelector;active;activeIndex;keyboard;loop;orientation;constructor(element,options={}){ super(element,options);this.updateOptions(options);this.on(element,"click",(event)=>{ const target=event.target;const tab=target.closest(this.tabSelector);if(!tab || !element.contains(tab))return;event.preventDefault();this.show(tab);});this.on(element,"keydown",(event)=>{ if(!this.keyboard)return;const keyEvent=event;const keys=this.orientation==="vertical"?["ArrowUp","ArrowDown"]:["ArrowLeft","ArrowRight"];if(!keys.includes(keyEvent.key))return;const tabs=Array.from(element.querySelectorAll(this.tabSelector));const index=tabs.indexOf(document.activeElement);if(index<0)return;event.preventDefault();const isNext=keyEvent.key==="ArrowRight" || keyEvent.key==="ArrowDown";const fallback=this.loop?(isNext?tabs[0]:tabs[tabs.length-1]):tabs[index];const next=isNext?tabs[index+1]|| fallback:tabs[index-1]|| fallback;if(next){ next.focus();this.show(next);} });this.activateInitial();} updateOptions(options={}){ const shouldActivate=(options.active !==undefined || options.activeIndex !==undefined)&& this.cleanups.length>0;super.updateOptions(options);this.tabSelector=getOption(this.options,this.element,"tabs","tabSelector","[data-tabs]");this.panelSelector=getOption(this.options,this.element,"tabs","panelSelector",null);this.active=getOption(this.options,this.element,"tabs","active",null);this.activeIndex=getNumberOption(this.options,this.element,"tabs","activeIndex",-1);this.keyboard=getBooleanOption(this.options,this.element,"tabs","keyboard",true);this.loop=getBooleanOption(this.options,this.element,"tabs","loop",true);this.orientation=getOption(this.options,this.element,"tabs","orientation",this.element.getAttribute("aria-orientation")|| "horizontal");this.element.setAttribute("role",this.element.getAttribute("role")|| "tablist");this.element.setAttribute("aria-orientation",this.orientation);if(shouldActivate)this.activateInitial();return this;} activateInitial(){ const tabs=Array.from(this.element.querySelectorAll(this.tabSelector));if(!tabs.length)return;let initial=null;if(this.active instanceof HTMLElement){ initial=this.active;} else if(typeof this.active==="string"){ initial=this.element.querySelector(this.active)|| document.querySelector(this.active);} if(!initial && this.activeIndex>=0){ initial=tabs[this.activeIndex]|| null;} if(!initial){ initial=tabs.find((tab)=>tab.getAttribute("aria-selected")==="true")|| tabs[0];} if(initial)this.show(initial);} show(tab){ const selector=tab.getAttribute("data-tabs");const panel=selector?document.querySelector(selector):null;if(!panel)return this;this.element.querySelectorAll(this.tabSelector).forEach((item)=>{ const selected=item===tab;item.setAttribute("role",item.getAttribute("role")|| "tab");item.setAttribute("aria-selected",String(selected));item.tabIndex=selected?0:-1;const targetSelector=item.getAttribute("data-tabs");const target=targetSelector?document.querySelector(targetSelector):null;if(target)target.hidden=!selected;});if(this.panelSelector){ document.querySelectorAll(this.panelSelector).forEach((item)=>{ if(item !==panel)item.hidden=true;});} panel.setAttribute("role",panel.getAttribute("role")|| "tabpanel");emit(this.element,"tabs:show",{ tab,panel,instance:this });return this;} } class Toast extends Component { static componentName="toast";timeout=null;delay;autohide;constructor(element,options={}){ super(element,options);this.updateOptions(options);element.setAttribute("role",element.getAttribute("role")|| "status");element.setAttribute("aria-live",element.getAttribute("aria-live")|| "polite");} updateOptions(options={}){ super.updateOptions(options);this.delay=getNumberOption(this.options,this.element,"toast","delay",5000);this.autohide=getBooleanOption(this.options,this.element,"toast","autohide",true);return this;} show(){ this.element.classList.add("toast-show");if(this.timeout)clearTimeout(this.timeout);if(this.autohide && this.delay>0)this.timeout=setTimeout(()=>this.hide(),this.delay);emit(this.element,"toast:show",{ instance:this });return this;} hide(){ this.element.classList.remove("toast-show");if(this.timeout)clearTimeout(this.timeout);emit(this.element,"toast:hide",{ instance:this });return this;} destroy(){ if(this.timeout)clearTimeout(this.timeout);super.destroy();} } class Carousel extends Component { static componentName="carousel";timeout=null;items;index;interval;autoplay;pauseOnHover;keyboard;loop;constructor(element,options={}){ super(element,options);this.items=Array.from(element.querySelectorAll("[data-carousel-item]"));this.index=this.resolveInitialIndex();this.updateOptions(options);this.show(this.index);this.on(element,"click",(event)=>{ const target=event.target;const action=target.closest("[data-carousel]");if(!action)return;const value=action.getAttribute("data-carousel");if(value==="next")this.next();if(value==="prev")this.prev();if(value !=="next" && value !=="prev" && value !=="")this.show(Number(value));});this.on(element,"keydown",(event)=>{ const keyEvent=event;if(!this.keyboard || !["ArrowLeft","ArrowRight"].includes(keyEvent.key))return;event.preventDefault();if(keyEvent.key==="ArrowRight")this.next();if(keyEvent.key==="ArrowLeft")this.prev();});if(this.pauseOnHover){ this.on(element,"mouseenter",()=>this.pause());this.on(element,"mouseleave",()=>this.play());} if(this.autoplay)this.play();} updateOptions(options={}){ super.updateOptions(options);this.interval=getNumberOption(this.options,this.element,"carousel","interval",5000);this.autoplay=getBooleanOption(this.options,this.element,"carousel","autoplay",false);this.pauseOnHover=getBooleanOption(this.options,this.element,"carousel","pauseOnHover",true);this.keyboard=getBooleanOption(this.options,this.element,"carousel","keyboard",true);this.loop=getBooleanOption(this.options,this.element,"carousel","loop",true);const activeIndex=getNumberOption(this.options,this.element,"carousel","activeIndex",-1);if(activeIndex>=0)this.show(activeIndex);if(this.autoplay)this.play();if(!this.autoplay)this.pause();return this;} resolveInitialIndex(){ const configured=getNumberOption(this.options,this.element,"carousel","activeIndex",-1);if(configured>=0)return configured;return Math.max(0,this.items.findIndex((item)=>!item.hidden));} show(index){ if(!this.items.length)return this;if(!this.loop &&(index<0 || index>=this.items.length))return this;this.index=(index+this.items.length)% this.items.length;this.items.forEach((item,itemIndex)=>{ item.hidden=itemIndex !==this.index;});emit(this.element,"carousel:show",{ index:this.index,instance:this });return this;} next(){ return this.show(this.index+1);} prev(){ return this.show(this.index-1);} play(){ if(this.timeout)clearInterval(this.timeout);if(this.autoplay && this.interval>0){ this.timeout=setInterval(()=>this.next(),this.interval);} return this;} pause(){ if(this.timeout)clearInterval(this.timeout);this.timeout=null;return this;} destroy(){ this.pause();super.destroy();} } class Offcanvas extends Modal { static componentName="offcanvas";show(){ if(this.isOpen)return this;this.previousFocus=document.activeElement;this.isOpen=true;this.element.classList.add("offcanvas-open");this.element.setAttribute("aria-hidden","false");if(this.scrollLock)document.documentElement.style.overflow="hidden";if(this.focus)this.focusFirst();emit(this.element,"offcanvas:show",{ instance:this });return this;} hide(){ if(!this.isOpen)return this;this.isOpen=false;this.element.classList.remove("offcanvas-open");this.element.setAttribute("aria-hidden","true");if(this.scrollLock)document.documentElement.style.overflow="";if(this.previousFocus && typeof this.previousFocus.focus==="function")this.previousFocus.focus();emit(this.element,"offcanvas:hide",{ instance:this });return this;} } function readTriggerOptions(trigger,component,names){ return names.reduce((options,name)=>{ const value=getData(trigger,component,name);if(value !==null)options[name]=value;return options;},{});} function dismissTarget(target){ if(!target)return;if(target.classList.contains("modal")){ getInstance(target,Modal).hide();} else if(target.classList.contains("offcanvas")){ getInstance(target,Offcanvas).hide();} else if(target.classList.contains("toast")){ getInstance(target,Toast).hide();} else if(target.classList.contains("dropdown")|| target.matches("[data-dropdown]")){ getInstance(target,Dropdown).hide();} else { target.remove();} } function resolveDismissTargets(trigger){ const selector=trigger.getAttribute("data-dismiss");if(selector){ try { return Array.from(document.querySelectorAll(selector));} catch { return[];} } const localTarget=trigger.closest(".alert,.toast,.modal,.offcanvas,.dropdown,.popover,.tooltip");return localTarget?[localTarget]:[];} function bindDataApi(){ document.querySelectorAll("[data-dismiss]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraDismissTrigger)return;customTrigger.__aksaraDismissTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();resolveDismissTargets(trigger).forEach((target)=>dismissTarget(target));});});document.querySelectorAll("[data-modal-close]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraModalCloseTrigger)return;customTrigger.__aksaraModalCloseTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-modal-close");const modal=targetSelector?document.querySelector(targetSelector):trigger.closest(".modal");if(modal)getInstance(modal,Modal).hide();});});document.querySelectorAll("[data-modal]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraModalTrigger)return;customTrigger.__aksaraModalTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-modal");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"modal",["backdrop","keyboard","focus","scrollLock","draggable"]);getInstance(target,Modal,options).show();} } });});document.querySelectorAll("[data-offcanvas-close]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraOffcanvasCloseTrigger)return;customTrigger.__aksaraOffcanvasCloseTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-offcanvas-close");const panel=targetSelector?document.querySelector(targetSelector):trigger.closest(".offcanvas");if(panel)getInstance(panel,Offcanvas).hide();});});document.querySelectorAll("[data-offcanvas]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraOffcanvasTrigger)return;customTrigger.__aksaraOffcanvasTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-offcanvas");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"offcanvas",["backdrop","keyboard","focus","scrollLock"]);getInstance(target,Offcanvas,options).show();} } });});document.querySelectorAll("[data-toast]").forEach((trigger)=>{ const customTrigger=trigger;if(customTrigger.__aksaraToastTrigger)return;customTrigger.__aksaraToastTrigger=true;trigger.addEventListener("click",(event)=>{ event.preventDefault();const targetSelector=trigger.getAttribute("data-toast");if(targetSelector){ const target=document.querySelector(targetSelector);if(target){ const options=readTriggerOptions(trigger,"toast",["delay","autohide"]);getInstance(target,Toast,options).show();} } });});} const injectedArbitraryRules=new Set();let arbitrarySheet=null;let arbitraryRuleIndex=0;function getArbitrarySheet(){ if(typeof document==="undefined")return null;if(!arbitrarySheet){ if("adoptedStyleSheets" in document && typeof CSSStyleSheet !=="undefined"){ try { arbitrarySheet=new CSSStyleSheet();document.adoptedStyleSheets=[...document.adoptedStyleSheets,arbitrarySheet];return arbitrarySheet;} catch { } } let styleEl=document.getElementById("aksara-arbitrary-styles");if(!styleEl){ styleEl=document.createElement("style");styleEl.id="aksara-arbitrary-styles";document.head?.appendChild(styleEl);} arbitrarySheet=styleEl.sheet;} return arbitrarySheet;} function escapeArbitraryClass(className){ return Array.from(className).map((char,index)=>{ if(/^[a-zA-Z_-]$/.test(char))return char;if(/^[0-9]$/.test(char)){ return index===0?`\\${char.charCodeAt(0).toString(16).padStart(6,"0")}`:char;} return `\\${char}`;}).join("");} const runtimeArbitraryPropertyMap={ m:(v)=>`margin:${v}`,mt:(v)=>`margin-block-start:${v}`,mb:(v)=>`margin-block-end:${v}`,ms:(v)=>`margin-inline-start:${v}`,me:(v)=>`margin-inline-end:${v}`,mx:(v)=>`margin-inline:${v}`,my:(v)=>`margin-block:${v}`,p:(v)=>`padding:${v}`,pt:(v)=>`padding-block-start:${v}`,pb:(v)=>`padding-block-end:${v}`,ps:(v)=>`padding-inline-start:${v}`,pe:(v)=>`padding-inline-end:${v}`,px:(v)=>`padding-inline:${v}`,py:(v)=>`padding-block:${v}`,gap:(v)=>`gap:${v}`,"row-gap":(v)=>`row-gap:${v}`,"col-gap":(v)=>`column-gap:${v}`,g:(v)=>`--aksara-gutter-x:${v};--aksara-gutter-y:${v}`,gx:(v)=>`--aksara-gutter-x:${v}`,gy:(v)=>`--aksara-gutter-y:${v}`,w:(v)=>`width:${v}`,h:(v)=>`height:${v}`,"min-w":(v)=>`min-width:${v}`,"max-w":(v)=>`max-width:${v}`,"min-h":(v)=>`min-height:${v}`,"max-h":(v)=>`max-height:${v}`,top:(v)=>`inset-block-start:${v}`,bottom:(v)=>`inset-block-end:${v}`,start:(v)=>`inset-inline-start:${v}`,end:(v)=>`inset-inline-end:${v}`,left:(v)=>`left:${v}`,right:(v)=>`right:${v}`,inset:(v)=>`inset:${v}`,"inset-x":(v)=>`inset-inline:${v}`,"inset-y":(v)=>`inset-block:${v}`,"translate-x":(v)=>`transform:translateX(${v})`,"translate-y":(v)=>`transform:translateY(${v})`,rotate:(v)=>`transform:rotate(${v})`,scale:(v)=>`transform:scale(${v})`,"skew-x":(v)=>`transform:skewX(${v})`,"skew-y":(v)=>`transform:skewY(${v})`,rounded:(v)=>`border-radius:${v}`,border:(v)=>`border-width:${v}`,"border-t":(v)=>`border-top-width:${v}`,"border-b":(v)=>`border-bottom-width:${v}`,"border-s":(v)=>`border-inline-start-width:${v}`,"border-e":(v)=>`border-inline-end-width:${v}`,"border-x":(v)=>`border-inline-width:${v}`,"border-y":(v)=>`border-block-width:${v}`,opacity:(v)=>`opacity:${v}`,z:(v)=>`z-index:${v}`,leading:(v)=>`line-height:${v}`,tracking:(v)=>`letter-spacing:${v}`,text:(v)=>{ if(/^(start|center|end|justify|left|right|inline-start|inline-end)$/i.test(v)){ return `text-align:${v}`;} return/^(#[0-9a-fA-F]+|rgb|hsl|var\(--|currentColor|transparent)/i.test(v)?`color:${v}`:`font-size:${v}`;},bg:(v)=>`background-color:${v}`,"bg-color":(v)=>`background-color:${v}`,overscroll:(v)=>`overscroll-behavior:${v}`,"overscroll-x":(v)=>`overscroll-behavior-x:${v}`,"overscroll-y":(v)=>`overscroll-behavior-y:${v}`,fw:(v)=>`font-weight:${v}`,"font-weight":(v)=>`font-weight:${v}`,fs:(v)=>`font-size:${v}`,"font-size":(v)=>`font-size:${v}`,lh:(v)=>`line-height:${v}`,"line-height":(v)=>`line-height:${v}`,"text-align":(v)=>`text-align:${v}`,align:(v)=>`vertical-align:${v}`,"vertical-align":(v)=>`vertical-align:${v}`,items:(v)=>`align-items:${v}`,"align-items":(v)=>`align-items:${v}`,justify:(v)=>`justify-content:${v}`,"justify-content":(v)=>`justify-content:${v}`,self:(v)=>`align-self:${v}`,"align-self":(v)=>`align-self:${v}`,content:(v)=>`align-content:${v}`,"align-content":(v)=>`align-content:${v}`,d:(v)=>`display:${v}`,display:(v)=>`display:${v}`,pos:(v)=>`position:${v}`,position:(v)=>`position:${v}`,aspect:(v)=>`aspect-ratio:${v}`,"aspect-ratio":(v)=>`aspect-ratio:${v}`,cursor:(v)=>`cursor:${v}`,select:(v)=>`user-select:${v}`,"user-select":(v)=>`user-select:${v}`,pointer:(v)=>`pointer-events:${v}`,"pointer-events":(v)=>`pointer-events:${v}`,fit:(v)=>`object-fit:${v}`,"object-fit":(v)=>`object-fit:${v}`,overflow:(v)=>`overflow:${v}`,"overflow-x":(v)=>`overflow-x:${v}`,"overflow-y":(v)=>`overflow-y:${v}`,shadow:(v)=>`box-shadow:${v}`,"box-shadow":(v)=>`box-shadow:${v}` };const runtimeBreakpoints={ sm:"36rem",md:"48rem",lg:"62rem",xl:"75rem","2xl":"87.5rem","3xl":"100rem" };const runtimeStateSelectors={ hover:":hover",focus:":focus",active:":active",disabled:":disabled",checked:":checked",selected:'[aria-selected="true"]',visited:":visited",first:":first-child",last:":last-child",odd:":nth-child(odd)",even:":nth-child(even)" };function parseModifiersAndUtility(className){ const parts=[];let bracketDepth=0;let current="";for(let i=0;i<className.length;i++){ const ch=className[i];if(ch==="[")bracketDepth++;else if(ch==="]")bracketDepth--;if(ch===":" && bracketDepth===0){ parts.push(current);current="";} else { current+=ch;} } parts.push(current);const utility=parts.pop()??"";return { modifiers:parts,utility };} function injectArbitraryClass(className){ if(injectedArbitraryRules.has(className))return;injectedArbitraryRules.add(className);const { modifiers,utility }=parseModifiersAndUtility(className);if(!utility)return;let prop;let val;let isNegative=false;const bracketMatch=utility.match(/^\[([a-zA-Z0-9_-]+):(.+)\]$/);if(bracketMatch){ prop=bracketMatch[1];if(!prop.startsWith("-")){ prop=prop.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();} val=bracketMatch[2];} else { const match=utility.match(/^(-)?([a-zA-Z0-9_-]+)-\[(.+)\]$/);if(!match)return;isNegative=Boolean(match[1]);prop=match[2];val=match[3];if(isNegative &&/^(webkit|moz|ms|o)-/i.test(prop)){ prop=`-${prop}`;isNegative=false;} else { prop=prop.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();} } val=val.replace(/(?<!\\)_/g," ").replace(/\\_/g,"_").trim();if(isNegative && !val.startsWith("-")){ val=`-${val}`;} const resolver=runtimeArbitraryPropertyMap[prop];const declarations=resolver?resolver(val):`${prop}:${val}`;const escaped=escapeArbitraryClass(className);let selector=`.${escaped}`;let stateSelector="";let themeVariant="";let breakpointVariant="";for(const v of modifiers){ if(v==="dark" || v==="light")themeVariant=v;else if(runtimeBreakpoints[v])breakpointVariant=v;else if(runtimeStateSelectors[v])stateSelector+=runtimeStateSelectors[v];else if(v==="group-hover")selector=`.group:hover.${escaped}`;} selector+=stateSelector;let rule=`${selector}{${declarations}}`;if(themeVariant){ rule=themeVariant==="dark"?`[data-theme="dark"]${selector},.dark ${selector}{${declarations}}`:`[data-theme="light"]${selector},.light ${selector}{${declarations}}`;} if(breakpointVariant){ rule=`@media(min-width:${runtimeBreakpoints[breakpointVariant]}){${rule}}`;} const sheet=getArbitrarySheet();if(sheet){ try { sheet.insertRule(rule,arbitraryRuleIndex++);} catch { } } } function processElementClasses(el){ const classAttr=el.getAttribute("class");if(!classAttr || !classAttr.includes("["))return;const tokens=classAttr.split(/\s+/);for(const token of tokens){ if(token.includes("[")&& token.endsWith("]")){ injectArbitraryClass(token);} } } function scanArbitraryDom(root=document){ if(typeof document==="undefined")return;if(root instanceof Element){ processElementClasses(root);} root.querySelectorAll('[class*="["]').forEach(processElementClasses);} let mutationObserverStarted=false;function setupArbitraryObserver(){ if(mutationObserverStarted || typeof MutationObserver==="undefined" || typeof document==="undefined")return;mutationObserverStarted=true;const observer=new MutationObserver((mutations)=>{ for(const m of mutations){ if(m.type==="attributes" && m.target instanceof Element){ processElementClasses(m.target);} else if(m.type==="childList"){ m.addedNodes.forEach((node)=>{ if(node instanceof Element){ scanArbitraryDom(node);} });} } });observer.observe(document.documentElement,{ subtree:true,childList:true,attributes:true,attributeFilter:["class"]});} let currentTheme="system";function getSystemTheme(){ if(typeof window !=="undefined" && window.matchMedia && window.matchMedia("(prefers-color-scheme:dark)").matches){ return "dark";} return "light";} function applyTheme(theme){ if(typeof document==="undefined")return;const root=document.documentElement;const effectiveTheme=theme==="system"?getSystemTheme():theme;root.setAttribute("data-theme",effectiveTheme);if(effectiveTheme==="dark"){ root.classList.add("dark");root.classList.remove("light");} else { root.classList.add("light");root.classList.remove("dark");} } function setupClipboard(root=document){ if(typeof document==="undefined")return;root.querySelectorAll("[data-clipboard]").forEach((trigger)=>{ if(trigger.dataset.aksaraClipboardBound)return;trigger.dataset.aksaraClipboardBound="true";trigger.addEventListener("click",async(e)=>{ e.preventDefault();const targetSelector=trigger.getAttribute("data-clipboard");let textToCopy="";if(targetSelector && targetSelector.startsWith("#")){ const targetEl=document.querySelector(targetSelector);if(targetEl){ textToCopy=targetEl.value??targetEl.textContent??"";} } else if(targetSelector){ textToCopy=targetSelector;} else { textToCopy=trigger.getAttribute("data-clipboard-text")|| trigger.textContent || "";} if(navigator.clipboard && textToCopy){ try { await navigator.clipboard.writeText(textToCopy);const originalText=trigger.getAttribute("data-clipboard-original")|| trigger.innerHTML;const successText=trigger.getAttribute("data-clipboard-success");if(successText){ if(!trigger.hasAttribute("data-clipboard-original")){ trigger.setAttribute("data-clipboard-original",originalText);} trigger.innerHTML=successText;setTimeout(()=>{ trigger.innerHTML=originalText;},2000);} trigger.classList.add("is-copied");setTimeout(()=>trigger.classList.remove("is-copied"),2000);emit(trigger,"clipboard:copy",{ text:textToCopy });} catch { } } });});} const Aksara={ Modal,Tooltip,Popover,Accordion,Dropdown,Tabs,Toast,Carousel,Offcanvas,modal:(target,options)=>{ const args=resolveArgs(target,options,"[data-modal],.modal");return createAll(args.target,Modal,args.options);},tooltip:(target,options)=>{ const args=resolveArgs(target,options,"[data-tooltip]");return createAll(args.target,Tooltip,args.options);},popover:(target,options)=>{ const args=resolveArgs(target,options,"[data-popover]");return createAll(args.target,Popover,args.options);},accordion:(target,options)=>{ const args=resolveArgs(target,options,".accordion");return createAll(args.target,Accordion,args.options);},dropdown:(target,options)=>{ const args=resolveArgs(target,options,"[data-dropdown],.dropdown");return createAll(args.target,Dropdown,args.options);},tabs:(target,options)=>{ const args=resolveArgs(target,options,".tabs");return createAll(args.target,Tabs,args.options);},toast:(target,options)=>{ const args=resolveArgs(target,options,".toast");return createAll(args.target,Toast,args.options);},carousel:(target,options)=>{ const args=resolveArgs(target,options,".carousel");return createAll(args.target,Carousel,args.options);},offcanvas:(target,options)=>{ const args=resolveArgs(target,options,".offcanvas");return createAll(args.target,Offcanvas,args.options);},setTheme(theme){ currentTheme=theme;if(typeof localStorage !=="undefined"){ try { localStorage.setItem("aksara-theme",theme);} catch { } } applyTheme(theme);if(typeof document !=="undefined"){ emit(document.documentElement,"theme:change",{ theme });} return theme;},getTheme(){ return currentTheme;},initTheme(){ if(typeof localStorage !=="undefined"){ try { const saved=(localStorage.getItem("aksara-theme")|| localStorage.getItem("aksara-docs-theme"));if(saved &&(saved==="light" || saved==="dark" || saved==="system")){ currentTheme=saved;} } catch { } } applyTheme(currentTheme);if(typeof window !=="undefined" && window.matchMedia){ window.matchMedia("(prefers-color-scheme:dark)").addEventListener("change",()=>{ if(currentTheme==="system"){ applyTheme("system");} });} return currentTheme;},confirm(options){ if(typeof document==="undefined")return Promise.resolve(false);let host=document.getElementById("aksara-dialog-host");if(!host){ host=document.createElement("div");host.id="aksara-dialog-host";document.body.appendChild(host);} const tone=options.tone??"danger";const confirmLabel=options.confirmLabel??"Confirm";const cancelLabel=options.cancelLabel??"Cancel";const icon=options.icon??(tone==="danger"?"mdi-alert-circle-outline":"mdi-alert-outline");host.innerHTML=`<div class="modal fade modal-sm" id="aksaraConfirmModal" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="aksara-confirm-title"><div class="modal-dialog modal-dialog-centered"><div class="modal-content overflow-hidden border-0 shadow-lg"><div class="modal-body text-center p-4"><i class="mdi ${escapeHtmlStr(icon)} text-${escapeHtmlStr(tone)} fs-1 d-block mb-2" aria-hidden="true"></i><h5 id="aksara-confirm-title" class="fs-5 font-bold mb-2 text-body">${escapeHtmlStr(options.title)}</h5><p class="text-muted mb-0">${escapeHtmlStr(options.message)}</p></div><div class="modal-footer p-0 overflow-hidden m-0 w-100 gap-0 d-flex border-top"><button class="btn btn-ghost text-body rounded-0 py-3 m-0 text-center w-[50%]" type="button" data-aksara-confirm-cancel>${escapeHtmlStr(cancelLabel)}</button><button class="btn btn-ghost border-start text-${escapeHtmlStr(tone)} rounded-0 py-3 m-0 text-center w-[50%]" type="button" data-aksara-confirm-accept><i class="mdi mdi-check me-1" aria-hidden="true"></i>${escapeHtmlStr(confirmLabel)}</button></div></div></div></div>`;const modalEl=host.querySelector("#aksaraConfirmModal");if(!modalEl)return Promise.resolve(false);const modalInstance=Aksara.modal(modalEl);modalInstance.show();return new Promise((resolve)=>{ let settled=false;const finish=(value)=>{ if(settled)return;settled=true;modalInstance.hide();setTimeout(()=>{ if(host)host.innerHTML="";},200);resolve(value);};modalEl.addEventListener("modal:hide",()=>finish(false),{ once:true });host?.querySelector("[data-aksara-confirm-cancel]")?.addEventListener("click",()=>finish(false),{ once:true });host?.querySelector("[data-aksara-confirm-accept]")?.addEventListener("click",()=>finish(true),{ once:true });});},alert(options){ if(typeof document==="undefined")return Promise.resolve();let host=document.getElementById("aksara-dialog-host");if(!host){ host=document.createElement("div");host.id="aksara-dialog-host";document.body.appendChild(host);} const tone=options.tone??"primary";const buttonLabel=options.buttonLabel??"OK";const icon=options.icon??(tone==="danger"?"mdi-alert-circle-outline":tone==="warning"?"mdi-alert-outline":"mdi-information-outline");host.innerHTML=`<div class="modal fade modal-sm" id="aksaraAlertModal" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="aksara-alert-title"><div class="modal-dialog modal-dialog-centered"><div class="modal-content overflow-hidden border-0 shadow-lg"><div class="modal-body text-center p-4"><i class="mdi ${escapeHtmlStr(icon)} text-${escapeHtmlStr(tone)} fs-1 d-block mb-2" aria-hidden="true"></i><h5 id="aksara-alert-title" class="fs-5 font-bold mb-2 text-body">${escapeHtmlStr(options.title)}</h5><p class="text-muted mb-0">${escapeHtmlStr(options.message)}</p></div><div class="modal-footer p-0 overflow-hidden m-0 w-100 gap-0 d-flex border-top"><button class="btn btn-ghost text-body rounded-0 py-3 m-0 text-center w-100" type="button" data-aksara-alert-dismiss>${escapeHtmlStr(buttonLabel)}</button></div></div></div></div>`;const modalEl=host.querySelector("#aksaraAlertModal");if(!modalEl)return Promise.resolve();const modalInstance=Aksara.modal(modalEl);modalInstance.show();return new Promise((resolve)=>{ let settled=false;const finish=()=>{ if(settled)return;settled=true;modalInstance.hide();setTimeout(()=>{ if(host)host.innerHTML="";},200);resolve();};modalEl.addEventListener("modal:hide",()=>finish(),{ once:true });host?.querySelector("[data-aksara-alert-dismiss]")?.addEventListener("click",()=>finish(),{ once:true });});},notify(message,options={}){ if(typeof document==="undefined")return;let container=document.getElementById("aksara-toast-container");if(!container){ container=document.createElement("div");container.id="aksara-toast-container";container.className="aksara-toast-container";document.body.appendChild(container);} const toast=document.createElement("div");toast.className="aksara-toast-pill";const iconClass=options.icon??"mdi-information-outline";toast.innerHTML=`<i class="mdi ${escapeHtmlStr(iconClass)} text-primary" style="font-size:1.15rem;line-height:1;"></i><span>${escapeHtmlStr(message)}</span>`;container.appendChild(toast);const duration=options.duration??2500;setTimeout(()=>{ toast.style.opacity="0";toast.style.transform="translateY(8px)";setTimeout(()=>toast.remove(),250);},duration);},async clipboard(target,text){ if(typeof navigator==="undefined" || !navigator.clipboard)return false;let textToCopy=text??"";if(!textToCopy && typeof document !=="undefined"){ const el=typeof target==="string"?document.querySelector(target):target;if(el){ textToCopy=el.value??el.textContent??"";} } if(!textToCopy)return false;try { await navigator.clipboard.writeText(textToCopy);return true;} catch { return false;} },init(root=document){ if(root===document){ this.initTheme();} setupClipboard(root);scanArbitraryDom(root);setupArbitraryObserver();createAll(root.querySelectorAll("[data-tooltip]"),Tooltip);createAll(root.querySelectorAll("[data-popover]"),Popover);const dropdowns=new Set();root.querySelectorAll(".dropdown").forEach((el)=>dropdowns.add(el));root.querySelectorAll("[data-dropdown]").forEach((el)=>{ if(!el.closest(".dropdown")){ dropdowns.add(el);} });createAll(Array.from(dropdowns),Dropdown);createAll(root.querySelectorAll(".accordion"),Accordion);createAll(root.querySelectorAll(".tabs"),Tabs);createAll(root.querySelectorAll(".toast"),Toast);createAll(root.querySelectorAll(".carousel"),Carousel);createAll(root.querySelectorAll(".modal"),Modal);createAll(root.querySelectorAll(".offcanvas"),Offcanvas);bindDataApi();emit(document.documentElement,"init",{ root });return this;},destroy(){ Array.from(instances).forEach((instance)=>instance.destroy());registry.clear();emit(document.documentElement,"destroy");return this;} };if(typeof document !=="undefined"){ document.addEventListener("DOMContentLoaded",()=>Aksara.init());} function classNames(...classes){ return classes.filter(Boolean).join(" ").trim();} function toAttributes(attributes){ if(!attributes)return "";const parts=[];for(const[key,value]of Object.entries(attributes)){ if(value===true){ parts.push(key);} else if(value !==false && value !==null && value !==undefined){ parts.push(`${key}="${escapeHtmlStr(value)}"`);} } return parts.length>0?` ${parts.join(" ")}`:"";} function escapeHtmlStr(value){ return String(value??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'");} function SidebarNav(props){ const { items=[],title="",subtitle="",brandIcon="",className="",attributes }=props;const baseAttrs=toAttributes(attributes);const brandHtml=title?`<div class="sidebar-nav-brand">${brandIcon?`<span class="sidebar-nav-icon">${brandIcon}</span>`:""}<div><span class="sidebar-nav-brand-title">${escapeHtmlStr(title)}</span>${subtitle?`<span class="sidebar-nav-brand-subtitle">${escapeHtmlStr(subtitle)}</span>`:""}</div></div>`:"";const itemsHtml=items.map((item)=>{ const isLink=Boolean(item.href);const isTab=Boolean(item.panelTarget)&& !isLink;const Tag=isLink?"a":"button";const itemClasses=classNames("sidebar-nav-item",item.active && "active",item.disabled && "disabled",item.className);const itemAttrs=toAttributes({ href:isLink?item.href:undefined,type:!isLink?"button":undefined,"data-tabs":isTab?item.panelTarget:undefined,role:isTab?"tab":undefined,"aria-selected":isTab?(item.active?"true":"false"):undefined,tabindex:isTab?(item.active?"0":"-1"):undefined,id:isTab && item.id?`sidebar-tab-${item.id}`:item.id,"aria-controls":isTab && item.id?item.id:undefined,disabled:!isLink && item.disabled?true:undefined,"aria-disabled":item.disabled?"true":undefined,"aria-current":isLink && item.active?"page":undefined,...item.attributes });const iconHtml=item.icon?`<span class="sidebar-nav-icon" aria-hidden="true">${item.icon}</span>`:"";const badgeHtml=item.badge?`<span class="sidebar-nav-badge">${escapeHtmlStr(item.badge)}</span>`:"";return `<${Tag} class="${itemClasses}"${itemAttrs}>${iconHtml}<span class="sidebar-nav-label">${escapeHtmlStr(item.label)}</span>${badgeHtml}</${Tag}>`;}).join("");return `<nav class="${classNames("sidebar-nav",className)}"${baseAttrs}>${brandHtml}${itemsHtml}</nav>`.trim();} export const sidebarNav=SidebarNav;function SidebarNavHeader(props){ const { label,className="" }=props;return `<span class="${classNames("sidebar-nav-header",className)}">${escapeHtmlStr(label)}</span>`;} export const sidebarNavHeader=SidebarNavHeader;function SidebarLayout(props){ const { sidebar,content,className="",attributes }=props;const baseAttrs=toAttributes(attributes);return `<div class="${classNames("sidebar-layout",className)}"${baseAttrs}><div class="sidebar-pane">${sidebar}</div><div class="sidebar-content">${content}</div></div>`.trim();} export const sidebarLayout=SidebarLayout;function ListGroup(props={}){ const { children="",flush=false,numbered=false,horizontal=false,className="",attributes }=props;const horizontalClass=horizontal===true?"list-group-horizontal":typeof horizontal==="string"?`list-group-horizontal-${horizontal}`:null;const classes=classNames("list-group",flush && "list-group-flush",numbered && "list-group-numbered",horizontalClass,className);const Tag=numbered?"ol":"div";const baseAttrs=toAttributes(attributes);return `<${Tag} class="${classes}"${baseAttrs}>${children}</${Tag}>`.trim();} export const listGroup=ListGroup;function ListGroupItem(props={}){ const { content="",active=false,disabled=false,action=false,href,variant,className="",attributes }=props;const isLink=Boolean(href);const Tag=isLink?"a":action?"button":"div";const classes=classNames("list-group-item",(action || isLink)&& "list-group-item-action",active && "active",disabled && "disabled",variant && `list-group-item-${variant}`,className);const baseAttrs=toAttributes({ href,type:Tag==="button"?"button":undefined,disabled:Tag==="button" && disabled?true:undefined,"aria-current":active?"true":undefined,"aria-disabled":disabled?"true":undefined,...attributes });return `<${Tag} class="${classes}"${baseAttrs}>${content}</${Tag}>`.trim();} export const listGroupItem=ListGroupItem;function SettingsGroup(props={}){ const { children="",title="",className="",attributes }=props;const baseAttrs=toAttributes(attributes);const groupHtml=`<div class="${classNames("list-group",className)}"${baseAttrs}>${children}</div>`;if(!title)return groupHtml.trim();return `<div><p class="text-xs font-800 uppercase tracking-wider text-subtle mb-2 px-1">${escapeHtmlStr(title)}</p><div class="${classNames("list-group",className)}">${children}</div></div>`.trim();} export const settingsGroup=SettingsGroup;function SettingsItem(props){ const { label,description="",icon="",value="",trailing="",href,action=false,showChevron=false,active=false,disabled=false,className="",attributes }=props;const isLink=Boolean(href);const Tag=isLink?"a":action?"button":"div";const classes=classNames("list-group-item",(action || isLink)&& "list-group-item-action",active && "active",disabled && "disabled",className);const baseAttrs=toAttributes({ href,type:Tag==="button"?"button":undefined,disabled:Tag==="button" && disabled?true:undefined,"aria-current":active?"true":undefined,"aria-disabled":disabled?"true":undefined,...attributes });const iconHtml=icon?`<span class="flex items-center justify-center w-7 h-7 shrink-0 text-lg" aria-hidden="true">${icon}</span>`:"";const labelBlock=description?`<span class="flex-1 min-w-0"><span class="font-600 block">${escapeHtmlStr(label)}</span><span class="text-subtle text-sm block mt-1">${escapeHtmlStr(description)}</span></span>`:`<span class="flex-1 font-600">${escapeHtmlStr(label)}</span>`;const valueHtml=value?`<span class="text-subtle text-sm">${escapeHtmlStr(value)}</span>`:"";const chevronHtml=showChevron?`<span class="text-subtle opacity-50 text-sm ms-1" aria-hidden="true">›</span>`:"";return `<${Tag} class="${classes}"${baseAttrs}><div class="flex items-center gap-3">${iconHtml}${labelBlock}${valueHtml}${trailing}${chevronHtml}</div></${Tag}>`.trim();} export const settingsItem=SettingsItem;window.Aksara=Aksara;})();
|