@electroplix/components 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +512 -3
  2. package/cli.cjs +440 -0
  3. package/dist/README.md +14 -93
  4. package/dist/index.esm.js +17777 -163
  5. package/dist/src/__tests__/test-utils.d.ts +8 -0
  6. package/dist/src/__tests__/test-utils.d.ts.map +1 -0
  7. package/dist/src/components/blog/index.d.ts +88 -0
  8. package/dist/src/components/blog/index.d.ts.map +1 -0
  9. package/dist/src/components/buttons/index.d.ts +71 -0
  10. package/dist/src/components/buttons/index.d.ts.map +1 -0
  11. package/dist/src/components/content/BlockquoteTestimonial.d.ts +24 -0
  12. package/dist/src/components/content/BlockquoteTestimonial.d.ts.map +1 -0
  13. package/dist/src/components/content/CalloutBox.d.ts +26 -0
  14. package/dist/src/components/content/CalloutBox.d.ts.map +1 -0
  15. package/dist/src/components/content/HeadingSection.d.ts +26 -0
  16. package/dist/src/components/content/HeadingSection.d.ts.map +1 -0
  17. package/dist/src/components/content/InlineCodeText.d.ts +24 -0
  18. package/dist/src/components/content/InlineCodeText.d.ts.map +1 -0
  19. package/dist/src/components/content/ParagraphBlock.d.ts +23 -0
  20. package/dist/src/components/content/ParagraphBlock.d.ts.map +1 -0
  21. package/dist/src/components/content/RichMarkdown.d.ts +20 -0
  22. package/dist/src/components/content/RichMarkdown.d.ts.map +1 -0
  23. package/dist/src/components/content/index.d.ts +7 -0
  24. package/dist/src/components/content/index.d.ts.map +1 -0
  25. package/dist/src/components/data-display/Badge.d.ts +9 -0
  26. package/dist/src/components/data-display/Badge.d.ts.map +1 -0
  27. package/dist/src/components/data-display/BadgeGroup.d.ts +8 -0
  28. package/dist/src/components/data-display/BadgeGroup.d.ts.map +1 -0
  29. package/dist/src/components/data-display/BarChart.d.ts +12 -0
  30. package/dist/src/components/data-display/BarChart.d.ts.map +1 -0
  31. package/dist/src/components/data-display/CalendarGrid.d.ts +15 -0
  32. package/dist/src/components/data-display/CalendarGrid.d.ts.map +1 -0
  33. package/dist/src/components/data-display/DataTable.d.ts +24 -0
  34. package/dist/src/components/data-display/DataTable.d.ts.map +1 -0
  35. package/dist/src/components/data-display/LineChart.d.ts +11 -0
  36. package/dist/src/components/data-display/LineChart.d.ts.map +1 -0
  37. package/dist/src/components/data-display/PieChart.d.ts +9 -0
  38. package/dist/src/components/data-display/PieChart.d.ts.map +1 -0
  39. package/dist/src/components/data-display/ProgressBar.d.ts +11 -0
  40. package/dist/src/components/data-display/ProgressBar.d.ts.map +1 -0
  41. package/dist/src/components/data-display/RatingStars.d.ts +10 -0
  42. package/dist/src/components/data-display/RatingStars.d.ts.map +1 -0
  43. package/dist/src/components/data-display/Sparkline.d.ts +7 -0
  44. package/dist/src/components/data-display/Sparkline.d.ts.map +1 -0
  45. package/dist/src/components/data-display/Timeline.d.ts +12 -0
  46. package/dist/src/components/data-display/Timeline.d.ts.map +1 -0
  47. package/dist/src/components/data-display/index.d.ts +12 -0
  48. package/dist/src/components/data-display/index.d.ts.map +1 -0
  49. package/dist/src/components/ecommerce/index.d.ts +110 -0
  50. package/dist/src/components/ecommerce/index.d.ts.map +1 -0
  51. package/dist/src/components/forms/AddressAutocomplete.d.ts +27 -0
  52. package/dist/src/components/forms/AddressAutocomplete.d.ts.map +1 -0
  53. package/dist/src/components/forms/Captcha.d.ts +23 -0
  54. package/dist/src/components/forms/Captcha.d.ts.map +1 -0
  55. package/dist/src/components/forms/ContactForm.d.ts +28 -0
  56. package/dist/src/components/forms/ContactForm.d.ts.map +1 -0
  57. package/dist/src/components/forms/DateTimePicker.d.ts +27 -0
  58. package/dist/src/components/forms/DateTimePicker.d.ts.map +1 -0
  59. package/dist/src/components/forms/FileUploader.d.ts +24 -0
  60. package/dist/src/components/forms/FileUploader.d.ts.map +1 -0
  61. package/dist/src/components/forms/FormShell.d.ts +17 -0
  62. package/dist/src/components/forms/FormShell.d.ts.map +1 -0
  63. package/dist/src/components/forms/InputField.d.ts +32 -0
  64. package/dist/src/components/forms/InputField.d.ts.map +1 -0
  65. package/dist/src/components/forms/MultiStepWizard.d.ts +29 -0
  66. package/dist/src/components/forms/MultiStepWizard.d.ts.map +1 -0
  67. package/dist/src/components/forms/NewsletterSignup.d.ts +26 -0
  68. package/dist/src/components/forms/NewsletterSignup.d.ts.map +1 -0
  69. package/dist/src/components/forms/RadioGroup.d.ts +31 -0
  70. package/dist/src/components/forms/RadioGroup.d.ts.map +1 -0
  71. package/dist/src/components/forms/SelectDropdown.d.ts +33 -0
  72. package/dist/src/components/forms/SelectDropdown.d.ts.map +1 -0
  73. package/dist/src/components/forms/TextAreaField.d.ts +30 -0
  74. package/dist/src/components/forms/TextAreaField.d.ts.map +1 -0
  75. package/dist/src/components/forms/ToggleSwitch.d.ts +25 -0
  76. package/dist/src/components/forms/ToggleSwitch.d.ts.map +1 -0
  77. package/dist/src/components/forms/ValidationWrapper.d.ts +24 -0
  78. package/dist/src/components/forms/ValidationWrapper.d.ts.map +1 -0
  79. package/dist/src/components/forms/index.d.ts +29 -0
  80. package/dist/src/components/forms/index.d.ts.map +1 -0
  81. package/dist/src/components/hero/CTAOverlayHero.d.ts +29 -0
  82. package/dist/src/components/hero/CTAOverlayHero.d.ts.map +1 -0
  83. package/dist/src/components/hero/CarouselHero.d.ts +29 -0
  84. package/dist/src/components/hero/CarouselHero.d.ts.map +1 -0
  85. package/dist/src/components/hero/HeroShell.d.ts +18 -0
  86. package/dist/src/components/hero/HeroShell.d.ts.map +1 -0
  87. package/dist/src/components/hero/PatternedHero.d.ts +34 -0
  88. package/dist/src/components/hero/PatternedHero.d.ts.map +1 -0
  89. package/dist/src/components/hero/SplitHero.d.ts +31 -0
  90. package/dist/src/components/hero/SplitHero.d.ts.map +1 -0
  91. package/dist/src/components/hero/StaticHero.d.ts +26 -0
  92. package/dist/src/components/hero/StaticHero.d.ts.map +1 -0
  93. package/dist/src/components/hero/VideoHeaderHero.d.ts +29 -0
  94. package/dist/src/components/hero/VideoHeaderHero.d.ts.map +1 -0
  95. package/dist/src/components/hero/index.d.ts +15 -0
  96. package/dist/src/components/hero/index.d.ts.map +1 -0
  97. package/dist/src/components/lists-cards/index.d.ts +104 -0
  98. package/dist/src/components/lists-cards/index.d.ts.map +1 -0
  99. package/dist/src/components/marketing/index.d.ts +95 -0
  100. package/dist/src/components/marketing/index.d.ts.map +1 -0
  101. package/dist/src/components/media/index.d.ts +95 -0
  102. package/dist/src/components/media/index.d.ts.map +1 -0
  103. package/dist/src/components/miscellaneous/index.d.ts +63 -0
  104. package/dist/src/components/miscellaneous/index.d.ts.map +1 -0
  105. package/dist/src/components/modals/index.d.ts +83 -0
  106. package/dist/src/components/modals/index.d.ts.map +1 -0
  107. package/dist/src/components/navigation/AnchorLinks.d.ts +25 -0
  108. package/dist/src/components/navigation/AnchorLinks.d.ts.map +1 -0
  109. package/dist/src/components/navigation/Breadcrumbs.d.ts +25 -0
  110. package/dist/src/components/navigation/Breadcrumbs.d.ts.map +1 -0
  111. package/dist/src/components/navigation/LanguageSelector.d.ts +24 -0
  112. package/dist/src/components/navigation/LanguageSelector.d.ts.map +1 -0
  113. package/dist/src/components/navigation/MegaMenu.d.ts +28 -0
  114. package/dist/src/components/navigation/MegaMenu.d.ts.map +1 -0
  115. package/dist/src/components/navigation/Pagination.d.ts +18 -0
  116. package/dist/src/components/navigation/Pagination.d.ts.map +1 -0
  117. package/dist/src/components/navigation/PrimaryNav.d.ts +22 -0
  118. package/dist/src/components/navigation/PrimaryNav.d.ts.map +1 -0
  119. package/dist/src/components/navigation/SideDrawerNav.d.ts +22 -0
  120. package/dist/src/components/navigation/SideDrawerNav.d.ts.map +1 -0
  121. package/dist/src/components/navigation/SidebarMenu.d.ts +25 -0
  122. package/dist/src/components/navigation/SidebarMenu.d.ts.map +1 -0
  123. package/dist/src/components/navigation/Stepper.d.ts +17 -0
  124. package/dist/src/components/navigation/Stepper.d.ts.map +1 -0
  125. package/dist/src/components/navigation/Tabs.d.ts +22 -0
  126. package/dist/src/components/navigation/Tabs.d.ts.map +1 -0
  127. package/dist/src/components/navigation/index.d.ts +21 -0
  128. package/dist/src/components/navigation/index.d.ts.map +1 -0
  129. package/dist/src/components/onboarding/index.d.ts +66 -0
  130. package/dist/src/components/onboarding/index.d.ts.map +1 -0
  131. package/dist/src/components/search/index.d.ts +58 -0
  132. package/dist/src/components/search/index.d.ts.map +1 -0
  133. package/dist/src/components/site-identity/index.d.ts +48 -0
  134. package/dist/src/components/site-identity/index.d.ts.map +1 -0
  135. package/dist/src/components/social/index.d.ts +68 -0
  136. package/dist/src/components/social/index.d.ts.map +1 -0
  137. package/dist/src/components/user-accounts/index.d.ts +68 -0
  138. package/dist/src/components/user-accounts/index.d.ts.map +1 -0
  139. package/dist/src/core/config.d.ts +37 -0
  140. package/dist/src/core/config.d.ts.map +1 -0
  141. package/dist/src/core/icons.d.ts +25 -0
  142. package/dist/src/core/icons.d.ts.map +1 -0
  143. package/dist/src/core/index.d.ts +8 -0
  144. package/dist/src/core/index.d.ts.map +1 -0
  145. package/dist/src/core/provider.d.ts +45 -0
  146. package/dist/src/core/provider.d.ts.map +1 -0
  147. package/dist/src/core/types.d.ts +145 -0
  148. package/dist/src/core/types.d.ts.map +1 -0
  149. package/dist/src/core/utils.d.ts +70 -0
  150. package/dist/src/core/utils.d.ts.map +1 -0
  151. package/dist/src/index.d.ts +19 -5
  152. package/dist/src/index.d.ts.map +1 -1
  153. package/package.json +44 -5
  154. package/dist/src/lib/Navbar.d.ts +0 -5
  155. package/dist/src/lib/Navbar.d.ts.map +0 -1
  156. package/dist/src/lib/config.d.ts +0 -36
  157. package/dist/src/lib/config.d.ts.map +0 -1
  158. package/dist/src/lib/icons.d.ts +0 -10
  159. package/dist/src/lib/icons.d.ts.map +0 -1
  160. package/dist/src/lib/provider.d.ts +0 -38
  161. package/dist/src/lib/provider.d.ts.map +0 -1
  162. package/dist/src/lib/types.d.ts +0 -66
  163. package/dist/src/lib/types.d.ts.map +0 -1
