@xenide-io/the-old-ui-theme 0.5.4 → 0.6.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 (63) hide show
  1. package/dist/{Chip-C5hRFAhe.d.mts → Chip-DzC5xtK9.d.mts} +8 -3
  2. package/dist/{Chip-C5hRFAhe.d.ts → Chip-DzC5xtK9.d.ts} +8 -3
  3. package/dist/chunk-3G43JEI3.mjs +2564 -0
  4. package/dist/index.d.mts +2 -2
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +7 -2
  7. package/dist/index.mjs +3 -1
  8. package/dist/tailwind-preset.js +1 -0
  9. package/dist/tailwind-preset.mjs +1 -0
  10. package/dist/ui.d.mts +4 -531
  11. package/dist/ui.d.ts +4 -531
  12. package/dist/ui.js +407 -2504
  13. package/dist/ui.mjs +5 -91
  14. package/package.json +1 -1
  15. package/src/app/globals.css +18 -0
  16. package/src/components/ui/Typography.tsx +12 -4
  17. package/src/components/ui/index.ts +7 -184
  18. package/src/components/ui/typography.test.tsx +27 -0
  19. package/src/styles/suite-skin.css +21 -1
  20. package/src/styles/typography.css +72 -3
  21. package/tailwind-preset.ts +1 -0
  22. package/dist/chunk-SBBKXV35.mjs +0 -4620
  23. package/src/components/ui/AlertDialog.tsx +0 -62
  24. package/src/components/ui/AppLayout.tsx +0 -27
  25. package/src/components/ui/Autocomplete.tsx +0 -106
  26. package/src/components/ui/Banner.tsx +0 -63
  27. package/src/components/ui/ButtonGroup.tsx +0 -16
  28. package/src/components/ui/ChatBubble.tsx +0 -71
  29. package/src/components/ui/Collapsible.tsx +0 -46
  30. package/src/components/ui/Combobox.tsx +0 -119
  31. package/src/components/ui/ContextMenu.tsx +0 -81
  32. package/src/components/ui/DataTable.tsx +0 -133
  33. package/src/components/ui/DatePicker.tsx +0 -96
  34. package/src/components/ui/Dialog.tsx +0 -75
  35. package/src/components/ui/Divider.tsx +0 -39
  36. package/src/components/ui/Drawer.tsx +0 -71
  37. package/src/components/ui/HoverCard.tsx +0 -36
  38. package/src/components/ui/Indicator.tsx +0 -61
  39. package/src/components/ui/InputGroup.tsx +0 -16
  40. package/src/components/ui/Lettermark.tsx +0 -47
  41. package/src/components/ui/LoadingBar.tsx +0 -25
  42. package/src/components/ui/Menubar.tsx +0 -66
  43. package/src/components/ui/Metric.tsx +0 -34
  44. package/src/components/ui/Navigation.tsx +0 -94
  45. package/src/components/ui/NumberField.tsx +0 -76
  46. package/src/components/ui/Popover.tsx +0 -73
  47. package/src/components/ui/ProgressCircle.tsx +0 -63
  48. package/src/components/ui/Rating.tsx +0 -65
  49. package/src/components/ui/Resizable.tsx +0 -71
  50. package/src/components/ui/Row.tsx +0 -51
  51. package/src/components/ui/ScrollArea.tsx +0 -54
  52. package/src/components/ui/Sidebar.tsx +0 -79
  53. package/src/components/ui/Snack.tsx +0 -48
  54. package/src/components/ui/Splotch.tsx +0 -33
  55. package/src/components/ui/Stepper.tsx +0 -74
  56. package/src/components/ui/Tabs.tsx +0 -53
  57. package/src/components/ui/Tag.tsx +0 -65
  58. package/src/components/ui/Terminal.tsx +0 -54
  59. package/src/components/ui/ThemeManager.tsx +0 -18
  60. package/src/components/ui/Timeline.tsx +0 -60
  61. package/src/components/ui/Toast.tsx +0 -70
  62. package/src/components/ui/Toggle.tsx +0 -62
  63. package/src/components/ui/Widget.tsx +0 -31
