@shumoku/core 0.1.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 (220) hide show
  1. package/dist/icons/build-icons.d.ts +6 -0
  2. package/dist/icons/build-icons.d.ts.map +1 -0
  3. package/dist/icons/build-icons.js +163 -0
  4. package/dist/icons/build-icons.js.map +1 -0
  5. package/dist/icons/generated-icons.d.ts +32 -0
  6. package/dist/icons/generated-icons.d.ts.map +1 -0
  7. package/dist/icons/generated-icons.js +88 -0
  8. package/dist/icons/generated-icons.js.map +1 -0
  9. package/dist/icons/index.d.ts +2 -0
  10. package/dist/icons/index.d.ts.map +1 -0
  11. package/dist/icons/index.js +2 -0
  12. package/dist/icons/index.js.map +1 -0
  13. package/dist/index.d.ts +10 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +16 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/layout/hierarchical.d.ts +73 -0
  18. package/dist/layout/hierarchical.d.ts.map +1 -0
  19. package/dist/layout/hierarchical.js +1320 -0
  20. package/dist/layout/hierarchical.js.map +1 -0
  21. package/dist/layout/index.d.ts +6 -0
  22. package/dist/layout/index.d.ts.map +1 -0
  23. package/dist/layout/index.js +5 -0
  24. package/dist/layout/index.js.map +1 -0
  25. package/dist/models/index.d.ts +5 -0
  26. package/dist/models/index.d.ts.map +1 -0
  27. package/dist/models/index.js +5 -0
  28. package/dist/models/index.js.map +1 -0
  29. package/dist/models/types.d.ts +381 -0
  30. package/dist/models/types.d.ts.map +1 -0
  31. package/dist/models/types.js +61 -0
  32. package/dist/models/types.js.map +1 -0
  33. package/dist/renderer/components/index.d.ts +8 -0
  34. package/dist/renderer/components/index.d.ts.map +1 -0
  35. package/dist/renderer/components/index.js +8 -0
  36. package/dist/renderer/components/index.js.map +1 -0
  37. package/dist/renderer/components/link-renderer.d.ts +11 -0
  38. package/dist/renderer/components/link-renderer.d.ts.map +1 -0
  39. package/dist/renderer/components/link-renderer.js +340 -0
  40. package/dist/renderer/components/link-renderer.js.map +1 -0
  41. package/dist/renderer/components/node-renderer.d.ts +14 -0
  42. package/dist/renderer/components/node-renderer.d.ts.map +1 -0
  43. package/dist/renderer/components/node-renderer.js +242 -0
  44. package/dist/renderer/components/node-renderer.js.map +1 -0
  45. package/dist/renderer/components/port-renderer.d.ts +8 -0
  46. package/dist/renderer/components/port-renderer.d.ts.map +1 -0
  47. package/dist/renderer/components/port-renderer.js +85 -0
  48. package/dist/renderer/components/port-renderer.js.map +1 -0
  49. package/dist/renderer/components/subgraph-renderer.d.ts +13 -0
  50. package/dist/renderer/components/subgraph-renderer.d.ts.map +1 -0
  51. package/dist/renderer/components/subgraph-renderer.js +85 -0
  52. package/dist/renderer/components/subgraph-renderer.js.map +1 -0
  53. package/dist/renderer/icon-registry/index.d.ts +6 -0
  54. package/dist/renderer/icon-registry/index.d.ts.map +1 -0
  55. package/dist/renderer/icon-registry/index.js +5 -0
  56. package/dist/renderer/icon-registry/index.js.map +1 -0
  57. package/dist/renderer/icon-registry/registry.d.ts +25 -0
  58. package/dist/renderer/icon-registry/registry.d.ts.map +1 -0
  59. package/dist/renderer/icon-registry/registry.js +85 -0
  60. package/dist/renderer/icon-registry/registry.js.map +1 -0
  61. package/dist/renderer/icon-registry/types.d.ts +44 -0
  62. package/dist/renderer/icon-registry/types.d.ts.map +1 -0
  63. package/dist/renderer/icon-registry/types.js +5 -0
  64. package/dist/renderer/icon-registry/types.js.map +1 -0
  65. package/dist/renderer/index.d.ts +6 -0
  66. package/dist/renderer/index.d.ts.map +1 -0
  67. package/dist/renderer/index.js +5 -0
  68. package/dist/renderer/index.js.map +1 -0
  69. package/dist/renderer/render-model/builder.d.ts +43 -0
  70. package/dist/renderer/render-model/builder.d.ts.map +1 -0
  71. package/dist/renderer/render-model/builder.js +646 -0
  72. package/dist/renderer/render-model/builder.js.map +1 -0
  73. package/dist/renderer/render-model/index.d.ts +6 -0
  74. package/dist/renderer/render-model/index.d.ts.map +1 -0
  75. package/dist/renderer/render-model/index.js +5 -0
  76. package/dist/renderer/render-model/index.js.map +1 -0
  77. package/dist/renderer/render-model/types.d.ts +216 -0
  78. package/dist/renderer/render-model/types.d.ts.map +1 -0
  79. package/dist/renderer/render-model/types.js +6 -0
  80. package/dist/renderer/render-model/types.js.map +1 -0
  81. package/dist/renderer/renderer-types.d.ts +55 -0
  82. package/dist/renderer/renderer-types.d.ts.map +1 -0
  83. package/dist/renderer/renderer-types.js +5 -0
  84. package/dist/renderer/renderer-types.js.map +1 -0
  85. package/dist/renderer/svg-builder.d.ts +152 -0
  86. package/dist/renderer/svg-builder.d.ts.map +1 -0
  87. package/dist/renderer/svg-builder.js +176 -0
  88. package/dist/renderer/svg-builder.js.map +1 -0
  89. package/dist/renderer/svg-dom/builders/defs.d.ts +10 -0
  90. package/dist/renderer/svg-dom/builders/defs.d.ts.map +1 -0
  91. package/dist/renderer/svg-dom/builders/defs.js +82 -0
  92. package/dist/renderer/svg-dom/builders/defs.js.map +1 -0
  93. package/dist/renderer/svg-dom/builders/index.d.ts +9 -0
  94. package/dist/renderer/svg-dom/builders/index.d.ts.map +1 -0
  95. package/dist/renderer/svg-dom/builders/index.js +9 -0
  96. package/dist/renderer/svg-dom/builders/index.js.map +1 -0
  97. package/dist/renderer/svg-dom/builders/link.d.ts +18 -0
  98. package/dist/renderer/svg-dom/builders/link.d.ts.map +1 -0
  99. package/dist/renderer/svg-dom/builders/link.js +188 -0
  100. package/dist/renderer/svg-dom/builders/link.js.map +1 -0
  101. package/dist/renderer/svg-dom/builders/node.d.ts +15 -0
  102. package/dist/renderer/svg-dom/builders/node.d.ts.map +1 -0
  103. package/dist/renderer/svg-dom/builders/node.js +262 -0
  104. package/dist/renderer/svg-dom/builders/node.js.map +1 -0
  105. package/dist/renderer/svg-dom/builders/subgraph.d.ts +14 -0
  106. package/dist/renderer/svg-dom/builders/subgraph.d.ts.map +1 -0
  107. package/dist/renderer/svg-dom/builders/subgraph.js +63 -0
  108. package/dist/renderer/svg-dom/builders/subgraph.js.map +1 -0
  109. package/dist/renderer/svg-dom/builders/utils.d.ts +40 -0
  110. package/dist/renderer/svg-dom/builders/utils.d.ts.map +1 -0
  111. package/dist/renderer/svg-dom/builders/utils.js +79 -0
  112. package/dist/renderer/svg-dom/builders/utils.js.map +1 -0
  113. package/dist/renderer/svg-dom/index.d.ts +9 -0
  114. package/dist/renderer/svg-dom/index.d.ts.map +1 -0
  115. package/dist/renderer/svg-dom/index.js +7 -0
  116. package/dist/renderer/svg-dom/index.js.map +1 -0
  117. package/dist/renderer/svg-dom/interaction.d.ts +69 -0
  118. package/dist/renderer/svg-dom/interaction.d.ts.map +1 -0
  119. package/dist/renderer/svg-dom/interaction.js +296 -0
  120. package/dist/renderer/svg-dom/interaction.js.map +1 -0
  121. package/dist/renderer/svg-dom/renderer.d.ts +47 -0
  122. package/dist/renderer/svg-dom/renderer.d.ts.map +1 -0
  123. package/dist/renderer/svg-dom/renderer.js +188 -0
  124. package/dist/renderer/svg-dom/renderer.js.map +1 -0
  125. package/dist/renderer/svg-string/builders/defs.d.ts +10 -0
  126. package/dist/renderer/svg-string/builders/defs.d.ts.map +1 -0
  127. package/dist/renderer/svg-string/builders/defs.js +43 -0
  128. package/dist/renderer/svg-string/builders/defs.js.map +1 -0
  129. package/dist/renderer/svg-string/builders/link.d.ts +10 -0
  130. package/dist/renderer/svg-string/builders/link.d.ts.map +1 -0
  131. package/dist/renderer/svg-string/builders/link.js +149 -0
  132. package/dist/renderer/svg-string/builders/link.js.map +1 -0
  133. package/dist/renderer/svg-string/builders/node.d.ts +10 -0
  134. package/dist/renderer/svg-string/builders/node.d.ts.map +1 -0
  135. package/dist/renderer/svg-string/builders/node.js +134 -0
  136. package/dist/renderer/svg-string/builders/node.js.map +1 -0
  137. package/dist/renderer/svg-string/builders/subgraph.d.ts +10 -0
  138. package/dist/renderer/svg-string/builders/subgraph.d.ts.map +1 -0
  139. package/dist/renderer/svg-string/builders/subgraph.js +59 -0
  140. package/dist/renderer/svg-string/builders/subgraph.js.map +1 -0
  141. package/dist/renderer/svg-string/index.d.ts +5 -0
  142. package/dist/renderer/svg-string/index.d.ts.map +1 -0
  143. package/dist/renderer/svg-string/index.js +5 -0
  144. package/dist/renderer/svg-string/index.js.map +1 -0
  145. package/dist/renderer/svg-string/renderer.d.ts +17 -0
  146. package/dist/renderer/svg-string/renderer.d.ts.map +1 -0
  147. package/dist/renderer/svg-string/renderer.js +53 -0
  148. package/dist/renderer/svg-string/renderer.js.map +1 -0
  149. package/dist/renderer/svg.d.ts +105 -0
  150. package/dist/renderer/svg.d.ts.map +1 -0
  151. package/dist/renderer/svg.js +804 -0
  152. package/dist/renderer/svg.js.map +1 -0
  153. package/dist/renderer/text-measurer/browser-measurer.d.ts +25 -0
  154. package/dist/renderer/text-measurer/browser-measurer.d.ts.map +1 -0
  155. package/dist/renderer/text-measurer/browser-measurer.js +85 -0
  156. package/dist/renderer/text-measurer/browser-measurer.js.map +1 -0
  157. package/dist/renderer/text-measurer/fallback-measurer.d.ts +22 -0
  158. package/dist/renderer/text-measurer/fallback-measurer.d.ts.map +1 -0
  159. package/dist/renderer/text-measurer/fallback-measurer.js +113 -0
  160. package/dist/renderer/text-measurer/fallback-measurer.js.map +1 -0
  161. package/dist/renderer/text-measurer/index.d.ts +13 -0
  162. package/dist/renderer/text-measurer/index.d.ts.map +1 -0
  163. package/dist/renderer/text-measurer/index.js +35 -0
  164. package/dist/renderer/text-measurer/index.js.map +1 -0
  165. package/dist/renderer/text-measurer/types.d.ts +30 -0
  166. package/dist/renderer/text-measurer/types.d.ts.map +1 -0
  167. package/dist/renderer/text-measurer/types.js +5 -0
  168. package/dist/renderer/text-measurer/types.js.map +1 -0
  169. package/dist/renderer/theme.d.ts +29 -0
  170. package/dist/renderer/theme.d.ts.map +1 -0
  171. package/dist/renderer/theme.js +80 -0
  172. package/dist/renderer/theme.js.map +1 -0
  173. package/dist/themes/dark.d.ts +6 -0
  174. package/dist/themes/dark.d.ts.map +1 -0
  175. package/dist/themes/dark.js +96 -0
  176. package/dist/themes/dark.js.map +1 -0
  177. package/dist/themes/index.d.ts +13 -0
  178. package/dist/themes/index.d.ts.map +1 -0
  179. package/dist/themes/index.js +15 -0
  180. package/dist/themes/index.js.map +1 -0
  181. package/dist/themes/modern.d.ts +6 -0
  182. package/dist/themes/modern.d.ts.map +1 -0
  183. package/dist/themes/modern.js +164 -0
  184. package/dist/themes/modern.js.map +1 -0
  185. package/dist/themes/types.d.ts +234 -0
  186. package/dist/themes/types.d.ts.map +1 -0
  187. package/dist/themes/types.js +5 -0
  188. package/dist/themes/types.js.map +1 -0
  189. package/dist/themes/utils.d.ts +21 -0
  190. package/dist/themes/utils.d.ts.map +1 -0
  191. package/dist/themes/utils.js +124 -0
  192. package/dist/themes/utils.js.map +1 -0
  193. package/package.json +92 -0
  194. package/src/icons/build-icons.ts +189 -0
  195. package/src/icons/default/access-point.svg +3 -0
  196. package/src/icons/default/cloud.svg +3 -0
  197. package/src/icons/default/database.svg +3 -0
  198. package/src/icons/default/firewall.svg +4 -0
  199. package/src/icons/default/generic.svg +3 -0
  200. package/src/icons/default/internet.svg +3 -0
  201. package/src/icons/default/l2-switch.svg +3 -0
  202. package/src/icons/default/l3-switch.svg +3 -0
  203. package/src/icons/default/load-balancer.svg +3 -0
  204. package/src/icons/default/router.svg +3 -0
  205. package/src/icons/default/server.svg +3 -0
  206. package/src/icons/default/vpn.svg +3 -0
  207. package/src/icons/generated-icons.ts +111 -0
  208. package/src/icons/index.ts +1 -0
  209. package/src/index.ts +21 -0
  210. package/src/layout/hierarchical.ts +1543 -0
  211. package/src/layout/index.ts +6 -0
  212. package/src/models/index.ts +5 -0
  213. package/src/models/types.ts +528 -0
  214. package/src/renderer/index.ts +6 -0
  215. package/src/renderer/svg.ts +997 -0
  216. package/src/themes/dark.ts +110 -0
  217. package/src/themes/index.ts +24 -0
  218. package/src/themes/modern.ts +186 -0
  219. package/src/themes/types.ts +262 -0
  220. package/src/themes/utils.ts +143 -0
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Dark theme
3
+ */
4
+
5
+ import type { Theme } from './types.js'
6
+ import { modernTheme } from './modern.js'
7
+ import { DeviceType } from '../models/index.js'
8
+
9
+ export const darkTheme: Theme = {
10
+ ...modernTheme,
11
+ name: 'dark',
12
+ variant: 'dark',
13
+
14
+ colors: {
15
+ ...modernTheme.colors,
16
+
17
+ // Backgrounds (inverted)
18
+ background: '#0f172a',
19
+ surface: '#1e293b',
20
+ surfaceHover: '#334155',
21
+
22
+ // Text (inverted)
23
+ text: '#f1f5f9',
24
+ textSecondary: '#94a3b8',
25
+ textDisabled: '#475569',
26
+
27
+ // Primary (adjusted for dark)
28
+ primary: '#60a5fa',
29
+ primaryHover: '#3b82f6',
30
+ primaryActive: '#2563eb',
31
+
32
+ // Secondary (adjusted for dark)
33
+ secondary: '#a78bfa',
34
+ secondaryHover: '#8b5cf6',
35
+ secondaryActive: '#7c3aed',
36
+
37
+ // Status (adjusted for dark)
38
+ success: '#34d399',
39
+ warning: '#fbbf24',
40
+ error: '#f87171',
41
+ info: '#60a5fa',
42
+
43
+ // Links
44
+ link: '#60a5fa',
45
+ linkHover: '#3b82f6',
46
+ linkDown: '#f87171',
47
+
48
+ // Device colors (adjusted for dark)
49
+ devices: {
50
+ [DeviceType.Router]: '#60a5fa',
51
+ [DeviceType.L3Switch]: '#a78bfa',
52
+ [DeviceType.L2Switch]: '#c4b5fd',
53
+ [DeviceType.Firewall]: '#f87171',
54
+ [DeviceType.LoadBalancer]: '#fbbf24',
55
+ [DeviceType.Server]: '#34d399',
56
+ [DeviceType.AccessPoint]: '#22d3ee',
57
+ [DeviceType.Cloud]: '#60a5fa',
58
+ [DeviceType.Internet]: '#818cf8',
59
+ [DeviceType.Generic]: '#64748b',
60
+ },
61
+
62
+ // Module colors (adjusted for dark)
63
+ modules: {
64
+ core: '#1e3a8a',
65
+ distribution: '#581c87',
66
+ access: '#064e3b',
67
+ dmz: '#7f1d1d',
68
+ cloud: '#312e81',
69
+ default: '#374151',
70
+ },
71
+
72
+ // Grid
73
+ grid: '#334155',
74
+ guideline: '#60a5fa',
75
+ },
76
+
77
+ shadows: {
78
+ ...modernTheme.shadows,
79
+
80
+ // Darker shadows for dark theme
81
+ small: {
82
+ color: '#000000',
83
+ blur: 4,
84
+ offsetX: 0,
85
+ offsetY: 1,
86
+ alpha: 0.3,
87
+ },
88
+ medium: {
89
+ color: '#000000',
90
+ blur: 10,
91
+ offsetX: 0,
92
+ offsetY: 4,
93
+ alpha: 0.4,
94
+ },
95
+ large: {
96
+ color: '#000000',
97
+ blur: 25,
98
+ offsetX: 0,
99
+ offsetY: 10,
100
+ alpha: 0.5,
101
+ },
102
+ glow: {
103
+ color: '#60a5fa',
104
+ blur: 20,
105
+ offsetX: 0,
106
+ offsetY: 0,
107
+ alpha: 0.7,
108
+ },
109
+ },
110
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Theme system exports
3
+ */
4
+
5
+ export * from './types.js'
6
+ export { modernTheme } from './modern.js'
7
+ export { darkTheme } from './dark.js'
8
+ export {
9
+ mergeTheme,
10
+ createTheme,
11
+ applyThemeToCSS,
12
+ getThemeFromCSS
13
+ } from './utils.js'
14
+
15
+ // Default themes map
16
+ import { modernTheme } from './modern.js'
17
+ import { darkTheme } from './dark.js'
18
+
19
+ export const themes = {
20
+ modern: modernTheme,
21
+ dark: darkTheme,
22
+ } as const
23
+
24
+ export type ThemeName = keyof typeof themes
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Modern theme - Default light theme
3
+ */
4
+
5
+ import type { Theme } from './types.js'
6
+ import { DeviceType } from '../models/index.js'
7
+
8
+ export const modernTheme: Theme = {
9
+ name: 'modern',
10
+ variant: 'light',
11
+
12
+ colors: {
13
+ // Backgrounds
14
+ background: '#ffffff',
15
+ surface: '#f8fafc',
16
+ surfaceHover: '#f1f5f9',
17
+
18
+ // Text
19
+ text: '#0f172a',
20
+ textSecondary: '#64748b',
21
+ textDisabled: '#cbd5e1',
22
+
23
+ // Primary (Blue)
24
+ primary: '#3b82f6',
25
+ primaryHover: '#2563eb',
26
+ primaryActive: '#1d4ed8',
27
+
28
+ // Secondary (Purple)
29
+ secondary: '#8b5cf6',
30
+ secondaryHover: '#7c3aed',
31
+ secondaryActive: '#6d28d9',
32
+
33
+ // Status
34
+ success: '#10b981',
35
+ warning: '#f59e0b',
36
+ error: '#ef4444',
37
+ info: '#3b82f6',
38
+
39
+ // Links
40
+ link: '#3b82f6',
41
+ linkHover: '#2563eb',
42
+ linkDown: '#ef4444',
43
+
44
+ // Device colors
45
+ devices: {
46
+ [DeviceType.Router]: '#3b82f6',
47
+ [DeviceType.L3Switch]: '#8b5cf6',
48
+ [DeviceType.L2Switch]: '#a78bfa',
49
+ [DeviceType.Firewall]: '#ef4444',
50
+ [DeviceType.LoadBalancer]: '#f59e0b',
51
+ [DeviceType.Server]: '#10b981',
52
+ [DeviceType.AccessPoint]: '#06b6d4',
53
+ [DeviceType.Cloud]: '#3b82f6',
54
+ [DeviceType.Internet]: '#6366f1',
55
+ [DeviceType.Generic]: '#94a3b8',
56
+ },
57
+
58
+ // Module colors
59
+ modules: {
60
+ core: '#dbeafe',
61
+ distribution: '#e9d5ff',
62
+ access: '#d1fae5',
63
+ dmz: '#fee2e2',
64
+ cloud: '#e0e7ff',
65
+ default: '#f3f4f6',
66
+ },
67
+
68
+ // Grid
69
+ grid: '#e5e7eb',
70
+ guideline: '#3b82f6',
71
+ },
72
+
73
+ dimensions: {
74
+ device: {
75
+ small: { width: 60, height: 40 },
76
+ medium: { width: 80, height: 60 },
77
+ large: { width: 120, height: 80 },
78
+ },
79
+
80
+ fontSize: {
81
+ tiny: 10,
82
+ small: 12,
83
+ medium: 14,
84
+ large: 16,
85
+ huge: 20,
86
+ },
87
+
88
+ lineWidth: {
89
+ thin: 1,
90
+ normal: 2,
91
+ thick: 3,
92
+ emphasis: 4,
93
+ },
94
+
95
+ spacing: {
96
+ xs: 4,
97
+ sm: 8,
98
+ md: 16,
99
+ lg: 24,
100
+ xl: 32,
101
+ },
102
+
103
+ radius: {
104
+ small: 4,
105
+ medium: 8,
106
+ large: 12,
107
+ round: 9999,
108
+ },
109
+ },
110
+
111
+ shadows: {
112
+ none: {
113
+ color: 'transparent',
114
+ blur: 0,
115
+ offsetX: 0,
116
+ offsetY: 0,
117
+ },
118
+ small: {
119
+ color: '#0f172a',
120
+ blur: 4,
121
+ offsetX: 0,
122
+ offsetY: 1,
123
+ alpha: 0.05,
124
+ },
125
+ medium: {
126
+ color: '#0f172a',
127
+ blur: 10,
128
+ offsetX: 0,
129
+ offsetY: 4,
130
+ alpha: 0.1,
131
+ },
132
+ large: {
133
+ color: '#0f172a',
134
+ blur: 25,
135
+ offsetX: 0,
136
+ offsetY: 10,
137
+ alpha: 0.15,
138
+ },
139
+ glow: {
140
+ color: '#3b82f6',
141
+ blur: 20,
142
+ offsetX: 0,
143
+ offsetY: 0,
144
+ alpha: 0.5,
145
+ },
146
+ },
147
+
148
+ animations: {
149
+ duration: {
150
+ instant: 0,
151
+ fast: 150,
152
+ normal: 300,
153
+ slow: 500,
154
+ },
155
+
156
+ easing: {
157
+ linear: 'linear',
158
+ easeIn: 'ease-in',
159
+ easeOut: 'ease-out',
160
+ easeInOut: 'ease-in-out',
161
+ bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
162
+ },
163
+ },
164
+
165
+ typography: {
166
+ fontFamily: {
167
+ sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
168
+ mono: 'ui-monospace, "Cascadia Mono", "Consolas", monospace',
169
+ display: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
170
+ },
171
+
172
+ fontWeight: {
173
+ light: 300,
174
+ regular: 400,
175
+ medium: 500,
176
+ semibold: 600,
177
+ bold: 700,
178
+ },
179
+
180
+ letterSpacing: {
181
+ tight: -0.025,
182
+ normal: 0,
183
+ wide: 0.025,
184
+ },
185
+ },
186
+ }
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Theme system types
3
+ */
4
+
5
+ import type { DeviceType } from '../models/index.js'
6
+
7
+ export interface ThemeColors {
8
+ /**
9
+ * Background colors
10
+ */
11
+ background: string
12
+ surface: string
13
+ surfaceHover: string
14
+
15
+ /**
16
+ * Text colors
17
+ */
18
+ text: string
19
+ textSecondary: string
20
+ textDisabled: string
21
+
22
+ /**
23
+ * Primary palette
24
+ */
25
+ primary: string
26
+ primaryHover: string
27
+ primaryActive: string
28
+
29
+ /**
30
+ * Secondary palette
31
+ */
32
+ secondary: string
33
+ secondaryHover: string
34
+ secondaryActive: string
35
+
36
+ /**
37
+ * Status colors
38
+ */
39
+ success: string
40
+ warning: string
41
+ error: string
42
+ info: string
43
+
44
+ /**
45
+ * Link colors
46
+ */
47
+ link: string
48
+ linkHover: string
49
+ linkDown: string
50
+
51
+ /**
52
+ * Device type colors
53
+ */
54
+ devices: Partial<Record<DeviceType | string, string>>
55
+
56
+ /**
57
+ * Module colors (for Bento Grid)
58
+ */
59
+ modules: {
60
+ core: string
61
+ distribution: string
62
+ access: string
63
+ dmz: string
64
+ cloud: string
65
+ default: string
66
+ }
67
+
68
+ /**
69
+ * Grid and guides
70
+ */
71
+ grid: string
72
+ guideline: string
73
+ }
74
+
75
+ export interface ThemeDimensions {
76
+ /**
77
+ * Device dimensions
78
+ */
79
+ device: {
80
+ small: { width: number; height: number }
81
+ medium: { width: number; height: number }
82
+ large: { width: number; height: number }
83
+ }
84
+
85
+ /**
86
+ * Font sizes
87
+ */
88
+ fontSize: {
89
+ tiny: number
90
+ small: number
91
+ medium: number
92
+ large: number
93
+ huge: number
94
+ }
95
+
96
+ /**
97
+ * Line widths
98
+ */
99
+ lineWidth: {
100
+ thin: number
101
+ normal: number
102
+ thick: number
103
+ emphasis: number
104
+ }
105
+
106
+ /**
107
+ * Spacing
108
+ */
109
+ spacing: {
110
+ xs: number
111
+ sm: number
112
+ md: number
113
+ lg: number
114
+ xl: number
115
+ }
116
+
117
+ /**
118
+ * Border radius
119
+ */
120
+ radius: {
121
+ small: number
122
+ medium: number
123
+ large: number
124
+ round: number
125
+ }
126
+ }
127
+
128
+ export interface ThemeShadows {
129
+ /**
130
+ * Shadow definitions
131
+ */
132
+ none: ShadowDefinition
133
+ small: ShadowDefinition
134
+ medium: ShadowDefinition
135
+ large: ShadowDefinition
136
+ glow: ShadowDefinition
137
+ }
138
+
139
+ export interface ShadowDefinition {
140
+ color: string
141
+ blur: number
142
+ offsetX: number
143
+ offsetY: number
144
+ alpha?: number
145
+ }
146
+
147
+ export interface ThemeAnimations {
148
+ /**
149
+ * Animation durations in ms
150
+ */
151
+ duration: {
152
+ instant: number
153
+ fast: number
154
+ normal: number
155
+ slow: number
156
+ }
157
+
158
+ /**
159
+ * Easing functions
160
+ */
161
+ easing: {
162
+ linear: string
163
+ easeIn: string
164
+ easeOut: string
165
+ easeInOut: string
166
+ bounce: string
167
+ }
168
+ }
169
+
170
+ export interface ThemeTypography {
171
+ /**
172
+ * Font families
173
+ */
174
+ fontFamily: {
175
+ sans: string
176
+ mono: string
177
+ display: string
178
+ }
179
+
180
+ /**
181
+ * Font weights
182
+ */
183
+ fontWeight: {
184
+ light: number
185
+ regular: number
186
+ medium: number
187
+ semibold: number
188
+ bold: number
189
+ }
190
+
191
+ /**
192
+ * Letter spacing
193
+ */
194
+ letterSpacing: {
195
+ tight: number
196
+ normal: number
197
+ wide: number
198
+ }
199
+ }
200
+
201
+ export interface Theme {
202
+ /**
203
+ * Theme name
204
+ */
205
+ name: string
206
+
207
+ /**
208
+ * Theme variant
209
+ */
210
+ variant: 'light' | 'dark'
211
+
212
+ /**
213
+ * Color definitions
214
+ */
215
+ colors: ThemeColors
216
+
217
+ /**
218
+ * Size definitions
219
+ */
220
+ dimensions: ThemeDimensions
221
+
222
+ /**
223
+ * Shadow definitions
224
+ */
225
+ shadows: ThemeShadows
226
+
227
+ /**
228
+ * Animation settings
229
+ */
230
+ animations: ThemeAnimations
231
+
232
+ /**
233
+ * Typography settings
234
+ */
235
+ typography: ThemeTypography
236
+
237
+ /**
238
+ * Custom properties
239
+ */
240
+ custom?: Record<string, unknown>
241
+ }
242
+
243
+ export interface ThemeOptions {
244
+ /**
245
+ * Base theme to extend
246
+ */
247
+ extends?: Theme
248
+
249
+ /**
250
+ * Partial overrides
251
+ */
252
+ overrides?: DeepPartial<Theme>
253
+ }
254
+
255
+ // Utility type for deep partial
256
+ export type DeepPartial<T> = {
257
+ [P in keyof T]?: T[P] extends (infer U)[]
258
+ ? DeepPartial<U>[]
259
+ : T[P] extends readonly (infer U)[]
260
+ ? readonly DeepPartial<U>[]
261
+ : DeepPartial<T[P]>
262
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Theme utilities
3
+ */
4
+
5
+ import type { Theme, ThemeOptions, DeepPartial } from './types.js'
6
+
7
+ /**
8
+ * Merge theme with overrides
9
+ */
10
+ export function mergeTheme(base: Theme, overrides?: DeepPartial<Theme>): Theme {
11
+ if (!overrides) return base
12
+
13
+ return deepMerge(base, overrides) as Theme
14
+ }
15
+
16
+ /**
17
+ * Create custom theme
18
+ */
19
+ export function createTheme(options: ThemeOptions): Theme {
20
+ const base = options.extends || getDefaultTheme()
21
+ return mergeTheme(base, options.overrides)
22
+ }
23
+
24
+ /**
25
+ * Apply theme to CSS variables
26
+ */
27
+ export function applyThemeToCSS(theme: Theme, root: HTMLElement = document.documentElement): void {
28
+ const prefix = '--shumoku'
29
+
30
+ // Colors
31
+ root.style.setProperty(`${prefix}-bg`, theme.colors.background)
32
+ root.style.setProperty(`${prefix}-surface`, theme.colors.surface)
33
+ root.style.setProperty(`${prefix}-text`, theme.colors.text)
34
+ root.style.setProperty(`${prefix}-text-secondary`, theme.colors.textSecondary)
35
+ root.style.setProperty(`${prefix}-primary`, theme.colors.primary)
36
+ root.style.setProperty(`${prefix}-secondary`, theme.colors.secondary)
37
+ root.style.setProperty(`${prefix}-success`, theme.colors.success)
38
+ root.style.setProperty(`${prefix}-warning`, theme.colors.warning)
39
+ root.style.setProperty(`${prefix}-error`, theme.colors.error)
40
+ root.style.setProperty(`${prefix}-info`, theme.colors.info)
41
+
42
+ // Dimensions
43
+ root.style.setProperty(`${prefix}-radius-sm`, `${theme.dimensions.radius.small}px`)
44
+ root.style.setProperty(`${prefix}-radius-md`, `${theme.dimensions.radius.medium}px`)
45
+ root.style.setProperty(`${prefix}-radius-lg`, `${theme.dimensions.radius.large}px`)
46
+
47
+ // Spacing
48
+ root.style.setProperty(`${prefix}-space-xs`, `${theme.dimensions.spacing.xs}px`)
49
+ root.style.setProperty(`${prefix}-space-sm`, `${theme.dimensions.spacing.sm}px`)
50
+ root.style.setProperty(`${prefix}-space-md`, `${theme.dimensions.spacing.md}px`)
51
+ root.style.setProperty(`${prefix}-space-lg`, `${theme.dimensions.spacing.lg}px`)
52
+ root.style.setProperty(`${prefix}-space-xl`, `${theme.dimensions.spacing.xl}px`)
53
+
54
+ // Typography
55
+ root.style.setProperty(`${prefix}-font-sans`, theme.typography.fontFamily.sans)
56
+ root.style.setProperty(`${prefix}-font-mono`, theme.typography.fontFamily.mono)
57
+
58
+ // Shadows
59
+ const shadowToCSS = (shadow: Theme['shadows'][keyof Theme['shadows']]) => {
60
+ const alpha = shadow.alpha || 1
61
+ const color = hexToRgba(shadow.color, alpha)
62
+ return `${shadow.offsetX}px ${shadow.offsetY}px ${shadow.blur}px ${color}`
63
+ }
64
+
65
+ root.style.setProperty(`${prefix}-shadow-sm`, shadowToCSS(theme.shadows.small))
66
+ root.style.setProperty(`${prefix}-shadow-md`, shadowToCSS(theme.shadows.medium))
67
+ root.style.setProperty(`${prefix}-shadow-lg`, shadowToCSS(theme.shadows.large))
68
+
69
+ // Set theme variant
70
+ root.setAttribute('data-theme', theme.variant)
71
+ }
72
+
73
+ /**
74
+ * Get theme from CSS variables
75
+ */
76
+ export function getThemeFromCSS(root: HTMLElement = document.documentElement): Partial<Theme> {
77
+ const prefix = '--shumoku'
78
+ const style = getComputedStyle(root)
79
+
80
+ const getVar = (name: string) => style.getPropertyValue(`${prefix}-${name}`).trim()
81
+
82
+ return {
83
+ variant: root.getAttribute('data-theme') as 'light' | 'dark' || 'light',
84
+ colors: {
85
+ background: getVar('bg'),
86
+ surface: getVar('surface'),
87
+ text: getVar('text'),
88
+ textSecondary: getVar('text-secondary'),
89
+ primary: getVar('primary'),
90
+ secondary: getVar('secondary'),
91
+ success: getVar('success'),
92
+ warning: getVar('warning'),
93
+ error: getVar('error'),
94
+ info: getVar('info'),
95
+ } as Theme['colors'],
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Convert hex color to rgba
101
+ */
102
+ function hexToRgba(hex: string, alpha: number = 1): string {
103
+ if (hex === 'transparent') return 'transparent'
104
+
105
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
106
+ if (!result) return hex
107
+
108
+ const r = parseInt(result[1], 16)
109
+ const g = parseInt(result[2], 16)
110
+ const b = parseInt(result[3], 16)
111
+
112
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`
113
+ }
114
+
115
+ /**
116
+ * Deep merge utility
117
+ */
118
+ function deepMerge(target: any, source: any): any {
119
+ if (!source) return target
120
+
121
+ const result = { ...target }
122
+
123
+ for (const key in source) {
124
+ if (source.hasOwnProperty(key)) {
125
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
126
+ result[key] = deepMerge(target[key] || {}, source[key])
127
+ } else {
128
+ result[key] = source[key]
129
+ }
130
+ }
131
+ }
132
+
133
+ return result
134
+ }
135
+
136
+ /**
137
+ * Get default theme
138
+ */
139
+ function getDefaultTheme(): Theme {
140
+ // Lazy import to avoid circular dependency
141
+ const { modernTheme } = require('./modern')
142
+ return modernTheme
143
+ }