@hilum/ui 3.8.5 → 3.10.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 (90) hide show
  1. package/README.md +32 -1
  2. package/dist/{chunk-RI6QJR2L.js → chunk-R576DV2A.js} +120 -14
  3. package/dist/chunk-R576DV2A.js.map +1 -0
  4. package/dist/create-theme.js +2 -1
  5. package/dist/create-theme.js.map +1 -1
  6. package/dist/index.d.ts +733 -68
  7. package/dist/index.js +3097 -1619
  8. package/dist/index.js.map +1 -1
  9. package/dist/tokens.css +163 -19
  10. package/dist/tokens.d.ts +69 -5
  11. package/dist/tokens.js +1 -1
  12. package/llms.txt +11 -4
  13. package/package.json +11 -10
  14. package/src/components/accordion.tsx +2 -2
  15. package/src/components/account-menu.tsx +1 -1
  16. package/src/components/alert-dialog.tsx +107 -0
  17. package/src/components/ask-user-questions.tsx +24 -18
  18. package/src/components/badge.tsx +36 -3
  19. package/src/components/breadcrumb.tsx +4 -2
  20. package/src/components/button-group.tsx +1 -1
  21. package/src/components/button.tsx +31 -23
  22. package/src/components/calendar.tsx +1 -1
  23. package/src/components/card.tsx +4 -2
  24. package/src/components/checkbox-card.tsx +1 -1
  25. package/src/components/checkbox-group.tsx +2 -1
  26. package/src/components/code-block.tsx +99 -0
  27. package/src/components/color-input.tsx +9 -6
  28. package/src/components/color-picker.tsx +38 -26
  29. package/src/components/combobox.tsx +59 -12
  30. package/src/components/command-palette.tsx +150 -42
  31. package/src/components/command.tsx +5 -3
  32. package/src/components/context-menu.tsx +18 -15
  33. package/src/components/contextual-save-bar.tsx +156 -0
  34. package/src/components/data-table.tsx +34 -5
  35. package/src/components/date-picker.tsx +275 -28
  36. package/src/components/date-text.tsx +90 -0
  37. package/src/components/dropdown-menu.tsx +11 -8
  38. package/src/components/dropdown.tsx +6 -3
  39. package/src/components/empty-state.tsx +85 -20
  40. package/src/components/file-dropzone.tsx +2 -1
  41. package/src/components/file-thumbnail.tsx +84 -20
  42. package/src/components/filter-bar.tsx +91 -0
  43. package/src/components/grid-list.tsx +2 -2
  44. package/src/components/help-tooltip.tsx +1 -1
  45. package/src/components/input-copy.tsx +1 -1
  46. package/src/components/input-group.tsx +1 -1
  47. package/src/components/input-message.tsx +5 -4
  48. package/src/components/input-number.tsx +103 -11
  49. package/src/components/input.tsx +5 -3
  50. package/src/components/label.tsx +1 -0
  51. package/src/components/media-asset-card.tsx +1 -1
  52. package/src/components/menu-item.tsx +37 -3
  53. package/src/components/menubar.tsx +21 -18
  54. package/src/components/native-select.tsx +1 -1
  55. package/src/components/navigation-menu.tsx +2 -2
  56. package/src/components/notification.tsx +1 -1
  57. package/src/components/pagination.tsx +97 -3
  58. package/src/components/popover.tsx +2 -0
  59. package/src/components/property-row.tsx +7 -4
  60. package/src/components/radio-card.tsx +1 -1
  61. package/src/components/radio-group.tsx +2 -1
  62. package/src/components/rating.tsx +136 -0
  63. package/src/components/resizable.tsx +1 -1
  64. package/src/components/resource-item.tsx +133 -0
  65. package/src/components/rich-text-editor.tsx +1 -0
  66. package/src/components/search-input.tsx +98 -0
  67. package/src/components/searchable-table.tsx +10 -11
  68. package/src/components/select.tsx +28 -9
  69. package/src/components/sidebar.tsx +4 -4
  70. package/src/components/slider.tsx +78 -36
  71. package/src/components/sonner.tsx +18 -4
  72. package/src/components/stat-card.tsx +121 -37
  73. package/src/components/status-badge.tsx +142 -47
  74. package/src/components/status-tile.tsx +9 -0
  75. package/src/components/switch.tsx +6 -5
  76. package/src/components/tabs-subtle.tsx +10 -2
  77. package/src/components/tabs.tsx +23 -3
  78. package/src/components/textarea.tsx +2 -3
  79. package/src/components/thinking-steps.tsx +3 -3
  80. package/src/components/toggle.tsx +14 -13
  81. package/src/components/tooltip.tsx +11 -8
  82. package/src/components/url-redirect-prompt.tsx +0 -1
  83. package/src/index.ts +15 -0
  84. package/src/lib/density-context.tsx +65 -0
  85. package/src/lib/format.tsx +301 -0
  86. package/src/lib/interaction.ts +12 -4
  87. package/src/lib/scroll-fade.tsx +39 -0
  88. package/src/tokens/tokens.test.ts +77 -0
  89. package/src/tokens/tokens.ts +114 -5
  90. package/dist/chunk-RI6QJR2L.js.map +0 -1
