stimeo-ui 0.5.0 → 0.6.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/controllers/aspect_ratio_controller.d.ts +1 -3
  3. package/dist/controllers/aspect_ratio_controller.js +19 -11
  4. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  5. package/dist/controllers/avatar_controller.d.ts +36 -15
  6. package/dist/controllers/avatar_controller.js +195 -40
  7. package/dist/controllers/avatar_controller.js.map +1 -1
  8. package/dist/controllers/carousel_controller.d.ts +12 -3
  9. package/dist/controllers/carousel_controller.js +85 -9
  10. package/dist/controllers/carousel_controller.js.map +1 -1
  11. package/dist/controllers/checkbox_controller.d.ts +31 -5
  12. package/dist/controllers/checkbox_controller.js +136 -25
  13. package/dist/controllers/checkbox_controller.js.map +1 -1
  14. package/dist/controllers/color_picker_controller.d.ts +7 -1
  15. package/dist/controllers/color_picker_controller.js +35 -9
  16. package/dist/controllers/color_picker_controller.js.map +1 -1
  17. package/dist/controllers/date_range_picker_controller.d.ts +23 -4
  18. package/dist/controllers/date_range_picker_controller.js +157 -30
  19. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  20. package/dist/controllers/file_dropzone_controller.d.ts +7 -1
  21. package/dist/controllers/file_dropzone_controller.js +26 -3
  22. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  23. package/dist/controllers/focus_controller.d.ts +2 -3
  24. package/dist/controllers/focus_controller.js.map +1 -1
  25. package/dist/controllers/hover_card_controller.d.ts +2 -2
  26. package/dist/controllers/hover_card_controller.js.map +1 -1
  27. package/dist/controllers/idle_controller.d.ts +3 -3
  28. package/dist/controllers/idle_controller.js +27 -5
  29. package/dist/controllers/idle_controller.js.map +1 -1
  30. package/dist/controllers/menubar_controller.js +5 -3
  31. package/dist/controllers/menubar_controller.js.map +1 -1
  32. package/dist/controllers/multi_select_controller.d.ts +46 -12
  33. package/dist/controllers/multi_select_controller.js +460 -151
  34. package/dist/controllers/multi_select_controller.js.map +1 -1
  35. package/dist/controllers/number_input_controller.d.ts +24 -6
  36. package/dist/controllers/number_input_controller.js +275 -51
  37. package/dist/controllers/number_input_controller.js.map +1 -1
  38. package/dist/controllers/overflow_menu_controller.js +4 -0
  39. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  40. package/dist/controllers/pagination_controller.js +33 -0
  41. package/dist/controllers/pagination_controller.js.map +1 -1
  42. package/dist/controllers/password_strength_controller.d.ts +3 -3
  43. package/dist/controllers/password_strength_controller.js +20 -2
  44. package/dist/controllers/password_strength_controller.js.map +1 -1
  45. package/dist/controllers/persist_controller.d.ts +4 -4
  46. package/dist/controllers/persist_controller.js +24 -5
  47. package/dist/controllers/persist_controller.js.map +1 -1
  48. package/dist/controllers/popover_controller.d.ts +2 -2
  49. package/dist/controllers/popover_controller.js.map +1 -1
  50. package/dist/controllers/portal_controller.d.ts +1 -2
  51. package/dist/controllers/portal_controller.js.map +1 -1
  52. package/dist/controllers/radio_group_controller.d.ts +41 -15
  53. package/dist/controllers/radio_group_controller.js +540 -56
  54. package/dist/controllers/radio_group_controller.js.map +1 -1
  55. package/dist/controllers/rating_controller.d.ts +36 -31
  56. package/dist/controllers/rating_controller.js +272 -89
  57. package/dist/controllers/rating_controller.js.map +1 -1
  58. package/dist/controllers/resizable_controller.js +33 -0
  59. package/dist/controllers/resizable_controller.js.map +1 -1
  60. package/dist/controllers/roving_controller.d.ts +4 -0
  61. package/dist/controllers/roving_controller.js +60 -5
  62. package/dist/controllers/roving_controller.js.map +1 -1
  63. package/dist/controllers/scroll_area_controller.d.ts +6 -0
  64. package/dist/controllers/scroll_area_controller.js +154 -22
  65. package/dist/controllers/scroll_area_controller.js.map +1 -1
  66. package/dist/controllers/scroll_visibility_controller.js +33 -0
  67. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  68. package/dist/controllers/tags_input_controller.d.ts +41 -11
  69. package/dist/controllers/tags_input_controller.js +356 -120
  70. package/dist/controllers/tags_input_controller.js.map +1 -1
  71. package/dist/controllers/time_picker_controller.d.ts +42 -13
  72. package/dist/controllers/time_picker_controller.js +296 -107
  73. package/dist/controllers/time_picker_controller.js.map +1 -1
  74. package/dist/controllers/toggle_group_controller.d.ts +39 -13
  75. package/dist/controllers/toggle_group_controller.js +378 -55
  76. package/dist/controllers/toggle_group_controller.js.map +1 -1
  77. package/dist/controllers/toolbar_controller.js +5 -3
  78. package/dist/controllers/toolbar_controller.js.map +1 -1
  79. package/dist/controllers/tooltip_controller.d.ts +2 -2
  80. package/dist/controllers/tooltip_controller.js.map +1 -1
  81. package/dist/controllers/transition_controller.d.ts +2 -3
  82. package/dist/controllers/transition_controller.js.map +1 -1
  83. package/dist/controllers/tree_view_controller.js +5 -3
  84. package/dist/controllers/tree_view_controller.js.map +1 -1
  85. package/dist/index.js +2637 -781
  86. package/dist/index.js.map +1 -1
  87. package/dist/inspector/cli.d.ts +16 -3
  88. package/dist/inspector/cli.js +22 -6
  89. package/dist/inspector/cli.js.map +1 -1
  90. package/dist/inspector/cli_bin.js +22 -6
  91. package/dist/inspector/cli_bin.js.map +1 -1
  92. package/dist/inspector/examples.json +8 -8
  93. package/dist/inspector/manifest.json +169 -37
  94. package/dist/positioning/index.d.ts +2 -2
  95. package/dist/positioning/index.js.map +1 -1
  96. package/package.json +1 -1
