@yugnex/nexui 2.0.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 (138) hide show
  1. package/LICENSE +59 -0
  2. package/css/nexui-base.css +157 -0
  3. package/css/nexui-icons.css +86 -0
  4. package/css/nexui-tokens.css +113 -0
  5. package/css/nexui.css +16 -0
  6. package/dist/assets/geometry.d.ts +98 -0
  7. package/dist/assets/geometry.d.ts.map +1 -0
  8. package/dist/assets/geometry.js +114 -0
  9. package/dist/assets/geometry.js.map +1 -0
  10. package/dist/assets/typography.d.ts +3 -0
  11. package/dist/assets/typography.d.ts.map +1 -0
  12. package/dist/assets/typography.js +178 -0
  13. package/dist/assets/typography.js.map +1 -0
  14. package/dist/core/compiler.d.ts +30 -0
  15. package/dist/core/compiler.d.ts.map +1 -0
  16. package/dist/core/compiler.js +124 -0
  17. package/dist/core/compiler.js.map +1 -0
  18. package/dist/core/cx.d.ts +7 -0
  19. package/dist/core/cx.d.ts.map +1 -0
  20. package/dist/core/cx.js +34 -0
  21. package/dist/core/cx.js.map +1 -0
  22. package/dist/core/matrix.d.ts +118 -0
  23. package/dist/core/matrix.d.ts.map +1 -0
  24. package/dist/core/matrix.js +180 -0
  25. package/dist/core/matrix.js.map +1 -0
  26. package/dist/index.d.ts +27 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +74 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/primitives/avatar.d.ts +8 -0
  31. package/dist/primitives/avatar.d.ts.map +1 -0
  32. package/dist/primitives/avatar.js +146 -0
  33. package/dist/primitives/avatar.js.map +1 -0
  34. package/dist/primitives/badge.d.ts +8 -0
  35. package/dist/primitives/badge.d.ts.map +1 -0
  36. package/dist/primitives/badge.js +88 -0
  37. package/dist/primitives/badge.js.map +1 -0
  38. package/dist/primitives/button.d.ts +10 -0
  39. package/dist/primitives/button.d.ts.map +1 -0
  40. package/dist/primitives/button.js +137 -0
  41. package/dist/primitives/button.js.map +1 -0
  42. package/dist/primitives/checkbox.d.ts +13 -0
  43. package/dist/primitives/checkbox.d.ts.map +1 -0
  44. package/dist/primitives/checkbox.js +107 -0
  45. package/dist/primitives/checkbox.js.map +1 -0
  46. package/dist/primitives/input.d.ts +14 -0
  47. package/dist/primitives/input.d.ts.map +1 -0
  48. package/dist/primitives/input.js +177 -0
  49. package/dist/primitives/input.js.map +1 -0
  50. package/dist/primitives/panel.d.ts +9 -0
  51. package/dist/primitives/panel.d.ts.map +1 -0
  52. package/dist/primitives/panel.js +101 -0
  53. package/dist/primitives/panel.js.map +1 -0
  54. package/dist/primitives/progress.d.ts +8 -0
  55. package/dist/primitives/progress.d.ts.map +1 -0
  56. package/dist/primitives/progress.js +105 -0
  57. package/dist/primitives/progress.js.map +1 -0
  58. package/dist/primitives/separator.d.ts +8 -0
  59. package/dist/primitives/separator.d.ts.map +1 -0
  60. package/dist/primitives/separator.js +69 -0
  61. package/dist/primitives/separator.js.map +1 -0
  62. package/dist/primitives/skeleton.d.ts +8 -0
  63. package/dist/primitives/skeleton.d.ts.map +1 -0
  64. package/dist/primitives/skeleton.js +61 -0
  65. package/dist/primitives/skeleton.js.map +1 -0
  66. package/dist/primitives/spinner.d.ts +8 -0
  67. package/dist/primitives/spinner.d.ts.map +1 -0
  68. package/dist/primitives/spinner.js +64 -0
  69. package/dist/primitives/spinner.js.map +1 -0
  70. package/dist/primitives/status-ring.d.ts +8 -0
  71. package/dist/primitives/status-ring.d.ts.map +1 -0
  72. package/dist/primitives/status-ring.js +101 -0
  73. package/dist/primitives/status-ring.js.map +1 -0
  74. package/dist/primitives/switch.d.ts +12 -0
  75. package/dist/primitives/switch.d.ts.map +1 -0
  76. package/dist/primitives/switch.js +124 -0
  77. package/dist/primitives/switch.js.map +1 -0
  78. package/dist/primitives/text-stream.d.ts +23 -0
  79. package/dist/primitives/text-stream.d.ts.map +1 -0
  80. package/dist/primitives/text-stream.js +167 -0
  81. package/dist/primitives/text-stream.js.map +1 -0
  82. package/dist/tokens/colors.d.ts +127 -0
  83. package/dist/tokens/colors.d.ts.map +1 -0
  84. package/dist/tokens/colors.js +135 -0
  85. package/dist/tokens/colors.js.map +1 -0
  86. package/dist/tokens/motion.d.ts +37 -0
  87. package/dist/tokens/motion.d.ts.map +1 -0
  88. package/dist/tokens/motion.js +93 -0
  89. package/dist/tokens/motion.js.map +1 -0
  90. package/dist/tokens/shadows.d.ts +34 -0
  91. package/dist/tokens/shadows.d.ts.map +1 -0
  92. package/dist/tokens/shadows.js +45 -0
  93. package/dist/tokens/shadows.js.map +1 -0
  94. package/dist/tokens/spacing.d.ts +69 -0
  95. package/dist/tokens/spacing.d.ts.map +1 -0
  96. package/dist/tokens/spacing.js +71 -0
  97. package/dist/tokens/spacing.js.map +1 -0
  98. package/dist/tokens/type.d.ts +166 -0
  99. package/dist/tokens/type.d.ts.map +1 -0
  100. package/dist/tokens/type.js +215 -0
  101. package/dist/tokens/type.js.map +1 -0
  102. package/fonts/NexuiIcons.woff2 +0 -0
  103. package/fonts/NexuiMono-Regular.otf +0 -0
  104. package/fonts/NexuiMono-Regular.woff2 +0 -0
  105. package/fonts/NexuiSans-Bold.otf +0 -0
  106. package/fonts/NexuiSans-Bold.woff2 +0 -0
  107. package/fonts/NexuiSans-Medium.otf +0 -0
  108. package/fonts/NexuiSans-Medium.woff2 +0 -0
  109. package/fonts/NexuiSans-Regular.otf +0 -0
  110. package/fonts/NexuiSans-Regular.woff2 +0 -0
  111. package/native/Cargo.toml +16 -0
  112. package/native/src/lib.rs +127 -0
  113. package/nexui-utils.css +485 -0
  114. package/package.json +58 -0
  115. package/src/assets/geometry.ts +144 -0
  116. package/src/assets/typography.ts +184 -0
  117. package/src/core/compiler.ts +139 -0
  118. package/src/core/cx.ts +50 -0
  119. package/src/core/matrix.ts +195 -0
  120. package/src/index.ts +78 -0
  121. package/src/primitives/avatar.ts +159 -0
  122. package/src/primitives/badge.ts +98 -0
  123. package/src/primitives/button.ts +149 -0
  124. package/src/primitives/checkbox.ts +113 -0
  125. package/src/primitives/input.ts +187 -0
  126. package/src/primitives/panel.ts +111 -0
  127. package/src/primitives/progress.ts +112 -0
  128. package/src/primitives/separator.ts +73 -0
  129. package/src/primitives/skeleton.ts +68 -0
  130. package/src/primitives/spinner.ts +71 -0
  131. package/src/primitives/status-ring.ts +109 -0
  132. package/src/primitives/switch.ts +134 -0
  133. package/src/primitives/text-stream.ts +187 -0
  134. package/src/tokens/colors.ts +149 -0
  135. package/src/tokens/motion.ts +97 -0
  136. package/src/tokens/shadows.ts +58 -0
  137. package/src/tokens/spacing.ts +79 -0
  138. package/src/tokens/type.ts +224 -0
