@miozu/jera 0.3.0 → 0.4.2

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 (72) hide show
  1. package/CLAUDE.md +350 -59
  2. package/README.md +30 -22
  3. package/llms.txt +37 -4
  4. package/package.json +12 -2
  5. package/src/components/docs/CodeBlock.svelte +203 -0
  6. package/src/components/docs/DocSection.svelte +120 -0
  7. package/src/components/docs/PropsTable.svelte +136 -0
  8. package/src/components/docs/SplitPane.svelte +98 -0
  9. package/src/components/docs/index.js +14 -0
  10. package/src/components/feedback/Alert.svelte +234 -0
  11. package/src/components/feedback/EmptyState.svelte +6 -6
  12. package/src/components/feedback/ProgressBar.svelte +8 -8
  13. package/src/components/feedback/Skeleton.svelte +4 -4
  14. package/src/components/feedback/Spinner.svelte +1 -1
  15. package/src/components/feedback/Toast.svelte +137 -173
  16. package/src/components/forms/Checkbox.svelte +10 -10
  17. package/src/components/forms/Dropzone.svelte +14 -14
  18. package/src/components/forms/FileUpload.svelte +16 -16
  19. package/src/components/forms/IconInput.svelte +4 -4
  20. package/src/components/forms/Input.svelte +14 -14
  21. package/src/components/forms/NumberInput.svelte +13 -13
  22. package/src/components/forms/PinInput.svelte +8 -8
  23. package/src/components/forms/Radio.svelte +8 -8
  24. package/src/components/forms/RangeSlider.svelte +12 -12
  25. package/src/components/forms/SearchInput.svelte +10 -10
  26. package/src/components/forms/Select.svelte +156 -158
  27. package/src/components/forms/Switch.svelte +4 -4
  28. package/src/components/forms/Textarea.svelte +9 -9
  29. package/src/components/navigation/Accordion.svelte +1 -1
  30. package/src/components/navigation/AccordionItem.svelte +6 -6
  31. package/src/components/navigation/NavigationContainer.svelte +344 -0
  32. package/src/components/navigation/Sidebar.svelte +334 -0
  33. package/src/components/navigation/SidebarAccountGroup.svelte +495 -0
  34. package/src/components/navigation/SidebarAccountItem.svelte +492 -0
  35. package/src/components/navigation/SidebarGroup.svelte +230 -0
  36. package/src/components/navigation/SidebarGroupSwitcher.svelte +262 -0
  37. package/src/components/navigation/SidebarItem.svelte +210 -0
  38. package/src/components/navigation/SidebarNavigationItem.svelte +470 -0
  39. package/src/components/navigation/SidebarPopover.svelte +145 -0
  40. package/src/components/navigation/SidebarSearch.svelte +236 -0
  41. package/src/components/navigation/SidebarSection.svelte +158 -0
  42. package/src/components/navigation/SidebarToggle.svelte +86 -0
  43. package/src/components/navigation/Tabs.svelte +18 -18
  44. package/src/components/navigation/WorkspaceMenu.svelte +416 -0
  45. package/src/components/navigation/blocks/NavigationAccountGroup.svelte +396 -0
  46. package/src/components/navigation/blocks/NavigationCustomBlock.svelte +74 -0
  47. package/src/components/navigation/blocks/NavigationGroupSwitcher.svelte +277 -0
  48. package/src/components/navigation/blocks/NavigationSearch.svelte +300 -0
  49. package/src/components/navigation/blocks/NavigationSection.svelte +230 -0
  50. package/src/components/navigation/index.js +22 -0
  51. package/src/components/overlays/ConfirmDialog.svelte +18 -18
  52. package/src/components/overlays/Dropdown.svelte +2 -2
  53. package/src/components/overlays/DropdownDivider.svelte +1 -1
  54. package/src/components/overlays/DropdownItem.svelte +5 -5
  55. package/src/components/overlays/Modal.svelte +13 -13
  56. package/src/components/overlays/Popover.svelte +3 -3
  57. package/src/components/primitives/Avatar.svelte +12 -12
  58. package/src/components/primitives/Badge.svelte +7 -7
  59. package/src/components/primitives/Button.svelte +126 -174
  60. package/src/components/primitives/Card.svelte +15 -15
  61. package/src/components/primitives/Divider.svelte +3 -3
  62. package/src/components/primitives/LazyImage.svelte +1 -1
  63. package/src/components/primitives/Link.svelte +2 -2
  64. package/src/components/primitives/Stat.svelte +197 -0
  65. package/src/components/primitives/StatusBadge.svelte +24 -24
  66. package/src/index.js +62 -7
  67. package/src/tokens/colors.css +96 -128
  68. package/src/utils/highlighter.js +124 -0
  69. package/src/utils/index.js +7 -2
  70. package/src/utils/navigation.svelte.js +423 -0
  71. package/src/utils/reactive.svelte.js +126 -37
  72. package/src/utils/sidebar.svelte.js +211 -0
