@hogoshi/ui 0.0.0-stage → 0.1.1

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 (57) hide show
  1. package/package.json +63 -4
  2. package/src/components/avatar.tsx +30 -0
  3. package/src/components/badge.tsx +26 -0
  4. package/src/components/breadcrumb.tsx +37 -0
  5. package/src/components/button.tsx +58 -0
  6. package/src/components/calendar.tsx +244 -0
  7. package/src/components/card.tsx +18 -0
  8. package/src/components/chart.tsx +387 -0
  9. package/src/components/checkbox.tsx +26 -0
  10. package/src/components/code-block.tsx +118 -0
  11. package/src/components/collapsible.tsx +31 -0
  12. package/src/components/command.tsx +111 -0
  13. package/src/components/context-menu.tsx +150 -0
  14. package/src/components/counter.tsx +56 -0
  15. package/src/components/dialog.tsx +36 -0
  16. package/src/components/dropdown-menu.tsx +54 -0
  17. package/src/components/file-upload.tsx +381 -0
  18. package/src/components/glide.tsx +82 -0
  19. package/src/components/icon.tsx +28 -0
  20. package/src/components/image-viewer.tsx +370 -0
  21. package/src/components/input.tsx +187 -0
  22. package/src/components/kbd.tsx +14 -0
  23. package/src/components/logo-mark.ts +8 -0
  24. package/src/components/logo.tsx +36 -0
  25. package/src/components/navbar.tsx +144 -0
  26. package/src/components/otp.tsx +93 -0
  27. package/src/components/page-loader.tsx +37 -0
  28. package/src/components/pophover.tsx +28 -0
  29. package/src/components/popover.tsx +36 -0
  30. package/src/components/popup.tsx +75 -0
  31. package/src/components/progress.tsx +26 -0
  32. package/src/components/result.tsx +22 -0
  33. package/src/components/scroll-area.tsx +38 -0
  34. package/src/components/select.tsx +52 -0
  35. package/src/components/separator.tsx +14 -0
  36. package/src/components/sheet.tsx +96 -0
  37. package/src/components/sidebar.tsx +195 -0
  38. package/src/components/skeleton.tsx +14 -0
  39. package/src/components/slider.tsx +31 -0
  40. package/src/components/smooth-scroll.tsx +174 -0
  41. package/src/components/spinner.tsx +18 -0
  42. package/src/components/switch.tsx +22 -0
  43. package/src/components/table.tsx +52 -0
  44. package/src/components/tabs.tsx +48 -0
  45. package/src/components/theme-toggle.tsx +214 -0
  46. package/src/components/toaster.tsx +38 -0
  47. package/src/components/tooltip.tsx +43 -0
  48. package/src/components/video-player.tsx +559 -0
  49. package/src/components/video-settings.tsx +233 -0
  50. package/src/index.ts +102 -0
  51. package/src/lib/cn.ts +6 -0
  52. package/src/lib/jsx-highlight.ts +128 -0
  53. package/src/styles.css +443 -0
  54. package/src/theme/theme-script.ts +13 -0
  55. package/src/theme/theme.tsx +77 -0
  56. package/styles.css +1 -0
  57. package/README.md +0 -3