@@ -227,9 +227,11 @@ interface DocumentCondition {
227
227
  * A single accessibility requirement on a controller's markup (Inspector
228
228
  * stage 3). At least one of {@link attrs} must be present on the
229
229
  * {@link target} element; when {@link values} is given, the present
230
- * attribute's value must be one of them. {@link or} widens the requirement
231
- * with alternative attribute/value groups — the requirement is satisfied when
232
- * *any* group is (e.g. `role="status"` **or** `aria-live`).
230
+ * attribute's value must be one of them, and when it is not, the value must be
231
+ * non-empty — ARIA derives no name from `aria-label=""`, so an empty value
232
+ * leaves the requirement unmet. {@link or} widens the requirement with
233
+ * alternative attribute/value groups — the requirement is satisfied when *any*
234
+ * group is (e.g. `role="status"` **or** `aria-live`).
233
235
  */
234
236
  interface A11yRequirement {
235
237
  /**
@@ -597,6 +599,15 @@ interface ConditionalTargetRule {
597
599
  readonly whenPresent: string;
598
600
  /** Targets that become required once {@link whenPresent} appears. */
599
601
  readonly require: readonly string[];
602
+ /**
603
+ * Require each {@link require} entry to sit **inside** the `whenPresent`
604
+ * element rather than anywhere in the scope.
605
+ *
606
+ * A `<template>` is cloned at runtime, so a part declared outside it never
607
+ * reaches the clone. Without this the presence check passes on markup the
608
+ * controller then refuses to build from.
609
+ */
610
+ readonly requireInside?: boolean;
600
611
  /** Human-readable fix suggestion shown by the CLI (stage 4). */
601
612
  readonly suggestion: string;
602
613
  }
@@ -616,6 +627,8 @@ interface ValueConstraint {
616
627
  readonly finite?: boolean;
617
628
  /** Require a decoded number strictly greater than this bound. */
618
629
  readonly greaterThan?: number;
630
+ /** Require a decoded number with no fractional part. */
631
+ readonly integer?: boolean;
619
632
  /** Human-readable fix suggestion shown by the CLI (stage 4). */
620
633
  readonly suggestion: string;
621
634
  }
@@ -967,6 +967,12 @@ var DIAGNOSTIC_CODES = [
967
967
  ];
968
968
 
969
969
  // src/inspector/check.ts