@@ -63,60 +63,60 @@
63
63
 
64
64
  /* Default */
65
65
  .status-badge-default {
66
- background: color-mix(in srgb, var(--color-text-muted) 10%, transparent);
67
- color: var(--color-text-muted);
68
- border-color: color-mix(in srgb, var(--color-text-muted) 30%, transparent);
66
+ background: color-mix(in srgb, var(--color-base04) 10%, transparent);
67
+ color: var(--color-base04);
68
+ border-color: color-mix(in srgb, var(--color-base04) 30%, transparent);
69
69
  }
70
70
 
71
71
  /* Status variants */
72
72
  .status-badge-pending {
73
- background: color-mix(in srgb, var(--color-warning) 10%, transparent);
74
- color: var(--color-warning);
75
- border-color: color-mix(in srgb, var(--color-warning) 30%, transparent);
73
+ background: color-mix(in srgb, var(--color-base0A) 10%, transparent);
74
+ color: var(--color-base0A);
75
+ border-color: color-mix(in srgb, var(--color-base0A) 30%, transparent);
76
76
  }
77
77
 
78
78
  .status-badge-approved,
79
79
  .status-badge-success,
80
80
  .status-badge-connected {
81
- background: color-mix(in srgb, var(--color-success) 10%, transparent);
82
- color: var(--color-success);
83
- border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
81
+ background: color-mix(in srgb, var(--color-base0B) 10%, transparent);
82
+ color: var(--color-base0B);
83
+ border-color: color-mix(in srgb, var(--color-base0B) 30%, transparent);
84
84
  }
85
85
 
86
86
  .status-badge-rejected,
87
87
  .status-badge-error,
88
88
  .status-badge-disconnected {
89
- background: color-mix(in srgb, var(--color-error) 10%, transparent);
90
- color: var(--color-error);
91
- border-color: color-mix(in srgb, var(--color-error) 30%, transparent);
89
+ background: color-mix(in srgb, var(--color-base08) 10%, transparent);
90
+ color: var(--color-base08);
91
+ border-color: color-mix(in srgb, var(--color-base08) 30%, transparent);
92
92
  }
93
93
 
94
94
  /* Role variants */
95
95
  .status-badge-owner,
96
96
  .status-badge-primary,
97
97
  .status-badge-public {
98
- background: color-mix(in srgb, var(--color-primary) 10%, transparent);
99
- color: var(--color-primary);
100
- border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
98
+ background: color-mix(in srgb, var(--color-base0D) 10%, transparent);
99
+ color: var(--color-base0D);
100
+ border-color: color-mix(in srgb, var(--color-base0D) 30%, transparent);
101
101
  }
102
102
 
103
103
  .status-badge-admin {
104
- background: color-mix(in srgb, var(--color-secondary) 10%, transparent);
105
- color: var(--color-secondary);
106
- border-color: color-mix(in srgb, var(--color-secondary) 30%, transparent);
104
+ background: color-mix(in srgb, var(--color-base0C) 10%, transparent);
105
+ color: var(--color-base0C);
106
+ border-color: color-mix(in srgb, var(--color-base0C) 30%, transparent);
107
107
  }
108
108
 
109
109
  .status-badge-member,
110
110
  .status-badge-private {
111
- background: color-mix(in srgb, var(--color-text-muted) 10%, transparent);
112
- color: var(--color-text-muted);
113
- border-color: color-mix(in srgb, var(--color-text-muted) 30%, transparent);
111
+ background: color-mix(in srgb, var(--color-base04) 10%, transparent);
112
+ color: var(--color-base04);
113
+ border-color: color-mix(in srgb, var(--color-base04) 30%, transparent);
114
114
  }
115
115
 
116
116
  /* Info variant */
