@classic-homes/theme-svelte 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +305 -0
  2. package/dist/lib/components/Alert.svelte +51 -0
  3. package/dist/lib/components/Alert.svelte.d.ts +9 -0
  4. package/dist/lib/components/AlertDescription.svelte +16 -0
  5. package/dist/lib/components/AlertDescription.svelte.d.ts +9 -0
  6. package/dist/lib/components/AlertDialog.svelte +136 -0
  7. package/dist/lib/components/AlertDialog.svelte.d.ts +79 -0
  8. package/dist/lib/components/AlertTitle.svelte +16 -0
  9. package/dist/lib/components/AlertTitle.svelte.d.ts +9 -0
  10. package/dist/lib/components/Avatar.svelte +56 -0
  11. package/dist/lib/components/Avatar.svelte.d.ts +26 -0
  12. package/dist/lib/components/AvatarFallback.svelte +31 -0
  13. package/dist/lib/components/AvatarFallback.svelte.d.ts +17 -0
  14. package/dist/lib/components/AvatarImage.svelte +29 -0
  15. package/dist/lib/components/AvatarImage.svelte.d.ts +12 -0
  16. package/dist/lib/components/Badge.svelte +73 -0
  17. package/dist/lib/components/Badge.svelte.d.ts +11 -0
  18. package/dist/lib/components/Button.svelte +130 -0
  19. package/dist/lib/components/Button.svelte.d.ts +17 -0
  20. package/dist/lib/components/Card.svelte +58 -0
  21. package/dist/lib/components/Card.svelte.d.ts +26 -0
  22. package/dist/lib/components/CardContent.svelte +16 -0
  23. package/dist/lib/components/CardContent.svelte.d.ts +9 -0
  24. package/dist/lib/components/CardDescription.svelte +16 -0
  25. package/dist/lib/components/CardDescription.svelte.d.ts +9 -0
  26. package/dist/lib/components/CardFooter.svelte +16 -0
  27. package/dist/lib/components/CardFooter.svelte.d.ts +9 -0
  28. package/dist/lib/components/CardHeader.svelte +16 -0
  29. package/dist/lib/components/CardHeader.svelte.d.ts +9 -0
  30. package/dist/lib/components/CardTitle.svelte +16 -0
  31. package/dist/lib/components/CardTitle.svelte.d.ts +9 -0
  32. package/dist/lib/components/Checkbox.svelte +65 -0
  33. package/dist/lib/components/Checkbox.svelte.d.ts +14 -0
  34. package/dist/lib/components/DataTable.svelte +334 -0
  35. package/dist/lib/components/DataTable.svelte.d.ts +103 -0
  36. package/dist/lib/components/Dialog.svelte +111 -0
  37. package/dist/lib/components/Dialog.svelte.d.ts +22 -0
  38. package/dist/lib/components/DropdownMenu.svelte +135 -0
  39. package/dist/lib/components/DropdownMenu.svelte.d.ts +33 -0
  40. package/dist/lib/components/FileUpload.svelte +448 -0
  41. package/dist/lib/components/FileUpload.svelte.d.ts +42 -0
  42. package/dist/lib/components/FormField.svelte +134 -0
  43. package/dist/lib/components/FormField.svelte.d.ts +37 -0
  44. package/dist/lib/components/Input.svelte +61 -0
  45. package/dist/lib/components/Input.svelte.d.ts +19 -0
  46. package/dist/lib/components/Label.svelte +33 -0
  47. package/dist/lib/components/Label.svelte.d.ts +11 -0
  48. package/dist/lib/components/LoadingLogo.svelte +124 -0
  49. package/dist/lib/components/LoadingLogo.svelte.d.ts +16 -0
  50. package/dist/lib/components/LogoMain.svelte +237 -0
  51. package/dist/lib/components/LogoMain.svelte.d.ts +20 -0
  52. package/dist/lib/components/PageHeader.svelte +90 -0
  53. package/dist/lib/components/PageHeader.svelte.d.ts +28 -0
  54. package/dist/lib/components/Section.svelte +44 -0
  55. package/dist/lib/components/Section.svelte.d.ts +28 -0
  56. package/dist/lib/components/Select.svelte +174 -0
  57. package/dist/lib/components/Select.svelte.d.ts +32 -0
  58. package/dist/lib/components/Separator.svelte +29 -0
  59. package/dist/lib/components/Separator.svelte.d.ts +9 -0
  60. package/dist/lib/components/Skeleton.svelte +35 -0
  61. package/dist/lib/components/Skeleton.svelte.d.ts +7 -0
  62. package/dist/lib/components/Spinner.svelte +50 -0
  63. package/dist/lib/components/Spinner.svelte.d.ts +8 -0
  64. package/dist/lib/components/Switch.svelte +56 -0
  65. package/dist/lib/components/Switch.svelte.d.ts +14 -0
  66. package/dist/lib/components/TabPanel.svelte +44 -0
  67. package/dist/lib/components/TabPanel.svelte.d.ts +12 -0
  68. package/dist/lib/components/Tabs.svelte +125 -0
  69. package/dist/lib/components/Tabs.svelte.d.ts +19 -0
  70. package/dist/lib/components/Textarea.svelte +54 -0
  71. package/dist/lib/components/Textarea.svelte.d.ts +16 -0
  72. package/dist/lib/components/Toast.svelte +116 -0
  73. package/dist/lib/components/Toast.svelte.d.ts +12 -0
  74. package/dist/lib/components/ToastContainer.svelte +56 -0
  75. package/dist/lib/components/ToastContainer.svelte.d.ts +8 -0
  76. package/dist/lib/components/Tooltip.svelte +55 -0
  77. package/dist/lib/components/Tooltip.svelte.d.ts +18 -0
  78. package/dist/lib/components/layout/AppShell.svelte +82 -0
  79. package/dist/lib/components/layout/AppShell.svelte.d.ts +44 -0
  80. package/dist/lib/components/layout/DashboardLayout.svelte +248 -0
  81. package/dist/lib/components/layout/DashboardLayout.svelte.d.ts +62 -0
  82. package/dist/lib/components/layout/Footer.svelte +130 -0
  83. package/dist/lib/components/layout/Footer.svelte.d.ts +32 -0
  84. package/dist/lib/components/layout/FormPageLayout.svelte +92 -0
  85. package/dist/lib/components/layout/FormPageLayout.svelte.d.ts +33 -0
  86. package/dist/lib/components/layout/Header.svelte +94 -0
  87. package/dist/lib/components/layout/Header.svelte.d.ts +30 -0
  88. package/dist/lib/components/layout/PublicLayout.svelte +180 -0
  89. package/dist/lib/components/layout/PublicLayout.svelte.d.ts +39 -0
  90. package/dist/lib/components/layout/QuickLinks.svelte +112 -0
  91. package/dist/lib/components/layout/QuickLinks.svelte.d.ts +27 -0
  92. package/dist/lib/components/layout/Sidebar.svelte +243 -0
  93. package/dist/lib/components/layout/Sidebar.svelte.d.ts +48 -0
  94. package/dist/lib/composables/index.d.ts +8 -0
  95. package/dist/lib/composables/index.js +10 -0
  96. package/dist/lib/composables/useAsync.svelte.d.ts +102 -0
  97. package/dist/lib/composables/useAsync.svelte.js +210 -0
  98. package/dist/lib/composables/useForm.svelte.d.ts +123 -0
  99. package/dist/lib/composables/useForm.svelte.js +245 -0
  100. package/dist/lib/index.d.ts +65 -0
  101. package/dist/lib/index.js +83 -0
  102. package/dist/lib/performance.d.ts +79 -0
  103. package/dist/lib/performance.js +170 -0
  104. package/dist/lib/schemas/auth.d.ts +410 -0
  105. package/dist/lib/schemas/auth.js +216 -0
  106. package/dist/lib/schemas/common.d.ts +267 -0
  107. package/dist/lib/schemas/common.js +268 -0
  108. package/dist/lib/schemas/index.d.ts +24 -0
  109. package/dist/lib/schemas/index.js +32 -0
  110. package/dist/lib/stores/sidebar.svelte.d.ts +25 -0
  111. package/dist/lib/stores/sidebar.svelte.js +38 -0
  112. package/dist/lib/stores/theme.svelte.d.ts +72 -0
  113. package/dist/lib/stores/theme.svelte.js +150 -0
  114. package/dist/lib/stores/toast.svelte.d.ts +62 -0
  115. package/dist/lib/stores/toast.svelte.js +93 -0
  116. package/dist/lib/types/components.d.ts +85 -0
  117. package/dist/lib/types/components.js +7 -0
  118. package/dist/lib/types/layout.d.ts +258 -0
  119. package/dist/lib/types/layout.js +7 -0
  120. package/dist/lib/utils.d.ts +6 -0
  121. package/dist/lib/utils.js +9 -0
  122. package/dist/lib/validation.d.ts +101 -0
  123. package/dist/lib/validation.js +170 -0
  124. package/package.json +56 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Theme Store - Svelte 5 runes-based theme management