970
+ function isInside(node, ancestor) {
971
+ for (let current = node.parent; current; current = current.parent) {
972
+ if (current === ancestor) return true;
973
+ }
974
+ return false;
975
+ }
970
976
  function checkSource(source, manifest) {
971
977
  const diagnostics = [];
972
978
  const tree = parseHtml(neutralizeErb(source), erbElements(source));
@@ -1364,13 +1370,16 @@ function checkSource(source, manifest) {
1364
1370
  const present = presence.get(node)?.get(identifier) ?? /* @__PURE__ */ new Set();
1365
1371
  for (const rule of controller.conditionalTargets) {
1366
1372
  if (!present.has(rule.whenPresent)) continue;
1367
- const missing = rule.require.filter((target) => !present.has(target));
1373
+ const nodesOf = (target) => targetNodes.get(node)?.get(identifier)?.get(target) ?? [];
1374
+ const owners = nodesOf(rule.whenPresent);
1375
+ const satisfied = (target) => rule.requireInside ? nodesOf(target).some((el) => owners.some((owner) => isInside(el, owner))) : present.has(target);
1376
+ const missing = rule.require.filter((target) => !satisfied(target));
1368
1377
  if (missing.length === 0) continue;
1369
1378
  report(
1370
1379
  node,
1371
1380
  "missing-conditional-target",
1372
1381
  complete ? "error" : "warning",
1373
- `"${identifier}" has a "${rule.whenPresent}" target, which also requires ${list(missing)}.`,
1382
+ rule.requireInside ? `"${identifier}" requires ${list(missing)} inside its "${rule.whenPresent}".` : `"${identifier}" has a "${rule.whenPresent}" target, which also requires ${list(missing)}.`,
1374
1383
  node,
1375
1384
  complete ? rule.suggestion : UNRESOLVED_TARGET_HINT
1376
1385
  );
@@ -1388,7 +1397,7 @@ function checkSource(source, manifest) {
1388
1397
  if (!hasReadableMarkup(el)) continue;
1389
1398
  if (!contentHolds(node, identifier, el, req.whenContains)) continue;
1390
1399
  if (!elementHolds(el, req.whenElement)) continue;
1391
- checkA11y(report, el, identifier, req, severity);
1400
+ checkA11y(report, el, identifier, req, severity, isDynamicValue);
1392
1401
  }
1393
1402
  }
1394
1403
  }
@@ -1682,6 +1691,7 @@ function valueSatisfiesConstraint(raw, constraint) {
1682
1691
  if (Number.isNaN(value)) return false;
1683
1692
  if (constraint.finite && !Number.isFinite(value)) return false;
1684
1693
  if (constraint.greaterThan !== void 0 && !(value > constraint.greaterThan)) return false;
1694
+ if (constraint.integer && !Number.isInteger(value)) return false;
1685
1695
  return true;
1686
1696
  }
1687
1697
  function decodeNumericValue(raw) {
@@ -1692,6 +1702,7 @@ function describeValueConstraint(constraint) {
1692
1702
  if (constraint.greaterThan !== void 0) {
1693
1703
  parts.push(`greater than ${constraint.greaterThan}`);
1694
1704
  }
1705
+ if (constraint.integer) parts.push("with no fractional part");
1695
1706
  return parts.join(" ");
1696
1707
  }
1697
1708
  var UNRESOLVED_TARGET_HINT = "Part of this scope is rendered by a helper or a non-literal data: hash, so the target may exist at runtime.";
@@ -1699,7 +1710,7 @@ var UNRESOLVED_HOST_HINT = "An enclosing helper's data: option is not a literal
1699
1710
  function hasReadableMarkup(el) {
1700
1711
  return el.origin === "markup";
1701
1712
  }
1702
- function checkA11y(report, el, identifier, req, severity) {
1713
+ function checkA11y(report, el, identifier, req, severity, isDynamicValue) {
1703
1714
  const groups = [
1704
1715
  { attrs: req.attrs, values: req.values },
1705
1716
  ...req.or ?? []
@@ -1719,9 +1730,14 @@ function checkA11y(report, el, identifier, req, severity) {
1719
1730
  }
1720
1731
  const invalid = [];
1721
1732
  let anyPresent = false;
1733
+ let blank;
1722
1734
  for (const [name, allowed] of allowedByAttr) {
1723
1735
  const attr = el.attrs.find((a) => a.name === name);
1724
1736
  if (!attr) continue;
1737
+ if (allowed.anyValue && attr.value.trim() === "" && !isDynamicValue(attr)) {
1738
+ blank ??= attr;
1739
+ continue;
1740
+ }
1725
1741
  anyPresent = true;
1726
1742
  if (!allowed.anyValue && !allowed.values.has(attr.value.trim())) {
1727
1743
  invalid.push({ attr, values: [...allowed.values] });
@@ -1733,8 +1749,8 @@ function checkA11y(report, el, identifier, req, severity) {
1733
1749
  el,
1734
1750
  "missing-aria",
1735
1751
  severity,
1736
- `"${identifier}" ${verb} ${describeAttrs([...allowedByAttr.keys()])} on its ${where}.`,
1737
- el,
1752
+ blank ? `${blank.name} is empty on the ${where} of "${identifier}", which ${verb} a value there.` : `"${identifier}" ${verb} ${describeAttrs([...allowedByAttr.keys()])} on its ${where}.`,
1753
+ blank ?? el,
1738
1754
  req.suggestion
1739
1755
  );
1740
1756
  return;