117
117
  .status-badge-info {
118
- background: color-mix(in srgb, var(--color-info) 10%, transparent);
119
- color: var(--color-info);
120
- border-color: color-mix(in srgb, var(--color-info) 30%, transparent);
118
+ background: color-mix(in srgb, var(--color-base0D) 10%, transparent);
119
+ color: var(--color-base0D);
120
+ border-color: color-mix(in srgb, var(--color-base0D) 30%, transparent);
121
121
  }
122
122
  </style>
package/src/index.js CHANGED
@@ -25,12 +25,13 @@
25
25
  // COMPONENTS - Primitives
26
26
  // ============================================
27
27
 
28
- export { default as Button, buttonStyles } from './components/primitives/Button.svelte';
29
- export { default as Badge, badgeStyles } from './components/primitives/Badge.svelte';
28
+ export { default as Button } from './components/primitives/Button.svelte';
29
+ export { default as Badge } from './components/primitives/Badge.svelte';
30
30
  export { default as StatusBadge } from './components/primitives/StatusBadge.svelte';
31
31
  export { default as Divider } from './components/primitives/Divider.svelte';
32
32
  export { default as Avatar } from './components/primitives/Avatar.svelte';
33
33
  export { default as Card } from './components/primitives/Card.svelte';
34
+ export { default as Stat } from './components/primitives/Stat.svelte';
34
35
  export { default as Link } from './components/primitives/Link.svelte';
35
36
  export { default as LazyImage } from './components/primitives/LazyImage.svelte';
36
37
 
@@ -61,15 +62,14 @@ export {
61
62
  default as Toast,
62
63
  ToastController,
63
64
  createToastContext,
64
- getToastContext,
65
- toastStyles,
66
- positionStyles
65
+ getToastContext
67
66
  } from './components/feedback/Toast.svelte';
68
67
 
69
68
  export { default as Skeleton } from './components/feedback/Skeleton.svelte';
70
69
  export { default as ProgressBar } from './components/feedback/ProgressBar.svelte';
71
70
  export { default as Spinner } from './components/feedback/Spinner.svelte';
72
71
  export { default as EmptyState } from './components/feedback/EmptyState.svelte';
72
+ export { default as Alert } from './components/feedback/Alert.svelte';
73
73
 
74
74
  // ============================================
75
75
  // COMPONENTS - Overlays
@@ -90,6 +90,41 @@ export { default as Tabs } from './components/navigation/Tabs.svelte';
90
90
  export { default as Accordion } from './components/navigation/Accordion.svelte';
91
91
  export { default as AccordionItem } from './components/navigation/AccordionItem.svelte';
92
92
 
93
+ // Sidebar Components (Legacy - Enhanced)
94
+ export { default as Sidebar } from './components/navigation/Sidebar.svelte';
95
+ export { default as SidebarSection } from './components/navigation/SidebarSection.svelte';
96
+ export { default as SidebarItem } from './components/navigation/SidebarItem.svelte';
97
+ export { default as SidebarGroup } from './components/navigation/SidebarGroup.svelte';
98
+ export { default as SidebarPopover } from './components/navigation/SidebarPopover.svelte';
99
+ export { default as SidebarAccountItem } from './components/navigation/SidebarAccountItem.svelte';
100
+ export { default as SidebarToggle } from './components/navigation/SidebarToggle.svelte';
101
+ export { default as SidebarSearch } from './components/navigation/SidebarSearch.svelte';
102
+ export { default as SidebarGroupSwitcher } from './components/navigation/SidebarGroupSwitcher.svelte';
103
+ export { default as SidebarAccountGroup } from './components/navigation/SidebarAccountGroup.svelte';
104
+
105
+ // Enterprise Navigation System
106
+ export { default as NavigationContainer } from './components/navigation/NavigationContainer.svelte';
107
+ export { default as SidebarNavigationItem } from './components/navigation/SidebarNavigationItem.svelte';
108
+
109
+ // Navigation Blocks
110
+ export { default as NavigationSearch } from './components/navigation/blocks/NavigationSearch.svelte';
111
+ export { default as NavigationSection } from './components/navigation/blocks/NavigationSection.svelte';
112
+ export { default as NavigationAccountGroup } from './components/navigation/blocks/NavigationAccountGroup.svelte';
113
+ export { default as NavigationGroupSwitcher } from './components/navigation/blocks/NavigationGroupSwitcher.svelte';
114
+ export { default as NavigationCustomBlock } from './components/navigation/blocks/NavigationCustomBlock.svelte';
115
+
116
+ // Enterprise Components
117
+ export { default as WorkspaceMenu } from './components/navigation/WorkspaceMenu.svelte';
118
+
119
+ // ============================================
120
+ // COMPONENTS - Documentation
121
+ // ============================================
122
+
123
+ export { default as CodeBlock } from './components/docs/CodeBlock.svelte';
124
+ export { default as PropsTable } from './components/docs/PropsTable.svelte';
125
+ export { default as SplitPane } from './components/docs/SplitPane.svelte';
126
+ export { default as DocSection } from './components/docs/DocSection.svelte';
127
+
93
128
  // ============================================