3
+ *
4
+ * Features:
5
+ * - Light/dark/system mode support
6
+ * - System preference detection via matchMedia
7
+ * - Persistence via localStorage
8
+ * - SSR-safe (checks for window/document)
9
+ * - Reactive theme resolution
10
+ *
11
+ * @example
12
+ * ```svelte
13
+ * <script>
14
+ * import { themeStore } from '@classic-homes/theme-svelte';
15
+ * </script>
16
+ *
17
+ * <button onclick={() => themeStore.toggle()}>
18
+ * {themeStore.resolvedTheme === 'dark' ? 'Light' : 'Dark'} Mode
19
+ * </button>
20
+ *
21
+ * <select value={themeStore.mode} onchange={(e) => themeStore.setMode(e.target.value)}>
22
+ * <option value="light">Light</option>
23
+ * <option value="dark">Dark</option>
24
+ * <option value="system">System</option>
25
+ * </select>
26
+ * ```
27
+ */
28
+ export type ThemeMode = 'light' | 'dark' | 'system';
29
+ declare class ThemeStore {
30
+ /** Current theme mode setting (light, dark, or system) */
31
+ mode: ThemeMode;
32
+ /** Resolved theme (accounts for system preference when mode is 'system') */
33
+ resolvedTheme: "dark" | "light";
34
+ /** Whether we're on the client (not SSR) */
35
+ private isClient;
36
+ /** Media query for system dark mode preference */
37
+ private mediaQuery;
38
+ constructor();
39
+ private init;
40
+ private handleSystemChange;
41
+ private updateResolvedTheme;
42
+ private applyTheme;
43
+ /**
44
+ * Set theme mode and persist to localStorage
45
+ * @param mode - The theme mode to set ('light', 'dark', or 'system')
46
+ */
47
+ setMode(mode: ThemeMode): void;
48
+ /**
49
+ * Toggle between light and dark modes
50
+ * If currently using system mode, switches to the opposite of system preference
51
+ * NOTE: No-op when DARK_MODE_ENABLED is false
52
+ */
53
+ toggle(): void;
54
+ /**
55
+ * Reset to follow system preference
56
+ */
57
+ useSystem(): void;
58
+ /**
59
+ * Check if currently following system preference
60
+ */
61
+ get isSystem(): boolean;
62
+ /**
63
+ * Check if current resolved theme is dark
64
+ */
65
+ get isDark(): boolean;
66
+ /**
67
+ * Check if current resolved theme is light
68
+ */
69
+ get isLight(): boolean;
70
+ }
71
+ export declare const themeStore: ThemeStore;
72
+ export {};
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Theme Store - Svelte 5 runes-based theme management
3
+ *
4
+ * Features:
5
+ * - Light/dark/system mode support
6
+ * - System preference detection via matchMedia
7
+ * - Persistence via localStorage
8
+ * - SSR-safe (checks for window/document)
9
+ * - Reactive theme resolution
10
+ *
11
+ * @example
12
+ * ```svelte
13
+ * <script>
14
+ * import { themeStore } from '@classic-homes/theme-svelte';
15
+ * </script>
16
+ *
17
+ * <button onclick={() => themeStore.toggle()}>
18
+ * {themeStore.resolvedTheme === 'dark' ? 'Light' : 'Dark'} Mode
19
+ * </button>
20
+ *
21
+ * <select value={themeStore.mode} onchange={(e) => themeStore.setMode(e.target.value)}>
22
+ * <option value="light">Light</option>
23
+ * <option value="dark">Dark</option>
24
+ * <option value="system">System</option>
25
+ * </select>
26
+ * ```
27
+ */
28
+ /**
29
+ * TEMPORARY: Dark mode is disabled while we focus on light mode styling.
30
+ * Set to true to re-enable dark mode functionality.
31
+ */
32
+ const DARK_MODE_ENABLED = false;
33
+ const STORAGE_KEY = 'classic-theme-mode';
34
+ class ThemeStore {
35
+ constructor() {
36
+ /** Current theme mode setting (light, dark, or system) */
37
+ this.mode = $state('system');
38
+ /** Resolved theme (accounts for system preference when mode is 'system') */
39
+ this.resolvedTheme = $state('light');
40
+ /** Whether we're on the client (not SSR) */
41
+ this.isClient = typeof window !== 'undefined';
42
+ /** Media query for system dark mode preference */
43
+ this.mediaQuery = null;
44
+ if (this.isClient) {
45
+ this.init();
46
+ }
47
+ }
48
+ init() {
49
+ // Load persisted preference
50
+ try {
51
+ const stored = localStorage.getItem(STORAGE_KEY);
52
+ if (stored && ['light', 'dark', 'system'].includes(stored)) {
53
+ this.mode = stored;
54
+ }
55
+ }
56
+ catch {
57
+ // localStorage may not be available (private browsing, etc.)
58
+ }
59
+ // Set up system preference listener
60
+ this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
61
+ this.mediaQuery.addEventListener('change', this.handleSystemChange.bind(this));
62
+ // Initial resolution
63
+ this.updateResolvedTheme();
64
+ }
65
+ handleSystemChange() {
66
+ if (this.mode === 'system') {
67
+ this.updateResolvedTheme();
68
+ }
69
+ }
70
+ updateResolvedTheme() {
71
+ if (!this.isClient)
72
+ return;
73
+ let resolved;
74
+ // TEMPORARY: Force light mode while dark mode is disabled
75
+ if (!DARK_MODE_ENABLED) {
76
+ resolved = 'light';
77
+ }
78
+ else if (this.mode === 'system') {
79
+ resolved = this.mediaQuery?.matches ? 'dark' : 'light';
80
+ }
81
+ else {
82
+ resolved = this.mode;
83
+ }
84
+ this.resolvedTheme = resolved;
85
+ this.applyTheme(resolved);
86
+ }
87
+ applyTheme(theme) {
88
+ if (!this.isClient)
89
+ return;
90
+ const root = document.documentElement;
91
+ root.classList.remove('light', 'dark');
92
+ root.classList.add(theme);
93
+ // Update meta theme-color for mobile browsers
94
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]');
95
+ if (metaThemeColor) {
96
+ metaThemeColor.setAttribute('content', theme === 'dark' ? '#292424' : '#ffffff');
97
+ }
98
+ }
99
+ /**
100
+ * Set theme mode and persist to localStorage
101
+ * @param mode - The theme mode to set ('light', 'dark', or 'system')
102
+ */
103
+ setMode(mode) {
104
+ this.mode = mode;
105
+ if (this.isClient) {
106
+ try {
107
+ localStorage.setItem(STORAGE_KEY, mode);
108
+ }
109
+ catch {
110
+ // localStorage may not be available
111
+ }
112
+ }
113
+ this.updateResolvedTheme();
114
+ }
115
+ /**
116
+ * Toggle between light and dark modes
117
+ * If currently using system mode, switches to the opposite of system preference
118
+ * NOTE: No-op when DARK_MODE_ENABLED is false
119
+ */
120
+ toggle() {
121
+ if (!DARK_MODE_ENABLED)
122
+ return;
123
+ this.setMode(this.resolvedTheme === 'light' ? 'dark' : 'light');
124
+ }
125
+ /**
126
+ * Reset to follow system preference
127
+ */
128
+ useSystem() {
129
+ this.setMode('system');
130
+ }
131
+ /**
132
+ * Check if currently following system preference
133
+ */
134
+ get isSystem() {
135
+ return this.mode === 'system';
136
+ }
137
+ /**
138
+ * Check if current resolved theme is dark
139
+ */
140
+ get isDark() {
141
+ return this.resolvedTheme === 'dark';
142
+ }
143
+ /**
144
+ * Check if current resolved theme is light
145
+ */
146
+ get isLight() {
147
+ return this.resolvedTheme === 'light';
148
+ }
149
+ }
150
+ export const themeStore = new ThemeStore();
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Toast Store - Svelte 5 runes-based state management for toast notifications
3
+ *
4
+ * Features:
5
+ * - Auto-dismiss with configurable duration
6
+ * - Manual dismiss support
7
+ * - Proper timeout cleanup to prevent memory leaks
8
+ * - Convenience methods for common toast types
9
+ */
10
+ export interface Toast {
11
+ id: string;
12
+ message: string;
13
+ type: 'success' | 'error' | 'warning' | 'info';
14
+ title?: string;
15
+ duration?: number;
16
+ }
17
+ export type ToastInput = Omit<Toast, 'id'>;
18
+ declare class ToastStore {
19
+ toasts: Toast[];
20
+ /** Map of toast IDs to their timeout handles for cleanup */
21
+ private timeouts;
22
+ /**
23
+ * Add a new toast notification
24
+ * @param toast - Toast configuration without id
25
+ * @returns The generated toast id
26
+ */
27
+ add(toast: ToastInput): string;
28
+ /**
29
+ * Remove a toast by id
30
+ * Also clears any pending auto-dismiss timeout
31
+ */
32
+ remove(id: string): void;
33
+ /**
34
+ * Remove all toasts and clear all pending timeouts
35
+ */
36
+ clear(): void;
37
+ /**
38
+ * Update an existing toast
39
+ * @param id - Toast ID to update
40
+ * @param updates - Partial toast properties to update
41
+ */
42
+ update(id: string, updates: Partial<Omit<Toast, 'id'>>): void;
43
+ /**
44
+ * Convenience method for success toast
45
+ */
46
+ success(message: string, options?: Partial<Omit<ToastInput, 'message' | 'type'>>): string;
47
+ /**
48
+ * Convenience method for error toast
49
+ * Note: Errors persist by default (duration: 0) since they typically require acknowledgment
50
+ */
51
+ error(message: string, options?: Partial<Omit<ToastInput, 'message' | 'type'>>): string;
52
+ /**
53
+ * Convenience method for warning toast
54
+ */
55
+ warning(message: string, options?: Partial<Omit<ToastInput, 'message' | 'type'>>): string;
56
+ /**
57
+ * Convenience method for info toast
58
+ */
59
+ info(message: string, options?: Partial<Omit<ToastInput, 'message' | 'type'>>): string;
60
+ }
61
+ export declare const toastStore: ToastStore;
62
+ export {};
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Toast Store - Svelte 5 runes-based state management for toast notifications
3
+ *
4
+ * Features:
5
+ * - Auto-dismiss with configurable duration
6
+ * - Manual dismiss support
7
+ * - Proper timeout cleanup to prevent memory leaks
8
+ * - Convenience methods for common toast types
9
+ */
10
+ class ToastStore {
11
+ constructor() {
12
+ this.toasts = $state([]);
13
+ /** Map of toast IDs to their timeout handles for cleanup */
14
+ this.timeouts = new Map();
15
+ }
16
+ /**
17
+ * Add a new toast notification
18
+ * @param toast - Toast configuration without id
19
+ * @returns The generated toast id
20
+ */
21
+ add(toast) {
22
+ const id = crypto.randomUUID();
23
+ const newToast = { ...toast, id };
24
+ this.toasts = [...this.toasts, newToast];
25
+ // Auto-dismiss unless duration is explicitly 0 (persistent)
26
+ if (toast.duration !== 0) {
27
+ const duration = toast.duration ?? 5000;
28
+ const timeoutId = setTimeout(() => {
29
+ this.remove(id);
30
+ }, duration);
31
+ this.timeouts.set(id, timeoutId);
32
+ }
33
+ return id;
34
+ }
35
+ /**
36
+ * Remove a toast by id
37
+ * Also clears any pending auto-dismiss timeout
38
+ */
39
+ remove(id) {
40
+ // Clear timeout if exists to prevent memory leak
41
+ const timeoutId = this.timeouts.get(id);
42
+ if (timeoutId !== undefined) {
43
+ clearTimeout(timeoutId);
44
+ this.timeouts.delete(id);
45
+ }
46
+ this.toasts = this.toasts.filter((t) => t.id !== id);
47
+ }
48
+ /**
49
+ * Remove all toasts and clear all pending timeouts
50
+ */
51
+ clear() {
52
+ // Clear all pending timeouts
53
+ for (const timeoutId of this.timeouts.values()) {
54
+ clearTimeout(timeoutId);
55
+ }
56
+ this.timeouts.clear();
57
+ this.toasts = [];
58
+ }
59
+ /**
60
+ * Update an existing toast
61
+ * @param id - Toast ID to update
62
+ * @param updates - Partial toast properties to update
63
+ */
64
+ update(id, updates) {
65
+ this.toasts = this.toasts.map((t) => (t.id === id ? { ...t, ...updates } : t));
66
+ }
67
+ /**
68
+ * Convenience method for success toast
69
+ */
70
+ success(message, options) {
71
+ return this.add({ message, type: 'success', ...options });
72
+ }
73
+ /**
74
+ * Convenience method for error toast
75
+ * Note: Errors persist by default (duration: 0) since they typically require acknowledgment
76
+ */
77
+ error(message, options) {
78
+ return this.add({ message, type: 'error', duration: 0, ...options });
79
+ }
80
+ /**
81
+ * Convenience method for warning toast
82
+ */
83
+ warning(message, options) {
84
+ return this.add({ message, type: 'warning', ...options });
85
+ }
86
+ /**
87
+ * Convenience method for info toast
88
+ */
89
+ info(message, options) {
90
+ return this.add({ message, type: 'info', ...options });
91
+ }
92
+ }
93
+ export const toastStore = new ToastStore();
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Component Types for Classic Theme
3
+ *
4
+ * These types are exported from components but need to be
5
+ * re-exported from a TypeScript file for proper type inference.
6
+ */
7
+ /**
8
+ * Dropdown Menu Types
9
+ */
10
+ import type { Snippet } from 'svelte';
11
+ export interface DropdownMenuItem {
12
+ type?: 'item' | 'checkbox' | 'radio' | 'separator' | 'label';
13
+ label?: string;
14
+ value?: string;
15
+ disabled?: boolean;
16
+ checked?: boolean;
17
+ onSelect?: () => void;
18
+ destructive?: boolean;
19
+ icon?: Snippet;
20
+ shortcut?: string;
21
+ }
22
+ export interface DropdownMenuGroup {
23
+ label?: string;
24
+ items: DropdownMenuItem[];
25
+ }
26
+ /**
27
+ * Select Types
28
+ */
29
+ export interface SelectOption {
30
+ value: string;
31
+ label: string;
32
+ disabled?: boolean;
33
+ }
34
+ export interface SelectGroup {
35
+ label: string;
36
+ options: SelectOption[];
37
+ }
38
+ /**
39
+ * Tabs Types
40
+ */
41
+ export interface Tab {
42
+ id: string;
43
+ label: string;
44
+ disabled?: boolean;
45
+ }
46
+ /**
47
+ * FileUpload Types
48
+ */
49
+ export interface FileMetadata {
50
+ /** Unique identifier for the file */
51
+ id: string;
52
+ /** Original filename */
53
+ filename: string;
54
+ /** MIME type */
55
+ contentType: string;
56
+ /** File size in bytes */
57
+ size: number;
58
+ /** URL for preview (data URL or remote URL) */
59
+ url?: string;
60
+ /** Upload progress (0-100) */
61
+ progress?: number;
62
+ /** Error message if upload failed */
63
+ error?: string;
64
+ /** Whether the file is currently uploading */
65
+ uploading?: boolean;
66
+ }
67
+ /**
68
+ * DataTable Types
69
+ */
70
+ export interface DataTableColumn<T = Record<string, unknown>> {
71
+ /** Unique column identifier */
72
+ id: string;
73
+ /** Column header text */
74
+ header: string;
75
+ /** Key in the data object, or accessor function */
76
+ accessor: keyof T | ((row: T) => unknown);
77
+ /** Whether this column is sortable */
78
+ sortable?: boolean;
79
+ /** Column width (CSS value) */
80
+ width?: string;
81
+ /** Text alignment */
82
+ align?: 'left' | 'center' | 'right';
83
+ /** Custom cell render function returning string */
84
+ format?: (value: unknown, row: T) => string;
85
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Component Types for Classic Theme
3
+ *
4
+ * These types are exported from components but need to be
5
+ * re-exported from a TypeScript file for proper type inference.
6
+ */
7
+ export {};