@grupo-elo-editorial/shared-ui-react 1.0.0 → 1.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,99 @@
1
+ # Changelog — `@grupo-elo-editorial/shared-ui-react`
2
+
3
+ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning: [SemVer](https://semver.org/spec/v2.0.0.html).
4
+
5
+ ---
6
+
7
+ ## [1.2.0] — 2026-05-24 (HeroCarousel aspect ratios + RSC compatibility)
8
+
9
+ ### Fixed
10
+
11
+ - **`TopAccessibilityBar`**: the bar background was `var(--background)` — identical to the page background, so the bar blended in and visually disappeared. The "Ferramentas de Acessibilidade" label was also hidden below the `md:` (768px) breakpoint. Switched the bar to `var(--card)` so it sits on the elevated surface (matching the mockup), and dropped the label breakpoint from `md:` to `sm:` (640px) so the label is visible on most desktops/tablets, hiding only on narrow phones.
12
+
13
+ - **`Footer`**: the catalog navigation column had two entries pointing to the same `href` (`/livros/catalogo` for both "Livros" and "Mais Vendidos"), and the `<li>` `map` used `key={link.href}` — triggering a React duplicate-key warning on every render. Switched the key to `link.label` (unique within a column) and made "Mais Vendidos" point to `/livros/catalogo?ordem=mais_vendidos`. Also redirected "Lançamentos" from the non-existent `/lancamentos` route to `/livros/catalogo?ordem=recentes`, so the link now lands on the catalog with the right sort applied instead of 404'ing.
14
+
15
+ - **`HeroCarousel`**: the `<img>` aspect ratio was `aspect-[3/4] md:aspect-video` for every breakpoint ≥768px. On desktop this produced a ~720px-tall hero in a 1280px viewport — significantly taller than the mockup (440px) and mismatched against the panoramic desktop banner artwork specified by the site-multibrand PRD (F3 — desktop 1920×700, ratio ~2.74:1). Updated to `aspect-[5/6] md:aspect-video lg:aspect-[1920/700]`, which now matches the PRD-specified artwork dimensions at each breakpoint: mobile 750×900, tablet 1024×576, desktop 1920×700.
16
+
17
+ - **React Server Components compatibility**: six components used React hooks (`useState`, `useEffect`) without a `'use client'` directive. When consumed from npm as built `dist/` they worked because Vite preserved the runtime behavior, but when resolved via the `development` export condition to the raw `src/` (e.g. when linked into a Next.js App Router project from the workspace) they failed with *"You're importing a component that needs `useState`. This React Hook only works in a Client Component."* Added `'use client'` to:
18
+ - `atoms/Avatar.tsx`
19
+ - `atoms/Rating.tsx`
20
+ - `figma/ImageWithFallback.tsx`
21
+ - `molecules/SearchBar.tsx`
22
+ - `prd/HeroCarousel.tsx`
23
+ - `prd/TopAccessibilityBar.tsx`
24
+
25
+ Other client components (`prd/Footer.tsx`, `prd/MegaMenu.tsx`, plus the `ui/` Radix wrappers) already had the directive.
26
+
27
+ ### Migration
28
+
29
+ No API change. Consumers passing custom `className` to `<HeroCarousel>` continue to work as before. Visual change only — the hero will be shorter on desktop and slightly less tall on mobile. If a consumer was depending on the previous heights, override via `className` on the wrapper to constrain max-height.
30
+
31
+ ### Changed
32
+
33
+ - `package.json` `version` bumped `1.1.0 → 1.2.0`.
34
+
35
+ ---
36
+
37
+ ## [1.1.0] — 2026-05-20 (Layout primitives + Figma shared-ui sync)
38
+
39
+ Additive sync with the upstream Figma shared-ui file (`q4V5CYymU4oU5nlbbHNmh8`) and with `@grupo-elo-editorial/design-tokens@3.1.0`. No breaking changes; consumers of `^1.0.0` can bump to `^1.1.0` with zero code changes.
40
+
41
+ ### Added — Layout primitives
42
+
43
+ Three new layout components that consume the breakpoint/container/grid tokens introduced in `design-tokens@3.1.0`:
44
+
45
+ - **`Container`** — page-level wrapper. Centers content within `var(--container-max)` (1280px) with responsive `var(--container-px)` (1.5rem) horizontal padding. Polymorphic via the `as` prop (defaults to `'div'`).
46
+ - **`Grid`** — responsive grid primitive. Default progression: `grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4` with `gap-[var(--grid-gutter)]` (1.5rem). Override via `className`.
47
+ - **`Col`** — grid cell with explicit column span (1–6). Always includes `min-w-0` to prevent overflow on wide content (long text, large images) — addresses the implicit `min-width: auto` gotcha on grid items.
48
+
49
+ ```tsx
50
+ import { Container, Grid, Col } from '@grupo-elo-editorial/shared-ui-react';
51
+
52
+ <Container as="section">
53
+ <Grid>
54
+ <Col><ProductCard ... /></Col>
55
+ <Col><ProductCard ... /></Col>
56
+ <Col span={2}>Wide cell</Col>
57
+ </Grid>
58
+ </Container>
59
+ ```
60
+
61
+ ### Added — docs
62
+
63
+ - `docs/SHARED_UI_STANDARDS.md` — prescriptive guide for the package: filosofia, naming conventions, design tokens, A11y WCAG 2.2 AA, estados de componentes, props API, composição, testes, performance, checklist de qualidade, versionamento.
64
+
65
+ ### Changed
66
+
67
+ - `package.json` `version` bumped `1.0.0 → 1.1.0`.
68
+ - `package.json` `description` updated to mention layout primitives + new `design-tokens@^3.1.0` minimum.
69
+ - `src/index.ts` now re-exports `Container`, `Grid`, `Col` (and their `ContainerProps`/`GridProps`/`ColProps` types) from `./components/layout`.
70
+ - `repository.url` now uses canonical `git+https://` scheme (eliminates `npm publish` warning).
71
+
72
+ ### Compat with design-tokens v3.1.0
73
+
74
+ `@grupo-elo-editorial/design-tokens@^3.1.0` is the minimum effective dependency now (the layout primitives use `var(--container-max)`, `var(--container-px)`, and `var(--grid-gutter)` which were introduced in 3.1.0). Older 3.0.x of design-tokens still works for everything _except_ the layout primitives, which will render with browser-default sizing if the consumer hasn't bumped design-tokens.
75
+
76
+ ---
77
+
78
+ ## [1.0.0] — 2026-05-13 (Initial release — port from Figma)
79
+
80
+ First public release. 42 components ported 1:1 from the Figma Make export `loEUZ5dnW0f4e8GwQIEWSz`.
81
+
82
+ ### Added
83
+
84
+ - **7 custom atoms**: Button, Textarea, Badge, Avatar, Spinner, Divider, Rating
85
+ - **5 custom molecules**: ProductCard, SearchBar, PriceDisplay, QuantitySelector, FormGroup
86
+ - **4 custom organisms**: Hero, EmptyState, ErrorState, ProductGrid
87
+ - **2 PRD domain components**: TopAccessibilityBar, HeroCarousel
88
+ - **~50 shadcn/ui primitives** in `components/ui/` — Radix wrappers (Dialog, Sheet, Select, Tooltip, Accordion, Checkbox, Switch, RadioGroup, Breadcrumb, Progress, Calendar, Carousel, Chart, Command, ContextMenu, Drawer, DropdownMenu, Form, HoverCard, InputOTP, Menubar, NavigationMenu, Pagination, Popover, Resizable, ScrollArea, Separator, Sidebar, Skeleton, Slider, Sonner, Table, Tabs, ToggleGroup, …).
89
+ - **Re-exports** from atoms/molecules/organisms barrels: `Input`, `Select*`, `Checkbox`, `RadioGroup*`, `Toggle (= Switch)`, `Breadcrumb*`, `Accordion*`, `Tooltip*`, `ProgressBar`, `toast (sonner)`, `Modal (= Dialog)`, `Drawer (= Sheet)`.
90
+ - **`figma/ImageWithFallback`** helper.
91
+ - **Util**: `cn` (clsx + tailwind-merge).
92
+ - **Bundled CSS**: `dist/style.css` (96 kB, gzip 9 kB) — Lato fonts + Tailwind v4 + multibrand theme tokens with `[data-brand]` / `[data-theme]` selectors (aligned with `@grupo-elo-editorial/design-tokens@^3.0.0`).
93
+ - **Docs imported from Figma**: `docs/COMPONENT_LIBRARY.md`, `docs/CORRECTIONS.md`, `docs/GUIDELINES.md`.
94
+
95
+ ### Notes
96
+
97
+ - Stack: React 18+/19, TypeScript, Tailwind CSS v4, Radix UI, Lucide icons, Sonner toasts, `class-variance-authority` for variants.
98
+ - Brand + theme contract: `<html data-brand="elo-editora|perabook" data-theme="light|dark">` — same as design-tokens.
99
+ - The Figma export used `.brand-elo` / `.brand-pera` / `.dark` class selectors; this port adapted to `[data-brand]` / `[data-theme]` attribute selectors to match the design-tokens v3 contract. Component code consumes `var(--brand-*)` so the visual result is identical.
@@ -0,0 +1,29 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface ColProps {
3
+ children: ReactNode;
4
+ /**
5
+ * How many grid columns this cell spans (1–6). When omitted, the cell takes
6
+ * one column at every breakpoint.
7
+ */
8
+ span?: 1 | 2 | 3 | 4 | 5 | 6;
9
+ className?: string;
10
+ }
11
+ /**
12
+ * Grid cell with explicit column span. Always includes `min-w-0` to prevent
13
+ * grid items from overflowing when their content (long text, large images) is
14
+ * wider than the available column — without this the implicit `min-width: auto`
15
+ * on grid items would push the cell beyond its grid track.
16
+ *
17
+ * Use inside `<Grid>`. Not strictly required (you can use a plain `<div>` for
18
+ * 1-column cells), but recommended for any cell that spans multiple columns.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <Grid>
23
+ * <Col span={2}>Wide cell</Col>
24
+ * <Col>Standard cell</Col>
25
+ * <Col>Standard cell</Col>
26
+ * </Grid>
27
+ * ```
28
+ */
29
+ export declare function Col({ children, span, className }: ColProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { type ElementType, type ReactNode } from 'react';
2
+ export interface ContainerProps {
3
+ children: ReactNode;
4
+ /** Override the wrapper element. Default `'div'`. */
5
+ as?: ElementType;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * Page-level content wrapper. Centers content within `var(--container-max)`
10
+ * (1280px by default in `@grupo-elo-editorial/design-tokens@^3.1.0`) and applies
11
+ * the responsive `var(--container-px)` horizontal padding.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <Container as="section">
16
+ * <h2>Section heading</h2>
17
+ * <p>Body content stays within the centered, padded container.</p>
18
+ * </Container>
19
+ * ```
20
+ */
21
+ export declare function Container({ children, as: Tag, className }: ContainerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface GridProps {
3
+ children: ReactNode;
4
+ /**
5
+ * Override the default responsive column progression
6
+ * (`grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4`) by appending Tailwind utility classes here.
7
+ */
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Responsive grid primitive. Defaults to the progression defined by the
12
+ * `--grid-cols-{default,sm,md,lg}` tokens (1 → 2 → 3 → 4 columns) and the
13
+ * `--grid-gutter` (1.5rem) gap, both shipped by
14
+ * `@grupo-elo-editorial/design-tokens@^3.1.0`.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * <Grid>
19
+ * <Col><ProductCard ... /></Col>
20
+ * <Col><ProductCard ... /></Col>
21
+ * </Grid>
22
+ * ```
23
+ */
24
+ export declare function Grid({ children, className }: GridProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ export { Container } from './Container';
2
+ export type { ContainerProps } from './Container';
3
+ export { Grid } from './Grid';
4
+ export type { GridProps } from './Grid';
5
+ export { Col } from './Col';
6
+ export type { ColProps } from './Col';
@@ -2,6 +2,7 @@ import { HTMLAttributes } from 'react';
2
2
  export interface ProductCardProps extends HTMLAttributes<HTMLDivElement> {
3
3
  image: string;
4
4
  title: string;
5
+ author?: string;
5
6
  price: number;
6
7
  originalPrice?: number;
7
8
  rating?: number;
@@ -13,6 +14,10 @@ export interface ProductCardProps extends HTMLAttributes<HTMLDivElement> {
13
14
  onAddToCart?: () => void;
14
15
  onToggleFavorite?: () => void;
15
16
  isFavorite?: boolean;
17
+ /** Makes the card image and title clickable as a link. */
18
+ href?: string;
19
+ /** 'vertical' (default) stacks image above content; 'horizontal' places a compact image to the left. */
20
+ orientation?: 'vertical' | 'horizontal';
16
21
  }
17
22
  declare const ProductCard: import("react").ForwardRefExoticComponent<ProductCardProps & import("react").RefAttributes<HTMLDivElement>>;
18
23
  export { ProductCard };
@@ -0,0 +1,10 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface FooterProps extends HTMLAttributes<HTMLElement> {
3
+ brand?: 'elo-editora' | 'perabook';
4
+ onNewsletterSubmit?: (email: string) => void;
5
+ }
6
+ declare const Footer: {
7
+ ({ brand, onNewsletterSubmit, className, ...props }: FooterProps): import("react/jsx-runtime").JSX.Element;
8
+ displayName: string;
9
+ };
10
+ export { Footer };
@@ -0,0 +1,16 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface NavItem {
3
+ id: string;
4
+ label: string;
5
+ href?: string;
6
+ children?: NavItem[];
7
+ }
8
+ export interface MegaMenuProps extends HTMLAttributes<HTMLElement> {
9
+ items: NavItem[];
10
+ logo?: React.ReactNode;
11
+ rightSlot?: React.ReactNode;
12
+ searchSlot?: React.ReactNode;
13
+ drawerFooter?: React.ReactNode;
14
+ }
15
+ declare const MegaMenu: import("react").ForwardRefExoticComponent<MegaMenuProps & import("react").RefAttributes<HTMLElement>>;
16
+ export { MegaMenu };
@@ -2,6 +2,7 @@ import { HTMLAttributes } from 'react';
2
2
  export interface TopAccessibilityBarProps extends HTMLAttributes<HTMLDivElement> {
3
3
  onThemeChange?: (theme: 'light' | 'dark') => void;
4
4
  onFontSizeChange?: (size: number) => void;
5
+ showA11yLink?: boolean;
5
6
  }
6
7
  declare const TopAccessibilityBar: import("react").ForwardRefExoticComponent<TopAccessibilityBarProps & import("react").RefAttributes<HTMLDivElement>>;
7
8
  export { TopAccessibilityBar };
@@ -2,3 +2,7 @@ export { TopAccessibilityBar } from './TopAccessibilityBar';
2
2
  export type { TopAccessibilityBarProps } from './TopAccessibilityBar';
3
3
  export { HeroCarousel } from './HeroCarousel';
4
4
  export type { HeroCarouselProps, HeroSlide } from './HeroCarousel';
5
+ export { MegaMenu } from './MegaMenu';
6
+ export type { MegaMenuProps, NavItem } from './MegaMenu';
7
+ export { Footer } from './Footer';
8
+ export type { FooterProps } from './Footer';
package/dist/index.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from './components/atoms';
3
3
  export * from './components/molecules';
4
4
  export * from './components/organisms';
5
5
  export * from './components/prd';
6
+ export * from './components/layout';
6
7
  export { cn } from './components/ui/utils';