package/dist/tokens.css CHANGED
@@ -77,11 +77,14 @@
77
77
  --color-surface: var(--surface);
78
78
  --color-surface-foreground: var(--surface-foreground);
79
79
  --color-border: var(--border);
80
+ --color-border-strong: var(--border-strong);
80
81
  --color-input: var(--input);
81
82
  --color-muted: var(--muted);
82
83
  --color-muted-foreground: var(--muted-foreground);
83
84
  --color-accent: var(--accent);
84
85
  --color-accent-foreground: var(--accent-foreground);
86
+ --color-hover: var(--hover);
87
+ --color-active: var(--active);
85
88
  --color-primary: var(--primary);
86
89
  --color-primary-foreground: var(--primary-foreground);
87
90
  --color-secondary: var(--secondary);
@@ -93,6 +96,25 @@
93
96
  --color-warning: var(--warning);
94
97
  --color-warning-foreground: var(--warning-foreground);
95
98
  --color-ring: var(--ring);
99
+ --color-checker-a: var(--checker-a);
100
+ --color-checker-b: var(--checker-b);
101
+ --color-canvas: var(--canvas);
102
+ --color-surface-1: var(--surface-1);
103
+ --color-surface-2: var(--surface-2);
104
+ --color-surface-3: var(--surface-3);
105
+ --color-surface-4: var(--surface-4);
106
+ --color-surface-5: var(--surface-5);
107
+ --color-surface-6: var(--surface-6);
108
+ --color-surface-7: var(--surface-7);
109
+ --color-surface-8: var(--surface-8);
110
+ --shadow-surface-1: var(--surface-shadow-1);
111
+ --shadow-surface-2: var(--surface-shadow-2);
112
+ --shadow-surface-3: var(--surface-shadow-3);
113
+ --shadow-surface-4: var(--surface-shadow-4);
114
+ --shadow-surface-5: var(--surface-shadow-5);
115
+ --shadow-surface-6: var(--surface-shadow-6);
116
+ --shadow-surface-7: var(--surface-shadow-7);
117
+ --shadow-surface-8: var(--surface-shadow-8);
96
118
  }
97
119
 
98
120
  :root {
@@ -102,12 +124,15 @@
102
124
  --card-foreground: #171717;
103
125
  --surface: #fafafa;
104
126
  --surface-foreground: #262626;
105
- --border: #f5f5f5;
106
- --input: #f5f5f5;
127
+ --border: #e5e5e5;
128
+ --border-strong: #d4d4d4;
129
+ --input: #e5e5e5;
107
130
  --muted: #fafafa;
108
131
  --muted-foreground: #737373;
109
132
  --accent: #fdf0ff;
110
133
  --accent-foreground: #740092;
134
+ --hover: rgba(23, 23, 23, 0.05);
135
+ --active: rgba(23, 23, 23, 0.08);
111
136
  --primary: #c100f1;
112
137
  --primary-foreground: #ffffff;
113
138
  --secondary: #fafafa;
@@ -119,6 +144,25 @@
119
144
  --warning: #fff5bf;
120
145
  --warning-foreground: #171717;
121
146
  --ring: #c100f1;
147
+ --checker-a: #ffffff;
148
+ --checker-b: #e5e5e5;
149
+ --canvas: #f5f5f5;
150
+ --surface-1: #ffffff;
151
+ --surface-2: #ffffff;
152
+ --surface-3: #ffffff;
153
+ --surface-4: #ffffff;
154
+ --surface-5: #ffffff;
155
+ --surface-6: #ffffff;
156
+ --surface-7: #ffffff;
157
+ --surface-8: #ffffff;
158
+ --surface-shadow-1: 0 0 0 1px rgba(0, 0, 0, 0.06);
159
+ --surface-shadow-2: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06);
160
+ --surface-shadow-3: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06);
161
+ --surface-shadow-4: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04);
162
+ --surface-shadow-5: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04);
163
+ --surface-shadow-6: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.08);
164
+ --surface-shadow-7: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.08), 0 32px 40px 4px rgba(0, 0, 0, 0.1);
165
+ --surface-shadow-8: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.08), 0 32px 40px 4px rgba(0, 0, 0, 0.1), 0 48px 56px 8px rgba(0, 0, 0, 0.12);
122
166
  }
