@nous-research/ui 0.4.0 → 0.6.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-card.d.ts","sourceRoot":"","sources":["../../../src/ui/components/tier-card.tsx"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAO,EACP,SAAS,EACT,KAAK,EACL,SAAiB,EACjB,QAAQ,EACR,OAAO,EACP,KAAK,EACL,QAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,KAAK,EACN,EAAE,aAAa,2CAsHf;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,6CAA6C;IAC7C,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,2GAA2G;IAC3G,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,aAAa,CAAA;IACpB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD,4BAA4B;IAC5B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB"}
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { cn } from '../../utils';
4
+ import { ImageDistortion } from './image-distortion';
5
+ import { Typography } from './typography';
6
+ import { Small } from './typography/small';
7
+ /**
8
+ * Selectable tier / pricing card. Full-bleed distorted image background,
9
+ * readable overlay text, and an animated `.arc-border` shimmer on the
10
+ * selected state. Fully presentational — the consumer owns the data
11
+ * (tier schema, price formatting, tier imagery / tints).
12
+ *
13
+ * Visual states:
14
+ * - `selected`: brightens the distortion, activates `.arc-border`, and
15
+ * composites the headline / price with `mix-blend-mode: plus-lighter`
16
+ * so the text lifts off the image regardless of tint.
17
+ * - `isCurrent`: subtle midground-tinted border hint (suppressed when
18
+ * `selected` wins).
19
+ * - `overlay`: optional top-layer color blended with `mix-blend-mode:
20
+ * color` — used for the "highest tier" red treatment on top of any
21
+ * base tint.
22
+ */
23
+ export function TierCard({ badge, bullets, className, image, isCurrent = false, onSelect, overlay, price, selected = false, tint, tintStrength, title }) {
24
+ return (_jsxs("button", { className: cn('group relative flex w-full cursor-pointer flex-col border border-current/20', 'text-left transition-colors duration-300', selected && 'border-midground/60', isCurrent && !selected && 'border-midground/30', className), onClick: onSelect, type: "button", children: [_jsx("span", { "aria-hidden": true, className: cn('arc-border transition-opacity duration-200', selected ? 'opacity-100' : 'opacity-0 group-hover:opacity-100') }), _jsxs("div", { className: "relative aspect-[3/4] min-h-0 w-full flex-1 overflow-hidden", style: { backgroundColor: 'var(--background)' }, children: [_jsx(ImageDistortion, { active: selected, src: image, tint: tint, tintStrength: tintStrength }), overlay && (_jsx("div", { className: "pointer-events-none absolute inset-0", style: { backgroundColor: overlay, mixBlendMode: 'color' } })), _jsxs("div", { className: "pointer-events-none absolute inset-0 z-[1] flex flex-col justify-between p-3", children: [_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsxs(Small, { className: cn('block drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]', 'transition-colors', selected && 'text-midground'), style: selected ? { mixBlendMode: 'plus-lighter' } : undefined, children: [title, badge && _jsx("span", { className: "ml-1 opacity-50", children: badge })] }), price.secondary ? (_jsxs(_Fragment, { children: [_jsxs(Typography, { className: "block text-sm line-through opacity-50 drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.secondary, price.secondarySuffix && (_jsx("span", { className: "text-[0.625rem]", children: price.secondarySuffix }))] }), _jsxs(Typography, { className: "block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.primary, price.primarySuffix && (_jsxs("span", { className: "text-[0.625rem] opacity-60", children: [' ', price.primarySuffix] }))] })] })) : (_jsxs(Typography, { className: "block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]", expanded: true, style: { mixBlendMode: 'plus-lighter' }, children: [price.primary, price.primarySuffix && (_jsx("span", { className: "text-[0.625rem] opacity-60", children: price.primarySuffix }))] }))] }), bullets.length > 0 && (_jsx("ul", { className: "flex flex-col gap-1", children: bullets.map((bullet, i) => (_jsxs("li", { className: cn('font-courier text-[0.6875rem] leading-tight tracking-wider uppercase', 'drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]', 'opacity-70'), children: ["\u00B7 ", bullet] }, typeof bullet === 'string' ? bullet : i))) }))] })] })] }));
25
+ }
26
+ //# sourceMappingURL=tier-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-card.js","sourceRoot":"","sources":["../../../src/ui/components/tier-card.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client'\n\nimport { cn } from '../../utils'\n\nimport { ImageDistortion } from './image-distortion'\nimport { Typography } from './typography'\nimport { Small } from './typography/small'\n\n/**\n * Selectable tier / pricing card. Full-bleed distorted image background,\n * readable overlay text, and an animated `.arc-border` shimmer on the\n * selected state. Fully presentational — the consumer owns the data\n * (tier schema, price formatting, tier imagery / tints).\n *\n * Visual states:\n * - `selected`: brightens the distortion, activates `.arc-border`, and\n * composites the headline / price with `mix-blend-mode: plus-lighter`\n * so the text lifts off the image regardless of tint.\n * - `isCurrent`: subtle midground-tinted border hint (suppressed when\n * `selected` wins).\n * - `overlay`: optional top-layer color blended with `mix-blend-mode:\n * color` — used for the \"highest tier\" red treatment on top of any\n * base tint.\n */\nexport function TierCard({\n badge,\n bullets,\n className,\n image,\n isCurrent = false,\n onSelect,\n overlay,\n price,\n selected = false,\n tint,\n tintStrength,\n title\n}: TierCardProps) {\n return (\n <button\n className={cn(\n 'group relative flex w-full cursor-pointer flex-col border border-current/20',\n 'text-left transition-colors duration-300',\n selected && 'border-midground/60',\n isCurrent && !selected && 'border-midground/30',\n className\n )}\n onClick={onSelect}\n type=\"button\"\n >\n <span\n aria-hidden\n className={cn(\n 'arc-border transition-opacity duration-200',\n selected ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'\n )}\n />\n\n <div\n className=\"relative aspect-[3/4] min-h-0 w-full flex-1 overflow-hidden\"\n style={{ backgroundColor: 'var(--background)' }}\n >\n <ImageDistortion\n active={selected}\n src={image}\n tint={tint}\n tintStrength={tintStrength}\n />\n\n {overlay && (\n <div\n className=\"pointer-events-none absolute inset-0\"\n style={{ backgroundColor: overlay, mixBlendMode: 'color' }}\n />\n )}\n\n <div className=\"pointer-events-none absolute inset-0 z-[1] flex flex-col justify-between p-3\">\n <div className=\"flex flex-col gap-0.5\">\n <Small\n className={cn(\n 'block drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]',\n 'transition-colors',\n selected && 'text-midground'\n )}\n style={selected ? { mixBlendMode: 'plus-lighter' } : undefined}\n >\n {title}\n {badge && <span className=\"ml-1 opacity-50\">{badge}</span>}\n </Small>\n\n {price.secondary ? (\n <>\n <Typography\n className=\"block text-sm line-through opacity-50 drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.secondary}\n {price.secondarySuffix && (\n <span className=\"text-[0.625rem]\">\n {price.secondarySuffix}\n </span>\n )}\n </Typography>\n\n <Typography\n className=\"block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.primary}\n {price.primarySuffix && (\n <span className=\"text-[0.625rem] opacity-60\">\n {' '}\n {price.primarySuffix}\n </span>\n )}\n </Typography>\n </>\n ) : (\n <Typography\n className=\"block text-lg font-bold drop-shadow-[0_1px_3px_rgba(0,0,0,0.6)]\"\n expanded\n style={{ mixBlendMode: 'plus-lighter' }}\n >\n {price.primary}\n {price.primarySuffix && (\n <span className=\"text-[0.625rem] opacity-60\">\n {price.primarySuffix}\n </span>\n )}\n </Typography>\n )}\n </div>\n\n {bullets.length > 0 && (\n <ul className=\"flex flex-col gap-1\">\n {bullets.map((bullet, i) => (\n <li\n className={cn(\n 'font-courier text-[0.6875rem] leading-tight tracking-wider uppercase',\n 'drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]',\n 'opacity-70'\n )}\n key={typeof bullet === 'string' ? bullet : i}\n >\n · {bullet}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n </button>\n )\n}\n\nexport interface TierCardPrice {\n /** Headline price, e.g. `\"$20\"` or `\"Free\"`. */\n primary: string\n /** Small suffix rendered after `primary`, e.g. `\"/mo\"` or `\"first payment\"`. */\n primarySuffix?: string\n /** Optional struck-through comparison price rendered above `primary`, e.g. `\"$30\"`. */\n secondary?: string\n /** Small suffix rendered after `secondary`. */\n secondarySuffix?: string\n}\n\nexport interface TierCardProps {\n /** Small annotation after the title, e.g. `\"(current)\"`. */\n badge?: React.ReactNode\n /** Feature list rendered under the price. */\n bullets: React.ReactNode[]\n className?: string\n /** Background image URL. */\n image: string\n /** Applies the \"current plan\" border hint when not `selected`. */\n isCurrent?: boolean\n onSelect?: () => void\n /** Color blended with `mix-blend-mode: color` over the image (used for the highest-tier red treatment). */\n overlay?: string\n price: TierCardPrice\n /** Applies selected chrome (arc-border shimmer, active distortion, plus-lighter text blend). */\n selected?: boolean\n /** Shader tint passed through to `ImageDistortion`. */\n tint?: string\n /** Active / inactive tint strength passed through to `ImageDistortion`. */\n tintStrength?: { active: number; inactive: number }\n /** Tier name / headline. */\n title: React.ReactNode\n}\n"]}
@@ -115,6 +115,13 @@
115
115
  --color-foreground-base: var(--foreground-base);
116
116
  --color-gesso: #eaeaea;
117
117
 
118
+ /* Semantic tokens — defaults for DS preview; consumers (e.g. shadcn-style
119
+ dashboards) can remap these via their own @theme inline. */
120
+ --color-destructive: var(--destructive, #fb2c36);
121
+ --color-destructive-foreground: var(--destructive-foreground, #ffffff);
122
+ --color-success: var(--success, #4ade80);
123
+ --color-warning: var(--warning, #ffbd38);
124
+
118
125
  --color-current: currentColor;
119
126
  --color-transparent: transparent;
120
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nous-research/ui",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": [