rizzo-css 0.0.12 → 0.0.13

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 (230) hide show
  1. package/.env.example +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +17 -3
  4. package/bin/rizzo-css.js +93 -43
  5. package/package.json +5 -3
  6. package/scaffold/astro-app/README.md +13 -2
  7. package/scaffold/astro-app/src/components/Accordion.astro +178 -0
  8. package/scaffold/astro-app/src/components/Alert.astro +131 -0
  9. package/scaffold/astro-app/src/components/Avatar.astro +59 -0
  10. package/scaffold/astro-app/src/components/Badge.astro +24 -0
  11. package/scaffold/astro-app/src/components/Breadcrumb.astro +61 -0
  12. package/scaffold/astro-app/src/components/Button.astro +3 -0
  13. package/scaffold/astro-app/src/components/Card.astro +18 -0
  14. package/scaffold/astro-app/src/components/Checkbox.astro +38 -0
  15. package/scaffold/astro-app/src/components/CodeBlock.astro +393 -0
  16. package/scaffold/astro-app/src/components/CopyToClipboard.astro +219 -0
  17. package/scaffold/astro-app/src/components/Divider.astro +37 -0
  18. package/scaffold/astro-app/src/components/Dropdown.astro +807 -0
  19. package/scaffold/astro-app/src/components/FormGroup.astro +59 -0
  20. package/scaffold/astro-app/src/components/FrameworkSwitcher.astro +72 -0
  21. package/scaffold/astro-app/src/components/Input.astro +59 -0
  22. package/scaffold/astro-app/src/components/Modal.astro +212 -0
  23. package/scaffold/astro-app/src/components/Navbar.astro +701 -0
  24. package/scaffold/astro-app/src/components/Pagination.astro +240 -0
  25. package/scaffold/astro-app/src/components/ProgressBar.astro +65 -0
  26. package/scaffold/astro-app/src/components/Radio.astro +38 -0
  27. package/scaffold/astro-app/src/components/Search.astro +1259 -0
  28. package/scaffold/astro-app/src/components/Select.astro +49 -0
  29. package/scaffold/astro-app/src/components/Settings.astro +382 -0
  30. package/scaffold/astro-app/src/components/Spinner.astro +30 -0
  31. package/scaffold/astro-app/src/components/Table.astro +181 -0
  32. package/scaffold/astro-app/src/components/Tabs.astro +223 -0
  33. package/scaffold/astro-app/src/components/Textarea.astro +58 -0
  34. package/scaffold/astro-app/src/components/ThemeSwitcher.astro +504 -0
  35. package/scaffold/astro-app/src/components/Toast.astro +30 -0
  36. package/scaffold/astro-app/src/components/Tooltip.astro +32 -0
  37. package/scaffold/astro-app/src/components/icons/Brush.astro +10 -0
  38. package/scaffold/astro-app/src/components/icons/Cake.astro +11 -0
  39. package/scaffold/astro-app/src/components/icons/Check.astro +29 -0
  40. package/scaffold/astro-app/src/components/icons/Cherry.astro +11 -0
  41. package/scaffold/astro-app/src/components/icons/ChevronDown.astro +29 -0
  42. package/scaffold/astro-app/src/components/icons/Circle.astro +29 -0
  43. package/scaffold/astro-app/src/components/icons/Close.astro +30 -0
  44. package/scaffold/astro-app/src/components/icons/Cmd.astro +26 -0
  45. package/scaffold/astro-app/src/components/icons/Copy.astro +30 -0
  46. package/scaffold/astro-app/src/components/icons/Eye.astro +30 -0
  47. package/scaffold/astro-app/src/components/icons/Filter.astro +29 -0
  48. package/scaffold/astro-app/src/components/icons/Flame.astro +28 -0
  49. package/scaffold/astro-app/src/components/icons/Flower.astro +11 -0
  50. package/scaffold/astro-app/src/components/icons/Gear.astro +30 -0
  51. package/scaffold/astro-app/src/components/icons/Heart.astro +28 -0
  52. package/scaffold/astro-app/src/components/icons/IceCream.astro +31 -0
  53. package/scaffold/astro-app/src/components/icons/Leaf.astro +29 -0
  54. package/scaffold/astro-app/src/components/icons/Lemon.astro +11 -0
  55. package/scaffold/astro-app/src/components/icons/Moon.astro +29 -0
  56. package/scaffold/astro-app/src/components/icons/Owl.astro +34 -0
  57. package/scaffold/astro-app/src/components/icons/Palette.astro +33 -0
  58. package/scaffold/astro-app/src/components/icons/Rainbow.astro +31 -0
  59. package/scaffold/astro-app/src/components/icons/Search.astro +30 -0
  60. package/scaffold/astro-app/src/components/icons/Shield.astro +28 -0
  61. package/scaffold/astro-app/src/components/icons/Snowflake.astro +34 -0
  62. package/scaffold/astro-app/src/components/icons/Sort.astro +30 -0
  63. package/scaffold/astro-app/src/components/icons/Sun.astro +29 -0
  64. package/scaffold/astro-app/src/components/icons/Sunset.astro +10 -0
  65. package/scaffold/astro-app/src/components/icons/Zap.astro +9 -0
  66. package/scaffold/astro-app/src/components/icons/devicons/Astro.astro +53 -0
  67. package/scaffold/astro-app/src/components/icons/devicons/Bash.astro +34 -0
  68. package/scaffold/astro-app/src/components/icons/devicons/Css3.astro +29 -0
  69. package/scaffold/astro-app/src/components/icons/devicons/Git.astro +24 -0
  70. package/scaffold/astro-app/src/components/icons/devicons/Html5.astro +27 -0
  71. package/scaffold/astro-app/src/components/icons/devicons/Javascript.astro +25 -0
  72. package/scaffold/astro-app/src/components/icons/devicons/Nodejs.astro +47 -0
  73. package/scaffold/astro-app/src/components/icons/devicons/Plaintext.astro +33 -0
  74. package/scaffold/astro-app/src/components/icons/devicons/React.astro +27 -0
  75. package/scaffold/astro-app/src/components/icons/devicons/Svelte.astro +25 -0
  76. package/scaffold/astro-app/src/components/icons/devicons/Vue.astro +26 -0
  77. package/scaffold/astro-app/src/config/frameworks.ts +26 -0
  78. package/scaffold/astro-app/src/config/themes.ts +54 -0
  79. package/scaffold/astro-app/src/layouts/DocsLayout.astro +204 -0
  80. package/scaffold/astro-app/src/layouts/Layout.astro +11 -2
  81. package/scaffold/astro-app/src/pages/components/accordion.astro +172 -0
  82. package/scaffold/astro-app/src/pages/components/alert.astro +250 -0
  83. package/scaffold/astro-app/src/pages/components/avatar.astro +102 -0
  84. package/scaffold/astro-app/src/pages/components/badge.astro +119 -0
  85. package/scaffold/astro-app/src/pages/components/breadcrumb.astro +124 -0
  86. package/scaffold/astro-app/src/pages/components/button.astro +74 -0
  87. package/scaffold/astro-app/src/pages/components/cards.astro +247 -0
  88. package/scaffold/astro-app/src/pages/components/copy-to-clipboard.astro +49 -0
  89. package/scaffold/astro-app/src/pages/components/divider.astro +74 -0
  90. package/scaffold/astro-app/src/pages/components/dropdown.astro +394 -0
  91. package/scaffold/astro-app/src/pages/components/forms.astro +367 -0
  92. package/scaffold/astro-app/src/pages/components/icons.astro +246 -0
  93. package/scaffold/astro-app/src/pages/components/modal.astro +152 -0
  94. package/scaffold/astro-app/src/pages/components/navbar.astro +80 -0
  95. package/scaffold/astro-app/src/pages/components/pagination.astro +126 -0
  96. package/scaffold/astro-app/src/pages/components/progress-bar.astro +94 -0
  97. package/scaffold/astro-app/src/pages/components/search.astro +155 -0
  98. package/scaffold/astro-app/src/pages/components/settings.astro +78 -0
  99. package/scaffold/astro-app/src/pages/components/spinner.astro +81 -0
  100. package/scaffold/astro-app/src/pages/components/table.astro +144 -0
  101. package/scaffold/astro-app/src/pages/components/tabs.astro +220 -0
  102. package/scaffold/astro-app/src/pages/components/theme-switcher.astro +67 -0
  103. package/scaffold/astro-app/src/pages/components/toast.astro +157 -0
  104. package/scaffold/astro-app/src/pages/components/tooltip.astro +209 -0
  105. package/scaffold/astro-app/src/pages/components.astro +290 -0
  106. package/scaffold/astro-app/src/pages/docs/accessibility.astro +9 -0
  107. package/scaffold/astro-app/src/pages/docs/colors.astro +9 -0
  108. package/scaffold/astro-app/src/pages/docs/design-system.astro +9 -0
  109. package/scaffold/astro-app/src/pages/docs/getting-started.astro +9 -0
  110. package/scaffold/astro-app/src/pages/docs/index.astro +15 -0
  111. package/scaffold/astro-app/src/pages/docs/themes/[theme].astro +14 -0
  112. package/scaffold/astro-app/src/pages/docs/theming.astro +10 -0
  113. package/scaffold/astro-app/src/pages/index.astro +5 -11
  114. package/scaffold/svelte-app/README.md +9 -2
  115. package/scaffold/svelte-app/src/app.html +1 -1
  116. package/scaffold/svelte-app/src/lib/rizzo/Accordion.svelte +128 -0
  117. package/scaffold/svelte-app/src/lib/rizzo/Alert.svelte +85 -0
  118. package/scaffold/svelte-app/src/lib/rizzo/Avatar.svelte +39 -0
  119. package/scaffold/svelte-app/src/lib/rizzo/Badge.svelte +31 -0
  120. package/scaffold/svelte-app/src/lib/rizzo/Breadcrumb.svelte +49 -0
  121. package/scaffold/svelte-app/src/lib/rizzo/Button.svelte +27 -0
  122. package/scaffold/svelte-app/src/lib/rizzo/Card.svelte +17 -0
  123. package/scaffold/svelte-app/src/lib/rizzo/Checkbox.svelte +37 -0
  124. package/scaffold/svelte-app/src/lib/rizzo/CopyToClipboard.svelte +79 -0
  125. package/scaffold/svelte-app/src/lib/rizzo/Divider.svelte +28 -0
  126. package/scaffold/svelte-app/src/lib/rizzo/Dropdown.svelte +254 -0
  127. package/scaffold/svelte-app/src/lib/rizzo/FormGroup.svelte +51 -0
  128. package/scaffold/svelte-app/src/lib/rizzo/Input.svelte +59 -0
  129. package/scaffold/svelte-app/src/lib/rizzo/Modal.svelte +157 -0
  130. package/scaffold/svelte-app/src/lib/rizzo/Pagination.svelte +93 -0
  131. package/scaffold/svelte-app/src/lib/rizzo/ProgressBar.svelte +58 -0
  132. package/scaffold/svelte-app/src/lib/rizzo/Radio.svelte +38 -0
  133. package/scaffold/svelte-app/src/lib/rizzo/Select.svelte +51 -0
  134. package/scaffold/svelte-app/src/lib/rizzo/Spinner.svelte +14 -0
  135. package/scaffold/svelte-app/src/lib/rizzo/Table.svelte +158 -0
  136. package/scaffold/svelte-app/src/lib/rizzo/Tabs.svelte +117 -0
  137. package/scaffold/svelte-app/src/lib/rizzo/Textarea.svelte +59 -0
  138. package/scaffold/svelte-app/src/lib/rizzo/ThemeSwitcher.svelte +315 -0
  139. package/scaffold/svelte-app/src/lib/rizzo/Toast.svelte +33 -0
  140. package/scaffold/svelte-app/src/lib/rizzo/Tooltip.svelte +19 -0
  141. package/scaffold/svelte-app/src/lib/rizzo/icons/Check.svelte +29 -0
  142. package/scaffold/svelte-app/src/lib/rizzo/icons/ChevronDown.svelte +29 -0
  143. package/scaffold/svelte-app/src/lib/rizzo/icons/Circle.svelte +29 -0
  144. package/scaffold/svelte-app/src/lib/rizzo/icons/Close.svelte +30 -0
  145. package/scaffold/svelte-app/src/lib/rizzo/icons/Cmd.svelte +27 -0
  146. package/scaffold/svelte-app/src/lib/rizzo/icons/Copy.svelte +30 -0
  147. package/scaffold/svelte-app/src/lib/rizzo/icons/Eye.svelte +30 -0
  148. package/scaffold/svelte-app/src/lib/rizzo/icons/Filter.svelte +29 -0
  149. package/scaffold/svelte-app/src/lib/rizzo/icons/Gear.svelte +30 -0
  150. package/scaffold/svelte-app/src/lib/rizzo/icons/IceCream.svelte +31 -0
  151. package/scaffold/svelte-app/src/lib/rizzo/icons/Moon.svelte +29 -0
  152. package/scaffold/svelte-app/src/lib/rizzo/icons/Owl.svelte +34 -0
  153. package/scaffold/svelte-app/src/lib/rizzo/icons/Palette.svelte +33 -0
  154. package/scaffold/svelte-app/src/lib/rizzo/icons/Rainbow.svelte +31 -0
  155. package/scaffold/svelte-app/src/lib/rizzo/icons/Search.svelte +30 -0
  156. package/scaffold/svelte-app/src/lib/rizzo/icons/Snowflake.svelte +34 -0
  157. package/scaffold/svelte-app/src/lib/rizzo/icons/Sort.svelte +30 -0
  158. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Astro.svelte +45 -0
  159. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Bash.svelte +28 -0
  160. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Css3.svelte +23 -0
  161. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Git.svelte +18 -0
  162. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Html5.svelte +21 -0
  163. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Javascript.svelte +19 -0
  164. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Nodejs.svelte +44 -0
  165. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Plaintext.svelte +24 -0
  166. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/React.svelte +21 -0
  167. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/SvelteIcon.svelte +19 -0
  168. package/scaffold/svelte-app/src/lib/rizzo/icons/devicons/Vue.svelte +20 -0
  169. package/scaffold/svelte-app/src/lib/rizzo/index.ts +33 -0
  170. package/scaffold/svelte-app/src/lib/rizzo-docs/CodeBlock.svelte +239 -0
  171. package/scaffold/svelte-app/src/lib/rizzo-docs/SvelteDocPage.svelte +99 -0
  172. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AccordionDoc.svelte +53 -0
  173. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AlertDoc.svelte +114 -0
  174. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/AvatarDoc.svelte +92 -0
  175. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BadgeDoc.svelte +60 -0
  176. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/BreadcrumbDoc.svelte +55 -0
  177. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ButtonDoc.svelte +55 -0
  178. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CardsDoc.svelte +173 -0
  179. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComingSoon.svelte +12 -0
  180. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ComponentsOverview.svelte +92 -0
  181. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/CopyToClipboardDoc.svelte +26 -0
  182. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DividerDoc.svelte +105 -0
  183. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/DropdownDoc.svelte +161 -0
  184. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/FormsDoc.svelte +375 -0
  185. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/IconsDoc.svelte +246 -0
  186. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Index.svelte +8 -0
  187. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ModalDoc.svelte +50 -0
  188. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/NavbarDoc.svelte +79 -0
  189. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/PaginationDoc.svelte +44 -0
  190. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ProgressBarDoc.svelte +95 -0
  191. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SearchDoc.svelte +147 -0
  192. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SettingsDoc.svelte +158 -0
  193. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/SpinnerDoc.svelte +41 -0
  194. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TableDoc.svelte +116 -0
  195. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TabsDoc.svelte +152 -0
  196. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ThemeSwitcherDoc.svelte +181 -0
  197. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/Theming.svelte +6 -0
  198. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/ToastDoc.svelte +136 -0
  199. package/scaffold/svelte-app/src/lib/rizzo-docs/pages/TooltipDoc.svelte +57 -0
  200. package/scaffold/svelte-app/src/routes/+page.svelte +2 -2
  201. package/scaffold/svelte-app/src/routes/components/+page.svelte +4 -0
  202. package/scaffold/svelte-app/src/routes/components/[slug]/+page.svelte +7 -0
  203. package/scaffold/vanilla/README.md +11 -4
  204. package/scaffold/vanilla/components/accordion.html +187 -0
  205. package/scaffold/vanilla/components/alert.html +187 -0
  206. package/scaffold/vanilla/components/avatar.html +187 -0
  207. package/scaffold/vanilla/components/badge.html +187 -0
  208. package/scaffold/vanilla/components/breadcrumb.html +187 -0
  209. package/scaffold/vanilla/components/button.html +187 -0
  210. package/scaffold/vanilla/components/cards.html +187 -0
  211. package/scaffold/vanilla/components/copy-to-clipboard.html +187 -0
  212. package/scaffold/vanilla/components/divider.html +187 -0
  213. package/scaffold/vanilla/components/dropdown.html +187 -0
  214. package/scaffold/vanilla/components/forms.html +187 -0
  215. package/scaffold/vanilla/components/icons.html +187 -0
  216. package/scaffold/vanilla/components/index.html +212 -0
  217. package/scaffold/vanilla/components/modal.html +187 -0
  218. package/scaffold/vanilla/components/navbar.html +187 -0
  219. package/scaffold/vanilla/components/pagination.html +187 -0
  220. package/scaffold/vanilla/components/progress-bar.html +187 -0
  221. package/scaffold/vanilla/components/search.html +187 -0
  222. package/scaffold/vanilla/components/settings.html +187 -0
  223. package/scaffold/vanilla/components/spinner.html +187 -0
  224. package/scaffold/vanilla/components/table.html +187 -0
  225. package/scaffold/vanilla/components/tabs.html +187 -0
  226. package/scaffold/vanilla/components/theme-switcher.html +187 -0
  227. package/scaffold/vanilla/components/toast.html +187 -0
  228. package/scaffold/vanilla/components/tooltip.html +187 -0
  229. package/scaffold/vanilla/index.html +16 -6
  230. package/scaffold/vanilla/js/main.js +4 -3
