KIR-610 membership card, glass sheet#79
Conversation
Co-authored-by: Claude <claude@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Introduces PEK Design System (PDS) v4 foundations (tokens, typography, glass effects) and new UI primitives/components (membership card, user avatar, sheet styling), along with Storybook wiring and a new dev dependency for React diagnostics.
Changes:
- Add PDS v4 theme tokens + glass utilities in global styles, and wire new design-system components with Storybook stories.
- Refactor some existing UI components (Button/Card) and align class ordering/formatting across routes/devtools/header.
- Add
react-doctortooling and extend Biome configuration to include Storybook and sorted-class linting.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| package-lock.json | Locks new dependency graph (notably react-doctor and transitive deps). |
| full-stack/package.json | Adds react-doctor dev dependency. |
| full-stack/react-doctor.config.json | Configures react-doctor ignores for generated/ui code. |
| full-stack/tsconfig.json | Adds @pds4/* path alias for design-system imports. |
| full-stack/src/styles.css | Introduces PDS v4 tokens, spacing variables, glass utilities, and theme selector changes. |
| full-stack/src/routes/user/profile.tsx | Minor className ordering/formatting changes. |
| full-stack/src/routes/index.tsx | Minor className ordering/formatting changes across landing page UI. |
| full-stack/src/devtools/tanstack-store.devtools.tsx | Minor className ordering/formatting changes in devtool panel. |
| full-stack/src/components/ui/card.tsx | Maps CardTitle/CardDescription to PDS typography components. |
| full-stack/src/components/ui/button.tsx | Updates button variants/sizing and ring behavior. |
| full-stack/src/components/header.tsx | Minor className ordering/formatting changes. |
| full-stack/src/components/design-system/user-avatar.tsx | Adds tiered avatar component with badge rendering. |
| full-stack/src/components/design-system/user-avatar.stories.tsx | Adds Storybook stories for avatar variants/sizes. |
| full-stack/src/components/design-system/typography.tsx | Adds PDS typography primitives (Title/Subtitle/Text/Paragraph/Detail). |
| full-stack/src/components/design-system/typography.stories.tsx | Adds Storybook stories showcasing typography scale. |
| full-stack/src/components/design-system/sheet.tsx | Adds design-system wrappers for Sheet content/header/description with glass styling. |
| full-stack/src/components/design-system/sheet.stories.tsx | Adds Storybook stories for sheet placements/variants. |
| full-stack/src/components/design-system/membership-card.tsx | Adds membership card component with tier styling and inline activity affordance. |
| full-stack/src/components/design-system/membership-card.stories.tsx | Adds Storybook stories for membership-card variants. |
| full-stack/biome.json | Expands Biome include globs to cover .storybook. |
| full-stack/.storybook/preview.tsx | Wraps stories with TooltipProvider and imports global styles. |
| biome.json | Enables Biome useSortedClasses nursery rule (with custom options). |
|
|
||
| const buttonVariants = cva( | ||
| "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", | ||
| "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", |
There was a problem hiding this comment.
focus-visible:ring-3 / aria-invalid:ring-3 are likely invalid Tailwind utilities (the codebase elsewhere uses ring-[3px]). As-is, focus/invalid rings may not render. Consider reverting to ring-[3px] (or adding a theme ringWidth=3 and using ring-3 consistently).
| "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", | |
| "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", |
| 'relative flex min-h-fit min-w-fit cursor-pointer items-center rounded-2xl p-card!', | ||
| 'bg-muted/40! opacity-70 transition-opacity duration-fast', |
There was a problem hiding this comment.
Tailwind’s important modifier uses a ! prefix (e.g. !p-card, !bg-muted/40), not a suffix. p-card! / bg-muted/40! won’t be recognized, so the intended overrides won’t apply.
| 'relative flex min-h-fit min-w-fit cursor-pointer items-center rounded-2xl p-card!', | |
| 'bg-muted/40! opacity-70 transition-opacity duration-fast', | |
| 'relative flex min-h-fit min-w-fit cursor-pointer items-center rounded-2xl !p-card', | |
| '!bg-muted/40 opacity-70 transition-opacity duration-fast', |
| export interface UserAvatarProps extends ComponentProps<typeof Avatar> { | ||
| tier?: UserAvatarTier; | ||
| size?: UserAvatarSize; | ||
| showBadge?: boolean; | ||
| children?: React.ReactNode; | ||
| } |
There was a problem hiding this comment.
children?: React.ReactNode references the React namespace, but this file only imports ComponentProps from react. This will fail type-checking unless React is globally available. Prefer importing type ReactNode from react and using children?: ReactNode (or rely on ComponentProps<typeof Avatar>’s existing children typing).
| 'ring-4 data-[size=lg]:ring-6 data-[size=sm]:ring-2', | ||
| 'ring-transparent data-[tier=active]:ring-tier-3-start data-[tier=inactive]:ring-tier-inactive data-[tier=tier-1]:ring-tier-1-start data-[tier=tier-2]:ring-tier-2-start', | ||
| // Size styling | ||
| 'data-[size=default]:size-30 data-[size=lg]:size-50 data-[size=sm]:size-10', |
There was a problem hiding this comment.
These size/ring utilities (ring-6, size-30, size-50) are not in Tailwind’s default scale, so they likely won’t generate any CSS. Use supported scale values (e.g. ring-8, size-8/10/...) or switch to arbitrary values like ring-[6px] / size-[7.5rem] if custom sizing is intended.
| 'ring-4 data-[size=lg]:ring-6 data-[size=sm]:ring-2', | |
| 'ring-transparent data-[tier=active]:ring-tier-3-start data-[tier=inactive]:ring-tier-inactive data-[tier=tier-1]:ring-tier-1-start data-[tier=tier-2]:ring-tier-2-start', | |
| // Size styling | |
| 'data-[size=default]:size-30 data-[size=lg]:size-50 data-[size=sm]:size-10', | |
| 'ring-4 data-[size=lg]:ring-[6px] data-[size=sm]:ring-2', | |
| 'ring-transparent data-[tier=active]:ring-tier-3-start data-[tier=inactive]:ring-tier-inactive data-[tier=tier-1]:ring-tier-1-start data-[tier=tier-2]:ring-tier-2-start', | |
| // Size styling | |
| 'data-[size=default]:size-[7.5rem] data-[size=lg]:size-[12.5rem] data-[size=sm]:size-10', |
| 'data-[size=sm]:text-xs', | ||
| 'data-[size=lg]:text-3xl', |
There was a problem hiding this comment.
data-[size=sm]:... / data-[size=lg]:... on UserAvatarFallback won’t take effect because data-size is set on the parent Avatar, not on the fallback element itself. Use group-data-[size=...]/avatar:... (matching ui/avatar.tsx) or pass the size down as a data attribute to the fallback.
| 'data-[size=sm]:text-xs', | |
| 'data-[size=lg]:text-3xl', | |
| 'group-data-[size=sm]/avatar:text-xs', | |
| 'group-data-[size=lg]/avatar:text-3xl', |
| groupAvatarFallback: 'SS', | ||
| roles: 'körvezeto, gazdaságis', | ||
| membershipType: 'TAG', | ||
| startDate: '2020 mar', |
There was a problem hiding this comment.
baseProps includes props that MembershipCard doesn’t accept (groupAvatarFallback, membershipType, startDate). This will cause TS errors in Storybook. Either add these props to MembershipCard (and use them) or remove them from the stories.
| groupAvatarFallback: 'SS', | |
| roles: 'körvezeto, gazdaságis', | |
| membershipType: 'TAG', | |
| startDate: '2020 mar', | |
| roles: 'körvezeto, gazdaságis', |
| @import "@fontsource-variable/geist"; | ||
|
|
||
| @custom-variant dark (&:is(.dark *)); | ||
| @custom-variant dark (&:is([data-theme="dark"] *)); |
There was a problem hiding this comment.
This changes the dark: variant to depend on [data-theme="dark"], but the codebase still uses .dark as the dark selector (e.g. src/components/ui/chart.tsx has dark: ".dark"). Unless the app sets data-theme everywhere, existing dark: styles will stop applying. Consider supporting both selectors (or keep .dark and introduce a separate theme selector).
| @custom-variant dark (&:is([data-theme="dark"] *)); | |
| @custom-variant dark (&:is([data-theme="dark"] *, .dark *)); |
| "attributes": ["classList"], | ||
| "functions": ["clsx", "cva", "tw", "tw.*"] |
There was a problem hiding this comment.
useSortedClasses is configured to only look at classList attributes and clsx/cva/tw functions, but this repo predominantly uses className and the cn(...) helper. As configured, the rule likely won’t run on most JSX. Consider adding className to attributes and cn to functions (or document why it’s intentionally limited).
| "attributes": ["classList"], | |
| "functions": ["clsx", "cva", "tw", "tw.*"] | |
| "attributes": ["classList", "className"], | |
| "functions": ["clsx", "cva", "tw", "tw.*", "cn"] |
No description provided.