rip-lang 3.13.119 → 3.13.121

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.
Files changed (71) hide show
  1. package/README.md +11 -2
  2. package/docs/RIP-LANG.md +4 -0
  3. package/docs/dist/rip.js +257 -27
  4. package/docs/dist/rip.min.js +183 -183
  5. package/docs/dist/rip.min.js.br +0 -0
  6. package/docs/ui/accordion.rip +103 -0
  7. package/docs/ui/alert-dialog.rip +53 -0
  8. package/docs/ui/autocomplete.rip +115 -0
  9. package/docs/ui/avatar.rip +37 -0
  10. package/docs/ui/badge.rip +15 -0
  11. package/docs/ui/breadcrumb.rip +47 -0
  12. package/docs/ui/button-group.rip +26 -0
  13. package/docs/ui/button.rip +23 -0
  14. package/docs/ui/card.rip +25 -0
  15. package/docs/ui/carousel.rip +110 -0
  16. package/docs/ui/checkbox-group.rip +61 -0
  17. package/docs/ui/checkbox.rip +33 -0
  18. package/docs/ui/collapsible.rip +50 -0
  19. package/docs/ui/combobox.rip +130 -0
  20. package/docs/ui/context-menu.rip +88 -0
  21. package/docs/ui/date-picker.rip +206 -0
  22. package/docs/ui/dialog.rip +60 -0
  23. package/docs/ui/drawer.rip +58 -0
  24. package/docs/ui/editable-value.rip +82 -0
  25. package/docs/ui/field.rip +53 -0
  26. package/docs/ui/fieldset.rip +22 -0
  27. package/docs/ui/form.rip +39 -0
  28. package/docs/ui/grid.rip +901 -0
  29. package/docs/ui/hljs-rip.js +209 -0
  30. package/docs/ui/index.css +1797 -0
  31. package/docs/ui/index.html +2385 -0
  32. package/docs/ui/input-group.rip +28 -0
  33. package/docs/ui/input.rip +36 -0
  34. package/docs/ui/label.rip +16 -0
  35. package/docs/ui/menu.rip +134 -0
  36. package/docs/ui/menubar.rip +151 -0
  37. package/docs/ui/meter.rip +36 -0
  38. package/docs/ui/multi-select.rip +203 -0
  39. package/docs/ui/native-select.rip +33 -0
  40. package/docs/ui/nav-menu.rip +126 -0
  41. package/docs/ui/number-field.rip +162 -0
  42. package/docs/ui/otp-field.rip +89 -0
  43. package/docs/ui/pagination.rip +123 -0
  44. package/docs/ui/popover.rip +93 -0
  45. package/docs/ui/preview-card.rip +75 -0
  46. package/docs/ui/progress.rip +25 -0
  47. package/docs/ui/radio-group.rip +57 -0
  48. package/docs/ui/resizable.rip +123 -0
  49. package/docs/ui/scroll-area.rip +145 -0
  50. package/docs/ui/select.rip +151 -0
  51. package/docs/ui/separator.rip +17 -0
  52. package/docs/ui/skeleton.rip +22 -0
  53. package/docs/ui/slider.rip +165 -0
  54. package/docs/ui/spinner.rip +17 -0
  55. package/docs/ui/table.rip +27 -0
  56. package/docs/ui/tabs.rip +113 -0
  57. package/docs/ui/textarea.rip +48 -0
  58. package/docs/ui/toast.rip +87 -0
  59. package/docs/ui/toggle-group.rip +71 -0
  60. package/docs/ui/toggle.rip +24 -0
  61. package/docs/ui/toolbar.rip +38 -0
  62. package/docs/ui/tooltip.rip +85 -0
  63. package/package.json +1 -1
  64. package/src/compiler.js +24 -12
  65. package/src/components.js +43 -6
  66. package/src/grammar/grammar.rip +2 -2
  67. package/src/lexer.js +26 -0
  68. package/src/parser.js +2 -2
  69. package/src/sourcemap-utils.js +91 -0
  70. package/src/typecheck.js +33 -8
  71. package/src/ui.rip +118 -2
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.119-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.121-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
14
  <a href="#"><img src="https://img.shields.io/badge/tests-1%2C436%2F1%2C436-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
@@ -87,6 +87,15 @@ dog = Dog.new("Buddy") # Ruby-style constructor
87
87
 
