@marwes-ui/react 1.0.4 → 1.1.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/README.md +6 -0
- package/dist/chunk-VFY2GW62.js +34 -0
- package/dist/chunk-VFY2GW62.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/ssr.d.ts +16 -0
- package/dist/ssr.js +3 -0
- package/dist/ssr.js.map +1 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -395,6 +395,12 @@ Marwes is compatible with Tailwind and shadcn-style dark variants through `targe
|
|
|
395
395
|
|
|
396
396
|
Read the [Tailwind and shadcn integration guide](https://github.com/niklas-westman/marwes/blob/main/docs/guides/tailwind-shadcn-integration.md) for Tailwind v3/v4 examples, token mapping, provider-scoped variable limits, and the SSR no-flash boundary.
|
|
397
397
|
|
|
398
|
+
### Next.js App Router SSR
|
|
399
|
+
|
|
400
|
+
Use `MarwesThemeStyle`, `MarwesThemeScript`, and `variableStrategy="style-tag"` when a server-rendered app needs the correct light or dark variables before hydration. This is opt-in; normal React apps keep inline provider variables by default.
|
|
401
|
+
|
|
402
|
+
Read the [theme SSR no-flash guide](https://github.com/niklas-westman/marwes/blob/main/docs/guides/theme-ssr-no-flash.md) for Next.js App Router setup, CSP nonces, `suppressHydrationWarning`, custom light/dark themes, and stored/system preference behavior.
|
|
403
|
+
|
|
398
404
|
For a simple brand pass, override shared values once and let Marwes fill the rest. If your product needs different brand colors in light and dark mode, control `mode` and switch between two small `ThemeInput` override objects:
|
|
399
405
|
|
|
400
406
|
```tsx
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createMarwesThemeScript as createMarwesThemeScript$1, createMarwesThemeStyle as createMarwesThemeStyle$1 } from '@marwes-ui/core';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/ssr.tsx
|
|
5
|
+
function createMarwesThemeScript(options) {
|
|
6
|
+
return createMarwesThemeScript$1(options);
|
|
7
|
+
}
|
|
8
|
+
function createMarwesThemeStyle(options) {
|
|
9
|
+
return createMarwesThemeStyle$1(options);
|
|
10
|
+
}
|
|
11
|
+
function MarwesThemeScript({ nonce, ...options }) {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"script",
|
|
14
|
+
{
|
|
15
|
+
"data-marwes-ssr-theme-script": "true",
|
|
16
|
+
nonce,
|
|
17
|
+
dangerouslySetInnerHTML: { __html: createMarwesThemeScript(options) }
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
function MarwesThemeStyle({ nonce, ...options }) {
|
|
22
|
+
return /* @__PURE__ */ jsx(
|
|
23
|
+
"style",
|
|
24
|
+
{
|
|
25
|
+
"data-marwes-ssr-theme-style": "true",
|
|
26
|
+
nonce,
|
|
27
|
+
dangerouslySetInnerHTML: { __html: createMarwesThemeStyle(options) }
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { MarwesThemeScript, MarwesThemeStyle, createMarwesThemeScript, createMarwesThemeStyle };
|
|
33
|
+
//# sourceMappingURL=chunk-VFY2GW62.js.map
|
|
34
|
+
//# sourceMappingURL=chunk-VFY2GW62.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ssr.tsx"],"names":["createCoreMarwesThemeScript","createCoreMarwesThemeStyle"],"mappings":";;;;AAgBO,SAAS,wBAAwB,OAAA,EAA4C;AAClF,EAAA,OAAOA,0BAA4B,OAAO,CAAA;AAC5C;AAEO,SAAS,uBAAuB,OAAA,EAA2C;AAChF,EAAA,OAAOC,yBAA2B,OAAO,CAAA;AAC3C;AAEO,SAAS,iBAAA,CAAkB,EAAE,KAAA,EAAO,GAAG,SAAQ,EAA2B;AAC/E,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,8BAAA,EAA6B,MAAA;AAAA,MAC7B,KAAA;AAAA,MAEA,uBAAA,EAAyB,EAAE,MAAA,EAAQ,uBAAA,CAAwB,OAAO,CAAA;AAAE;AAAA,GACtE;AAEJ;AAEO,SAAS,gBAAA,CAAiB,EAAE,KAAA,EAAO,GAAG,SAAQ,EAA0B;AAC7E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,6BAAA,EAA4B,MAAA;AAAA,MAC5B,KAAA;AAAA,MAEA,uBAAA,EAAyB,EAAE,MAAA,EAAQ,sBAAA,CAAuB,OAAO,CAAA;AAAE;AAAA,GACrE;AAEJ","file":"chunk-VFY2GW62.js","sourcesContent":["import type { MarwesThemeScriptOptions, MarwesThemeStyleOptions } from \"@marwes-ui/core\"\nimport {\n createMarwesThemeScript as createCoreMarwesThemeScript,\n createMarwesThemeStyle as createCoreMarwesThemeStyle,\n} from \"@marwes-ui/core\"\n\nexport type { MarwesThemeScriptOptions, MarwesThemeStyleOptions }\n\nexport type MarwesThemeScriptProps = MarwesThemeScriptOptions & {\n nonce?: string\n}\n\nexport type MarwesThemeStyleProps = MarwesThemeStyleOptions & {\n nonce?: string\n}\n\nexport function createMarwesThemeScript(options?: MarwesThemeScriptOptions): string {\n return createCoreMarwesThemeScript(options)\n}\n\nexport function createMarwesThemeStyle(options?: MarwesThemeStyleOptions): string {\n return createCoreMarwesThemeStyle(options)\n}\n\nexport function MarwesThemeScript({ nonce, ...options }: MarwesThemeScriptProps) {\n return (\n <script\n data-marwes-ssr-theme-script=\"true\"\n nonce={nonce}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: SSR helper emits deterministic Marwes-owned code before hydration.\n dangerouslySetInnerHTML={{ __html: createMarwesThemeScript(options) }}\n />\n )\n}\n\nexport function MarwesThemeStyle({ nonce, ...options }: MarwesThemeStyleProps) {\n return (\n <style\n data-marwes-ssr-theme-style=\"true\"\n nonce={nonce}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: SSR helper emits deterministic Marwes-owned CSS before hydration.\n dangerouslySetInnerHTML={{ __html: createMarwesThemeStyle(options) }}\n />\n )\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ThemeInput, ThemePreference, ThemeMode, FontLoadingConfig, ResolvedTheme, ButtonOptions, InputOptions, SelectOptions, SelectAppearance as SelectAppearance$1, SelectOption as SelectOption$1, TextareaOptions, RichTextOptions, InputOtpOptions, CurrencyCode, iconRegistry, IconSize, IconStrokeWidth, AvatarOptions, CheckboxProps as CheckboxProps$1, DividerOptions, DividerSize, DividerOrientation, SpinnerOptions, SpacingOptions, SpacingSize, HeadingOptions, HeadingSize, ParagraphOptions, ParagraphSize, ToastOptions, ToastVariant, ToastIntent, ToastPlacement, TooltipOptions, IconNameType, RadioOptions, BadgeOptions, SwitchOptions, SliderOptions, TabOptions, DialogOptions } from '@marwes-ui/core';
|
|
3
|
-
export { AvatarSize, AvatarType, BadgeVariant, ButtonAction, ButtonSize, ButtonVariant, Density, FontLoadingConfig, FontLoadingMode, FontLoadingOptions, IconName, MwAvailableFont, MwFontFallback, MwGoogleFontFamily, MwStyledTheme, MwThemeVarName, MwThemeVarNames, MwThemeVarReference, MwThemeVars, ResolvedTheme, SpacingSize, Spacings, SwitchSize, Theme, ThemeInput, ThemeMode, ThemePreference, ToneName, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
|
|
2
|
+
import { ThemeInput, ThemePreference, ThemeMode, FontLoadingConfig, ThemeVariableStrategy, ResolvedTheme, ButtonOptions, InputOptions, SelectOptions, SelectAppearance as SelectAppearance$1, SelectOption as SelectOption$1, TextareaOptions, RichTextOptions, InputOtpOptions, CurrencyCode, iconRegistry, IconSize, IconStrokeWidth, AvatarOptions, CheckboxProps as CheckboxProps$1, DividerOptions, DividerSize, DividerOrientation, SpinnerOptions, SpacingOptions, SpacingSize, HeadingOptions, HeadingSize, ParagraphOptions, ParagraphSize, ToastOptions, ToastVariant, ToastIntent, ToastPlacement, TooltipOptions, IconNameType, RadioOptions, BadgeOptions, SwitchOptions, SliderOptions, TabOptions, DialogOptions } from '@marwes-ui/core';
|
|
3
|
+
export { AvatarSize, AvatarType, BadgeVariant, ButtonAction, ButtonSize, ButtonVariant, Density, FontLoadingConfig, FontLoadingMode, FontLoadingOptions, IconName, MarwesThemeScriptOptions, MarwesThemeStyleOptions, MwAvailableFont, MwFontFallback, MwGoogleFontFamily, MwStyledTheme, MwThemeVarName, MwThemeVarNames, MwThemeVarReference, MwThemeVars, ResolvedTheme, SpacingSize, Spacings, SwitchSize, Theme, ThemeInput, ThemeMode, ThemeModeAttribute, ThemeModeRootTarget, ThemePreference, ThemeVariableStrategy, ToneName, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
+
export { MarwesThemeScript, MarwesThemeScriptProps, MarwesThemeStyle, MarwesThemeStyleProps, createMarwesThemeScript, createMarwesThemeStyle } from './ssr.js';
|
|
5
6
|
|
|
6
7
|
type ThemeTarget = "provider" | "html" | "body";
|
|
7
8
|
type ThemeAttribute = "class" | "data-theme" | "data-mode";
|
|
@@ -20,9 +21,10 @@ type MarwesProviderProps = {
|
|
|
20
21
|
target?: ThemeTarget;
|
|
21
22
|
attribute?: ThemeAttribute;
|
|
22
23
|
disableTransitionOnChange?: boolean;
|
|
24
|
+
variableStrategy?: ThemeVariableStrategy;
|
|
23
25
|
children: React.ReactNode;
|
|
24
26
|
};
|
|
25
|
-
declare function MarwesProvider({ theme, defaultPreference, preference: controlledPreference, defaultMode, mode: controlledMode, fontLoading, onPreferenceChange, onModeChange, storageKey, enableSystem, target, attribute, disableTransitionOnChange, children, }: MarwesProviderProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function MarwesProvider({ theme, defaultPreference, preference: controlledPreference, defaultMode, mode: controlledMode, fontLoading, onPreferenceChange, onModeChange, storageKey, enableSystem, target, attribute, disableTransitionOnChange, variableStrategy, children, }: MarwesProviderProps): react_jsx_runtime.JSX.Element;
|
|
26
28
|
|
|
27
29
|
declare function useTheme(): ResolvedTheme;
|
|
28
30
|
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { MarwesThemeScript, MarwesThemeStyle, createMarwesThemeScript, createMarwesThemeStyle } from './chunk-VFY2GW62.js';
|
|
1
2
|
import '@marwes-ui/presets/firstEdition/styles.css';
|
|
2
3
|
import { createRichTextRecipe, resolveRichTextAllowedFormats, normalizeRichTextHtml, isRichTextHtmlEmpty, createDividerRecipe, createSpacingRecipe, createSliderRecipe, richTextCommandByFormat, resolveIconSize, resolveIconStrokeWidth, iconRegistry, resolveIconA11y, ThemeMode, resolveThemePreference, nextThemeMode, resolveThemeInput, createSpinnerRecipe, createButtonRecipe, ButtonAction, ButtonVariant, IconName, createInputRecipe, createSelectRecipe, resolveSelectMode, createTextareaRecipe, paragraphRecipe, buildInputFieldA11yIds, sanitizeInputOtpValue, createInputOtpRecipe, buildRichTextFieldA11yIds, buildCurrencyHelperText, getCurrencySymbol, createAvatarRecipe, createPurposeSemanticAttributes, checkboxRecipe, buildCheckboxFieldA11yIds, buildCheckboxGroupFieldA11yIds, headingRecipe, createCardRecipe, createToastRecipe, createTooltipRecipe, createAccordionRecipe, buildAccordionFieldA11yIds, radioRecipe, buildRadioGroupFieldA11yIds, createBadgeRecipe, createSwitchRecipe, buildSwitchFieldA11yIds, buildSliderFieldA11yIds, createTabRecipe, resolveTabValue, buildTabGroupA11yIds, moveTabSelection, createDialogRecipe, sanitizeCurrencyValue, isThemePreference, themeToCSSVars, extractUsedWeights, extractFontFamilyName, shouldLoadGoogleFont, buildGoogleFontsUrl } from '@marwes-ui/core';
|
|
3
4
|
export { AvatarSize, AvatarType, BadgeVariant, ButtonAction, ButtonSize, ButtonVariant, IconName, Spacings, SwitchSize, ThemeMode, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
|
|
@@ -6,7 +7,6 @@ import { useEffect } from 'react';
|
|
|
6
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
8
|
import { createPortal } from 'react-dom';
|
|
8
9
|
|
|
9
|
-
// src/index.ts
|
|
10
10
|
var MarwesContext = React2.createContext(null);
|
|
11
11
|
var loadedFonts = /* @__PURE__ */ new Set();
|
|
12
12
|
var preconnected = false;
|
|
@@ -19,6 +19,7 @@ function themeToRootStyle(theme) {
|
|
|
19
19
|
}
|
|
20
20
|
function applyThemeToElement(element, theme) {
|
|
21
21
|
element.setAttribute("data-marwes-theme", "true");
|
|
22
|
+
element.setAttribute("data-marwes-mode", theme.mode);
|
|
22
23
|
for (const [property, value] of Object.entries(themeToRootStyle(theme))) {
|
|
23
24
|
if (property === "backgroundColor") {
|
|
24
25
|
element.style.backgroundColor = value;
|
|
@@ -153,6 +154,7 @@ function MarwesProvider({
|
|
|
153
154
|
target = "provider",
|
|
154
155
|
attribute = "class",
|
|
155
156
|
disableTransitionOnChange = false,
|
|
157
|
+
variableStrategy = "inline",
|
|
156
158
|
children
|
|
157
159
|
}) {
|
|
158
160
|
const rootRef = React2.useRef(null);
|
|
@@ -206,15 +208,16 @@ function MarwesProvider({
|
|
|
206
208
|
() => resolveThemeInput({ ...theme ?? {}, mode: activeMode }),
|
|
207
209
|
[activeMode, theme]
|
|
208
210
|
);
|
|
209
|
-
const rootStyle = React2.useMemo(
|
|
210
|
-
()
|
|
211
|
-
|
|
212
|
-
);
|
|
211
|
+
const rootStyle = React2.useMemo(() => {
|
|
212
|
+
if (variableStrategy === "style-tag") return void 0;
|
|
213
|
+
return themeToRootStyle(resolved);
|
|
214
|
+
}, [resolved, variableStrategy]);
|
|
213
215
|
React2.useEffect(() => {
|
|
216
|
+
if (variableStrategy === "style-tag") return;
|
|
214
217
|
if (rootRef.current) {
|
|
215
218
|
applyThemeToElement(rootRef.current, resolved);
|
|
216
219
|
}
|
|
217
|
-
}, [resolved]);
|
|
220
|
+
}, [resolved, variableStrategy]);
|
|
218
221
|
React2.useEffect(() => {
|
|
219
222
|
if (target === "provider") return;
|
|
220
223
|
const apply = () => {
|
|
@@ -252,6 +255,7 @@ function MarwesProvider({
|
|
|
252
255
|
ref: rootRef,
|
|
253
256
|
className: `mw-theme--${resolved.mode}`,
|
|
254
257
|
"data-marwes-theme": "true",
|
|
258
|
+
"data-marwes-mode": resolved.mode,
|
|
255
259
|
style: rootStyle,
|
|
256
260
|
children
|
|
257
261
|
}
|