@marwes-ui/vue 1.0.0 → 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/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  <div align="center">
2
2
 
3
- <img alt="Marwes Design System" src="https://raw.githubusercontent.com/niklas-westman/marwes/main/.github/assets/banner-light.png" width="100%">
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
5
  <br>
6
6
  <br>
7
7
 
8
8
  # Marwes Design System - Vue
9
9
 
10
- **Vue 3 components with first edition styling, typed theme tokens, accessibility contracts, and AI-readable semantics built in.**
10
+ **Vue 3 components with default Marwes styling, typed theme tokens, accessibility contracts, and AI-readable semantics built in.**
11
11
 
12
12
  Vue 3.4+ • TypeScript-first • Default CSS included • ThemeInput • Google Fonts DX • Purpose components
13
13
 
@@ -21,7 +21,7 @@ Vue 3.4+ • TypeScript-first • Default CSS included • ThemeInput • Google
21
21
 
22
22
  Marwes gives Vue apps a ready design-system base without requiring custom CSS setup or local component forks.
23
23
 
24
- - **One package for Vue apps**: components, provider, default first edition CSS, theme helpers, and typed props.
24
+ - **One package for Vue apps**: components, provider, default preset CSS, theme helpers, and typed props.
25
25
  - **Vue-native binding**: common controls support `v-model` while preserving Marwes semantic contracts.
26
26
  - **Consequential theming**: a `ThemeInput` object changes colors, fonts, radius, density, typography, and component visuals through shared CSS variables.
27
27
  - **Purpose components**: `SubmitButton`, `CancelButton`, and `DestructiveButton` make intent machine-readable so tests, audits, and AI agents can handle actions safely.
@@ -36,7 +36,7 @@ For a Vue app, install this package first. It includes the Vue adapter, loads th
36
36
  | `@marwes-ui/vue` | You are building a Vue app. |
37
37
  | `@marwes-ui/react` | You are building a React app instead. |
38
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. |
39
+ | `@marwes-ui/presets` | You need standalone preset CSS or preset theme exports. |
40
40
 
41
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.
42
42
 
@@ -46,14 +46,14 @@ This split keeps installation simple for app teams while giving humans and AI ag
46
46
  pnpm add @marwes-ui/vue vue
47
47
  ```
48
48
 
49
- No preset CSS import is needed. `@marwes-ui/vue` depends on `@marwes-ui/presets` and loads the first edition CSS automatically.
49
+ No preset CSS import is needed. `@marwes-ui/vue` depends on `@marwes-ui/presets` and loads the default Marwes CSS automatically.
50
50
 
51
51
  ## Quick Start
52
52
 
53
53
  ```vue
54
54
  <script setup lang="ts">
55
55
  import { ref } from "vue"
56
- import { Button, Checkbox, Input, MarwesProvider, SubmitButton } from "@marwes-ui/vue"
56
+ import { Button, ButtonVariant, Checkbox, Input, MarwesProvider, SubmitButton } from "@marwes-ui/vue"
57
57
 
58
58
  const email = ref("")
59
59
  const subscribed = ref(false)
@@ -63,7 +63,7 @@ const subscribed = ref(false)
63
63
  <MarwesProvider>
64
64
  <Input v-model="email" placeholder="Email" ariaLabel="Email" />
65
65
  <Checkbox v-model="subscribed" ariaLabel="Subscribe" />
66
- <Button variant="secondary">Preview</Button>
66
+ <Button :variant="ButtonVariant.secondary">Preview</Button>
67
67
  <SubmitButton>Save</SubmitButton>
68
68
  </MarwesProvider>
69
69
  </template>
@@ -75,7 +75,7 @@ Marwes components pick up provider tokens automatically. Your own Vue styling ca
75
75
 
