@shipsite.dev/components 0.2.29 → 0.2.30

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.
@@ -1,5 +1,10 @@
1
1
  import React from 'react';
2
2
  import { type ImageSource } from '../ui/theme-image';
3
+ interface BlogArticleAuthor {
4
+ name: string;
5
+ role: string;
6
+ image: string;
7
+ }
3
8
  interface BlogArticle {
4
9
  slug: string;
5
10
  title: string;
@@ -9,6 +14,8 @@ interface BlogArticle {
9
14
  image: ImageSource;
10
15
  readingTime: number;
11
16
  href: string;
17
+ featured?: boolean;
18
+ author?: BlogArticleAuthor;
12
19
  }
13
20
  interface BlogIndexProps {
14
21
  id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BlogIndex.d.ts","sourceRoot":"","sources":["../../src/blog/BlogIndex.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAcD,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAkDvF"}
1
+ {"version":3,"file":"BlogIndex.d.ts","sourceRoot":"","sources":["../../src/blog/BlogIndex.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,UAAU,cAAc;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA+DD,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAmCvF"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Section } from '../ui/section';
3
3
  import { ThemeImage } from '../ui/theme-image';
4
4
  function formatDate(dateStr) {
@@ -13,7 +13,12 @@ function formatDate(dateStr) {
13
13
  return dateStr;
14
14
  }
15
15
  }
16
+ function ArticleCard({ article }) {
17
+ return (_jsxs("a", { href: article.href, className: "group block rounded-3xl p-2 -m-2 hover:bg-muted/50 hover:scale-[1.015] transition-all duration-300 ease-out focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring", children: [_jsx("div", { className: "aspect-[3/2] overflow-hidden rounded-2xl", children: _jsx(ThemeImage, { src: article.image, alt: article.title, className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105" }) }), _jsxs("div", { className: "pt-4", children: [_jsxs("div", { className: "flex items-center justify-between text-sm text-muted-foreground mb-2", children: [article.category && (_jsx("span", { className: "font-medium text-primary", children: article.category })), article.date && _jsx("time", { dateTime: article.date, children: formatDate(article.date) })] }), _jsx("h3", { className: "text-lg font-semibold leading-snug text-foreground mb-2 group-hover:text-primary transition-colors", children: article.title }), _jsx("p", { className: "text-base text-muted-foreground line-clamp-2 mb-4", children: article.excerpt }), article.author && (_jsxs("div", { className: "flex items-center gap-3", children: [article.author.image && (_jsx("img", { src: article.author.image, alt: article.author.name, className: "w-10 h-10 rounded-full object-cover" })), _jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: article.author.name }), article.author.role && (_jsx("div", { className: "text-xs text-muted-foreground", children: article.author.role }))] })] }))] })] }, article.slug));
18
+ }
16
19
  export function BlogIndex({ id, title, description, articles, children }) {
17
- return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground", children: description })] })), articles && articles.length > 0 && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: articles.map((article) => (_jsxs("a", { href: article.href, className: "group block rounded-xl glass-1 hover:glass-2 transition-all overflow-hidden focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring", children: [_jsx("div", { className: "aspect-[16/9] overflow-hidden", children: _jsx(ThemeImage, { src: article.image, alt: article.title, className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105" }) }), _jsxs("div", { className: "p-5", children: [article.category && (_jsx("span", { className: "inline-block text-xs font-medium text-primary mb-2", children: article.category })), _jsx("h3", { className: "font-semibold tracking-tight text-foreground mb-2 group-hover:text-primary transition-colors", children: article.title }), _jsx("p", { className: "text-sm text-muted-foreground mb-4 line-clamp-2", children: article.excerpt }), _jsxs("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [article.date && _jsx("time", { dateTime: article.date, children: formatDate(article.date) }), article.readingTime > 0 && _jsxs("span", { children: [article.readingTime, " min read"] })] })] })] }, article.slug))) })), children] }) }));
20
+ const featured = articles?.filter((a) => a.featured) ?? [];
21
+ const all = articles ?? [];
22
+ return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground", children: description })] })), featured.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8 mb-12", children: featured.map((article) => (_jsx(ArticleCard, { article: article }, article.slug))) }), _jsx("hr", { className: "border-border mb-12" }), _jsx("h3", { className: "text-xl font-semibold text-foreground mb-8", children: "All Articles" })] })), all.length > 0 && (_jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8", children: all.map((article) => (_jsx(ArticleCard, { article: article }, article.slug))) })), children] }) }));
18
23
  }
19
24
  //# sourceMappingURL=BlogIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BlogIndex.js","sourceRoot":"","sources":["../../src/blog/BlogIndex.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AAqBjE,SAAS,UAAU,CAAC,OAAe;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE;YACrD,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,OAAO;YACd,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAkB;IACtF,OAAO,CACL,KAAC,OAAO,IAAC,EAAE,EAAE,EAAE,YACb,eAAK,SAAS,EAAC,gBAAgB,aAC5B,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CACzB,eAAK,SAAS,EAAC,mBAAmB,aAC/B,KAAK,IAAI,aAAI,SAAS,EAAC,qDAAqD,YAAE,KAAK,GAAM,EACzF,WAAW,IAAI,YAAG,SAAS,EAAC,+BAA+B,YAAE,WAAW,GAAK,IAC1E,CACP,EACA,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,cAAK,SAAS,EAAC,sDAAsD,YAClE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACzB,aAEE,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,SAAS,EAAC,uJAAuJ,aAEjK,cAAK,SAAS,EAAC,+BAA+B,YAC5C,KAAC,UAAU,IACT,GAAG,EAAE,OAAO,CAAC,KAAK,EAClB,GAAG,EAAE,OAAO,CAAC,KAAK,EAClB,SAAS,EAAC,oFAAoF,GAC9F,GACE,EACN,eAAK,SAAS,EAAC,KAAK,aACjB,OAAO,CAAC,QAAQ,IAAI,CACnB,eAAM,SAAS,EAAC,oDAAoD,YACjE,OAAO,CAAC,QAAQ,GACZ,CACR,EACD,aAAI,SAAS,EAAC,8FAA8F,YACzG,OAAO,CAAC,KAAK,GACX,EACL,YAAG,SAAS,EAAC,iDAAiD,YAC3D,OAAO,CAAC,OAAO,GACd,EACJ,eAAK,SAAS,EAAC,uDAAuD,aACnE,OAAO,CAAC,IAAI,IAAI,eAAM,QAAQ,EAAE,OAAO,CAAC,IAAI,YAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAQ,EAC/E,OAAO,CAAC,WAAW,GAAG,CAAC,IAAI,2BAAO,OAAO,CAAC,WAAW,iBAAiB,IACnE,IACF,KA3BD,OAAO,CAAC,IAAI,CA4Bf,CACL,CAAC,GACE,CACP,EACA,QAAQ,IACL,GACE,CACX,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"BlogIndex.js","sourceRoot":"","sources":["../../src/blog/BlogIndex.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AA6BjE,SAAS,UAAU,CAAC,OAAe;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE;YACrD,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,OAAO;YACd,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,OAAO,EAA4B;IACxD,OAAO,CACL,aAEE,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,SAAS,EAAC,uLAAuL,aAEjM,cAAK,SAAS,EAAC,0CAA0C,YACvD,KAAC,UAAU,IACT,GAAG,EAAE,OAAO,CAAC,KAAK,EAClB,GAAG,EAAE,OAAO,CAAC,KAAK,EAClB,SAAS,EAAC,oFAAoF,GAC9F,GACE,EACN,eAAK,SAAS,EAAC,MAAM,aACnB,eAAK,SAAS,EAAC,sEAAsE,aAClF,OAAO,CAAC,QAAQ,IAAI,CACnB,eAAM,SAAS,EAAC,0BAA0B,YAAE,OAAO,CAAC,QAAQ,GAAQ,CACrE,EACA,OAAO,CAAC,IAAI,IAAI,eAAM,QAAQ,EAAE,OAAO,CAAC,IAAI,YAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAQ,IAC5E,EACN,aAAI,SAAS,EAAC,oGAAoG,YAC/G,OAAO,CAAC,KAAK,GACX,EACL,YAAG,SAAS,EAAC,mDAAmD,YAC7D,OAAO,CAAC,OAAO,GACd,EACH,OAAO,CAAC,MAAM,IAAI,CACjB,eAAK,SAAS,EAAC,yBAAyB,aACrC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CACvB,cACE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EACzB,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EACxB,SAAS,EAAC,qCAAqC,GAC/C,CACH,EACD,0BACE,cAAK,SAAS,EAAC,qCAAqC,YAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAO,EAC/E,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CACtB,cAAK,SAAS,EAAC,+BAA+B,YAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAO,CAC3E,IACG,IACF,CACP,IACG,KAzCD,OAAO,CAAC,IAAI,CA0Cf,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAkB;IACtF,MAAM,QAAQ,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,QAAQ,IAAI,EAAE,CAAC;IAE3B,OAAO,CACL,KAAC,OAAO,IAAC,EAAE,EAAE,EAAE,YACb,eAAK,SAAS,EAAC,gBAAgB,aAC5B,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CACzB,eAAK,SAAS,EAAC,mBAAmB,aAC/B,KAAK,IAAI,aAAI,SAAS,EAAC,qDAAqD,YAAE,KAAK,GAAM,EACzF,WAAW,IAAI,YAAG,SAAS,EAAC,+BAA+B,YAAE,WAAW,GAAK,IAC1E,CACP,EACA,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CACtB,8BACE,cAAK,SAAS,EAAC,6CAA6C,YACzD,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACzB,KAAC,WAAW,IAAoB,OAAO,EAAE,OAAO,IAA9B,OAAO,CAAC,IAAI,CAAsB,CACrD,CAAC,GACE,EACN,aAAI,SAAS,EAAC,qBAAqB,GAAG,EACtC,aAAI,SAAS,EAAC,4CAA4C,6BAAkB,IAC3E,CACJ,EACA,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CACjB,cAAK,SAAS,EAAC,sDAAsD,YAClE,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACpB,KAAC,WAAW,IAAoB,OAAO,EAAE,OAAO,IAA9B,OAAO,CAAC,IAAI,CAAsB,CACrD,CAAC,GACE,CACP,EACA,QAAQ,IACL,GACE,CACX,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"PricingSectionClient.d.ts","sourceRoot":"","sources":["../../src/marketing/PricingSectionClient.tsx"],"names":[],"mappings":"AAQA,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC9B;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;QAAC,KAAK,EAAE,kBAAkB,GAAG,uBAAuB,CAAA;KAAE,EAAE,CAAC;CAC3F;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,YAAwB,EAAE,WAAsB,EAAE,gBAAiC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,yBAAyB,2CAuF3L"}
1
+ {"version":3,"file":"PricingSectionClient.d.ts","sourceRoot":"","sources":["../../src/marketing/PricingSectionClient.tsx"],"names":[],"mappings":"AASA,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC9B;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;QAAC,KAAK,EAAE,kBAAkB,GAAG,uBAAuB,CAAA;KAAE,EAAE,CAAC;CAC3F;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,YAAwB,EAAE,WAAsB,EAAE,gBAAiC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,yBAAyB,2CAkG3L"}
@@ -5,9 +5,10 @@ import { Check } from 'lucide-react';
5
5
  import { cn } from '../lib/utils';
6
6
  import { Section } from '../ui/section';
7
7
  import { Button } from '../ui/button';
8
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
8
9
  export function PricingSectionClient({ id, title, description, monthlyLabel = 'Monthly', yearlyLabel = 'Yearly', mostPopularLabel = 'Most Popular', plans, rows }) {
9
10
  const [isYearly, setIsYearly] = useState(false);
10
- return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground max-w-2xl mx-auto", children: description })] })), plans.some((p) => p.yearlyPrice) && (_jsxs("div", { className: "flex items-center justify-center gap-3 mb-12", children: [_jsx("span", { className: cn('text-sm font-medium', !isYearly ? 'text-foreground' : 'text-muted-foreground'), children: monthlyLabel }), _jsx("button", { onClick: () => setIsYearly(!isYearly), className: cn('relative w-12 h-6 rounded-full transition-colors', isYearly ? 'bg-primary' : 'bg-muted'), children: _jsx("span", { className: cn('absolute top-0.5 w-5 h-5 bg-background rounded-full shadow transition-transform', isYearly ? 'translate-x-6' : 'translate-x-0.5') }) }), _jsx("span", { className: cn('text-sm font-medium', isYearly ? 'text-foreground' : 'text-muted-foreground'), children: yearlyLabel })] })), _jsx("div", { className: cn('grid grid-cols-1 gap-6 mb-16', plans.length === 2 && 'md:grid-cols-2', plans.length >= 3 && 'md:grid-cols-3'), children: plans.map((plan) => (_jsxs("div", { className: cn('relative rounded-2xl p-8', plan.popular
11
+ return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground max-w-2xl mx-auto", children: description })] })), plans.some((p) => p.yearlyPrice) && (_jsx("div", { className: "flex justify-center mb-12", children: _jsx(TabsPrimitive.Root, { defaultValue: "monthly", onValueChange: (v) => setIsYearly(v === 'yearly'), children: _jsxs(TabsPrimitive.List, { className: "inline-flex rounded-full glass-1 p-1 gap-1", children: [_jsx(TabsPrimitive.Trigger, { value: "monthly", className: "rounded-full px-5 py-2 text-sm font-medium text-muted-foreground transition-all hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[state=active]:bg-primary data-[state=active]:text-primary-foreground", children: monthlyLabel }), _jsx(TabsPrimitive.Trigger, { value: "yearly", className: "rounded-full px-5 py-2 text-sm font-medium text-muted-foreground transition-all hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[state=active]:bg-primary data-[state=active]:text-primary-foreground", children: yearlyLabel })] }) }) })), _jsx("div", { className: cn('grid grid-cols-1 gap-6 mb-16', plans.length === 2 && 'md:grid-cols-2', plans.length >= 3 && 'md:grid-cols-3'), children: plans.map((plan) => (_jsxs("div", { className: cn('relative rounded-2xl p-8', plan.popular
11
12
  ? 'glass-4 ring-2 ring-primary shadow-xl'
12
13
  : 'glass-1'), children: [plan.popular && (_jsx("div", { className: "absolute -top-3 left-1/2 -translate-x-1/2 px-3 py-1 bg-primary text-primary-foreground text-xs font-medium rounded-full", children: mostPopularLabel })), _jsx("h3", { className: "text-xl font-bold mb-2 text-foreground", children: plan.name }), plan.description && _jsx("p", { className: "text-sm mb-4 text-muted-foreground", children: plan.description }), _jsx("div", { className: "mb-6", children: _jsx("span", { className: "text-4xl font-bold text-foreground", children: isYearly && plan.yearlyPrice ? plan.yearlyPrice : plan.price }) }), _jsx(Button, { asChild: true, className: "w-full", variant: plan.popular ? 'default' : 'glow', children: _jsx("a", { href: plan.cta.href, children: plan.cta.label }) }), _jsx("ul", { className: "mt-6 space-y-3", children: plan.features.map((feature) => (_jsxs("li", { className: "flex items-start gap-2 text-sm text-muted-foreground", children: [_jsx(Check, { className: "w-4 h-4 mt-0.5 shrink-0 text-primary" }), feature] }, feature))) })] }, plan.name))) }), rows.length > 0 && (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border", children: [_jsx("th", { className: "text-left py-4 pr-4 font-medium text-foreground", children: "Feature" }), plans.map((plan) => _jsx("th", { className: "text-center py-4 px-4 font-medium text-foreground", children: plan.name }, plan.name))] }) }), _jsx("tbody", { children: rows.map((row, i) => {
13
14
  if (row.type === 'category') {
@@ -1 +1 @@
1
- {"version":3,"file":"PricingSectionClient.js","sourceRoot":"","sources":["../../src/marketing/PricingSectionClient.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PricingSectionClient.js","sourceRoot":"","sources":["../../src/marketing/PricingSectionClient.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
2
+ import * as React from "react";
3
+ declare const Tabs: React.ForwardRefExoticComponent<TabsPrimitive.TabsProps & React.RefAttributes<HTMLDivElement>>;
4
+ declare function TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>): import("react/jsx-runtime").JSX.Element;
5
+ declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
6
+ declare function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
7
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
8
+ //# sourceMappingURL=tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/ui/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,QAAA,MAAM,IAAI,gGAAqB,CAAC;AAEhC,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,2CAQjD;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,2CAWpD;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,2CAWpD;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import { cn } from "../lib/utils";
5
+ const Tabs = TabsPrimitive.Root;
6
+ function TabsList({ className, ...props }) {
7
+ return (_jsx(TabsPrimitive.List, { "data-slot": "tabs-list", className: cn("text-muted-foreground flex items-center", className), ...props }));
8
+ }
9
+ function TabsTrigger({ className, ...props }) {
10
+ return (_jsx(TabsPrimitive.Trigger, { "data-slot": "tabs-trigger", className: cn("data-[state=active]:glass-4 ring-offset-background hover:bg-accent/50 hover:text-accent-foreground focus-visible:ring-ring data-[state=active]:text-foreground flex flex-col gap-3 rounded-md border border-transparent px-5 pt-4 pb-6 text-left text-sm font-medium transition-all focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-xl dark:border-b-0", className), ...props }));
11
+ }
12
+ function TabsContent({ className, ...props }) {
13
+ return (_jsx(TabsPrimitive.Content, { "data-slot": "tabs-content", className: cn("border-border dark:border-border/20 bg-input/30 ring-offset-background focus-visible:ring-ring dark:bg-card relative overflow-hidden rounded-lg border focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden", className), ...props }));
14
+ }
15
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
16
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/ui/tabs.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC;AAEhC,SAAS,QAAQ,CAAC,EAChB,SAAS,EACT,GAAG,KAAK,EACwC;IAChD,OAAO,CACL,KAAC,aAAa,CAAC,IAAI,iBACP,WAAW,EACrB,SAAS,EAAE,EAAE,CAAC,yCAAyC,EAAE,SAAS,CAAC,KAC/D,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EAC2C;IACnD,OAAO,CACL,KAAC,aAAa,CAAC,OAAO,iBACV,cAAc,EACxB,SAAS,EAAE,EAAE,CACX,kcAAkc,EAClc,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EACnB,SAAS,EACT,GAAG,KAAK,EAC2C;IACnD,OAAO,CACL,KAAC,aAAa,CAAC,OAAO,iBACV,cAAc,EACxB,SAAS,EAAE,EAAE,CACX,sOAAsO,EACtO,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipsite.dev/components",
3
- "version": "0.2.29",
3
+ "version": "0.2.30",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shipsite/shipsite",
@@ -37,6 +37,7 @@
37
37
  "@radix-ui/react-accordion": "^1.2.3",
38
38
  "@radix-ui/react-dialog": "^1.1.6",
39
39
  "@radix-ui/react-slot": "^1.2.0",
40
+ "@radix-ui/react-tabs": "^1.1.13",
40
41
  "class-variance-authority": "^0.7.1",
41
42
  "clsx": "^2.1.1",
42
43
  "lucide-react": "^0.475.0",
@@ -46,10 +47,10 @@
46
47
  "tailwind-merge": "^3.0.2"
47
48
  },
48
49
  "devDependencies": {
49
- "typescript": "^5.8.3",
50
- "@types/react": "^19",
51
50
  "@types/node": "^20",
52
- "tailwindcss": "^4"
51
+ "@types/react": "^19",
52
+ "tailwindcss": "^4",
53
+ "typescript": "^5.8.3"
53
54
  },
54
55
  "peerDependencies": {
55
56
  "next": ">=15"
@@ -2,6 +2,12 @@ import React from 'react';
2
2
  import { Section } from '../ui/section';
3
3
  import { ThemeImage, type ImageSource } from '../ui/theme-image';
4
4
 
5
+ interface BlogArticleAuthor {
6
+ name: string;
7
+ role: string;
8
+ image: string;
9
+ }
10
+
5
11
  interface BlogArticle {
6
12
  slug: string;
7
13
  title: string;
@@ -11,6 +17,8 @@ interface BlogArticle {
11
17
  image: ImageSource;
12
18
  readingTime: number;
13
19
  href: string;
20
+ featured?: boolean;
21
+ author?: BlogArticleAuthor;
14
22
  }
15
23
 
16
24
  interface BlogIndexProps {
@@ -33,7 +41,59 @@ function formatDate(dateStr: string): string {
33
41
  }
34
42
  }
35
43
 
44
+ function ArticleCard({ article }: { article: BlogArticle }) {
45
+ return (
46
+ <a
47
+ key={article.slug}
48
+ href={article.href}
49
+ className="group block rounded-3xl p-2 -m-2 hover:bg-muted/50 hover:scale-[1.015] transition-all duration-300 ease-out focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"
50
+ >
51
+ <div className="aspect-[3/2] overflow-hidden rounded-2xl">
52
+ <ThemeImage
53
+ src={article.image}
54
+ alt={article.title}
55
+ className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
56
+ />
57
+ </div>
58
+ <div className="pt-4">
59
+ <div className="flex items-center justify-between text-sm text-muted-foreground mb-2">
60
+ {article.category && (
61
+ <span className="font-medium text-primary">{article.category}</span>
62
+ )}
63
+ {article.date && <time dateTime={article.date}>{formatDate(article.date)}</time>}
64
+ </div>
65
+ <h3 className="text-lg font-semibold leading-snug text-foreground mb-2 group-hover:text-primary transition-colors">
66
+ {article.title}
67
+ </h3>
68
+ <p className="text-base text-muted-foreground line-clamp-2 mb-4">
69
+ {article.excerpt}
70
+ </p>
71
+ {article.author && (
72
+ <div className="flex items-center gap-3">
73
+ {article.author.image && (
74
+ <img
75
+ src={article.author.image}
76
+ alt={article.author.name}
77
+ className="w-10 h-10 rounded-full object-cover"
78
+ />
79
+ )}
80
+ <div>
81
+ <div className="text-sm font-medium text-foreground">{article.author.name}</div>
82
+ {article.author.role && (
83
+ <div className="text-xs text-muted-foreground">{article.author.role}</div>
84
+ )}
85
+ </div>
86
+ </div>
87
+ )}
88
+ </div>
89
+ </a>
90
+ );
91
+ }
92
+
36
93
  export function BlogIndex({ id, title, description, articles, children }: BlogIndexProps) {
94
+ const featured = articles?.filter((a) => a.featured) ?? [];
95
+ const all = articles ?? [];
96
+
37
97
  return (
38
98
  <Section id={id}>
39
99
  <div className="container-main">
@@ -43,39 +103,21 @@ export function BlogIndex({ id, title, description, articles, children }: BlogIn
43
103
  {description && <p className="text-lg text-muted-foreground">{description}</p>}
44
104
  </div>
45
105
  )}
46
- {articles && articles.length > 0 && (
47
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
48
- {articles.map((article) => (
49
- <a
50
- key={article.slug}
51
- href={article.href}
52
- className="group block rounded-xl glass-1 hover:glass-2 transition-all overflow-hidden focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"
53
- >
54
- <div className="aspect-[16/9] overflow-hidden">
55
- <ThemeImage
56
- src={article.image}
57
- alt={article.title}
58
- className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
59
- />
60
- </div>
61
- <div className="p-5">
62
- {article.category && (
63
- <span className="inline-block text-xs font-medium text-primary mb-2">
64
- {article.category}
65
- </span>
66
- )}
67
- <h3 className="font-semibold tracking-tight text-foreground mb-2 group-hover:text-primary transition-colors">
68
- {article.title}
69
- </h3>
70
- <p className="text-sm text-muted-foreground mb-4 line-clamp-2">
71
- {article.excerpt}
72
- </p>
73
- <div className="flex items-center gap-3 text-xs text-muted-foreground">
74
- {article.date && <time dateTime={article.date}>{formatDate(article.date)}</time>}
75
- {article.readingTime > 0 && <span>{article.readingTime} min read</span>}
76
- </div>
77
- </div>
78
- </a>
106
+ {featured.length > 0 && (
107
+ <>
108
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-12">
109
+ {featured.map((article) => (
110
+ <ArticleCard key={article.slug} article={article} />
111
+ ))}
112
+ </div>
113
+ <hr className="border-border mb-12" />
114
+ <h3 className="text-xl font-semibold text-foreground mb-8">All Articles</h3>
115
+ </>
116
+ )}
117
+ {all.length > 0 && (
118
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
119
+ {all.map((article) => (
120
+ <ArticleCard key={article.slug} article={article} />
79
121
  ))}
80
122
  </div>
81
123
  )}
@@ -5,6 +5,7 @@ import { Check } from 'lucide-react';
5
5
  import { cn } from '../lib/utils';
6
6
  import { Section } from '../ui/section';
7
7
  import { Button } from '../ui/button';
8
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
8
9
 
9
10
  interface PricingPlanProps {
10
11
  name: string;
@@ -50,12 +51,23 @@ export function PricingSectionClient({ id, title, description, monthlyLabel = 'M
50
51
  )}
51
52
 
52
53
  {plans.some((p) => p.yearlyPrice) && (
53
- <div className="flex items-center justify-center gap-3 mb-12">
54
- <span className={cn('text-sm font-medium', !isYearly ? 'text-foreground' : 'text-muted-foreground')}>{monthlyLabel}</span>
55
- <button onClick={() => setIsYearly(!isYearly)} className={cn('relative w-12 h-6 rounded-full transition-colors', isYearly ? 'bg-primary' : 'bg-muted')}>
56
- <span className={cn('absolute top-0.5 w-5 h-5 bg-background rounded-full shadow transition-transform', isYearly ? 'translate-x-6' : 'translate-x-0.5')} />
57
- </button>
58
- <span className={cn('text-sm font-medium', isYearly ? 'text-foreground' : 'text-muted-foreground')}>{yearlyLabel}</span>
54
+ <div className="flex justify-center mb-12">
55
+ <TabsPrimitive.Root defaultValue="monthly" onValueChange={(v) => setIsYearly(v === 'yearly')}>
56
+ <TabsPrimitive.List className="inline-flex rounded-full glass-1 p-1 gap-1">
57
+ <TabsPrimitive.Trigger
58
+ value="monthly"
59
+ className="rounded-full px-5 py-2 text-sm font-medium text-muted-foreground transition-all hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[state=active]:bg-primary data-[state=active]:text-primary-foreground"
60
+ >
61
+ {monthlyLabel}
62
+ </TabsPrimitive.Trigger>
63
+ <TabsPrimitive.Trigger
64
+ value="yearly"
65
+ className="rounded-full px-5 py-2 text-sm font-medium text-muted-foreground transition-all hover:text-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[state=active]:bg-primary data-[state=active]:text-primary-foreground"
66
+ >
67
+ {yearlyLabel}
68
+ </TabsPrimitive.Trigger>
69
+ </TabsPrimitive.List>
70
+ </TabsPrimitive.Root>
59
71
  </div>
60
72
  )}
61
73
 
@@ -0,0 +1,55 @@
1
+ "use client";
2
+
3
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import * as React from "react";
5
+
6
+ import { cn } from "../lib/utils";
7
+
8
+ const Tabs = TabsPrimitive.Root;
9
+
10
+ function TabsList({
11
+ className,
12
+ ...props
13
+ }: React.ComponentProps<typeof TabsPrimitive.List>) {
14
+ return (
15
+ <TabsPrimitive.List
16
+ data-slot="tabs-list"
17
+ className={cn("text-muted-foreground flex items-center", className)}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+
23
+ function TabsTrigger({
24
+ className,
25
+ ...props
26
+ }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
27
+ return (
28
+ <TabsPrimitive.Trigger
29
+ data-slot="tabs-trigger"
30
+ className={cn(
31
+ "data-[state=active]:glass-4 ring-offset-background hover:bg-accent/50 hover:text-accent-foreground focus-visible:ring-ring data-[state=active]:text-foreground flex flex-col gap-3 rounded-md border border-transparent px-5 pt-4 pb-6 text-left text-sm font-medium transition-all focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-xl dark:border-b-0",
32
+ className,
33
+ )}
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function TabsContent({
40
+ className,
41
+ ...props
42
+ }: React.ComponentProps<typeof TabsPrimitive.Content>) {
43
+ return (
44
+ <TabsPrimitive.Content
45
+ data-slot="tabs-content"
46
+ className={cn(
47
+ "border-border dark:border-border/20 bg-input/30 ring-offset-background focus-visible:ring-ring dark:bg-card relative overflow-hidden rounded-lg border focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden",
48
+ className,
49
+ )}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ export { Tabs, TabsContent, TabsList, TabsTrigger };