webs-sdk 0.19.64 → 0.19.66
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/AGENTS.md +44 -0
- package/CLAUDE.md +80 -0
- package/README.md +513 -490
- package/dist/components/ARFilters/ARFilters.js +54 -54
- package/dist/components/ArtGenerator.js +141 -141
- package/dist/components/AvatarAI.js +14 -14
- package/dist/components/CookieConsent/constants.js +31 -31
- package/dist/components/CreativeFaceSwap.js +23 -23
- package/dist/components/GifsIa.js +76 -76
- package/dist/components/MemeGenerator.js +12 -12
- package/dist/components/PasswordReset/constants.js +33 -33
- package/dist/components/RecoveryPassword/constants.js +27 -27
- package/dist/components/SpinningWheel/SpinningWheel.js +7 -7
- package/dist/components/SpinningWheel/index.d.ts +1 -1
- package/dist/components/SpinningWheel/index.d.ts.map +1 -1
- package/dist/components/SpinningWheel/index.js +2 -1
- package/dist/components/SpinningWheel/index.js.map +1 -1
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts +49 -0
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts.map +1 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js +122 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js.map +1 -0
- package/dist/components/ui/badge.d.ts +1 -0
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/compose-refs.d.ts +6 -0
- package/dist/components/ui/compose-refs.d.ts.map +1 -0
- package/dist/components/ui/compose-refs.js +57 -0
- package/dist/components/ui/compose-refs.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +3 -1
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +2 -2
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/index.d.ts +2 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +2 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/components/ui/media-player.d.ts +127 -0
- package/dist/components/ui/media-player.d.ts.map +1 -0
- package/dist/components/ui/media-player.js +1633 -0
- package/dist/components/ui/media-player.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +3 -1
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +2 -2
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/ui/use-lazy-ref.d.ts +4 -0
- package/dist/components/ui/use-lazy-ref.d.ts.map +1 -0
- package/dist/components/ui/use-lazy-ref.js +45 -0
- package/dist/components/ui/use-lazy-ref.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/network.d.ts +12 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +15 -0
- package/dist/network.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/types/media-chrome-store-types.d.ts +107 -0
- package/dist/types/media-chrome-store-types.d.ts.map +1 -0
- package/dist/types/media-chrome-store-types.js +3 -0
- package/dist/types/media-chrome-store-types.js.map +1 -0
- package/dist/utils/QRCode.d.ts +1 -0
- package/dist/utils/QRCode.d.ts.map +1 -0
- package/dist/utils/QRCode.js +2 -0
- package/dist/utils/QRCode.js.map +1 -0
- package/dist/utils/imageValidation.d.ts +6 -0
- package/dist/utils/imageValidation.d.ts.map +1 -0
- package/dist/utils/imageValidation.js +64 -0
- package/dist/utils/imageValidation.js.map +1 -0
- package/docs/CONFIGURED_MEDIA_PLAYER.md +40 -0
- package/docs/CORP_AUTH_USAGE.md +687 -0
- package/docs/EXAMPLES_WALLPAPERSNAME_IMPLEMENTATION.md +1445 -0
- package/docs/EXAMPLE_ENDPOINTS_COMUNICATION.md +55 -0
- package/docs/EXTERNAL_SDK_GUIDE.md +1340 -0
- package/docs/FOR_YOU_360_FACESWAP_FIX.md +400 -0
- package/docs/FOR_YOU_IMPLEMENTATION_GUIDE.md +1413 -0
- package/docs/FOR_YOU_QUIZ_ARCHITECTURE.md +753 -0
- package/docs/FOR_YOU_SDK_WALLPAPERSNAME_BUG.md +106 -0
- package/docs/FOR_YOU_WALLPAPERSNAME_ENHANCEMENT_PLAN.md +210 -0
- package/docs/LEGAL_USAGE.md +190 -0
- package/docs/STREAK_IMPLEMENTATION_GUIDE.md +430 -0
- package/package.json +106 -84
- package/public/spin2win/assets/border-afristream.svg +26 -26
- package/public/spin2win/assets/border-efc.svg +23 -23
- package/public/spin2win/assets/border-streetreel.svg +23 -23
- package/public/spin2win/assets/border-totalgym.svg +27 -27
- package/public/spin2win/assets/border-womantoday.svg +26 -26
- package/public/spin2win/assets/indicator-afristream.svg +28 -28
- package/public/spin2win/assets/indicator-efc.svg +29 -29
- package/public/spin2win/assets/indicator-streetreel.svg +29 -29
- package/public/spin2win/assets/indicator-totalgym.svg +29 -29
- package/public/spin2win/fonts/switzer/README.md +22 -22
- package/scripts/install-agent-skill.cjs +34 -0
- package/skills/webs-sdk-package/SKILL.md +21 -0
- package/skills/webs-sdk-package/references/components.md +32 -0
- package/skills/webs-sdk-package/references/integration.md +32 -0
- package/skills/webs-sdk-package/references/ui.md +197 -0
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# Instrucciones para agregar la fuente Switzer
|
|
2
|
-
|
|
3
|
-
## 📁 Archivos necesarios
|
|
4
|
-
|
|
5
|
-
Copia los siguientes archivos de la fuente Switzer a esta carpeta:
|
|
6
|
-
|
|
7
|
-
### Archivos requeridos:
|
|
8
|
-
- `Switzer-Regular.woff2`
|
|
9
|
-
- `Switzer-Regular.woff`
|
|
10
|
-
- `Switzer-Medium.woff2`
|
|
11
|
-
- `Switzer-Medium.woff`
|
|
12
|
-
- `Switzer-Semibold.woff2`
|
|
13
|
-
- `Switzer-Semibold.woff`
|
|
14
|
-
- `Switzer-Bold.woff2`
|
|
15
|
-
- `Switzer-Bold.woff`
|
|
16
|
-
|
|
17
|
-
## 📝 Notas:
|
|
18
|
-
- Los archivos .woff2 son la versión comprimida (más eficiente)
|
|
19
|
-
- Los archivos .woff son la versión de respaldo para navegadores antiguos
|
|
20
|
-
- La configuración de @font-face ya está lista en `spin2win/styles/fonts.css`
|
|
21
|
-
|
|
22
|
-
## ✅ Una vez copiados los archivos:
|
|
1
|
+
# Instrucciones para agregar la fuente Switzer
|
|
2
|
+
|
|
3
|
+
## 📁 Archivos necesarios
|
|
4
|
+
|
|
5
|
+
Copia los siguientes archivos de la fuente Switzer a esta carpeta:
|
|
6
|
+
|
|
7
|
+
### Archivos requeridos:
|
|
8
|
+
- `Switzer-Regular.woff2`
|
|
9
|
+
- `Switzer-Regular.woff`
|
|
10
|
+
- `Switzer-Medium.woff2`
|
|
11
|
+
- `Switzer-Medium.woff`
|
|
12
|
+
- `Switzer-Semibold.woff2`
|
|
13
|
+
- `Switzer-Semibold.woff`
|
|
14
|
+
- `Switzer-Bold.woff2`
|
|
15
|
+
- `Switzer-Bold.woff`
|
|
16
|
+
|
|
17
|
+
## 📝 Notas:
|
|
18
|
+
- Los archivos .woff2 son la versión comprimida (más eficiente)
|
|
19
|
+
- Los archivos .woff son la versión de respaldo para navegadores antiguos
|
|
20
|
+
- La configuración de @font-face ya está lista en `spin2win/styles/fonts.css`
|
|
21
|
+
|
|
22
|
+
## ✅ Una vez copiados los archivos:
|
|
23
23
|
La fuente Switzer estará disponible automáticamente para el tema `womantoday`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Copy the portable Agent Skills bundle into a consuming project.
|
|
5
|
+
// JavaScript is used because published CLI entry points must run on Node without TS tooling.
|
|
6
|
+
const fs = require('node:fs');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
11
|
+
console.log('Usage: webs-sdk-skill [--force]\nInstall skill into .agents/skills/webs-sdk-package in the current directory.');
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
if (args.some((arg) => arg !== '--force')) {
|
|
15
|
+
console.error('Unknown option. Use webs-sdk-skill --help.');
|
|
16
|
+
process.exit(2);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const source = path.resolve(__dirname, '..', 'skills', 'webs-sdk-package');
|
|
20
|
+
const target = path.resolve(process.cwd(), '.agents', 'skills', 'webs-sdk-package');
|
|
21
|
+
if (!fs.existsSync(path.join(source, 'SKILL.md'))) {
|
|
22
|
+
console.error('Package is missing its agent skill.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
if (fs.existsSync(target)) {
|
|
26
|
+
if (!args.includes('--force')) {
|
|
27
|
+
console.error(`Skill already exists at ${target}. Run webs-sdk-skill --force to replace it.`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
33
|
+
fs.cpSync(source, target, { recursive: true });
|
|
34
|
+
console.log(`Installed webs-sdk skill at ${target}`);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: webs-sdk-package
|
|
3
|
+
description: Use the webs-sdk npm package in Nexum portals. Activate when choosing or integrating reusable SDK functionality: authentication, sessions, tracking, consent, AI content components, For You, Streak, quiz, esports, Radix UI, VideoPlayer, ConfiguredMediaPlayer, MediaPlayer, or when checking whether the installed package already exports a needed component.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Use webs-sdk in a portal
|
|
7
|
+
|
|
8
|
+
1. Read `references/components.md` to choose the existing component or library and its public import path. Read `references/integration.md` for the relevant usage and installation details.
|
|
9
|
+
2. Verify the installed package version and exact public exports/types in `node_modules/webs-sdk/dist/index.d.ts` or `node_modules/webs-sdk/dist/components/ui/index.d.ts`. Catalog is a guide, not an exhaustive or version-independent API contract.
|
|
10
|
+
3. Use `webs-sdk` or `webs-sdk/ui`; never import from private `dist/` paths. Keep default `WebsSDK` singleton out of client components. Add client boundary for interactive React UI. Consult installed `node_modules/webs-sdk/docs/` for feature-specific guidance.
|
|
11
|
+
4. If functionality is absent, report the gap before creating shared functionality in a portal. Add reusable code to the SDK instead.
|
|
12
|
+
|
|
13
|
+
## UI governance (webs-sdk/ui)
|
|
14
|
+
|
|
15
|
+
**Prefer verified `webs-sdk/ui` exports over direct `@radix-ui` imports or local duplicates.** The SDK supplies many accessible primitives with `data-slot` attributes; check its actual export barrel before choosing one. Avoid direct Radix dependencies where an SDK export exists.
|
|
16
|
+
|
|
17
|
+
**Structural primitives are largely unbranded.** Style `Button`, `Input`, `Dialog`, `NavigationMenu`, `Card`, etc. with portal CSS tokens and Tailwind classes. Some exports (for example `Skeleton` and media players) do include styles: inspect the installed component before styling. Key gotchas verified in source: `Button` has no `variant`/`size` props; `navigationMenuTriggerStyle()` returns `""`; `Badge` accepts but silently strips its `variant` prop before rendering.
|
|
18
|
+
|
|
19
|
+
**Do not force a visual redesign** when a parity requirement (legacy andromeda match or Figma spec) exists. Use `webs-sdk/ui` for accessible structure; reproduce the exact visual via CSS.
|
|
20
|
+
|
|
21
|
+
See `references/ui.md` for styling patterns, the complete verified export map, and what is **not** in the barrel.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Component and capability map
|
|
2
|
+
|
|
3
|
+
Choose an existing export before writing portal-specific code. Names below reflect the SDK source at packaging time; the installed package's `.d.ts` files are authoritative. Components accept different Props, API adapters and theme options: inspect their declarations rather than guessing required fields.
|
|
4
|
+
|
|
5
|
+
## Root entry: `webs-sdk`
|
|
6
|
+
|
|
7
|
+
| Goal | Exports to inspect | Where it fits |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Session, authentication, users, portal metadata | Default `WebsSDK` singleton: `Session`, `AuthManager`, `User`, `Andromeda`, `ContentManager`, `CorporateAuthManager`, `Legal`, `Networking`, `Storage`, `Config`, `.pre` | SDK orchestration, typically server-side in Next.js API routes/middleware. Do not directly bundle default singleton in client UI. |
|
|
10
|
+
| Analytics and consent | `CookieConsent`, `getCookieConsentTexts`, `initGoogleAnalytics`, `updateGAConsent`, `trackGAEvent`, `trackGAPageView`, `isGALoaded`; singleton `MixPanel`, `Clarity`, `Calypso` | Cookie banner and opt-in GA; use consent APIs before loading analytics. |
|
|
11
|
+
| CDN and media checks | `handleCDNRequest`, `validateVideoUrl`, `validateVideoBatch`, `useValidateVideoOnMount`, `useLazyVideoValidation` | CDN route handler, video URL validation and hooks; not a video player. |
|
|
12
|
+
| Image/AI creation | `AvatarAI`, `CreativeFaceSwap`, `Wallpapers`, `WallpapersName`, `AETemplatesSection`, `MemeGenerator`, `Stickers`, `ARFilters`, `ArtGenerator`, `GifsIa`, `QrCode` | Standalone widgets and, where exported, `*Page` and `*ForYouCard` variants. Search Props for API/config/theme requirements. |
|
|
13
|
+
| Other content | `Ringtone`, `Quiz`, `EsportsNews`, `EsportsVideos`, `EsportsLive` | Content widgets, quizzes, esports with API adapter/config types. |
|
|
14
|
+
| For You page | `ForYouFullPage`, `ForYouPage`, `ForYouCard`, individual feature `*Card`, `useAvatarAI`, `useQuiz`, other `use*` hooks | Config-driven feature hub and reusable cards/hooks. Full page has config/theme/translation props; see installed `docs/FOR_YOU_IMPLEMENTATION_GUIDE.md`. |
|
|
15
|
+
| Streak | `StreakWidget`, `StreakCard`, `StreakModal`, `StreakCelebration`, `useStreak` | Activity streak UI and data hook; see installed `docs/STREAK_IMPLEMENTATION_GUIDE.md`. |
|
|
16
|
+
| Login support UI | `PasswordResetRequest`, `PasswordResetForm`, `RecoveryPassword` | Password recovery pieces; not a complete LoginPage. |
|
|
17
|
+
| Forms | `ContactForm`, `ContactFormContent`, `createContactFormAPI` | Reusable configurable contact form. |
|
|
18
|
+
| Networking/dev tools | `NetworkInspectorUI`, `trackRequest`, `trackResponse`, `getLogs`, `clearLogs`, `getStats` | Request inspection in development. |
|
|
19
|
+
| Small utilities | `downloadFile`, `generateQRCode`, `getForYouTranslations`, `forYouFetch` | Reuse instead of copy/pasting helpers. |
|
|
20
|
+
|
|
21
|
+
## UI entry: `webs-sdk/ui`
|
|
22
|
+
|
|
23
|
+
Most structural primitives are **unbranded** Radix or native wrappers. Many emit `data-slot` attributes for CSS targeting and forward `className`; some exports (for example `Skeleton` and media players) include built-in classes. Apply portal visuals via `className` or `[data-slot]` selectors. Verify the installed barrel at `node_modules/webs-sdk/dist/components/ui/index.d.ts`; `references/ui.md` lists exceptions and styling patterns.
|
|
24
|
+
|
|
25
|
+
| Goal | Export | Decision |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| Prop-configured video/audio | `ConfiguredMediaPlayer` | Preferred new Radix player for a ready-to-use layout. Set `src`, optional `poster`, `tracks`, `sources`, `controls`; see `references/integration.md` and installed `docs/CONFIGURED_MEDIA_PLAYER.md`. |
|
|
28
|
+
| Custom media controls | `MediaPlayer` plus `MediaPlayerVideo` / `MediaPlayerAudio`, `MediaPlayerControls`, `MediaPlayerPlay`, `MediaPlayerSeek`, `MediaPlayerTime`, `MediaPlayerVolume`, `MediaPlayerSettings`, `MediaPlayerFullscreen`, etc. | Composable Radix parts; root alone does not create media or controls. |
|
|
29
|
+
| Existing/legacy video integration | `VideoPlayer` | Different API (`videoUrl`, `posterImage`, `languages`); retain for existing consumers. |
|
|
30
|
+
| Standard UI primitives | `Button` (no variants — unstyled slot), `Input`, `Dialog`/parts, `DropdownMenu`/parts, `Tabs`/parts, `Select`/parts, `Tooltip`/parts, `Avatar`/parts, `Accordion`/parts, `Alert`, `Badge` (variant prop stripped), `Carousel`, `Checkbox`, `NavigationMenu`/parts (`navigationMenuTriggerStyle` returns `""`), `Textarea`, `Card`/parts, `Separator`, `Skeleton`, `Field`/parts, `Item`/parts, `InputGroup`/parts, `ButtonGroup`/parts, `Breadcrumb`/parts, `HoverCard`/parts, `AlertDialog`/parts, `Collapsible`/parts, `ContextMenu`/parts, `AspectRatio`, `Label` | Prefer exported primitives over direct `@radix-ui/*` imports when the SDK offers an equivalent. |
|
|
31
|
+
|
|
32
|
+
Both entry points have independent barrels. Import from `webs-sdk/ui` for UI, not `webs-sdk` or `webs-sdk/dist/...`. All React UI must run with a suitable client boundary and styling; consult `references/integration.md`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Install and use the SDK skill
|
|
2
|
+
|
|
3
|
+
## Portal dependency and agent skill are separate
|
|
4
|
+
|
|
5
|
+
1. Install the private npm package in the portal (requires registry access): `npm install webs-sdk`.
|
|
6
|
+
2. To make the skill discoverable by Pi and other agents that support the Agent Skills directory convention, run from the portal root: `npm exec -- webs-sdk-skill`. This copies the skill to `.agents/skills/webs-sdk-package/`; commit that directory with the portal if teammates should get the skill. The installer never overwrites an existing installation unless called with `--force`. Restart the agent or reload skills. Installing npm package **alone does not activate** a skill in arbitrary agent tools.
|
|
7
|
+
3. For Pi only, an alternative is `pi install npm:webs-sdk --local`: the package's `pi.skills` manifest enables its skill without copying files into the portal. This does **not** install `webs-sdk` as a dependency of the portal app: do step 1 as well. A personal install omits `--local`. Local Pi packages require project trust. Avoid enabling both paths simultaneously (duplicate skill names).
|
|
8
|
+
4. Agent Skills-compatible tools can also load `skills/webs-sdk-package/SKILL.md` directly from the published package if configured to scan that directory. Other agents may require their own skill configuration.
|
|
9
|
+
|
|
10
|
+
When upgrading the npm package, rerun `npm exec -- webs-sdk-skill --force` if you copied the skill. The published skill version tracks the npm package, but the installed app dependency, copied skill, and agent's running context can be out of sync. Always check the installed declarations at `node_modules/webs-sdk/dist/index.d.ts` and `node_modules/webs-sdk/dist/components/ui/index.d.ts` before coding.
|
|
11
|
+
|
|
12
|
+
## Usage patterns
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
'use client';
|
|
16
|
+
import { ConfiguredMediaPlayer } from 'webs-sdk/ui';
|
|
17
|
+
|
|
18
|
+
export function Video({ src }: { src: string }) {
|
|
19
|
+
return <ConfiguredMediaPlayer src={src} controls={{ seekButtons: true, pictureInPicture: true }} />;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For Tailwind CSS v4, the portal CSS must explicitly scan the installed SDK UI directory (normally ignored under `node_modules`): add `@source "../../node_modules/webs-sdk/dist/components/ui";` relative to the CSS file. Adjust depth to the portal layout; without generated utilities UI controls may appear unstyled. Consult `node_modules/webs-sdk/docs/CONFIGURED_MEDIA_PLAYER.md` for props, HLS and captions. `ConfiguredMediaPlayer` and `MediaPlayer` are different from legacy `VideoPlayer`.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// In a server-side route/middleware, not a client component:
|
|
27
|
+
import WebsSDK from 'webs-sdk';
|
|
28
|
+
|
|
29
|
+
const metadata = await WebsSDK.Andromeda.getWebsiteMetadatabyHostname(hostname);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not assume a backend response shape, API keys, or portal theme. Inspect the relevant exported Props and feature guide; fetch backend data through the existing server-side pattern. `webs-sdk/ui` is a client-side React entry and does not initialize sessions, authentication or analytics for you.
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# webs-sdk/ui — UI governance for portal consumers
|
|
2
|
+
|
|
3
|
+
Import path: `from 'webs-sdk/ui'`
|
|
4
|
+
Authoritative export list: `node_modules/webs-sdk/dist/components/ui/index.d.ts`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Rule 1 — Prefer existing `webs-sdk/ui` exports over direct `@radix-ui` imports
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
// ✅ Correct
|
|
12
|
+
import { Dialog, DialogContent, DialogTrigger } from 'webs-sdk/ui';
|
|
13
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from 'webs-sdk/ui';
|
|
14
|
+
import { NavigationMenu, NavigationMenuList, NavigationMenuItem } from 'webs-sdk/ui';
|
|
15
|
+
|
|
16
|
+
// ❌ Wrong — creates version drift, duplicate bundle, breaks governance
|
|
17
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The SDK exports many Radix-backed primitives with `data-slot` attributes. Verify the barrel first; use existing exports rather than duplicating them locally. Direct Radix imports for already-exported primitives risk version drift.
|
|
21
|
+
|
|
22
|
+
If a primitive you need is **missing from `webs-sdk/ui`**: report the gap and add it to the SDK source (`src/components/ui/`) rather than adding a direct Radix dep to the portal.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Rule 2 — Primitives are intentionally unstyled; you own all visual CSS
|
|
27
|
+
|
|
28
|
+
Most structural components wrap a Radix primitive or native element, expose a `data-slot` attribute and forward applicable props including `className`. Check each export for exceptions and built-in styles rather than assuming every primitive has the same implementation.
|
|
29
|
+
|
|
30
|
+
**Exceptions with minimal built-in classes:**
|
|
31
|
+
- `TooltipContent` — positioning and open/close animation classes
|
|
32
|
+
- `Skeleton` — `animate-pulse rounded-md bg-muted`
|
|
33
|
+
- `ConfiguredMediaPlayer` / `media-player` — rich layout classes for media controls
|
|
34
|
+
|
|
35
|
+
**Verified gotchas** (do not assume CVA variants exist):
|
|
36
|
+
|
|
37
|
+
| Component | Gotcha |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `Button` | **No `variant` or `size` props.** Plain unstyled slot. Add your own via `className`. |
|
|
40
|
+
| `navigationMenuTriggerStyle()` | **Returns `""`** (empty string). Apply link/trigger styles yourself. |
|
|
41
|
+
| `Badge` | Accepts `variant?: "default"\|"outline"\|"secondary"\|"destructive"` but **silently strips it** before rendering. No variant classes are applied. |
|
|
42
|
+
| `Item` | Has `variant`/`size` props but outputs empty CVA strings — they become `data-variant`/`data-size` DOM attributes for CSS targeting only. |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Rule 3 — Style via `className` or `[data-slot]` CSS; keep primitives unbranded
|
|
47
|
+
|
|
48
|
+
### Pattern A — inline `className` (component-level)
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from 'webs-sdk/ui';
|
|
52
|
+
|
|
53
|
+
<Dialog>
|
|
54
|
+
<DialogTrigger className="rounded-full bg-[var(--color-primary)] px-6 py-2 text-sm font-semibold">
|
|
55
|
+
Open
|
|
56
|
+
</DialogTrigger>
|
|
57
|
+
<DialogContent className="rounded-2xl bg-[var(--color-bg-card)] border border-[var(--color-border)] p-8 max-w-lg">
|
|
58
|
+
<DialogHeader className="mb-4">
|
|
59
|
+
<DialogTitle className="text-xl font-semibold text-[--color-text-base]">
|
|
60
|
+
Title
|
|
61
|
+
</DialogTitle>
|
|
62
|
+
</DialogHeader>
|
|
63
|
+
</DialogContent>
|
|
64
|
+
</Dialog>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Pattern B — `[data-slot]` in `globals.css` (theme-wide)
|
|
68
|
+
|
|
69
|
+
```css
|
|
70
|
+
/* globals.css — applies to all Dialog instances in the portal */
|
|
71
|
+
[data-slot="dialog-content"] {
|
|
72
|
+
border-radius: 1rem;
|
|
73
|
+
background: var(--color-bg-card);
|
|
74
|
+
border: 1px solid var(--color-border);
|
|
75
|
+
padding: 2rem;
|
|
76
|
+
}
|
|
77
|
+
[data-slot="dialog-title"] {
|
|
78
|
+
font-size: 1.25rem;
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
color: var(--color-text-base);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Pattern C — thin portal wrapper (Figma-exact layout)
|
|
85
|
+
|
|
86
|
+
Wrap `webs-sdk/ui` parts in a portal component when you need Figma-specific structure (custom close icon, extra sections, specific variants):
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// src/components/ui/PortalDialog.tsx
|
|
90
|
+
'use client';
|
|
91
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from 'webs-sdk/ui';
|
|
92
|
+
import { cn } from '@/lib/utils';
|
|
93
|
+
|
|
94
|
+
export function PortalDialog({ title, trigger, children, className }: Props) {
|
|
95
|
+
return (
|
|
96
|
+
<Dialog>
|
|
97
|
+
<DialogTrigger asChild>{trigger}</DialogTrigger>
|
|
98
|
+
<DialogContent className={cn('rounded-2xl bg-[var(--color-bg-card)] p-8', className)}>
|
|
99
|
+
<DialogHeader>
|
|
100
|
+
<DialogTitle>{title}</DialogTitle>
|
|
101
|
+
</DialogHeader>
|
|
102
|
+
{children}
|
|
103
|
+
</DialogContent>
|
|
104
|
+
</Dialog>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Rule 4 — Parity requirement overrides design system preference
|
|
112
|
+
|
|
113
|
+
When a portal must match legacy andromeda visually (or a Figma spec produced before this governance rule), **do not force a redesign**. Use `webs-sdk/ui` for accessible behaviour; reproduce the legacy visual exactly via CSS custom properties. Parity wins.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## NavigationMenu — navbar pattern
|
|
118
|
+
|
|
119
|
+
`navigationMenuTriggerStyle()` returns `""` — do not call it expecting classes:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuLink } from 'webs-sdk/ui';
|
|
123
|
+
|
|
124
|
+
<NavigationMenu className="hidden md:flex">
|
|
125
|
+
<NavigationMenuList className="flex items-center gap-1">
|
|
126
|
+
{pages.map(page => (
|
|
127
|
+
<NavigationMenuItem key={page.url}>
|
|
128
|
+
<NavigationMenuLink
|
|
129
|
+
href={page.url}
|
|
130
|
+
className="rounded-lg px-4 py-2 text-sm font-medium text-[var(--color-text-base)] hover:bg-[var(--color-bg-hover)]"
|
|
131
|
+
>
|
|
132
|
+
{page.label}
|
|
133
|
+
</NavigationMenuLink>
|
|
134
|
+
</NavigationMenuItem>
|
|
135
|
+
))}
|
|
136
|
+
</NavigationMenuList>
|
|
137
|
+
</NavigationMenu>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Tailwind v4 scan — required for ConfiguredMediaPlayer
|
|
143
|
+
|
|
144
|
+
`webs-sdk/ui` components that use Tailwind classes (media players, Skeleton, TooltipContent) are inside `node_modules`, which Tailwind v4 does not scan by default. Without this, player controls appear unstyled:
|
|
145
|
+
|
|
146
|
+
```css
|
|
147
|
+
/* portal globals.css or main CSS file */
|
|
148
|
+
@source "../../node_modules/webs-sdk/dist/components/ui";
|
|
149
|
+
/* adjust relative path to match where this CSS file lives */
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
See `node_modules/webs-sdk/docs/CONFIGURED_MEDIA_PLAYER.md` for the canonical path example.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## What is NOT in `webs-sdk/ui` (verify before use)
|
|
157
|
+
|
|
158
|
+
The following are **not** confirmed exports in the barrel at time of writing — always check `node_modules/webs-sdk/dist/components/ui/index.d.ts`:
|
|
159
|
+
|
|
160
|
+
- `Popover` (not exported)
|
|
161
|
+
- `Switch`
|
|
162
|
+
- `RadioGroup`
|
|
163
|
+
- `Progress`
|
|
164
|
+
- `Slider` (as a named export — Radix slider dep exists but verify export)
|
|
165
|
+
|
|
166
|
+
Never assume a component is available because a similar shadcn component exists. Verify, then use.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Design token conventions (portals)
|
|
171
|
+
|
|
172
|
+
Portal tokens live in `globals.css` under `:root` and `@theme inline` (Tailwind v4):
|
|
173
|
+
|
|
174
|
+
```css
|
|
175
|
+
:root {
|
|
176
|
+
--portal-primary: #ff8546;
|
|
177
|
+
--portal-card: #1a1a1a;
|
|
178
|
+
--portal-text: #fdfbff;
|
|
179
|
+
--portal-border: rgba(255,255,255,0.12);
|
|
180
|
+
--color-primary: var(--portal-primary);
|
|
181
|
+
--color-bg-card: var(--portal-card);
|
|
182
|
+
--color-text-base: var(--portal-text);
|
|
183
|
+
--color-border: var(--portal-border);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@theme inline {
|
|
187
|
+
--color-primary: var(--portal-primary);
|
|
188
|
+
--color-card: var(--portal-card);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Reference in component `className`:
|
|
193
|
+
```tsx
|
|
194
|
+
<Card className="bg-card border border-[var(--portal-border)] rounded-2xl p-6">
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Keep primitives unbranded (no portal-specific defaults baked in). In `next_template`, put shared tokens in `src/styles/globals.css` and portal overrides in `public/themes/{name}.css` loaded after it; follow the consumer's actual theme setup.
|