package/src/styles.css ADDED
@@ -0,0 +1,443 @@
1
+ @import "tailwindcss";
2
+ @import "@hogoshi/tokens/dist/tokens.css";
3
+ @import "@hogoshi/tokens/dist/themes.css";
4
+ @import "@hogoshi/tokens/dist/tailwind-theme.css";
5
+
6
+ @source "./";
7
+
8
+ * {
9
+ scrollbar-width: thin;
10
+ scrollbar-color: transparent transparent;
11
+ }
12
+
13
+ [data-scrolling] {
14
+ scrollbar-color: var(--scrollbar-thumb) transparent;
15
+ }
16
+
17
+ *::-webkit-scrollbar {
18
+ width: var(--scrollbar-size);
19
+ height: var(--scrollbar-size);
20
+ }
21
+
22
+ *::-webkit-scrollbar-track,
23
+ *::-webkit-scrollbar-corner {
24
+ background: transparent;
25
+ }
26
+
27
+ *::-webkit-scrollbar-thumb {
28
+ background: transparent;
29
+ border-radius: 999px;
30
+ transition: background-color var(--motion-duration) var(--motion-ease);
31
+ }
32
+
33
+ [data-scrolling]::-webkit-scrollbar-thumb {
34
+ background: var(--scrollbar-thumb);
35
+ }
36
+
37
+ button:not(:disabled),
38
+ a,
39
+ [role="button"]:not([aria-disabled="true"]) {
40
+ cursor: pointer;
41
+ }
42
+
43
+ button:disabled,
44
+ [aria-disabled="true"] {
45
+ cursor: not-allowed;
46
+ }
47
+
48
+ :root,
49
+ [data-mode="light"] {
50
+ color-scheme: light;
51
+ }
52
+
53
+ :root[data-mode="dark"],
54
+ [data-mode="dark"] {
55
+ color-scheme: dark;
56
+ }
57
+
58
+ html,
59
+ body {
60
+ background: var(--bg);
61
+ color: var(--fg);
62
+ font-family: var(--font-sans);
63
+ font-size: var(--text-base);
64
+ -webkit-font-smoothing: antialiased;
65
+ text-rendering: optimizeLegibility;
66
+ }
67
+
68
+ ::selection {
69
+ background: var(--accent-muted);
70
+ color: var(--fg);
71
+ }
72
+
73
+ :root {
74
+ --safe-top: env(safe-area-inset-top, 0px);
75
+ --safe-right: env(safe-area-inset-right, 0px);
76
+ --safe-bottom: env(safe-area-inset-bottom, 0px);
77
+ --safe-left: env(safe-area-inset-left, 0px);
78
+ }
79
+
80
+ html {
81
+ scroll-behavior: auto;
82
+ -webkit-tap-highlight-color: transparent;
83
+ -webkit-text-size-adjust: 100%;
84
+ text-size-adjust: 100%;
85
+ }
86
+
87
+ body {
88
+ overscroll-behavior-y: none;
89
+ }
90
+
91
+ button,
92
+ a,
93
+ nav,
94
+ [role="button"],
95
+ [role="tab"],
96
+ [role="menuitem"] {
97
+ -webkit-user-select: none;
98
+ user-select: none;
99
+ -webkit-touch-callout: none;
100
+ touch-action: manipulation;
101
+ }
102
+
103
+ @media (display-mode: standalone) {
104
+ body {
105
+ -webkit-user-select: none;
106
+ user-select: none;
107
+ }
108
+
109
+ input,
110
+ textarea,
111
+ [contenteditable],
112
+ .hogoshi-code,
113
+ .hogoshi-selectable {
114
+ -webkit-user-select: text;
115
+ user-select: text;
116
+ }
117
+ }
118
+
119
+ :root,
120
+ [data-mode="light"] {
121
+ --code-keyword: oklch(48% 0.18 300);
122
+ --code-string: oklch(46% 0.12 175);
123
+ --code-number: oklch(48% 0.14 55);
124
+ --code-title: oklch(52% 0.2 330);
125
+ --code-attr: oklch(48% 0.14 250);
126
+ --code-punct: var(--fg-muted);
127
+ }
128
+
129
+ :root[data-mode="dark"],
130
+ [data-mode="dark"] {
131
+ --code-keyword: oklch(78% 0.14 300);
132
+ --code-string: oklch(84% 0.1 175);
133
+ --code-number: oklch(84% 0.12 70);
134
+ --code-title: oklch(82% 0.14 330);
135
+ --code-attr: oklch(84% 0.08 230);
136
+ --code-punct: var(--fg-muted);
137
+ }
138
+
139
+ .hogoshi-code,
140
+ .hogoshi-code code {
141
+ color: var(--fg);
142
+ white-space: pre-wrap;
143
+ overflow-wrap: anywhere;
144
+ }
145
+
146
+ .hogoshi-code .hljs-tag,
147
+ .hogoshi-code .hljs-punctuation {
148
+ color: var(--code-punct);
149
+ }
150
+
151
+ .hogoshi-code .hljs-tag .hljs-name,
152
+ .hogoshi-code .hljs-name,
153
+ .hogoshi-code .hljs-selector-tag,
154
+ .hogoshi-code .hljs-title,
155
+ .hogoshi-code .hljs-title.class_,
156
+ .hogoshi-code .hljs-title.function_,
157
+ .hogoshi-code .hljs-function {
158
+ color: var(--code-title);
159
+ }
160
+
161
+ .hogoshi-code .hljs-keyword,
162
+ .hogoshi-code .hljs-built_in,
163
+ .hogoshi-code .hljs-type {
164
+ color: var(--code-keyword);
165
+ }
166
+
167
+ .hogoshi-code .hljs-tag .hljs-attr,
168
+ .hogoshi-code .hljs-attr,
169
+ .hogoshi-code .hljs-attribute,
170
+ .hogoshi-code .hljs-variable {
171
+ color: var(--code-attr);
172
+ }
173
+
174
+ .hogoshi-code .hljs-tag .hljs-string,
175
+ .hogoshi-code .hljs-string,
176
+ .hogoshi-code .hljs-regexp {
177
+ color: var(--code-string);
178
+ }
179
+
180
+ .hogoshi-code .hljs-number,
181
+ .hogoshi-code .hljs-literal {
182
+ color: var(--code-number);
183
+ }
184
+
185
+ .hogoshi-code .hljs-tag .hljs-boolean {
186
+ color: var(--fg);
187
+ }
188
+
189
+ .hogoshi-code .hljs-comment,
190
+ .hogoshi-code .hljs-doctag {
191
+ color: var(--fg-subtle);
192
+ }
193
+
194
+ [cmdk-list] {
195
+ -webkit-overflow-scrolling: touch;
196
+ touch-action: pan-y;
197
+ overscroll-behavior: contain;
198
+ }
199
+
200
+ .hogoshi-command[data-state="open"] {
201
+ animation: command-in var(--motion-duration) var(--motion-ease) forwards;
202
+ }
203
+
204
+ .hogoshi-command[data-state="closed"] {
205
+ animation: command-out var(--motion-duration) var(--motion-ease) forwards;
206
+ }
207
+
208
+ .hogoshi-command-overlay[data-state="open"] {
209
+ animation: overlay-blur-in calc(var(--motion-duration) * 2.2) var(--motion-ease);
210
+ }
211
+
212
+ .hogoshi-command-overlay[data-state="closed"] {
213
+ animation: overlay-blur-out calc(var(--motion-duration) * 2.2) var(--motion-ease) forwards;
214
+ }
215
+
216
+ @keyframes overlay-blur-in {
217
+ from { opacity: 0; backdrop-filter: blur(0); }
218
+ to { opacity: 1; backdrop-filter: blur(40px); }
219
+ }
220
+
221
+ @keyframes overlay-blur-out {
222
+ from { opacity: 1; backdrop-filter: blur(40px); }
223
+ to { opacity: 0; backdrop-filter: blur(0); }
224
+ }
225
+
226
+ @keyframes fade-in {
227
+ from { opacity: 0; }
228
+ to { opacity: 1; }
229
+ }
230
+
231
+ @keyframes fade-out {
232
+ from { opacity: 1; }
233
+ to { opacity: 0; }
234
+ }
235
+
236
+ @keyframes command-in {
237
+ from { opacity: 0; transform: translateX(-50%) scale(0.96); }
238
+ to { opacity: 1; transform: translateX(-50%) scale(1); }
239
+ }
240
+
241
+ @keyframes command-out {
242
+ from { opacity: 1; transform: translateX(-50%) scale(1); }
243
+ to { opacity: 0; transform: translateX(-50%) scale(0.96); }
244
+ }
245
+
246
+ @keyframes shimmer {
247
+ from { background-position: 200% 0; }
248
+ to { background-position: -200% 0; }
249
+ }
250
+
251
+ @keyframes month-next {
252
+ from { opacity: 0; transform: translateX(10px); }
253
+ to { opacity: 1; transform: translateX(0); }
254
+ }
255
+
256
+ @keyframes month-prev {
257
+ from { opacity: 0; transform: translateX(-10px); }
258
+ to { opacity: 1; transform: translateX(0); }
259
+ }
260
+
261
+ @keyframes otp-in {
262
+ from { opacity: 0; transform: translateY(110%); filter: blur(4px); }
263
+ to { opacity: 1; transform: none; filter: blur(0); }
264
+ }
265
+
266
+ @keyframes otp-out {
267
+ from { opacity: 1; transform: none; filter: blur(0); }
268
+ to { opacity: 0; transform: translateY(-110%); filter: blur(4px); }
269
+ }
270
+
271
+ @keyframes item-in {
272
+ from { opacity: 0; transform: translateY(4px) scale(0.98); }
273
+ to { opacity: 1; transform: none; }
274
+ }
275
+
276
+ @keyframes slide-from-right {
277
+ from { opacity: 0; transform: translateX(6%) scale(0.98); }
278
+ to { opacity: 1; transform: none; }
279
+ }
280
+
281
+ @keyframes slide-from-left {
282
+ from { opacity: 0; transform: translateX(-6%) scale(0.98); }
283
+ to { opacity: 1; transform: none; }
284
+ }
285
+
286
+ @keyframes tab-in {
287
+ from { opacity: 0; filter: blur(10px); }
288
+ to { opacity: 1; filter: blur(0); }
289
+ }
290
+
291
+ @keyframes tab-out {
292
+ from { opacity: 1; filter: blur(0); }
293
+ to { opacity: 0; filter: blur(10px); }
294
+ }
295
+
296
+ @keyframes photo-next {
297
+ from { opacity: 0; transform: translateX(14%) scale(0.96); filter: blur(8px); }
298
+ to { opacity: 1; transform: none; filter: blur(0); }
299
+ }
300
+
301
+ @keyframes photo-prev {
302
+ from { opacity: 0; transform: translateX(-14%) scale(0.96); filter: blur(8px); }
303
+ to { opacity: 1; transform: none; filter: blur(0); }
304
+ }
305
+
306
+ @keyframes loader-pulse {
307
+ 0%, 100% { opacity: 0.6; transform: scale(0.92); }
308
+ 50% { opacity: 1; transform: scale(1); }
309
+ }
310
+
311
+ @keyframes panel-from-right {
312
+ from { opacity: 0; transform: translateX(32%); }
313
+ to { opacity: 1; transform: none; }
314
+ }
315
+
316
+ @keyframes panel-from-left {
317
+ from { opacity: 0; transform: translateX(-32%); }
318
+ to { opacity: 1; transform: none; }
319
+ }
320
+
321
+ @keyframes player-flash {
322
+ from { opacity: 0.9; transform: scale(0.8); }
323
+ to { opacity: 0; transform: scale(1.4); }
324
+ }
325
+
326
+ @keyframes check-pop {
327
+ from { opacity: 0; transform: scale(0.4); }
328
+ to { opacity: 1; transform: scale(1); }
329
+ }
330
+
331
+ html[data-theme-switching],
332
+ html[data-theme-switching] body {
333
+ overflow: hidden !important;
334
+ }
335
+
336
+ html[data-theme-switching] body {
337
+ pointer-events: none !important;
338
+ }
339
+
340
+ html[data-theme-switching] *,
341
+ html[data-theme-switching] *::before,
342
+ html[data-theme-switching] *::after {
343
+ transition: none !important;
344
+ animation-play-state: paused !important;
345
+ }
346
+
347
+ .hogoshi-theme-layer {
348
+ position: fixed;
349
+ inset: 0;
350
+ z-index: 2147483647;
351
+ overflow: hidden;
352
+ pointer-events: none;
353
+ clip-path: circle(0 at 50% 50%);
354
+ background: var(--bg);
355
+ color: var(--fg);
356
+ font-family: var(--font-sans);
357
+ }
358
+
359
+ .hogoshi-theme-layer > div {
360
+ min-height: 100%;
361
+ }
362
+
363
+ .hogoshi-theme-layer * {
364
+ transition: none !important;
365
+ animation: none !important;
366
+ }
367
+
368
+ .hogoshi-grab,
369
+ button.hogoshi-grab:not(:disabled) {
370
+ cursor: grab;
371
+ user-select: none;
372
+ }
373
+
374
+ .hogoshi-grab:active,
375
+ button.hogoshi-grab:not(:disabled):active,
376
+ .hogoshi-grab[data-swiping="true"] {
377
+ cursor: grabbing;
378
+ }
379
+
380
+ .hogoshi-grab[data-disabled],
381
+ button.hogoshi-grab:disabled {
382
+ cursor: not-allowed;
383
+ }
384
+
385
+ [data-sonner-toast],
386
+ [data-sonner-toast] *:not([data-close-button]) {
387
+ cursor: grab !important;
388
+ user-select: none !important;
389
+ }
390
+
391
+ [data-sonner-toast]:active,
392
+ [data-sonner-toast][data-swiping="true"],
393
+ [data-sonner-toast]:active *:not([data-close-button]),
394
+ [data-sonner-toast][data-swiping="true"] *:not([data-close-button]) {
395
+ cursor: grabbing !important;
396
+ }
397
+
398
+ [data-sonner-toast] [data-close-button],
399
+ [data-sonner-toast] [data-close-button] * {
400
+ cursor: pointer !important;
401
+ }
402
+
403
+ .hogoshi-textarea {
404
+ background-image:
405
+ linear-gradient(135deg, transparent calc(50% - 0.6px), var(--fg-subtle) calc(50% - 0.6px), var(--fg-subtle) calc(50% + 0.6px), transparent calc(50% + 0.6px)),
406
+ linear-gradient(135deg, transparent calc(50% - 0.6px), var(--fg-subtle) calc(50% - 0.6px), var(--fg-subtle) calc(50% + 0.6px), transparent calc(50% + 0.6px));
407
+ background-size: 10px 10px, 5px 5px;
408
+ background-position: right 5px bottom 5px, right 5px bottom 5px;
409
+ background-repeat: no-repeat;
410
+ }
411
+
412
+ .hogoshi-textarea::-webkit-resizer {
413
+ background: transparent;
414
+ }
415
+
416
+ .hogoshi-chart {
417
+ isolation: isolate;
418
+ overflow: hidden;
419
+ }
420
+
421
+ .hogoshi-chart .recharts-wrapper {
422
+ position: relative;
423
+ z-index: 1;
424
+ }
425
+
426
+ .hogoshi-chart .recharts-tooltip-wrapper {
427
+ pointer-events: none;
428
+ z-index: 20;
429
+ }
430
+
431
+ .hogoshi-chart-label {
432
+ z-index: 0;
433
+ }
434
+
435
+ @media (prefers-reduced-motion: reduce) {
436
+ *,
437
+ *::before,
438
+ *::after {
439
+ animation-duration: 1ms !important;
440
+ animation-iteration-count: 1 !important;
441
+ transition-duration: 1ms !important;
442
+ }
443
+ }
@@ -0,0 +1,13 @@
1
+ export const THEME_INIT_SCRIPT = `(function(){try{
2
+ var d=document.documentElement;
3
+ var raw=localStorage.getItem("hogoshi:theme");
4
+ var p=raw?JSON.parse(raw):{};
5
+ var mode=p.mode||"system";
6
+ var resolved=mode==="system"?(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"):mode;
7
+ d.setAttribute("data-mode",resolved);
8
+ d.setAttribute("data-font-size",String(p.fontSize??4));
9
+ d.setAttribute("data-radius",String(p.radius??8));
10
+ if(p.density==="compact")d.setAttribute("data-density","compact");
11
+ if(p.motion&&p.motion!=="full")d.setAttribute("data-motion",p.motion);
12
+ d.style.colorScheme=resolved;
13
+ }catch(e){}})();`;
@@ -0,0 +1,77 @@
1
+ "use client";
2
+
3
+ import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
4
+
5
+ const STORAGE_KEY = "hogoshi:theme";
6
+
7
+ export type ColorMode = "light" | "dark" | "system";
8
+ export type ResolvedMode = "light" | "dark";
9
+
10
+ interface ThemeState {
11
+ mode: ColorMode;
12
+ resolved: ResolvedMode;
13
+ setMode: (mode: ColorMode) => void;
14
+ }
15
+
16
+ const ThemeContext = createContext<ThemeState | null>(null);
17
+
18
+ function systemMode(): ResolvedMode {
19
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
20
+ }
21
+
22
+ function readStored(): Record<string, unknown> {
23
+ try {
24
+ const raw = localStorage.getItem(STORAGE_KEY);
25
+ return raw ? (JSON.parse(raw) as Record<string, unknown>) : {};
26
+ } catch {
27
+ return {};
28
+ }
29
+ }
30
+
31
+ function readMode(): ColorMode {
32
+ const mode = readStored().mode;
33
+ return mode === "light" || mode === "dark" ? mode : "system";
34
+ }
35
+
36
+ function applyMode(next: ResolvedMode) {
37
+ const root = document.documentElement;
38
+ root.setAttribute("data-mode", next);
39
+ root.style.colorScheme = next;
40
+ }
41
+
42
+ export function ThemeProvider({ children }: { children: ReactNode }) {
43
+ const [mode, setMode] = useState<ColorMode | null>(null);
44
+ const [resolved, setResolved] = useState<ResolvedMode>("light");
45
+
46
+ useEffect(() => {
47
+ setMode(readMode());
48
+ setResolved(document.documentElement.getAttribute("data-mode") === "dark" ? "dark" : "light");
49
+ }, []);
50
+
51
+ useEffect(() => {
52
+ if (!mode) return;
53
+ const next = mode === "system" ? systemMode() : mode;
54
+ setResolved(next);
55
+ applyMode(next);
56
+ localStorage.setItem(STORAGE_KEY, JSON.stringify({ ...readStored(), mode }));
57
+ if (mode !== "system") return;
58
+ const query = window.matchMedia("(prefers-color-scheme: dark)");
59
+ const sync = () => {
60
+ const value = systemMode();
61
+ setResolved(value);
62
+ applyMode(value);
63
+ };
64
+ query.addEventListener("change", sync);
65
+ return () => query.removeEventListener("change", sync);
66
+ }, [mode]);
67
+
68
+ return (
69
+ <ThemeContext.Provider value={{ mode: mode ?? "system", resolved, setMode }}>{children}</ThemeContext.Provider>
70
+ );
71
+ }
72
+
73
+ export function useTheme() {
74
+ const value = useContext(ThemeContext);
75
+ if (!value) throw new Error("useTheme must be used within ThemeProvider");
76
+ return value;
77
+ }
package/styles.css ADDED
@@ -0,0 +1 @@
1
+ @import "./src/styles.css";
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.