@fusion.dev/helix-core 0.0.0-dev

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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/custom-elements.json +8005 -0
  3. package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +67 -0
  4. package/dist/controllers/aria-forward-controller/aria-forward-controller.js +146 -0
  5. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +79 -0
  6. package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +140 -0
  7. package/dist/controllers/command-controller/command-controller.d.ts +83 -0
  8. package/dist/controllers/command-controller/command-controller.js +93 -0
  9. package/dist/controllers/copy-controller/copy-controller.d.ts +58 -0
  10. package/dist/controllers/copy-controller/copy-controller.js +128 -0
  11. package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.d.ts +76 -0
  12. package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.js +67 -0
  13. package/dist/controllers/dismiss-controller/dismiss-controller.d.ts +58 -0
  14. package/dist/controllers/dismiss-controller/dismiss-controller.js +165 -0
  15. package/dist/controllers/drilldown-controller/drilldown-controller.d.ts +127 -0
  16. package/dist/controllers/drilldown-controller/drilldown-controller.js +171 -0
  17. package/dist/controllers/floating-controller/floating-controller.d.ts +123 -0
  18. package/dist/controllers/floating-controller/floating-controller.js +227 -0
  19. package/dist/controllers/focus-trap-controller/focus-trap-controller.d.ts +26 -0
  20. package/dist/controllers/focus-trap-controller/focus-trap-controller.js +93 -0
  21. package/dist/controllers/indicator-controller/indicator-controller.d.ts +97 -0
  22. package/dist/controllers/indicator-controller/indicator-controller.js +164 -0
  23. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +113 -0
  24. package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +117 -0
  25. package/dist/controllers/popover-controller/popover-controller.d.ts +132 -0
  26. package/dist/controllers/popover-controller/popover-controller.js +150 -0
  27. package/dist/controllers/source-controller/source-controller.d.ts +55 -0
  28. package/dist/controllers/source-controller/source-controller.js +94 -0
  29. package/dist/controllers/token-color-controller/token-color-controller.d.ts +63 -0
  30. package/dist/controllers/token-color-controller/token-color-controller.js +105 -0
  31. package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +127 -0
  32. package/dist/controllers/virtualize-controller/virtualize-controller.js +216 -0
  33. package/dist/events/element-events.d.ts +4 -0
  34. package/dist/events/element-events.js +34 -0
  35. package/dist/events/events.d.ts +743 -0
  36. package/dist/events/events.js +799 -0
  37. package/dist/helix-element/helix-element.d.ts +201 -0
  38. package/dist/helix-element/helix-element.js +695 -0
  39. package/dist/helix-form-element/helix-form-element.d.ts +152 -0
  40. package/dist/helix-form-element/helix-form-element.js +194 -0
  41. package/dist/index.d.ts +54 -0
  42. package/dist/index.js +54 -0
  43. package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +137 -0
  44. package/dist/mixins/mixin-chart-source/mixin-chart-source.js +140 -0
  45. package/dist/mixins/mixin-collection/index.d.ts +1 -0
  46. package/dist/mixins/mixin-collection/index.js +1 -0
  47. package/dist/mixins/mixin-collection/mixin-collection.d.ts +58 -0
  48. package/dist/mixins/mixin-collection/mixin-collection.js +154 -0
  49. package/dist/mixins/mixin-controller-active/mixin-controller-active.d.ts +53 -0
  50. package/dist/mixins/mixin-controller-active/mixin-controller-active.js +155 -0
  51. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +54 -0
  52. package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +157 -0
  53. package/dist/mixins/mixin-controller-open/mixin-controller-open.d.ts +49 -0
  54. package/dist/mixins/mixin-controller-open/mixin-controller-open.js +176 -0
  55. package/dist/mixins/mixin-controller-value/mixin-controller-value.d.ts +73 -0
  56. package/dist/mixins/mixin-controller-value/mixin-controller-value.js +173 -0
  57. package/dist/mixins/mixin-dismissible/mixin-dismissible.d.ts +41 -0
  58. package/dist/mixins/mixin-dismissible/mixin-dismissible.js +79 -0
  59. package/dist/mixins/mixin-field/mixin-field.d.ts +145 -0
  60. package/dist/mixins/mixin-field/mixin-field.js +423 -0
  61. package/dist/utils/anchor-element/anchor-element.d.ts +23 -0
  62. package/dist/utils/anchor-element/anchor-element.js +39 -0
  63. package/dist/utils/capture-pointer/capture-pointer.d.ts +22 -0
  64. package/dist/utils/capture-pointer/capture-pointer.js +30 -0
  65. package/dist/utils/closest-instance/closest-instance.d.ts +25 -0
  66. package/dist/utils/closest-instance/closest-instance.js +34 -0
  67. package/dist/utils/create-sheet/create-sheet.d.ts +16 -0
  68. package/dist/utils/create-sheet/create-sheet.js +16 -0
  69. package/dist/utils/custom-element/custom-element.d.ts +26 -0
  70. package/dist/utils/custom-element/custom-element.js +114 -0
  71. package/dist/utils/draw-icon/draw-icon.d.ts +38 -0
  72. package/dist/utils/draw-icon/draw-icon.js +39 -0
  73. package/dist/utils/draw-tooltip/draw-tooltip.d.ts +56 -0
  74. package/dist/utils/draw-tooltip/draw-tooltip.js +89 -0
  75. package/dist/utils/elapsed-time/elapsed-time.d.ts +10 -0
  76. package/dist/utils/elapsed-time/elapsed-time.js +117 -0
  77. package/dist/utils/focusable-elements/focusable-elements.d.ts +40 -0
  78. package/dist/utils/focusable-elements/focusable-elements.js +88 -0
  79. package/dist/utils/format-numbers/format-numbers.d.ts +1 -0
  80. package/dist/utils/format-numbers/format-numbers.js +29 -0
  81. package/dist/utils/host-aria/host-aria.d.ts +38 -0
  82. package/dist/utils/host-aria/host-aria.js +41 -0
  83. package/dist/utils/inherit-disabled/inherit-disabled.d.ts +33 -0
  84. package/dist/utils/inherit-disabled/inherit-disabled.js +55 -0
  85. package/dist/utils/line-path/line-path.d.ts +23 -0
  86. package/dist/utils/line-path/line-path.js +107 -0
  87. package/dist/utils/on-unless-false/on-unless-false.d.ts +28 -0
  88. package/dist/utils/on-unless-false/on-unless-false.js +32 -0
  89. package/dist/utils/read-series/read-series.d.ts +78 -0
  90. package/dist/utils/read-series/read-series.js +187 -0
  91. package/dist/utils/relative-time/relative-time.d.ts +24 -0
  92. package/dist/utils/relative-time/relative-time.js +84 -0
  93. package/dist/utils/request-change/request-change.d.ts +48 -0
  94. package/dist/utils/request-change/request-change.js +7 -0
  95. package/dist/utils/resolve-active-item/resolve-active-item.d.ts +28 -0
  96. package/dist/utils/resolve-active-item/resolve-active-item.js +21 -0
  97. package/dist/utils/restore-value/restore-value.d.ts +32 -0
  98. package/dist/utils/restore-value/restore-value.js +84 -0
  99. package/dist/utils/scale/scale.d.ts +23 -0
  100. package/dist/utils/scale/scale.js +32 -0
  101. package/dist/utils/scale/ticks.d.ts +27 -0
  102. package/dist/utils/scale/ticks.js +52 -0
  103. package/dist/utils/scroll-item-into-view/scroll-item-into-view.d.ts +10 -0
  104. package/dist/utils/scroll-item-into-view/scroll-item-into-view.js +98 -0
  105. package/dist/utils/slot-filled/slot-filled.d.ts +26 -0
  106. package/dist/utils/slot-filled/slot-filled.js +26 -0
  107. package/dist/utils/tell-disclosure/tell-disclosure.d.ts +51 -0
  108. package/dist/utils/tell-disclosure/tell-disclosure.js +76 -0
  109. package/dist/utils/ticker/ticker.d.ts +8 -0
  110. package/dist/utils/ticker/ticker.js +55 -0
  111. package/dist/utils/tone-marks/tone-marks.d.ts +52 -0
  112. package/dist/utils/tone-marks/tone-marks.js +36 -0
  113. package/dist/utils/value-as/value-as.d.ts +64 -0
  114. package/dist/utils/value-as/value-as.js +105 -0
  115. package/package.json +58 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * A date or time control's string value, read as the platform reads it.