94
129
  // UTILITIES - Class Composition
95
130
  // ============================================
@@ -104,13 +139,33 @@ export {
104
139
  createReactive,
105
140
  createDerived,
106
141
  ThemeState,
107
- createThemeContext,
108
- getThemeContext,
142
+ getTheme,
143
+ resetTheme,
109
144
  createComponentState,
110
145
  createIdGenerator,
111
146
  generateId
112
147
  } from './utils/reactive.svelte.js';
113
148
 
149
+ // Sidebar State Management
150
+ export {
151
+ createSidebarState,
152
+ SIDEBAR_CONTEXT_KEY
153
+ } from './utils/sidebar.svelte.js';
154
+
155
+ // Enterprise Navigation State Management
156
+ export {
157
+ NavigationState,
158
+ createNavigationState,
159
+ NAVIGATION_CONTEXT_KEY
160
+ } from './utils/navigation.svelte.js';
161
+
162
+ // Code Highlighting
163
+ export {
164
+ getHighlighter,
165
+ highlightCode,
166
+ DEFAULT_LANGUAGES
167
+ } from './utils/highlighter.js';
168
+
114
169
  // ============================================
115
170
  // ACTIONS
116
171
  // ============================================
@@ -17,107 +17,61 @@
17
17
 
18
18
  :root {
19
19
  /* ========================================
20
- * BASE COLORS (Grayscale Spectrum)
21
- * From darkest (base0) to lightest (base7)
20
+ * BASE16 COLORS
21
+ * Proper Base16 hex naming: base00-base0F
22
22
  * ======================================== */
23
23
 
24
- --base0: #232733; /* Darkest background */
25
- --base1: #2C3040; /* Default dark background */
26
- --base2: #3E4359; /* Selection, highlights */
27
- --base3: #565E78; /* Comments, subtle text */
28
- --base4: #737E99; /* Muted foreground */
29
- --base5: #D0D2DB; /* Default foreground */
30
- --base6: #F3F4F7; /* Light foreground */
31
- --base7: #FAFBFD; /* Lightest/white */
24
+ /* Grayscale (base00-base07) */
25
+ --base00: #232733; /* Darkest background */
26
+ --base01: #2C3040; /* Default dark background */
27
+ --base02: #3E4359; /* Selection, highlights */
28
+ --base03: #565E78; /* Comments, subtle text */
29
+ --base04: #737E99; /* Muted foreground */
30
+ --base05: #D0D2DB; /* Default foreground */
31
+ --base06: #F3F4F7; /* Light foreground */
32
+ --base07: #FAFBFD; /* Lightest/white */
33
+
34
+ /* Accents (base08-base0F) */
35
+ --base08: #EB3137; /* Red - errors, destructive */
36
+ --base09: #FF9837; /* Orange - numbers, attention */
37
+ --base0A: #E8D176; /* Yellow - warnings, highlights */
38
+ --base0B: #6DD672; /* Green - success, positive */
39
+ --base0C: #40FFE2; /* Cyan - methods, cool accent */
40
+ --base0D: #83D2FC; /* Blue - info, links */
41
+ --base0E: #C974E6; /* Magenta - primary brand */
42
+ --base0F: #FF9982; /* Peach - keywords, warm accent */
32
43
 
33
44
  /* ========================================
34
- * ACCENT COLORS (Base16 Extended Palette)
35
- * Official miozu palette from @miozu/js-theme
45
+ * COLOR ALIASES
46
+ * Prefixed version for CSS custom property usage
36
47
  * ======================================== */
37
48
 
38
- --base8: #EB3137; /* Red - errors, destructive */
39
- --base9: #FF9837; /* Orange - numbers, attention */
40
- --base10: #6DD672; /* Green - success, positive */
41
- --base11: #E8D176; /* Yellow - warnings, highlights */
42
- --base12: #83D2FC; /* Blue - info, links */
43
- --base13: #C974E6; /* Magenta - primary brand, functions */
44
- --base14: #FF9982; /* Peach - keywords, warm accent */
45
- --base15: #40FFE2; /* Cyan - methods, cool accent */
46
-
47
- /* Named color aliases */
48
- --red: var(--base8);
49
- --orange: var(--base9);
50
- --green: var(--base10);
51
- --yellow: var(--base11);
52
- --blue: var(--base12);
53
- --magenta: var(--base13);
54
- --peach: var(--base14);
55
- --cyan: var(--base15);
56
-
57
- /* ========================================
58
- * SEMANTIC MAPPINGS (Dark Theme Default)
59
- * Use these in components for consistency
60
- * ======================================== */
61
-
62
- /* Backgrounds */
63
- --color-bg: var(--base0);
64
- --color-surface: var(--base1);
65
- --color-surface-alt: var(--base2);
66
- --color-hover: var(--base2);
67
- --color-surface-hover: var(--base2);
68
-
69
- /* Foregrounds */
70
- --color-text: var(--base5);
71
- --color-text-strong: var(--base7);
72
- --color-text-muted: var(--base4);
73
- --color-text-subtle: var(--base3);
74
-
75
- /* Borders */
76
- --color-border: var(--base3);
77
- --color-border-muted: var(--base2);
78
-
79
- /* Brand */
80
- --color-primary: var(--magenta); /* base13 - #C974E6 */
81
- --color-secondary: var(--blue); /* base12 - #83D2FC */
82
- --color-accent: var(--cyan); /* base15 - #40FFE2 */
83
-
84
- /* States */
85
- --color-success: var(--green); /* base10 - #6DD672 */
86
- --color-warning: var(--yellow); /* base11 - #E8D176 */
87
- --color-error: var(--red); /* base8 - #EB3137 */
88
- --color-info: var(--blue); /* base12 - #83D2FC */
89
-
90
- /* ========================================
91
- * BASE COLOR ALIASES
92
- * For direct base color access in components
93
- * ======================================== */
94
-
95
- /* Grayscale (base0-7) */
96
- --color-base0: var(--base0);
97
- --color-base1: var(--base1);
98
- --color-base2: var(--base2);
99
- --color-base3: var(--base3);
100
- --color-base4: var(--base4);
101
- --color-base5: var(--base5);
102
- --color-base6: var(--base6);
103
- --color-base7: var(--base7);
104
-
105
- /* Accents (base8-15) */
106
- --color-base8: var(--base8);
107
- --color-base9: var(--base9);
108
- --color-base10: var(--base10);
109
- --color-base11: var(--base11);
110
- --color-base12: var(--base12);
111
- --color-base13: var(--base13);
112
- --color-base14: var(--base14);
113
- --color-base15: var(--base15);
49
+ --color-base00: var(--base00);
50
+ --color-base01: var(--base01);
51
+ --color-base02: var(--base02);
52
+ --color-base03: var(--base03);
53
+ --color-base04: var(--base04);
54
+ --color-base05: var(--base05);
55
+ --color-base06: var(--base06);
56
+ --color-base07: var(--base07);
57
+ --color-base08: var(--base08);
58
+ --color-base09: var(--base09);
59
+ --color-base0A: var(--base0A);
60
+ --color-base0B: var(--base0B);
61
+ --color-base0C: var(--base0C);
62
+ --color-base0D: var(--base0D);
63
+ --color-base0E: var(--base0E);
64
+ --color-base0F: var(--base0F);
65
+
66
+ /* Border utility */
67
+ --color-border: var(--base03);
114
68
  }
