@podoba/react 0.0.14 → 0.0.15
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/package.json +3 -3
- package/src/components/brand-page-header.tsx +1 -1
- package/src/components/context-menu.tsx +2 -2
- package/src/components/cta-pill.tsx +36 -0
- package/src/components/stats-card.tsx +1 -1
- package/src/components/subtle.tsx +21 -0
- package/src/components/tile.tsx +1 -1
- package/src/index.ts +2 -0
- package/src/layout/card.tsx +2 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@podoba/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "podoba React components — React Aria Components + Tailwind primitives + layout, built with uic.",
|
|
6
6
|
"repository": {
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"typecheck": "tsc --build"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@podoba/tokens": "^0.0.
|
|
29
|
-
"@podoba/tailwind": "^0.0.
|
|
28
|
+
"@podoba/tokens": "^0.0.15",
|
|
29
|
+
"@podoba/tailwind": "^0.0.15",
|
|
30
30
|
"react-aria-components": "1.18.0",
|
|
31
31
|
"class-variance-authority": "0.7.1",
|
|
32
32
|
"clsx": "2.1.1",
|
|
@@ -116,7 +116,7 @@ export function BrandPageHeader({
|
|
|
116
116
|
))}
|
|
117
117
|
</nav>
|
|
118
118
|
) : null}
|
|
119
|
-
<h1 className="text-display font-medium leading-[1.12] tracking-
|
|
119
|
+
<h1 className="text-display font-medium leading-[1.12] tracking-wide text-fg">
|
|
120
120
|
{parentLink ? (
|
|
121
121
|
// gs "title to go back": muted clickable parent line above the title.
|
|
122
122
|
// `[&_a]` styles the nested router <Link> (anchor) without @app/ui
|
|
@@ -126,7 +126,7 @@ const MenuItem = uic(RACMenuItem, {
|
|
|
126
126
|
// gs `.panel`: 258px, radius 12px, 8px/6px padding, 180deg #242424→#1f1f1f
|
|
127
127
|
// gradient, 0 12px 28px rgba(0,0,0,.22) shadow. No token covers the gradient/shadow.
|
|
128
128
|
const panelClass =
|
|
129
|
-
'w-[258px] max-w-[calc(100vw-16px)] rounded-
|
|
129
|
+
'w-[258px] max-w-[calc(100vw-16px)] rounded-lg bg-gradient-to-b from-[#242424] to-[#1f1f1f] ' +
|
|
130
130
|
'px-1.5 py-2 shadow-[0_12px_28px_rgba(0,0,0,0.22)] outline-none'
|
|
131
131
|
const menuClass = 'grid max-h-[calc(100vh-16px)] gap-0.5 overflow-y-auto outline-none'
|
|
132
132
|
|
|
@@ -178,7 +178,7 @@ function ContextMenuBody({
|
|
|
178
178
|
<span className="min-w-0 flex-1 truncate">{item.label}</span>
|
|
179
179
|
{badge ? (
|
|
180
180
|
// gs `.badge`: 24px pill, #333437 bg / #c8c8ca text, 10px (text-micro).
|
|
181
|
-
<span className="ml-auto inline-flex h-6 items-center justify-center rounded-full bg-[#333437] px-3 py-0.5 text-micro font-medium leading-5 tracking-
|
|
181
|
+
<span className="ml-auto inline-flex h-6 items-center justify-center rounded-full bg-[#333437] px-3 py-0.5 text-micro font-medium leading-5 tracking-tight text-[#c8c8ca]">
|
|
182
182
|
{badge}
|
|
183
183
|
</span>
|
|
184
184
|
) : null}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CtaPill — the gs Brand Core hero CTA: a GS-green bar reading "Let's create
|
|
5
|
+
* something" (the middle word emphasised) with an action control on the right.
|
|
6
|
+
*
|
|
7
|
+
* The copy is three fragments (`lead` · `emphasis` · `tail`) so a consumer can
|
|
8
|
+
* translate each per-locale while keeping the middle-word highlight. Presentational
|
|
9
|
+
* only (hard rule #1): every string arrives via props — no i18n, no domain data.
|
|
10
|
+
*
|
|
11
|
+
* a11y NOTE: the background is the light brand-green (#6eddb1); the emphasised word is
|
|
12
|
+
* rendered WHITE per the gs design — white-on-green is ~1.66:1, below WCAG AA, so it
|
|
13
|
+
* reads as a decorative highlight (it also carries a bold weight), not load-bearing
|
|
14
|
+
* copy. The surrounding text stays on the dark `fg` (~10:1).
|
|
15
|
+
*/
|
|
16
|
+
export interface CtaPillProps {
|
|
17
|
+
/** Regular lead-in before the emphasised word (e.g. "Let's"). */
|
|
18
|
+
lead: ReactNode
|
|
19
|
+
/** The emphasised bold, white middle word (e.g. "create"). */
|
|
20
|
+
emphasis: ReactNode
|
|
21
|
+
/** Regular trailing text after the emphasis (e.g. "something"). */
|
|
22
|
+
tail: ReactNode
|
|
23
|
+
/** Right-side action control (e.g. a Create button). */
|
|
24
|
+
children: ReactNode
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function CtaPill({ lead, emphasis, tail, children }: CtaPillProps) {
|
|
28
|
+
return (
|
|
29
|
+
<div className="flex min-w-[560px] items-center justify-between gap-4 rounded-lg bg-brand-secondary px-6 py-4">
|
|
30
|
+
<p className="text-subtitle font-medium leading-[22px] tracking-normal text-fg">
|
|
31
|
+
{lead} <span className="font-semibold text-white">{emphasis}</span> {tail}
|
|
32
|
+
</p>
|
|
33
|
+
<div className="shrink-0">{children}</div>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -85,7 +85,7 @@ function StatsCardBody({
|
|
|
85
85
|
* `-0.02em` (`AssetsTile.module.scss .count`).
|
|
86
86
|
*/}
|
|
87
87
|
<span
|
|
88
|
-
className={`flex flex-1 items-center text-[1.875rem] font-medium leading-[2rem] ${dark ? 'tracking-
|
|
88
|
+
className={`flex flex-1 items-center text-[1.875rem] font-medium leading-[2rem] ${dark ? 'tracking-normal text-white' : 'tracking-wide text-fg'}`}
|
|
89
89
|
>
|
|
90
90
|
{value}
|
|
91
91
|
</span>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Subtle — inline de-emphasised text (the light `fg-subtle` grey, #b3b3b3). Wraps its
|
|
5
|
+
* children in a `text-fg-subtle` span; anything OUTSIDE it stays at the surrounding
|
|
6
|
+
* full-contrast `fg`. Compose it freely to two-tone arbitrary runs of a line — unlike
|
|
7
|
+
* a fixed-slot header it handles mid-line emphasis in ANY order and ANY language:
|
|
8
|
+
*
|
|
9
|
+
* <h1>
|
|
10
|
+
* <Subtle>Good afternoon</Subtle> {name} 👋
|
|
11
|
+
* <br />
|
|
12
|
+
* <Subtle>You have</Subtle> {count} planned tasks <Subtle>today</Subtle>
|
|
13
|
+
* </h1>
|
|
14
|
+
*
|
|
15
|
+
* With i18n, put the `<subtle>…</subtle>` runs INSIDE the translation string and render
|
|
16
|
+
* it via `<Trans components={{ subtle: <Subtle /> }} />`, so each locale places the
|
|
17
|
+
* emphasis where its own word order needs it. Presentational only (hard rule #1).
|
|
18
|
+
*/
|
|
19
|
+
export function Subtle({ children }: { children: ReactNode }) {
|
|
20
|
+
return <span className="text-fg-subtle">{children}</span>
|
|
21
|
+
}
|
package/src/components/tile.tsx
CHANGED
|
@@ -64,7 +64,7 @@ function TileBody({ head, children, tail }: Pick<TileProps, 'head' | 'children'
|
|
|
64
64
|
)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const baseSurface = 'flex h-full min-h-[200px] flex-col gap-6 rounded-
|
|
67
|
+
const baseSurface = 'flex h-full min-h-[200px] flex-col gap-6 rounded-lg p-6'
|
|
68
68
|
|
|
69
69
|
export function Tile({ theme = 'light', head, children, tail, link, className }: TileProps) {
|
|
70
70
|
const surface = [baseSurface, THEME[theme], className].filter(Boolean).join(' ')
|
package/src/index.ts
CHANGED
|
@@ -52,6 +52,8 @@ export * from "./layout/persistent-page-shell";
|
|
|
52
52
|
|
|
53
53
|
// --- product patterns (label-driven; no domain coupling) ---
|
|
54
54
|
export * from "./components/brand-page-header";
|
|
55
|
+
export * from "./components/cta-pill";
|
|
56
|
+
export * from "./components/subtle";
|
|
55
57
|
export * from "./components/stats-card";
|
|
56
58
|
export * from "./components/tile";
|
|
57
59
|
export * from "./components/dashboard-grid";
|
package/src/layout/card.tsx
CHANGED
|
@@ -4,9 +4,8 @@ import { uic } from '../utils/uic'
|
|
|
4
4
|
* Card — surface panel (port of gs-manager's `Card`).
|
|
5
5
|
*
|
|
6
6
|
* gs SCSS → our tokens (Tailwind + `@app/tokens` CSS vars, no SCSS — hard rule #3):
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
9
|
-
* used `--radius-lg`, so this maps to `rounded-lg`.
|
|
7
|
+
* - `rounded-lg` (`--radius-lg` = 0.5rem = 8px) — the single unified card/panel
|
|
8
|
+
* radius across the design system (the old 1.1rem soft-panel radius was retired).
|
|
10
9
|
* - `--color-background-secondary` (the light card fill) → `bg-surface-card`
|
|
11
10
|
* (our `--color-surface-card` = #f7f6f2).
|
|
12
11
|
* - `outlined` → 1px `--color-border` (#eceae1) → `border border-border`.
|