@@ -1,62 +0,0 @@
1
- "use client";
2
-
3
- import { useState, type ReactNode } from "react";
4
- import { Modal, type ModalProps } from "@/components/ui/Modal";
5
- import { Button, type ButtonProps } from "@/components/ui/Button";
6
-
7
- export interface AlertDialogProps extends Omit<ModalProps, "onClose"> {
8
- isOpen?: boolean;
9
- onClose?: () => void;
10
- onConfirm?: () => void | Promise<void>;
11
- confirmText?: string;
12
- cancelText?: string;
13
- confirmProps?: Partial<ButtonProps>;
14
- cancelProps?: Partial<ButtonProps>;
15
- children?: ReactNode;
16
- }
17
-
18
- export function AlertDialog({
19
- isOpen: openProp,
20
- onClose,
21
- onConfirm,
22
- confirmText = "Confirm",
23
- cancelText = "Cancel",
24
- confirmProps,
25
- cancelProps,
26
- children,
27
- title,
28
- ...modalProps
29
- }: AlertDialogProps) {
30
- const [loading, setLoading] = useState(false);
31
- const isOpen = openProp ?? true;
32
-
33
- const handleConfirm = async () => {
34
- if (!onConfirm) return;
35
- setLoading(true);
36
- try { await onConfirm(); } finally { setLoading(false); }
37
- onClose?.();
38
- };
39
-
40
- return (
41
- <Modal
42
- open={isOpen}
43
- onClose={onClose}
44
- title={title}
45
- footer={
46
- <div className="flex justify-end gap-2">
47
- <Button variant="secondary" {...cancelProps} onClick={onClose}>{cancelText}</Button>
48
- {onConfirm && (
49
- <Button variant="primary" loading={loading} {...confirmProps} onClick={handleConfirm}>
50
- {confirmText}
51
- </Button>
52
- )}
53
- </div>
54
- }
55
- {...modalProps}
56
- >
57
- {children}
58
- </Modal>
59
- );
60
- }
61
-
62
- AlertDialog.displayName = "AlertDialog";
@@ -1,27 +0,0 @@
1
- "use client";
2
-
3
- import { type ReactNode, useState } from "react";
4
- import { cn } from "@/lib/cn";
5
-
6
- export interface AppLayoutProps {
7
- sidebar: ReactNode;
8
- children: ReactNode;
9
- sidebarWidth?: number;
10
- className?: string;
11
- }
12
-
13
- export function AppLayout({ sidebar, children, sidebarWidth = 240, className }: AppLayoutProps) {
14
- return (
15
- <div
16
- className={cn("ph-app-layout grid min-h-screen", className)}
17
- style={{ gridTemplateColumns: `${sidebarWidth}px minmax(0, 1fr)` }}
18
- >
19
- <aside className="ph-app-layout__sidebar border-r border-ph-border bg-ph-surface overflow-y-auto">
20
- {sidebar}
21
- </aside>
22
- <main className="ph-app-layout__content min-w-0 overflow-y-auto bg-ph-canvas">
23
- {children}
24
- </main>
25
- </div>
26
- );
27
- }
@@ -1,106 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useRef, useEffect, type InputHTMLAttributes } from "react";
4
- import { cn } from "@/lib/cn";
5
-
6
- export interface AutocompleteOption {
7
- value: string;
8
- label: string;
9
- }
10
-
11
- export interface AutocompleteProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onSelect"> {
12
- options: AutocompleteOption[];
13
- onSelect?: (option: AutocompleteOption) => void;
14
- }
15
-
16
- export function Autocomplete({
17
- options,
18
- onSelect,
19
- className,
20
- value: controlledValue,
21
- onChange,
22
- placeholder = "Type to search...",
23
- ...inputProps
24
- }: AutocompleteProps) {
25
- const [open, setOpen] = useState(false);
26
- const [search, setSearch] = useState("");
27
- const [activeIndex, setActiveIndex] = useState(-1);
28
- const containerRef = useRef<HTMLDivElement>(null);
29
- const inputRef = useRef<HTMLInputElement>(null);
30
- const listRef = useRef<HTMLDivElement>(null);
31
-
32
- const filtered = options.filter((o) =>
33
- o.label.toLowerCase().includes(search.toLowerCase())
34
- );
35
-
36
- const handleSelect = (opt: AutocompleteOption) => {
37
- setSearch(opt.label);
38
- setOpen(false);
39
- onSelect?.(opt);
40
- };
41
-
42
- useEffect(() => {
43
- if (!open) { setActiveIndex(-1); return; }
44
- const handle = (e: MouseEvent) => {
45
- if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
46
- setOpen(false);
47
- }
48
- };
49
- const handleKey = (e: KeyboardEvent) => {
50
- if (e.key === "ArrowDown") { setActiveIndex((i) => Math.min(i + 1, filtered.length - 1)); e.preventDefault(); }
51
- if (e.key === "ArrowUp") { setActiveIndex((i) => Math.max(i - 1, 0)); e.preventDefault(); }
52
- if (e.key === "Enter" && activeIndex >= 0) { handleSelect(filtered[activeIndex]); e.preventDefault(); }
53
- if (e.key === "Escape") { setOpen(false); }
54
- };
55
- document.addEventListener("mousedown", handle);
56
- document.addEventListener("keydown", handleKey);
57
- return () => {
58
- document.removeEventListener("mousedown", handle);
59
- document.removeEventListener("keydown", handleKey);
60
- };
61
- }, [open, filtered, activeIndex]);
62
-
63
- useEffect(() => {
64
- if (activeIndex >= 0 && listRef.current) {
65
- const el = listRef.current.children[activeIndex] as HTMLElement;
66
- el?.scrollIntoView({ block: "nearest" });
67
- }
68
- }, [activeIndex]);
69
-
70
- return (
71
- <div ref={containerRef} className={cn("ph-autocomplete relative", className)}>
72
- <input
73
- ref={inputRef}
74
- type="text"
75
- value={search}
76
- onChange={(e) => { setSearch(e.target.value); setOpen(true); onChange?.(e); }}
77
- onFocus={() => setOpen(true)}
78
- placeholder={placeholder}
79
- className="ph-input w-full"
80
- {...inputProps}
81
- />
82
- {open && filtered.length > 0 && (
83
- <div ref={listRef} className="ph-autocomplete__dropdown" role="listbox">
84
- {filtered.map((opt, i) => (
85
- <button
86
- key={opt.value}
87
- type="button"
88
- role="option"
89
- aria-selected={i === activeIndex}
90
- onMouseDown={() => handleSelect(opt)}
91
- onMouseEnter={() => setActiveIndex(i)}
92
- className={cn(
93
- "ph-autocomplete__option",
94
- i === activeIndex && "ph-autocomplete__option--active"
95
- )}
96
- >
97
- {opt.label}
98
- </button>
99
- ))}
100
- </div>
101
- )}
102
- </div>
103
- );
104
- }
105
-
106
- Autocomplete.displayName = "Autocomplete";
@@ -1,63 +0,0 @@
1
- import { forwardRef, type HTMLAttributes, type ReactNode } from "react";
2
- import { cn } from "@/lib/cn";
3
-
4
- export type BannerType = "info" | "success" | "warning" | "danger" | "ai";
5
-
6
- export interface BannerProps extends HTMLAttributes<HTMLDivElement> {
7
- type?: BannerType;
8
- onClose?: () => void;
9
- action?: ReactNode;
10
- hideIcon?: boolean;
11
- square?: boolean;
12
- icon?: ReactNode;
13
- children: ReactNode;
14
- }
15
-
16
- const typeClass: Record<BannerType, string> = {
17
- info: "ph-banner-info",
18
- success: "ph-banner-success",
19
- warning: "ph-banner-warning",
20
- danger: "ph-banner-danger",
21
- ai: "ph-banner-ai",
22
- };
23
-
24
- export const Banner = forwardRef<HTMLDivElement, BannerProps>(function Banner({
25
- type = "info",
26
- onClose,
27
- action,
28
- hideIcon = false,
29
- square = false,
30
- icon,
31
- className,
32
- children,
33
- ...props
34
- }, ref) {
35
- return (
36
- <div
37
- ref={ref}
38
- role="alert"
39
- className={cn(
40
- "ph-banner",
41
- typeClass[type],
42
- square && "ph-banner--square",
43
- className
44
- )}
45
- {...props}
46
- >
47
- <div className="ph-banner__body">
48
- {icon}
49
- <div className="ph-banner__content">{children}</div>
50
- {action && <div className="ph-banner__action">{action}</div>}
51
- {onClose && (
52
- <button type="button" onClick={onClose} className="ph-banner__close" aria-label="Dismiss">
53
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
54
- <path d="M4 4l8 8M12 4l-8 8" />
55
- </svg>
56
- </button>
57
- )}
58
- </div>
59
- </div>
60
- );
61
- });
62
-
63
- Banner.displayName = "Banner";
@@ -1,16 +0,0 @@
1
- import { type ReactNode, type HTMLAttributes } from "react";
2
- import { cn } from "@/lib/cn";
3
-
4
- export interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {
5
- children: ReactNode;
6
- }
7
-
8
- export function ButtonGroup({ children, className, ...props }: ButtonGroupProps) {
9
- return (
10
- <div className={cn("ph-btn-group", className)} {...props}>
11
- {children}
12
- </div>
13
- );
14
- }
15
-
16
- ButtonGroup.displayName = "ButtonGroup";
@@ -1,71 +0,0 @@
1
- import type { ComponentPropsWithoutRef, ReactNode } from "react";
2
- import { cn } from "@/lib/cn";
3
-
4
- export type ChatBubbleVariant = "from" | "self";
5
-
6
- export interface ChatBubbleProps extends ComponentPropsWithoutRef<"div"> {
7
- /** Message content */
8
- children?: ReactNode;
9
- /** Avatar or icon */
10
- avatar?: ReactNode;
11
- /** Sender name */
12
- name?: string;
13
- /** Timestamp */
14
- time?: string;
15
- /** "from" = left/grey, "self" = right/brand */
16
- variant?: ChatBubbleVariant;
17
- /** Footer text (e.g. "Synced with...") */
18
- footer?: ReactNode;
19
- }
20
-
21
- export function ChatBubble({
22
- children,
23
- avatar,
24
- name,
25
- time,
26
- variant = "from",
27
- footer,
28
- className,
29
- ...props
30
- }: ChatBubbleProps) {
31
- const isSelf = variant === "self";
32
-
33
- return (
34
- <div
35
- className={cn(
36
- "flex gap-3",
37
- isSelf && "flex-row-reverse",
38
- className,
39
- )}
40
- {...props}
41
- >
42
- {avatar && (
43
- <div className="shrink-0">{avatar}</div>
44
- )}
45
- <div className={cn("min-w-0 flex-1", isSelf && "text-right")}>
46
- {(name || time) && (
47
- <header
48
- className={cn(
49
- "flex gap-2 text-xs text-ph-mutedtext",
50
- isSelf && "flex-row-reverse justify-end",
51
- )}
52
- >
53
- {name && <span className="font-semibold text-ph-ink">{name}</span>}
54
- {time && <span>{time}</span>}
55
- </header>
56
- )}
57
- <div
58
- className={cn(
59
- "mt-2 inline-block text-left shadow-ph",
60
- isSelf ? "ph-chat-self" : "ph-chat-from",
61
- )}
62
- >
63
- {children}
64
- </div>
65
- {footer && (
66
- <footer className="mt-2 text-[11px] text-ph-mutedtext">{footer}</footer>
67
- )}
68
- </div>
69
- </div>
70
- );
71
- }
@@ -1,46 +0,0 @@
1
- "use client";
2
-
3
- import { useState, type ReactNode, type HTMLAttributes } from "react";
4
- import { cn } from "@/lib/cn";
5
-
6
- export interface CollapsibleProps extends HTMLAttributes<HTMLDivElement> {
7
- trigger: ReactNode;
8
- open?: boolean;
9
- onOpenChange?: (open: boolean) => void;
10
- children: ReactNode;
11
- }
12
-
13
- export function Collapsible({
14
- trigger,
15
- open: controlledOpen,
16
- onOpenChange,
17
- children,
18
- className,
19
- ...props
20
- }: CollapsibleProps) {
21
- const [internalOpen, setInternalOpen] = useState(false);
22
- const isOpen = controlledOpen ?? internalOpen;
23
- const setOpen = onOpenChange ?? setInternalOpen;
24
-
25
- return (
26
- <div className={cn("ph-collapsible", className)} {...props}>
27
- <button
28
- type="button"
29
- onClick={() => setOpen(!isOpen)}
30
- className="ph-collapsible__trigger"
31
- aria-expanded={isOpen}
32
- >
33
- <svg
34
- className={cn("ph-collapsible__chevron", isOpen && "ph-collapsible__chevron--open")}
35
- width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"
36
- >
37
- <path d="M4 5l3 3 3-3" />
38
- </svg>
39
- {trigger}
40
- </button>
41
- {isOpen && <div className="ph-collapsible__content">{children}</div>}
42
- </div>
43
- );
44
- }
45
-
46
- Collapsible.displayName = "Collapsible";
@@ -1,119 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useRef, useEffect, type ReactNode } from "react";
4
- import { cn } from "@/lib/cn";
5
-
6
- export interface ComboboxOption {
7
- value: string;
8
- label: string;
9
- }
10
-
11
- export interface ComboboxProps {
12
- options: ComboboxOption[];
13
- value?: string[];
14
- onChange?: (value: string[]) => void;
15
- placeholder?: string;
16
- className?: string;
17
- disabled?: boolean;
18
- }
19
-
20
- export function Combobox({
21
- options,
22
- value = [],
23
- onChange,
24
- placeholder = "Search...",
25
- className,
26
- disabled,
27
- }: ComboboxProps) {
28
- const [open, setOpen] = useState(false);
29
- const [search, setSearch] = useState("");
30
- const inputRef = useRef<HTMLInputElement>(null);
31
- const containerRef = useRef<HTMLDivElement>(null);
32
-
33
- const filtered = options.filter((o) =>
34
- o.label.toLowerCase().includes(search.toLowerCase())
35
- );
36
-
37
- const selectedSet = new Set(value);
38
-
39
- const toggle = (val: string) => {
40
- const next = selectedSet.has(val)
41
- ? value.filter((v) => v !== val)
42
- : [...value, val];
43
- onChange?.(next);
44
- };
45
-
46
- useEffect(() => {
47
- if (!open) return;
48
- const handle = (e: MouseEvent) => {
49
- if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
50
- setOpen(false);
51
- }
52
- };
53
- document.addEventListener("mousedown", handle);
54
- return () => document.removeEventListener("mousedown", handle);
55
- }, [open]);
56
-
57
- return (
58
- <div ref={containerRef} className={cn("ph-combobox relative", className)}>
59
- <div className="ph-combobox__input-wrap">
60
- {value.length > 0 && (
61
- <div className="ph-combobox__chips">
62
- {value.map((v) => {
63
- const opt = options.find((o) => o.value === v);
64
- return (
65
- <span key={v} className="ph-combobox__chip">
66
- {opt?.label ?? v}
67
- <button
68
- type="button"
69
- onClick={() => toggle(v)}
70
- className="ph-combobox__chip-remove"
71
- aria-label={`Remove ${opt?.label ?? v}`}
72
- >
73
- <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
74
- <path d="M2 2l6 6M8 2l-6 6" />
75
- </svg>
76
- </button>
77
- </span>
78
- );
79
- })}
80
- </div>
81
- )}
82
- <input
83
- ref={inputRef}
84
- type="text"
85
- value={search}
86
- onChange={(e) => { setSearch(e.target.value); setOpen(true); }}
87
- onFocus={() => setOpen(true)}
88
- placeholder={value.length === 0 ? placeholder : ""}
89
- disabled={disabled}
90
- className="ph-combobox__input"
91
- />
92
- </div>
93
- {open && filtered.length > 0 && (
94
- <div className="ph-combobox__dropdown">
95
- {filtered.map((opt) => (
96
- <button
97
- key={opt.value}
98
- type="button"
99
- onClick={() => toggle(opt.value)}
100
- className={cn(
101
- "ph-combobox__option",
102
- selectedSet.has(opt.value) && "ph-combobox__option--selected"
103
- )}
104
- >
105
- {selectedSet.has(opt.value) && (
106
- <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
107
- <path d="M2.5 6l2.5 2.5 4.5-5" />
108
- </svg>
109
- )}
110
- <span>{opt.label}</span>
111
- </button>
112
- ))}
113
- </div>
114
- )}
115
- </div>
116
- );
117
- }
118
-
119
- Combobox.displayName = "Combobox";
@@ -1,81 +0,0 @@
1
- "use client";
2
-
3
- import { useState, useRef, useEffect, type ReactNode, type HTMLAttributes } from "react";
4
- import { cn } from "@/lib/cn";
5
-
6
- export interface ContextMenuItem {
7
- label?: string;
8
- onClick?: () => void;
9
- disabled?: boolean;
10
- separator?: boolean;
11
- icon?: ReactNode;
12
- }
13
-
14
- export interface ContextMenuProps extends HTMLAttributes<HTMLDivElement> {
15
- items: ContextMenuItem[];
16
- children: ReactNode;
17
- }
18
-
19
- export function ContextMenu({ items, children, className, ...props }: ContextMenuProps) {
20
- const [open, setOpen] = useState(false);
21
- const [pos, setPos] = useState({ x: 0, y: 0 });
22
- const menuRef = useRef<HTMLDivElement>(null);
23
-
24
- useEffect(() => {
25
- if (!open) return;
26
- const handle = (e: MouseEvent) => {
27
- if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
28
- setOpen(false);
29
- }
30
- };
31
- const handleKey = (e: KeyboardEvent) => {
32
- if (e.key === "Escape") setOpen(false);
33
- };
34
- document.addEventListener("mousedown", handle);
35
- document.addEventListener("keydown", handleKey);
36
- return () => {
37
- document.removeEventListener("mousedown", handle);
38
- document.removeEventListener("keydown", handleKey);
39
- };
40
- }, [open]);
41
-
42
- return (
43
- <div
44
- className={cn("ph-context-menu", className)}
45
- onContextMenu={(e) => {
46
- e.preventDefault();
47
- setPos({ x: e.clientX, y: e.clientY });
48
- setOpen(true);
49
- }}
50
- {...props}
51
- >
52
- {children}
53
- {open && (
54
- <div
55
- ref={menuRef}
56
- className="ph-context-menu__panel"
57
- style={{ left: pos.x, top: pos.y }}
58
- >
59
- {items.map((item, i) =>
60
- item.separator ? (
61
- <div key={i} className="ph-context-menu__separator" />
62
- ) : (
63
- <button
64
- key={i}
65
- type="button"
66
- disabled={item.disabled}
67
- onClick={() => { item.onClick?.(); setOpen(false); }}
68
- className="ph-context-menu__item"
69
- >
70
- {item.icon && <span className="ph-context-menu__icon">{item.icon}</span>}
71
- <span>{item.label}</span>
72
- </button>
73
- )
74
- )}
75
- </div>
76
- )}
77
- </div>
78
- );
79
- }
80
-
81
- ContextMenu.displayName = "ContextMenu";