@vobs/ui 0.3.0 → 1.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 (212) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +60 -0
  3. package/package.json +52 -110
  4. package/src/activity-rail.ts +125 -0
  5. package/src/alert.ts +65 -0
  6. package/src/assets/icons/alert-circle.svg +1 -0
  7. package/src/assets/icons/alert-triangle.svg +1 -0
  8. package/src/assets/icons/alert.d27e24.svg +1 -0
  9. package/src/assets/icons/alert.svg +1 -0
  10. package/src/assets/icons/apple.svg +1 -0
  11. package/src/assets/icons/arrow-down.svg +1 -0
  12. package/src/assets/icons/arrow-expand.svg +1 -0
  13. package/src/assets/icons/arrow-left.svg +1 -0
  14. package/src/assets/icons/arrow-minimize.svg +1 -0
  15. package/src/assets/icons/arrow-right-to-line.svg +1 -0
  16. package/src/assets/icons/arrow-right.svg +1 -0
  17. package/src/assets/icons/arrow-up-right.svg +1 -0
  18. package/src/assets/icons/arrow-up.0c0c0d.svg +1 -0
  19. package/src/assets/icons/arrow-up.svg +1 -0
  20. package/src/assets/icons/at.svg +1 -0
  21. package/src/assets/icons/atom.0c0c0d.svg +1 -0
  22. package/src/assets/icons/atom.svg +1 -0
  23. package/src/assets/icons/bar.svg +1 -0
  24. package/src/assets/icons/bell.svg +1 -0
  25. package/src/assets/icons/box.svg +1 -0
  26. package/src/assets/icons/bug.svg +1 -0
  27. package/src/assets/icons/calendar.svg +1 -0
  28. package/src/assets/icons/check-circle.33c192.svg +1 -0
  29. package/src/assets/icons/check-circle.svg +1 -0
  30. package/src/assets/icons/check.d1d3db.svg +1 -0
  31. package/src/assets/icons/check.svg +1 -0
  32. package/src/assets/icons/chevron-down.svg +1 -0
  33. package/src/assets/icons/chevron-right.svg +1 -0
  34. package/src/assets/icons/chevron-up.svg +1 -0
  35. package/src/assets/icons/circle.svg +1 -0
  36. package/src/assets/icons/clock.svg +1 -0
  37. package/src/assets/icons/cmd.svg +1 -0
  38. package/src/assets/icons/code.svg +1 -0
  39. package/src/assets/icons/columns.svg +1 -0
  40. package/src/assets/icons/copy.svg +1 -0
  41. package/src/assets/icons/cpu.svg +1 -0
  42. package/src/assets/icons/dashboard.0c0c0d.svg +1 -0
  43. package/src/assets/icons/dashboard.svg +1 -0
  44. package/src/assets/icons/dollar.svg +1 -0
  45. package/src/assets/icons/download.svg +1 -0
  46. package/src/assets/icons/edit.svg +1 -0
  47. package/src/assets/icons/extensions.svg +1 -0
  48. package/src/assets/icons/external.svg +1 -0
  49. package/src/assets/icons/eye.svg +1 -0
  50. package/src/assets/icons/file-text.svg +1 -0
  51. package/src/assets/icons/file.svg +1 -0
  52. package/src/assets/icons/files.svg +1 -0
  53. package/src/assets/icons/filter.svg +1 -0
  54. package/src/assets/icons/folder.svg +1 -0
  55. package/src/assets/icons/gear.svg +1 -0
  56. package/src/assets/icons/git.svg +1 -0
  57. package/src/assets/icons/github.svg +1 -0
  58. package/src/assets/icons/globe.svg +1 -0
  59. package/src/assets/icons/grid-2x2.svg +1 -0
  60. package/src/assets/icons/hash.svg +1 -0
  61. package/src/assets/icons/heart.svg +1 -0
  62. package/src/assets/icons/help.svg +1 -0
  63. package/src/assets/icons/home.svg +1 -0
  64. package/src/assets/icons/image.svg +1 -0
  65. package/src/assets/icons/info-circle.svg +1 -0
  66. package/src/assets/icons/info-square.svg +1 -0
  67. package/src/assets/icons/info.387bff.svg +1 -0
  68. package/src/assets/icons/info.svg +1 -0
  69. package/src/assets/icons/key.svg +1 -0
  70. package/src/assets/icons/layers.svg +1 -0
  71. package/src/assets/icons/layout.svg +1 -0
  72. package/src/assets/icons/link.svg +1 -0
  73. package/src/assets/icons/list.svg +1 -0
  74. package/src/assets/icons/lock.svg +1 -0
  75. package/src/assets/icons/log-out.svg +1 -0
  76. package/src/assets/icons/logo.svg +1 -0
  77. package/src/assets/icons/mail.svg +1 -0
  78. package/src/assets/icons/menu.svg +1 -0
  79. package/src/assets/icons/message-circle.svg +1 -0
  80. package/src/assets/icons/message-plus.svg +1 -0
  81. package/src/assets/icons/message-square.svg +1 -0
  82. package/src/assets/icons/mic.svg +1 -0
  83. package/src/assets/icons/minus.svg +1 -0
  84. package/src/assets/icons/moon.svg +1 -0
  85. package/src/assets/icons/more-h.svg +1 -0
  86. package/src/assets/icons/mouse.svg +1 -0
  87. package/src/assets/icons/palette.svg +1 -0
  88. package/src/assets/icons/panel-bottom.svg +1 -0
  89. package/src/assets/icons/pause.svg +1 -0
  90. package/src/assets/icons/play.svg +1 -0
  91. package/src/assets/icons/plug.svg +1 -0
  92. package/src/assets/icons/plus.0c0c0d.svg +1 -0
  93. package/src/assets/icons/plus.svg +1 -0
  94. package/src/assets/icons/refresh.svg +1 -0
  95. package/src/assets/icons/ruler.svg +1 -0
  96. package/src/assets/icons/scroll-text.svg +1 -0
  97. package/src/assets/icons/search-menu.svg +1 -0
  98. package/src/assets/icons/search.svg +1 -0
  99. package/src/assets/icons/send.0c0c0d.svg +1 -0
  100. package/src/assets/icons/send.svg +1 -0
  101. package/src/assets/icons/settings.0c0c0d.svg +1 -0
  102. package/src/assets/icons/settings.svg +1 -0
  103. package/src/assets/icons/shield.svg +1 -0
  104. package/src/assets/icons/sidebar-left.svg +1 -0
  105. package/src/assets/icons/sidebar-right.svg +1 -0
  106. package/src/assets/icons/sliders.svg +1 -0
  107. package/src/assets/icons/sparkles.32f08c.svg +1 -0
  108. package/src/assets/icons/sparkles.svg +1 -0
  109. package/src/assets/icons/square.svg +1 -0
  110. package/src/assets/icons/star.svg +1 -0
  111. package/src/assets/icons/sun.svg +1 -0
  112. package/src/assets/icons/terminal.svg +1 -0
  113. package/src/assets/icons/trash.svg +1 -0
  114. package/src/assets/icons/trending-down.svg +1 -0
  115. package/src/assets/icons/trending-up.svg +1 -0
  116. package/src/assets/icons/type.svg +1 -0
  117. package/src/assets/icons/upload.svg +1 -0
  118. package/src/assets/icons/user-circle.svg +1 -0
  119. package/src/assets/icons/user.svg +1 -0
  120. package/src/assets/icons/users.svg +1 -0
  121. package/src/assets/icons/wrench.svg +1 -0
  122. package/src/assets/icons/x-circle.svg +1 -0
  123. package/src/assets/icons/x.svg +1 -0
  124. package/src/assets/icons/zap.0c0c0d.svg +1 -0
  125. package/src/assets/icons/zap.svg +1 -0
  126. package/src/avatar.ts +64 -0
  127. package/src/button.ts +88 -0
  128. package/src/card.ts +59 -0
  129. package/src/chat-composer.ts +156 -0
  130. package/src/dialog.ts +127 -0
  131. package/src/drawer.ts +131 -0
  132. package/src/editor-tabs.ts +184 -0
  133. package/src/file-tree.ts +214 -0
  134. package/src/forms.ts +270 -0
  135. package/src/icon.ts +117 -0
  136. package/src/icons.js +165 -0
  137. package/src/index.test.ts +213 -0
  138. package/src/index.ts +94 -0
  139. package/src/kbd.ts +72 -0
  140. package/src/menu.ts +119 -0
  141. package/src/nav-list.ts +157 -0
  142. package/src/overlay.test.ts +66 -0
  143. package/src/overlay.ts +205 -0
  144. package/src/page-header.ts +97 -0
  145. package/src/pagination.ts +163 -0
  146. package/src/second-batch.test.ts +205 -0
  147. package/src/stat-card.ts +92 -0
  148. package/src/status-bar.ts +108 -0
  149. package/src/styles/base.css +240 -0
  150. package/src/styles/components.css +1234 -0
  151. package/{dist → src/styles}/styles.css +2 -0
  152. package/src/styles/toast.css +57 -0
  153. package/src/styles/tokens.css +438 -0
  154. package/src/styles/vui.css +47 -0
  155. package/src/table.ts +191 -0
  156. package/src/tabs.ts +100 -0
  157. package/src/tag.ts +33 -0
  158. package/src/third-batch.test.ts +137 -0
  159. package/src/toast.test.ts +55 -0
  160. package/src/toast.ts +79 -0
  161. package/src/types.ts +25 -0
  162. package/src/utils.ts +221 -0
  163. package/src/workbench-titlebar.ts +137 -0
  164. package/dist/app-shell-dom.d.ts +0 -30
  165. package/dist/app-shell-dom.js +0 -913
  166. package/dist/app-shell.d.ts +0 -235
  167. package/dist/app-shell.js +0 -415
  168. package/dist/base.css +0 -51
  169. package/dist/calendar-picker.d.ts +0 -45
  170. package/dist/calendar-picker.js +0 -217
  171. package/dist/calendar.d.ts +0 -95
  172. package/dist/calendar.js +0 -194
  173. package/dist/complex-inputs.d.ts +0 -300
  174. package/dist/complex-inputs.js +0 -866
  175. package/dist/components.css +0 -4756
  176. package/dist/data-display.d.ts +0 -1094
  177. package/dist/data-display.js +0 -2341
  178. package/dist/dialog.d.ts +0 -26
  179. package/dist/dialog.js +0 -94
  180. package/dist/feedback.d.ts +0 -88
  181. package/dist/feedback.js +0 -281
  182. package/dist/forms.d.ts +0 -378
  183. package/dist/forms.js +0 -1019
  184. package/dist/icons-config.d.ts +0 -25
  185. package/dist/icons-config.js +0 -14
  186. package/dist/icons.d.ts +0 -41
  187. package/dist/icons.js +0 -185
  188. package/dist/index.d.ts +0 -31
  189. package/dist/index.js +0 -40
  190. package/dist/locale/en-US.d.ts +0 -31
  191. package/dist/locale/en-US.js +0 -20
  192. package/dist/locale/zh-CN.d.ts +0 -31
  193. package/dist/locale/zh-CN.js +0 -20
  194. package/dist/navigation.d.ts +0 -609
  195. package/dist/navigation.js +0 -1707
  196. package/dist/overlay.d.ts +0 -308
  197. package/dist/overlay.js +0 -974
  198. package/dist/page-state.d.ts +0 -23
  199. package/dist/page-state.js +0 -96
  200. package/dist/primitives.d.ts +0 -268
  201. package/dist/primitives.js +0 -764
  202. package/dist/theme-data.d.ts +0 -394
  203. package/dist/theme-data.js +0 -417
  204. package/dist/theme.d.ts +0 -97
  205. package/dist/theme.js +0 -301
  206. package/dist/tokens.css +0 -570
  207. package/dist/tree.d.ts +0 -144
  208. package/dist/tree.js +0 -475
  209. package/dist/virtual-list.d.ts +0 -190
  210. package/dist/virtual-list.js +0 -538
  211. package/dist/workbench.d.ts +0 -136
  212. package/dist/workbench.js +0 -156