115
69
 
116
70
  /* ========================================
117
71
  * LIGHT THEME
118
- * Inverted grayscale, same accents
72
+ * Inverted grayscale for light backgrounds
119
73
  *
120
- * Supports multiple selectors for flexibility:
74
+ * Supports multiple selectors:
121
75
  * - data-theme="light" (generic)
122
76
  * - data-theme="miozu-light" (Selify/Miozu apps)
123
77
  * - .light (class-based)
@@ -126,27 +80,32 @@
126
80
  [data-theme="light"],
127
81
  [data-theme="miozu-light"],
128
82
  .light {
129
- /* Inverted base colors */
130
- --color-bg: var(--base7);
131
- --color-surface: var(--base6);
132
- --color-surface-alt: var(--base5);
133
- --color-hover: var(--base5);
134
- --color-surface-hover: var(--base5);
135
-
136
- /* Inverted foregrounds */
137
- --color-text: var(--base2);
138
- --color-text-strong: var(--base0);
139
- --color-text-muted: var(--base3);
140
- --color-text-subtle: var(--base4);
141
-
142
- /* Inverted borders */
143
- --color-border: var(--base4);
144
- --color-border-muted: var(--base5);
83
+ /* Inverted grayscale */
84
+ --base00: #FAFBFD;
85
+ --base01: #F3F4F7;
86
+ --base02: #D0D2DB;
87
+ --base03: #737E99;
88
+ --base04: #565E78;
89
+ --base05: #3E4359;
90
+ --base06: #2C3040;
91
+ --base07: #232733;
92
+
93
+ /* Update aliases */
94
+ --color-base00: var(--base00);
95
+ --color-base01: var(--base01);
96
+ --color-base02: var(--base02);
97
+ --color-base03: var(--base03);
98
+ --color-base04: var(--base04);
99
+ --color-base05: var(--base05);
100
+ --color-base06: var(--base06);
101
+ --color-base07: var(--base07);
102
+
103
+ --color-border: var(--base03);
145
104
  }