76
76
  ```vue
77
77
  <script setup lang="ts">
78
- import { Button, MarwesProvider, mwThemeVars } from "@marwes-ui/vue"
78
+ import { Button, ButtonVariant, MarwesProvider, mwThemeVars } from "@marwes-ui/vue"
79
79
 
80
80
  const panelStyle = {
81
81
  padding: mwThemeVars.spacing.sp24,
@@ -90,7 +90,7 @@ const panelStyle = {
90
90
  <main class="app-shell">
91
91
  <aside class="primary-callout">Launch workspace</aside>
92
92
  <section class="feature-panel" :style="panelStyle">
93
- <Button variant="primary">Save</Button>
93
+ <Button :variant="ButtonVariant.primary">Save</Button>
94
94
  </section>
95
95
  </main>
96
96
  </MarwesProvider>
@@ -136,7 +136,9 @@ import {
136
136
  StatusBadge,
137
137
  SubmitButton,
138
138
  type ButtonProps,
139
+ type HeadingProps,
139
140
  type InputFieldProps,
141
+ type ParagraphProps,
140
142
  } from "@marwes-ui/vue"
141
143
 
142
144
  const primaryAction: ButtonProps = {
@@ -152,6 +154,14 @@ const emailField: InputFieldProps = {
152
154
  placeholder: "you@example.com",
153
155
  },
154
156
  }
157
+
158
+ const titleProps: HeadingProps = {
159
+ size: "h2",
160
+ }
161
+
162
+ const descriptionProps: ParagraphProps = {
163
+ size: "md",
164
+ }
155
165
  </script>
156
166
 
157
167
  <template>
@@ -159,8 +169,8 @@ const emailField: InputFieldProps = {
159
169
  <template #title>Project setup</template>
160
170
  <StatusBadge :variant="BadgeVariant.success">Ready</StatusBadge>
161
171
  <Spacer :spacing="Spacings.sp16" />
162
- <H1 size="h2">Launch workspace</H1>
163
- <Paragraph size="md">
172
+ <H1 v-bind="titleProps">Launch workspace</H1>
173
+ <Paragraph v-bind="descriptionProps">
164
174
  Components share theme tokens, typed variants, spacing, and semantic metadata.
165
175
  </Paragraph>
166
176
  <InputField v-bind="emailField" />
@@ -223,11 +233,11 @@ Typed tokens and helpers:
223
233
 
224
234
  ## Theme In Seconds
225
235
 
226
- First edition is the default. Pass `theme` only when a brand or design file needs to change the baseline.
236
+ The default Marwes theme is already active. If you already have a good-looking design library or brand system, pass a small typed `ThemeInput` override instead of rebuilding component CSS.
227
237
 
228
238
  ```vue
229
239
  <script setup lang="ts">
230
- import { MarwesProvider, mwAvailableFonts } from "@marwes-ui/vue"
240
+ import { MarwesProvider, mwAvailableFonts, type ThemeInput } from "@marwes-ui/vue"
231
241
 
232
242
  const brandTheme = {
233
243
  color: {
@@ -251,7 +261,7 @@ const brandTheme = {
251
261
  radius: 10,
252
262
  density: "comfortable",
253
263
  },
254
- }
264
+ } satisfies ThemeInput
255
265
  </script>
256
266
 
257
267
  <template>