3
+ *
4
+ * **Six families needed this and none of them could have it alone.** `Date
5
+ * Input` and `Date Picker` both hold `YYYY-MM-DD`, `Time Input` and `Time
6
+ * Picker` both hold `HH:mm`, and `Number Input` and `Rating` both hold a
7
+ * number, so `valueAsDate` and `valueAsNumber` would have been four
8
+ * implementations of two conversions with four chances to disagree about what
9
+ * an invalid value returns. Here rather than in a shared folder under
10
+ * `helix/headless`, because there is no such folder and this is a pure function
11
+ * of a string: it sits beside `formatNumbers` and `relativeTime`, which are the
12
+ * same kind of thing.
13
+ *
14
+ * **UTC throughout, which is the platform's own choice and looks wrong until it
15
+ * is explained.** `<input type="date">.valueAsDate` returns midnight UTC rather
16
+ * than midnight local, so a date that is the same date everywhere does not
17
+ * become a different one by crossing a timezone. Constructing through
18
+ * `new Date('2026-08-26')` happens to do this and `new Date(2026, 7, 26)` does
19
+ * not, and the difference is a whole day for anybody west of Greenwich: the
20
+ * local constructor gives a `Date` whose UTC date is the 25th. `Date.UTC` says
21
+ * which one is meant rather than relying on a parse rule.
22
+ *
23
+ * **Invalid is `null` and `NaN`, never a thrown error and never a guess.** That
24
+ * is what the platform answers for a half-typed date, which is most of the
25
+ * keystrokes a reader makes in one: a control that threw on the way to a valid
26
+ * value would be unusable, and one that guessed would submit a date nobody
27
+ * chose.
28
+ */
29
+ /** `YYYY-MM-DD`, and nothing that merely starts like it. */
30
+ const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
31
+ /** `HH:mm`, optionally with seconds, which is what a step under a minute produces. */
32
+ const ISO_TIME = /^(\d{2}):(\d{2})(?::(\d{2}(?:\.\d{1,3})?))?$/;
33
+ /** Milliseconds in one day, for a time value, which is an offset rather than an instant. */
34
+ const DAY = 86_400_000;
35
+ /**
36
+ * The date a `YYYY-MM-DD` value names, at midnight UTC, or `null`.
37
+ *
38
+ * The range check is not decoration. `2026-02-31` matches the pattern and
39
+ * `Date.UTC` rolls it forward to 3 March, so without reading the parts back a
40
+ * control would report a date the reader never typed and never saw.
41
+ */
42
+ export const valueAsDate = (value) => {
43
+ const parts = ISO_DATE.exec(value);
44
+ if (!parts) {
45
+ return null;
46
+ }
47
+ const [year, month, day] = [Number(parts[1]), Number(parts[2]), Number(parts[3])];
48
+ const date = new Date(Date.UTC(year, month - 1, day));
49
+ const rolled = date.getUTCFullYear() !== year || date.getUTCMonth() !== month - 1 || date.getUTCDate() !== day;
50
+ return rolled ? null : date;
51
+ };
52
+ /** The `YYYY-MM-DD` value for a date, or the empty string, which is how a control says nothing. */
53
+ export const dateAsValue = (date) => {
54
+ if (!date || Number.isNaN(date.getTime())) {
55
+ return '';
56
+ }
57
+ return date.toISOString().slice(0, 10);
58
+ };
59
+ /**
60
+ * The time an `HH:mm` value names, on 1 January 1970 UTC, or `null`.
61
+ *
62
+ * The platform's own answer for `<input type="time">`, and the epoch day is
63
+ * what makes `valueAsNumber` come out as milliseconds since midnight rather
64
+ * than as an instant nobody meant.
65
+ */
66
+ export const valueAsTime = (value) => {
67
+ const parts = ISO_TIME.exec(value);
68
+ if (!parts) {
69
+ return null;
70
+ }
71
+ const [hours, minutes] = [Number(parts[1]), Number(parts[2])];
72
+ const seconds = parts[3] === undefined ? 0 : Number(parts[3]);
73
+ if (hours > 23 || minutes > 59 || seconds >= 60) {
74
+ return null;
75
+ }
76
+ return new Date(Date.UTC(1970, 0, 1, hours, minutes, Math.floor(seconds), (seconds % 1) * 1000));
77
+ };
78
+ /**
79
+ * The `HH:mm` value for a time, or the empty string.
80
+ *
81
+ * Seconds are written only where there are any, because `HH:mm` is what this
82
+ * library's time controls hold and a trailing `:00` on every value would be a
83
+ * format change dressed as a conversion.
84
+ */
85
+ export const timeAsValue = (date) => {
86
+ if (!date || Number.isNaN(date.getTime())) {
87
+ return '';
88
+ }
89
+ const within = ((date.getTime() % DAY) + DAY) % DAY;
90
+ const clock = new Date(within);
91
+ const pad = (part) => String(part).padStart(2, '0');
92
+ const seconds = clock.getUTCSeconds() + clock.getUTCMilliseconds() / 1000;
93
+ const hm = `${pad(clock.getUTCHours())}:${pad(clock.getUTCMinutes())}`;
94
+ return seconds === 0 ? hm : `${hm}:${pad(clock.getUTCSeconds())}`;
95
+ };
96
+ /**
97
+ * The number a value holds, or `NaN`.
98
+ *
99
+ * `Number('')` is zero, which is the trap: an empty control would report a
100
+ * number it does not hold and a form would submit it. The platform answers
101
+ * `NaN` for an empty `<input type="number">` and so does this.
102
+ */
103
+ export const valueAsNumber = (value) => value.trim() === '' ? Number.NaN : Number(value);
104
+ /** The value for a number, or the empty string, which is how a control says nothing. */
105
+ export const numberAsValue = (count) => (Number.isNaN(count) ? '' : String(count));
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@fusion.dev/helix-core",
3
+ "description": "Helix element primitives: base classes, mixins, decorators, utilities.",
4
+ "version": "0.0.0-dev",
5
+ "license": "MIT",
6
+ "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
+ "repository": {
8
+ "directory": "helix/core",
9
+ "type": "git",
10
+ "url": "git+https://github.com/project-fusion/fusion.git"
11
+ },
12
+ "type": "module",
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "custom-elements.json",
23
+ "dist"
24
+ ],
25
+ "customElements": "custom-elements.json",
26
+ "sideEffects": false,
27
+ "scripts": {
28
+ "analyze": "cem analyze --config custom-elements-manifest.config.ts",
29
+ "build": "tsc -p tsconfig.json",
30
+ "typecheck": "tsc -p tsconfig.json --noEmit",
31
+ "test": "bun test src"
32
+ },
33
+ "bugs": "https://github.com/project-fusion/fusion/issues",
34
+ "dependencies": {
35
+ "@floating-ui/dom": "^1.8.0",
36
+ "@fusion.dev/helix-icons": "0.0.0-dev"
37
+ },
38
+ "devDependencies": {
39
+ "@custom-elements-manifest/analyzer": "^0.11.0",
40
+ "@fusion.dev/helix-cem": "0.0.0-dev",
41
+ "@fusion.dev/helix-testing": "0.0.0-dev",
42
+ "lit": "^3.2.1"
43
+ },
44
+ "homepage": "https://fusion.dev",
45
+ "keywords": [
46
+ "web-components",
47
+ "custom-elements",
48
+ "lit",
49
+ "design-system",
50
+ "helix"
51
+ ],
52
+ "peerDependencies": {
53
+ "lit": "^3.2.1"
54
+ },
55
+ "publishConfig": {
56
+ "access": "restricted"
57
+ }
58
+ }