@@ -0,0 +1,223 @@
1
+ ---
2
+ interface Tab {
3
+ id: string;
4
+ label: string;
5
+ content?: string;
6
+ }
7
+
8
+ interface Props {
9
+ tabs: Tab[];
10
+ id?: string;
11
+ defaultTab?: string;
12
+ variant?: 'default' | 'pills' | 'underline';
13
+ class?: string;
14
+ }
15
+
16
+ const {
17
+ tabs,
18
+ id,
19
+ defaultTab,
20
+ variant = 'default',
21
+ class: className = '',
22
+ } = Astro.props;
23
+
24
+ const tabsId = id || `tabs-${Math.random().toString(36).substr(2, 9)}`;
25
+ const activeTabId = defaultTab || tabs[0]?.id || '';
26
+ const variantClass = variant !== 'default' ? `tabs--${variant}` : '';
27
+ const classes = `tabs ${variantClass} ${className}`.trim();
28
+ ---
29
+
30
+ <div class={classes} data-tabs={tabsId}>
31
+ <div
32
+ class="tabs__list"
33
+ role="tablist"
34
+ aria-label="Tabs"
35
+ >
36
+ {tabs.map((tab, index) => {
37
+ const tabId = `${tabsId}-tab-${tab.id}`;
38
+ const panelId = `${tabsId}-panel-${tab.id}`;
39
+ const isActive = tab.id === activeTabId;
40
+
41
+ return (
42
+ <span
43
+ class={`tabs__tab ${isActive ? 'tabs__tab--active' : ''}`}
44
+ id={tabId}
45
+ role="tab"
46
+ tabindex={isActive ? 0 : -1}
47
+ aria-selected={isActive ? 'true' : 'false'}
48
+ aria-controls={panelId}
49
+ data-tab-id={tab.id}
50
+ data-tab-index={index}
51
+ >
52
+ {tab.label}
53
+ </span>
54
+ );
55
+ })}
56
+ </div>
57
+
58
+ <div class="tabs__panels-wrapper">
59
+ {tabs.map((tab, index) => {
60
+ const tabId = `${tabsId}-tab-${tab.id}`;
61
+ const panelId = `${tabsId}-panel-${tab.id}`;
62
+ const isActive = tab.id === activeTabId;
63
+
64
+ return (
65
+ <div
66
+ class={`tabs__panel ${isActive ? 'tabs__panel--active' : ''}`}
67
+ id={panelId}
68
+ role="tabpanel"
69
+ aria-labelledby={tabId}
70
+ aria-hidden={isActive ? 'false' : 'true'}
71
+ data-panel-id={tab.id}
72
+ data-panel-index={index}
73
+ >
74
+ {tab.content ? (
75
+ <div set:html={tab.content} class="tabs__panel-content" />
76
+ ) : null}
77
+ </div>
78
+ );
79
+ })}
80
+ </div>
81
+
82
+ <!-- Default slot for panel content (matched by order) -->
83
+ <div class="tabs__slot-content" style="display: none;">
84
+ <slot />
85
+ </div>
86
+ </div>
87
+
88
+ <script define:vars={{ tabsId, activeTabId }}>
89
+ (function initTabs() {
90
+ const init = () => {
91
+ const tabsContainer = document.querySelector(`[data-tabs="${tabsId}"]`);
92
+ if (!tabsContainer) {
93
+ if (document.readyState === 'loading') {
94
+ document.addEventListener('DOMContentLoaded', init);
95
+ return;
96
+ }
97
+ return;
98
+ }
99
+
100
+ const tabButtons = tabsContainer.querySelectorAll('[role="tab"]');
101
+ const tabPanels = tabsContainer.querySelectorAll('[role="tabpanel"]');
102
+
103
+ if (tabButtons.length === 0 || tabPanels.length === 0) {
104
+ return;
105
+ }
106
+
107
+ // Set initial active state
108
+ let activeIndex = Array.from(tabButtons).findIndex(
109
+ (btn) => btn.getAttribute('data-tab-id') === activeTabId
110
+ );
111
+ if (activeIndex === -1) activeIndex = 0;
112
+
113
+ const activateTab = (index) => {
114
+ // Validate index
115
+ if (index < 0 || index >= tabButtons.length) return;
116
+
117
+ const targetButton = tabButtons[index];
118
+ const targetTabId = targetButton.getAttribute('data-tab-id');
119
+ if (!targetTabId) return;
120
+
121
+ // Update all buttons
122
+ tabButtons.forEach((btn, idx) => {
123
+ const isActive = idx === index;
124
+ btn.setAttribute('aria-selected', isActive ? 'true' : 'false');
125
+ btn.setAttribute('tabindex', isActive ? '0' : '-1');
126
+ btn.classList.toggle('tabs__tab--active', isActive);
127
+ });
128
+
129
+ // Update all panels
130
+ tabPanels.forEach((panel) => {
131
+ const panelId = panel.getAttribute('data-panel-id');
132
+ const isActive = panelId === targetTabId;
133
+ panel.setAttribute('aria-hidden', isActive ? 'false' : 'true');
134
+ panel.classList.toggle('tabs__panel--active', isActive);
135
+ });
136
+ };
137
+
138
+ // Click handler
139
+ tabButtons.forEach((button, index) => {
140
+ button.addEventListener('click', () => {
141
+ activateTab(index);
142
+ });
143
+ });
144
+
145
+ // Keyboard navigation
146
+ tabButtons.forEach((button, index) => {
147
+ button.addEventListener('keydown', (e) => {
148
+ let targetIndex = index;
149
+
150
+ switch (e.key) {
151
+ case 'ArrowRight':
152
+ case 'ArrowDown':
153
+ e.preventDefault();
154
+ targetIndex = (index + 1) % tabButtons.length;
155
+ break;
156
+ case 'ArrowLeft':
157
+ case 'ArrowUp':
158
+ e.preventDefault();
159
+ targetIndex = index === 0 ? tabButtons.length - 1 : index - 1;
160
+ break;
161
+ case 'Home':
162
+ e.preventDefault();
163
+ targetIndex = 0;
164
+ break;
165
+ case 'End':
166
+ e.preventDefault();
167
+ targetIndex = tabButtons.length - 1;
168
+ break;
169
+ case 'Enter':
170
+ case ' ':
171
+ e.preventDefault();
172
+ activateTab(index);
173
+ return;
174
+ default:
175
+ return;
176
+ }
177
+
178
+ activateTab(targetIndex);
179
+ tabButtons[targetIndex].focus();
180
+ });
181
+ });
182
+
183
+ // Distribute slot content to panels (only if content property not used)
184
+ // Use requestAnimationFrame to ensure DOM is ready
185
+ requestAnimationFrame(() => {
186
+ const slotContent = tabsContainer.querySelector('.tabs__slot-content');
187
+ if (slotContent) {
188
+ const slotChildren = Array.from(slotContent.children);
189
+
190
+ // Only distribute if we have slot children
191
+ if (slotChildren.length > 0) {
192
+ slotChildren.forEach((child, index) => {
193
+ if (index < tabPanels.length) {
194
+ const panel = tabPanels[index];
195
+ // Check if panel already has content from content property
196
+ // Content property adds a div with class tabs__panel-content
197
+ const hasContentProperty = panel.querySelector('.tabs__panel-content') !== null;
198
+
199
+ // Only distribute slot content if panel doesn't have content property
200
+ if (!hasContentProperty) {
201
+ // Simply move the child element itself into the panel
202
+ // This preserves all content and structure
203
+ panel.appendChild(child);
204
+ }
205
+ }
206
+ });
207
+ }
208
+ // Remove the wrapper after distribution
209
+ slotContent.remove();
210
+ }
211
+ });
212
+
213
+ // Initialize with default active tab
214
+ activateTab(activeIndex);
215
+ };
216
+
217
+ if (document.readyState === 'loading') {
218
+ document.addEventListener('DOMContentLoaded', init);
219
+ } else {
220
+ init();
221
+ }
222
+ })();
223
+ </script>
@@ -0,0 +1,58 @@
1
+ ---
2
+ interface Props {
3
+ id?: string;
4
+ name?: string;
5
+ value?: string;
6
+ placeholder?: string;
7
+ required?: boolean;
8
+ disabled?: boolean;
9
+ readonly?: boolean;
10
+ rows?: number;
11
+ cols?: number;
12
+ size?: 'sm' | 'md' | 'lg';
13
+ error?: boolean;
14
+ success?: boolean;
15
+ class?: string;
16
+ ariaDescribedby?: string;
17
+ ariaInvalid?: boolean | 'true' | 'false';
18
+ }
19
+
20
+ const {
21
+ id,
22
+ name,
23
+ value,
24
+ placeholder,
25
+ required = false,
26
+ disabled = false,
27
+ readonly = false,
28
+ rows = 4,
29
+ cols,
30
+ size = 'md',
31
+ error = false,
32
+ success = false,
33
+ class: className = '',
34
+ ariaDescribedby,
35
+ ariaInvalid,
36
+ } = Astro.props;
37
+
38
+ const sizeClass = size !== 'md' ? `form-input--${size}` : '';
39
+ const errorClass = error ? 'form-input--error' : '';
40
+ const successClass = success ? 'form-input--success' : '';
41
+ const classes = `form-input ${sizeClass} ${errorClass} ${successClass} ${className}`.trim();
42
+
43
+ const invalid = error || ariaInvalid === true || ariaInvalid === 'true';
44
+ ---
45
+
46
+ <textarea
47
+ id={id}
48
+ name={name}
49
+ placeholder={placeholder}
50
+ required={required}
51
+ disabled={disabled}
52
+ readonly={readonly}
53
+ rows={rows}
54
+ cols={cols}
55
+ class={classes}
56
+ aria-invalid={invalid ? 'true' : 'false'}
57
+ aria-describedby={ariaDescribedby}
58
+ >{value}</textarea>