@cupra/ui-react 2.0.0-canary.264 → 2.0.0-canary.265

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.
Files changed (2) hide show
  1. package/README.md +496 -0
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -0,0 +1,496 @@
1
+ # UI React (React Components)
2
+
3
+ ## Contents
4
+
5
+ - [Overview](#overview)
6
+ - [Audience](#audience)
7
+ - [Requirements & Compatibility](#requirements--compatibility)
8
+ - [TypeScript and module resolution](#typescript-and-module-resolution)
9
+ - [Getting started](#getting-started)
10
+ - [Documentation & Live Playground](#documentation--live-playground)
11
+ - [Breaking Changes & Deprecations](#breaking-changes--deprecations)
12
+ - [Versioning and Release Channels](#versioning-and-release-channels)
13
+ - [Recommended usage](#recommended-usage)
14
+ - [Usage](#usage)
15
+ - [Theme provider props](#theme-provider-props)
16
+ - [Option A — Manual CSS and font links (recommended for performance)](#option-a--manual-css-and-font-links-recommended-for-performance)
17
+ - [Option B — Provider loads assets automatically](#option-b--provider-loads-assets-automatically)
18
+ - [Boolean props](#boolean-props)
19
+ - [Fonts](#fonts)
20
+ - [Icons](#icons)
21
+ - [RTL and internationalization](#rtl-and-internationalization)
22
+ - [License](#license)
23
+ - [Support](#support)
24
+
25
+ ## Overview
26
+
27
+ React components and wrappers built on top of the DS-UI Web Components, providing a seamless and idiomatic developer experience for React.
28
+ This package exposes React-friendly APIs (props, JSX, typed events) while preserving the DS-UI theming, styling, and asset resolution model.
29
+
30
+ ## Audience
31
+
32
+ Use `@cupra/ui-react` if your application is built with **React** and you want:
33
+
34
+ - First-class React ergonomics with DS-UI components
35
+ - Automatic integration with the underlying Web Components
36
+ - Full theming support with minimal configuration
37
+ - A smooth adoption path inside existing React codebases
38
+
39
+ If you need a **framework-agnostic** solution, consider `@cupra/ui-kit` (Web Components).
40
+
41
+ ## Requirements & Compatibility
42
+
43
+ This library provides **official support for React 18 and React 19**.
44
+
45
+ - **Supported React versions:** `>=18.3.1 <20`
46
+
47
+ Projects using other React versions may still install and use the library, but behaviour is not guaranteed.
48
+
49
+ <details>
50
+ <summary>Supported browsers and technical guarantees</summary>
51
+
52
+ This package wraps `@cupra/ui-kit` Web Components, so the same browser/OS support matrix applies:
53
+
54
+ | Platform | Minimum supported version |
55
+ | ----------------- | ---------------------------------------------------- |
56
+ | iOS / iPadOS | 17+ |
57
+ | Android | 13+ |
58
+ | Chrome (desktop) | Current stable version − 1 |
59
+ | Edge (desktop) | Current stable version − 1 |
60
+ | Firefox (desktop) | Current stable version − 1 |
61
+ | Safari (desktop) | Latest version available on supported macOS releases |
62
+
63
+ Any browser/OS version representing more than 1% of total website traffic remains supported even
64
+ if it falls below these versions, until its traffic share drops back under that threshold.
65
+
66
+ The published JavaScript is transpiled to a conservative ES2020 target, but no polyfills are
67
+ shipped for runtime APIs below the versions above, and native support for Custom Elements,
68
+ Shadow DOM and `<slot>` is required.
69
+
70
+ Full rationale, transpilation details and maintenance guide:
71
+ [BROWSER_SUPPORT.md](../../BROWSER_SUPPORT.md) (repository only — not included in the npm package).
72
+
73
+ </details>
74
+
75
+ ## TypeScript and module resolution
76
+
77
+ This library is **bundler-first**.
78
+
79
+ <details open>
80
+ <summary>Subpath imports (recommended)</summary>
81
+
82
+ Importing components via subpaths (for example `@cupra/ui-react/Accordion`) requires
83
+ TypeScript to use **bundler-based module resolution**:
84
+
85
+ - **TypeScript ≥ 5**
86
+ - `"moduleResolution": "bundler"`
87
+
88
+ This matches how modern bundlers resolve modules and enables the best developer experience,
89
+ including proper tree-shaking and code-splitting.
90
+
91
+ Minimal required `tsconfig.json` setting:
92
+
93
+ ```
94
+ {
95
+ "compilerOptions": {
96
+ "moduleResolution": "bundler"
97
+ }
98
+ }
99
+ ```
100
+
101
+ Other compiler options (`target`, `module`, `lib`, etc.) are project-specific and can be configured as needed.
102
+
103
+ </details>
104
+
105
+ <details>
106
+ <summary>Root imports (compatibility mode)</summary>
107
+
108
+ If your project cannot use `moduleResolution: "bundler"`, you can still consume the library using **root imports**:
109
+
110
+ ```
111
+ import { Accordion, IconButton } from "@cupra/ui-react";
112
+ ```
113
+
114
+ This mode works with legacy or constrained TypeScript setups, but has the following trade-offs:
115
+
116
+ - Subpath imports are not available
117
+ - Reduced tree-shaking and chunking opportunities
118
+ - All components are imported from the package entry point
119
+
120
+ Root imports are supported as a fallback, but **subpath imports are recommended whenever possible**.
121
+
122
+ </details>
123
+
124
+ <details>
125
+ <summary>Notes</summary>
126
+
127
+ - Subpath imports are intentionally designed for bundler-based environments.
128
+ - The library does not attempt to enforce Node-style module resolution.
129
+ - No additional runtime configuration is required when using a modern bundler.
130
+
131
+ </details>
132
+
133
+ ## Getting started
134
+
135
+ ### Installation
136
+
137
+ `@cupra/ui-react` is a React wrapper around the Web Components provided by
138
+ `@cupra/ui-kit`.
139
+
140
+ For this reason, **both packages must be installed** in your project.
141
+
142
+ Using npm:
143
+
144
+ ```
145
+ npm install @cupra/ui-react @cupra/ui-kit
146
+ ```
147
+
148
+ Using pnpm:
149
+
150
+ ```
151
+ pnpm add @cupra/ui-react @cupra/ui-kit
152
+ ```
153
+
154
+ Using yarn:
155
+
156
+ ```
157
+ yarn add @cupra/ui-react @cupra/ui-kit
158
+ ```
159
+
160
+ <details>
161
+ <summary>About peer dependencies</summary>
162
+
163
+ `@cupra/ui-kit` is declared as a **peer dependency** of `@cupra/ui-react`.
164
+
165
+ This means:
166
+
167
+ - `@cupra/ui-react` does not bundle or ship the Web Components itself
168
+ - the consuming project must provide a compatible version of `@cupra/ui-kit`
169
+ - only a single instance of the design system is expected at runtime
170
+
171
+ Some package managers (such as npm ≥ 7 or pnpm with compatible settings) may install
172
+ peer dependencies automatically. Others (such as Yarn) require installing them explicitly.
173
+
174
+ If you encounter missing-module or runtime errors after installing `@cupra/ui-react`,
175
+ make sure that `@cupra/ui-kit` is also installed in your project.
176
+
177
+ </details>
178
+
179
+ ## Documentation & Live Playground
180
+
181
+ You can explore all `ui-react` components, their APIs, theming options and live examples
182
+ in the online documentation and playground:
183
+
184
+ https://diagonal.cupra.com/ui-react/index.html
185
+
186
+ ## Breaking Changes & Deprecations
187
+
188
+ Track every breaking change and deprecation, and use the migration helper to safely upgrade between versions:
189
+
190
+ - Breaking changes (merged + upcoming): [https://seatcode.github.io/ds-ui/](https://seatcode.github.io/ds-ui/)
191
+ - Deprecations (forward-looking advisories): [https://seatcode.github.io/ds-ui/deprecations.html](https://seatcode.github.io/ds-ui/deprecations.html)
192
+
193
+ ## Versioning and Release Channels
194
+
195
+ This package is distributed through npm using **two release channels**.
196
+
197
+ <details>
198
+ <summary>Stable releases (latest)</summary>
199
+
200
+ Production-ready versions:
201
+
202
+ - Follow Semantic Versioning
203
+ - Include only validated changes
204
+ - Recommended for all production apps
205
+
206
+ Install:
207
+
208
+ ```
209
+ npm install @cupra/ui-react
210
+ ```
211
+
212
+ Specific version:
213
+
214
+ ```
215
+ npm install @cupra/ui-react@0.1.3
216
+ ```
217
+
218
+ </details>
219
+
220
+ <details>
221
+ <summary>Canary releases (canary)</summary>
222
+
223
+ Early-access versions published after each merge into `main`.
224
+
225
+ Use canary releases if you:
226
+
227
+ - Want to preview upcoming changes
228
+ - Are validating new features
229
+ - Accept small instability or rapid iteration
230
+
231
+ Latest canary:
232
+
233
+ ```
234
+ npm install @cupra/ui-react@canary
235
+ ```
236
+
237
+ Specific canary version:
238
+
239
+ ```
240
+ npm install @cupra/ui-react@0.1.4-canary.2
241
+ ```
242
+
243
+ </details>
244
+
245
+ ## Recommended usage
246
+
247
+ - **Production:** use **stable versions** (for example `@cupra/ui-react@1.1.3`)
248
+ - **Internal testing / preview:** use **canary** versions
249
+
250
+ ## Usage
251
+
252
+ When possible, import components via subpaths:
253
+
254
+ ```
255
+ import { Button } from "@cupra/ui-react/Button";
256
+ ```
257
+
258
+ If your TypeScript setup does not support bundler-based module resolution, use root imports instead:
259
+
260
+ ```
261
+ import { Button } from "@cupra/ui-react";
262
+ ```
263
+
264
+ Wrap your React application with `ThemeProvider`.
265
+
266
+ ### Theme provider props
267
+
268
+ `ThemeProvider` has one required prop, `theme`, and three optional boolean props that turn off what the
269
+ provider loads on its own. Booleans are `false` unless set, so `skip-fonts` and `skip-fonts={true}` are
270
+ equivalent.
271
+
272
+ | Prop | Type | Default | Description |
273
+ | -------------------- | ---------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
274
+ | `theme` | `'cupra-diagonal' \| 'seat'` | none (required) | Visual theme applied to every descendant component. |
275
+ | `skip-fonts` | boolean | `false` | Do not add `fonts.css`, the stylesheet that declares the theme's `@font-face` rules, nor the preloads of the critical font weights. |
276
+ | `skip-styles` | boolean | `false` | Do not add `theme.css`, the stylesheet the `ui-kit` components require. |
277
+ | `skip-unused-styles` | boolean | `false` | Do not add `unused-styles.css`, the theme's `--ds-` tokens that `ui-kit` doesn't consume internally. |
278
+
279
+ `ThemeProvider` forwards its props directly to the underlying `<ds-theme-provider>` Web Component, so
280
+ prop names match its HTML attributes (kebab-case), not idiomatic React camelCase.
281
+
282
+ If you set a `skip-*` prop, you must include the corresponding `<link>` tags yourself, as in Option A.
283
+ The provider renders its children once `theme.css` has loaded.
284
+
285
+ Each theme publishes three stylesheets:
286
+
287
+ - `theme.css` holds everything the `ui-kit` Web Components actually consume. It is always required.
288
+ - `unused-styles.css` holds the rest of the theme's `--ds-` tokens, which no `ui-kit` component consumes
289
+ internally. It only matters if your own CSS reads those raw tokens directly, so it can be omitted or
290
+ deferred otherwise.
291
+ - `fonts.css` holds the theme's `@font-face` rules. See [Fonts](#fonts).
292
+
293
+ ### Option A — Manual CSS and font links (recommended for performance)
294
+
295
+ By default the provider injects the stylesheets at runtime, after JavaScript runs. Serving them yourself
296
+ from the `<head>` avoids that extra round trip, lets the browser discover them earlier and is better for
297
+ performance. Set the three `skip` props and add the files manually, controlling their priority:
298
+
299
+ - `theme.css` as a normal, high-priority stylesheet link (always required).
300
+ - `unused-styles.css` with lower priority, for example with `rel="preload"` and `as="style"`, turned into a
301
+ stylesheet once loaded via `onLoad`, or omitted entirely if you don't read raw tokens. If your own CSS
302
+ does read raw tokens, load it with the same priority as `theme.css`.
303
+ - `fonts.css` as a stylesheet link, plus a preload for each critical font file.
304
+
305
+ This is also the setup for server-side rendering, since no JavaScript is needed to load the assets.
306
+ Replace `[theme]` with `cupra-diagonal` or `seat` and `[version]` with the installed package version.
307
+
308
+ ```
309
+ import { ThemeProvider } from "@cupra/ui-react/ThemeProvider";
310
+ import { Button } from "@cupra/ui-react/Button";
311
+ import { Icon } from "@cupra/ui-react/Icon";
312
+
313
+ export function App() {
314
+ return (
315
+ <>
316
+ {/* One preload per critical font weight, see Fonts below */}
317
+ <link rel="preload" as="font" type="font/woff2" href="https://ds-assets.cupra.com/fonts/[theme]/[font-file].woff2" crossOrigin="anonymous" />
318
+ <link rel="stylesheet" href="https://ds-assets.cupra.com/[version]/styles/[theme]/fonts.css" />
319
+ <link rel="stylesheet" href="https://ds-assets.cupra.com/[version]/styles/[theme]/theme.css" />
320
+ {/* Lower priority; only needed if your own CSS reads raw --ds- tokens directly */}
321
+ <link
322
+ rel="preload"
323
+ as="style"
324
+ href="https://ds-assets.cupra.com/[version]/styles/[theme]/unused-styles.css"
325
+ onLoad={(e) => { e.currentTarget.rel = "stylesheet"; }}
326
+ />
327
+ <ThemeProvider theme="[theme]" skip-fonts skip-styles skip-unused-styles>
328
+ <Button variant="destructive" icon-name="filters-background">
329
+ Click me
330
+ </Button>
331
+ <Icon icon-name="filters-background" />
332
+ </ThemeProvider>
333
+ </>
334
+ );
335
+ }
336
+ ```
337
+
338
+ <details>
339
+ <summary>Keeping files in sync and self-hosting</summary>
340
+
341
+ Keep the three files in sync with the installed package version. To self-host, download the files and
342
+ serve them from your own domain (and the font files they reference):
343
+
344
+ ```bash
345
+ curl -O https://ds-assets.cupra.com/[version]/styles/[theme]/theme.css
346
+ curl -O https://ds-assets.cupra.com/[version]/styles/[theme]/unused-styles.css
347
+ curl -O https://ds-assets.cupra.com/[version]/styles/[theme]/fonts.css
348
+ ```
349
+
350
+ </details>
351
+
352
+ ### Option B — Provider loads assets automatically
353
+
354
+ ```
355
+ import { ThemeProvider } from "@cupra/ui-react/ThemeProvider";
356
+ import { Button } from "@cupra/ui-react/Button";
357
+
358
+ export function App() {
359
+ return (
360
+ <ThemeProvider theme="cupra-diagonal">
361
+ <Button variant="primary">Button</Button>
362
+ </ThemeProvider>
363
+ );
364
+ }
365
+ ```
366
+
367
+ The provider loads `fonts.css`, `theme.css` and `unused-styles.css` from the CDN for the installed
368
+ `@cupra/ui-kit` version.
369
+
370
+ ### Boolean props
371
+
372
+ Boolean props of the wrappers are `false` unless set, on React 18 and on React 19. To turn a behavior
373
+ off, use the matching negative prop (`skip-fonts`, `hide-divider`, `hide-close`...) instead of passing
374
+ `false` to a prop that defaults to `true`. If you are upgrading from an earlier version, see the
375
+ `@cupra/ui-react` changelog for the list of renamed props.
376
+
377
+ ## Fonts
378
+
379
+ Each theme publishes `fonts.css` next to `theme.css`. It only declares the theme's `@font-face` rules
380
+ (woff2, `font-display: fallback`), so the browser downloads just the weights a page renders and only
381
+ swaps the typeface within the first ~3 seconds: later, text doesn't shift. `ThemeProvider` adds it unless
382
+ `skip-fonts` is set; with `skip-fonts`, link it yourself as in Option A. That is also the setup for
383
+ server-side rendering, since no JavaScript is needed to load the fonts.
384
+
385
+ <details>
386
+ <summary>Preloading the critical font weights</summary>
387
+
388
+ **Preload the critical weights.** With `fallback` the browser waits about 100 ms for a font, then shows the
389
+ fallback typeface and swaps to the real one if it arrives within ~3 seconds. After that it keeps the
390
+ fallback for that page view and uses the real one on the next, cached, navigation. Unless `skip-fonts` is
391
+ set, `ThemeProvider` preloads the Regular and Medium weights of the theme next to `fonts.css`, while its
392
+ content waits for `theme.css`. With `skip-fonts` or server-side rendering, add the preloads to your
393
+ `<head>` yourself. Adding them there also helps with `ThemeProvider`: the download starts before the
394
+ JavaScript loads, and the provider skips any preload already present. In Next.js, render the `<link>` in
395
+ the root layout; React 19 hoists it to the `<head>`.
396
+
397
+ ```tsx
398
+ <link
399
+ rel="preload"
400
+ as="font"
401
+ type="font/woff2"
402
+ href="https://ds-assets.cupra.com/fonts/[theme]/[font-file].woff2"
403
+ crossOrigin="anonymous"
404
+ />
405
+ ```
406
+
407
+ - Preload only the weights rendered above the fold, usually Regular and Medium. Every preload competes
408
+ with other critical requests.
409
+ - Keep `crossOrigin`, even on the same origin. Fonts are fetched in CORS mode, and a preload without it
410
+ is not reused: the font downloads twice.
411
+ - The `href` must match the URL in `fonts.css` exactly.
412
+
413
+ </details>
414
+
415
+ <details>
416
+ <summary>Font files per theme</summary>
417
+
418
+ | Theme | `font-family` | Font files (`[font-file]`) |
419
+ | ---------------- | -------------- | ------------------------------------------------------------------------------------------------------------------ |
420
+ | `seat` | `seat` | `SeatBcn-Book` (350), `SeatBcn-Regular` (400), `SeatBcn-Medium` (500), `SeatBcn-Bold` (700), `SeatBcn-Black` (900) |
421
+ | `cupra-diagonal` | `cupra-screen` | `CupraScreen-Light` (300), `CupraScreen-Book` (350), `CupraScreen-Regular` (400), `CupraScreen-Medium` (500) |
422
+
423
+ </details>
424
+
425
+ ## Icons
426
+
427
+ Icons must always be consumed through the `<Icon>` React component — never by loading SVG files directly from the CDN.
428
+
429
+ SVG icon files are stored per-theme under the CDN and are optimised to work with the `Icon` component (they rely on CSS custom properties injected by the component to resolve color and size). Loading them directly as `<img>` tags or via `fetch` bypasses this mechanism and will produce unstyled, incorrectly-colored, or incorrectly-sized output.
430
+
431
+ ```tsx
432
+ // Correct: use Icon
433
+ import { Icon } from '@cupra/ui-react/Icon';
434
+
435
+ <Icon icon-name="arrow-right" />
436
+
437
+ // Wrong: do not load icon SVGs from the CDN directly
438
+ <img src="https://ds-assets.cupra.com/[version]/assets/icons/[theme]/arrow-right.svg" />
439
+ ```
440
+
441
+ ## RTL and internationalization
442
+
443
+ Set `dir` and `lang` on `<html>`; the components follow them. The `cupra` and `seat-legacy` themes have no RTL support. See the `@cupra/ui-kit` README for the full list of what is automatic and what you configure.
444
+
445
+ A form with an email field that stays left to right inside an RTL page:
446
+
447
+ ```tsx
448
+ import { SearchInput } from '@cupra/ui-react/SearchInput';
449
+ import { TextInput } from '@cupra/ui-react/TextInput';
450
+
451
+ export function ContactForm() {
452
+ return (
453
+ <form dir="rtl" lang="ar">
454
+ <TextInput>
455
+ <input dir="auto" name="name" placeholder="الاسم" />
456
+ </TextInput>
457
+
458
+ <TextInput>
459
+ <input dir="ltr" type="email" name="email" placeholder="name@example.com" />
460
+ </TextInput>
461
+
462
+ <SearchInput>
463
+ <input dir="auto" type="text" name="search" placeholder="بحث" />
464
+ </SearchInput>
465
+ </form>
466
+ );
467
+ }
468
+ ```
469
+
470
+ <details>
471
+ <summary>Translating the accessibility texts</summary>
472
+
473
+ The built-in `aria-label` texts have optional `data-aria-label` props. They are plain strings, so they work in React 18 as they are:
474
+
475
+ ```tsx
476
+ import { Calendar } from '@cupra/ui-react/Calendar';
477
+
478
+ <Calendar
479
+ locale="ar"
480
+ data-aria-label="التقويم"
481
+ data-aria-label-previous-month="الشهر السابق"
482
+ data-aria-label-next-month="الشهر التالي"
483
+ />;
484
+ ```
485
+
486
+ </details>
487
+
488
+ ## License
489
+
490
+ SEAT S.A. Library EULA 1.0
491
+ See `LICENSE.md` in this package for the full text.
492
+ Third-party attributions may appear in `THIRD_PARTY_LICENSES.md`.
493
+
494
+ ## Support
495
+
496
+ For help and support, contact: **ds.support@seat.es**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cupra/ui-react",
3
- "version": "2.0.0-canary.264",
3
+ "version": "2.0.0-canary.265",
4
4
  "description": "React components library",
5
5
  "author": "SEAT S.A.",
6
6
  "license": "SEAT S.A. Library EULA 1.0",
@@ -50,7 +50,7 @@
50
50
  }
51
51
  ],
52
52
  "peerDependencies": {
53
- "@cupra/ui-kit": "2.0.0-canary.248",
53
+ "@cupra/ui-kit": "2.0.0-canary.249",
54
54
  "react": ">= 18.3.1 < 20",
55
55
  "react-dom": ">= 18.3.1 < 20",
56
56
  "typescript": ">=5.0.0"
@@ -75,7 +75,7 @@
75
75
  "storybook": "^10.6.2",
76
76
  "typescript": "^5.9.3",
77
77
  "vite": "^8.3.3",
78
- "@cupra/ui-kit": "2.0.0-canary.248"
78
+ "@cupra/ui-kit": "2.0.0-canary.249"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "rm -rf dist && pnpm --filter @cupra/ui-kit build:react && tsc --declaration --emitDeclarationOnly && BUILD_FORMAT=esm vite build --emptyOutDir false && BUILD_FORMAT=cjs vite build --emptyOutDir false",