@marwes-ui/presets 0.0.4 → 1.0.1
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 +1 -1
- package/README.md +271 -47
- package/dist/chunk-2JNIKK66.js +21 -0
- package/dist/chunk-2JNIKK66.js.map +1 -0
- package/dist/firstEdition/index.d.ts +3 -3
- package/dist/firstEdition/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +15 -9
- package/src/firstEdition/accordion.css +140 -0
- package/src/firstEdition/avatar.css +204 -0
- package/src/firstEdition/badge.css +139 -0
- package/src/firstEdition/button.css +219 -0
- package/src/firstEdition/card.css +136 -0
- package/src/firstEdition/checkbox.css +214 -0
- package/src/firstEdition/dialog.css +149 -0
- package/src/firstEdition/divider.css +37 -0
- package/src/firstEdition/icon.css +72 -0
- package/src/firstEdition/index.ts +19 -0
- package/src/firstEdition/input-otp.css +107 -0
- package/src/firstEdition/input.css +73 -0
- package/src/firstEdition/molecules/accordion-field.css +46 -0
- package/src/firstEdition/molecules/checkbox-field.css +53 -0
- package/src/firstEdition/molecules/checkbox-group-field.css +67 -0
- package/src/firstEdition/molecules/dialog-modal.css +34 -0
- package/src/firstEdition/molecules/input-field.css +260 -0
- package/src/firstEdition/molecules/radio-group-field.css +59 -0
- package/src/firstEdition/molecules/slider-field.css +83 -0
- package/src/firstEdition/molecules/switch-field.css +37 -0
- package/src/firstEdition/molecules/tab-group.css +26 -0
- package/src/firstEdition/molecules/toast-container.css +45 -0
- package/src/firstEdition/radio.css +121 -0
- package/src/firstEdition/rich-text.css +134 -0
- package/src/firstEdition/select.css +337 -0
- package/src/firstEdition/slider.css +228 -0
- package/src/firstEdition/spacing.css +6 -0
- package/src/firstEdition/spinner.css +94 -0
- package/src/firstEdition/styles.css +27 -0
- package/src/firstEdition/switch.css +156 -0
- package/src/firstEdition/tab.css +81 -0
- package/src/firstEdition/textarea.css +63 -0
- package/src/firstEdition/toast.css +318 -0
- package/src/firstEdition/tokens.css +35 -0
- package/src/firstEdition/tooltip.css +112 -0
- package/src/firstEdition/typography.css +33 -0
- package/dist/chunk-UJIVT75P.js +0 -26
- package/dist/chunk-UJIVT75P.js.map +0 -1
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,68 +1,292 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img alt="Marwes Design System" src="https://raw.githubusercontent.com/niklas-westman/marwes/main/.github/assets/banner-light.png" width="100%" style="border-radius: 40px;">
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Provide static CSS for `.mw-*` classnames.
|
|
8
|
-
- Map semantic theme values to visual styles with CSS variables.
|
|
5
|
+
<br>
|
|
6
|
+
<br>
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
# Marwes Design System - Presets
|
|
9
|
+
|
|
10
|
+
**Static default CSS and preset theme exports for Marwes React and Vue apps.**
|
|
11
|
+
|
|
12
|
+
Static `.mw-*` CSS • CSS variables • Default Marwes visuals • No runtime CSS-in-JS
|
|
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
|
+
Most apps install `@marwes-ui/react` or `@marwes-ui/vue`, and those adapters load the default preset automatically. Install presets directly when you need the standalone CSS path, the explicit `firstEditionTheme` object, or preset CSS in a custom adapter.
|
|
23
|
+
|
|
24
|
+
Presets gives Marwes its default visual layer:
|
|
25
|
+
|
|
26
|
+
- default component CSS
|
|
27
|
+
- theme-variable driven colors, radius, focus, typography, density, and state styling
|
|
28
|
+
- stable `.mw-*` class styling for every shipped component family
|
|
29
|
+
- no CSS-in-JS runtime
|
|
30
|
+
- CSS that follows the same core recipes used by React and Vue
|
|
31
|
+
|
|
32
|
+
## Package Map
|
|
33
|
+
|
|
34
|
+
Presets are the static visual layer, not the normal app entry point.
|
|
35
|
+
|
|
36
|
+
| Package | Use it when |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `@marwes-ui/react` | You are building a React app. |
|
|
39
|
+
| `@marwes-ui/vue` | You are building a Vue app. |
|
|
40
|
+
| `@marwes-ui/core` | You need framework-agnostic recipes, theme utilities, accessibility contracts, or adapter/tooling APIs. |
|
|
41
|
+
| `@marwes-ui/presets` | You need standalone preset CSS or preset theme exports. |
|
|
42
|
+
|
|
43
|
+
This package gives humans and AI agents a predictable CSS contract: `.mw-*` classes consume `--mw-*` variables generated by the provider, while adapters stay thin.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pnpm add @marwes-ui/presets
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Normal App Setup
|
|
52
|
+
|
|
53
|
+
React and Vue apps normally import only the adapter:
|
|
14
54
|
|
|
15
|
-
## Install and Use
|
|
16
55
|
```tsx
|
|
17
|
-
import { MarwesProvider } from "@marwes-ui/react"
|
|
18
|
-
import { firstEdition } from "@marwes-ui/presets";
|
|
19
|
-
import "@marwes-ui/presets/firstEdition/styles.css";
|
|
56
|
+
import { Button, ButtonVariant, MarwesProvider } from "@marwes-ui/react"
|
|
20
57
|
|
|
21
|
-
|
|
58
|
+
export function App() {
|
|
59
|
+
return (
|
|
60
|
+
<MarwesProvider>
|
|
61
|
+
<Button variant={ButtonVariant.primary}>Save</Button>
|
|
62
|
+
</MarwesProvider>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Direct CSS Import
|
|
68
|
+
|
|
69
|
+
Use the direct CSS path for custom adapters, static prototypes, or tooling that needs the preset without the React/Vue entry.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import "@marwes-ui/presets/firstEdition/styles.css"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Available Styled Families
|
|
76
|
+
|
|
77
|
+
The default preset styles these Marwes families today:
|
|
78
|
+
|
|
79
|
+
- Accordion and accordion fields
|
|
80
|
+
- Avatar and avatar groups
|
|
81
|
+
- Badge and contextual badge variants
|
|
82
|
+
- Button and purpose button variants
|
|
83
|
+
- Card variants
|
|
84
|
+
- Checkbox, checkbox fields, and checkbox groups
|
|
85
|
+
- Dialog and dialog modal
|
|
86
|
+
- Divider
|
|
87
|
+
- Icon
|
|
88
|
+
- Input, textarea, select, rich text, OTP, and field variants
|
|
89
|
+
- Paragraph and heading typography
|
|
90
|
+
- Radio and radio groups
|
|
91
|
+
- Slider and slider fields
|
|
92
|
+
- Spacing and spacer primitives
|
|
93
|
+
- Spinner variants
|
|
94
|
+
- Switch and switch fields
|
|
95
|
+
- Tab groups and panels
|
|
96
|
+
- Toast and toast container
|
|
97
|
+
- Tooltip and tooltip groups
|
|
98
|
+
|
|
99
|
+
## Custom Theme With Preset CSS
|
|
100
|
+
|
|
101
|
+
Preset CSS consumes provider-generated `--mw-*` variables. Marwes is designed to look great from the beginning: map an existing design library or graphical profile into a partial `ThemeInput`, override only the tokens your product owns, pass it to `MarwesProvider`, and the preset follows it.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { MarwesProvider, mwAvailableFonts, type ThemeInput } from "@marwes-ui/react"
|
|
105
|
+
|
|
106
|
+
const brandTheme = {
|
|
107
|
+
color: {
|
|
108
|
+
primary: "#2457FF",
|
|
109
|
+
danger: "#D90429",
|
|
110
|
+
success: "#15803D",
|
|
111
|
+
warning: "#D97706",
|
|
112
|
+
background: "#F8FAFC",
|
|
113
|
+
surface: "#FFFFFF",
|
|
114
|
+
surfaceElevated: "#FFFFFF",
|
|
115
|
+
text: "#111827",
|
|
116
|
+
textMuted: "#4B5563",
|
|
117
|
+
border: "#D1D5DB",
|
|
118
|
+
focus: "#2457FF",
|
|
119
|
+
},
|
|
120
|
+
font: {
|
|
121
|
+
primary: mwAvailableFonts.Poppins,
|
|
122
|
+
secondary: mwAvailableFonts.Lora,
|
|
123
|
+
},
|
|
124
|
+
ui: {
|
|
125
|
+
radius: 10,
|
|
126
|
+
density: "comfortable",
|
|
127
|
+
},
|
|
128
|
+
} satisfies ThemeInput
|
|
129
|
+
|
|
130
|
+
<MarwesProvider theme={brandTheme}>
|
|
22
131
|
<App />
|
|
23
|
-
</MarwesProvider
|
|
132
|
+
</MarwesProvider>
|
|
24
133
|
```
|
|
25
134
|
|
|
26
|
-
##
|
|
27
|
-
Preset definition:
|
|
28
|
-
- `src/firstEdition/index.ts`
|
|
135
|
+
## Light And Dark Mode
|
|
29
136
|
|
|
30
|
-
|
|
31
|
-
- `src/firstEdition/styles.css`
|
|
137
|
+
The preset CSS already contains the light and dark visual rules. In React and Vue apps, use `ThemeMode.light` and `ThemeMode.dark` instead of string literals, then let `MarwesProvider` own the active mode and toggle it with the adapter hook:
|
|
32
138
|
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
139
|
+
```tsx
|
|
140
|
+
import { Button, ButtonVariant, MarwesProvider, ThemeMode, useThemeMode } from "@marwes-ui/react"
|
|
141
|
+
|
|
142
|
+
function ThemeToggle() {
|
|
143
|
+
const { mode, toggleMode } = useThemeMode()
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<Button variant={ButtonVariant.secondary} onClick={toggleMode}>
|
|
147
|
+
Use {mode === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark} mode
|
|
148
|
+
</Button>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function App() {
|
|
153
|
+
return (
|
|
154
|
+
<MarwesProvider defaultMode={ThemeMode.light}>
|
|
155
|
+
<ThemeToggle />
|
|
156
|
+
<AppShell />
|
|
157
|
+
</MarwesProvider>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
When the mode changes, the provider updates the preset's `--mw-*` variables and root class. Preset selectors such as `.mw-theme--dark .mw-btn` then pick up the correct dark-mode component states without any extra CSS in the app.
|
|
163
|
+
|
|
164
|
+
You do not need a `themeByMode` map for the normal toggle. With no `theme` prop, Marwes uses its default light and dark palettes. With shared brand overrides, pass the same partial `theme` object and the provider still swaps every omitted token by mode.
|
|
165
|
+
|
|
166
|
+
Use a `themeByMode` map only when your product wants different brand overrides in light and dark mode, such as a different primary color or surface color per mode:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
import { useState } from "react"
|
|
170
|
+
import {
|
|
171
|
+
Button,
|
|
172
|
+
ButtonVariant,
|
|
173
|
+
MarwesProvider,
|
|
174
|
+
ThemeMode,
|
|
175
|
+
type ThemeInput,
|
|
176
|
+
useThemeMode,
|
|
177
|
+
} from "@marwes-ui/react"
|
|
178
|
+
|
|
179
|
+
const themeByMode = {
|
|
180
|
+
[ThemeMode.light]: { color: { primary: "#2457FF", background: "#F8FAFC", text: "#111827" } },
|
|
181
|
+
[ThemeMode.dark]: { color: { primary: "#8BA2FF", background: "#0B1020", text: "#F8FAFC" } },
|
|
182
|
+
} satisfies Record<ThemeMode, ThemeInput>
|
|
183
|
+
|
|
184
|
+
function ThemeToggle() {
|
|
185
|
+
const { mode, toggleMode } = useThemeMode()
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<Button variant={ButtonVariant.secondary} onClick={toggleMode}>
|
|
189
|
+
Use {mode === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark} mode
|
|
190
|
+
</Button>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function App() {
|
|
195
|
+
const [mode, setMode] = useState<ThemeMode>(ThemeMode.light)
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<MarwesProvider mode={mode} theme={themeByMode[mode]} onModeChange={setMode}>
|
|
199
|
+
<ThemeToggle />
|
|
200
|
+
<AppShell />
|
|
201
|
+
</MarwesProvider>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## firstEditionTheme
|
|
207
|
+
|
|
208
|
+
`firstEditionTheme` remains exported for explicit or advanced use. React and Vue providers already use the same baseline by default, so normal app code does not need to pass it.
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { firstEditionTheme } from "@marwes-ui/presets"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## CSS Contract
|
|
40
215
|
|
|
41
|
-
## Contract with Core
|
|
42
216
|
Core recipes emit:
|
|
43
|
-
- stable classes such as
|
|
44
|
-
-
|
|
217
|
+
- stable classes such as `.mw-btn`, `.mw-input`, `.mw-checkbox`, `.mw-card`
|
|
218
|
+
- component-scoped vars where needed
|
|
219
|
+
- semantic theme variables such as `--mw-color-primary-base`, `--mw-color-text`, and `--mw-ui-radius`
|
|
220
|
+
- fixed spacing variables such as `--mw-spacing-sp-24`
|
|
45
221
|
|
|
46
|
-
|
|
222
|
+
Preset CSS must style those classes and variables consistently without adapter-specific hacks.
|
|
47
223
|
|
|
48
|
-
|
|
49
|
-
- Keep prefix `--mw-*` for variables.
|
|
50
|
-
- Keep classname prefix `.mw-*`.
|
|
51
|
-
- Prefer semantic vars from core (`--mw-primary`, `--mw-text`, `--mw-surface`) over hardcoded colors.
|
|
52
|
-
- Keep focus-visible and disabled states explicit in CSS.
|
|
224
|
+
Plain CSS can use those variables anywhere under `MarwesProvider`:
|
|
53
225
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
226
|
+
```css
|
|
227
|
+
.project-panel {
|
|
228
|
+
padding: var(--mw-spacing-sp-24);
|
|
229
|
+
color: var(--mw-color-text);
|
|
230
|
+
background: var(--mw-color-surface);
|
|
231
|
+
border: 1px solid var(--mw-color-border);
|
|
232
|
+
border-radius: var(--mw-ui-radius);
|
|
233
|
+
}
|
|
234
|
+
```
|
|
57
235
|
|
|
58
|
-
|
|
236
|
+
JavaScript styling layers should import token helpers from `@marwes-ui/core`, `@marwes-ui/react`, or `@marwes-ui/vue` instead of duplicating `var(...)` strings.
|
|
237
|
+
|
|
238
|
+
Use the helper that matches the job:
|
|
239
|
+
|
|
240
|
+
- `mwThemeVars` returns CSS `var(...)` references for app-owned CSS-in-JS, style objects, vanilla-extract, and config files.
|
|
241
|
+
- `mwThemeVarNames` returns raw custom property names for assigning overrides or inspecting the preset CSS contract.
|
|
242
|
+
- `mwVar()` wraps custom or advanced `--mw-*` names with optional fallback support.
|
|
243
|
+
- `mwStyledTheme` mirrors `mwThemeVars` as a plain theme object for styled-components and Emotion integrations.
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import { mwThemeVarNames, mwThemeVars, mwVar } from "@marwes-ui/core"
|
|
247
|
+
|
|
248
|
+
const panelStyle = {
|
|
249
|
+
padding: mwThemeVars.spacing.sp24,
|
|
250
|
+
color: mwThemeVars.color.text,
|
|
251
|
+
outlineColor: mwVar("--mw-color-focus", "#2457FF"),
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const localOverride = {
|
|
255
|
+
[mwThemeVarNames.color.focus]: "#FF00AA",
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
These helpers exist so preset CSS, adapter components, and custom application styles all follow the same provider-generated variables. That enables custom layouts and third-party styling systems to stay visually aligned with the default preset without depending on React, Vue, styled-components, or Emotion.
|
|
260
|
+
|
|
261
|
+
## Accessible Styling Contract
|
|
262
|
+
|
|
263
|
+
Presets make the semantic contract visible without replacing it. Core and the adapters own roles, labels, state, and ARIA wiring; preset CSS owns the visual states that users need to perceive.
|
|
264
|
+
|
|
265
|
+
That means the default CSS includes styling for:
|
|
266
|
+
|
|
267
|
+
- visible focus states on interactive controls
|
|
268
|
+
- disabled, invalid, selected, expanded, checked, and busy states
|
|
269
|
+
- theme-driven text and background colors with contrast-aware defaults
|
|
270
|
+
- component classes that match the same recipes used by React and Vue
|
|
271
|
+
|
|
272
|
+
Example: an invalid input field is accessible because the adapter applies `aria-invalid` and `aria-describedby`; the preset then makes that same invalid state visually obvious through `.mw-input-field--invalid` and related input classes.
|
|
273
|
+
|
|
274
|
+
## Package Boundaries
|
|
275
|
+
|
|
276
|
+
- `@marwes-ui/core` owns recipes, semantic metadata, and theme resolution.
|
|
277
|
+
- `@marwes-ui/presets` owns static default CSS.
|
|
278
|
+
- `@marwes-ui/react` and `@marwes-ui/vue` load this preset by default and render components.
|
|
59
279
|
|
|
60
280
|
## Scripts
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
pnpm --filter @marwes-ui/presets build
|
|
284
|
+
pnpm --filter @marwes-ui/presets typecheck
|
|
285
|
+
pnpm --filter @marwes-ui/presets test
|
|
286
|
+
```
|
|
64
287
|
|
|
65
288
|
## Related Docs
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
289
|
+
|
|
290
|
+
- [Docs index](https://github.com/niklas-westman/marwes/tree/main/docs)
|
|
291
|
+
- [Architecture](https://github.com/niklas-westman/marwes/blob/main/docs/reference/architecture.md)
|
|
292
|
+
- [Figma to Marwes](https://github.com/niklas-westman/marwes/blob/main/docs/guides/figma-to-marwes.md)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import '@fontsource/instrument-sans/400.css';
|
|
2
|
+
import '@fontsource/instrument-sans/500.css';
|
|
3
|
+
import '@fontsource/instrument-sans/600.css';
|
|
4
|
+
|
|
5
|
+
// src/firstEdition/index.ts
|
|
6
|
+
var firstEditionTheme = {
|
|
7
|
+
color: {
|
|
8
|
+
primary: {
|
|
9
|
+
base: "#2F31FC",
|
|
10
|
+
label: "#FFFFFF",
|
|
11
|
+
labelDisabled: "rgba(255,255,255,0.5)"
|
|
12
|
+
},
|
|
13
|
+
success: "#00875A"
|
|
14
|
+
},
|
|
15
|
+
font: { primary: "'Instrument Sans', Inter, system-ui, sans-serif" },
|
|
16
|
+
ui: { radius: 4, density: "comfortable" }
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { firstEditionTheme };
|
|
20
|
+
//# sourceMappingURL=chunk-2JNIKK66.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-2JNIKK66.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/firstEdition/index.ts"],"names":[],"mappings":";;;;;AAOO,IAAM,iBAAA,GAAgC;AAAA,EAC3C,KAAA,EAAO;AAAA,IACL,OAAA,EAAS;AAAA,MACP,IAAA,EAAM,SAAA;AAAA,MACN,KAAA,EAAO,SAAA;AAAA,MACP,aAAA,EAAe;AAAA,KACjB;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AAAA,EACA,IAAA,EAAM,EAAE,OAAA,EAAS,iDAAA,EAAkD;AAAA,EACnE,EAAA,EAAI,EAAE,MAAA,EAAQ,CAAA,EAAG,SAAS,aAAA;AAC5B","file":"chunk-2JNIKK66.js","sourcesContent":["import type { ThemeInput } from \"@marwes-ui/core\"\nimport \"@fontsource/instrument-sans/400.css\"\nimport \"@fontsource/instrument-sans/500.css\"\nimport \"@fontsource/instrument-sans/600.css\"\n\n// Explicit ThemeInput for consumers that still want to import the preset object.\n// MarwesProvider uses the same first edition baseline when no theme is provided.\nexport const firstEditionTheme: ThemeInput = {\n color: {\n primary: {\n base: \"#2F31FC\",\n label: \"#FFFFFF\",\n labelDisabled: \"rgba(255,255,255,0.5)\",\n },\n success: \"#00875A\",\n },\n font: { primary: \"'Instrument Sans', Inter, system-ui, sans-serif\" },\n ui: { radius: 4, density: \"comfortable\" },\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { firstEditionTheme } from './firstEdition/index.js';
|
|
2
|
+
export { ThemeInput } from '@marwes-ui/core';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marwes-ui/presets",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
+
"license": "MIT",
|
|
7
8
|
"private": false,
|
|
8
9
|
"type": "module",
|
|
9
|
-
"sideEffects":
|
|
10
|
+
"sideEffects": [
|
|
11
|
+
"*.css",
|
|
12
|
+
"**/*.css"
|
|
13
|
+
],
|
|
10
14
|
"main": "./dist/index.js",
|
|
11
15
|
"types": "./dist/index.d.ts",
|
|
12
16
|
"exports": {
|
|
@@ -22,22 +26,24 @@
|
|
|
22
26
|
},
|
|
23
27
|
"files": [
|
|
24
28
|
"dist",
|
|
25
|
-
"src/firstEdition
|
|
29
|
+
"src/firstEdition"
|
|
26
30
|
],
|
|
27
31
|
"dependencies": {
|
|
28
|
-
"@fontsource/instrument-sans": "
|
|
29
|
-
"@marwes-ui/core": "
|
|
32
|
+
"@fontsource/instrument-sans": "5.2.8",
|
|
33
|
+
"@marwes-ui/core": "1.0.1"
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
|
-
"rimraf": "
|
|
33
|
-
"tsup": "
|
|
34
|
-
"typescript": "
|
|
36
|
+
"rimraf": "6.1.2",
|
|
37
|
+
"tsup": "8.5.1",
|
|
38
|
+
"typescript": "5.9.3",
|
|
39
|
+
"vitest": "4.0.18"
|
|
35
40
|
},
|
|
36
41
|
"scripts": {
|
|
37
42
|
"dev": "tsup --watch",
|
|
38
43
|
"build": "tsup",
|
|
39
44
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
40
|
-
"test": "
|
|
45
|
+
"test:typecheck": "tsc -p tsconfig.test.json --noEmit",
|
|
46
|
+
"test": "vitest run",
|
|
41
47
|
"clean": "rimraf dist",
|
|
42
48
|
"lint": "biome lint .",
|
|
43
49
|
"format": "biome format --write ."
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Accordion Component Styles
|
|
3
|
+
* Validated against the latest live Figma sync:
|
|
4
|
+
* - .figma/marwes/components/accordion.json
|
|
5
|
+
* - .figma/marwes/pages/-accordion/-accordion_1364-11755.json
|
|
6
|
+
* - .figma/marwes/pages/-accordion/-accordion-dark_2276-47132.json
|
|
7
|
+
*
|
|
8
|
+
* Light state colors:
|
|
9
|
+
* default surface #ffffff
|
|
10
|
+
* hover surface #f3f4f6
|
|
11
|
+
* pressed surface #e5e7eb
|
|
12
|
+
* border #e5e7eb
|
|
13
|
+
* focus border #2f31fc
|
|
14
|
+
* title #141414
|
|
15
|
+
* icon/content #595959
|
|
16
|
+
* disabled text #737373
|
|
17
|
+
*
|
|
18
|
+
* Dark state colors:
|
|
19
|
+
* default surface #2e2e2e
|
|
20
|
+
* hover surface #595959
|
|
21
|
+
* pressed surface #737373
|
|
22
|
+
* border #474747
|
|
23
|
+
* focus border #5859fc
|
|
24
|
+
* title #f9fafb
|
|
25
|
+
* icon/content #a3a3a3
|
|
26
|
+
* disabled text #595959
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
.mw-accordion {
|
|
30
|
+
--mw-accordion-title: var(--mw-color-text);
|
|
31
|
+
--mw-accordion-icon: var(--mw-color-text-muted);
|
|
32
|
+
--mw-accordion-content: var(--mw-color-text-muted);
|
|
33
|
+
--mw-accordion-surface: var(--mw-color-surface-elevated);
|
|
34
|
+
--mw-accordion-surface-hover: var(--mw-color-surface-subtle);
|
|
35
|
+
--mw-accordion-surface-pressed: var(--mw-color-border-subtle);
|
|
36
|
+
--mw-accordion-border: var(--mw-color-border-subtle);
|
|
37
|
+
--mw-accordion-focus-border: var(--mw-color-focus, #2f31fc);
|
|
38
|
+
--mw-accordion-title-disabled: var(--mw-color-text-disabled);
|
|
39
|
+
--mw-accordion-icon-disabled: var(--mw-color-text-disabled);
|
|
40
|
+
--mw-accordion-content-disabled: var(--mw-color-text-disabled);
|
|
41
|
+
|
|
42
|
+
width: 100%;
|
|
43
|
+
background: var(--mw-accordion-surface);
|
|
44
|
+
border: 1px solid var(--mw-accordion-border);
|
|
45
|
+
border-radius: var(--mw-ui-radius, 6px);
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
transition: background-color 150ms ease, border-color 150ms ease;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.mw-accordion__trigger {
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: space-between;
|
|
54
|
+
width: 100%;
|
|
55
|
+
padding: 16px;
|
|
56
|
+
border: none;
|
|
57
|
+
background: transparent;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
text-align: left;
|
|
60
|
+
gap: 8px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.mw-accordion__title {
|
|
64
|
+
flex: 1;
|
|
65
|
+
font-family: var(--mw-font-primary, inherit);
|
|
66
|
+
font-size: var(--mw-density-font-size, 14px);
|
|
67
|
+
font-weight: 500;
|
|
68
|
+
line-height: 16px;
|
|
69
|
+
color: var(--mw-accordion-title);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.mw-accordion__icon {
|
|
73
|
+
display: inline-block;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
width: 16px;
|
|
76
|
+
height: 16px;
|
|
77
|
+
background-color: var(--mw-accordion-icon);
|
|
78
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolyline fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
|
79
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolyline fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
|
80
|
+
mask-repeat: no-repeat;
|
|
81
|
+
mask-position: center;
|
|
82
|
+
mask-size: contain;
|
|
83
|
+
-webkit-mask-repeat: no-repeat;
|
|
84
|
+
-webkit-mask-position: center;
|
|
85
|
+
-webkit-mask-size: contain;
|
|
86
|
+
transition: transform 200ms ease;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.mw-accordion--open .mw-accordion__icon {
|
|
90
|
+
transform: rotate(180deg);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.mw-accordion:not(.mw-accordion--disabled):hover {
|
|
94
|
+
background: var(--mw-accordion-surface-hover);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.mw-accordion:not(.mw-accordion--disabled) .mw-accordion__trigger:active,
|
|
98
|
+
.mw-accordion:not(.mw-accordion--disabled) .mw-accordion__trigger:active + .mw-accordion__panel {
|
|
99
|
+
background: var(--mw-accordion-surface-pressed);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.mw-accordion:focus-within {
|
|
103
|
+
border-color: var(--mw-accordion-focus-border);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.mw-accordion__trigger:focus-visible {
|
|
107
|
+
outline: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.mw-accordion__content {
|
|
111
|
+
padding: 0 16px 16px;
|
|
112
|
+
font-family: var(--mw-font-primary, inherit);
|
|
113
|
+
font-size: var(--mw-density-font-size, 14px);
|
|
114
|
+
line-height: 20px;
|
|
115
|
+
color: var(--mw-accordion-content);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.mw-accordion--disabled {
|
|
119
|
+
--mw-accordion-title: var(--mw-accordion-title-disabled);
|
|
120
|
+
--mw-accordion-icon: var(--mw-accordion-icon-disabled);
|
|
121
|
+
--mw-accordion-content: var(--mw-accordion-content-disabled);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.mw-accordion--disabled .mw-accordion__trigger {
|
|
125
|
+
cursor: not-allowed;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.mw-theme--dark .mw-accordion {
|
|
129
|
+
--mw-accordion-title: var(--mw-color-text);
|
|
130
|
+
--mw-accordion-icon: var(--mw-color-text-muted);
|
|
131
|
+
--mw-accordion-content: var(--mw-color-text-muted);
|
|
132
|
+
--mw-accordion-surface: var(--mw-color-surface-elevated);
|
|
133
|
+
--mw-accordion-surface-hover: var(--mw-color-surface-subtle);
|
|
134
|
+
--mw-accordion-surface-pressed: var(--mw-color-border);
|
|
135
|
+
--mw-accordion-border: var(--mw-color-border-subtle);
|
|
136
|
+
--mw-accordion-focus-border: var(--mw-color-focus, #5859fc);
|
|
137
|
+
--mw-accordion-title-disabled: var(--mw-color-text-disabled);
|
|
138
|
+
--mw-accordion-icon-disabled: var(--mw-color-text-disabled);
|
|
139
|
+
--mw-accordion-content-disabled: var(--mw-color-text-disabled);
|
|
140
|
+
}
|