@hypen-space/web 0.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.
Files changed (195) hide show
  1. package/dist/chunk-2s02mkzs.js +32 -0
  2. package/dist/chunk-2s02mkzs.js.map +9 -0
  3. package/dist/src/canvas/accessibility.js +152 -0
  4. package/dist/src/canvas/accessibility.js.map +10 -0
  5. package/dist/src/canvas/events.js +198 -0
  6. package/dist/src/canvas/events.js.map +10 -0
  7. package/dist/src/canvas/index.js +28 -0
  8. package/dist/src/canvas/index.js.map +9 -0
  9. package/dist/src/canvas/input.js +132 -0
  10. package/dist/src/canvas/input.js.map +10 -0
  11. package/dist/src/canvas/layout.js +309 -0
  12. package/dist/src/canvas/layout.js.map +10 -0
  13. package/dist/src/canvas/paint.js +878 -0
  14. package/dist/src/canvas/paint.js.map +10 -0
  15. package/dist/src/canvas/renderer.js +276 -0
  16. package/dist/src/canvas/renderer.js.map +10 -0
  17. package/dist/src/canvas/text.js +118 -0
  18. package/dist/src/canvas/text.js.map +10 -0
  19. package/dist/src/canvas/types.js +2 -0
  20. package/dist/src/canvas/types.js.map +9 -0
  21. package/dist/src/canvas/utils.js +139 -0
  22. package/dist/src/canvas/utils.js.map +10 -0
  23. package/dist/src/dom/applicators/advanced-layout.js +111 -0
  24. package/dist/src/dom/applicators/advanced-layout.js.map +10 -0
  25. package/dist/src/dom/applicators/background.js +54 -0
  26. package/dist/src/dom/applicators/background.js.map +10 -0
  27. package/dist/src/dom/applicators/border.js +33 -0
  28. package/dist/src/dom/applicators/border.js.map +10 -0
  29. package/dist/src/dom/applicators/color.js +36 -0
  30. package/dist/src/dom/applicators/color.js.map +10 -0
  31. package/dist/src/dom/applicators/display.js +57 -0
  32. package/dist/src/dom/applicators/display.js.map +10 -0
  33. package/dist/src/dom/applicators/effects.js +89 -0
  34. package/dist/src/dom/applicators/effects.js.map +10 -0
  35. package/dist/src/dom/applicators/events.js +518 -0
  36. package/dist/src/dom/applicators/events.js.map +10 -0
  37. package/dist/src/dom/applicators/font.js +39 -0
  38. package/dist/src/dom/applicators/font.js.map +10 -0
  39. package/dist/src/dom/applicators/index.js +296 -0
  40. package/dist/src/dom/applicators/index.js.map +10 -0
  41. package/dist/src/dom/applicators/layout.js +86 -0
  42. package/dist/src/dom/applicators/layout.js.map +10 -0
  43. package/dist/src/dom/applicators/margin.js +32 -0
  44. package/dist/src/dom/applicators/margin.js.map +10 -0
  45. package/dist/src/dom/applicators/padding.js +35 -0
  46. package/dist/src/dom/applicators/padding.js.map +10 -0
  47. package/dist/src/dom/applicators/size.js +42 -0
  48. package/dist/src/dom/applicators/size.js.map +10 -0
  49. package/dist/src/dom/applicators/transform.js +92 -0
  50. package/dist/src/dom/applicators/transform.js.map +10 -0
  51. package/dist/src/dom/applicators/transition.js +66 -0
  52. package/dist/src/dom/applicators/transition.js.map +10 -0
  53. package/dist/src/dom/applicators/typography.js +87 -0
  54. package/dist/src/dom/applicators/typography.js.map +10 -0
  55. package/dist/src/dom/canvas/index.js +50 -0
  56. package/dist/src/dom/canvas/index.js.map +10 -0
  57. package/dist/src/dom/components/audio.js +48 -0
  58. package/dist/src/dom/components/audio.js.map +10 -0
  59. package/dist/src/dom/components/avatar.js +58 -0
  60. package/dist/src/dom/components/avatar.js.map +10 -0
  61. package/dist/src/dom/components/badge.js +55 -0
  62. package/dist/src/dom/components/badge.js.map +10 -0
  63. package/dist/src/dom/components/button.js +29 -0
  64. package/dist/src/dom/components/button.js.map +10 -0
  65. package/dist/src/dom/components/card.js +33 -0
  66. package/dist/src/dom/components/card.js.map +10 -0
  67. package/dist/src/dom/components/center.js +32 -0
  68. package/dist/src/dom/components/center.js.map +10 -0
  69. package/dist/src/dom/components/checkbox.js +54 -0
  70. package/dist/src/dom/components/checkbox.js.map +10 -0
  71. package/dist/src/dom/components/column.js +31 -0
  72. package/dist/src/dom/components/column.js.map +10 -0
  73. package/dist/src/dom/components/container.js +29 -0
  74. package/dist/src/dom/components/container.js.map +10 -0
  75. package/dist/src/dom/components/divider.js +45 -0
  76. package/dist/src/dom/components/divider.js.map +10 -0
  77. package/dist/src/dom/components/grid.js +44 -0
  78. package/dist/src/dom/components/grid.js.map +10 -0
  79. package/dist/src/dom/components/heading.js +47 -0
  80. package/dist/src/dom/components/heading.js.map +10 -0
  81. package/dist/src/dom/components/image.js +39 -0
  82. package/dist/src/dom/components/image.js.map +10 -0
  83. package/dist/src/dom/components/index.js +217 -0
  84. package/dist/src/dom/components/index.js.map +10 -0
  85. package/dist/src/dom/components/input.js +41 -0
  86. package/dist/src/dom/components/input.js.map +10 -0
  87. package/dist/src/dom/components/link.js +42 -0
  88. package/dist/src/dom/components/link.js.map +10 -0
  89. package/dist/src/dom/components/list.js +42 -0
  90. package/dist/src/dom/components/list.js.map +10 -0
  91. package/dist/src/dom/components/paragraph.js +35 -0
  92. package/dist/src/dom/components/paragraph.js.map +10 -0
  93. package/dist/src/dom/components/progressbar.js +57 -0
  94. package/dist/src/dom/components/progressbar.js.map +10 -0
  95. package/dist/src/dom/components/route.js +44 -0
  96. package/dist/src/dom/components/route.js.map +10 -0
  97. package/dist/src/dom/components/router.js +33 -0
  98. package/dist/src/dom/components/router.js.map +10 -0
  99. package/dist/src/dom/components/row.js +31 -0
  100. package/dist/src/dom/components/row.js.map +10 -0
  101. package/dist/src/dom/components/select.js +57 -0
  102. package/dist/src/dom/components/select.js.map +10 -0
  103. package/dist/src/dom/components/slider.js +48 -0
  104. package/dist/src/dom/components/slider.js.map +10 -0
  105. package/dist/src/dom/components/spacer.js +30 -0
  106. package/dist/src/dom/components/spacer.js.map +10 -0
  107. package/dist/src/dom/components/spinner.js +65 -0
  108. package/dist/src/dom/components/spinner.js.map +10 -0
  109. package/dist/src/dom/components/stack.js +45 -0
  110. package/dist/src/dom/components/stack.js.map +10 -0
  111. package/dist/src/dom/components/switch.js +83 -0
  112. package/dist/src/dom/components/switch.js.map +10 -0
  113. package/dist/src/dom/components/text.js +37 -0
  114. package/dist/src/dom/components/text.js.map +10 -0
  115. package/dist/src/dom/components/textarea.js +51 -0
  116. package/dist/src/dom/components/textarea.js.map +10 -0
  117. package/dist/src/dom/components/video.js +51 -0
  118. package/dist/src/dom/components/video.js.map +10 -0
  119. package/dist/src/dom/debug.js +170 -0
  120. package/dist/src/dom/debug.js.map +10 -0
  121. package/dist/src/dom/events.js +112 -0
  122. package/dist/src/dom/events.js.map +10 -0
  123. package/dist/src/dom/index.js +73 -0
  124. package/dist/src/dom/index.js.map +9 -0
  125. package/dist/src/dom/renderer.js +277 -0
  126. package/dist/src/dom/renderer.js.map +10 -0
  127. package/dist/src/index.js +89 -0
  128. package/dist/src/index.js.map +9 -0
  129. package/package.json +84 -0
  130. package/src/canvas/QUICKSTART.md +421 -0
  131. package/src/canvas/README.md +376 -0
  132. package/src/canvas/accessibility.ts +218 -0
  133. package/src/canvas/events.ts +307 -0
  134. package/src/canvas/index.ts +35 -0
  135. package/src/canvas/input.ts +210 -0
  136. package/src/canvas/layout.ts +401 -0
  137. package/src/canvas/paint.ts +1321 -0
  138. package/src/canvas/renderer.ts +422 -0
  139. package/src/canvas/text.ts +182 -0
  140. package/src/canvas/types.ts +137 -0
  141. package/src/canvas/utils.ts +218 -0
  142. package/src/dom/README.md +265 -0
  143. package/src/dom/applicators/advanced-layout.ts +128 -0
  144. package/src/dom/applicators/background.ts +50 -0
  145. package/src/dom/applicators/border.ts +19 -0
  146. package/src/dom/applicators/color.ts +23 -0
  147. package/src/dom/applicators/display.ts +54 -0
  148. package/src/dom/applicators/effects.ts +97 -0
  149. package/src/dom/applicators/events.ts +689 -0
  150. package/src/dom/applicators/font.ts +27 -0
  151. package/src/dom/applicators/index.ts +354 -0
  152. package/src/dom/applicators/layout.ts +92 -0
  153. package/src/dom/applicators/margin.ts +18 -0
  154. package/src/dom/applicators/padding.ts +18 -0
  155. package/src/dom/applicators/size.ts +31 -0
  156. package/src/dom/applicators/transform.ts +93 -0
  157. package/src/dom/applicators/transition.ts +65 -0
  158. package/src/dom/applicators/typography.ts +91 -0
  159. package/src/dom/canvas/index.ts +60 -0
  160. package/src/dom/components/audio.ts +45 -0
  161. package/src/dom/components/avatar.ts +49 -0
  162. package/src/dom/components/badge.ts +45 -0
  163. package/src/dom/components/button.ts +13 -0
  164. package/src/dom/components/card.ts +19 -0
  165. package/src/dom/components/center.ts +16 -0
  166. package/src/dom/components/checkbox.ts +54 -0
  167. package/src/dom/components/column.ts +15 -0
  168. package/src/dom/components/container.ts +13 -0
  169. package/src/dom/components/divider.ts +37 -0
  170. package/src/dom/components/grid.ts +40 -0
  171. package/src/dom/components/heading.ts +41 -0
  172. package/src/dom/components/image.ts +27 -0
  173. package/src/dom/components/index.ts +115 -0
  174. package/src/dom/components/input.ts +29 -0
  175. package/src/dom/components/link.ts +35 -0
  176. package/src/dom/components/list.ts +30 -0
  177. package/src/dom/components/paragraph.ts +23 -0
  178. package/src/dom/components/progressbar.ts +51 -0
  179. package/src/dom/components/route.ts +37 -0
  180. package/src/dom/components/router.ts +22 -0
  181. package/src/dom/components/row.ts +15 -0
  182. package/src/dom/components/select.ts +56 -0
  183. package/src/dom/components/slider.ts +45 -0
  184. package/src/dom/components/spacer.ts +16 -0
  185. package/src/dom/components/spinner.ts +60 -0
  186. package/src/dom/components/stack.ts +34 -0
  187. package/src/dom/components/switch.ts +86 -0
  188. package/src/dom/components/text.ts +24 -0
  189. package/src/dom/components/textarea.ts +50 -0
  190. package/src/dom/components/video.ts +50 -0
  191. package/src/dom/debug.ts +247 -0
  192. package/src/dom/events.ts +168 -0
  193. package/src/dom/index.ts +11 -0
  194. package/src/dom/renderer.ts +327 -0
  195. package/src/index.ts +56 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Typography Applicators