146
105
 
147
106
  /* ========================================
148
107
  * DARK THEME (Explicit)
149
- * Same as :root default, for explicit dark mode
108
+ * Same as :root default
150
109
  *
151
110
  * Supports multiple selectors:
152
111
  * - data-theme="dark" (generic)
@@ -157,19 +116,25 @@
157
116
  [data-theme="dark"],
158
117
  [data-theme="miozu-dark"],
159
118
  .dark {
160
- --color-bg: var(--base0);
161
- --color-surface: var(--base1);
162
- --color-surface-alt: var(--base2);
163
- --color-hover: var(--base2);
164
- --color-surface-hover: var(--base2);
165
-
166
- --color-text: var(--base5);
167
- --color-text-strong: var(--base7);
168
- --color-text-muted: var(--base4);
169
- --color-text-subtle: var(--base3);
170
-
171
- --color-border: var(--base3);
172
- --color-border-muted: var(--base2);
119
+ --base00: #232733;
120
+ --base01: #2C3040;
121
+ --base02: #3E4359;
122
+ --base03: #565E78;
123
+ --base04: #737E99;
124
+ --base05: #D0D2DB;
125
+ --base06: #F3F4F7;
126
+ --base07: #FAFBFD;
127
+
128
+ --color-base00: var(--base00);
129
+ --color-base01: var(--base01);
130
+ --color-base02: var(--base02);
131
+ --color-base03: var(--base03);
132
+ --color-base04: var(--base04);
133
+ --color-base05: var(--base05);
134
+ --color-base06: var(--base06);
135
+ --color-base07: var(--base07);
136
+
137
+ --color-border: var(--base03);
173
138
  }
174
139
 
175
140
  /* ========================================
@@ -178,12 +143,15 @@
178
143
  * ======================================== */
179
144
 
180
145
  [data-theme="high-contrast"] {
181
- --color-bg: #000000;
182
- --color-surface: #0a0a0a;
183
- --color-surface-alt: #1a1a1a;
184
- --color-text: var(--base7);
185
- --color-text-strong: #FFFFFF;
186
- --color-text-muted: var(--base5);
187
- --color-border: var(--base5);
188
- --color-border-muted: var(--base4);
146
+ --base00: #000000;
147
+ --base01: #0a0a0a;
148
+ --base02: #1a1a1a;
149
+ --base07: #FFFFFF;
150
+
151
+ --color-base00: var(--base00);
152
+ --color-base01: var(--base01);
153
+ --color-base02: var(--base02);
154
+ --color-base07: var(--base07);
155
+
156
+ --color-border: var(--base05);
189
157
  }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Syntax highlighting utility using Shiki v3 with CSS variables theme.