@@ -0,0 +1,144 @@
1
+ // @yugnex/nexui — Icon Geometry
2
+ // Hand-authored SVG path data. 24x24 viewBox. Stroke-based (fill:none).
3
+ // Render: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
4
+ // <path d={NexuiIcons.check} />
5
+ // </svg>
6
+
7
+ export const NexuiIcons = {
8
+ // ── Navigation & Actions ─────────────────────────────────────────────────
9
+ arrowLeft: "M19 12H5M5 12l7-7M5 12l7 7",
10
+ arrowRight: "M5 12h14M13 5l7 7-7 7",
11
+ arrowUp: "M12 19V5M5 12l7-7 7 7",
12
+ arrowDown: "M12 5v14M19 12l-7 7-7-7",
13
+ chevronLeft: "M15 18l-6-6 6-6",
14
+ chevronRight: "M9 18l6-6-6-6",
15
+ chevronUp: "M18 15l-6-6-6 6",
16
+ chevronDown: "M6 9l6 6 6-6",
17
+ chevronUpDown: "M8 9l4-4 4 4M8 15l4 4 4-4",
18
+ externalLink: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",
19
+
20
+ // ── File & Folder ────────────────────────────────────────────────────────
21
+ file: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6",
22
+ fileCode: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M10 13l-2 2 2 2 M14 13l2 2-2 2",
23
+ fileText: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M16 13H8 M16 17H8 M10 9H8",
24
+ folder: "M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z",
25
+ folderOpen: "M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z M2 10h20",
26
+
27
+ // ── Interface ────────────────────────────────────────────────────────────
28
+ home: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 22V12h6v10",
29
+ menu: "M3 12h18M3 6h18M3 18h18",
30
+ x: "M18 6L6 18M6 6l12 12",
31
+ plus: "M12 5v14M5 12h14",
32
+ minus: "M5 12h14",
33
+ check: "M20 6L9 17l-5-5",
34
+ search: "M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z",
35
+ filter: "M22 3H2l8 9.46V19l4 2v-8.54z",
36
+ settings: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z",
37
+ moreHoriz: "M5 12h.01M12 12h.01M19 12h.01",
38
+ moreVert: "M12 5h.01M12 12h.01M12 19h.01",
39
+ copy: "M20 9H11a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2z M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",
40
+ trash: "M3 6h18M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6M10 11v6M14 11v6M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2",
41
+ edit: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z",
42
+ download: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3",
43
+ upload: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M17 8l-5-5-5 5 M12 3v12",
44
+ share: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8 M16 6l-4-4-4 4 M12 2v13",
45
+ refresh: "M23 4v6h-6 M1 20v-6h6 M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15",
46
+
47
+ // ── Status & Feedback ────────────────────────────────────────────────────
48
+ info: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 8h.01 M12 12v4",
49
+ alertCircle: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 8v4 M12 16h.01",
50
+ alertTriangle: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z M12 9v4 M12 17h.01",
51
+ checkCircle: "M22 11.08V12a10 10 0 1 1-5.93-9.14 M22 4L12 14.01l-3-3",
52
+ loader: "M12 2v4 M12 18v4 M4.93 4.93l2.83 2.83 M16.24 16.24l2.83 2.83 M2 12h4 M18 12h4 M4.93 19.07l2.83-2.83 M16.24 7.76l2.83-2.83",
53
+ activity: "M22 12h-4l-3 9L9 3l-3 9H2",
54
+
55
+ // ── Communication ────────────────────────────────────────────────────────
56
+ message: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",
57
+ send: "M22 2L11 13 M22 2L15 22l-4-9-9-4 22-7z",
58
+ bell: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9 M13.73 21a2 2 0 0 1-3.46 0",
59
+
60
+ // ── Code & Tech ──────────────────────────────────────────────────────────
61
+ code: "M16 18l6-6-6-6 M8 6l-6 6 6 6",
62
+ terminal: "M4 17l6-6-6-6 M12 19h8",
63
+ cpu: "M18 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z M9 9h6v6H9z M9 1v3 M15 1v3 M9 20v3 M15 20v3 M20 9h3 M20 14h3 M1 9h3 M1 14h3",
64
+ database: "M12 2C7.58 2 4 3.79 4 6v12c0 2.21 3.58 4 8 4s8-1.79 8-4V6c0-2.21-3.58-4-8-4z M4 12c0 2.21 3.58 4 8 4s8-1.79 8-4 M4 6c0 2.21 3.58 4 8 4s8-1.79 8-4",
65
+ server: "M22 2H2a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h20a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z M0 14h24v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-4z M6 6h.01 M6 18h.01",
66
+ git: "M18 3a3 3 0 0 1 0 6 3 3 0 0 1-2.83-2H9.83A3 3 0 0 1 4 9a3 3 0 0 1 3-3 3 3 0 0 1 2.83 2h5.34A3 3 0 0 1 18 6z M6 15a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M6 9v6",
67
+ gitBranch: "M6 3v12 M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M18 9a9 9 0 0 1-9 9",
68
+ gitCommit: "M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M1.05 12H7 M17.01 12H23",
69
+ gitPullRequest: "M18 15a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M6 3a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M13 6h3a2 2 0 0 1 2 2v7 M6 9v12",
70
+ package: "M16.5 9.4L7.55 4.24 M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 1 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z M3.27 6.96L12 12.01l8.73-5.05 M12 22.08V12",
71
+ play: "M5 3l14 9-14 9V3z",
72
+ stop: "M18 18H6V6h12z",
73
+ pause: "M6 19h4V5H6v14zM14 5v14h4V5h-4z",
74
+
75
+ // ── Security ─────────────────────────────────────────────────────────────
76
+ // Fixed padlock — corrected from the malformed original
77
+ lock: "M19 11H5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7a2 2 0 0 0-2-2z M7 11V7a5 5 0 0 1 10 0v4",
78
+ unlock: "M19 11H5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7a2 2 0 0 0-2-2z M7 11V7a5 5 0 0 1 9.9-1",
79
+ shield: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",
80
+ shieldCheck: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z M9 12l2 2 4-4",
81
+ eye: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",
82
+ eyeOff: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94 M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19 M1 1l22 22",
83
+ key: "M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4",
84
+
85
+ // ── User & Social ────────────────────────────────────────────────────────
86
+ user: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2 M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z",
87
+ users: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z",
88
+ userPlus: "M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M8.5 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M20 8v6 M23 11h-6",
89
+
90
+ // ── Layout & Panels ──────────────────────────────────────────────────────
91
+ layout: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z M3 9h18 M9 21V9",
92
+ sidebar: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z M9 3v18",
93
+ grid: "M3 3h7v7H3z M14 3h7v7h-7z M14 14h7v7h-7z M3 14h7v7H3z",
94
+ columns: "M12 3h9v18h-9z M3 3h7v18H3z",
95
+ maximize: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",
96
+ minimize: "M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3",
97
+
98
+ // ── Charts & Data ────────────────────────────────────────────────────────
99
+ barChart: "M18 20V10 M12 20V4 M6 20v-6",
100
+ lineChart: "M3 3v18h18 M3 9l4.5 4.5L12 9l4.5 6L21 9",
101
+ pieChart: "M21.21 15.89A10 10 0 1 1 8 2.83 M22 12A10 10 0 0 0 12 2v10z",
102
+ trendUp: "M23 6l-9.5 9.5-5-5L1 18 M17 6h6v6",
103
+ trendDown: "M23 18l-9.5-9.5-5 5L1 6 M17 18h6v-6",
104
+ zap: "M13 2L3 14h9l-1 8 10-12h-9l1-8z",
105
+
106
+ // ── Misc ─────────────────────────────────────────────────────────────────
107
+ star: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z",
108
+ heart: "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z",
109
+ bookmark: "M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",
110
+ tag: "M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z M7 7h.01",
111
+ link: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71 M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
112
+ globe: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M2 12h20 M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z",
113
+ clock: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 6v6l4 2",
114
+ calendar: "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z M16 1v4 M8 1v4 M3 9h18",
115
+ sparkles: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5z M19 15l.75 2.25L22 18l-2.25.75L19 21l-.75-2.25L16 18l2.25-.75z M5 3l.5 1.5L7 5l-1.5.5L5 7l-.5-1.5L3 5l1.5-.5z",
116
+ } as const;
117
+
118
+ export type NexuiIconName = keyof typeof NexuiIcons;
119
+
120
+ /** Renders an SVG string for the given icon. */
121
+ export function nexIcon(
122
+ name: NexuiIconName,
123
+ opts: {
124
+ size?: number;
125
+ strokeWidth?: number;
126
+ color?: string;
127
+ className?: string;
128
+ ariaLabel?: string;
129
+ } = {}
130
+ ): string {
131
+ const {
132
+ size = 16,
133
+ strokeWidth = 1.5,
134
+ color = "currentColor",
135
+ className = "",
136
+ ariaLabel,
137
+ } = opts;
138
+
139
+ const aria = ariaLabel
140
+ ? `role="img" aria-label="${ariaLabel}"`
141
+ : `aria-hidden="true"`;
142
+
143
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="${strokeWidth}" stroke-linecap="round" stroke-linejoin="round"${className ? ` class="${className}"` : ""} ${aria}><path d="${NexuiIcons[name]}"/></svg>`;
144
+ }
@@ -0,0 +1,184 @@
1
+ // @yugnex/nexui — Typography Asset
2
+ // Exports a complete CSS text block ready for injection via <style>.
3
+ // Includes: @font-face stubs, fluid type scale custom properties,
4
+ // and base reset for typographic elements.
5
+ // Inject once per page: document.head.appendChild(<style>NexuiTypographySheet</style>)
6
+
7
+ import { NEXUI_FONT_SIZE, NEXUI_FONT_FAMILY, NEXUI_LINE_HEIGHT } from "../tokens/type";
8
+ import { NEXUI_KEYFRAMES } from "../tokens/motion";
9
+
10
+ // @font-face declarations pointing to the in-house WOFF2 files in /fonts/.
11
+ // Consumers must serve the /fonts/ directory as static assets.
12
+ // Next.js: copy packages/nexui/fonts/ to public/nexui-fonts/ and update the paths below,
13
+ // OR use the path helper: import { NEXUI_FONT_PATH } from "@yugnex/nexui/assets/typography"
14
+ // The fonts/ directory is in the @yugnex/nexui package root (published with "files").
15
+ const FONT_FACE_BLOCK = `
16
+ @font-face {
17
+ font-family: 'NexuiSans';
18
+ font-style: normal;
19
+ font-weight: 400;
20
+ font-display: swap;
21
+ src: url('./fonts/NexuiSans-Regular.woff2') format('woff2');
22
+ }
23
+ @font-face {
24
+ font-family: 'NexuiSans';
25
+ font-style: normal;
26
+ font-weight: 500;
27
+ font-display: swap;
28
+ src: url('./fonts/NexuiSans-Medium.woff2') format('woff2');
29
+ }
30
+ @font-face {
31
+ font-family: 'NexuiSans';
32
+ font-style: normal;
33
+ font-weight: 700;
34
+ font-display: swap;
35
+ src: url('./fonts/NexuiSans-Bold.woff2') format('woff2');
36
+ }
37
+ @font-face {
38
+ font-family: 'NexuiMono';
39
+ font-style: normal;
40
+ font-weight: 400;
41
+ font-display: swap;
42
+ src: url('./fonts/NexuiMono-Regular.woff2') format('woff2');
43
+ }
44
+ `.trim();
45
+
46
+ // Fluid type custom properties on :root
47
+ const FLUID_VARS_BLOCK = `:root {
48
+ --nx-fs-2xs: ${NEXUI_FONT_SIZE["2xs"]};
49
+ --nx-fs-xs: ${NEXUI_FONT_SIZE["xs"]};
50
+ --nx-fs-sm: ${NEXUI_FONT_SIZE["sm"]};
51
+ --nx-fs-base: ${NEXUI_FONT_SIZE["base"]};
52
+ --nx-fs-md: ${NEXUI_FONT_SIZE["md"]};
53
+ --nx-fs-lg: ${NEXUI_FONT_SIZE["lg"]};
54
+ --nx-fs-xl: ${NEXUI_FONT_SIZE["xl"]};
55
+ --nx-fs-2xl: ${NEXUI_FONT_SIZE["2xl"]};
56
+ --nx-fs-3xl: ${NEXUI_FONT_SIZE["3xl"]};
57
+ --nx-fs-4xl: ${NEXUI_FONT_SIZE["4xl"]};
58
+ --nx-fs-5xl: ${NEXUI_FONT_SIZE["5xl"]};
59
+ --nx-fs-6xl: ${NEXUI_FONT_SIZE["6xl"]};
60
+ --nx-fs-7xl: ${NEXUI_FONT_SIZE["7xl"]};
61
+
62
+ --nx-ff-sans: ${NEXUI_FONT_FAMILY.sans};
63
+ --nx-ff-mono: ${NEXUI_FONT_FAMILY.mono};
64
+ --nx-ff-display: ${NEXUI_FONT_FAMILY.display};
65
+
66
+ --nx-lh-tight: ${NEXUI_LINE_HEIGHT.tight};
67
+ --nx-lh-normal: ${NEXUI_LINE_HEIGHT.normal};
68
+ --nx-lh-relaxed: ${NEXUI_LINE_HEIGHT.relaxed};
69
+ --nx-lh-code: ${NEXUI_LINE_HEIGHT.code};
70
+ }`;
71
+
72
+ // Base typographic reset
73
+ const TYPE_RESET_BLOCK = `
74
+ *,
75
+ *::before,
76
+ *::after {
77
+ box-sizing: border-box;
78
+ }
79
+
80
+ html {
81
+ -webkit-text-size-adjust: 100%;
82
+ tab-size: 2;
83
+ font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
84
+ -webkit-font-smoothing: antialiased;
85
+ -moz-osx-font-smoothing: grayscale;
86
+ }
87
+
88
+ body {
89
+ margin: 0;
90
+ font-family: var(--nx-ff-sans, ${NEXUI_FONT_FAMILY.sans});
91
+ font-size: var(--nx-fs-base);
92
+ line-height: ${NEXUI_LINE_HEIGHT.relaxed};
93
+ color: var(--nx-text, #E6EDF3);
94
+ background-color: var(--nx-bg-base, #0D1117);
95
+ }
96
+
97
+ code, kbd, samp, pre {
98
+ font-family: var(--nx-ff-mono, ${NEXUI_FONT_FAMILY.mono});
99
+ font-size: 0.9em;
100
+ }
101
+
102
+ h1, h2, h3, h4, h5, h6 {
103
+ margin: 0;
104
+ font-family: var(--nx-ff-display, ${NEXUI_FONT_FAMILY.display});
105
+ line-height: ${NEXUI_LINE_HEIGHT.tight};
106
+ color: var(--nx-text, #E6EDF3);
107
+ }
108
+
109
+ h1 { font-size: var(--nx-fs-4xl); font-weight: 700; }
110
+ h2 { font-size: var(--nx-fs-3xl); font-weight: 700; }
111
+ h3 { font-size: var(--nx-fs-2xl); font-weight: 600; }
112
+ h4 { font-size: var(--nx-fs-xl); font-weight: 600; }
113
+ h5 { font-size: var(--nx-fs-lg); font-weight: 600; }
114
+ h6 { font-size: var(--nx-fs-md); font-weight: 500; }
115
+
116
+ p {
117
+ margin: 0;
118
+ line-height: ${NEXUI_LINE_HEIGHT.relaxed};
119
+ }
120
+
121
+ a {
122
+ color: var(--nx-accent-text, #F5B342);
123
+ text-decoration: none;
124
+ }
125
+ a:hover {
126
+ text-decoration: underline;
127
+ }
128
+
129
+ strong, b { font-weight: 600; }
130
+ em, i { font-style: italic; }
131
+
132
+ small { font-size: var(--nx-fs-xs); }
133
+
134
+ pre {
135
+ margin: 0;
136
+ overflow-x: auto;
137
+ tab-size: 2;
138
+ }
139
+
140
+ /* Scrollbar styling */
141
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
142
+ ::-webkit-scrollbar-track { background: transparent; }
143
+ ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 3px; }
144
+ ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.20); }
145
+
146
+ /* Focus visible ring (keyboard nav) */
147
+ :focus-visible {
148
+ outline: 2px solid var(--nx-accent, #E89010);
149
+ outline-offset: 2px;
150
+ }
151
+ :focus:not(:focus-visible) {
152
+ outline: none;
153
+ }
154
+
155
+ /* Selection */
156
+ ::selection {
157
+ background: rgba(232,144,16,0.25);
158
+ color: var(--nx-text, #E6EDF3);
159
+ }
160
+
161
+ /* Reduced motion */
162
+ @media (prefers-reduced-motion: reduce) {
163
+ *, *::before, *::after {
164
+ animation-duration: 0.01ms !important;
165
+ animation-iteration-count: 1 !important;
166
+ transition-duration: 0.01ms !important;
167
+ scroll-behavior: auto !important;
168
+ }
169
+ }
170
+ `.trim();
171
+
172
+ // All blocks composed into a single injectable string
173
+ export const NexuiTypographySheet: string =
174
+ [FONT_FACE_BLOCK, FLUID_VARS_BLOCK, TYPE_RESET_BLOCK, NEXUI_KEYFRAMES].join("\n\n");
175
+
176
+ // Fluid type calculation exposed for custom use
177
+ export function fluidType(minPx: number, maxPx: number, minVp = 320, maxVp = 1440): string {
178
+ const slope = (maxPx - minPx) / (maxVp - minVp);
179
+ const y = minPx - slope * minVp;
180
+ const yFixed = parseFloat(y.toFixed(4));
181
+ const slopeFixed = parseFloat((slope * 100).toFixed(4));
182
+ const sign = yFixed >= 0 ? "+" : "-";
183
+ return `clamp(${minPx}px, ${Math.abs(yFixed)}px ${sign} ${slopeFixed}vw, ${maxPx}px)`;
184
+ }
@@ -0,0 +1,139 @@
1
+ // @yugnex/nexui — Style Compiler
2
+ // Converts LayoutMatrix bitmasks to CSS, manages theme injection,
3
+ // and provides shadow-DOM-safe CSS text output.
4
+
5
+ import {
6
+ NEXUI_THEMES,
7
+ type NexuiTheme,
8
+ MATRIX_PAD_MAP,
9
+ MATRIX_DISPLAY_MAP,
10
+ MATRIX_RADIUS_MAP,
11
+ MATRIX_GAP_MAP,
12
+ MATRIX_WIDTH_MAP,
13
+ MATRIX_OVERFLOW_MAP,
14
+ } from "./matrix";
15
+
16
+ const SELECTOR_PREFIX = "nx-m-";
17
+
18
+ // Bitmask masks for each field
19
+ const MASK_PAD = 0x00000F;
20
+ const MASK_DISPLAY = 0x0000F0;
21
+ const MASK_RADIUS = 0x000F00;
22
+ const MASK_GAP = 0x00F000;
23
+ const MASK_WIDTH = 0x0F0000;
24
+ const MASK_OVERFLOW = 0xF00000;
25
+
26
+ function bitmaskToCSSBody(mask: number): string {
27
+ let css = "";
28
+ const pad = mask & MASK_PAD;
29
+ const display = mask & MASK_DISPLAY;
30
+ const radius = mask & MASK_RADIUS;
31
+ const gap = mask & MASK_GAP;
32
+ const width = mask & MASK_WIDTH;
33
+ const overflow = mask & MASK_OVERFLOW;
34
+
35
+ if (MATRIX_PAD_MAP[pad]) css += MATRIX_PAD_MAP[pad];
36
+ if (MATRIX_DISPLAY_MAP[display]) css += MATRIX_DISPLAY_MAP[display];
37
+ if (MATRIX_RADIUS_MAP[radius]) css += MATRIX_RADIUS_MAP[radius];
38
+ if (MATRIX_GAP_MAP[gap]) css += MATRIX_GAP_MAP[gap];
39
+ if (MATRIX_WIDTH_MAP[width]) css += MATRIX_WIDTH_MAP[width];
40
+ if (MATRIX_OVERFLOW_MAP[overflow]) css += MATRIX_OVERFLOW_MAP[overflow];
41
+
42
+ return css;
43
+ }
44
+
45
+ export class NexuiStyleCompiler {
46
+ private sheet: CSSStyleSheet | null = null;
47
+ private cache = new Map<number, string>(); // mask → className
48
+ private currentTheme: NexuiTheme = "void";
49
+
50
+ // ─── Global document stylesheet ───────────────────────────────────────────
51
+
52
+ private getSheet(): CSSStyleSheet {
53
+ if (this.sheet) return this.sheet;
54
+ const style = document.createElement("style");
55
+ style.id = "yugnex-nexui-engine";
56
+ document.head.appendChild(style);
57
+ this.sheet = style.sheet as CSSStyleSheet;
58
+ return this.sheet;
59
+ }
60
+
61
+ /** Inject a bitmask class into the global document stylesheet.
62
+ * Returns the class name. Safe for light-DOM components only.
63
+ * For shadow DOM components, use compileBitmaskToString(). */
64
+ public compileBitmask(mask: number): string {
65
+ if (this.cache.has(mask)) return this.cache.get(mask)!;
66
+ const selector = `${SELECTOR_PREFIX}${mask.toString(16).toUpperCase()}`;
67
+ const body = bitmaskToCSSBody(mask);
68
+ if (body) {
69
+ try {
70
+ const sheet = this.getSheet();
71
+ sheet.insertRule(`.${selector}{${body}}`, sheet.cssRules.length);
72
+ } catch {
73
+ // CSSOM insertRule can fail in sandboxed frames — ignore silently
74
+ }
75
+ }
76
+ this.cache.set(mask, selector);
77
+ return selector;
78
+ }
79
+
80
+ /** Returns a complete `<style>` text block for use inside a shadow root.
81
+ * Shadow DOM cannot see global document styles, so call this inside
82
+ * connectedCallback() and inject the result into shadowRoot. */
83
+ public compileBitmaskToString(mask: number): string {
84
+ const selector = `${SELECTOR_PREFIX}${mask.toString(16).toUpperCase()}`;
85
+ const body = bitmaskToCSSBody(mask);
86
+ return body ? `.${selector}{${body}}` : "";
87
+ }
88
+
89
+ /** Returns CSS text for all currently compiled bitmask rules.
90
+ * Useful for SSR, test snapshots, or shadow root bulk-injection. */
91
+ public dumpCompiledCSS(): string {
92
+ let out = "";
93
+ for (const [mask] of this.cache) {
94
+ out += this.compileBitmaskToString(mask) + "\n";
95
+ }
96
+ return out;
97
+ }
98
+
99
+ // ─── Theme management ──────────────────────────────────────────────────────
100
+
101
+ /** Returns a CSS custom property block for the given theme.
102
+ * Inject into :root for global use, or into :host for shadow DOM. */
103
+ public getThemeCSS(theme: NexuiTheme, selector = ":root"): string {
104
+ const tokens = NEXUI_THEMES[theme];
105
+ const rules = Object.entries(tokens)
106
+ .map(([k, v]) => ` ${k}:${v};`)
107
+ .join("\n");
108
+ return `${selector}{\n${rules}\n}`;
109
+ }
110
+
111
+ /** Mounts theme custom properties on :root and stores active theme.
112
+ * Safe to call multiple times — replaces the previous theme block. */
113
+ public mountGlobalTheme(theme: NexuiTheme = "void"): void {
114
+ this.currentTheme = theme;
115
+ const existing = document.getElementById("yugnex-nexui-theme");
116
+ const style = (existing as HTMLStyleElement | null) ?? document.createElement("style");
117
+ style.id = "yugnex-nexui-theme";
118
+ style.textContent = this.getThemeCSS(theme, ":root");
119
+ if (!existing) document.head.appendChild(style);
120
+ }
121
+
122
+ public switchTheme(theme: NexuiTheme): void {
123
+ this.mountGlobalTheme(theme);
124
+ }
125
+
126
+ public getActiveTheme(): NexuiTheme {
127
+ return this.currentTheme;
128
+ }
129
+
130
+ /** Returns the full CSS needed for a shadow root: theme vars + compiled bitmasks. */
131
+ public getShadowRootCSS(masks: number[], theme?: NexuiTheme): string {
132
+ const t = theme ?? this.currentTheme;
133
+ const themeBlock = this.getThemeCSS(t, ":host");
134
+ const matrixBlock = masks.map(m => this.compileBitmaskToString(m)).join("\n");
135
+ return themeBlock + "\n" + matrixBlock;
136
+ }
137
+ }
138
+
139
+ export const nexui_compiler = new NexuiStyleCompiler();
package/src/core/cx.ts ADDED
@@ -0,0 +1,50 @@
1
+ // @yugnex/nexui — Class Name Utility
2
+ // Zero dependencies. Replaces clsx / classnames.
3
+ // cx("a", false && "b", undefined, "c") → "a c"
4
+ // cx({ active: true, disabled: false }) → "active"
5
+
6
+ type CxArg =
7
+ | string
8
+ | number
9
+ | boolean
10
+ | null
11
+ | undefined
12
+ | CxArg[]
13
+ | Record<string, boolean | undefined | null>;
14
+
15
+ export function cx(...args: CxArg[]): string {
16
+ const classes: string[] = [];
17
+
18
+ for (const arg of args) {
19
+ if (!arg) continue;
20
+
21
+ if (typeof arg === "string" || typeof arg === "number") {
22
+ classes.push(String(arg));
23
+ continue;
24
+ }
25
+
26
+ if (Array.isArray(arg)) {
27
+ const inner = cx(...arg);
28
+ if (inner) classes.push(inner);
29
+ continue;
30
+ }
31
+
32
+ if (typeof arg === "object") {
33
+ for (const [key, value] of Object.entries(arg)) {
34
+ if (value) classes.push(key);
35
+ }
36
+ }
37
+ }
38
+
39
+ return classes.join(" ");
40
+ }
41
+
42
+ /** Variant helper — picks one class from a map based on a key.
43
+ * Useful for component variant props without template literals. */
44
+ export function cv<T extends string>(
45
+ map: Record<T, string>,
46
+ variant: T,
47
+ fallback = ""
48
+ ): string {
49
+ return map[variant] ?? fallback;
50
+ }