3
+ */
4
+
5
+ import type { ApplicatorHandler } from "./index.js";
6
+
7
+ export const typographyHandlers: Record<string, ApplicatorHandler> = {
8
+ textAlign: (el, value) => {
9
+ el.style.textAlign = String(value);
10
+ },
11
+
12
+ textTransform: (el, value) => {
13
+ el.style.textTransform = String(value);
14
+ },
15
+
16
+ textDecoration: (el, value) => {
17
+ el.style.textDecoration = String(value);
18
+ },
19
+
20
+ textDecorationColor: (el, value) => {
21
+ el.style.textDecorationColor = String(value);
22
+ },
23
+
24
+ textDecorationStyle: (el, value) => {
25
+ el.style.textDecorationStyle = String(value);
26
+ },
27
+
28
+ textDecorationThickness: (el, value) => {
29
+ el.style.textDecorationThickness = typeof value === "number" ? `${value}px` : String(value);
30
+ },
31
+
32
+ letterSpacing: (el, value) => {
33
+ el.style.letterSpacing = typeof value === "number" ? `${value}px` : String(value);
34
+ },
35
+
36
+ wordSpacing: (el, value) => {
37
+ el.style.wordSpacing = typeof value === "number" ? `${value}px` : String(value);
38
+ },
39
+
40
+ lineHeight: (el, value) => {
41
+ el.style.lineHeight = String(value);
42
+ },
43
+
44
+ textIndent: (el, value) => {
45
+ el.style.textIndent = typeof value === "number" ? `${value}px` : String(value);
46
+ },
47
+
48
+ textOverflow: (el, value) => {
49
+ el.style.textOverflow = String(value);
50
+ },
51
+
52
+ whiteSpace: (el, value) => {
53
+ el.style.whiteSpace = String(value);
54
+ },
55
+
56
+ wordBreak: (el, value) => {
57
+ el.style.wordBreak = String(value);
58
+ },
59
+
60
+ verticalAlign: (el, value) => {
61
+ el.style.verticalAlign = String(value);
62
+ },
63
+
64
+ fontVariant: (el, value) => {
65
+ el.style.fontVariant = String(value);
66
+ },
67
+
68
+ fontStretch: (el, value) => {
69
+ el.style.fontStretch = String(value);
70
+ },
71
+
72
+ fontStyle: (el, value) => {
73
+ el.style.fontStyle = String(value);
74
+ },
75
+
76
+ writingMode: (el, value) => {
77
+ el.style.writingMode = String(value);
78
+ },
79
+
80
+ maxLines: (el, value) => {
81
+ const lines = typeof value === "number" ? value : parseInt(String(value), 10);
82
+ if (!isNaN(lines) && lines > 0) {
83
+ el.style.display = "-webkit-box";
84
+ el.style.setProperty("-webkit-line-clamp", String(lines));
85
+ el.style.setProperty("-webkit-box-orient", "vertical");
86
+ el.style.overflow = "hidden";
87
+ }
88
+ },
89
+ };
90
+
91
+
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Canvas Component with Applicators
3
+ *
4
+ * Special handling for canvas rendering
5
+ */
6
+
7
+ import type { ComponentHandler } from "../components/index.js";
8
+ import type { ApplicatorHandler } from "../applicators/index.js";
9
+
10
+ export const canvasHandler: ComponentHandler = {
11
+ create(): HTMLElement {
12
+ const el = document.createElement("canvas");
13
+ el.dataset.hypenType = "canvas";
14
+ return el as any as HTMLElement;
15
+ },
16
+
17
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
18
+ const canvas = el as HTMLCanvasElement;
19
+
20
+ if (props.width !== undefined) {
21
+ canvas.width = Number(props.width);
22
+ }
23
+
24
+ if (props.height !== undefined) {
25
+ canvas.height = Number(props.height);
26
+ }
27
+ },
28
+ };
29
+
30
+ /**
31
+ * Canvas applicators - special drawing commands
32
+ */
33
+ export const canvasApplicators: Record<string, ApplicatorHandler> = {
34
+ // Fill style
35
+ fillStyle: (el, value) => {
36
+ const canvas = el as HTMLCanvasElement;
37
+ const ctx = canvas.getContext("2d");
38
+ if (ctx) {
39
+ ctx.fillStyle = String(value);
40
+ }
41
+ },
42
+
43
+ // Stroke style
44
+ strokeStyle: (el, value) => {
45
+ const canvas = el as HTMLCanvasElement;
46
+ const ctx = canvas.getContext("2d");
47
+ if (ctx) {
48
+ ctx.strokeStyle = String(value);
49
+ }
50
+ },
51
+
52
+ // Line width
53
+ lineWidth: (el, value) => {
54
+ const canvas = el as HTMLCanvasElement;
55
+ const ctx = canvas.getContext("2d");
56
+ if (ctx) {
57
+ ctx.lineWidth = Number(value);
58
+ }
59
+ },
60
+ };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Audio Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const audioHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("audio");
10
+ el.dataset.hypenType = "audio";
11
+ return el as any as HTMLElement;
12
+ },
13
+
14
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
15
+ const audio = el as HTMLAudioElement;
16
+
17
+ // Source
18
+ const src = props["0"] || props.src;
19
+ if (src !== undefined) {
20
+ audio.src = String(src);
21
+ }
22
+
23
+ // Controls
24
+ if (props.controls !== undefined) {
25
+ audio.controls = Boolean(props.controls);
26
+ }
27
+
28
+ // Autoplay
29
+ if (props.autoplay !== undefined) {
30
+ audio.autoplay = Boolean(props.autoplay);
31
+ }
32
+
33
+ // Loop
34
+ if (props.loop !== undefined) {
35
+ audio.loop = Boolean(props.loop);
36
+ }
37
+
38
+ // Muted
39
+ if (props.muted !== undefined) {
40
+ audio.muted = Boolean(props.muted);
41
+ }
42
+ },
43
+ };
44
+
45
+
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Avatar Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const avatarHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.dataset.hypenType = "avatar";
11
+ el.style.display = "inline-flex";
12
+ el.style.alignItems = "center";
13
+ el.style.justifyContent = "center";
14
+ el.style.width = "40px";
15
+ el.style.height = "40px";
16
+ el.style.borderRadius = "50%";
17
+ el.style.backgroundColor = "#9e9e9e";
18
+ el.style.color = "#fff";
19
+ el.style.fontSize = "16px";
20
+ el.style.fontWeight = "600";
21
+ el.style.overflow = "hidden";
22
+ return el;
23
+ },
24
+
25
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
26
+ // Image source
27
+ if (props.src !== undefined) {
28
+ const img = document.createElement("img");
29
+ img.src = String(props.src);
30
+ img.style.width = "100%";
31
+ img.style.height = "100%";
32
+ img.style.objectFit = "cover";
33
+ el.innerHTML = "";
34
+ el.appendChild(img);
35
+ } else if (props.initials !== undefined) {
36
+ // Show initials
37
+ el.textContent = String(props.initials).toUpperCase();
38
+ }
39
+
40
+ // Size
41
+ if (props.size !== undefined) {
42
+ const size = typeof props.size === "number" ? `${props.size}px` : String(props.size);
43
+ el.style.width = size;
44
+ el.style.height = size;
45
+ }
46
+ },
47
+ };
48
+
49
+
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Badge Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const badgeHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("span");
10
+ el.dataset.hypenType = "badge";
11
+ el.style.display = "inline-block";
12
+ el.style.padding = "4px 8px";
13
+ el.style.borderRadius = "4px";
14
+ el.style.fontSize = "12px";
15
+ el.style.fontWeight = "600";
16
+ el.style.backgroundColor = "#e0e0e0";
17
+ el.style.color = "#333";
18
+ return el;
19
+ },
20
+
21
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
22
+ // Theme
23
+ if (props.theme !== undefined) {
24
+ const theme = String(props.theme);
25
+ const themeColors: Record<string, { bg: string; color: string }> = {
26
+ success: { bg: "#4CAF50", color: "#fff" },
27
+ error: { bg: "#f44336", color: "#fff" },
28
+ warning: { bg: "#ff9800", color: "#fff" },
29
+ info: { bg: "#2196F3", color: "#fff" },
30
+ default: { bg: "#e0e0e0", color: "#333" },
31
+ };
32
+ const colors = themeColors[theme] || themeColors.default;
33
+ el.style.backgroundColor = colors.bg;
34
+ el.style.color = colors.color;
35
+ }
36
+
37
+ // Text content
38
+ const text = props["0"] || props.text;
39
+ if (text !== undefined) {
40
+ el.textContent = String(text);
41
+ }
42
+ },
43
+ };
44
+
45
+
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Button Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const buttonHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("button");
10
+ el.dataset.hypenType = "button";
11
+ return el;
12
+ },
13
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Card Component - Container with default styling
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const cardHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.dataset.hypenType = "card";
11
+ el.style.backgroundColor = "#ffffff";
12
+ el.style.borderRadius = "8px";
13
+ el.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.1)";
14
+ el.style.padding = "16px";
15
+ return el;
16
+ },
17
+ };
18
+
19
+
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Center Component - Centers content
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const centerHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.style.display = "flex";
11
+ el.style.alignItems = "center";
12
+ el.style.justifyContent = "center";
13
+ el.dataset.hypenType = "center";
14
+ return el;
15
+ },
16
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Checkbox Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const checkboxHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const wrapper = document.createElement("label");
10
+ wrapper.dataset.hypenType = "checkbox";
11
+ wrapper.style.display = "inline-flex";
12
+ wrapper.style.alignItems = "center";
13
+ wrapper.style.gap = "8px";
14
+ wrapper.style.cursor = "pointer";
15
+
16
+ const input = document.createElement("input");
17
+ input.type = "checkbox";
18
+ input.dataset.hypenCheckbox = "true";
19
+
20
+ wrapper.appendChild(input);
21
+
22
+ return wrapper;
23
+ },
24
+
25
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
26
+ const input = el.querySelector('input[type="checkbox"]') as HTMLInputElement;
27
+ if (!input) return;
28
+
29
+ // Checked state
30
+ if (props.checked !== undefined) {
31
+ input.checked = Boolean(props.checked);
32
+ }
33
+
34
+ // Disabled
35
+ if (props.disabled !== undefined) {
36
+ input.disabled = Boolean(props.disabled);
37
+ }
38
+
39
+ // Label text
40
+ const label = props["0"] || props.label;
41
+ if (label !== undefined) {
42
+ // Remove existing text node if any
43
+ const textNodes = Array.from(el.childNodes).filter(
44
+ node => node.nodeType === Node.TEXT_NODE
45
+ );
46
+ textNodes.forEach(node => node.remove());
47
+
48
+ // Add new label text
49
+ el.appendChild(document.createTextNode(String(label)));
50
+ }
51
+ },
52
+ };
53
+
54
+
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Column Component - Vertical Stack
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const columnHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.style.display = "flex";
11
+ el.style.flexDirection = "column";
12
+ el.dataset.hypenType = "column";
13
+ return el;
14
+ },
15
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Container/Box Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const containerHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.dataset.hypenType = "container";
11
+ return el;
12
+ },
13
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Divider Component - Visual separator
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const dividerHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("hr");
10
+ el.dataset.hypenType = "divider";
11
+ el.style.border = "none";
12
+ el.style.borderTop = "1px solid #e0e0e0";
13
+ el.style.margin = "0";
14
+ return el;
15
+ },
16
+
17
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
18
+ // Thickness
19
+ if (props.thickness !== undefined) {
20
+ const thickness = typeof props.thickness === "number"
21
+ ? `${props.thickness}px`
22
+ : String(props.thickness);
23
+ el.style.borderTopWidth = thickness;
24
+ }
25
+
26
+ // Orientation
27
+ if (props.orientation === "vertical") {
28
+ el.style.borderTop = "none";
29
+ el.style.borderLeft = "1px solid #e0e0e0";
30
+ el.style.height = "100%";
31
+ el.style.width = "0";
32
+ el.style.display = "inline-block";
33
+ }
34
+ },
35
+ };
36
+
37
+
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Grid Component - CSS Grid Layout
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const gridHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("div");
10
+ el.style.display = "grid";
11
+ el.dataset.hypenType = "grid";
12
+ return el;
13
+ },
14
+
15
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
16
+ // Columns
17
+ if (props.columns !== undefined) {
18
+ const columns = typeof props.columns === "number"
19
+ ? `repeat(${props.columns}, 1fr)`
20
+ : String(props.columns);
21
+ el.style.gridTemplateColumns = columns;
22
+ }
23
+
24
+ // Rows
25
+ if (props.rows !== undefined) {
26
+ const rows = typeof props.rows === "number"
27
+ ? `repeat(${props.rows}, 1fr)`
28
+ : String(props.rows);
29
+ el.style.gridTemplateRows = rows;
30
+ }
31
+
32
+ // Gap
33
+ if (props.gap !== undefined) {
34
+ const gap = typeof props.gap === "number" ? `${props.gap}px` : String(props.gap);
35
+ el.style.gap = gap;
36
+ }
37
+ },
38
+ };
39
+
40
+
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Heading Component - Semantic headings (h1-h6)
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const headingHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("h2");
10
+ el.dataset.hypenType = "heading";
11
+ return el;
12
+ },
13
+
14
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
15
+ // Level property (1-6)
16
+ if (props.level !== undefined) {
17
+ const level = Math.max(1, Math.min(6, Number(props.level)));
18
+ const newEl = document.createElement(`h${level}`);
19
+ newEl.dataset.hypenType = "heading";
20
+
21
+ // Copy content and attributes
22
+ newEl.innerHTML = el.innerHTML;
23
+ Array.from(el.attributes).forEach(attr => {
24
+ newEl.setAttribute(attr.name, attr.value);
25
+ });
26
+
27
+ // Replace the element
28
+ if (el.parentNode) {
29
+ el.parentNode.replaceChild(newEl, el);
30
+ }
31
+ }
32
+
33
+ // Text content
34
+ const text = props["0"] || props.text;
35
+ if (text !== undefined) {
36
+ el.textContent = String(text);
37
+ }
38
+ },
39
+ };
40
+
41
+
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Image Component
3
+ */
4
+
5
+ import type { ComponentHandler } from "./index.js";
6
+
7
+ export const imageHandler: ComponentHandler = {
8
+ create(): HTMLElement {
9
+ const el = document.createElement("img");
10
+ el.dataset.hypenType = "image";
11
+ return el as any as HTMLElement;
12
+ },
13
+
14
+ applyProps(el: HTMLElement, props: Record<string, any>): void {
15
+ const img = el as HTMLImageElement;
16
+
17
+ // Support url, src, or first positional argument
18
+ const src = props["0"] || props.url || props.src;
19
+ if (src !== undefined) {
20
+ img.src = String(src);
21
+ }
22
+
23
+ if (props.alt !== undefined) {
24
+ img.alt = String(props.alt);
25
+ }
26
+ },
27
+ };
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Component Registry
3
+ *
4
+ * Manages mappings from Hypen component types to DOM elements
5
+ */
6
+
7
+ export interface ComponentHandler {
8
+ create(): HTMLElement;
9
+ applyProps?(element: HTMLElement, props: Record<string, any>): void;
10
+ }
11
+
12
+ export class ComponentRegistry {
13
+ private handlers: Map<string, ComponentHandler> = new Map();
14
+
15
+ constructor() {
16
+ this.registerDefaults();
17
+ }
18
+
19
+ /**
20
+ * Register a component handler
21
+ */
22
+ register(type: string, handler: ComponentHandler): void {
23
+ this.handlers.set(type.toLowerCase(), handler);
24
+ }
25
+
26
+ /**
27
+ * Get handler for a component type
28
+ */
29
+ get(type: string): ComponentHandler | undefined {
30
+ return this.handlers.get(type.toLowerCase());
31
+ }
32
+
33
+ /**
34
+ * Create element for a component type
35
+ */
36
+ createElement(type: string, props: Record<string, any> = {}): HTMLElement | null {
37
+ const handler = this.get(type);
38
+ if (!handler) return null;
39
+
40
+ const element = handler.create();
41
+ if (handler.applyProps) {
42
+ handler.applyProps(element, props);
43
+ }
44
+ return element;
45
+ }
46
+
47
+ /**
48
+ * Register all default Hypen components
49
+ */
50
+ private registerDefaults(): void {
51
+ // Import and register all component handlers
52
+ const { columnHandler } = require("./column.js");
53
+ const { rowHandler } = require("./row.js");
54
+ const { textHandler } = require("./text.js");
55
+ const { imageHandler } = require("./image.js");
56
+ const { buttonHandler } = require("./button.js");
57
+ const { containerHandler } = require("./container.js");
58
+ const { centerHandler } = require("./center.js");
59
+ const { listHandler } = require("./list.js");
60
+ const { inputHandler } = require("./input.js");
61
+ const { linkHandler } = require("./link.js");
62
+ const { textareaHandler } = require("./textarea.js");
63
+ const { checkboxHandler } = require("./checkbox.js");
64
+ const { selectHandler } = require("./select.js");
65
+ const { spacerHandler } = require("./spacer.js");
66
+ const { stackHandler } = require("./stack.js");
67
+ const { dividerHandler } = require("./divider.js");
68
+ const { gridHandler } = require("./grid.js");
69
+ const { cardHandler } = require("./card.js");
70
+ const { headingHandler } = require("./heading.js");
71
+ const { switchHandler } = require("./switch.js");
72
+ const { sliderHandler } = require("./slider.js");
73
+ const { spinnerHandler } = require("./spinner.js");
74
+ const { badgeHandler } = require("./badge.js");
75
+ const { avatarHandler } = require("./avatar.js");
76
+ const { progressBarHandler } = require("./progressbar.js");
77
+ const { videoHandler } = require("./video.js");
78
+ const { audioHandler } = require("./audio.js");
79
+ const { paragraphHandler } = require("./paragraph.js");
80
+ const { routerHandler } = require("./router.js");
81
+ const { routeHandler } = require("./route.js");
82
+
83
+ this.register("column", columnHandler);
84
+ this.register("row", rowHandler);
85
+ this.register("text", textHandler);
86
+ this.register("image", imageHandler);
87
+ this.register("button", buttonHandler);
88
+ this.register("container", containerHandler);
89
+ this.register("box", containerHandler);
90
+ this.register("center", centerHandler);
91
+ this.register("list", listHandler);
92
+ this.register("input", inputHandler);
93
+ this.register("link", linkHandler);
94
+ this.register("textarea", textareaHandler);
95
+ this.register("checkbox", checkboxHandler);
96
+ this.register("select", selectHandler);
97
+ this.register("spacer", spacerHandler);
98
+ this.register("stack", stackHandler);
99
+ this.register("divider", dividerHandler);
100
+ this.register("grid", gridHandler);
101
+ this.register("card", cardHandler);
102
+ this.register("heading", headingHandler);
103
+ this.register("switch", switchHandler);
104
+ this.register("slider", sliderHandler);
105
+ this.register("spinner", spinnerHandler);
106
+ this.register("badge", badgeHandler);
107
+ this.register("avatar", avatarHandler);
108
+ this.register("progressbar", progressBarHandler);
109
+ this.register("video", videoHandler);
110
+ this.register("audio", audioHandler);
111
+ this.register("paragraph", paragraphHandler);
112
+ this.register("router", routerHandler);
113
+ this.register("route", routeHandler);
114
+ }
115
+ }