@asteby/metacore-auth 4.0.0 → 5.0.0

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
@@ -95,7 +95,7 @@ export function SignInRoute() {
95
95
 
96
96
  ## Design notes
97
97
 
98
- - **Zustand store is canonical** — matches the Ops frontend shape (user + token + reset). Persists to `localStorage` keys `auth_token` / `auth_user`.
98
+ - **Zustand store is canonical** — generic shape (user + token + reset) shared across host applications. Persists to `localStorage` keys `auth_token` / `auth_user`.
99
99
  - **Factory, not singleton** — `createApiClient` avoids baking env vars into the library. The host app wires token / language / branch getters.
100
100
  - **Pages are brand-less** — accept `brandName`, `logo`, `showcase`, `headerSlot`, `footerSlot` so each app supplies its own identity.
101
101
  - **`onSubmit` delegated** — pages don't assume endpoints, toasts, or navigation. The caller owns the network layer.
@@ -0,0 +1,18 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ export interface Feature {
3
+ key: string;
4
+ Icon?: ComponentType<{
5
+ className?: string;
6
+ }>;
7
+ title: ReactNode;
8
+ description?: ReactNode;
9
+ }
10
+ export interface FeatureListProps {
11
+ features: Feature[];
12
+ noAnimate?: boolean;
13
+ /** Stagger between rows, ms. Default 70. */
14
+ stagger?: number;
15
+ className?: string;
16
+ }
17
+ export declare function FeatureList({ features, noAnimate, stagger, className, }: FeatureListProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=feature-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-list.d.ts","sourceRoot":"","sources":["../../../src/showcases/blocks/feature-list.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGrD,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC5C,KAAK,EAAE,SAAS,CAAA;IAChB,WAAW,CAAC,EAAE,SAAS,CAAA;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,OAAY,EACZ,SAAS,GACV,EAAE,gBAAgB,2CAmClB"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Vertical list of icon + title + description rows. Generic explainer block
3
+ // — auth showcases ("what you get"), settings dashboards, onboarding tours,
4
+ // pricing-tier breakdowns. No product assumptions.
5
+ import { motion } from 'framer-motion';
6
+ import { cn } from '@asteby/metacore-ui/lib';
7
+ export function FeatureList({ features, noAnimate, stagger = 70, className, }) {
8
+ return (_jsx("div", { className: cn('space-y-4', className), children: features.map((feature, i) => {
9
+ const animProps = noAnimate
10
+ ? {}
11
+ : {
12
+ initial: { opacity: 0, x: -8 },
13
+ animate: { opacity: 1, x: 0 },
14
+ transition: { delay: 0.1 + i * (stagger / 1000), duration: 0.35 },
15
+ };
16
+ return (_jsxs(motion.div, { ...animProps, className: "flex items-start gap-3", children: [feature.Icon && (_jsx("div", { className: "size-9 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0 mt-0.5", children: _jsx(feature.Icon, { className: "size-4 text-primary" }) })), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-sm font-semibold", children: feature.title }), feature.description && (_jsx("div", { className: "text-xs text-muted-foreground mt-0.5 leading-relaxed", children: feature.description }))] })] }, feature.key));
17
+ }) }));
18
+ }
19
+ //# sourceMappingURL=feature-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-list.js","sourceRoot":"","sources":["../../../src/showcases/blocks/feature-list.tsx"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,mDAAmD;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAiB5C,MAAM,UAAU,WAAW,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,OAAO,GAAG,EAAE,EACZ,SAAS,GACQ;IACjB,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,YACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,SAAS,GAAG,SAAS;gBACzB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;oBAC9B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;oBAC7B,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAClE,CAAA;YACL,OAAO,CACL,MAAC,MAAM,CAAC,GAAG,OAEJ,SAAoB,EACzB,SAAS,EAAC,wBAAwB,aAEjC,OAAO,CAAC,IAAI,IAAI,CACf,cAAK,SAAS,EAAC,uFAAuF,YACpG,KAAC,OAAO,CAAC,IAAI,IAAC,SAAS,EAAC,qBAAqB,GAAG,GAC5C,CACP,EACD,eAAK,SAAS,EAAC,gBAAgB,aAC7B,cAAK,SAAS,EAAC,uBAAuB,YAAE,OAAO,CAAC,KAAK,GAAO,EAC3D,OAAO,CAAC,WAAW,IAAI,CACtB,cAAK,SAAS,EAAC,sDAAsD,YAClE,OAAO,CAAC,WAAW,GAChB,CACP,IACG,KAhBD,OAAO,CAAC,GAAG,CAiBL,CACd,CAAA;QACH,CAAC,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface HeroPanelProps {
3
+ title: ReactNode;
4
+ subtitle?: ReactNode;
5
+ /** Optional eyebrow rendered above the title (badge, pill, etc). */
6
+ eyebrow?: ReactNode;
7
+ /** Optional content rendered below the subtitle (CTAs, badges). */
8
+ footer?: ReactNode;
9
+ /** Default `'center'`. */
10
+ align?: 'left' | 'center';
11
+ /** Skip the entry animation. */
12
+ noAnimate?: boolean;
13
+ className?: string;
14
+ }
15
+ export declare function HeroPanel({ title, subtitle, eyebrow, footer, align, noAnimate, className, }: HeroPanelProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=hero-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero-panel.d.ts","sourceRoot":"","sources":["../../../src/showcases/blocks/hero-panel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,oEAAoE;IACpE,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;IACzB,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,MAAM,EACN,KAAgB,EAChB,SAAS,EACT,SAAS,GACV,EAAE,cAAc,2CA0BhB"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Title + subtitle stacked block. Use it as the top of any auth showcase
3
+ // (or any hero zone in the app — module dashboards, settings empty states,
4
+ // marketing surfaces). No brand or product assumptions.
5
+ import { motion } from 'framer-motion';
6
+ import { cn } from '@asteby/metacore-ui/lib';
7
+ export function HeroPanel({ title, subtitle, eyebrow, footer, align = 'center', noAnimate, className, }) {
8
+ const Wrap = noAnimate ? 'div' : motion.div;
9
+ const animProps = noAnimate
10
+ ? {}
11
+ : {
12
+ initial: { opacity: 0, y: 16 },
13
+ animate: { opacity: 1, y: 0 },
14
+ transition: { duration: 0.5 },
15
+ };
16
+ return (_jsxs(Wrap, { ...animProps, className: cn('max-w-md', align === 'center' ? 'text-center mx-auto' : 'text-left', className), children: [eyebrow && _jsx("div", { className: "mb-3", children: eyebrow }), _jsx("h2", { className: "text-3xl font-bold tracking-tight", children: title }), subtitle && (_jsx("p", { className: "text-muted-foreground text-sm leading-relaxed mt-3", children: subtitle })), footer && _jsx("div", { className: "mt-6", children: footer })] }));
17
+ }
18
+ //# sourceMappingURL=hero-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero-panel.js","sourceRoot":"","sources":["../../../src/showcases/blocks/hero-panel.tsx"],"names":[],"mappings":";AAAA,yEAAyE;AACzE,2EAA2E;AAC3E,wDAAwD;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAgB5C,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,MAAM,EACN,KAAK,GAAG,QAAQ,EAChB,SAAS,EACT,SAAS,GACM;IACf,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;IAC3C,MAAM,SAAS,GAAG,SAAS;QACzB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC;YACE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YAC9B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;YAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC9B,CAAA;IACL,OAAO,CACL,MAAC,IAAI,OACE,SAAoB,EACzB,SAAS,EAAE,EAAE,CACX,UAAU,EACV,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,EACxD,SAAS,CACV,aAEA,OAAO,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,OAAO,GAAO,EACjD,aAAI,SAAS,EAAC,mCAAmC,YAAE,KAAK,GAAM,EAC7D,QAAQ,IAAI,CACX,YAAG,SAAS,EAAC,oDAAoD,YAAE,QAAQ,GAAK,CACjF,EACA,MAAM,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,MAAM,GAAO,IAC1C,CACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { HeroPanel, type HeroPanelProps } from './hero-panel';
2
+ export { TileGrid, type Tile, type TileGridProps } from './tile-grid';
3
+ export { FeatureList, type Feature, type FeatureListProps, } from './feature-list';
4
+ export { StatRow, type Stat, type StatRowProps } from './stat-row';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/showcases/blocks/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EACL,WAAW,EACX,KAAK,OAAO,EACZ,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,12 @@
1
+ // Composable, brand-agnostic blocks for building auth showcases — and any
2
+ // other hero zone in an app (dashboards, empty states, marketing surfaces).
3
+ //
4
+ // Apps build their own showcase by composing these. The SDK does not ship
5
+ // product-specific showcases (chat mockups, marketplace tiles, etc) — those
6
+ // live in each app's `features/auth/showcase/`, since they encode the app's
7
+ // narrative and copy.
8
+ export { HeroPanel } from './hero-panel';
9
+ export { TileGrid } from './tile-grid';
10
+ export { FeatureList, } from './feature-list';
11
+ export { StatRow } from './stat-row';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/showcases/blocks/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,4EAA4E;AAC5E,sBAAsB;AACtB,OAAO,EAAE,SAAS,EAAuB,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAiC,MAAM,aAAa,CAAA;AACrE,OAAO,EACL,WAAW,GAGZ,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAgC,MAAM,YAAY,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface Stat {
3
+ key: string;
4
+ /** The big number (or any node). */
5
+ value: ReactNode;
6
+ /** The label under the number. */
7
+ label: ReactNode;
8
+ }
9
+ export interface StatRowProps {
10
+ stats: Stat[];
11
+ noAnimate?: boolean;
12
+ className?: string;
13
+ }
14
+ export declare function StatRow({ stats, noAnimate, className }: StatRowProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=stat-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-row.d.ts","sourceRoot":"","sources":["../../../src/showcases/blocks/stat-row.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,oCAAoC;IACpC,KAAK,EAAE,SAAS,CAAA;IAChB,kCAAkC;IAClC,KAAK,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,YAAY,2CAwBpE"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Horizontal row of headline metrics. "1.2M+ messages", "+2k orgs",
3
+ // "99.9% uptime" — anywhere a quick credibility band makes sense (auth
4
+ // showcase footer, dashboard summary, marketing strip).
5
+ import { motion } from 'framer-motion';
6
+ import { cn } from '@asteby/metacore-ui/lib';
7
+ export function StatRow({ stats, noAnimate, className }) {
8
+ return (_jsx("div", { className: cn('flex items-center justify-center gap-8 flex-wrap', className), children: stats.map((stat, i) => {
9
+ const animProps = noAnimate
10
+ ? {}
11
+ : {
12
+ initial: { opacity: 0, y: 8 },
13
+ animate: { opacity: 1, y: 0 },
14
+ transition: { delay: 0.1 + i * 0.06, duration: 0.35 },
15
+ };
16
+ return (_jsxs(motion.div, { ...animProps, className: "text-center", children: [_jsx("div", { className: "text-2xl font-bold tracking-tight", children: stat.value }), _jsx("div", { className: "text-xs text-muted-foreground mt-0.5", children: stat.label })] }, stat.key));
17
+ }) }));
18
+ }
19
+ //# sourceMappingURL=stat-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-row.js","sourceRoot":"","sources":["../../../src/showcases/blocks/stat-row.tsx"],"names":[],"mappings":";AAAA,oEAAoE;AACpE,uEAAuE;AACvE,wDAAwD;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AAgB5C,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAgB;IACnE,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,kDAAkD,EAAE,SAAS,CAAC,YAC9E,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,SAAS,GAAG,SAAS;gBACzB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;oBAC7B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;oBAC7B,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;iBACtD,CAAA;YACL,OAAO,CACL,MAAC,MAAM,CAAC,GAAG,OAEJ,SAAoB,EACzB,SAAS,EAAC,aAAa,aAEvB,cAAK,SAAS,EAAC,mCAAmC,YAAE,IAAI,CAAC,KAAK,GAAO,EACrE,cAAK,SAAS,EAAC,sCAAsC,YAAE,IAAI,CAAC,KAAK,GAAO,KALnE,IAAI,CAAC,GAAG,CAMF,CACd,CAAA;QACH,CAAC,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ export interface Tile {
3
+ /** Stable key. */
4
+ key: string;
5
+ /** Primary text under the icon. */
6
+ label: ReactNode;
7
+ /** Optional secondary text (category, tag, count). */
8
+ tag?: ReactNode;
9
+ /** Lucide-style icon component (or anything that renders SVG). Optional. */
10
+ Icon?: ComponentType<{
11
+ className?: string;
12
+ }>;
13
+ /** Image source — used instead of `Icon` if provided. */
14
+ imageSrc?: string;
15
+ /** Click handler. Tile becomes a button when set. */
16
+ onClick?: () => void;
17
+ }
18
+ export interface TileGridProps {
19
+ tiles: Tile[];
20
+ /** Columns at lg+ (default 3). Mobile is always 2. */
21
+ columns?: 2 | 3 | 4;
22
+ /** Skip the staggered entry animation. */
23
+ noAnimate?: boolean;
24
+ /** Time between tile entries when animating, ms. Default 50. */
25
+ stagger?: number;
26
+ className?: string;
27
+ /** Per-tile className (use to tweak padding/border without subclassing). */
28
+ tileClassName?: string;
29
+ }
30
+ export declare function TileGrid({ tiles, columns, noAnimate, stagger, className, tileClassName, }: TileGridProps): import("react/jsx-runtime").JSX.Element;
31
+ //# sourceMappingURL=tile-grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-grid.d.ts","sourceRoot":"","sources":["../../../src/showcases/blocks/tile-grid.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGrD,MAAM,WAAW,IAAI;IACnB,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,mCAAmC;IACnC,KAAK,EAAE,SAAS,CAAA;IAChB,sDAAsD;IACtD,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,4EAA4E;IAC5E,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC5C,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,sDAAsD;IACtD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAW,EACX,SAAS,EACT,OAAY,EACZ,SAAS,EACT,aAAa,GACd,EAAE,aAAa,2CA8Df"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Grid of icon + label tiles. Generic enough to back: marketplace addon
3
+ // previews, ERP module pickers, settings dashboards, "what's included" auth
4
+ // showcases, integration galleries. Apps pass `tiles` and choose layout.
5
+ import { motion } from 'framer-motion';
6
+ import { cn } from '@asteby/metacore-ui/lib';
7
+ export function TileGrid({ tiles, columns = 3, noAnimate, stagger = 50, className, tileClassName, }) {
8
+ const colsClass = columns === 2 ? 'lg:grid-cols-2' : columns === 4 ? 'lg:grid-cols-4' : 'lg:grid-cols-3';
9
+ return (_jsx("div", { className: cn('grid grid-cols-2 gap-3', colsClass, className), children: tiles.map((tile, i) => {
10
+ const content = (_jsxs("div", { className: "flex flex-col items-center text-center gap-2", children: [_jsx("div", { className: "size-10 rounded-lg bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors overflow-hidden", children: tile.imageSrc ? (_jsx("img", { src: tile.imageSrc, alt: "", className: "size-full object-cover" })) : tile.Icon ? (_jsx(tile.Icon, { className: "size-5 text-primary" })) : null }), _jsxs("div", { children: [_jsx("div", { className: "text-xs font-semibold leading-tight", children: tile.label }), tile.tag && (_jsx("div", { className: "text-[10px] text-muted-foreground mt-0.5", children: tile.tag }))] })] }));
11
+ const innerProps = {
12
+ className: cn('group relative rounded-xl border bg-card p-3 shadow-sm', 'hover:shadow-md hover:border-primary/30 transition-all', tile.onClick && 'cursor-pointer', tileClassName),
13
+ };
14
+ const animProps = noAnimate
15
+ ? {}
16
+ : {
17
+ initial: { opacity: 0, scale: 0.92 },
18
+ animate: { opacity: 1, scale: 1 },
19
+ transition: { delay: 0.1 + i * (stagger / 1000), duration: 0.35 },
20
+ };
21
+ if (tile.onClick) {
22
+ return (_jsx(motion.button, { type: "button", onClick: tile.onClick, ...animProps, ...innerProps, children: content }, tile.key));
23
+ }
24
+ return (_jsx(motion.div, { ...animProps, ...innerProps, children: content }, tile.key));
25
+ }) }));
26
+ }
27
+ //# sourceMappingURL=tile-grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-grid.js","sourceRoot":"","sources":["../../../src/showcases/blocks/tile-grid.tsx"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,yEAAyE;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAA;AA8B5C,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,OAAO,GAAG,CAAC,EACX,SAAS,EACT,OAAO,GAAG,EAAE,EACZ,SAAS,EACT,aAAa,GACC;IACd,MAAM,SAAS,GACb,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACxF,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,SAAS,EAAE,SAAS,CAAC,YAC/D,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,OAAO,GAAG,CACd,eAAK,SAAS,EAAC,8CAA8C,aAC3D,cAAK,SAAS,EAAC,+HAA+H,YAC3I,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CACf,cAAK,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAC,EAAE,EAAC,SAAS,EAAC,wBAAwB,GAAG,CACtE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,CAAC,IAAI,IAAC,SAAS,EAAC,qBAAqB,GAAG,CAC9C,CAAC,CAAC,CAAC,IAAI,GACJ,EACN,0BACE,cAAK,SAAS,EAAC,qCAAqC,YAAE,IAAI,CAAC,KAAK,GAAO,EACtE,IAAI,CAAC,GAAG,IAAI,CACX,cAAK,SAAS,EAAC,0CAA0C,YAAE,IAAI,CAAC,GAAG,GAAO,CAC3E,IACG,IACF,CACP,CAAA;YAED,MAAM,UAAU,GAAG;gBACjB,SAAS,EAAE,EAAE,CACX,wDAAwD,EACxD,wDAAwD,EACxD,IAAI,CAAC,OAAO,IAAI,gBAAgB,EAChC,aAAa,CACd;aACF,CAAA;YAED,MAAM,SAAS,GAAG,SAAS;gBACzB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;oBACpC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;oBACjC,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAClE,CAAA;YAEL,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,OAAO,CACL,KAAC,MAAM,CAAC,MAAM,IAEZ,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,IAAI,CAAC,OAAO,KAChB,SAAoB,KACrB,UAAU,YAEb,OAAO,IANH,IAAI,CAAC,GAAG,CAOC,CACjB,CAAA;YACH,CAAC;YACD,OAAO,CACL,KAAC,MAAM,CAAC,GAAG,OAAqB,SAAoB,KAAM,UAAU,YACjE,OAAO,IADO,IAAI,CAAC,GAAG,CAEZ,CACd,CAAA;QACH,CAAC,CAAC,GACE,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ export type GenericShowcaseProps = {
3
+ /** Headline. Apps usually pass their brand name + a one-liner. */
4
+ title?: string;
5
+ /** Subhead under the title. */
6
+ subtitle?: string;
7
+ /** Optional slot rendered below the subtitle (CTAs, badges, signed-by, …). */
8
+ footer?: ReactNode;
9
+ };
10
+ export declare function GenericShowcase({ title, subtitle, footer, }?: GenericShowcaseProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/showcases/generic.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,MAAM,oBAAoB,GAAG;IACjC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAoB,EACpB,QAA0C,EAC1C,MAAM,GACP,GAAE,oBAAyB,2CAkB3B"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Brand-neutral fallback showcase for apps that don't have a custom one yet.
3
+ // A simple animated gradient blob with a tagline — enough to keep the auth
4
+ // page from looking empty without forcing any product narrative.
5
+ import { motion } from 'framer-motion';
6
+ export function GenericShowcase({ title = 'Bienvenido', subtitle = 'Inicia sesión para continuar.', footer, } = {}) {
7
+ return (_jsxs("div", { className: "relative w-full h-full flex items-center justify-center px-8 overflow-hidden", children: [_jsx("div", { className: "pointer-events-none absolute -top-1/4 -right-1/4 size-[480px] rounded-full bg-gradient-to-br from-primary/30 via-primary/10 to-transparent blur-3xl" }), _jsx("div", { className: "pointer-events-none absolute -bottom-1/4 -left-1/4 size-[420px] rounded-full bg-gradient-to-tr from-primary/20 to-transparent blur-3xl" }), _jsxs(motion.div, { initial: { opacity: 0, y: 16 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.5 }, className: "relative z-10 text-center max-w-sm", children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight mb-3", children: title }), _jsx("p", { className: "text-muted-foreground text-sm leading-relaxed", children: subtitle }), footer && _jsx("div", { className: "mt-6", children: footer })] })] }));
8
+ }
9
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/showcases/generic.tsx"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,2EAA2E;AAC3E,iEAAiE;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAYtC,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,GAAG,YAAY,EACpB,QAAQ,GAAG,+BAA+B,EAC1C,MAAM,MACkB,EAAE;IAC1B,OAAO,CACL,eAAK,SAAS,EAAC,8EAA8E,aAC3F,cAAK,SAAS,EAAC,qJAAqJ,GAAG,EACvK,cAAK,SAAS,EAAC,wIAAwI,GAAG,EAE1J,MAAC,MAAM,CAAC,GAAG,IACT,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAC9B,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAC7B,SAAS,EAAC,oCAAoC,aAE9C,aAAI,SAAS,EAAC,wCAAwC,YAAE,KAAK,GAAM,EACnE,YAAG,SAAS,EAAC,+CAA+C,YAAE,QAAQ,GAAK,EAC1E,MAAM,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,MAAM,GAAO,IACpC,IACT,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { GenericShowcase, type GenericShowcaseProps } from './generic';
2
+ export { HeroPanel, TileGrid, FeatureList, StatRow, type HeroPanelProps, type TileGridProps, type Tile, type FeatureListProps, type Feature, type StatRowProps, type Stat, } from './blocks';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/showcases/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAA;AACtE,OAAO,EACL,SAAS,EACT,QAAQ,EACR,WAAW,EACX,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,IAAI,EACT,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,IAAI,GACV,MAAM,UAAU,CAAA"}
@@ -0,0 +1,6 @@
1
+ // Brand-neutral fallback showcase + composable building blocks.
2
+ // Apps that want a custom showcase compose the blocks (HeroPanel, TileGrid,
3
+ // FeatureList, StatRow) from `@asteby/metacore-auth/showcases/blocks`.
4
+ export { GenericShowcase } from './generic';
5
+ export { HeroPanel, TileGrid, FeatureList, StatRow, } from './blocks';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/showcases/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EAAE,eAAe,EAA6B,MAAM,WAAW,CAAA;AACtE,OAAO,EACL,SAAS,EACT,QAAQ,EACR,WAAW,EACX,OAAO,GAQR,MAAM,UAAU,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-auth",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Metacore auth kit — Zustand store, API client factory, login/signup/forgot pages, guards for TanStack Router",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,15 +43,33 @@
43
43
  "./components": {
44
44
  "types": "./dist/components/index.d.ts",
45
45
  "import": "./dist/components/index.js"
46
+ },
47
+ "./showcases": {
48
+ "types": "./dist/showcases/index.d.ts",
49
+ "import": "./dist/showcases/index.js"
50
+ },
51
+ "./showcases/generic": {
52
+ "types": "./dist/showcases/generic.d.ts",
53
+ "import": "./dist/showcases/generic.js"
54
+ },
55
+ "./showcases/blocks": {
56
+ "types": "./dist/showcases/blocks/index.d.ts",
57
+ "import": "./dist/showcases/blocks/index.js"
46
58
  }
47
59
  },
48
60
  "peerDependencies": {
49
61
  "react": ">=18",
50
62
  "react-dom": ">=18",
51
63
  "@tanstack/react-router": ">=1.100",
64
+ "framer-motion": ">=10",
52
65
  "zustand": ">=5",
53
66
  "@asteby/metacore-ui": "^0.6.0"
54
67
  },
68
+ "peerDependenciesMeta": {
69
+ "framer-motion": {
70
+ "optional": true
71
+ }
72
+ },
55
73
  "dependencies": {
56
74
  "@hookform/resolvers": "^3.9.0",
57
75
  "axios": "^1.7.7",
@@ -63,6 +81,7 @@
63
81
  "@types/react": "^19.0.0",
64
82
  "@types/react-dom": "^19.0.0",
65
83
  "@tanstack/react-router": "^1.168.0",
84
+ "framer-motion": "^11.11.0",
66
85
  "react": "^19.2.4",
67
86
  "react-dom": "^19.2.4",
68
87
  "typescript": "^5.6.0",