123
167
 
124
168
  @media (prefers-color-scheme: dark) {
@@ -129,12 +173,15 @@
129
173
  --card-foreground: #fafafa;
130
174
  --surface: #1a1a1a;
131
175
  --surface-foreground: #f5f5f5;
132
- --border: #404040;
133
- --input: #262626;
176
+ --border: #4a4a4a;
177
+ --border-strong: #5c5c5c;
178
+ --input: #4a4a4a;
134
179
  --muted: #262626;
135
180
  --muted-foreground: #a3a3a3;
136
181
  --accent: #404040;
137
182
  --accent-foreground: #fafafa;
183
+ --hover: rgba(250, 250, 250, 0.06);
184
+ --active: rgba(250, 250, 250, 0.1);
138
185
  --primary: #c100f1;
139
186
  --primary-foreground: #ffffff;
140
187
  --secondary: #262626;
@@ -146,6 +193,25 @@
146
193
  --warning: #221600;
147
194
  --warning-foreground: #fffad0;
148
195
  --ring: #c100f1;
196
+ --checker-a: #4a4a4a;
197
+ --checker-b: #333333;
198
+ --canvas: #1c1c1c;
199
+ --surface-1: #171717;
200
+ --surface-2: #1f1f1f;
201
+ --surface-3: #262626;
202
+ --surface-4: #2b2b2b;
203
+ --surface-5: #303030;
204
+ --surface-6: #353535;
205
+ --surface-7: #3a3a3a;
206
+ --surface-8: #404040;
207
+ --surface-shadow-1: 0 0 0 1px rgba(255, 255, 255, 0.08);
208
+ --surface-shadow-2: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24);
209
+ --surface-shadow-3: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24);
210
+ --surface-shadow-4: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16);
211
+ --surface-shadow-5: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16);
212
+ --surface-shadow-6: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32);
213
+ --surface-shadow-7: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32), 0 32px 40px 4px rgba(0, 0, 0, 0.4);
214
+ --surface-shadow-8: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32), 0 32px 40px 4px rgba(0, 0, 0, 0.4), 0 48px 56px 8px rgba(0, 0, 0, 0.4);
149
215
  }
150
216
  }
151
217
 
@@ -156,12 +222,15 @@
156
222
  --card-foreground: #fafafa;
157
223
  --surface: #1a1a1a;
158
224
  --surface-foreground: #f5f5f5;
159
- --border: #404040;
160
- --input: #262626;
225
+ --border: #4a4a4a;
226
+ --border-strong: #5c5c5c;
227
+ --input: #4a4a4a;
161
228
  --muted: #262626;
162
229
  --muted-foreground: #a3a3a3;
163
230
  --accent: #404040;
164
231
  --accent-foreground: #fafafa;
232
+ --hover: rgba(250, 250, 250, 0.06);
233
+ --active: rgba(250, 250, 250, 0.1);
165
234
  --primary: #c100f1;
166
235
  --primary-foreground: #ffffff;
167
236
  --secondary: #262626;
@@ -173,6 +242,25 @@
173
242
  --warning: #221600;
174
243
  --warning-foreground: #fffad0;
175
244
  --ring: #c100f1;
245
+ --checker-a: #4a4a4a;
246
+ --checker-b: #333333;
247
+ --canvas: #1c1c1c;
248
+ --surface-1: #171717;
249
+ --surface-2: #1f1f1f;
250
+ --surface-3: #262626;
251
+ --surface-4: #2b2b2b;
252
+ --surface-5: #303030;
253
+ --surface-6: #353535;
254
+ --surface-7: #3a3a3a;
255
+ --surface-8: #404040;
256
+ --surface-shadow-1: 0 0 0 1px rgba(255, 255, 255, 0.08);
257
+ --surface-shadow-2: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24);
258
+ --surface-shadow-3: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24);
259
+ --surface-shadow-4: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16);
260
+ --surface-shadow-5: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16);
261
+ --surface-shadow-6: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32);
262
+ --surface-shadow-7: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32), 0 32px 40px 4px rgba(0, 0, 0, 0.4);
263
+ --surface-shadow-8: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 1px -0.5px rgba(0, 0, 0, 0.24), 0 3px 3px -1.5px rgba(0, 0, 0, 0.24), 0 6px 6px -3px rgba(0, 0, 0, 0.24), 0 12px 12px -6px rgba(0, 0, 0, 0.16), 0 24px 24px -12px rgba(0, 0, 0, 0.16), 0 24px 24px 2px rgba(0, 0, 0, 0.32), 0 32px 40px 4px rgba(0, 0, 0, 0.4), 0 48px 56px 8px rgba(0, 0, 0, 0.4);
176
264
  }