@@ -1,417 +0,0 @@
1
- /** @license MIT
2
- * Copyright (c) 2026 vobsjs
3
- * @vobs/ui
4
- */
5
- export const DEFAULT_THEME = 'dark';
6
- export const DEFAULT_BRAND_ID = 'green';
7
- export const DEFAULT_BRAND_COLOR = '#32F08C';
8
- export const brandPresets = [
9
- { id: 'green', label: 'Nimbus Green', color: DEFAULT_BRAND_COLOR },
10
- { id: 'blue', label: 'Nimbus Blue', color: '#80C1FF' },
11
- { id: 'purple', label: 'Nimbus Purple', color: '#8E80FF' },
12
- { id: 'yellow', label: 'Nimbus Yellow', color: '#FFD080' },
13
- { id: 'red', label: 'Nimbus Red', color: '#FF8080' },
14
- { id: 'teal', label: 'Nimbus Teal', color: '#2DD288' },
15
- { id: 'cyan', label: 'Nimbus Cyan', color: '#04CBE5' },
16
- { id: 'violet', label: 'Nimbus Violet', color: '#BFA5FF' },
17
- { id: 'slate', label: 'Nimbus Slate', color: '#AFB9CF' },
18
- { id: 'neutral', label: 'Nimbus Neutral', color: '#BABABA' },
19
- ];
20
- export const primitiveTokenValues = {
21
- '--radius-2': '2px',
22
- '--radius-4': '4px',
23
- '--radius-6': '6px',
24
- '--radius-8': '8px',
25
- '--radius-10': '10px',
26
- '--radius-full': '9999px',
27
- '--spacer-0': '0px',
28
- '--spacer-2': '2px',
29
- '--spacer-4': '4px',
30
- '--spacer-6': '6px',
31
- '--spacer-8': '8px',
32
- '--spacer-10': '10px',
33
- '--spacer-12': '12px',
34
- '--spacer-14': '14px',
35
- '--spacer-16': '16px',
36
- '--spacer-20': '20px',
37
- '--spacer-24': '24px',
38
- '--spacer-32': '32px',
39
- '--spacer-40': '40px',
40
- '--k-icon-xs': '14px',
41
- '--k-icon-sm': '16px',
42
- '--k-icon-md': '20px',
43
- '--k-icon-lg': '24px',
44
- '--font-family-default': 'SF Pro Text',
45
- '--font-family-heading': 'SF Pro',
46
- '--font-family-mono': 'JetBrains Mono',
47
- '--font-family-base': 'var(--font-family-default)',
48
- '--font-family-heading-alias': 'var(--font-family-heading)',
49
- '--font-family-mono-alias': 'var(--font-family-mono)',
50
- '--body-xs-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
51
- '--body-xs-font-size': '10px',
52
- '--body-xs-font-weight': '400',
53
- '--body-xs-line-height': '14px',
54
- '--body-sm-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
55
- '--body-sm-font-size': '11px',
56
- '--body-sm-font-weight': '400',
57
- '--body-sm-line-height': '16px',
58
- '--body-sm-strong-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
59
- '--body-sm-strong-font-size': '11px',
60
- '--body-sm-strong-font-weight': '500',
61
- '--body-sm-strong-line-height': '16px',
62
- '--body-md-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
63
- '--body-md-font-size': '12px',
64
- '--body-md-font-weight': '400',
65
- '--body-md-line-height': '18px',
66
- '--body-md-strong-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
67
- '--body-md-strong-font-size': '12px',
68
- '--body-md-strong-font-weight': '500',
69
- '--body-md-strong-line-height': '18px',
70
- '--body-base-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
71
- '--body-base-font-size': '13px',
72
- '--body-base-font-weight': '400',
73
- '--body-base-line-height': '20px',
74
- '--body-base-strong-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
75
- '--body-base-strong-font-size': '13px',
76
- '--body-base-strong-font-weight': '500',
77
- '--body-base-strong-line-height': '20px',
78
- '--heading-3xs-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
79
- '--heading-3xs-font-size': '11px',
80
- '--heading-3xs-font-weight': '600',
81
- '--heading-3xs-line-height': '16px',
82
- '--heading-2xs-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
83
- '--heading-2xs-font-size': '12px',
84
- '--heading-2xs-font-weight': '600',
85
- '--heading-2xs-line-height': '18px',
86
- '--heading-xs-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
87
- '--heading-xs-font-size': '13px',
88
- '--heading-xs-font-weight': '600',
89
- '--heading-xs-line-height': '20px',
90
- '--heading-sm-font-family': '"SF Pro Text", system-ui, -apple-system, sans-serif',
91
- '--heading-sm-font-size': '16px',
92
- '--heading-sm-font-weight': '600',
93
- '--heading-sm-line-height': '24px',
94
- '--heading-md-font-family': '"SF Pro", system-ui, -apple-system, sans-serif',
95
- '--heading-md-font-size': '20px',
96
- '--heading-md-font-weight': '600',
97
- '--heading-md-line-height': '28px',
98
- '--heading-lg-font-family': '"SF Pro", system-ui, -apple-system, sans-serif',
99
- '--heading-lg-font-size': '22px',
100
- '--heading-lg-font-weight': '600',
101
- '--heading-lg-line-height': '30px',
102
- '--heading-xl-font-family': '"SF Pro", system-ui, -apple-system, sans-serif',
103
- '--heading-xl-font-size': '24px',
104
- '--heading-xl-font-weight': '600',
105
- '--heading-xl-line-height': '32px',
106
- '--heading-2xl-font-family': '"SF Pro", system-ui, -apple-system, sans-serif',
107
- '--heading-2xl-font-size': '28px',
108
- '--heading-2xl-font-weight': '600',
109
- '--heading-2xl-line-height': '36px',
110
- '--heading-3xl-font-family': '"SF Pro", system-ui, -apple-system, sans-serif',
111
- '--heading-3xl-font-size': '32px',
112
- '--heading-3xl-font-weight': '600',
113
- '--heading-3xl-line-height': '40px',
114
- '--code-editor-font-family': '"JetBrains Mono", system-ui, -apple-system, sans-serif',
115
- '--code-editor-font-size': '13px',
116
- '--code-editor-font-weight': '450',
117
- '--code-editor-line-height': '20px',
118
- '--code-terminal-font-family': '"JetBrains Mono", system-ui, -apple-system, sans-serif',
119
- '--code-terminal-font-size': '12px',
120
- '--code-terminal-font-weight': '450',
121
- '--code-terminal-line-height': '18px',
122
- '--font-weight-default': '400',
123
- '--font-weight-regular': 'var(--font-weight-default)',
124
- '--font-weight-code': '450',
125
- '--font-weight-medium': '500',
126
- '--font-weight-strong': '600',
127
- '--font-weight-semibold': 'var(--font-weight-strong)',
128
- '--z-index-dropdown': '2000',
129
- '--z-index-drawer': '2500',
130
- '--z-index-modal': '3000',
131
- '--z-index-notification': '3500',
132
- '--z-index-tooltip': '4000',
133
- '--transition-fast': '0.12s ease',
134
- '--transition-normal': '0.2s ease',
135
- '--transition-slow': '0.3s ease',
136
- '--breakpoint-sm': '576px',
137
- '--breakpoint-md': '768px',
138
- '--breakpoint-lg': '1024px',
139
- '--breakpoint-xl': '1280px',
140
- };
141
- const semanticAliases = {
142
- '--color-background': 'var(--bg-base-default)',
143
- '--color-surface': 'var(--bg-base-secondary)',
144
- '--color-surface-variant': 'var(--bg-base-tertiary)',
145
- '--color-overlay-1': 'var(--bg-overlay-l1)',
146
- '--color-overlay-2': 'var(--bg-overlay-l2)',
147
- '--color-overlay-3': 'var(--bg-overlay-l3)',
148
- '--color-overlay-4': 'var(--bg-overlay-l4)',
149
- '--color-card': 'var(--bg-base-secondary)',
150
- '--color-tooltip': 'var(--bg-tooltip)',
151
- '--color-menu': 'var(--bg-menu)',
152
- '--color-foreground': 'var(--text-default)',
153
- '--color-foreground-hover': 'var(--text-default-hover)',
154
- '--color-on-surface': 'var(--text-default)',
155
- '--color-on-surface-variant': 'var(--text-secondary)',
156
- '--color-muted-foreground': 'var(--text-secondary)',
157
- '--color-disabled-foreground': 'var(--text-disabled)',
158
- '--color-border': 'var(--border-neutral-l1)',
159
- '--color-border-strong': 'var(--border-neutral-l2)',
160
- '--color-border-stronger': 'var(--border-neutral-l3)',
161
- '--color-border-contrast': 'var(--border-contrast)',
162
- '--color-outline': 'var(--border-neutral-l1)',
163
- '--color-primary': 'var(--bg-brand)',
164
- '--color-primary-hover': 'var(--bg-brand-hover)',
165
- '--color-primary-disabled': 'var(--bg-brand-disabled)',
166
- '--color-primary-soft': 'var(--bg-brand-popup)',
167
- '--color-accent': 'var(--bg-brand)',
168
- '--color-on-primary': 'var(--text-onbrand)',
169
- '--color-info': 'var(--status-primary-default)',
170
- '--color-success': 'var(--status-success-default)',
171
- '--color-warning': 'var(--status-warning-default)',
172
- '--color-error': 'var(--status-error-default)',
173
- '--color-error-soft': 'var(--status-error-surface-l1)',
174
- '--color-foreground-muted': 'var(--text-secondary)',
175
- '--accent-blue': 'var(--status-primary-default)',
176
- '--code-string': 'var(--code-text)',
177
- };
178
- export const themeTokenValues = {
179
- dark: {
180
- '--bg-base-default': '#1A1B1D',
181
- '--bg-base-secondary': '#222427',
182
- '--bg-base-tertiary': '#2A2D31',
183
- '--bg-tooltip': '#1A1B1D',
184
- '--bg-menu': '#202123',
185
- '--bg-invert': '#DADDE5',
186
- '--bg-invert-hover': '#EDEFF2',
187
- '--bg-invert-active': '#979AA4',
188
- '--bg-invert-disabled': 'rgba(224, 226, 242, 0.12)',
189
- '--bg-overlay-l1': 'rgba(224, 226, 242, 0.04)',
190
- '--bg-overlay-l2': 'rgba(224, 226, 242, 0.06)',
191
- '--bg-overlay-l3': 'rgba(224, 226, 242, 0.08)',
192
- '--bg-overlay-l4': 'rgba(224, 226, 242, 0.12)',
193
- '--text-default': '#D1D3DB',
194
- '--text-default-hover': '#F5F9FE',
195
- '--text-default-active': '#F5F9FE',
196
- '--text-secondary': '#9599A6',
197
- '--text-secondary-hover': '#D1D3DB',
198
- '--text-secondary-active': '#D1D3DB',
199
- '--text-tertiary': '#666B75',
200
- '--text-disabled': '#666B75',
201
- '--text-onbrand': '#0C0C0D',
202
- '--text-onaccent': '#0C0C0D',
203
- '--icon-default': '#D1D3DB',
204
- '--icon-default-hover': '#F5F9FE',
205
- '--icon-default-active': '#F5F9FE',
206
- '--icon-secondary': '#9599A6',
207
- '--icon-secondary-hover': '#D1D3DB',
208
- '--icon-secondary-active': '#D1D3DB',
209
- '--icon-tertiary': '#666B75',
210
- '--icon-disabled': '#666B75',
211
- '--icon-onbrand': '#0C0C0D',
212
- '--icon-onaccent': '#0C0C0D',
213
- '--border-neutral-l1': 'rgba(224, 226, 242, 0.1)',
214
- '--border-neutral-l2': 'rgba(224, 226, 242, 0.16)',
215
- '--border-neutral-l3': 'rgba(224, 226, 242, 0.2)',
216
- '--border-contrast': '#FFFFFF',
217
- '--status-primary-default': '#387BFF',
218
- '--status-primary-hover': '#4C88FF',
219
- '--status-primary-active': '#1759DD',
220
- '--status-primary-surface-l1': 'rgba(53, 121, 255, 0.18)',
221
- '--status-primary-surface-l2': 'rgba(53, 121, 255, 0.28)',
222
- '--status-primary-surface-l3': 'rgba(53, 121, 255, 0.36)',
223
- '--status-info-default': 'var(--status-primary-default)',
224
- '--status-info-surface-l1': 'var(--status-primary-surface-l1)',
225
- '--status-success-default': '#33C192',
226
- '--status-success-hover': '#5ED4AD',
227
- '--status-success-active': '#27B082',
228
- '--status-success-surface-l1': 'rgba(0, 165, 110, 0.18)',
229
- '--status-success-surface-l2': 'rgba(0, 165, 110, 0.28)',
230
- '--status-success-surface-l3': 'rgba(0, 165, 110, 0.36)',
231
- '--status-alert-default': '#D29D00',
232
- '--status-alert-hover': '#DFB949',
233
- '--status-alert-active': '#AB8820',
234
- '--status-alert-surface-l1': 'rgba(210, 157, 0, 0.16)',
235
- '--status-alert-surface-l2': 'rgba(210, 157, 0, 0.28)',
236
- '--status-alert-surface-l3': 'rgba(210, 157, 0, 0.36)',
237
- '--status-warning-default': '#D27E24',
238
- '--status-warning-hover': '#D78B28',
239
- '--status-warning-active': '#B46510',
240
- '--status-warning-surface-l1': 'rgba(210, 126, 36, 0.16)',
241
- '--status-warning-surface-l2': 'rgba(210, 126, 36, 0.28)',
242
- '--status-warning-surface-l3': 'rgba(210, 126, 36, 0.36)',
243
- '--status-error-default': '#F65A5A',
244
- '--status-error-hover': '#F86262',
245
- '--status-error-active': '#B33636',
246
- '--status-error-surface-l1': 'rgba(246, 70, 70, 0.18)',
247
- '--status-error-surface-l2': 'rgba(246, 70, 70, 0.28)',
248
- '--status-error-surface-l3': 'rgba(246, 70, 70, 0.36)',
249
- '--code-text': '#E0E3EE',
250
- '--code-doc': '#7F838C',
251
- '--code-link': '#3C7EFF',
252
- '--code-number': '#F48CCA',
253
- '--code-action': '#B38CFF',
254
- '--code-instruction': '#F0D8FF',
255
- '--code-function': '#F29D79',
256
- '--code-constant': '#80BBFF',
257
- '--code-parameter': '#82D99F',
258
- '--code-attribute': '#DED47E',
259
- '--code-tag': '#F2858C',
260
- ...semanticAliases,
261
- },
262
- light: {
263
- '--bg-base-default': '#FFFFFF',
264
- '--bg-base-secondary': '#F5F6F8',
265
- '--bg-base-tertiary': '#EDF0F5',
266
- '--bg-tooltip': '#0F1117',
267
- '--bg-menu': '#FFFFFF',
268
- '--bg-invert': '#0F1117',
269
- '--bg-invert-hover': '#1F2937',
270
- '--bg-invert-active': '#374151',
271
- '--bg-invert-disabled': 'rgba(15, 17, 23, 0.12)',
272
- '--bg-overlay-l1': 'rgba(0, 0, 0, 0.04)',
273
- '--bg-overlay-l2': 'rgba(0, 0, 0, 0.06)',
274
- '--bg-overlay-l3': 'rgba(0, 0, 0, 0.08)',
275
- '--bg-overlay-l4': 'rgba(0, 0, 0, 0.12)',
276
- '--text-default': '#0F1117',
277
- '--text-default-hover': '#000000',
278
- '--text-default-active': '#000000',
279
- '--text-secondary': '#4B5563',
280
- '--text-secondary-hover': '#1F2937',
281
- '--text-secondary-active': '#1F2937',
282
- '--text-tertiary': '#5B6370',
283
- '--text-disabled': '#525A68',
284
- '--text-onbrand': '#FFFFFF',
285
- '--text-onaccent': '#FFFFFF',
286
- '--icon-default': '#0F1117',
287
- '--icon-default-hover': '#000000',
288
- '--icon-default-active': '#000000',
289
- '--icon-secondary': '#4B5563',
290
- '--icon-secondary-hover': '#1F2937',
291
- '--icon-secondary-active': '#1F2937',
292
- '--icon-tertiary': '#5B6370',
293
- '--icon-disabled': '#525A68',
294
- '--icon-onbrand': '#FFFFFF',
295
- '--icon-onaccent': '#FFFFFF',
296
- '--border-neutral-l1': 'rgba(0, 0, 0, 0.12)',
297
- '--border-neutral-l2': 'rgba(0, 0, 0, 0.18)',
298
- '--border-neutral-l3': 'rgba(0, 0, 0, 0.25)',
299
- '--border-contrast': '#0F1117',
300
- '--status-success-default': '#16A34A',
301
- '--status-warning-default': '#CA8A04',
302
- '--status-error-default': '#DC2626',
303
- '--status-info-default': '#2E69FF',
304
- '--status-success-surface-l1': 'rgba(22, 163, 74, 0.08)',
305
- '--status-warning-surface-l1': 'rgba(202, 138, 4, 0.08)',
306
- '--status-error-surface-l1': 'rgba(220, 38, 38, 0.08)',
307
- '--status-info-surface-l1': 'rgba(46, 105, 255, 0.08)',
308
- ...semanticAliases,
309
- },
310
- };
311
- export function resolveBrandColor(value = DEFAULT_BRAND_ID) {
312
- if (typeof value === 'object') {
313
- const color = normalizeHexColor(value.color);
314
- return {
315
- id: value.id?.trim() || 'custom',
316
- label: value.label?.trim() || value.id?.trim() || color,
317
- color,
318
- };
319
- }
320
- const input = value.trim();
321
- const preset = brandPresets.find((item) => item.id === input || item.color.toLowerCase() === input.toLowerCase());
322
- if (preset !== undefined)
323
- return preset;
324
- const color = normalizeHexColor(input);
325
- return { id: 'custom', label: color, color };
326
- }
327
- export function deriveBrandTokens(color) {
328
- const normalized = normalizeHexColor(color);
329
- if (normalized === DEFAULT_BRAND_COLOR) {
330
- return {
331
- background: DEFAULT_BRAND_COLOR,
332
- hover: '#0FDC78',
333
- disabled: 'rgba(50, 240, 140, 0.2)',
334
- soft: 'rgba(50, 240, 140, 0.12)',
335
- onBrand: '#0C0C0D',
336
- };
337
- }
338
- const dark = perceivedBrightness(normalized) < 150;
339
- return {
340
- background: normalized,
341
- hover: mixHex(normalized, dark ? '#FFFFFF' : '#000000', 0.14),
342
- disabled: hexToRgba(normalized, 0.3),
343
- soft: hexToRgba(normalized, 0.12),
344
- onBrand: contrastRatio(normalized, '#FFFFFF') >= contrastRatio(normalized, '#0C0C0D')
345
- ? '#FFFFFF'
346
- : '#0C0C0D',
347
- };
348
- }
349
- export function deriveBrandTextColor(color) {
350
- const normalized = normalizeHexColor(color);
351
- if (contrastRatio(normalized, '#FFFFFF') >= 4.5)
352
- return normalized;
353
- let low = 0;
354
- let high = 1;
355
- for (let index = 0; index < 24; index += 1) {
356
- const amount = (low + high) / 2;
357
- const candidate = mixHex(normalized, '#000000', amount);
358
- if (contrastRatio(candidate, '#FFFFFF') >= 4.5)
359
- high = amount;
360
- else
361
- low = amount;
362
- }
363
- return mixHex(normalized, '#000000', high);
364
- }
365
- export function normalizeHexColor(value) {
366
- const input = value.trim();
367
- const short = /^#?([0-9a-f]{3})$/iu.exec(input);
368
- if (short?.[1] !== undefined) {
369
- return `#${Array.from(short[1], (character) => character.repeat(2)).join('')}`.toUpperCase();
370
- }
371
- const full = /^#?([0-9a-f]{6})$/iu.exec(input);
372
- if (full?.[1] !== undefined)
373
- return `#${full[1]}`.toUpperCase();
374
- throw new TypeError(`Invalid brand color: ${value}`);
375
- }
376
- export function contrastRatio(left, right) {
377
- const leftLuminance = relativeLuminance(normalizeHexColor(left));
378
- const rightLuminance = relativeLuminance(normalizeHexColor(right));
379
- const lighter = Math.max(leftLuminance, rightLuminance);
380
- const darker = Math.min(leftLuminance, rightLuminance);
381
- return (lighter + 0.05) / (darker + 0.05);
382
- }
383
- function relativeLuminance(color) {
384
- const { red, green, blue } = hexToRgb(color);
385
- const linear = (channel) => {
386
- const value = channel / 255;
387
- return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
388
- };
389
- return 0.2126 * linear(red) + 0.7152 * linear(green) + 0.0722 * linear(blue);
390
- }
391
- function perceivedBrightness(color) {
392
- const { red, green, blue } = hexToRgb(color);
393
- return red * 0.299 + green * 0.587 + blue * 0.114;
394
- }
395
- function mixHex(color, target, amount) {
396
- const sourceRgb = hexToRgb(color);
397
- const targetRgb = hexToRgb(target);
398
- const mix = (source, destination) => Math.round(source + (destination - source) * amount);
399
- return rgbToHex(mix(sourceRgb.red, targetRgb.red), mix(sourceRgb.green, targetRgb.green), mix(sourceRgb.blue, targetRgb.blue));
400
- }
401
- function hexToRgba(color, alpha) {
402
- const { red, green, blue } = hexToRgb(color);
403
- return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
404
- }
405
- function hexToRgb(color) {
406
- const normalized = normalizeHexColor(color).slice(1);
407
- return {
408
- red: Number.parseInt(normalized.slice(0, 2), 16),
409
- green: Number.parseInt(normalized.slice(2, 4), 16),
410
- blue: Number.parseInt(normalized.slice(4, 6), 16),
411
- };
412
- }
413
- function rgbToHex(red, green, blue) {
414
- return `#${[red, green, blue]
415
- .map((channel) => channel.toString(16).padStart(2, '0'))
416
- .join('')}`.toUpperCase();
417
- }
package/dist/theme.d.ts DELETED
@@ -1,97 +0,0 @@
1
- /** @license MIT
2
- * Copyright (c) 2026 vobsjs
3
- * @vobs/ui
4
- */
5
- import { type BrandColor, type BrandInput, type ThemeName } from './theme-data.js';
6
- export { brandPresets, contrastRatio, DEFAULT_BRAND_COLOR, DEFAULT_BRAND_ID, DEFAULT_THEME, deriveBrandTokens, deriveBrandTextColor, normalizeHexColor, resolveBrandColor, type BrandColor, type BrandColorInput, type BrandInput, type BrandTokens, type ThemeName, } from './theme-data.js';
7
- export interface ThemeStyleTarget {
8
- setProperty(name: string, value: string): void;
9
- removeProperty(name: string): string;
10
- }
11
- export interface ThemeTarget {
12
- readonly style: ThemeStyleTarget;
13
- setAttribute(name: string, value: string): void;
14
- }
15
- export interface ThemePersistence {
16
- readTheme?(): unknown;
17
- writeTheme?(theme: ThemeName): void;
18
- writeSystemTheme?(): void;
19
- readBrand?(): unknown;
20
- writeBrand?(brand: BrandColor): void;
21
- }
22
- export interface SystemThemePreference {
23
- read(): ThemeName;
24
- subscribe?(listener: (theme: ThemeName) => void): () => void;
25
- }
26
- export interface ThemeStorage {
27
- getItem(key: string): string | null;
28
- setItem(key: string, value: string): void;
29
- }
30
- export interface ThemeMediaQuery {
31
- readonly matches: boolean;
32
- addEventListener(type: 'change', listener: (event: {
33
- readonly matches: boolean;
34
- }) => void): void;
35
- removeEventListener(type: 'change', listener: (event: {
36
- readonly matches: boolean;
37
- }) => void): void;
38
- }
39
- export interface ThemeState {
40
- readonly theme: ThemeName;
41
- readonly brand: BrandColor;
42
- }
43
- export type ThemePreference = ThemeName | 'system';
44
- export declare const THEME_PREFERENCE_CHANGE_EVENT = "vobs:theme-preference-change";
45
- export declare const THEME_STATE_CHANGE_EVENT = "vobs:theme-state-change";
46
- export interface ThemePreferenceChangeDetail {
47
- readonly shellId?: string;
48
- readonly theme?: ThemePreference;
49
- readonly brand?: BrandInput;
50
- }
51
- export interface ThemeStateChangeDetail {
52
- readonly shellId: string;
53
- readonly theme: ThemeName;
54
- readonly preference: ThemePreference;
55
- readonly brand: BrandColor;
56
- }
57
- export interface ThemeControllerOptions {
58
- readonly target: ThemeTarget;
59
- readonly initialTheme?: ThemeName;
60
- readonly initialPreference?: ThemePreference;
61
- readonly initialBrand?: BrandInput;
62
- readonly persistence?: ThemePersistence;
63
- readonly systemPreference?: SystemThemePreference;
64
- readonly onWarning?: (message: string) => void;
65
- }
66
- export interface ThemeController {
67
- readonly theme: ThemeName;
68
- readonly preference: ThemePreference;
69
- readonly brand: BrandColor;
70
- readonly state: ThemeState;
71
- setTheme(theme: ThemeName): void;
72
- setPreference(preference: ThemePreference): void;
73
- toggleTheme(): ThemeName;
74
- setBrand(brand: BrandInput): BrandColor;
75
- subscribe(listener: (state: ThemeState) => void): () => void;
76
- destroy(): void;
77
- }
78
- export interface ThemeAttributes {
79
- readonly 'data-theme': ThemeName;
80
- readonly 'data-brand': string;
81
- readonly style?: string;
82
- }
83
- export declare function createThemeController(options: ThemeControllerOptions): ThemeController;
84
- export declare function createStorageThemePersistence(storage: ThemeStorage, keys?: {
85
- readonly theme?: string;
86
- readonly brand?: string;
87
- }): ThemePersistence;
88
- export declare function createMediaThemePreference(query: ThemeMediaQuery): SystemThemePreference;
89
- export declare function createThemeState(theme?: ThemeName, brand?: BrandInput): ThemeState;
90
- export declare function createThemeAttributes(state: ThemeState): ThemeAttributes;
91
- export declare function createThemeBootstrapScript(state: ThemeState): string;
92
- /**
93
- * Reads a design-token value (CSS variable) for the active theme, for third-party adapters (contract ui-adapters.md §3.1).
94
- * Data source: tokens.css variables on html[data-theme] (getComputedStyle reads the latest effective value).
95
- * Returns undefined without a document (SSR/non-browser) or when the variable is undefined — adapters must degrade gracefully.
96
- */
97
- export declare function resolveUiToken(name: `--${string}`): string | undefined;