package/cli.cjs ADDED
@@ -0,0 +1,440 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @electroplix/components CLI
5
+ *
6
+ * Usage:
7
+ * npx @electroplix/components init – scaffold config + providers
8
+ * npx @electroplix/components add <name|category> – show install/import instructions
9
+ * npx @electroplix/components list – list all available components
10
+ */
11
+
12
+ const fs = require("fs");
13
+ const path = require("path");
14
+
15
+ /* ══════════════════════════════════════════════════════════════════ */
16
+ /* ANSI Styling */
17
+ /* ══════════════════════════════════════════════════════════════════ */
18
+
19
+ const ESC = "\x1b[";
20
+ const R = `${ESC}0m`;
21
+
22
+ const s = {
23
+ bold: (t) => `${ESC}1m${t}${R}`,
24
+ dim: (t) => `${ESC}2m${t}${R}`,
25
+ italic: (t) => `${ESC}3m${t}${R}`,
26
+ purple: (t) => `${ESC}38;2;139;92;246m${t}${R}`,
27
+ violet: (t) => `${ESC}38;2;167;139;250m${t}${R}`,
28
+ cyan: (t) => `${ESC}38;2;34;211;238m${t}${R}`,
29
+ green: (t) => `${ESC}38;2;52;211;153m${t}${R}`,
30
+ yellow: (t) => `${ESC}38;2;251;191;36m${t}${R}`,
31
+ red: (t) => `${ESC}38;2;251;113;133m${t}${R}`,
32
+ white: (t) => `${ESC}38;2;243;244;246m${t}${R}`,
33
+ gray: (t) => `${ESC}38;2;107;114;128m${t}${R}`,
34
+ };
35
+
36
+ /* ══════════════════════════════════════════════════════════════════ */
37
+ /* Box-drawing helpers */
38
+ /* ══════════════════════════════════════════════════════════════════ */
39
+
40
+ const B = {
41
+ tl: "\u256D", tr: "\u256E", bl: "\u2570", br: "\u256F",
42
+ h: "\u2500", v: "\u2502",
43
+ tee: "\u251C", end: "\u2570",
44
+ branch: "\u251C\u2500\u2500", last: "\u2570\u2500\u2500",
45
+ pipe: "\u2502 ",
46
+ dot: "\u25CF", arrow: "\u2192", check: "\u2713", star: "\u2605",
47
+ diamond: "\u25C6", spark: "\u26A1",
48
+ };
49
+
50
+ function hr(w) { return B.h.repeat(w); }
51
+
52
+ function stripAnsi(t) { return t.replace(/\x1b\[[0-9;]*m/g, ""); }
53
+
54
+ function boxLine(l, content, r, w) {
55
+ const vis = stripAnsi(content);
56
+ const pad = Math.max(0, w - vis.length - 2);
57
+ return ` ${l}${content}${" ".repeat(pad)}${r}`;
58
+ }
59
+
60
+ /* ══════════════════════════════════════════════════════════════════ */
61
+ /* Brand banner */
62
+ /* ══════════════════════════════════════════════════════════════════ */
63
+
64
+ function printBanner() {
65
+ const W = 58;
66
+ const lines = [
67
+ "",
68
+ ` ${B.tl}${hr(W)}${B.tr}`,
69
+ boxLine(B.v, ` ${s.bold(s.purple(`${B.spark} ELECTROPLIX`))} ${s.dim(s.violet("COMPONENTS"))}`, B.v, W),
70
+ boxLine(B.v, ` ${s.gray("Parametric \u2022 Config-Driven \u2022 Zero-Dependency")}`, B.v, W),
71
+ ` ${B.bl}${hr(W)}${B.br}`,
72
+ "",
73
+ ];
74
+ console.log(lines.join("\n"));
75
+ }
76
+
77
+ /* ══════════════════════════════════════════════════════════════════ */
78
+ /* Component registry */
79
+ /* ══════════════════════════════════════════════════════════════════ */
80
+
81
+ const CATEGORIES = {
82
+ navigation: [
83
+ "AnchorLinks", "Breadcrumbs", "LanguageSelector", "MegaMenu",
84
+ "Pagination", "PrimaryNav", "SidebarMenu", "SideDrawerNav", "Stepper", "Tabs",
85
+ ],
86
+ hero: [
87
+ "HeroShell", "StaticHero", "CarouselHero", "CTAOverlayHero",
88
+ "PatternedHero", "SplitHero", "VideoHeaderHero",
89
+ ],
90
+ buttons: [
91
+ "PrimaryButton", "SecondaryButton", "TertiaryButton", "IconButton",
92
+ "FloatingActionButton", "ButtonGroup", "LoadingButton", "ShareButton",
93
+ "DownloadButton", "PrintButton",
94
+ ],
95
+ forms: [
96
+ "FormShell", "InputField", "TextAreaField", "SelectDropdown", "RadioGroup",
97
+ "ToggleSwitch", "DateTimePicker", "FileUploader", "ContactForm",
98
+ "NewsletterSignup", "MultiStepWizard", "Captcha", "AddressAutocomplete",
99
+ "ValidationWrapper",
100
+ ],
101
+ content: [
102
+ "BlockquoteTestimonial", "CalloutBox", "HeadingSection",
103
+ "InlineCodeText", "ParagraphBlock", "RichMarkdown",
104
+ ],
105
+ "data-display": [
106
+ "Badge", "BadgeGroup", "BarChart", "LineChart", "PieChart", "Sparkline",
107
+ "ProgressBar", "RatingStars", "CalendarGrid", "DataTable", "Timeline",
108
+ ],
109
+ ecommerce: [
110
+ "CartDrawer", "MiniCartPanel", "OrderSummary", "ProductCard",
111
+ "ProductGrid", "ProductDetail", "VariantSelector", "QuickAddButton",
112
+ "WishlistButton", "PaymentButtons",
113
+ ],
114
+ "lists-cards": [
115
+ "BlockShell", "Accordion", "GenericList", "FeatureGrid",
116
+ "ItemCardGrid", "PricingTable", "SortableTable", "LCTimeline",
117
+ ],
118
+ marketing: [
119
+ "ComparisonTable", "CountdownTimer", "FeatureHighlights", "LeadMagnetGate",
120
+ "MarketingHeroBlock", "PromoPopup", "TestimonialsCarousel", "TrustBadges",
121
+ ],
122
+ media: [
123
+ "MediaShell", "ResponsiveVideo", "AudioEmbed", "AvatarProfile", "IconGrid",
124
+ "ImageGallery", "LightboxGallery", "MasonryGrid", "PolaroidImage",
125
+ "LottieOrSVG", "ImageCropperUploader",
126
+ ],
127
+ miscellaneous: [
128
+ "CookieConsent", "ScrollProgressBar", "ThemeToggle", "EmptyState",
129
+ "AppInstallBanner", "DownloadBlock", "InlineCode", "RSSFeed",
130
+ ],
131
+ modals: [
132
+ "OverlayBase", "GenericModal", "ConfirmDialog", "FormDialog",
133
+ "LoadingOverlay", "Tooltip", "ToastBanners", "CookieNotice", "WelcomePopup",
134
+ ],
135
+ onboarding: [
136
+ "FAQAccordion", "OnboardingWizard", "ProductTour", "TooltipHelp",
137
+ "SupportChat", "ContactSupportBlock",
138
+ ],
139
+ search: [
140
+ "SiteSearchBar", "AutoSuggest", "FacetFilters", "SearchResultCard",
141
+ "SearchResults", "SearchEmptyState",
142
+ ],
143
+ "site-identity": [
144
+ "LogoDisplay", "AnimatedBrandMark", "Taglines", "BrandingShell",
145
+ "BrandIconGrid", "FaviconUploader",
146
+ ],
147
+ social: [
148
+ "SocialShareBar", "SocialLoginButtons", "SocialEmbed", "FollowLike",
149
+ "ReactionsBar", "CommentsBox", "ReviewsForm",
150
+ ],
151
+ "user-accounts": [
152
+ "AuthForm", "PasswordReset", "MultiFactorAuthInput", "ProfileOverview",
153
+ "ProfileSettings", "AccountSettings", "RoleBadge",
154
+ ],
155
+ blog: [
156
+ "BlogCard", "AuthorByline", "TagList", "BlogBadge", "ReadingBar",
157
+ "ArticleRenderer", "RelatedPosts", "ArchiveList", "CommentsSection",
158
+ ],
159
+ };
160
+
161
+ /* build lookup maps */
162
+ const ALL_COMPONENTS = new Map();
163
+ for (const [cat, names] of Object.entries(CATEGORIES)) {
164
+ for (const n of names) ALL_COMPONENTS.set(n.toLowerCase(), { name: n, category: cat });
165
+ }
166
+
167
+ const CATEGORY_ALIASES = new Map();
168
+ for (const cat of Object.keys(CATEGORIES)) {
169
+ CATEGORY_ALIASES.set(cat.toLowerCase(), cat);
170
+ CATEGORY_ALIASES.set(cat.replace(/-/g, "").toLowerCase(), cat);
171
+ CATEGORY_ALIASES.set(cat.replace(/-/g, " ").toLowerCase(), cat);
172
+ }
173
+
174
+ const totalCount = Object.values(CATEGORIES).reduce((sum, a) => sum + a.length, 0);
175
+
176
+ /* ══════════════════════════════════════════════════════════════════ */
177
+ /* INIT command */
178
+ /* ══════════════════════════════════════════════════════════════════ */
179
+
180
+ function init() {
181
+ printBanner();
182
+
183
+ const configName = "electroplix.config.ts";
184
+ const providerRel = path.join("components", "providers.tsx");
185
+ const configPath = path.join(process.cwd(), configName);
186
+ const providerDir = path.join(process.cwd(), "components");
187
+ const providerPath = path.join(providerDir, "providers.tsx");
188
+
189
+ const created = [];
190
+ const skipped = [];
191
+
192
+ /* ── config file ─────────────────────────────────────── */
193
+ if (fs.existsSync(configPath)) {
194
+ skipped.push(configName);
195
+ } else {
196
+ const configTemplate = `import { defineConfig } from "@electroplix/components/config";
197
+
198
+ const config = defineConfig({
199
+ // \u2500\u2500 Global overrides (applied to ALL categories) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
200
+ accentColor: "#7C3AED",
201
+ textColor: "#E5E7EB",
202
+ bgColor: "#0b0b0c",
203
+ borderColor: "rgba(255,255,255,0.14)",
204
+ radius: 14,
205
+ fontFamily: "Inter, system-ui, sans-serif",
206
+
207
+ // \u2500\u2500 Per-category overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
208
+ // navigation: { sticky: true, height: 64 },
209
+ // hero: { minH: 600 },
210
+ // buttons: { bgColor: "#e94560", radius: 12 },
211
+ // forms: { inputBg: "rgba(255,255,255,0.05)" },
212
+ // ecommerce: { accentColor: "#10B981" },
213
+ });
214
+
215
+ export default config;
216
+ `;
217
+ fs.writeFileSync(configPath, configTemplate, "utf-8");
218
+ created.push(configName);
219
+ }
220
+
221
+ /* ── providers wrapper ───────────────────────────────── */
222
+ if (fs.existsSync(providerPath)) {
223
+ skipped.push(providerRel);
224
+ } else {
225
+ if (!fs.existsSync(providerDir)) {
226
+ fs.mkdirSync(providerDir, { recursive: true });
227
+ }
228
+ const providerTemplate = `"use client";
229
+
230
+ import { ElectroplixProvider } from "@electroplix/components";
231
+ import config from "../electroplix.config";
232
+
233
+ /**
234
+ * Client-side providers wrapper.
235
+ * Import this into your root layout (which stays as a Server Component).
236
+ */
237
+ export function Providers({ children }: { children: React.ReactNode }) {
238
+ return (
239
+ <ElectroplixProvider config={config}>
240
+ {children}
241
+ </ElectroplixProvider>
242
+ );
243
+ }
244
+ `;
245
+ fs.writeFileSync(providerPath, providerTemplate, "utf-8");
246
+ created.push(providerRel);
247
+ }
248
+
249
+ /* ── output ──────────────────────────────────────────── */
250
+ if (created.length) {
251
+ console.log(` ${s.green(B.check)} ${s.bold("Created:")}`);
252
+ for (const f of created) {
253
+ console.log(` ${s.green(B.arrow)} ${s.cyan(f)}`);
254
+ }
255
+ console.log();
256
+ }
257
+ if (skipped.length) {
258
+ console.log(` ${s.yellow("!")} ${s.bold("Already exists")} ${s.dim("(skipped):")}`);
259
+ for (const f of skipped) {
260
+ console.log(` ${s.gray(B.arrow)} ${s.gray(f)}`);
261
+ }
262
+ console.log();
263
+ }
264
+
265
+ console.log(` ${s.bold("Next steps:")}`);
266
+ console.log();
267
+ console.log(` ${s.white("1.")} Update your ${s.cyan("app/layout.tsx")}:`);
268
+ console.log();
269
+ console.log(` ${s.gray("import { Providers } from \"../components/providers\";")}`);
270
+ console.log();
271
+ console.log(` ${s.gray("export default function RootLayout({ children }) {")}`);
272
+ console.log(` ${s.gray(" return (")}`);
273
+ console.log(` ${s.gray(" <html><body>")}`);
274
+ console.log(` ${s.gray(" ")}${s.cyan("<Providers>")}${s.gray("{children}")}${s.cyan("</Providers>")}`);
275
+ console.log(` ${s.gray(" </body></html>")}`);
276
+ console.log(` ${s.gray(" );")}`);
277
+ console.log(` ${s.gray("}")}`);
278
+ console.log();
279
+ console.log(` ${s.white("2.")} Import components in ${s.cyan("\"use client\"")} pages:`);
280
+ console.log();
281
+ console.log(` ${s.gray("import { PrimaryNav, StaticHero } from \"@electroplix/components\";")}`);
282
+ console.log();
283
+ }
284
+
285
+ /* ══════════════════════════════════════════════════════════════════ */
286
+ /* ADD command */
287
+ /* ══════════════════════════════════════════════════════════════════ */
288
+
289
+ function add(name) {
290
+ printBanner();
291
+
292
+ if (!name) {
293
+ console.log(` ${s.red("\u2717")} ${s.bold("Missing argument")}\n`);
294
+ console.log(` ${s.white("Usage:")}`);
295
+ console.log(` ${s.cyan("npx @electroplix/components add")} ${s.violet("<ComponentName>")}`);
296
+ console.log(` ${s.cyan("npx @electroplix/components add")} ${s.violet("<category>")}`);
297
+ console.log();
298
+ console.log(` ${s.dim("Examples:")}`);
299
+ console.log(` ${s.gray("npx @electroplix/components add PrimaryNav")}`);
300
+ console.log(` ${s.gray("npx @electroplix/components add navigation")}`);
301
+ console.log();
302
+ process.exit(1);
303
+ }
304
+
305
+ const key = name.toLowerCase().replace(/\s+/g, "-");
306
+
307
+ /* ── try category match first ──────────────────────── */
308
+ const catMatch = CATEGORY_ALIASES.get(key);
309
+ if (catMatch) {
310
+ const comps = CATEGORIES[catMatch];
311
+ console.log(` ${s.purple(B.star)} ${s.bold(catMatch)} ${s.dim(`\u2014 ${comps.length} components`)}`);
312
+ console.log();
313
+ console.log(` ${s.white("Import all:")}`);
314
+ console.log();
315
+ console.log(` ${s.cyan("import {")}`);
316
+ for (let i = 0; i < comps.length; i++) {
317
+ const comma = i < comps.length - 1 ? "," : "";
318
+ console.log(` ${s.cyan(" " + comps[i] + comma)}`);
319
+ }
320
+ console.log(` ${s.cyan("} from \"@electroplix/components\";")}`);
321
+ console.log();
322
+
323
+ /* tree display */
324
+ console.log(` ${s.bold("Components:")}`);
325
+ console.log();
326
+ for (let i = 0; i < comps.length; i++) {
327
+ const isLast = i === comps.length - 1;
328
+ const prefix = isLast ? B.last : B.branch;
329
+ console.log(` ${s.gray(prefix)} ${s.violet(comps[i])}`);
330
+ }
331
+ console.log();
332
+ return;
333
+ }
334
+
335
+ /* ── try individual component match ────────────────── */
336
+ const entry = ALL_COMPONENTS.get(key);
337
+ if (!entry) {
338
+ console.log(` ${s.red("\u2717")} Component or category ${s.bold("\"" + name + "\"")} not found.\n`);
339
+ console.log(` ${s.dim("Run")} ${s.cyan("npx @electroplix/components list")} ${s.dim("to see all options.")}\n`);
340
+ process.exit(1);
341
+ }
342
+
343
+ const W = 52;
344
+ console.log(` ${B.tl}${hr(W)}${B.tr}`);
345
+ console.log(boxLine(B.v, ` ${s.bold(s.purple(entry.name))} ${s.dim("from " + s.violet(entry.category))}`, B.v, W));
346
+ console.log(` ${B.bl}${hr(W)}${B.br}`);
347
+ console.log();
348
+ console.log(` ${s.green("1.")} ${s.white("Install")} ${s.dim("(if not already):")}`);
349
+ console.log(` ${s.cyan("npm install @electroplix/components")}`);
350
+ console.log();
351
+ console.log(` ${s.green("2.")} ${s.white("Import:")}`);
352
+ console.log(` ${s.cyan("import { " + entry.name + " } from \"@electroplix/components\";")}`);
353
+ console.log();
354
+ console.log(` ${s.green("3.")} ${s.white("Use in JSX:")}`);
355
+ console.log(` ${s.cyan("<" + entry.name + " />")}`);
356
+ console.log();
357
+ console.log(` ${s.dim("All components are config-driven. Wrap your app with")}`);
358
+ console.log(` ${s.dim("<Providers> (from")} ${s.cyan("npx @electroplix/components init")}${s.dim(") to theme globally.")}`);
359
+ console.log();
360
+ }
361
+
362
+ /* ══════════════════════════════════════════════════════════════════ */
363
+ /* LIST command */
364
+ /* ══════════════════════════════════════════════════════════════════ */
365
+
366
+ function list() {
367
+ printBanner();
368
+
369
+ console.log(` ${s.bold(s.white(totalCount + " components"))} ${s.dim("across")} ${s.bold(s.white(Object.keys(CATEGORIES).length + " categories"))}`);
370
+ console.log(` ${s.gray(hr(54))}`);
371
+ console.log();
372
+
373
+ const catEntries = Object.entries(CATEGORIES);
374
+
375
+ for (let ci = 0; ci < catEntries.length; ci++) {
376
+ const [cat, names] = catEntries[ci];
377
+ const isLastCat = ci === catEntries.length - 1;
378
+ const catPrefix = isLastCat ? B.end : B.tee;
379
+ const childPipe = isLastCat ? " " : B.pipe;
380
+
381
+ console.log(` ${s.gray(catPrefix)} ${s.bold(s.purple(cat))} ${s.dim("(" + names.length + ")")}`);
382
+
383
+ for (let ni = 0; ni < names.length; ni++) {
384
+ const isLastName = ni === names.length - 1;
385
+ const namePrefix = isLastName ? B.last : B.branch;
386
+ console.log(` ${s.gray(childPipe)} ${s.gray(namePrefix)} ${s.cyan(names[ni])}`);
387
+ }
388
+
389
+ if (!isLastCat) console.log(` ${s.gray(B.pipe)}`);
390
+ }
391
+
392
+ console.log();
393
+ console.log(` ${s.dim("Add a component:")} ${s.cyan("npx @electroplix/components add <name>")}`);
394
+ console.log(` ${s.dim("Add a category:")} ${s.cyan("npx @electroplix/components add <category>")}`);
395
+ console.log(` ${s.dim("Scaffold project:")} ${s.cyan("npx @electroplix/components init")}`);
396
+ console.log();
397
+ }
398
+
399
+ /* ══════════════════════════════════════════════════════════════════ */
400
+ /* HELP / default */
401
+ /* ══════════════════════════════════════════════════════════════════ */
402
+
403
+ function help() {
404
+ printBanner();
405
+
406
+ console.log(` ${s.bold("Commands:")}`);
407
+ console.log();
408
+ console.log(` ${s.cyan("init")} ${s.white("Scaffold config + providers for your project")}`);
409
+ console.log(` ${s.cyan("add")} ${s.violet("<name>")} ${s.white("Show import instructions for a component")}`);
410
+ console.log(` ${s.cyan("add")} ${s.violet("<category>")} ${s.white("Show all components in a category")}`);
411
+ console.log(` ${s.cyan("list")} ${s.white("Browse all")} ${s.bold(totalCount + "")} ${s.white("components")}`);
412
+ console.log();
413
+ console.log(` ${s.bold("Examples:")}`);
414
+ console.log();
415
+ console.log(` ${s.gray("$")} ${s.white("npx @electroplix/components init")}`);
416
+ console.log(` ${s.gray("$")} ${s.white("npx @electroplix/components add PrimaryNav")}`);
417
+ console.log(` ${s.gray("$")} ${s.white("npx @electroplix/components add navigation")}`);
418
+ console.log(` ${s.gray("$")} ${s.white("npx @electroplix/components list")}`);
419
+ console.log();
420
+ }
421
+
422
+ /* ══════════════════════════════════════════════════════════════════ */
423
+ /* Main */
424
+ /* ══════════════════════════════════════════════════════════════════ */
425
+
426
+ const [, , cmd, ...args] = process.argv;
427
+
428
+ switch (cmd) {
429
+ case "init":
430
+ init();
431
+ break;
432
+ case "add":
433
+ add(args.join(" "));
434
+ break;
435
+ case "list":
436
+ list();
437
+ break;
438
+ default:
439
+ help();
440
+ }
package/dist/README.md CHANGED
@@ -1,114 +1,35 @@
1
1
  # @electroplix/components
2
2
 
3
- Parametric, config-driven React UI components.
3
+ Parametric, config-driven React UI components — 153 components across 18 categories.
4
4
 
5
- ## Install
6
-
7
- ```bash
8
- npm install @electroplix/components
9
- # or
10
- pnpm add @electroplix/components
11
- ```
12
-
13
- > **Peer dependencies:** `react >=18` and `react-dom >=18`.
5
+ See the full documentation in the [root README](../README.md).
14
6
 
15
7
  ## Quick start
16
8
 
17
- ```tsx
18
- import { Navbar } from "@electroplix/components";
19
-
20
- export default function Page() {
21
- return (
22
- <Navbar
23
- logoText="MyBrand"
24
- links={[
25
- { label: "Home", href: "/" },
26
- { label: "Docs", href: "/docs" },
27
- ]}
28
- ctaText="Sign Up"
29
- />
30
- );
31
- }
9
+ ```bash
10
+ npm install @electroplix/components
11
+ npx @electroplix/components init
32
12
  ```
33
13
 
34
- ## Global configuration
35
-
36
- Create a config file and wrap your app with `ElectroplixProvider` to set
37
- style defaults for **every** component instance:
38
-
39
- ```ts
40
- // electroplix.config.ts
41
- import { defineConfig } from "@electroplix/components";
42
-
43
- export default defineConfig({
44
- navbar: {
45
- bgColor: "#22223B",
46
- textColor: "#F2E9E4",
47
- accentColor: "#C9ADA7",
48
- borderColor: "#4A4E69",
49
- fontFamily: "Roboto, sans-serif",
50
- height: 80,
51
- padding: 32,
52
- sticky: true,
53
- showSearch: true,
54
- showCTA: true,
55
- },
56
- });
57
- ```
14
+ Then update `app/layout.tsx`:
58
15
 
59
16
  ```tsx
60
- // app/layout.tsx (Next.js App Router example)
61
- import { ElectroplixProvider } from "@electroplix/components";
62
- import config from "../electroplix.config";
17
+ import { Providers } from "../components/providers";
63
18
 
64
19
  export default function RootLayout({ children }: { children: React.ReactNode }) {
65
20
  return (
66
- <html lang="en">
21
+ <html>
67
22
  <body>
68
- <ElectroplixProvider config={config}>
69
- {children}
70
- </ElectroplixProvider>
23
+ <Providers>{children}</Providers>
71
24
  </body>
72
25
  </html>
73
26
  );
74
27
  }
75
28
  ```
76
29
 
77
- Components will merge configuration in priority order:
78
- 1. **Per-instance** `config` prop (highest)
79
- 2. **Global** `ElectroplixProvider` config
80
- 3. **Built-in** defaults
81
-
82
- ## API reference
83
-
84
- ### `<Navbar>`
30
+ Use components in `"use client"` pages:
85
31
 
86
- | Prop | Type | Default | Description |
87
- |------|------|---------|-------------|
88
- | `logoText` | `string` | `"Electroplix"` | Brand text |
89
- | `logoHref` | `string` | `"/"` | Logo link target |
90
- | `links` | `NavLink[]` | `[]` | Navigation links |
91
- | `ctaText` | `string` | `"Get Started"` | CTA button label |
92
- | `ctaHref` | `string` | `"#"` | CTA button href |
93
- | `searchPlaceholder` | `string` | `"Search…"` | Search input placeholder |
94
- | `onSearch` | `(q: string) => void` | — | Search callback |
95
- | `config` | `NavbarConfig` | — | Per-instance style overrides |
96
-
97
- ### `NavbarConfig` (global or per-instance)
98
-
99
- | Key | Type | Default |
100
- |-----|------|---------|
101
- | `bgColor` | `string` | `"#0B0B0C"` |
102
- | `textColor` | `string` | `"#F3F4F6"` |
103
- | `accentColor` | `string` | `"#8B5CF6"` |
104
- | `borderColor` | `string` | `"rgba(255,255,255,0.1)"` |
105
- | `fontFamily` | `string` | `"Inter, ui-sans-serif, system-ui"` |
106
- | `height` | `number` | `72` |
107
- | `padding` | `number` | `24` |
108
- | `sticky` | `boolean` | `false` |
109
- | `showSearch` | `boolean` | `false` |
110
- | `showCTA` | `boolean` | `false` |
111
-
112
- ## License
113
-
114
- MIT
32
+ ```tsx
33
+ "use client";
34
+ import { PrimaryNav, StaticHero } from "@electroplix/components";
35
+ ```