177
265
 
178
266
  [data-theme="mid"] {
@@ -183,11 +271,14 @@
183
271
  --surface: #525252;
184
272
  --surface-foreground: #fafafa;
185
273
  --border: #a3a3a3;
186
- --input: #404040;
274
+ --border-strong: #bdbdbd;
275
+ --input: #a3a3a3;
187
276
  --muted: #525252;
188
277
  --muted-foreground: #e5e5e5;
189
278
  --accent: #404040;
190
279
  --accent-foreground: #fafafa;
280
+ --hover: rgba(255, 255, 255, 0.08);
281
+ --active: rgba(255, 255, 255, 0.13);
191
282
  --primary: #c100f1;
192
283
  --primary-foreground: #ffffff;
193
284
  --secondary: #525252;
@@ -199,8 +290,52 @@
199
290
  --warning: #fff5bf;
200
291
  --warning-foreground: #171717;
201
292
  --ring: #c100f1;
293
+ --checker-a: #8a8a8a;
294
+ --checker-b: #6b6b6b;
295
+ --canvas: #636363;
296
+ --surface-1: #737373;
297
+ --surface-2: #6b6b6b;
298
+ --surface-3: #636363;
299
+ --surface-4: #5b5b5b;
300
+ --surface-5: #525252;
301
+ --surface-6: #4d4d4d;
302
+ --surface-7: #474747;
303
+ --surface-8: #404040;
304
+ --surface-shadow-1: 0 0 0 1px rgba(0, 0, 0, 0.14);
305
+ --surface-shadow-2: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15);
306
+ --surface-shadow-3: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15);
307
+ --surface-shadow-4: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15), 0 12px 12px -6px rgba(0, 0, 0, 0.1);
308
+ --surface-shadow-5: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15), 0 12px 12px -6px rgba(0, 0, 0, 0.1), 0 24px 24px -12px rgba(0, 0, 0, 0.1);
309
+ --surface-shadow-6: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15), 0 12px 12px -6px rgba(0, 0, 0, 0.1), 0 24px 24px -12px rgba(0, 0, 0, 0.1), 0 24px 24px 2px rgba(0, 0, 0, 0.2);
310
+ --surface-shadow-7: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15), 0 12px 12px -6px rgba(0, 0, 0, 0.1), 0 24px 24px -12px rgba(0, 0, 0, 0.1), 0 24px 24px 2px rgba(0, 0, 0, 0.2), 0 32px 40px 4px rgba(0, 0, 0, 0.25);
311
+ --surface-shadow-8: 0 0 0 1px rgba(0, 0, 0, 0.14), 0 1px 1px -0.5px rgba(0, 0, 0, 0.15), 0 3px 3px -1.5px rgba(0, 0, 0, 0.15), 0 6px 6px -3px rgba(0, 0, 0, 0.15), 0 12px 12px -6px rgba(0, 0, 0, 0.1), 0 24px 24px -12px rgba(0, 0, 0, 0.1), 0 24px 24px 2px rgba(0, 0, 0, 0.2), 0 32px 40px 4px rgba(0, 0, 0, 0.25), 0 48px 56px 8px rgba(0, 0, 0, 0.3);
202
312
  }
203
313
 
314
+ :root {
315
+ --density-control-height: 32px;
316
+ --density-input-height: 40px;
317
+ --density-row-height: 36px;
318
+ --density-text: 14px;
319
+ --density-label: 12px;
320
+ --density-menu-item-height: 40px;
321
+ --density-menu-text: 14px;
322
+ --density-padding-x: 12px;
323
+ --density-radius: 8px;
324
+ }
325
+ [data-density="compact"] {
326
+ --density-control-height: 24px;
327
+ --density-input-height: 24px;
328
+ --density-row-height: 28px;
329
+ --density-text: 12px;
330
+ --density-label: 11px;
331
+ --density-menu-item-height: 28px;
332
+ --density-menu-text: 13px;
333
+ --density-padding-x: 8px;
334
+ --density-radius: 5px;
335
+ }
336
+
337
+ @custom-variant compact (&:where([data-density="compact"], [data-density="compact"] *));
338
+
204
339
  @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *, .dark, .dark *));
205
340
 
206
341
  @utility display-xl {
@@ -275,6 +410,13 @@
275
410
  text-wrap: pretty;
276
411
  }
