starwind 1.15.5 → 1.16.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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Create animated websites in record time.**
6
6
 
7
- Starwind UI is a collection of 42+ beautifully designed, animated, and accessible components built purely with Astro and vanilla JS. Inspired by [shadcn/ui](https://ui.shadcn.com/), components are added directly to your codebase, giving you full ownership and complete control.
7
+ Starwind UI is a collection of 45+ beautifully designed, animated, and accessible components built purely with Astro and vanilla JS. Inspired by [shadcn/ui](https://ui.shadcn.com/), components are added directly to your codebase, giving you full ownership and complete control.
8
8
 
9
9
  **[Get Started →](https://starwind.dev/docs/getting-started/installation/)**  |  **[Explore Components](https://starwind.dev/docs/components/)**
10
10
 
package/dist/index.js CHANGED
@@ -6,9 +6,10 @@ import { Command, Option } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "starwind",
9
- version: "1.15.5",
9
+ version: "1.16.1",
10
10
  description: "Add beautifully designed components to your Astro applications",
11
11
  license: "MIT",
12
+ homepage: "https://starwind.dev/",
12
13
  author: {
13
14
  name: "webreaper",
14
15
  url: "https://x.com/BowTiedWebReapr"
@@ -20,15 +21,16 @@ var package_default = {
20
21
  },
21
22
  keywords: [
22
23
  "starwind",
23
- "starwind ui",
24
- "starwind cli",
24
+ "starwind-ui",
25
+ "starwind-cli",
25
26
  "astro",
26
- "astro component",
27
- "astro ui",
28
- "astro ui library",
27
+ "astro-component",
28
+ "astro-ui",
29
+ "withastro",
30
+ "ui",
31
+ "accessibility",
29
32
  "tailwind",
30
- "components",
31
- "add component"
33
+ "components"
32
34
  ],
33
35
  type: "module",
34
36
  bin: {
@@ -58,7 +60,7 @@ var package_default = {
58
60
  },
59
61
  dependencies: {
60
62
  "@clack/prompts": "^0.11.0",
61
- "@starwind-ui/core": "1.15.5",
63
+ "@starwind-ui/core": "1.16.1",
62
64
  chalk: "^5.6.2",
63
65
  commander: "^14.0.2",
64
66
  execa: "^9.6.0",
@@ -87,12 +89,16 @@ var MIN_ASTRO_VERSION = "5.0.0";
87
89
  var PATHS = {
88
90
  STARWIND_CORE: "@starwind-ui/core",
89
91
  STARWIND_CORE_COMPONENTS: "src/components",
92
+ STARWIND_CORE_UTILS: "src/lib/utils",
90
93
  STARWIND_REMOTE_COMPONENT_REGISTRY: "https://starwind.dev/registry.json",
91
94
  STARWIND_PRO_REGISTRY: "https://pro.starwind.dev/r/{name}",
92
95
  LOCAL_CSS_FILE: "src/styles/starwind.css",
93
96
  LOCAL_CONFIG_FILE: "starwind.config.json",
94
97
  LOCAL_STYLES_DIR: "src/styles",
95
- LOCAL_COMPONENTS_DIR: "src/components"
98
+ LOCAL_COMPONENTS_DIR: "src/components",
99
+ LOCAL_UTILS_DIR: "src/lib/utils",
100
+ VSCODE_DIR: ".vscode",
101
+ VSCODE_SNIPPETS_FILE: ".vscode/starwind.code-snippets"
96
102
  };
97
103
  var ASTRO_PACKAGES = {
98
104
  core: "astro@latest"
@@ -140,6 +146,7 @@ var defaultConfig = {
140
146
  // components: "@/components",
141
147
  // },
142
148
  componentDir: "src/components/starwind",
149
+ utilsDir: PATHS.LOCAL_UTILS_DIR,
143
150
  components: []
144
151
  };
145
152
  async function getConfig() {
@@ -182,6 +189,7 @@ async function updateConfig(updates, options = { appendComponents: true }) {
182
189
  ...updates.tailwind || {}
183
190
  },
184
191
  componentDir: updates.componentDir ? updates.componentDir : currentConfig.componentDir,
192
+ utilsDir: updates.utilsDir ? updates.utilsDir : currentConfig.utilsDir ?? defaultConfig.utilsDir,
185
193
  components: finalComponents
186
194
  };
187
195
  try {
@@ -226,6 +234,7 @@ var componentSchema = z.object({
226
234
  name: z.string(),
227
235
  version: z.string(),
228
236
  dependencies: z.array(z.string()).default([]),
237
+ fileDependencies: z.array(z.string()).optional(),
229
238
  type: z.enum(["component"])
230
239
  });
231
240
  var registryRootSchema = z.object({
@@ -274,25 +283,74 @@ async function getAllComponents(forceRefresh = false) {
274
283
  }
275
284
 
276
285
  // src/utils/component.ts
277
- async function copyComponent(name, overwrite = false) {
286
+ function resolveConfigPath(directory) {
287
+ if (directory.startsWith("@/")) {
288
+ return path.join("src", directory.slice(2));
289
+ }
290
+ return directory;
291
+ }
292
+ function normalizeFileDependencyPath(fileDependency) {
293
+ const normalized = fileDependency.replace(/\\/g, "/");
294
+ if (path.posix.isAbsolute(normalized)) {
295
+ throw new Error(`File dependency "${fileDependency}" must be a relative path`);
296
+ }
297
+ const trimmed = normalized.startsWith("starwind/") ? normalized.slice("starwind/".length) : normalized;
298
+ const safePath = path.posix.normalize(trimmed);
299
+ if (safePath.startsWith("..") || safePath === "." || safePath.length === 0) {
300
+ throw new Error(`File dependency "${fileDependency}" contains an invalid path`);
301
+ }
302
+ return safePath;
303
+ }
304
+ async function copyFileDependencies(options) {
305
+ const { coreDir, fileDependencies, utilsDir } = options;
306
+ if (fileDependencies.length === 0) return;
307
+ const targetUtilsRoot = path.join(resolveConfigPath(utilsDir), "starwind");
308
+ const sourceUtilsRoot = path.join(coreDir, PATHS.STARWIND_CORE_UTILS, "starwind");
309
+ await fs2.ensureDir(targetUtilsRoot);
310
+ for (const fileDependency of fileDependencies) {
311
+ const relativePath = normalizeFileDependencyPath(fileDependency);
312
+ const sourcePath = path.join(sourceUtilsRoot, relativePath);
313
+ const destinationPath = path.join(targetUtilsRoot, relativePath);
314
+ if (!await fs2.pathExists(sourcePath)) {
315
+ throw new Error(
316
+ `File dependency "${fileDependency}" for component is missing from ${PATHS.STARWIND_CORE_UTILS}/starwind`
317
+ );
318
+ }
319
+ await fs2.ensureDir(path.dirname(destinationPath));
320
+ await fs2.copy(sourcePath, destinationPath, { overwrite: true });
321
+ }
322
+ }
323
+ async function copyComponent(name, overwrite = false, options) {
278
324
  const config = await getConfig();
279
325
  const currentComponents = Array.isArray(config.components) ? config.components : [];
280
- if (!overwrite && currentComponents.some((component) => component.name === name)) {
281
- const existingComponent = currentComponents.find((c) => c.name === name);
282
- return {
283
- status: "skipped",
284
- name,
285
- version: existingComponent?.version ?? "unknown"
286
- };
287
- }
288
- const componentDir = path.join(config.componentDir, "starwind", name);
289
326
  try {
290
- await fs2.ensureDir(componentDir);
291
- const pkgUrl = import.meta.resolve?.(PATHS.STARWIND_CORE);
327
+ const registry = await getRegistry();
328
+ const componentInfo = registry.find((component) => component.name === name);
329
+ if (!componentInfo) {
330
+ throw new Error(`Component ${name} not found in registry`);
331
+ }
332
+ const fileDependencies = componentInfo.fileDependencies ?? [];
333
+ const resolvePackageUrl = options?.resolvePackageUrl ?? ((specifier) => import.meta.resolve?.(specifier));
334
+ const pkgUrl = resolvePackageUrl(PATHS.STARWIND_CORE);
292
335
  if (!pkgUrl) {
293
336
  throw new Error(`Could not resolve ${PATHS.STARWIND_CORE} package, is it installed?`);
294
337
  }
295
338
  const coreDir = path.dirname(fileURLToPath(pkgUrl));
339
+ if (!overwrite && currentComponents.some((component) => component.name === name)) {
340
+ await copyFileDependencies({
341
+ coreDir,
342
+ fileDependencies,
343
+ utilsDir: config.utilsDir || PATHS.LOCAL_UTILS_DIR
344
+ });
345
+ const existingComponent = currentComponents.find((c) => c.name === name);
346
+ return {
347
+ status: "skipped",
348
+ name,
349
+ version: existingComponent?.version ?? "unknown"
350
+ };
351
+ }
352
+ const componentDir = path.join(config.componentDir, "starwind", name);
353
+ await fs2.ensureDir(componentDir);
296
354
  const sourceDir = path.join(coreDir, PATHS.STARWIND_CORE_COMPONENTS, name);
297
355
  const files = await fs2.readdir(sourceDir);
298
356
  for (const file of files) {
@@ -300,11 +358,11 @@ async function copyComponent(name, overwrite = false) {
300
358
  const destPath = path.join(componentDir, file);
301
359
  await fs2.copy(sourcePath, destPath, { overwrite: true });
302
360
  }
303
- const registry = await getRegistry();
304
- const componentInfo = registry.find((c) => c.name === name);
305
- if (!componentInfo) {
306
- throw new Error(`Component ${name} not found in registry`);
307
- }
361
+ await copyFileDependencies({
362
+ coreDir,
363
+ fileDependencies,
364
+ utilsDir: config.utilsDir || PATHS.LOCAL_UTILS_DIR
365
+ });
308
366
  return {
309
367
  status: "installed",
310
368
  name,
@@ -1100,9 +1158,9 @@ var tailwindConfig = `@import "tailwindcss";
1100
1158
  --primary: var(--color-blue-700);
1101
1159
  --primary-foreground: var(--color-neutral-50);
1102
1160
  --primary-accent: var(--color-blue-700);
1103
- --secondary: var(--color-fuchsia-700);
1104
- --secondary-foreground: var(--color-neutral-50);
1105
- --secondary-accent: var(--color-fuchsia-700);
1161
+ --secondary: var(--color-neutral-200);
1162
+ --secondary-foreground: var(--color-neutral-950);
1163
+ --secondary-accent: var(--color-neutral-950);
1106
1164
  --muted: var(--color-neutral-100);
1107
1165
  --muted-foreground: var(--color-neutral-600);
1108
1166
  --accent: var(--color-neutral-100);
@@ -1141,9 +1199,9 @@ var tailwindConfig = `@import "tailwindcss";
1141
1199
  --primary: var(--color-blue-700);
1142
1200
  --primary-foreground: var(--color-neutral-50);
1143
1201
  --primary-accent: var(--color-blue-400);
1144
- --secondary: var(--color-fuchsia-700);
1202
+ --secondary: var(--color-neutral-800);
1145
1203
  --secondary-foreground: var(--color-neutral-50);
1146
- --secondary-accent: var(--color-fuchsia-400);
1204
+ --secondary-accent: var(--color-neutral-50);
1147
1205
  --muted: var(--color-neutral-800);
1148
1206
  --muted-foreground: var(--color-neutral-400);
1149
1207
  --accent: var(--color-neutral-700);
@@ -1468,6 +1526,63 @@ async function setupLayoutCssImport(cssPath) {
1468
1526
  }
1469
1527
  }
1470
1528
 
1529
+ // src/utils/snippets.ts
1530
+ var THEME_TOGGLE_SNIPPET = {
1531
+ "Starwind UI Theme Toggle": {
1532
+ prefix: "starwind-theme-toggle",
1533
+ description: "Starwind UI theme initialization script for the document head",
1534
+ scope: "astro,typescript",
1535
+ body: [
1536
+ "<script is:inline>",
1537
+ " function initTheme() {",
1538
+ ' const colorTheme = localStorage.getItem("colorTheme");',
1539
+ " if (!colorTheme) {",
1540
+ ' if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {',
1541
+ ' document.documentElement.classList.add("dark");',
1542
+ ' localStorage.setItem("colorTheme", "dark");',
1543
+ " } else {",
1544
+ ' document.documentElement.classList.remove("dark");',
1545
+ ' localStorage.setItem("colorTheme", "light");',
1546
+ " }",
1547
+ " } else {",
1548
+ ' if (colorTheme === "dark") {',
1549
+ ' document.documentElement.classList.add("dark");',
1550
+ ' } else if (colorTheme === "light") {',
1551
+ ' document.documentElement.classList.remove("dark");',
1552
+ ' } else if (colorTheme === "system") {',
1553
+ ' const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;',
1554
+ ' document.documentElement.classList.toggle("dark", prefersDark);',
1555
+ " }",
1556
+ " }",
1557
+ " }",
1558
+ "",
1559
+ " initTheme();",
1560
+ ' document.addEventListener("astro:after-swap", initTheme);',
1561
+ "</script>"
1562
+ ]
1563
+ }
1564
+ };
1565
+ async function setupSnippets() {
1566
+ await ensureDirectory(PATHS.VSCODE_DIR);
1567
+ const targetPath = PATHS.VSCODE_SNIPPETS_FILE;
1568
+ let existingSnippets = {};
1569
+ if (await fileExists(targetPath)) {
1570
+ try {
1571
+ existingSnippets = await readJsonFile(targetPath);
1572
+ } catch (error) {
1573
+ existingSnippets = {};
1574
+ }
1575
+ }
1576
+ const updatedSnippets = {
1577
+ ...existingSnippets,
1578
+ "Starwind UI Theme Toggle": {
1579
+ ...THEME_TOGGLE_SNIPPET["Starwind UI Theme Toggle"]
1580
+ }
1581
+ };
1582
+ await writeJsonFile(targetPath, updatedSnippets);
1583
+ return true;
1584
+ }
1585
+
1471
1586
  // src/utils/tsconfig.ts
1472
1587
  import * as p7 from "@clack/prompts";
1473
1588
  var REQUIRED_TSCONFIG = {
@@ -1639,6 +1754,7 @@ async function init(withinAdd = false, options) {
1639
1754
  }
1640
1755
  );
1641
1756
  }
1757
+ const utilsDir = PATHS.LOCAL_UTILS_DIR;
1642
1758
  const cssFileDir = path2.dirname(configChoices.cssFile);
1643
1759
  const componentInstallDir = path2.join(configChoices.installLocation, "starwind");
1644
1760
  configTasks.push({
@@ -1650,6 +1766,14 @@ async function init(withinAdd = false, options) {
1650
1766
  return "Created project structure";
1651
1767
  }
1652
1768
  });
1769
+ configTasks.push({
1770
+ title: "Setting up VS Code snippets",
1771
+ task: async () => {
1772
+ await setupSnippets();
1773
+ await sleep(250);
1774
+ return "VS Code snippets configured";
1775
+ }
1776
+ });
1653
1777
  configTasks.push({
1654
1778
  title: "Setup Astro config file",
1655
1779
  task: async () => {
@@ -1734,6 +1858,7 @@ async function init(withinAdd = false, options) {
1734
1858
  // components: "@/components",
1735
1859
  // },
1736
1860
  componentDir: configChoices.installLocation,
1861
+ utilsDir,
1737
1862
  components: []
1738
1863
  });
1739
1864
  await sleep(250);