88
88
  Both `#{}` and `${}` compile to JavaScript template literals. Use whichever you prefer.
89
89
 
90
+ ### Objects
91
+
92
+ ```coffee
93
+ user = {name: "Alice", age: 30}
94
+ config =
95
+ api.endpoint: "https://example.com" # Dotted keys become flat string keys
96
+ api.timeout: 5000 # {'api.endpoint': "...", 'api.timeout': 5000}
97
+ ```
98
+
90
99
  ### Destructuring & Comprehensions
91
100
 
92
101
  ```coffee
@@ -424,7 +433,7 @@ Rip includes optional packages for full-stack development:
424
433
  | [rip-lang](https://www.npmjs.com/package/rip-lang) | 3.13.62 | Core language compiler |
425
434
  | [@rip-lang/server](packages/server/) | 1.3.12 | Multi-worker app server (web framework, hot reload, HTTPS, mDNS) |
426
435
  | [@rip-lang/db](packages/db/) | 1.3.15 | DuckDB server with official UI + ActiveRecord-style client |
427
- | [ui](packages/ui/) | — | Rip UI — 38 headless components (Grid, Select, Dialog, Tabs, etc.) |
436
+ | [@rip-lang/ui](packages/ui/) | — | Unified UI system browser widgets, email components, shared helpers, Tailwind integration |
428
437
  | [@rip-lang/swarm](packages/swarm/) | 1.2.18 | Parallel job runner with worker pool |
429
438
  | [@rip-lang/csv](packages/csv/) | 1.3.6 | CSV parser + writer |
430
439
  | [@rip-lang/schema](packages/schema/) | 0.3.8 | Unified schema → TypeScript types, SQL DDL, validation, ORM |
package/docs/RIP-LANG.md CHANGED
@@ -106,6 +106,7 @@ colors = %w(red green blue) # any delimiter: [] () {} <> || !! etc.
106
106
  # Objects
107
107
  user = {name: "Alice", age: 30}
108
108
  shorthand = {name, age} # Same as {name: name, age: age}
109
+ config = {api.host: "localhost", api.port: 3000} # Dotted keys → flat string keys
109
110
 
110
111
  # Ranges
111
112
  nums = [1..5] # [1, 2, 3, 4, 5]
@@ -2068,6 +2069,9 @@ a[/pat/, 1] # regex extract
2068
2069
  a? # existence check (a != null)
2069
2070
  a ?? b # nullish coalescing
2070
2071
 
2072
+ # Dotted keys
2073
+ {a.b: 1} # {'a.b': 1} — flat string key
2074
+
2071
2075
  # Word arrays
2072
2076
  %w[foo bar baz] # ["foo", "bar", "baz"] — Ruby-style word literal
2073
2077
 
package/docs/dist/rip.js CHANGED
@@ -2633,6 +2633,25 @@
2633
2633
  inTernary = false;
2634
2634
  return forward(1);
2635
2635
  }
2636
+ if (tokens[i - 1]?.[0] === "PROPERTY" && tokens[i - 2]?.[0] === ".") {
2637
+ let j = i - 2;
2638
+ while (j >= 2 && tokens[j]?.[0] === "." && (tokens[j - 1]?.[0] === "PROPERTY" || tokens[j - 1]?.[0] === "IDENTIFIER")) {
2639
+ j -= 2;
2640
+ }
2641
+ j += 1;
2642
+ if (tokens[j]?.[0] === "IDENTIFIER" || tokens[j]?.[0] === "PROPERTY") {
2643
+ let parts = [];
2644
+ for (let k = j;k < i; k += 2)
2645
+ parts.push(tokens[k][1]);
2646
+ let str = gen("STRING", `"${parts.join(".")}"`, tokens[j]);
2647
+ str.pre = tokens[j].pre;
2648
+ str.spaced = tokens[j].spaced;
2649
+ str.newLine = tokens[j].newLine;
2650
+ str.loc = tokens[j].loc;
2651
+ tokens.splice(j, i - j, str);
2652
+ i = j + 1;
2653
+ }
2654
+ }
2636
2655
  let s = EXPRESSION_END.has(this.tokens[i - 1]?.[0]) ? stack[stack.length - 1]?.[1] ?? i - 1 : i - 1;
2637
2656
  if (this.tokens[i - 2]?.[0] === "@")
2638
2657
  s = i - 2;
@@ -2818,6 +2837,13 @@
2818
2837
  return true;
2819
2838
  if (this.tokens[j + 1]?.[0] === ":")
2820
2839
  return true;
2840
+ if ((this.tokens[j]?.[0] === "IDENTIFIER" || this.tokens[j]?.[0] === "PROPERTY") && this.tokens[j + 1]?.[0] === ".") {
2841
+ let k = j + 2;
2842
+ while (this.tokens[k]?.[0] === "PROPERTY" && this.tokens[k + 1]?.[0] === ".")
2843
+ k += 2;
2844
+ if (this.tokens[k]?.[0] === "PROPERTY" && this.tokens[k + 1]?.[0] === ":")
2845
+ return true;
2846
+ }
2821
2847
  if (EXPRESSION_START.has(this.tokens[j]?.[0])) {
2822
2848
  let end = null;
2823
2849
  this.detectEnd(j + 1, (t) => EXPRESSION_END.has(t[0]), (t, i) => end = i);
@@ -3420,9 +3446,9 @@
3420
3446
  case 331:
3421
3447
  return ["import", $[$0 - 4], $[$0]];
3422
3448
  case 332:
3423
- return ["import", [$[$0 - 4], $[$0 - 2]], $[$0]];
3449
+ return ["import", $[$0 - 4], $[$0 - 2], $[$0]];
3424
3450
  case 333:
3425
- return ["import", [$[$0 - 7], $[$0 - 4]], $[$0]];
3451
+ return ["import", $[$0 - 7], $[$0 - 4], $[$0]];
3426
3452
  case 344:
3427
3453
  return ["*", $[$0]];
3428
3454
  case 345:
@@ -4162,12 +4188,13 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4162
4188
  }
4163
4189
  }
4164
4190
  }
4191
+ let atLineStart = tag === "IDENTIFIER" && (prevTag === "INDENT" || prevTag === "TERMINATOR" || prevTag === "RENDER");
4165
4192
  if (isClsxCallEnd) {
4166
4193
  isTemplateElement = true;
4167
4194
  } else if (tag === "IDENTIFIER" && isTemplateTag(token[1]) && !isAfterControlFlow) {
4168
4195
  isTemplateElement = true;
4169
4196
  } else if (tag === "IDENTIFIER" && !isAfterControlFlow) {
4170
- isTemplateElement = startsWithTag(tokens, i);
4197
+ isTemplateElement = atLineStart || startsWithTag(tokens, i);
4171
4198
  } else if (tag === "PROPERTY" || tag === "STRING" || tag === "STRING_END" || tag === "NUMBER" || tag === "BOOL" || tag === "CALL_END" || tag === ")" || tag === "PRESENCE") {
4172
4199
  isTemplateElement = startsWithTag(tokens, i);
4173
4200
  }
@@ -4184,7 +4211,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4184
4211
  }
4185
4212
  }
4186
4213
  }
4187
- let isBareTag = isClsxCallEnd || tag === "IDENTIFIER" && isTemplateTag(token[1]) || isClassOrIdTail;
4214
+ let isBareTag = isClsxCallEnd || tag === "IDENTIFIER" && (isTemplateTag(token[1]) || atLineStart) || isClassOrIdTail;
4188
4215
  if (isBareTag) {
4189
4216
  let callStartToken = gen2("CALL_START", "(", token);
4190
4217
  let arrowToken = gen2("->", "->", token);
@@ -4409,6 +4436,8 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4409
4436
  const expandType = (t) => t ? t.replace(/::/g, ":").replace(/(\w+(?:<[^>]+>)?)\?\?/g, "$1 | null | undefined").replace(/(\w+(?:<[^>]+>)?)\?(?![.:])/g, "$1 | undefined").replace(/(\w+(?:<[^>]+>)?)\!/g, "NonNullable<$1>") : null;
4410
4437
  const sl = [];
4411
4438
  sl.push("class {");
4439
+ sl.push(" declare _root: Element | null;");
4440
+ sl.push(" emit(name: string, detail?: any): void {}");
4412
4441
  const propEntries = [];
4413
4442
  for (const { name, type, isPublic, required } of stateVars) {
4414
4443
  if (!isPublic)
@@ -4492,6 +4521,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4492
4521
  }
4493
4522
  sl.push(" }");
4494
4523
  const eventMethodTypes = new Map;
4524
+ for (const [eventName, methodName] of autoEventHandlers) {
4525
+ eventMethodTypes.set(methodName, eventName);
4526
+ }
4495
4527
  if (renderBlock) {
4496
4528
  const scanEvents = (node) => {
4497
4529
  if (!Array.isArray(node))
@@ -4533,7 +4565,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4533
4565
  }
4534
4566
  for (const { name, func } of methods) {
4535
4567
  if (Array.isArray(func) && (func[0] === "->" || func[0] === "=>")) {
4536
- const [, params, methodBody] = func;
4568
+ let [, params, methodBody] = func;
4569
+ if ((!params || Array.isArray(params) && params.length === 0) && this.containsIt(methodBody))
4570
+ params = ["it"];
4537
4571
  let paramStr = Array.isArray(params) ? params.map((p) => this.formatParam(p)).join(", ") : "";
4538
4572
  const boundEvent = eventMethodTypes.get(name);
4539
4573
  if (boundEvent && Array.isArray(params) && params.length > 0) {
@@ -4669,7 +4703,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4669
4703
  constructions.push(` };`);
4670
4704
  }
4671
4705
  }
4672
- } else if (typeof head2 === "string" && head2 !== "object" && head2 !== "switch" && TEMPLATE_TAGS.has(head2.split(/[.#]/)[0])) {
4706
+ } else if (typeof head2 === "string" && head2 !== "object" && head2 !== "switch" && (TEMPLATE_TAGS.has(head2.split(/[.#]/)[0]) || /^[a-z]/.test(head2) && node.length > 1 && Array.isArray(node[1]) && (node[1][0] === "->" || node[1][0] === "=>"))) {
4673
4707
  const tagName = head2.split(/[.#]/)[0];
4674
4708
  const iProps = extractIntrinsicProps(node.slice(1));
4675
4709
  const tagLine = node.loc?.r;
@@ -4788,7 +4822,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4788
4822
  lines.push(" for (const key in this._rest) this._applyInheritedProp(this._inheritedEl, key, this._rest[key]);");
4789
4823
  lines.push(" }");
4790
4824
  lines.push(" _applyInheritedProp(el, key, value) {");
4791
- lines.push(" if (!el || key === 'key' || key === 'ref' || key.startsWith('__bind_')) return;");
4825
+ lines.push(" if (!el || key === 'key' || key === 'ref' || key === 'children' || key.startsWith('__bind_')) return;");
4792
4826
  lines.push(" if (key[0] === '@') {");
4793
4827
  lines.push(" const event = key.slice(1).split('.')[0];");
4794
4828
  lines.push(" this._restHandlers || (this._restHandlers = {});");
@@ -4834,7 +4868,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4834
4868
  }
4835
4869
  for (const { name, func } of methods) {
4836
4870
  if (Array.isArray(func) && (func[0] === "->" || func[0] === "=>")) {
4837
- const [, params, methodBody] = func;
4871
+ let [, params, methodBody] = func;
4872
+ if ((!params || Array.isArray(params) && params.length === 0) && this.containsIt(methodBody))
4873
+ params = ["it"];
4838
4874
  const paramStr = Array.isArray(params) ? params.map((p) => this.formatParam(p)).join(", ") : "";
4839
4875
  const transformed = this.reactiveMembers ? this.transformComponentMembers(methodBody) : methodBody;
4840
4876
  const isAsync = this.containsAwait(methodBody);
@@ -5029,6 +5065,30 @@ ${blockFactoriesCode}return ${lines.join(`
5029
5065
  this._createLines.push(`${slotVar} = ${s}.children instanceof Node ? ${s}.children : (${s}.children != null ? document.createTextNode(String(${s}.children)) : document.createComment(''));`);