277
412
 
413
+ @utility caption-sm {
414
+ font-family: var(--font-sans);
415
+ font-size: 0.6875rem;
416
+ font-weight: 400;
417
+ line-height: 1.5;
418
+ }
419
+
278
420
  @utility caption-xs {
279
421
  font-family: var(--font-sans);
280
422
  font-size: 0.625rem;
@@ -354,17 +496,19 @@
354
496
  50% { opacity: 1; transform: translateY(-1px) scale(1); }
355
497
  }
356
498
 
357
- *,
358
- ::before,
359
- ::after {
360
- box-sizing: border-box;
361
- border-color: var(--border);
362
- }
499
+ @layer base {
500
+ *,
501
+ ::before,
502
+ ::after {
503
+ box-sizing: border-box;
504
+ border-color: var(--border);
505
+ }
363
506
 
364
- html,
365
- body {
366
- background-color: var(--background);
367
- color: var(--foreground);
368
- -webkit-font-smoothing: antialiased;
369
- -moz-osx-font-smoothing: grayscale;
507
+ html,
508
+ body {
509
+ background-color: var(--background);
510
+ color: var(--foreground);
511
+ -webkit-font-smoothing: antialiased;
512
+ -moz-osx-font-smoothing: grayscale;
513
+ }
370
514
  }
package/dist/tokens.d.ts CHANGED
@@ -51,12 +51,15 @@ declare const tokens: {
51
51
  readonly cardForeground: "#171717";
52
52
  readonly surface: "#fafafa";
53
53
  readonly surfaceForeground: "#262626";
54
- readonly border: "#f5f5f5";
55
- readonly input: "#f5f5f5";
54
+ readonly border: "#e5e5e5";
55
+ readonly borderStrong: "#d4d4d4";
56
+ readonly input: "#e5e5e5";
56
57
  readonly muted: "#fafafa";
57
58
  readonly mutedForeground: "#737373";
58
59
  readonly accent: "#fdf0ff";
59
60
  readonly accentForeground: "#740092";
61
+ readonly hover: "rgba(23, 23, 23, 0.05)";
62
+ readonly active: "rgba(23, 23, 23, 0.08)";
60
63
  readonly primary: "#c100f1";
61
64
  readonly primaryForeground: "#ffffff";
62
65
  readonly secondary: "#fafafa";
@@ -68,6 +71,9 @@ declare const tokens: {
68
71
  readonly warning: "#fff5bf";
69
72
  readonly warningForeground: "#171717";
70
73
  readonly ring: "#c100f1";
74
+ readonly checkerA: "#ffffff";
75
+ readonly checkerB: "#e5e5e5";
76
+ readonly canvas: "#f5f5f5";
71
77
  };
72
78
  readonly mid: {
73
79
  readonly background: "#737373";
@@ -77,11 +83,14 @@ declare const tokens: {
77
83
  readonly surface: "#525252";
78
84
  readonly surfaceForeground: "#fafafa";
79
85
  readonly border: "#a3a3a3";
80
- readonly input: "#404040";
86
+ readonly borderStrong: "#bdbdbd";
87
+ readonly input: "#a3a3a3";
81
88
  readonly muted: "#525252";
82
89
  readonly mutedForeground: "#e5e5e5";
83
90
  readonly accent: "#404040";
84
91
  readonly accentForeground: "#fafafa";
92
+ readonly hover: "rgba(255, 255, 255, 0.08)";
93
+ readonly active: "rgba(255, 255, 255, 0.13)";
85
94
  readonly primary: "#c100f1";
86
95
  readonly primaryForeground: "#ffffff";
87
96
  readonly secondary: "#525252";
@@ -93,6 +102,9 @@ declare const tokens: {
93
102
  readonly warning: "#fff5bf";
94
103
  readonly warningForeground: "#171717";
95
104
  readonly ring: "#c100f1";
105
+ readonly checkerA: "#8a8a8a";
106
+ readonly checkerB: "#6b6b6b";
107
+ readonly canvas: "#636363";
96
108
  };
97
109
  readonly dark: {
98
110
  readonly background: "#171717";
@@ -101,12 +113,15 @@ declare const tokens: {
101
113
  readonly cardForeground: "#fafafa";
102
114
  readonly surface: "#1a1a1a";
103
115
  readonly surfaceForeground: "#f5f5f5";
104
- readonly border: "#404040";
105
- readonly input: "#262626";
116
+ readonly border: "#4a4a4a";
117
+ readonly borderStrong: "#5c5c5c";
118
+ readonly input: "#4a4a4a";
106
119
  readonly muted: "#262626";
107
120
  readonly mutedForeground: "#a3a3a3";
108
121
  readonly accent: "#404040";
109
122
  readonly accentForeground: "#fafafa";
123
+ readonly hover: "rgba(250, 250, 250, 0.06)";
124
+ readonly active: "rgba(250, 250, 250, 0.1)";
110
125
  readonly primary: "#c100f1";
111
126
  readonly primaryForeground: "#ffffff";
112
127
  readonly secondary: "#262626";
@@ -118,6 +133,23 @@ declare const tokens: {
118
133
  readonly warning: "#221600";
119
134
  readonly warningForeground: "#fffad0";
120
135
  readonly ring: "#c100f1";
136
+ readonly checkerA: "#4a4a4a";
137
+ readonly checkerB: "#333333";
138
+ readonly canvas: "#1c1c1c";
139
+ };
140
+ };
141
+ readonly surfaces: {
142
+ readonly light: {
143
+ readonly bg: readonly ["#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"];
144
+ readonly shadow: string[];
145
+ };
146
+ readonly mid: {
147
+ readonly bg: readonly ["#737373", "#6b6b6b", "#636363", "#5b5b5b", "#525252", "#4d4d4d", "#474747", "#404040"];
148
+ readonly shadow: string[];
149
+ };
150
+ readonly dark: {
151
+ readonly bg: readonly ["#171717", "#1f1f1f", "#262626", "#2b2b2b", "#303030", "#353535", "#3a3a3a", "#404040"];
152
+ readonly shadow: string[];
121
153
  };
122
154
  };
123
155
  readonly fontFamily: {
@@ -190,6 +222,14 @@ declare const tokens: {
190
222
  readonly lineHeight: "1.625";
191
223
  readonly textWrap: "pretty";
192
224
  };
225
+ /** 11px — dense metadata (table sub-lines, chips, editor hints). Use instead of text-[11px]. */
226
+ readonly "caption-sm": {
227
+ readonly family: "sans";
228
+ readonly size: "0.6875rem";
229
+ readonly weight: 400;
230
+ readonly lineHeight: "1.5";
231
+ };
232
+ /** 10px — the floor. Use instead of text-[10px]; keep to non-essential metadata. */
193
233
  readonly "caption-xs": {
194
234
  readonly family: "sans";
195
235
  readonly size: "0.625rem";
@@ -245,6 +285,30 @@ declare const tokens: {
245
285
  readonly xl: "calc(0.5rem + 4px)";
246
286
  readonly full: "9999px";
247
287
  };
288
+ readonly density: {
289
+ readonly default: {
290
+ readonly controlHeight: "32px";
291
+ readonly inputHeight: "40px";
292
+ readonly rowHeight: "36px";
293
+ readonly text: "14px";
294
+ readonly label: "12px";
295
+ readonly menuItemHeight: "40px";
296
+ readonly menuText: "14px";
297
+ readonly paddingX: "12px";
298
+ readonly radius: "8px";
299
+ };
300
+ readonly compact: {
301
+ readonly controlHeight: "24px";
302
+ readonly inputHeight: "24px";
303
+ readonly rowHeight: "28px";
304
+ readonly text: "12px";
305
+ readonly label: "11px";
306
+ readonly menuItemHeight: "28px";
307
+ readonly menuText: "13px";
308
+ readonly paddingX: "8px";
309
+ readonly radius: "5px";
310
+ };
311
+ };
248
312
  readonly zIndex: {
249
313
  readonly dropdown: 40;
250
314
  readonly sticky: 50;
package/dist/tokens.js CHANGED
@@ -1,3 +1,3 @@
1
- export { tokens } from './chunk-RI6QJR2L.js';
1
+ export { tokens } from './chunk-R576DV2A.js';
2
2
  //# sourceMappingURL=tokens.js.map
3
3
  //# sourceMappingURL=tokens.js.map
package/llms.txt CHANGED
@@ -5,10 +5,10 @@
5
5
  ## Key Facts
6
6
 
7
7
  - Package name: `@hilum/ui`
8
- - Package version: 3.8.5
9
- - Component modules: 104
10
- - Atom components: 73
11
- - Molecule components: 31
8
+ - Package version: 3.9.0
9
+ - Component modules: 111
10
+ - Atom components: 77
11
+ - Molecule components: 34
12
12
  - Docs site: https://ui.hilum.dev
13
13
  - Source repository: https://git-codecommit.us-east-1.amazonaws.com/v1/repos/hilum-ui
14
14
  - Machine-readable docs index: https://ui.hilum.dev/catalog.json
@@ -172,6 +172,13 @@ Primary exports:
172
172
  - Toggle (/atoms/toggle/) — Two-state press button for toolbars and filter controls.
173
173
  - Tooltip (/atoms/tooltip/) — Brief label that appears on hover or focus to clarify an element.
174
174
  - URL Redirect Prompt (/molecules/url-redirect-prompt/) — Redirect recommendation callout shown when an editable URL handle changes. Composes: Callout · Switch.
175
+ - Contextual Save Bar (/molecules/contextual-save-bar/) — Unsaved-changes bar with Save and Discard for edit screens, with ⌘S and unload guarding. Composes: Button · Icon.
176
+ - Date Text (/atoms/date-text/) — Locale-aware dates and relative times, plus Intl helpers for money, numbers and plurals.
177
+ - Resource Item (/molecules/resource-item/) — Primary/secondary text hierarchy for resource table cells and full-row mobile list items. Composes: Stacked List · Table.
178
+ - Search Input (/atoms/search-input/) — Search field with leading icon, clear button, Escape-to-clear and loading state. Composes: Input · Spinner.
179
+ - Filter Bar (/molecules/filter-bar/) — List toolbar with search, filters, clear action and trailing actions; responsive. Composes: Search Input · Select · Button.
180
+ - Rating (/atoms/rating/) — Read-only star rating with partial stars, or an accessible radio-group input.
181
+ - Code Block (/atoms/code-block/) — Styled scrollable pre with language label and copy-to-clipboard.
175
182
 
176
183
  ## Structured Data
177
184
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hilum/ui",
3
- "version": "3.8.5",
3
+ "version": "3.10.0",
4
4
  "private": false,
5
5
  "description": "Hilum UI — design system primitives (Button, Input, Dialog, Combobox, …) + tokens + fonts + icons",
6
6
  "license": "MIT",
@@ -18,24 +18,25 @@
18
18
  ],
19
19
  "exports": {
20
20
  ".": {
21
- "import": "./dist/index.js",
22
- "types": "./dist/index.d.ts"
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
23
  },
24
24
  "./icons": {
25
- "import": "./dist/icons.js",
26
- "types": "./dist/icons.d.ts"
25
+ "types": "./dist/icons.d.ts",
26
+ "import": "./dist/icons.js"
27
27
  },
28
28
  "./tokens": {
29
- "import": "./dist/tokens.js",
30
- "types": "./dist/tokens.d.ts"
29
+ "types": "./dist/tokens.d.ts",
30
+ "import": "./dist/tokens.js"
31
31
  },
32
32
  "./tokens.css": "./dist/tokens.css",
33
33
  "./fonts.css": "./dist/fonts.css",
34
34
  "./fonts/*": "./dist/fonts/*",
35
35
  "./create-theme": {
36
- "import": "./dist/create-theme.js",
37
- "types": "./dist/create-theme.d.ts"
38
- }
36
+ "types": "./dist/create-theme.d.ts",
37
+ "import": "./dist/create-theme.js"
38
+ },
39
+ "./package.json": "./package.json"
39
40
  },
40
41
  "files": [
41
42
  "dist",
@@ -364,7 +364,7 @@ const AccordionGroup = forwardRef<HTMLDivElement, AccordionGroupProps>((props, r
364
364
  <AnimatePresence>
365
365
  {focusRect && (
366
366
  <motion.div
367
- className={`absolute ${shape.focusRing} pointer-events-none z-20 border border-[#6B97FF]`}
367
+ className={`absolute ${shape.focusRing} pointer-events-none z-20 border-2 border-ring`}
368
368
  initial={false}
369
369
  animate={{
370
370
  left: focusRect.left - 2,
@@ -626,7 +626,7 @@ const AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(
626
626
  className={cn(
627
627
  `relative z-10 flex items-center gap-2.5 ${shape.item} px-3 py-2 w-full cursor-pointer outline-none select-none`,
628
628
  !groupCtx?.grouped &&
629
- "focus-visible:ring-1 focus-visible:ring-[#6B97FF] focus-visible:ring-offset-0",
629
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0",
630
630
  className,
631
631
  )}
632
632
  {...(props as React.ComponentProps<typeof AccordionPrimitive.Trigger>)}
@@ -71,7 +71,7 @@ const AccountMenuItem = React.forwardRef<
71
71
  "group",
72
72
  destructive
73
73
  ? "text-destructive focus:bg-destructive/10 focus:text-destructive"
74
- : "text-foreground focus:bg-muted focus:text-foreground",
74
+ : "text-foreground focus:bg-active focus:text-foreground",
75
75
  "data-[disabled]:opacity-40",
76
76
  "[&_svg:not([class*='size-'])]:size-4",
77
77
  className,
@@ -143,7 +143,113 @@ const AlertDialogCancel = React.forwardRef<
143
143
  ));
144
144
  AlertDialogCancel.displayName = "AlertDialogCancel";
145
145
 
146
+ /* ─────────────────────── ConfirmDialog ─────────────────────── */
147
+
148
+ interface ConfirmDialogProps {
149
+ /** Element that opens the dialog (e.g. a "Delete" Button). Optional when controlled. */
150
+ trigger?: React.ReactNode;
151
+ open?: boolean;
152
+ onOpenChange?: (open: boolean) => void;
153
+ title: React.ReactNode;
154
+ description?: React.ReactNode;
155
+ confirmLabel?: React.ReactNode;
156
+ cancelLabel?: React.ReactNode;
157
+ /** Red confirm button for irreversible actions (delete, cancel order). */
158
+ destructive?: boolean;
159
+ /**
160
+ * Runs on confirm. If it returns a promise the confirm button shows a
161
+ * pending state and the dialog stays open until it resolves; a rejection
162
+ * keeps the dialog open so the caller can surface the error (e.g. toast).
163
+ */
164
+ onConfirm: () => void | Promise<unknown>;
165
+ /** Extra content between the description and the footer. */
166
+ children?: React.ReactNode;
167
+ className?: string;
168
+ }
169
+
170
+ /**
171
+ * One-call confirmation dialog — replaces hand-built "Delete X" dialogs.
172
+ *
173
+ * <ConfirmDialog
174
+ * trigger={<Button variant="destructive">Delete</Button>}
175
+ * title="Delete product?"
176
+ * description="This can't be undone."
177
+ * confirmLabel="Delete product"
178
+ * destructive
179
+ * onConfirm={() => deleteProduct(id)}
180
+ * />
181
+ */
182
+ function ConfirmDialog({
183
+ trigger,
184
+ open: openProp,
185
+ onOpenChange,
186
+ title,
187
+ description,
188
+ confirmLabel = "Confirm",
189
+ cancelLabel = "Cancel",
190
+ destructive = false,
191
+ onConfirm,
192
+ children,
193
+ className,
194
+ }: ConfirmDialogProps) {
195
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
196
+ const [pending, setPending] = React.useState(false);
197
+ const open = openProp ?? uncontrolledOpen;
198
+ const setOpen = (next: boolean) => {
199
+ if (pending && !next) return;
200
+ if (openProp === undefined) setUncontrolledOpen(next);
201
+ onOpenChange?.(next);
202
+ };
203
+
204
+ const handleConfirm = async (event: React.MouseEvent) => {
205
+ event.preventDefault();
206
+ const result = onConfirm();
207
+ if (result && typeof (result as Promise<unknown>).then === "function") {
208
+ setPending(true);
209
+ try {
210
+ await result;
211
+ setPending(false);
212
+ if (openProp === undefined) setUncontrolledOpen(false);
213
+ onOpenChange?.(false);
214
+ } catch {
215
+ setPending(false);
216
+ }
217
+ return;
218
+ }
219
+ setOpen(false);
220
+ };
221
+
222
+ return (
223
+ <AlertDialogRoot open={open} onOpenChange={setOpen}>
224
+ {trigger && <AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>}
225
+ <AlertDialogContent className={className}>
226
+ <AlertDialogHeader>
227
+ <AlertDialogTitle>{title}</AlertDialogTitle>
228
+ {description && <AlertDialogDescription>{description}</AlertDialogDescription>}
229
+ </AlertDialogHeader>
230
+ {children}
231
+ <AlertDialogFooter>
232
+ <AlertDialogCancel disabled={pending}>{cancelLabel}</AlertDialogCancel>
233
+ <AlertDialogAction
234
+ onClick={handleConfirm}
235
+ disabled={pending}
236
+ aria-busy={pending || undefined}
237
+ className={cn(
238
+ destructive &&
239
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive/80",
240
+ )}
241
+ >
242
+ {confirmLabel}
243
+ </AlertDialogAction>
244
+ </AlertDialogFooter>
245
+ </AlertDialogContent>
246
+ </AlertDialogRoot>
247
+ );
248
+ }
249
+ ConfirmDialog.displayName = "ConfirmDialog";
250
+
146
251
  export {
252
+ ConfirmDialog,
147
253
  AlertDialogRoot as AlertDialog,
148
254
  AlertDialogTrigger,
149
255
  AlertDialogPortal,
@@ -156,3 +262,4 @@ export {
156
262
  AlertDialogAction,
157
263
  AlertDialogCancel,
158
264
  };
265
+ export type { ConfirmDialogProps };