@@ -263,6 +273,90 @@ const brandTheme = {
263
273
 
264
274
  The provider resolves `ThemeInput` into `--mw-*` CSS variables. Preset CSS consumes those variables across the full component system.
265
275
 
276
+ Marwes is designed to look great from the beginning. Start with the default preset, then override only the colors, fonts, radius, or density that belong to your product. Unspecified values keep the polished Marwes defaults.
277
+
278
+ ## Light And Dark Mode
279
+
280
+ MarwesProvider can own the active mode for the app. Use `ThemeMode.light` and `ThemeMode.dark` instead of string literals, then read or change the active mode with `useThemeMode()` anywhere under the provider. Every component under the provider receives the matching `--mw-*` variables and `mw-theme--light` / `mw-theme--dark` class.
281
+
282
+ ```vue
283
+ <script setup lang="ts">
284
+ import { Button, ButtonVariant, ThemeMode, useThemeMode } from "@marwes-ui/vue"
285
+
286
+ const { mode, toggleMode } = useThemeMode()
287
+ </script>
288
+
289
+ <template>
290
+ <Button :variant="ButtonVariant.secondary" @click="toggleMode">
291
+ Use {{ mode === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark }} mode
292
+ </Button>
293
+ </template>
294
+ ```
295
+
296
+ ```vue
297
+ <script setup lang="ts">
298
+ import { MarwesProvider, ThemeMode } from "@marwes-ui/vue"
299
+ import ThemeToggle from "./theme-toggle.vue"
300
+ </script>
301
+
302
+ <template>
303
+ <MarwesProvider :default-mode="ThemeMode.light">
304
+ <ThemeToggle />
305
+ <AppShell />
306
+ </MarwesProvider>
307
+ </template>
308
+ ```
309
+
310
+ `default-mode` sets the initial uncontrolled mode. `toggleMode()` updates the provider, so Marwes components, preset CSS, and custom app styles that use `--mw-*` variables all move together without duplicating local theme state.
311
+
312
+ 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:
313
+
314
+ ```vue
315
+ <script setup lang="ts">
316
+ import { ref } from "vue"
317
+ import { MarwesProvider, ThemeMode, type ThemeInput } from "@marwes-ui/vue"
318
+ import ThemeToggle from "./theme-toggle.vue"
319
+
320
+ const mode = ref<ThemeMode>(ThemeMode.light)
321
+
322
+ const themeByMode = {
323
+ [ThemeMode.light]: {
324
+ color: {
325
+ primary: "#2457FF",
326
+ background: "#F8FAFC",
327
+ surface: "#FFFFFF",
328
+ text: "#111827",
329
+ border: "#D1D5DB",
330
+ focus: "#2457FF",
331
+ },
332
+ },
333
+ [ThemeMode.dark]: {
334
+ color: {
335
+ primary: "#8BA2FF",
336
+ background: "#0B1020",
337
+ surface: "#111827",
338
+ text: "#F8FAFC",
339
+ border: "#334155",
340
+ focus: "#93C5FD",
341
+ },
342
+ },
343
+ } satisfies Record<ThemeMode, ThemeInput>
344
+
345
+ function setMode(nextMode: ThemeMode) {
346
+ mode.value = nextMode
347
+ }
348
+ </script>
349
+
350
+ <template>
351
+ <MarwesProvider :mode="mode" :theme="themeByMode[mode]" :on-mode-change="setMode">
352
+ <ThemeToggle />
353
+ <AppShell />
354
+ </MarwesProvider>
355
+ </template>
356
+ ```
357
+
358
+ Mode-specific defaults fill every omitted token, so each override can stay small. `:theme="{ mode: ThemeMode.dark }"` is still enough for the default dark baseline.
359
+
266
360
  ## Custom Styling Tokens
267
361
 
268
362
  `MarwesProvider` resolves `ThemeInput` into `--mw-*` CSS variables. Marwes components and preset CSS consume those variables automatically. The custom styling token helpers let app-owned Vue styles, script-driven style objects, and build-time config use the same provider-scoped values instead of hard-coding colors, spacing, radius, typography, or duplicated `var(...)` strings.
@@ -331,14 +425,14 @@ Most Google Font use cases only need `mwAvailableFonts`; no `fontLoading` prop i
331
425
 
332
426
  ```vue
333
427
  <script setup lang="ts">
334
- import { mwAvailableFonts } from "@marwes-ui/vue"
428
+ import { MarwesProvider, mwAvailableFonts, type ThemeInput } from "@marwes-ui/vue"
335
429
 
336
430
  const theme = {
337
431
  font: {
338
432
  primary: mwAvailableFonts.Poppins,
339
433
  secondary: mwAvailableFonts.Lora,
340
434
  },
341
- }
435
+ } satisfies ThemeInput
342
436
  </script>
343
437
 
344
438
  <template>
@@ -402,16 +496,18 @@ Example:
402
496
 
403
497
  ```vue
404
498
  <script setup lang="ts">
405
- import { InputField } from "@marwes-ui/vue"
499
+ import { InputField, type InputFieldProps } from "@marwes-ui/vue"
500
+
501
+ const receiptEmailField = {
502
+ label: "Email",
503
+ helperText: "Used for receipts.",
504
+ error: "Enter a valid email.",
505
+ input: { type: "email", placeholder: "you@example.com" },
506
+ } satisfies InputFieldProps
406
507
  </script>
407
508
 
408
509
  <template>
409
- <InputField
410
- label="Email"
411
- helperText="Used for receipts."
412
- error="Enter a valid email."
413
- :input="{ type: 'email', placeholder: 'you@example.com' }"
414
- />
510
+ <InputField v-bind="receiptEmailField" />
415
511
  </template>
416
512
  ```
417
513
 
@@ -434,7 +530,7 @@ The important part is that the same label, helper, error, and invalid contract i
434
530
  ## Package Boundaries
435
531
 
436
532
  - `@marwes-ui/core` owns recipes, theme resolution, a11y mapping, and semantic metadata.
437
- - `@marwes-ui/presets` owns first edition CSS.
533
+ - `@marwes-ui/presets` owns default preset CSS.
438
534
  - `@marwes-ui/vue` owns Vue rendering and provider behavior.
439
535
 
440
536
  ## Scripts
package/dist/index.d.ts CHANGED
@@ -1,28 +1,43 @@
1
1
  import * as vue from 'vue';
2
- import { VNodeChild } from 'vue';
2
+ import { ComputedRef, VNodeChild } from 'vue';
3
3
  import * as _marwes_ui_core from '@marwes-ui/core';
4
- import { ThemeInput, FontLoadingConfig, ThemeMode, 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';
4
+ import { ThemeInput, 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';
5
5
  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, ToneName, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
6
6
 
7
7
  type MarwesProviderProps = {
8
8
  theme?: ThemeInput;
9
+ defaultMode?: ThemeMode;
10
+ mode?: ThemeMode;
9
11
  fontLoading?: FontLoadingConfig;
10
12
  onModeChange?: (mode: ThemeMode) => void;
11
13
  };
12
14
  declare const MarwesProvider: vue.DefineComponent<{
15
+ mode?: any;
13
16
  theme?: any;
17
+ defaultMode?: any;
14
18
  fontLoading?: any;
15
19
  onModeChange?: any;
16
20
  }, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
17
21
  [key: string]: any;
18
22
  }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{
23
+ mode?: any;
19
24
  theme?: any;
25
+ defaultMode?: any;
20
26
  fontLoading?: any;
21
27
  onModeChange?: any;
22
28
  }> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
23
29
 
24
30
  declare function useTheme(): ResolvedTheme;
25
31
 
32
+ type ThemeModeContextValue = {
33
+ mode: ComputedRef<ThemeMode>;
34
+ setMode: (mode: ThemeMode) => void;
35
+ toggleMode: () => void;
36
+ isDark: ComputedRef<boolean>;
37
+ isLight: ComputedRef<boolean>;
38
+ };
39
+ declare function useThemeMode(): ThemeModeContextValue;
40
+
26
41
  type ButtonProps = ButtonOptions & {
27
42
  onClick?: (event: MouseEvent) => void;
28
43
  className?: string;
@@ -2853,4 +2868,4 @@ declare const InfoDialog: vue.DefineComponent<{
2853
2868
  onAcknowledge?: any;
2854
2869
  }> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
2855
2870
 
2856
- export { Accordion, AccordionField, type AccordionFieldItem, type AccordionFieldProps, type AccordionProps, Avatar, AvatarBadge, type AvatarBadgeProps, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, Badge, BadgeGroup, type BadgeGroupProps, type BadgeProps, BrightnessSlider, type BrightnessSliderProps, Button, type ButtonProps, ButtonSpinner, type ButtonSpinnerProps, CancelButton, type CancelButtonProps, Card, type CardProps, Checkbox, CheckboxField, type CheckboxFieldProps, CheckboxGroupField, type CheckboxGroupFieldOption, type CheckboxGroupFieldProps, type CheckboxProps, CloseButton, type CloseButtonProps, ConfirmButton, type ConfirmButtonProps, ConfirmDialog, type ConfirmDialogProps, ContentTabs, type ContentTabsProps, CopyButton, type CopyButtonProps, CreateButton, type CreateButtonProps, CurrencyField, type CurrencyFieldProps, DateOfBirthField, type DateOfBirthFieldProps, DestructiveButton, type DestructiveButtonProps, DestructiveDialog, type DestructiveDialogProps, Dialog, type DialogFooterControls, DialogModal, type DialogModalProps, type DialogProps, Divider, type DividerProps, DownloadButton, type DownloadButtonProps, DropdownButton, type DropdownButtonProps, DropdownField, type DropdownFieldProps, EditButton, type EditButtonProps, EmailField, type EmailFieldProps, EmptyStateSpinner, type EmptyStateSpinnerProps, ErrorToast, type ErrorToastProps, FAQAccordion, type FAQAccordionProps, FeatureToggle, type FeatureToggleProps, FilterButton, type FilterButtonProps, H1, H2, H3, type HeadingLevel, type HeadingProps, Icon, type IconProps, InfoDialog, type InfoDialogProps, InfoToast, type InfoToastProps, Input, InputField, type InputFieldProps, InputOtp, type InputOtpProps, type InputProps, LinkButton, type LinkButtonProps, type ManagedToast, MarwesProvider, type MarwesProviderProps, NavigationTabs, type NavigationTabsProps, NotificationBadge, type NotificationBadgeProps, OptionRadioGroup, type OptionRadioGroupProps, Paragraph, type ParagraphProps, PasswordField, type PasswordFieldProps, PermissionSwitch, type PermissionSwitchProps, PhoneField, type PhoneFieldProps, PreferenceSwitch, type PreferenceSwitchProps, PresenceAvatar, type PresenceAvatarProps, PrimaryButton, type PrimaryButtonProps, PriorityBadge, type PriorityBadgeProps, ProductCard, type ProductCardProps, ProfileAvatar, type ProfileAvatarProps, ProfileCard, type ProfileCardProps, Radio, RadioGroupField, type RadioGroupFieldOption, type RadioGroupFieldProps, type RadioProps, RadiusSlider, type RadiusSliderProps, RatingRadioGroup, type RatingRadioGroupProps, RefreshButton, type RefreshButtonProps, RichText, RichTextField, type RichTextFieldProps, type RichTextProps, SaveButton, type SaveButtonProps, SearchButton, type SearchButtonProps, SearchField, type SearchFieldProps, SecondaryButton, type SecondaryButtonProps, SectionsAccordion, type SectionsAccordionProps, Select, type SelectAppearance, SelectField, type SelectFieldProps, type SelectOption, type SelectProps, SettingsAccordion, type SettingsAccordionProps, SettingsTabs, type SettingsTabsProps, type ShowToastOptions, Slider, SliderField, type SliderFieldProps, type SliderProps, SortButton, type SortButtonProps, Spacer, type SpacerProps, Spacing, type SpacingProps, Spinner, type SpinnerProps, StatCard, type StatCardProps, StatusBadge, type StatusBadgeProps, SubmitButton, type SubmitButtonProps, SuccessButton, type SuccessButtonProps, SuccessToast, type SuccessToastProps, Switch, SwitchField, type SwitchFieldProps, type SwitchProps, Tab, TabGroup, type TabGroupItem, type TabGroupProps, TabPanel, type TabPanelProps, type TabProps, TeamAvatarGroup, type TeamAvatarGroupProps, TextButton, type TextButtonProps, Textarea, TextareaField, type TextareaFieldProps, type TextareaProps, Toast, ToastContainer, type ToastContainerProps, type ToastController, type ToastProps, ToastProvider, type ToastProviderProps, Tooltip, TooltipGroup, type TooltipGroupProps, type TooltipProps, URLField, type URLFieldProps, UploadButton, type UploadButtonProps, VerifyButton, type VerifyButtonProps, VolumeSlider, type VolumeSliderProps, WarningToast, type WarningToastProps, YesNoRadioGroup, type YesNoRadioGroupProps, ZipCodeField, type ZipCodeFieldProps, createHeadingComponent, useTheme, useToast };
2871
+ export { Accordion, AccordionField, type AccordionFieldItem, type AccordionFieldProps, type AccordionProps, Avatar, AvatarBadge, type AvatarBadgeProps, AvatarGroup, type AvatarGroupItem, type AvatarGroupProps, type AvatarProps, Badge, BadgeGroup, type BadgeGroupProps, type BadgeProps, BrightnessSlider, type BrightnessSliderProps, Button, type ButtonProps, ButtonSpinner, type ButtonSpinnerProps, CancelButton, type CancelButtonProps, Card, type CardProps, Checkbox, CheckboxField, type CheckboxFieldProps, CheckboxGroupField, type CheckboxGroupFieldOption, type CheckboxGroupFieldProps, type CheckboxProps, CloseButton, type CloseButtonProps, ConfirmButton, type ConfirmButtonProps, ConfirmDialog, type ConfirmDialogProps, ContentTabs, type ContentTabsProps, CopyButton, type CopyButtonProps, CreateButton, type CreateButtonProps, CurrencyField, type CurrencyFieldProps, DateOfBirthField, type DateOfBirthFieldProps, DestructiveButton, type DestructiveButtonProps, DestructiveDialog, type DestructiveDialogProps, Dialog, type DialogFooterControls, DialogModal, type DialogModalProps, type DialogProps, Divider, type DividerProps, DownloadButton, type DownloadButtonProps, DropdownButton, type DropdownButtonProps, DropdownField, type DropdownFieldProps, EditButton, type EditButtonProps, EmailField, type EmailFieldProps, EmptyStateSpinner, type EmptyStateSpinnerProps, ErrorToast, type ErrorToastProps, FAQAccordion, type FAQAccordionProps, FeatureToggle, type FeatureToggleProps, FilterButton, type FilterButtonProps, H1, H2, H3, type HeadingLevel, type HeadingProps, Icon, type IconProps, InfoDialog, type InfoDialogProps, InfoToast, type InfoToastProps, Input, InputField, type InputFieldProps, InputOtp, type InputOtpProps, type InputProps, LinkButton, type LinkButtonProps, type ManagedToast, MarwesProvider, type MarwesProviderProps, NavigationTabs, type NavigationTabsProps, NotificationBadge, type NotificationBadgeProps, OptionRadioGroup, type OptionRadioGroupProps, Paragraph, type ParagraphProps, PasswordField, type PasswordFieldProps, PermissionSwitch, type PermissionSwitchProps, PhoneField, type PhoneFieldProps, PreferenceSwitch, type PreferenceSwitchProps, PresenceAvatar, type PresenceAvatarProps, PrimaryButton, type PrimaryButtonProps, PriorityBadge, type PriorityBadgeProps, ProductCard, type ProductCardProps, ProfileAvatar, type ProfileAvatarProps, ProfileCard, type ProfileCardProps, Radio, RadioGroupField, type RadioGroupFieldOption, type RadioGroupFieldProps, type RadioProps, RadiusSlider, type RadiusSliderProps, RatingRadioGroup, type RatingRadioGroupProps, RefreshButton, type RefreshButtonProps, RichText, RichTextField, type RichTextFieldProps, type RichTextProps, SaveButton, type SaveButtonProps, SearchButton, type SearchButtonProps, SearchField, type SearchFieldProps, SecondaryButton, type SecondaryButtonProps, SectionsAccordion, type SectionsAccordionProps, Select, type SelectAppearance, SelectField, type SelectFieldProps, type SelectOption, type SelectProps, SettingsAccordion, type SettingsAccordionProps, SettingsTabs, type SettingsTabsProps, type ShowToastOptions, Slider, SliderField, type SliderFieldProps, type SliderProps, SortButton, type SortButtonProps, Spacer, type SpacerProps, Spacing, type SpacingProps, Spinner, type SpinnerProps, StatCard, type StatCardProps, StatusBadge, type StatusBadgeProps, SubmitButton, type SubmitButtonProps, SuccessButton, type SuccessButtonProps, SuccessToast, type SuccessToastProps, Switch, SwitchField, type SwitchFieldProps, type SwitchProps, Tab, TabGroup, type TabGroupItem, type TabGroupProps, TabPanel, type TabPanelProps, type TabProps, TeamAvatarGroup, type TeamAvatarGroupProps, TextButton, type TextButtonProps, Textarea, TextareaField, type TextareaFieldProps, type TextareaProps, type ThemeModeContextValue, Toast, ToastContainer, type ToastContainerProps, type ToastController, type ToastProps, ToastProvider, type ToastProviderProps, Tooltip, TooltipGroup, type TooltipGroupProps, type TooltipProps, URLField, type URLFieldProps, UploadButton, type UploadButtonProps, VerifyButton, type VerifyButtonProps, VolumeSlider, type VolumeSliderProps, WarningToast, type WarningToastProps, YesNoRadioGroup, type YesNoRadioGroupProps, ZipCodeField, type ZipCodeFieldProps, createHeadingComponent, useTheme, useThemeMode, useToast };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import '@marwes-ui/presets/firstEdition/styles.css';
2
- import { resolveThemeInput, resolveIconSize, resolveIconStrokeWidth, iconRegistry, resolveIconA11y, createSpinnerRecipe, createButtonRecipe, ButtonAction, ButtonVariant, IconName, createInputRecipe, createSelectRecipe, resolveSelectMode, createTextareaRecipe, createRichTextRecipe, resolveRichTextAllowedFormats, normalizeRichTextHtml, isRichTextHtmlEmpty, paragraphRecipe, buildInputFieldA11yIds, sanitizeInputOtpValue, createInputOtpRecipe, buildRichTextFieldA11yIds, buildCurrencyHelperText, getCurrencySymbol, sanitizeCurrencyValue, createAvatarRecipe, createPurposeSemanticAttributes, checkboxRecipe, buildCheckboxFieldA11yIds, buildCheckboxGroupFieldA11yIds, createDividerRecipe, createSpacingRecipe, createCardRecipe, createToastRecipe, createTooltipRecipe, createAccordionRecipe, buildAccordionFieldA11yIds, radioRecipe, buildRadioGroupFieldA11yIds, createBadgeRecipe, createSwitchRecipe, buildSwitchFieldA11yIds, createSliderRecipe, buildSliderFieldA11yIds, createTabRecipe, resolveTabValue, buildTabGroupA11yIds, createDialogRecipe, themeToCSSVars, richTextCommandByFormat, headingRecipe, moveTabSelection, extractUsedWeights, extractFontFamilyName, shouldLoadGoogleFont, buildGoogleFontsUrl } from '@marwes-ui/core';
3
- export { AvatarSize, AvatarType, BadgeVariant, ButtonAction, ButtonSize, ButtonVariant, IconName, Spacings, SwitchSize, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
4
- import { defineComponent, computed, ref, onMounted, watch, provide, h, useAttrs, onBeforeUnmount, shallowRef, Fragment, nextTick, Teleport, inject } from 'vue';
2
+ import { ThemeMode, resolveThemeInput, resolveIconSize, resolveIconStrokeWidth, iconRegistry, resolveIconA11y, createSpinnerRecipe, createButtonRecipe, ButtonAction, ButtonVariant, IconName, createInputRecipe, createSelectRecipe, resolveSelectMode, createTextareaRecipe, createRichTextRecipe, resolveRichTextAllowedFormats, normalizeRichTextHtml, isRichTextHtmlEmpty, paragraphRecipe, buildInputFieldA11yIds, sanitizeInputOtpValue, createInputOtpRecipe, buildRichTextFieldA11yIds, buildCurrencyHelperText, getCurrencySymbol, sanitizeCurrencyValue, createAvatarRecipe, createPurposeSemanticAttributes, checkboxRecipe, buildCheckboxFieldA11yIds, buildCheckboxGroupFieldA11yIds, createDividerRecipe, createSpacingRecipe, createCardRecipe, createToastRecipe, createTooltipRecipe, createAccordionRecipe, buildAccordionFieldA11yIds, radioRecipe, buildRadioGroupFieldA11yIds, createBadgeRecipe, createSwitchRecipe, buildSwitchFieldA11yIds, createSliderRecipe, buildSliderFieldA11yIds, createTabRecipe, resolveTabValue, buildTabGroupA11yIds, createDialogRecipe, themeToCSSVars, richTextCommandByFormat, headingRecipe, moveTabSelection, extractUsedWeights, extractFontFamilyName, shouldLoadGoogleFont, buildGoogleFontsUrl } from '@marwes-ui/core';
3
+ export { AvatarSize, AvatarType, BadgeVariant, ButtonAction, ButtonSize, ButtonVariant, IconName, Spacings, SwitchSize, ThemeMode, createFontStack, mwAvailableFonts, mwFontFallbacks, mwGoogleFontFamilies, mwStyledTheme, mwThemeVarNames, mwThemeVars, mwVar } from '@marwes-ui/core';
4
+ import { defineComponent, ref, computed, onMounted, watch, provide, h, useAttrs, onBeforeUnmount, shallowRef, Fragment, nextTick, Teleport, inject } from 'vue';
5
5
 
6
6
  // src/index.ts
7
7
 
@@ -65,11 +65,29 @@ function loadThemeFonts(theme, config = "auto") {
65
65
  // src/provider/marwes-provider.ts
66
66
  var MarwesProvider = defineComponent({
67
67
  name: "MarwesProvider",
68
- props: ["theme", "fontLoading", "onModeChange"],
68
+ props: ["theme", "defaultMode", "mode", "fontLoading", "onModeChange"],
69
69
  setup(rawProps, { slots }) {
70
70
  const props = rawProps;
71
- const resolved = computed(() => resolveThemeInput(props.theme ?? {}));
71
+ const internalMode = ref(props.defaultMode ?? ThemeMode.light);
72
+ const activeMode = computed(
73
+ () => props.mode ?? props.theme?.mode ?? internalMode.value
74
+ );
75
+ const isModeControlled = computed(
76
+ () => props.mode !== void 0 || props.theme?.mode !== void 0
77
+ );
78
+ const resolved = computed(
79
+ () => resolveThemeInput({ ...props.theme ?? {}, mode: activeMode.value })
80
+ );
72
81
  const rootRef = ref(null);
82
+ function setMode(nextMode) {
83
+ if (!isModeControlled.value) {
84
+ internalMode.value = nextMode;
85
+ }
86
+ props.onModeChange?.(nextMode);
87
+ }
88
+ function toggleMode() {
89
+ setMode(activeMode.value === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark);
90
+ }
73
91
  function syncThemeToRuntime() {
74
92
  if (rootRef.value) {
75
93
  applyThemeToElement(rootRef.value, resolved.value);
@@ -80,7 +98,9 @@ var MarwesProvider = defineComponent({
80
98
  watch(resolved, syncThemeToRuntime);
81
99
  provide(marwesContextKey, {
82
100
  theme: resolved,
83
- onModeChange: props.onModeChange
101
+ mode: activeMode,
102
+ setMode,
103
+ toggleMode
84
104
  });
85
105
  return () => h(
86
106
  "div",
@@ -101,6 +121,19 @@ function useTheme() {
101
121
  }
102
122
  return context.theme.value;
103
123
  }
124
+ function useThemeMode() {
125
+ const context = inject(marwesContextKey, null);
126
+ if (!context) {
127
+ throw new Error("MarwesProvider is missing. Wrap your app in <MarwesProvider />.");
128
+ }
129
+ return {
130
+ mode: context.mode,
131
+ setMode: context.setMode,
132
+ toggleMode: context.toggleMode,
133
+ isDark: computed(() => context.mode.value === ThemeMode.dark),
134
+ isLight: computed(() => context.mode.value === ThemeMode.light)
135
+ };
136
+ }
104
137
 
105
138
  // src/internal/render-utils.ts
106
139
  function mergeClassNames(...parts) {
@@ -6520,6 +6553,6 @@ var InfoDialog = defineComponent({
6520
6553
  }
6521
6554
  });
6522
6555
 
6523
- export { Accordion, AccordionField, Avatar, AvatarBadge, AvatarGroup, Badge, BadgeGroup, BrightnessSlider, Button, ButtonSpinner, CancelButton, Card, Checkbox, CheckboxField, CheckboxGroupField, CloseButton, ConfirmButton, ConfirmDialog, ContentTabs, CopyButton, CreateButton, CurrencyField, DateOfBirthField, DestructiveButton, DestructiveDialog, Dialog, DialogModal, Divider, DownloadButton, DropdownButton, DropdownField, EditButton, EmailField, EmptyStateSpinner, ErrorToast, FAQAccordion, FeatureToggle, FilterButton, H1, H2, H3, Icon, InfoDialog, InfoToast, Input, InputField, InputOtp, LinkButton, MarwesProvider, NavigationTabs, NotificationBadge, OptionRadioGroup, Paragraph, PasswordField, PermissionSwitch, PhoneField, PreferenceSwitch, PresenceAvatar, PrimaryButton, PriorityBadge, ProductCard, ProfileAvatar, ProfileCard, Radio, RadioGroupField, RadiusSlider, RatingRadioGroup, RefreshButton, RichText, RichTextField, SaveButton, SearchButton, SearchField, SecondaryButton, SectionsAccordion, Select, SelectField, SettingsAccordion, SettingsTabs, Slider, SliderField, SortButton, Spacer, Spacing, Spinner, StatCard, StatusBadge, SubmitButton, SuccessButton, SuccessToast, Switch, SwitchField, Tab, TabGroup, TabPanel, TeamAvatarGroup, TextButton, Textarea, TextareaField, Toast, ToastContainer, ToastProvider, Tooltip, TooltipGroup, URLField, UploadButton, VerifyButton, VolumeSlider, WarningToast, YesNoRadioGroup, ZipCodeField, createHeadingComponent, useTheme, useToast };
6556
+ export { Accordion, AccordionField, Avatar, AvatarBadge, AvatarGroup, Badge, BadgeGroup, BrightnessSlider, Button, ButtonSpinner, CancelButton, Card, Checkbox, CheckboxField, CheckboxGroupField, CloseButton, ConfirmButton, ConfirmDialog, ContentTabs, CopyButton, CreateButton, CurrencyField, DateOfBirthField, DestructiveButton, DestructiveDialog, Dialog, DialogModal, Divider, DownloadButton, DropdownButton, DropdownField, EditButton, EmailField, EmptyStateSpinner, ErrorToast, FAQAccordion, FeatureToggle, FilterButton, H1, H2, H3, Icon, InfoDialog, InfoToast, Input, InputField, InputOtp, LinkButton, MarwesProvider, NavigationTabs, NotificationBadge, OptionRadioGroup, Paragraph, PasswordField, PermissionSwitch, PhoneField, PreferenceSwitch, PresenceAvatar, PrimaryButton, PriorityBadge, ProductCard, ProfileAvatar, ProfileCard, Radio, RadioGroupField, RadiusSlider, RatingRadioGroup, RefreshButton, RichText, RichTextField, SaveButton, SearchButton, SearchField, SecondaryButton, SectionsAccordion, Select, SelectField, SettingsAccordion, SettingsTabs, Slider, SliderField, SortButton, Spacer, Spacing, Spinner, StatCard, StatusBadge, SubmitButton, SuccessButton, SuccessToast, Switch, SwitchField, Tab, TabGroup, TabPanel, TeamAvatarGroup, TextButton, Textarea, TextareaField, Toast, ToastContainer, ToastProvider, Tooltip, TooltipGroup, URLField, UploadButton, VerifyButton, VolumeSlider, WarningToast, YesNoRadioGroup, ZipCodeField, createHeadingComponent, useTheme, useThemeMode, useToast };
6524
6557
  //# sourceMappingURL=index.js.map
6525
6558
  //# sourceMappingURL=index.js.map