5030
5066
  return slotVar;
5031
5067
  }
5068
+ if (headStr === "switch") {
5069
+ const disc = rest[0];
5070
+ const whens = rest[1] || [];
5071
+ const defaultCase = rest[2] || null;
5072
+ let chain = defaultCase;
5073
+ for (let i = whens.length - 1;i >= 0; i--) {
5074
+ const [, tests, body] = whens[i];
5075
+ let cond;
5076
+ if (disc === null) {
5077
+ cond = tests.length === 1 ? tests[0] : tests.reduce((a, t) => a ? ["||", a, t] : t, null);
5078
+ } else {
5079
+ cond = tests.length === 1 ? ["==", disc, tests[0]] : tests.map((t) => ["==", disc, t]).reduce((a, c) => a ? ["||", a, c] : c, null);
5080
+ }
5081
+ chain = ["if", cond, body, chain];
5082
+ }
5083
+ if (chain) {
5084
+ if (Array.isArray(chain) && chain[0] === "if")
5085
+ return this.generateConditional(chain);
5086
+ return this.generateTemplateBlock(chain);
5087
+ }
5088
+ const cv = this.newElementVar("c");
5089
+ this._createLines.push(`${cv} = document.createComment('switch');`);
5090
+ return cv;
5091
+ }
5032
5092
  if (headStr && this.isHtmlTag(headStr) && !meta(head, "text")) {
5033
5093
  let [tagName, id] = headStr.split("#");
5034
5094
  return this.generateTag(tagName || "div", [], rest, id);
@@ -6482,15 +6542,23 @@ if (typeof globalThis !== 'undefined') {
6482
6542
  collectSubExprs(node, result) {
6483
6543
  if (!Array.isArray(node))
6484
6544
  return;
6545
+ let head = node[0];
6546
+ if (Array.isArray(head) || head != null && typeof head !== "string" && !(head instanceof String)) {
6547
+ for (let i = 0;i < node.length; i++) {
6548
+ if (Array.isArray(node[i]))
6549
+ this.collectSubExprs(node[i], result);
6550
+ }
6551
+ return;
6552
+ }
6485
6553
  if (node.loc) {
6486
- let head = str(node[0]);
6554
+ head = str(head);
6487
6555
  let ident = null;
6488
- if (typeof head === "string" && /^[=+\-*/%<>!&|?~^]|^\.\.?$|^def$|^class$|^state$|^computed$|^readonly$|^for-/.test(head)) {
6489
- if (typeof node[1] === "string" && /^[a-zA-Z_$]/.test(node[1]))
6490
- ident = node[1];
6491
- } else if (head === ".") {
6556
+ if (head === ".") {
6492
6557
  if (typeof node[2] === "string")
6493
6558
  ident = node[2];
6559
+ } else if (typeof head === "string" && /^[=+\-*/%<>!&|?~^]|^\.\.?$|^def$|^class$|^state$|^computed$|^readonly$|^for-/.test(head)) {
6560
+ if (typeof node[1] === "string" && /^[a-zA-Z_$]/.test(node[1]))
6561
+ ident = node[1];
6494
6562
  } else if (typeof head === "string" && /^[a-zA-Z_$]/.test(head)) {
6495
6563
  ident = head;
6496
6564
  }
@@ -6531,6 +6599,8 @@ if (typeof globalThis !== 'undefined') {
6531
6599
  }
6532
6600
  if (head === "component")
6533
6601
  return;
6602
+ if (head === "enum")
6603
+ return;
6534
6604
  if (CodeGenerator.ASSIGNMENT_OPS.has(head)) {
6535
6605
  let [target, value] = rest;
6536
6606
  if (typeof target === "string" || target instanceof String) {
@@ -8218,6 +8288,14 @@ ${this.indent()}}`;
8218
8288
  }
8219
8289
  if (this.options.skipImports)
8220
8290
  return "";
8291
+ if (rest.length === 3) {
8292
+ let [def, named, source2] = rest;
8293
+ let fixedSource2 = this.addJsExtensionAndAssertions(source2);
8294
+ if (named[0] === "*" && named.length === 2)
8295
+ return `import ${def}, * as ${named[1]} from ${fixedSource2}`;
8296
+ let names = named.map((i) => Array.isArray(i) && i.length === 2 ? `${i[0]} as ${i[1]}` : i).join(", ");
8297
+ return `import ${def}, { ${names} } from ${fixedSource2}`;
8298
+ }
8221
8299
  let [specifier, source] = rest;
8222
8300
  let fixedSource = this.addJsExtensionAndAssertions(source);
8223
8301
  if (typeof specifier === "string")
@@ -8225,13 +8303,6 @@ ${this.indent()}}`;
8225
8303
  if (Array.isArray(specifier)) {
8226
8304
  if (specifier[0] === "*" && specifier.length === 2)
8227
8305
  return `import * as ${specifier[1]} from ${fixedSource}`;
8228
- if (typeof specifier[0] === "string" && Array.isArray(specifier[1])) {
8229
- let def = specifier[0], second = specifier[1];
8230
- if (second[0] === "*" && second.length === 2)
8231
- return `import ${def}, * as ${second[1]} from ${fixedSource}`;
8232
- let names2 = (Array.isArray(second) ? second : [second]).map((i) => Array.isArray(i) && i.length === 2 ? `${i[0]} as ${i[1]}` : i).join(", ");
8233
- return `import ${def}, { ${names2} } from ${fixedSource}`;
8234
- }
8235
8306
  let names = specifier.map((i) => Array.isArray(i) && i.length === 2 ? `${i[0]} as ${i[1]}` : i).join(", ");
8236
8307
  return `import { ${names} } from ${fixedSource}`;
8237
8308
  }
@@ -9663,8 +9734,8 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
9663
9734
  return new CodeGenerator({}).getComponentRuntime();
9664
9735
  }
9665
9736
  // src/browser.js
9666
- var VERSION = "3.13.119";
9667
- var BUILD_DATE = "2026-03-14@11:16:29GMT";
9737
+ var VERSION = "3.13.121";
9738
+ var BUILD_DATE = "2026-03-17@16:10:50GMT";
9668
9739
  if (typeof globalThis !== "undefined") {
9669
9740
  if (!globalThis.__rip)
9670
9741
  new Function(getReactiveRuntime())();
@@ -9967,11 +10038,14 @@ ${indented}`);
9967
10038
  var __state;
9968
10039
  var _ariaBindDialog;
9969
10040
  var _ariaBindPopover;
10041
+ var _ariaHasAnchor;
9970
10042
  var _ariaListNav;
9971
10043
  var _ariaLockScroll;
9972
10044
  var _ariaModalStack;
9973
10045
  var _ariaNAV;
9974
10046
  var _ariaPopupDismiss;
10047
+ var _ariaPopupGuard;
10048
+ var _ariaPosition;
9975
10049
  var _ariaPositionBelow;
9976
10050
  var _ariaRovingNav;
9977
10051
  var _ariaTrapFocus;
@@ -11149,8 +11223,17 @@ ${indented}`);
11149
11223
  return window.removeEventListener("scroll", onScroll, true);
11150
11224
  };
11151
11225
  };
11226
+ _ariaPopupGuard = function(delay2 = 250) {
11227
+ let blockedUntil;
11228
+ blockedUntil = 0;
11229
+ return { block: function(ms = delay2) {
11230
+ return blockedUntil = Date.now() + ms;
11231
+ }, canOpen: function() {
11232
+ return Date.now() >= blockedUntil;
11233
+ } };
11234
+ };
11152
11235
  _ariaBindPopover = function(open, popover, setOpen, source = null) {
11153
- let currentFocus, desired, el, get, onToggle, opts, restoreEl, restoreFocus, shown, src;
11236
+ let currentFocus, desired, el, get, onToggle, opts, restoreEl, restoreFocus, shown, src, syncState;
11154
11237
  get = function(x) {
11155
11238
  return typeof x === "function" ? x() : x;
11156
11239
  };
@@ -11170,6 +11253,21 @@ ${indented}`);
11170
11253
  if (!Object.hasOwn(HTMLElement.prototype, "togglePopover"))
11171
11254
  return;
11172
11255
  restoreEl = null;
11256
+ syncState = function(isOpen) {
11257
+ if (isOpen) {
11258
+ el.hidden = false;
11259
+ try {
11260
+ el.inert = false;
11261
+ } catch {}
11262
+ return el.removeAttribute("aria-hidden");
11263
+ } else {
11264
+ try {
11265
+ el.inert = true;
11266
+ } catch {}
11267
+ el.setAttribute("aria-hidden", "true");
11268
+ return el.hidden = true;
11269
+ }
11270
+ };
11173
11271
  restoreFocus = function() {
11174
11272
  let focusAttempt, target;
11175
11273
  target = restoreEl;
@@ -11199,7 +11297,9 @@ ${indented}`);
11199
11297
  isOpen = e.newState === "open";
11200
11298
  if (isOpen) {
11201
11299
  restoreEl = get(source) || currentFocus();
11300
+ syncState(true);
11202
11301
  } else {
11302
+ syncState(false);
11203
11303
  restoreFocus();
11204
11304
  }
11205
11305
  return setOpen?.(isOpen);
@@ -11211,18 +11311,21 @@ ${indented}`);
11211
11311
  src = get(source);
11212
11312
  if (desired) {
11213
11313
  restoreEl = src || currentFocus();
11314
+ syncState(true);
11214
11315
  }
11215
11316
  opts = src && desired ? { force: desired, source: src } : { force: desired };
11216
11317
  try {
11217
11318
  el.togglePopover(opts);
11218
11319
  } catch {}
11320
+ } else {
11321
+ syncState(desired);
11219
11322
  }
11220
11323
  return function() {
11221
11324
  return el.removeEventListener("toggle", onToggle);
11222
11325
  };
11223
11326
  };
11224
11327
  _ariaBindDialog = function(open, dialog, setOpen, dismissable = true) {
11225
- let currentFocus, el, get, onCancel, onClose, restoreEl, restoreFocus;
11328
+ let currentFocus, el, get, onCancel, onClose, restoreEl, restoreFocus, syncState;
11226
11329
  get = function(x) {
11227
11330
  return typeof x === "function" ? x() : x;
11228
11331
  };
@@ -11240,6 +11343,21 @@ ${indented}`);
11240
11343
  if (!el?.showModal)
11241
11344
  return;
11242
11345
  restoreEl = null;
11346
+ syncState = function(isOpen) {
11347
+ if (isOpen) {
11348
+ el.hidden = false;
11349
+ try {
11350
+ el.inert = false;
11351
+ } catch {}
11352
+ return el.removeAttribute("aria-hidden");
11353
+ } else {
11354
+ try {
11355
+ el.inert = true;
11356
+ } catch {}
11357
+ el.setAttribute("aria-hidden", "true");
11358
+ return el.hidden = true;
11359
+ }
11360
+ };
11243
11361
  restoreFocus = function() {
11244
11362
  let focusAttempt, target;
11245
11363
  target = restoreEl;
@@ -11273,6 +11391,7 @@ ${indented}`);
11273
11391
  };
11274
11392
  onClose = function() {
11275
11393
  setOpen?.(false);
11394
+ syncState(false);
11276
11395
  return restoreFocus();
11277
11396
  };
11278
11397
  el.addEventListener("cancel", onCancel);
@@ -11280,12 +11399,14 @@ ${indented}`);
11280
11399
  if (open && !el.open) {
11281
11400
  if (!restoreEl)
11282
11401
  restoreEl = currentFocus();
11402
+ syncState(true);
11283
11403
  try {
11284
11404
  el.showModal();
11285
11405
  } catch {}
11286
- }
11287
- if (!open && el.open) {
11406
+ } else if (!open && el.open) {
11288
11407
  el.close();
11408
+ } else {
11409
+ syncState(!!open);
11289
11410
  }
11290
11411
  return function() {
11291
11412
  el.removeEventListener("cancel", onCancel);
@@ -11402,7 +11523,116 @@ ${indented}`);
11402
11523
  return window.scrollTo(0, scrollY);
11403
11524
  }
11404
11525
  };
11405
- globalThis.__aria ??= { listNav: _ariaListNav, rovingNav: _ariaRovingNav, popupDismiss: _ariaPopupDismiss, bindPopover: _ariaBindPopover, bindDialog: _ariaBindDialog, positionBelow: _ariaPositionBelow, trapFocus: _ariaTrapFocus, wireAria: _ariaWireAria, lockScroll: _ariaLockScroll, unlockScroll: _ariaUnlockScroll };
11526
+ _ariaHasAnchor = function() {
11527
+ let anchor, floating, rect;
11528
+ return (() => {
11529
+ try {
11530
+ if (!document?.createElement)
11531
+ return false;
11532
+ anchor = document.createElement("div");
11533
+ floating = document.createElement("div");
11534
+ anchor.style.cssText = "position:fixed;top:100px;left:100px;width:10px;height:10px;anchor-name:--probe";
11535
+ floating.style.cssText = "position:fixed;inset:auto;margin:0;position-anchor:--probe;position-area:bottom start;width:10px;height:10px";
11536
+ document.body.appendChild(anchor);
11537
+ document.body.appendChild(floating);
11538
+ rect = floating.getBoundingClientRect();
11539
+ anchor.remove();
11540
+ floating.remove();
11541
+ return rect.top > 50;
11542
+ } catch {
11543
+ return false;
11544
+ }
11545
+ })();
11546
+ }();
11547
+ _ariaPosition = function(trigger, floating, opts = {}) {
11548
+ let align, matchWidth, name, offset, placement, rect, side;
11549
+ if (!(trigger && floating))
11550
+ return;
11551
+ placement = opts.placement ?? "bottom start";
11552
+ offset = opts.offset ?? 4;
11553
+ matchWidth = opts.matchWidth ?? false;
11554
+ if (_ariaHasAnchor) {
11555
+ name = `--anchor-${floating.id || Math.random().toString(36).slice(2, 8)}`;
11556
+ trigger.style.anchorName = name;
11557
+ floating.style.positionAnchor = name;
11558
+ floating.style.position = "fixed";
11559
+ floating.style.inset = "auto";
11560
+ floating.style.margin = "0";
11561
+ floating.style.positionArea = placement;
11562
+ floating.style.positionTry = "flip-block, flip-inline, flip-block flip-inline";
11563
+ floating.style.positionVisibility = "anchors-visible";
11564
+ [side] = placement.split(" ");
11565
+ floating.style.marginTop = "";
11566
+ floating.style.marginBottom = "";
11567
+ floating.style.marginLeft = "";
11568
+ floating.style.marginRight = "";
11569
+ switch (side) {
11570
+ case "bottom":
11571
+ floating.style.marginTop = `${offset}px`;
11572
+ break;
11573
+ case "top":
11574
+ floating.style.marginBottom = `${offset}px`;
11575
+ break;
11576
+ case "left":
11577
+ floating.style.marginRight = `${offset}px`;
11578
+ break;
11579
+ case "right":
11580
+ floating.style.marginLeft = `${offset}px`;
11581
+ break;
11582
+ }
11583
+ return matchWidth ? floating.style.minWidth = "anchor-size(width)" : undefined;
11584
+ } else {
11585
+ rect = trigger.getBoundingClientRect();
11586
+ floating.style.position = "fixed";
11587
+ floating.style.inset = "auto";
11588
+ floating.style.margin = "0";
11589
+ [side, align] = placement.split(" ");
11590
+ align ??= "start";
11591
+ switch (side) {
11592
+ case "bottom":
11593
+ floating.style.top = `${rect.bottom + offset}px`;
11594
+ break;
11595
+ case "top":
11596
+ floating.style.bottom = `${window.innerHeight - rect.top + offset}px`;
11597
+ break;
11598
+ case "left":
11599
+ floating.style.right = `${window.innerWidth - rect.left + offset}px`;
11600
+ break;
11601
+ case "right":
11602
+ floating.style.left = `${rect.right + offset}px`;
11603
+ break;
11604
+ }
11605
+ if (Array.isArray(["bottom", "top"]) ? ["bottom", "top"].includes(side) : (side in ["bottom", "top"])) {
11606
+ switch (align) {
11607
+ case "start":
11608
+ floating.style.left = `${rect.left}px`;
11609
+ break;
11610
+ case "center":
11611
+ floating.style.left = `${rect.left + rect.width / 2}px`;
11612
+ floating.style.transform = "translateX(-50%)";
11613
+ break;
11614
+ case "end":
11615
+ floating.style.right = `${window.innerWidth - rect.right}px`;
11616
+ break;
11617
+ }
11618
+ } else {
11619
+ switch (align) {
11620
+ case "start":
11621
+ floating.style.top = `${rect.top}px`;
11622
+ break;
11623
+ case "center":
11624
+ floating.style.top = `${rect.top + rect.height / 2}px`;
11625
+ floating.style.transform = "translateY(-50%)";
11626
+ break;
11627
+ case "end":
11628
+ floating.style.bottom = `${window.innerHeight - rect.bottom}px`;
11629
+ break;
11630
+ }
11631
+ }
11632
+ return matchWidth ? floating.style.minWidth = `${rect.width}px` : undefined;
11633
+ }
11634
+ };
11635
+ globalThis.__aria ??= { listNav: _ariaListNav, rovingNav: _ariaRovingNav, popupDismiss: _ariaPopupDismiss, popupGuard: _ariaPopupGuard, bindPopover: _ariaBindPopover, bindDialog: _ariaBindDialog, positionBelow: _ariaPositionBelow, trapFocus: _ariaTrapFocus, wireAria: _ariaWireAria, lockScroll: _ariaLockScroll, unlockScroll: _ariaUnlockScroll, position: _ariaPosition, hasAnchor: _ariaHasAnchor };
11406
11636
  globalThis.ARIA ??= globalThis.__aria;
11407
11637
 
11408
11638
  // docs/dist/_entry.js