3
+ * Provides cached highlighter instance for performance.
4
+ * Handles the case when shiki is not installed as an optional dependency.
5
+ *
6
+ * @module @miozu/jera/utils/highlighter
7
+ */
8
+
9
+ // Cache the highlighter to avoid recreating it for each request
10
+ let highlighterPromise = null;
11
+ let shikiAvailable = null;
12
+
13
+ /**
14
+ * Default languages supported by the highlighter
15
+ */
16
+ export const DEFAULT_LANGUAGES = [
17
+ 'javascript',
18
+ 'typescript',
19
+ 'svelte',
20
+ 'jsx',
21
+ 'tsx',
22
+ 'html',
23
+ 'css',
24
+ 'json',
25
+ 'bash',
26
+ 'shell',
27
+ 'markdown',
28
+ 'python',
29
+ 'sql',
30
+ 'yaml',
31
+ 'toml'
32
+ ];
33
+
34
+ /**
35
+ * Check if shiki is available
36
+ * @returns {Promise<boolean>}
37
+ */
38
+ async function isShikiAvailable() {
39
+ if (shikiAvailable !== null) return shikiAvailable;
40
+
41
+ try {
42
+ await import('shiki');
43
+ shikiAvailable = true;
44
+ } catch {
45
+ shikiAvailable = false;
46
+ }
47
+ return shikiAvailable;
48
+ }
49
+
50
+ /**
51
+ * Get or create the Shiki highlighter with CSS variables theme.
52
+ * The highlighter is cached and reused for performance.
53
+ *
54
+ * @returns {Promise<import('shiki').Highlighter|null>}
55
+ */
56
+ export async function getHighlighter() {
57
+ if (!await isShikiAvailable()) {
58
+ return null;
59
+ }
60
+
61
+ if (!highlighterPromise) {
62
+ highlighterPromise = (async () => {
63
+ const shiki = await import('shiki');
64
+
65
+ // Create a CSS variables theme that uses CSS custom properties
66
+ const cssVarsTheme = shiki.createCssVariablesTheme({
67
+ name: 'css-variables',
68
+ variablePrefix: '--shiki-',
69
+ variableDefaults: {},
70
+ fontStyle: true
71
+ });
72
+
73
+ return shiki.createHighlighter({
74
+ themes: [cssVarsTheme],
75
+ langs: DEFAULT_LANGUAGES
76
+ });
77
+ })();
78
+ }
79
+
80
+ return highlighterPromise;
81
+ }
82
+
83
+ /**
84
+ * Highlight code using Shiki with CSS variables theme.
85
+ *
86
+ * @param {string} code - The code to highlight
87
+ * @param {string} [lang='text'] - The language for syntax highlighting
88
+ * @returns {Promise<string>} HTML string with highlighted code
89
+ */
90
+ export async function highlightCode(code, lang = 'text') {
91
+ try {
92
+ const highlighter = await getHighlighter();
93
+
94
+ if (!highlighter) {
95
+ // Shiki not available, return basic escaped code
96
+ return `<pre class="shiki"><code>${escapeHtml(code)}</code></pre>`;
97
+ }
98
+
99
+ const html = highlighter.codeToHtml(code.trim(), {
100
+ lang: lang || 'text',
101
+ theme: 'css-variables'
102
+ });
103
+
104
+ return html;
105
+ } catch (err) {
106
+ console.error('Highlighting error:', err);
107
+ // Fallback to basic escaping
108
+ return `<pre class="shiki"><code>${escapeHtml(code)}</code></pre>`;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Escape HTML special characters
114
+ * @param {string} str
115
+ * @returns {string}
116
+ */
117
+ function escapeHtml(str) {
118
+ return str
119
+ .replace(/&/g, '&amp;')
120
+ .replace(/</g, '&lt;')
121
+ .replace(/>/g, '&gt;')
122
+ .replace(/"/g, '&quot;')
123
+ .replace(/'/g, '&#039;');
124
+ }
@@ -9,9 +9,14 @@ export {
9
9
  createReactive,
10
10
  createDerived,
11
11
  ThemeState,
12
- createThemeContext,
13
- getThemeContext,
12
+ getTheme,
13
+ resetTheme,
14
14
  createComponentState,
15
15
  createIdGenerator,
16
16
  generateId
17
17
  } from './reactive.svelte.js';
18
+
19
+ export {
20
+ createSidebarState,
21
+ SIDEBAR_CONTEXT_KEY
22
+ } from './sidebar.svelte.js';