@vvedantb/ui 0.25.1 → 0.26.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 +33 -1
- package/package.json +1 -1
- package/src/brand/AppWordmark.tsx +56 -0
- package/src/brand/index.ts +2 -0
- package/src/marketing/PricingModal.tsx +1 -1
- package/src/marketing/landing.css +3 -3
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Shared React 19 web UI. Source-exported: no build step.
|
|
|
10
10
|
| `@vvedantb/ui/tokens/css/*.css` | `index`, `base`, `dialog`, `modal`, `tabs`, `tabs-pills`, `utilities`, `scrollbar-thin`, `clear-input`, `motion`, `animations`, `nav-icons`, `compat-shadcn-rgb`, `border-beam` (opt-in, for `BorderBeam`), `markdown` (opt-in, for `Markdown`). CSS. `tokens.css` imports `scrollbar-thin`, `clear-input` and `motion`. |
|
|
11
11
|
| `@vvedantb/ui/tokens/compat/shadcn-rgb.css` | Same file as `tokens/css/compat-shadcn-rgb.css`. CSS. |
|
|
12
12
|
| `@vvedantb/ui/tokens/tailwind-preset` | Tailwind preset (`.mjs`) for `@config "@vvedantb/ui/tokens/tailwind-preset"`. Kept as a build-tool entry: Tailwind needs a resolvable package path, and it is not a React API. |
|
|
13
|
-
| `@vvedantb/ui/landing.css` | Landing page classes (`landing-atmosphere`, `landing-grain`, `landing-pulse-dot`, ambient graph and preview animations, smooth `#top` scrolling). CSS. |
|
|
13
|
+
| `@vvedantb/ui/landing.css` | Landing page classes (`landing-wordmark-text` for `AppWordmark`, `landing-atmosphere`, `landing-grain`, `landing-pulse-dot`, ambient graph and preview animations, smooth `#top` scrolling). CSS. |
|
|
14
14
|
| `@vvedantb/ui/package.json` | Package metadata. |
|
|
15
15
|
|
|
16
16
|
Removed in 0.4.0-rc.1: the `/cn`, `/sonner`, `/audio`, `/shell`, `/app`, `/composer` and `/tokens/native` subpaths. Import from `@vvedantb/ui`. See [`MIGRATION.md`](MIGRATION.md).
|
|
@@ -902,6 +902,38 @@ in its equal-size square. `"start"` left-aligns the glyph's ink in the same squa
|
|
|
902
902
|
<IconVmem size={16} align="start" />
|
|
903
903
|
```
|
|
904
904
|
|
|
905
|
+
### `AppWordmark`
|
|
906
|
+
|
|
907
|
+
Shared marketing wordmark for product app names across Project V sites: the `Icon*` glyph, then the full lowercase name (`vibot`, `vmem`, `verve`, `velth`, `vhub`) in Instrument Sans (`--font-sans`), weight 500, letter-spacing `-0.02em`, upright. The label is the lowercase app id, not `FAMILY_APPS[].name`. Use it in headers, the Products menu, ecosystem cards and footers.
|
|
908
|
+
|
|
909
|
+
**Font rule:** app names use this sans `AppWordmark` (Instrument Sans, `--font-sans`, weight 500). Only the PROJECT V wordmark uses Michroma. No serif and no italic sans for app names.
|
|
910
|
+
|
|
911
|
+
Never use `AppWordmark` for `projectv` (the type rejects it).
|
|
912
|
+
|
|
913
|
+
Setup. The package does not bundle the font. `--font-sans` comes from the package tokens. Load Instrument Sans in the app, as for the rest of the UI, if it is not already loaded.
|
|
914
|
+
|
|
915
|
+
```css
|
|
916
|
+
@import "@vvedantb/ui/landing.css"; /* provides .landing-wordmark-text */
|
|
917
|
+
```
|
|
918
|
+
|
|
919
|
+
| Prop | Type | Default | Notes |
|
|
920
|
+
| --- | --- | --- | --- |
|
|
921
|
+
| `app` | `"vibot" \| "vmem" \| "verve" \| "velth" \| "vhub"` | required | `ProductAppName`. |
|
|
922
|
+
| `size` | `number` | `24` | Text font size in px. The icon is `Math.round(size * 0.875)` px square. Gap is `0.3em`. |
|
|
923
|
+
| `icon` | `boolean` | `true` | `false` renders text only. |
|
|
924
|
+
| `href` | `string` | none | Root is an `<a>` with a focus ring. Otherwise a `<span>`. |
|
|
925
|
+
| `className` | `string` | none | On the root. |
|
|
926
|
+
| `target`, `rel`, `aria-label`, `title`, `id` | as `<a>` | none | Forwarded to the root. `target="_blank"` is never forced. |
|
|
927
|
+
|
|
928
|
+
```tsx
|
|
929
|
+
import { AppWordmark } from "@vvedantb/ui"
|
|
930
|
+
|
|
931
|
+
<AppWordmark app="vmem" /> {/* header, 24 */}
|
|
932
|
+
<AppWordmark app="vmem" size={16} /> {/* menu or footer */}
|
|
933
|
+
<AppWordmark app="vibot" icon={false} /> {/* text only */}
|
|
934
|
+
<AppWordmark app="vhub" href="https://vhub.projectv.uk" /> {/* link */}
|
|
935
|
+
```
|
|
936
|
+
|
|
905
937
|
### `AppMark` (deprecated)
|
|
906
938
|
|
|
907
939
|
Deprecated in favour of the `Icon*` components for plain marks. Tiles stay here.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vvedantb/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Shared React 19 UI for web apps: one JavaScript entry (primitives, shell pieces, app helpers including the Convex and Clerk provider, VITE env parsing and ensure-user, artifact viewers over the @vvedantb/server artifacts core, native tokens), design-token CSS, shared Tailwind v4 CSS and a Tailwind preset.",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { AnchorHTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "../utils/cn";
|
|
3
|
+
import { APP_ICONS } from "./AppIcons";
|
|
4
|
+
import type { AppName } from "./svg";
|
|
5
|
+
|
|
6
|
+
/** The five product apps. `projectv` keeps its Michroma wordmark and never uses `AppWordmark`. */
|
|
7
|
+
export type ProductAppName = Exclude<AppName, "projectv">;
|
|
8
|
+
|
|
9
|
+
export type AppWordmarkProps = Pick<AnchorHTMLAttributes<HTMLAnchorElement>, "target" | "rel" | "aria-label" | "title" | "id"> & {
|
|
10
|
+
/** Which product app's name to show. The label is always the lowercase app id. */
|
|
11
|
+
app: ProductAppName;
|
|
12
|
+
/** Text font size in px (default 24). The icon is `Math.round(size * 0.875)` px square and the gap is `0.3em`. */
|
|
13
|
+
size?: number;
|
|
14
|
+
/** `false` renders the name only (default `true`). */
|
|
15
|
+
icon?: boolean;
|
|
16
|
+
/** When set, the root is an `<a>` with a focus ring. Otherwise it is a `<span>`. */
|
|
17
|
+
href?: string;
|
|
18
|
+
className?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Icon size relative to the text font size. */
|
|
22
|
+
const ICON_SCALE = 0.875;
|
|
23
|
+
|
|
24
|
+
const FOCUS_RING =
|
|
25
|
+
"rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Marketing wordmark for a product app: the `Icon*` glyph, then the full lowercase name in Instrument Sans
|
|
29
|
+
* (`--font-sans`), weight 500, upright. Needs `landing.css` for `.landing-wordmark-text`.
|
|
30
|
+
* Only the PROJECT V wordmark uses Michroma. App names use no serif and no italic.
|
|
31
|
+
*/
|
|
32
|
+
export function AppWordmark({ app, size = 24, icon = true, href, className, ...rest }: AppWordmarkProps) {
|
|
33
|
+
const Icon = APP_ICONS[app];
|
|
34
|
+
const classes = cn("inline-flex flex-row items-center text-foreground", href && FOCUS_RING, className);
|
|
35
|
+
// Font size sits on the root so the `0.3em` gap tracks the text size. The text node inherits it.
|
|
36
|
+
const style = { fontSize: size, gap: "0.3em" };
|
|
37
|
+
const content = (
|
|
38
|
+
<>
|
|
39
|
+
{icon ? <Icon size={Math.round(size * ICON_SCALE)} /> : null}
|
|
40
|
+
<span className="landing-wordmark-text leading-none">{app}</span>
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
if (href) {
|
|
44
|
+
return (
|
|
45
|
+
<a {...rest} href={href} className={classes} style={style} data-app={app}>
|
|
46
|
+
{content}
|
|
47
|
+
</a>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return (
|
|
51
|
+
<span aria-label={rest["aria-label"]} title={rest.title} id={rest.id} className={classes} style={style} data-app={app}>
|
|
52
|
+
{content}
|
|
53
|
+
</span>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
AppWordmark.displayName = "AppWordmark";
|
package/src/brand/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* Instrument Serif ships only regular (+ italic). Disable faux-bold. */
|
|
2
1
|
.landing-wordmark-text {
|
|
3
|
-
font-family: var(--font-
|
|
4
|
-
font-weight:
|
|
2
|
+
font-family: var(--font-sans);
|
|
3
|
+
font-weight: 500;
|
|
4
|
+
letter-spacing: -0.02em;
|
|
5
5
|
font-synthesis: none;
|
|
6
6
|
}
|
|
7
7
|
|