@marwes-ui/react 0.0.4 → 1.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Niklas Westman
3
+ Copyright (c) 2026 Niklas Westman, Martino Ognissanti and contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,137 +1,455 @@
1
- # @marwes-ui/react
1
+ <div align="center">
2
2
 
3
- React adapter for Marwes core recipes.
3
+ <img alt="Marwes Design System" src="https://raw.githubusercontent.com/niklas-westman/marwes/main/.github/assets/banner-light.png" width="100%">
4
4
 
5
- ## Responsibilities
6
- - Provide React components and provider APIs.
7
- - Resolve theme from context and call core recipes.
8
- - Apply typed RenderKit output to React elements.
5
+ <br>
6
+ <br>
9
7
 
10
- ## Non-Responsibilities
11
- - No component logic duplication from core.
12
- - No preset CSS ownership.
8
+ # Marwes Design System - React
9
+
10
+ **React components with first edition styling, typed theme tokens, accessibility contracts, and AI-readable semantics built in.**
11
+
12
+ React 18+ • TypeScript-first • Default CSS included • ThemeInput • Google Fonts DX • Purpose components
13
+
14
+ [Documentation](https://github.com/niklas-westman/marwes/tree/main/docs) • [Storybook](https://d3hobet9plpuvm.cloudfront.net/storybook-react/latest/) • [GitHub](https://github.com/niklas-westman/marwes)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## Why Use It
21
+
22
+ Marwes is built for teams and AI-assisted workflows that need a component system that is easy to install, easy to theme, and hard to misuse.
23
+
24
+ - **One package for React apps**: components, provider, default first edition CSS, theme helpers, and typed props.
25
+ - **Beautiful defaults**: install the adapter, wrap your app, and start building without a separate CSS setup.
26
+ - **Consequential theming**: a `ThemeInput` object changes colors, fonts, radius, density, typography, and component visuals through shared CSS variables.
27
+ - **Purpose components**: `SubmitButton`, `CancelButton`, and `DestructiveButton` make intent machine-readable so tests, audits, and AI agents can handle actions safely.
28
+ - **Shared core contracts**: every React component is backed by the same framework-agnostic recipes, a11y mapping, and theme shape.
29
+
30
+ ## Package Map
31
+
32
+ For a React app, install this package first. It includes the React adapter, loads the default preset CSS, and re-exports the core theme helpers you normally need.
33
+
34
+ | Package | Use it when |
35
+ | --- | --- |
36
+ | `@marwes-ui/react` | You are building a React app. |
37
+ | `@marwes-ui/vue` | You are building a Vue app instead. |
38
+ | `@marwes-ui/core` | You are building adapters, tests, tooling, or framework-agnostic integrations. |
39
+ | `@marwes-ui/presets` | You need standalone first edition CSS or preset theme exports. |
40
+
41
+ This split keeps installation simple for app teams while giving humans and AI agents clear package boundaries: adapters render, core defines contracts, presets style.
13
42
 
14
43
  ## Install
44
+
15
45
  ```bash
16
- pnpm add @marwes-ui/core @marwes-ui/react @marwes-ui/presets
46
+ pnpm add @marwes-ui/react react react-dom
17
47
  ```
18
48
 
49
+ No preset CSS import is needed. `@marwes-ui/react` depends on `@marwes-ui/presets` and loads the first edition CSS automatically.
50
+
19
51
  ## Quick Start
52
+
20
53
  ```tsx
21
- import { MarwesProvider, Button, ButtonVariant, Input, Checkbox } from "@marwes-ui/react";
22
- import { firstEdition } from "@marwes-ui/presets";
23
- import "@marwes-ui/presets/firstEdition/styles.css";
54
+ import {
55
+ Button,
56
+ Checkbox,
57
+ Input,
58
+ MarwesProvider,
59
+ SubmitButton,
60
+ } from "@marwes-ui/react"
24
61
 
25
62
  export function App() {
26
63
  return (
27
- <MarwesProvider preset={firstEdition} theme={{ color: { primary: "#5B8CFF" } }}>
28
- <Button variant={ButtonVariant.primary}>Save</Button>
29
- <Input placeholder="Email" onValueChange={(v) => console.log(v)} />
64
+ <MarwesProvider>
65
+ <Input placeholder="Email" ariaLabel="Email" />
30
66
  <Checkbox ariaLabel="Subscribe" />
67
+ <Button variant="secondary">Preview</Button>
68
+ <SubmitButton>Save</SubmitButton>
31
69
  </MarwesProvider>
32
- );
70
+ )
33
71
  }
34
72
  ```
35
73
 
36
- ## Button Philosophy
74
+ ## Style App-Owned UI
37
75
 
38
- Marwes buttons follow a **semantic-first** approach:
76
+ Marwes components pick up provider tokens automatically. Your own React styling can use the same tokens by importing `mwThemeVars`. This example uses styled-components, but the same values work in Emotion, vanilla-extract, inline style objects, CSS Modules, and plain CSS.
39
77
 
40
- ### Recommended: Semantic Components
41
78
  ```tsx
42
- import { CancelButton, SubmitButton, CreateButton, DangerButton } from "@marwes-ui/react";
79
+ import { Button, MarwesProvider, mwThemeVars } from "@marwes-ui/react"
80
+ import styled from "styled-components"
43
81
 
44
- // These auto-set AI-friendly action metadata
45
- <CancelButton onClick={handleCancel}>Cancel</CancelButton>
46
- <SubmitButton>Save</SubmitButton>
47
- <CreateButton onClick={handleCreate}>New Item</CreateButton>
48
- <DangerButton onClick={handleDelete}>Delete</DangerButton>
82
+ const AppShell = styled.main`
83
+ min-height: 100dvh;
84
+ padding: ${mwThemeVars.spacing.sp24};
85
+ color: ${mwThemeVars.color.text};
86
+ background: ${mwThemeVars.color.background};
87
+ `
88
+
89
+ const FeaturePanel = styled.section`
90
+ padding: ${mwThemeVars.spacing.sp24};
91
+ background: ${mwThemeVars.color.surface};
92
+ border: 1px solid ${mwThemeVars.color.border};
93
+ border-radius: ${mwThemeVars.ui.radius};
94
+ `
95
+
96
+ const PrimaryCallout = styled.aside`
97
+ background: ${mwThemeVars.color.primary.base};
98
+ color: ${mwThemeVars.color.primary.label};
99
+ `
100
+
101
+ export function App() {
102
+ return (
103
+ <MarwesProvider>
104
+ <AppShell>
105
+ <PrimaryCallout>Launch workspace</PrimaryCallout>
106
+ <FeaturePanel>
107
+ <Button variant="primary">Save</Button>
108
+ </FeaturePanel>
109
+ </AppShell>
110
+ </MarwesProvider>
111
+ )
112
+ }
49
113
  ```
50
114
 
51
- ### Advanced: Raw Props with Type-Safe Enums
115
+ Plain CSS and CSS Modules can use the raw custom properties directly:
116
+
117
+ ```css
118
+ .app-shell {
119
+ min-height: 100dvh;
120
+ padding: var(--mw-spacing-sp-24);
121
+ color: var(--mw-color-text);
122
+ background: var(--mw-color-background);
123
+ }
124
+ ```
125
+
126
+ ## Use Typed Components
127
+
128
+ Import components, enums, and prop types from the same package. The values line up with the same core recipes and preset CSS.
129
+
52
130
  ```tsx
53
- import { Button, ButtonVariant, ButtonSize, ButtonAction } from "@marwes-ui/react";
131
+ import {
132
+ BadgeVariant,
133
+ Button,
134
+ ButtonSize,
135
+ ButtonVariant,
136
+ Card,
137
+ H1,
138
+ InputField,
139
+ Paragraph,
140
+ Spacer,
141
+ Spacings,
142
+ StatusBadge,
143
+ SubmitButton,
144
+ type ButtonProps,
145
+ type InputFieldProps,
146
+ } from "@marwes-ui/react"
54
147
 
55
- // For dynamic or custom scenarios
56
- <Button
57
- variant={ButtonVariant.primary}
58
- size={ButtonSize.md}
59
- action={ButtonAction.submit}
60
- >
61
- Submit
62
- </Button>
148
+ const primaryAction: ButtonProps = {
149
+ variant: ButtonVariant.primary,
150
+ size: ButtonSize.md,
151
+ children: "Create project",
152
+ }
153
+
154
+ const emailField: InputFieldProps = {
155
+ label: "Email",
156
+ helperText: "Used for project notifications.",
157
+ input: {
158
+ type: "email",
159
+ placeholder: "you@example.com",
160
+ },
161
+ }
162
+
163
+ export function ProjectPanel() {
164
+ return (
165
+ <Card title="Project setup">
166
+ <StatusBadge variant={BadgeVariant.success}>Ready</StatusBadge>
167
+ <Spacer spacing={Spacings.sp16} />
168
+ <H1 size="h2">Launch workspace</H1>
169
+ <Paragraph size="md">
170
+ Components share theme tokens, typed variants, spacing, and semantic metadata.
171
+ </Paragraph>
172
+ <InputField {...emailField} />
173
+ <Spacer spacing={Spacings.sp24} />
174
+ <Button {...primaryAction} />
175
+ <SubmitButton>Save changes</SubmitButton>
176
+ </Card>
177
+ )
178
+ }
63
179
  ```
64
180
 
65
- Semantic components are preferred for guaranteed AI context and consistent UX.
181
+ ## Available Components
66
182
 
67
- ## Current Exports
68
183
  Provider and hooks:
69
184
  - `MarwesProvider`
70
185
  - `useTheme`
71
- - `useSystem`
186
+ - `useToast`
187
+
188
+ Actions and buttons:
189
+ - `Button`
190
+ - `PrimaryButton`, `SecondaryButton`, `TextButton`, `SuccessButton`
191
+ - `SubmitButton`, `CancelButton`, `CreateButton`, `DestructiveButton`
192
+ - `LinkButton`, `SaveButton`, `ConfirmButton`, `VerifyButton`
193
+ - `EditButton`, `CloseButton`, `RefreshButton`
194
+ - `UploadButton`, `DownloadButton`, `CopyButton`
195
+ - `SearchButton`, `FilterButton`, `SortButton`, `DropdownButton`
196
+
197
+ Forms and inputs:
198
+ - `Input`, `Textarea`, `Select`, `RichText`, `InputOtp`
199
+ - `InputField`, `TextareaField`, `SelectField`, `RichTextField`
200
+ - `DropdownField`, `SearchField`, `PasswordField`, `EmailField`
201
+ - `DateOfBirthField`, `ZipCodeField`, `PhoneField`, `URLField`, `CurrencyField`
202
+ - `Checkbox`, `CheckboxField`, `CheckboxGroupField`
203
+ - `Radio`, `RadioGroupField`, `YesNoRadioGroup`, `RatingRadioGroup`, `OptionRadioGroup`
204
+ - `Switch`, `SwitchField`, `FeatureToggle`, `PreferenceSwitch`, `PermissionSwitch`
205
+ - `Slider`, `SliderField`, `VolumeSlider`, `BrightnessSlider`, `RadiusSlider`
72
206
 
73
- Atoms:
74
- - `Button`, `PrimaryButton`, `SecondaryButton`, `TextButton`
75
- - `CancelButton`, `SubmitButton`, `CreateButton`, `DangerButton`, `LinkButton`
76
- - `Input`
207
+ Content and layout:
208
+ - `Card`, `ProductCard`, `ProfileCard`, `StatCard`
209
+ - `H1`, `H2`, `H3`, `Paragraph`
210
+ - `Spacer`, `Spacing`, `Divider`
77
211
  - `Icon`
78
- - `Checkbox`
79
- - `H1`, `H2`, `H3`
80
- - `Paragraph`
212
+ - `Avatar`, `AvatarBadge`, `AvatarGroup`, `ProfileAvatar`, `PresenceAvatar`, `TeamAvatarGroup`
81
213
 
82
- Enums (const objects):
83
- - `ButtonVariant` - `primary`, `secondary`, `text`
84
- - `ButtonSize` - `xs`, `sm`, `md`, `lg`
85
- - `ButtonAction` - `submit`, `cancel`, `create`, `delete`, `navigate`, `edit`, `reset`, `button`
214
+ Feedback and overlays:
215
+ - `Badge`, `BadgeGroup`, `StatusBadge`, `PriorityBadge`, `NotificationBadge`
216
+ - `Spinner`, `ButtonSpinner`, `EmptyStateSpinner`
217
+ - `Toast`, `ToastContainer`, `ToastProvider`
218
+ - `SuccessToast`, `ErrorToast`, `WarningToast`, `InfoToast`
219
+ - `Tooltip`, `TooltipGroup`
220
+ - `Dialog`, `DialogModal`, `ConfirmDialog`, `DestructiveDialog`, `InfoDialog`
221
+ - `Accordion`, `AccordionField`, `FAQAccordion`, `SettingsAccordion`, `SectionsAccordion`
222
+ - `Tab`, `TabGroup`, `TabPanel`, `NavigationTabs`, `ContentTabs`, `SettingsTabs`
86
223
 
87
- Molecules:
88
- - `CheckboxField`
224
+ Typed tokens and helpers:
225
+ - `ThemeInput`, `ThemeMode`, `Density`, `ToneName`
226
+ - `mwAvailableFonts`, `mwGoogleFontFamilies`, `mwFontFallbacks`, `createFontStack`
227
+ - `mwThemeVars`, `mwThemeVarNames`, `mwStyledTheme`, `mwVar`
228
+ - `ButtonVariant`, `ButtonSize`, `ButtonAction`
229
+ - `BadgeVariant`, `AvatarSize`, `AvatarType`, `SwitchSize`, `IconName`, `Spacings`
89
230
 
90
- Utilities:
91
- - `useRenderKitDebug`
231
+ ## Theme In Seconds
92
232
 
93
- ## Adapter Rules
94
- - Treat `@marwes-ui/core` as source of truth for behavior and a11y.
95
- - Apply RenderKit fields explicitly.
96
- - Keep component wrappers thin and predictable.
97
- - Do not hardcode Figma design values in adapters.
233
+ First edition is the default. Pass `theme` only when a brand or design file needs to change the baseline.
98
234
 
99
- ## Package Structure
100
- - `src/provider/*` - provider + hooks
101
- - `src/components/*` - React wrappers around core recipes
102
- - `src/index.ts` - public exports
235
+ ```tsx
236
+ import { MarwesProvider, mwAvailableFonts } from "@marwes-ui/react"
237
+
238
+ const brandTheme = {
239
+ color: {
240
+ primary: "#2457FF",
241
+ danger: "#D90429",
242
+ success: "#15803D",
243
+ warning: "#D97706",
244
+ background: "#F8FAFC",
245
+ surface: "#FFFFFF",
246
+ surfaceElevated: "#FFFFFF",
247
+ text: "#111827",
248
+ textMuted: "#4B5563",
249
+ border: "#D1D5DB",
250
+ focus: "#2457FF",
251
+ },
252
+ font: {
253
+ primary: mwAvailableFonts.Poppins,
254
+ secondary: mwAvailableFonts.Lora,
255
+ },
256
+ ui: {
257
+ radius: 10,
258
+ density: "comfortable",
259
+ },
260
+ }
261
+
262
+ export function App() {
263
+ return (
264
+ <MarwesProvider theme={brandTheme}>
265
+ <AppShell />
266
+ </MarwesProvider>
267
+ )
268
+ }
269
+ ```
103
270
 
104
- ## Figma Mapping
105
- If design changes originate in Figma, align token/state mapping with:
106
- - `../../docs/FIGMA_TO_MARWES.md`
271
+ The provider resolves `ThemeInput` into `--mw-*` CSS variables. Preset CSS consumes those variables across the full component system.
107
272
 
108
- Most Figma changes should land in core theme/recipes and presets CSS first, then flow into React automatically.
273
+ ## Custom Styling Tokens
109
274
 
110
- ## Scripts
111
- - `pnpm --filter @marwes-ui/react dev`
112
- - `pnpm --filter @marwes-ui/react build`
113
- - `pnpm --filter @marwes-ui/react typecheck`
275
+ `MarwesProvider` resolves `ThemeInput` into `--mw-*` CSS variables. Marwes components and preset CSS consume those variables automatically. The custom styling token helpers let app-owned styles use the same provider-scoped values instead of hard-coding colors, spacing, radius, typography, or duplicated `var(...)` strings.
276
+
277
+ Use the helpers by purpose:
278
+
279
+ - `mwThemeVars` is the default styling helper. It returns CSS `var(...)` references for styled-components, Emotion, vanilla-extract, inline style values, and config files.
280
+ - `mwThemeVarNames` returns raw custom property names for assigning provider-scoped overrides in style objects or tooling.
281
+ - `mwVar()` wraps custom or advanced `--mw-*` names when the named token object does not cover a specialized case.
282
+ - `mwStyledTheme` is a plain object that mirrors `mwThemeVars` for styled-components or Emotion `ThemeProvider` usage.
283
+
284
+ ```tsx
285
+ import type { ReactNode } from "react"
286
+ import { mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from "@marwes-ui/react"
287
+ import styled, { ThemeProvider } from "styled-components"
114
288
 
115
- ## Package Structure
289
+ const Panel = styled.section`
290
+ padding: ${mwThemeVars.spacing.sp24};
291
+ color: ${mwThemeVars.color.text};
292
+ background: ${mwThemeVars.color.surface};
293
+ border-radius: ${mwThemeVars.ui.radius};
294
+ `
116
295
 
296
+ const InlinePanel = () => (
297
+ <div
298
+ style={{
299
+ [mwThemeVarNames.color.focus]: "#FF00AA",
300
+ color: mwThemeVars.color.text,
301
+ outlineColor: mwVar("--mw-color-focus", "#2457FF"),
302
+ }}
303
+ />
304
+ )
305
+
306
+ const AppTheme = ({ children }: { children: ReactNode }) => (
307
+ <ThemeProvider theme={mwStyledTheme}>{children}</ThemeProvider>
308
+ )
309
+ ```
310
+
311
+ Plain CSS and CSS Modules do not need a JavaScript bridge:
312
+
313
+ ```css
314
+ .panel {
315
+ padding: var(--mw-spacing-sp-24);
316
+ color: var(--mw-color-text);
317
+ border-radius: var(--mw-ui-radius);
318
+ }
319
+ ```
320
+
321
+ This enables React apps to keep custom panels, local layouts, third-party CSS-in-JS components, and design-tool integrations visually tied to the same active theme as Marwes components. Changing `MarwesProvider theme={...}` updates both preset components and app-owned styles.
322
+
323
+ Keep the APIs separate:
324
+ - Use `Spacings.sp24` for Marwes spacing props such as `<Spacer spacing={Spacings.sp24} />`.
325
+ - Use `mwThemeVars.spacing.sp24` for custom CSS values.
326
+ - Use `mwThemeVarNames.spacing.sp24` when assigning or inspecting a CSS custom property name.
327
+ - Use `useTheme()` when React logic needs resolved runtime values such as `"#2457FF"`.
328
+
329
+ ## Google Fonts DX
330
+
331
+ Most Google Font use cases only need `mwAvailableFonts`; no `fontLoading` prop is needed.
332
+
333
+ ```tsx
334
+ import { MarwesProvider, mwAvailableFonts } from "@marwes-ui/react"
335
+
336
+ <MarwesProvider
337
+ theme={{
338
+ font: {
339
+ primary: mwAvailableFonts.Poppins,
340
+ secondary: mwAvailableFonts.Lora,
341
+ },
342
+ }}
343
+ >
344
+ <App />
345
+ </MarwesProvider>
346
+ ```
347
+
348
+ For self-hosted or licensed fonts, use `BrandSans`, `BrandSerif`, `BrandMono`, or `createFontStack()`.
349
+
350
+ ## Semantic Buttons
351
+
352
+ Prefer purpose components for common actions. They lock UX intent and emit AI-readable metadata, so the component is not just "a button with red styling" but a known action with known risk.
353
+
354
+ ```tsx
355
+ import {
356
+ CancelButton,
357
+ CreateButton,
358
+ DestructiveButton,
359
+ SubmitButton,
360
+ } from "@marwes-ui/react"
361
+
362
+ <CancelButton>Cancel</CancelButton>
363
+ <CreateButton>Create</CreateButton>
364
+ <SubmitButton>Save</SubmitButton>
365
+ <DestructiveButton>Delete</DestructiveButton>
366
+ ```
367
+
368
+ That matters for agentic workflows. A human, test, or AI agent can inspect the DOM and see that a destructive button requires confirmation before activation:
369
+
370
+ ```html
371
+ <button
372
+ data-component="button"
373
+ data-purpose="destructive"
374
+ data-action="delete"
375
+ data-destructive="true"
376
+ data-confirmation-required="true"
377
+ >
378
+ Delete
379
+ </button>
380
+ ```
381
+
382
+ An agent can then follow a safer rule: if `data-confirmation-required="true"`, ask the user before clicking. A test can assert the same behavior without guessing from the label "Delete" or from a red color.
383
+
384
+ Use raw `Button` props when you intentionally need a custom combination.
385
+
386
+ ```tsx
387
+ import { Button, ButtonAction, ButtonSize, ButtonVariant } from "@marwes-ui/react"
388
+
389
+ <Button
390
+ action={ButtonAction.submit}
391
+ size={ButtonSize.md}
392
+ variant={ButtonVariant.primary}
393
+ >
394
+ Submit
395
+ </Button>
117
396
  ```
118
- dist/ # Build output (npm published files)
119
- ├── index.js # ESM bundle
120
- ├── index.d.ts # TypeScript declarations
121
- └── index.js.map # Source maps
122
-
123
- src/ # Source files (not published)
124
- ├── components/ # React components
125
- ├── hooks/ # React hooks
126
- └── provider/ # Context provider
127
-
128
- tsconfig.json # TypeScript config (noEmit: true)
129
- tsup.config.ts # Build configuration
397
+
398
+ ## Why It Is Accessible
399
+
400
+ Marwes React components are accessible because the adapter renders a shared core contract, not because each component hand-rolls ARIA in isolation.
401
+
402
+ - Core recipes produce typed `a11y` output for roles, labels, described-by wiring, invalid state, disabled state, and semantic metadata.
403
+ - React components prefer native DOM controls first: `button`, `input`, `select`, `textarea`, `hr`, and standard form wiring.
404
+ - Field components connect visible labels, helper text, and errors through `id`, `htmlFor`, `aria-describedby`, `aria-invalid`, and polite error announcements.
405
+ - Coordinated widgets carry explicit contracts: tabs wire `tablist`/`tab`/`tabpanel`, dialogs own dialog semantics, toasts expose live-region behavior, and purpose buttons expose risk metadata.
406
+ - Storybook accessibility smoke checks run through the Storybook a11y addon for the promoted React families, and shared contract tests keep React aligned with Vue.
407
+
408
+ Example:
409
+
410
+ ```tsx
411
+ import { InputField } from "@marwes-ui/react"
412
+
413
+ <InputField
414
+ label="Email"
415
+ helperText="Used for receipts."
416
+ error="Enter a valid email."
417
+ input={{ type: "email", placeholder: "you@example.com" }}
418
+ />
130
419
  ```
131
420
 
132
- **Important**: The `dist/` folder is generated by `pnpm build` and should never be edited directly. Only the `dist/` folder is published to npm (configured in `package.json` `files` field).
421
+ That contract resolves to DOM wiring like:
422
+
423
+ ```html
424
+ <label for="email">Email</label>
425
+ <input
426
+ id="email"
427
+ type="email"
428
+ aria-describedby="email-helper email-error"
429
+ aria-invalid="true"
430
+ >
431
+ <p id="email-helper">Used for receipts.</p>
432
+ <p id="email-error" aria-live="polite">Enter a valid email.</p>
433
+ ```
434
+
435
+ The important part is that the same label, helper, error, and invalid contract is tested at the shared contract layer and then applied by the React adapter.
436
+
437
+ ## Package Boundaries
438
+
439
+ - `@marwes-ui/core` owns recipes, theme resolution, a11y mapping, and semantic metadata.
440
+ - `@marwes-ui/presets` owns first edition CSS.
441
+ - `@marwes-ui/react` owns React rendering and provider behavior.
442
+
443
+ ## Scripts
444
+
445
+ ```bash
446
+ pnpm --filter @marwes-ui/react build
447
+ pnpm --filter @marwes-ui/react typecheck
448
+ pnpm --filter @marwes-ui/react test
449
+ ```
133
450
 
134
451
  ## Related Docs
135
- - `../../docs/PROJECT.md`
136
- - `../../docs/ARCHITECTURE.md`
137
- - `../../docs/ENGINEERING.md`
452
+
453
+ - [Docs index](https://github.com/niklas-westman/marwes/tree/main/docs)
454
+ - [Architecture](https://github.com/niklas-westman/marwes/blob/main/docs/reference/architecture.md)
455
+ - [Figma to Marwes](https://github.com/niklas-westman/marwes/blob/main/docs/guides/figma-to-marwes.md)