@maz-ui/mcp 5.0.0-beta.5 → 5.0.0-beta.51

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.
Files changed (164) hide show
  1. package/README.md +1 -1
  2. package/dist/mcp.d.mts +22 -9
  3. package/dist/mcp.d.ts +22 -9
  4. package/dist/mcp.mjs +160 -83
  5. package/docs/generated-docs/maz-avatar.doc.md +30 -30
  6. package/docs/generated-docs/maz-bottom-sheet.doc.md +16 -13
  7. package/docs/generated-docs/maz-btn.doc.md +21 -19
  8. package/docs/generated-docs/maz-checkbox.doc.md +16 -17
  9. package/docs/generated-docs/maz-circular-progress-bar.doc.md +1 -1
  10. package/docs/generated-docs/maz-code-highlight.doc.md +11 -0
  11. package/docs/generated-docs/maz-container.doc.md +1 -0
  12. package/docs/generated-docs/maz-date-picker.doc.md +41 -41
  13. package/docs/generated-docs/maz-drawer.doc.md +7 -8
  14. package/docs/generated-docs/maz-dropdown.doc.md +3 -0
  15. package/docs/generated-docs/maz-expand-animation.doc.md +4 -4
  16. package/docs/generated-docs/maz-fullscreen-loader.doc.md +5 -5
  17. package/docs/generated-docs/maz-gallery.doc.md +15 -15
  18. package/docs/generated-docs/maz-input-code.doc.md +16 -16
  19. package/docs/generated-docs/maz-input-phone-number.doc.md +43 -42
  20. package/docs/generated-docs/maz-input-price.doc.md +14 -14
  21. package/docs/generated-docs/maz-input-tags.doc.md +16 -16
  22. package/docs/generated-docs/maz-input.doc.md +33 -33
  23. package/docs/generated-docs/maz-lazy-img.doc.md +14 -14
  24. package/docs/generated-docs/maz-loading-bar.doc.md +4 -4
  25. package/docs/generated-docs/maz-markdown-editor.doc.md +65 -0
  26. package/docs/generated-docs/maz-popover.doc.md +1 -1
  27. package/docs/generated-docs/maz-pull-to-refresh.doc.md +39 -20
  28. package/docs/generated-docs/maz-radio-buttons.doc.md +17 -17
  29. package/docs/generated-docs/maz-radio.doc.md +16 -16
  30. package/docs/generated-docs/maz-reading-progress-bar.doc.md +4 -4
  31. package/docs/generated-docs/maz-select-country.doc.md +27 -26
  32. package/docs/generated-docs/maz-sidebar-content.doc.md +5 -0
  33. package/docs/generated-docs/maz-sidebar-footer.doc.md +5 -0
  34. package/docs/generated-docs/maz-sidebar-group.doc.md +11 -0
  35. package/docs/generated-docs/maz-sidebar-header.doc.md +5 -0
  36. package/docs/generated-docs/maz-sidebar-menu-button.doc.md +27 -0
  37. package/docs/generated-docs/maz-sidebar-menu-item.doc.md +5 -0
  38. package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +16 -0
  39. package/docs/generated-docs/maz-sidebar-menu.doc.md +5 -0
  40. package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
  41. package/docs/generated-docs/maz-sidebar-trigger.doc.md +5 -0
  42. package/docs/generated-docs/maz-sidebar.doc.md +36 -0
  43. package/docs/generated-docs/maz-slider.doc.md +1 -1
  44. package/docs/generated-docs/maz-spinner.doc.md +4 -4
  45. package/docs/generated-docs/maz-switch.doc.md +14 -14
  46. package/docs/generated-docs/maz-table-virtualizer.doc.md +20 -0
  47. package/docs/generated-docs/maz-table.doc.md +43 -37
  48. package/docs/generated-docs/maz-tabs-bar.doc.md +20 -9
  49. package/docs/generated-docs/maz-tabs.doc.md +6 -3
  50. package/docs/generated-docs/maz-textarea.doc.md +27 -25
  51. package/docs/generated-docs/maz-ticker.doc.md +1 -1
  52. package/docs/generated-docs/maz-timeline.doc.md +4 -4
  53. package/docs/generated-docs/maz-window-mockup.doc.md +23 -0
  54. package/docs/src/blog/v4.md +1 -1
  55. package/docs/src/blog/v5.md +5 -7
  56. package/docs/src/components/maz-avatar.md +52 -4
  57. package/docs/src/components/maz-bottom-sheet.md +300 -169
  58. package/docs/src/components/maz-btn.md +1 -1
  59. package/docs/src/components/maz-checklist.md +10 -10
  60. package/docs/src/components/maz-code-highlight.md +233 -0
  61. package/docs/src/components/maz-date-picker.md +55 -1
  62. package/docs/src/components/maz-dialog.md +46 -0
  63. package/docs/src/components/maz-dropdown.md +32 -16
  64. package/docs/src/components/maz-icon.md +16 -5
  65. package/docs/src/components/maz-input-phone-number.md +30 -0
  66. package/docs/src/components/maz-lazy-img.md +64 -0
  67. package/docs/src/components/maz-markdown-editor.md +369 -0
  68. package/docs/src/components/maz-pull-to-refresh.md +176 -17
  69. package/docs/src/components/maz-select-country.md +138 -1
  70. package/docs/src/components/maz-sidebar.md +719 -0
  71. package/docs/src/components/maz-table.md +156 -1
  72. package/docs/src/components/maz-tabs.md +110 -3
  73. package/docs/src/components/maz-textarea.md +58 -0
  74. package/docs/src/components/maz-timeline.md +60 -0
  75. package/docs/src/components/maz-window-mockup.md +249 -0
  76. package/docs/src/composables/use-drag.md +239 -0
  77. package/docs/src/composables/use-form-validator.md +297 -16
  78. package/docs/src/composables/use-pull-to-refresh.md +79 -0
  79. package/docs/src/composables/use-swipe.md +26 -11
  80. package/docs/src/directives/click-outside.md +8 -15
  81. package/docs/src/directives/fullscreen-img.md +1 -1
  82. package/docs/src/directives/lazy-img.md +44 -11
  83. package/docs/src/directives/tooltip.md +24 -1
  84. package/docs/src/directives/zoom-img.md +1 -1
  85. package/docs/src/ecosystem/eslint-config.md +95 -1
  86. package/docs/src/{guide/icons.md → ecosystem/icons/index.md} +1 -1
  87. package/docs/src/ecosystem/node/exec-promise.md +87 -0
  88. package/docs/src/ecosystem/node/index.md +53 -0
  89. package/docs/src/ecosystem/node/logger.md +146 -0
  90. package/docs/src/ecosystem/node/print-banner.md +93 -0
  91. package/docs/src/{guide → ecosystem}/nuxt.md +102 -47
  92. package/docs/src/{guide → ecosystem}/themes.md +152 -71
  93. package/docs/src/{guide → ecosystem}/translations.md +1 -1
  94. package/docs/src/ecosystem/utils/camel-case.md +31 -0
  95. package/docs/src/{helpers → ecosystem/utils}/capitalize.md +2 -3
  96. package/docs/src/ecosystem/utils/check-availability.md +79 -0
  97. package/docs/src/ecosystem/utils/cookie.md +80 -0
  98. package/docs/src/ecosystem/utils/debounce-callback.md +38 -0
  99. package/docs/src/ecosystem/utils/debounce-id.md +69 -0
  100. package/docs/src/ecosystem/utils/debounce.md +65 -0
  101. package/docs/src/ecosystem/utils/fetch-locale-ip.md +33 -0
  102. package/docs/src/ecosystem/utils/format-json.md +33 -0
  103. package/docs/src/ecosystem/utils/format-phone-number.md +37 -0
  104. package/docs/src/ecosystem/utils/get-browser-locale.md +29 -0
  105. package/docs/src/ecosystem/utils/get-error-message.md +39 -0
  106. package/docs/src/ecosystem/utils/idle-timeout.md +90 -0
  107. package/docs/src/ecosystem/utils/index.md +60 -0
  108. package/docs/src/ecosystem/utils/is-client.md +32 -0
  109. package/docs/src/ecosystem/utils/is-equal.md +38 -0
  110. package/docs/src/ecosystem/utils/is-server.md +31 -0
  111. package/docs/src/ecosystem/utils/is-standalone-mode.md +43 -0
  112. package/docs/src/ecosystem/utils/kebab-case.md +36 -0
  113. package/docs/src/ecosystem/utils/normalize-string.md +77 -0
  114. package/docs/src/ecosystem/utils/pascal-case.md +35 -0
  115. package/docs/src/ecosystem/utils/script-loader.md +77 -0
  116. package/docs/src/ecosystem/utils/sleep.md +59 -0
  117. package/docs/src/ecosystem/utils/snake-case.md +36 -0
  118. package/docs/src/ecosystem/utils/swipe-handler.md +91 -0
  119. package/docs/src/ecosystem/utils/textarea-autogrow.md +41 -0
  120. package/docs/src/ecosystem/utils/throttle-id.md +48 -0
  121. package/docs/src/ecosystem/utils/throttle.md +57 -0
  122. package/docs/src/ecosystem/utils/truthy-filter.md +31 -0
  123. package/docs/src/ecosystem/utils/types/deep-key-of.md +48 -0
  124. package/docs/src/ecosystem/utils/types/deep-partial.md +42 -0
  125. package/docs/src/ecosystem/utils/types/deep-required.md +39 -0
  126. package/docs/src/ecosystem/utils/types/flatten-object-keys.md +44 -0
  127. package/docs/src/ecosystem/utils/types/generic-instance-type.md +42 -0
  128. package/docs/src/ecosystem/utils/types/infer-maybe-ref.md +35 -0
  129. package/docs/src/ecosystem/utils/upper-first.md +32 -0
  130. package/docs/src/ecosystem/utils/user-visibility.md +69 -0
  131. package/docs/src/guide/getting-started.md +15 -13
  132. package/docs/src/guide/global-defaults.md +102 -0
  133. package/docs/src/guide/maz-ui-provider.md +6 -3
  134. package/docs/src/guide/migration-v4.md +13 -9
  135. package/docs/src/guide/migration-v5.md +211 -15
  136. package/docs/src/guide/resolvers.md +8 -8
  137. package/docs/src/guide/tailwind.md +4 -0
  138. package/docs/src/guide/vue.md +4 -4
  139. package/docs/src/index.md +13 -13
  140. package/docs/src/plugins/aos.md +1 -1
  141. package/package.json +11 -10
  142. package/docs/src/helpers/camel-case.md +0 -14
  143. package/docs/src/helpers/check-availability.md +0 -14
  144. package/docs/src/helpers/debounce-callback.md +0 -14
  145. package/docs/src/helpers/debounce-id.md +0 -14
  146. package/docs/src/helpers/debounce.md +0 -14
  147. package/docs/src/helpers/is-client.md +0 -14
  148. package/docs/src/helpers/is-equal.md +0 -14
  149. package/docs/src/helpers/is-standalone-mode.md +0 -14
  150. package/docs/src/helpers/kebab-case.md +0 -14
  151. package/docs/src/helpers/normalize-string.md +0 -14
  152. package/docs/src/helpers/pascal-case.md +0 -14
  153. package/docs/src/helpers/script-loader.md +0 -14
  154. package/docs/src/helpers/sleep.md +0 -14
  155. package/docs/src/helpers/snake-case.md +0 -14
  156. package/docs/src/helpers/throttle-id.md +0 -14
  157. package/docs/src/helpers/throttle.md +0 -14
  158. /package/docs/src/{guide → ecosystem/icons}/icon-set.md +0 -0
  159. /package/docs/src/{guide → ecosystem}/mcp.md +0 -0
  160. /package/docs/src/{helpers → ecosystem/utils}/country-code-to-unicode-flag.md +0 -0
  161. /package/docs/src/{helpers → ecosystem/utils}/currency.md +0 -0
  162. /package/docs/src/{helpers → ecosystem/utils}/date.md +0 -0
  163. /package/docs/src/{helpers → ecosystem/utils}/get-country-flag-url.md +0 -0
  164. /package/docs/src/{helpers → ecosystem/utils}/number.md +0 -0
@@ -11,8 +11,7 @@ description: vClickOutside is a Vue directive to trigger a function when the use
11
11
 
12
12
  <ComponentDemo>
13
13
  <div
14
- style="padding: 50px; background-color: var(--maz-surface-300);"
15
- class="maz:flex maz:flex-center maz:rounded-md"
14
+ class="maz:flex maz:flex-center maz:rounded-md maz:p-12 maz:bg-surface-300"
16
15
  >
17
16
  <MazCard v-click-outside="clikedOutside">
18
17
  Click outside me
@@ -21,8 +20,7 @@ description: vClickOutside is a Vue directive to trigger a function when the use
21
20
 
22
21
  <div
23
22
  v-if="hasClikedOutside"
24
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-success); color: black;"
25
- class="maz:flex maz:flex-center maz:rounded-md"
23
+ class="maz:flex maz:flex-center maz:rounded-md maz:bg-sucess maz:text-success-foreground maz:p-4 maz:mt-4"
26
24
  >
27
25
  You clicked outside
28
26
  </div>
@@ -44,8 +42,7 @@ function clikedOutside() {
44
42
 
45
43
  <template>
46
44
  <div
47
- style="padding: 50px; background-color: var(--maz-surface-300);"
48
- class="flex flex-center rounded"
45
+ class="maz:flex maz:flex-center maz:rounded-md maz:p-12 maz:bg-surface-300"
49
46
  >
50
47
  <MazCard v-click-outside="clikedOutside">
51
48
  Click outside me
@@ -54,8 +51,7 @@ function clikedOutside() {
54
51
 
55
52
  <div
56
53
  v-if="hasClikedOutside"
57
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-success); color: black;"
58
- class="flex flex-center rounded"
54
+ class="maz:flex maz:flex-center maz:rounded-md maz:bg-sucess maz:text-success-foreground maz:p-4 maz:mt-4"
59
55
  >
60
56
  You clicked outside
61
57
  </div>
@@ -71,8 +67,7 @@ The directive can accept an options object to customize its behavior:
71
67
 
72
68
  <ComponentDemo>
73
69
  <div
74
- style="padding: 50px; background-color: var(--maz-surface-300);"
75
- class="maz:flex maz:flex-center maz:rounded-md"
70
+ class="maz:flex maz:flex-center maz:rounded-md maz:p-12 maz:bg-surface-300"
76
71
  >
77
72
  <MazCard v-click-outside="{ callback: clickedOutsideWithIgnore, ignore: ['.ignore-me'] }">
78
73
  <div class="maz:p-4">
@@ -86,8 +81,7 @@ The directive can accept an options object to customize its behavior:
86
81
 
87
82
  <div
88
83
  v-if="hasClickedOutsideWithIgnore"
89
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-warning); color: black;"
90
- class="maz:flex maz:flex-center maz:rounded-md"
84
+ class="maz:flex maz:flex-center maz:rounded-md maz:bg-sucess maz:text-success-foreground maz:p-4 maz:mt-4"
91
85
  >
92
86
  You clicked outside (button clicks are ignored)
93
87
  </div>
@@ -128,8 +122,7 @@ The directive can be configured to trigger only once:
128
122
 
129
123
  <ComponentDemo>
130
124
  <div
131
- style="padding: 50px; background-color: var(--maz-surface-300);"
132
- class="maz:flex maz:flex-center maz:rounded-md"
125
+ class="maz:flex maz:flex-center maz:rounded-md maz:p-12 maz:bg-surface-300"
133
126
  >
134
127
  <MazCard v-click-outside="{ callback: clickedOnce, once: true }">
135
128
  Click outside me (works only once)
@@ -249,7 +242,7 @@ app.mount('#app')
249
242
 
250
243
  ### Nuxt
251
244
 
252
- Please refer to the [Nuxt module documentation](./../guide/nuxt.md) for more information.
245
+ Please refer to the [Nuxt module documentation](./../ecosystem/nuxt.md) for more information.
253
246
 
254
247
  <script lang="ts" setup>
255
248
  import { ref } from 'vue'
@@ -83,7 +83,7 @@ app.mount('#app')
83
83
 
84
84
  ### Nuxt
85
85
 
86
- Please refer to the [Nuxt module documentation](./../guide/nuxt.md) for more information.
86
+ Please refer to the [Nuxt module documentation](./../ecosystem/nuxt.md) for more information.
87
87
 
88
88
  ## Types
89
89
 
@@ -1,15 +1,20 @@
1
1
  ---
2
2
  title: vLazyImg
3
- description: vLazyImg is a Vue directive to lazy load images with many options. The image will be loaded on user's scroll
3
+ description: vLazyImg is a Vue directive to lazy load images with many options. Images are loaded when they enter the viewport, using a shared IntersectionObserver for optimal performance.
4
4
  ---
5
5
 
6
6
  # {{ $frontmatter.title }}
7
7
 
8
8
  {{ $frontmatter.description }}
9
9
 
10
+ ::: tip Performance
11
+ Every element bound to the directive shares a pooled `IntersectionObserver` (grouped by observer options) and keeps its state per element. You can render hundreds of lazy images - like a list of [`MazAvatar`](./../components/maz-avatar.md) - with only a handful of observers and no leak when elements unmount.
12
+ :::
13
+
10
14
  ## Basic usage
11
15
 
12
16
  <img
17
+ alt="Lazy loaded image"
13
18
  style="background-color: var(--maz-surface-300); width: 80%;"
14
19
  class="flex flex-center rounded"
15
20
  v-lazy-img="'https://placedog.net/1500/1000'"
@@ -49,11 +54,41 @@ import { vLazyImg } from 'maz-ui/directives'
49
54
  </template>
50
55
  ```
51
56
 
57
+ ## Disable lazy loading
58
+
59
+ Set `disabled: true` to load the image immediately, bypassing the `IntersectionObserver`. Useful for above-the-fold images or server-side rendering.
60
+
61
+ ```vue
62
+ <template>
63
+ <img
64
+ v-lazy-img="{ src: 'https://placedog.net/1500/1000', disabled: true }"
65
+ >
66
+ </template>
67
+ ```
68
+
69
+ ## Fallback image on error
70
+
71
+ Provide a `fallbackSrc` to replace the image when it fails to load. Set `fallbackSrc: false` to keep the broken image instead of loading the default placeholder.
72
+
73
+ <img class="maz:size-40" v-lazy-img="{ src: 'https://broken-link.example' }" alt="broken image" />
74
+
75
+ ```vue
76
+ <template>
77
+ <img
78
+ v-lazy-img="{
79
+ src: 'https://broken-link.example',
80
+ fallbackSrc: '/images/fallback.png',
81
+ }"
82
+ >
83
+ </template>
84
+ ```
85
+
52
86
  ## Options
53
87
 
54
88
  > Open the developer console to show logs
55
89
 
56
90
  <img
91
+ alt="Lazy loaded image with options"
57
92
  style="background-color: var(--maz-surface-300); width: 80%;"
58
93
  class="flex flex-center rounded"
59
94
  v-lazy-img="lazyBinding"
@@ -61,8 +96,7 @@ import { vLazyImg } from 'maz-ui/directives'
61
96
 
62
97
  ```vue
63
98
  <script lang="ts" setup>
64
- import { vLazyImg, vLazyImgBindingValue } from 'maz-ui/directives'
65
- import { ref } from 'vue'
99
+ import { vLazyImg, type vLazyImgBindingValue } from 'maz-ui/directives'
66
100
 
67
101
  const lazyBinding: vLazyImgBindingValue = {
68
102
  src: 'https://placedog.net/1500/1000',
@@ -71,7 +105,7 @@ const lazyBinding: vLazyImgBindingValue = {
71
105
  loadedClass: 'custom-class-loaded',
72
106
  errorClass: 'custom-class-error',
73
107
  fallbackClass: 'custom-class-fallback',
74
- observerOnce: false, // launch onIntersecting function each times where the user scrolls on the image
108
+ observerOnce: false, // run onIntersecting each time the user scrolls onto the image
75
109
  loadOnce: false,
76
110
  onLoading: (el: Element) => console.log('loading', el),
77
111
  onLoaded: (el: Element) => console.log('loaded', el),
@@ -94,7 +128,6 @@ const lazyBinding: vLazyImgBindingValue = {
94
128
  ### Vue
95
129
 
96
130
  ```typescript
97
- import errorPhoto from 'path/to/error-photo.png'
98
131
  import { vLazyImgInstall, type vLazyImgOptions } from 'maz-ui/directives'
99
132
  import { createApp } from 'vue'
100
133
 
@@ -109,13 +142,12 @@ const vLazyImgOptions: vLazyImgOptions = {
109
142
  fallbackClass: 'm-lazy-fallback',
110
143
  observerOnce: true,
111
144
  loadOnce: true,
112
- noUseErrorPhoto: false,
113
145
  observerOptions: {
114
146
  root: undefined,
115
147
  rootMargin: undefined,
116
148
  threshold: 0.1,
117
149
  },
118
- errorPhoto,
150
+ fallbackSrc: '/images/fallback.png', // or `false` to disable the default placeholder
119
151
  onLoading: (el: Element) => console.log('loading', el),
120
152
  onLoaded: (el: Element) => console.log('loaded', el),
121
153
  onError: (el: Element) => console.log('error', el),
@@ -129,7 +161,7 @@ app.mount('#app')
129
161
 
130
162
  ### Nuxt
131
163
 
132
- Please refer to the [Nuxt module documentation](./../guide/nuxt.md) for more information.
164
+ Please refer to the [Nuxt module documentation](./../ecosystem/nuxt.md) for more information.
133
165
 
134
166
  ## Types
135
167
 
@@ -147,7 +179,8 @@ export interface vLazyImgOptions {
147
179
  threshold: number
148
180
  rootMargin?: string
149
181
  }
150
- fallbackSrc?: string
182
+ /** Image loaded on error - set to `false` to keep the broken image */
183
+ fallbackSrc?: string | false
151
184
  onLoading?: (el: Element) => unknown
152
185
  onLoaded?: (el: Element) => unknown
153
186
  onError?: (el: Element) => unknown
@@ -155,7 +188,9 @@ export interface vLazyImgOptions {
155
188
  }
156
189
 
157
190
  interface vLazyImgBindingOptions extends vLazyImgOptions {
191
+ /** The source of the image when the binding value is an options object */
158
192
  src?: string
193
+ /** Load the image immediately, bypassing the IntersectionObserver */
159
194
  disabled?: boolean
160
195
  }
161
196
 
@@ -164,7 +199,6 @@ export type vLazyImgBindingValue = string | vLazyImgBindingOptions
164
199
 
165
200
  <script lang="ts" setup>
166
201
  import { vLazyImg, type vLazyImgBindingValue } from 'maz-ui/directives/vLazyImg'
167
- import { ref } from 'vue'
168
202
 
169
203
  const lazyBinding: vLazyImgBindingValue = {
170
204
  src: 'https://placedog.net/1500/1000',
@@ -173,7 +207,6 @@ export type vLazyImgBindingValue = string | vLazyImgBindingOptions
173
207
  loadedClass: 'custom-class-loaded',
174
208
  errorClass: 'custom-class-error',
175
209
  fallbackClass: 'custom-class-fallback',
176
- noUseErrorPhoto: true,
177
210
  observerOnce: false,
178
211
  loadOnce: true,
179
212
  onLoading: (el: Element) => console.log('loading', el),
@@ -400,6 +400,29 @@ The `offset` (in px) option allows you to adjust the position of the tooltip rel
400
400
  </template>
401
401
  </ComponentDemo>
402
402
 
403
+ ## Conditionally disable
404
+
405
+ Pass `false`, `null` or `undefined` as the binding value to silently disable the tooltip — no popover instance is created, no listeners are attached, and no warning is logged. This is the recommended way to skip the tooltip on the fly without conditionally rendering two different elements:
406
+
407
+ ```vue
408
+ <script lang="ts" setup>
409
+ import { vTooltip } from 'maz-ui/directives'
410
+ import { computed, ref } from 'vue'
411
+
412
+ const label = ref<string>('')
413
+ const tooltipBinding = computed(() => label.value ? { text: label.value } : false)
414
+ </script>
415
+
416
+ <template>
417
+ <!-- When label is empty the directive becomes a no-op -->
418
+ <MazBtn v-tooltip="tooltipBinding">
419
+ Hover me
420
+ </MazBtn>
421
+ </template>
422
+ ```
423
+
424
+ If the binding switches back to a valid value later, the tooltip mounts as expected. Toggling the value off again destroys the existing popover instance.
425
+
403
426
  ## Global install
404
427
 
405
428
  ### Vue
@@ -421,7 +444,7 @@ app.mount('#app')
421
444
 
422
445
  ### Nuxt
423
446
 
424
- Please refer to the [Nuxt module documentation](./../guide/nuxt.md) for more information.
447
+ Please refer to the [Nuxt module documentation](./../ecosystem/nuxt.md) for more information.
425
448
 
426
449
  ## Types
427
450
 
@@ -107,7 +107,7 @@ app.mount('#app')
107
107
 
108
108
  ### Nuxt
109
109
 
110
- Please refer to the [Nuxt module documentation](./../guide/nuxt.md) for more information.
110
+ Please refer to the [Nuxt module documentation](./../ecosystem/nuxt.md) for more information.
111
111
 
112
112
  ## Types
113
113
 
@@ -114,6 +114,8 @@ defineConfig({
114
114
  detectComponentClasses: true,
115
115
  // Monorepo: directory used to resolve `tailwindcss` and the config file.
116
116
  cwd: 'apps/web',
117
+ // Custom `maz/tailwind-no-arbitrary-px` rule — see "Custom rules" below.
118
+ noArbitraryPx: true,
117
119
  },
118
120
  })
119
121
  ```
@@ -135,12 +137,98 @@ defineConfig({
135
137
 
136
138
  The plugin recognizes the most common class-name utilities out of the box (`clsx`, `cn`, `tw-merge`, `cva`, `tv`, …); see the [plugin docs](https://github.com/schoero/eslint-plugin-better-tailwindcss) for the full list and how to register your own.
137
139
 
140
+ ## Custom rules
141
+
142
+ `@maz-ui/eslint-config` ships its own ESLint plugin under the **`maz/*`** namespace. Rules are grouped by category — `maz/tailwind-*` today, with room for `maz/js-*` and others as they get added.
143
+
144
+ ### `maz/tailwind-no-arbitrary-px`
145
+
146
+ Forbids `px` units inside Tailwind arbitrary value classes (`w-[16px]`, `m-[-16px]`, `[gap:24px]`, …) and **autofixes** them to `rem` (or `em`) using your project's root font-size. Whitespace inside brackets (e.g. `[up to 100px]`) is left alone, so plain prose is never rewritten by accident.
147
+
148
+ ::: info Registered only when `tailwindcss` is enabled
149
+ The `maz` plugin and the `maz/tailwind-*` rules are only added to the flat-config when `tailwindcss` is set to anything other than `false`. With `tailwindcss: false` *(default)*, neither the plugin nor the rule appear in the resolved config — keeping the preset zero-cost for non-Tailwind projects. To use the rule without opting into the full Tailwind preset, register `mazPlugin` manually (see [Use the plugin directly](#use-the-plugin-directly)).
150
+ :::
151
+
152
+ When `tailwindcss` is on, the rule is enabled with defaults. You can tune it two ways:
153
+
154
+ **Standard ESLint override** *(idiomatic, max control)*
155
+
156
+ ```ts
157
+ defineConfig({
158
+ tailwindcss: 'recommended',
159
+ rules: {
160
+ 'maz/tailwind-no-arbitrary-px': ['error', { baseFontSize: 10, unit: 'em' }],
161
+ },
162
+ })
163
+ ```
164
+
165
+ User `rules` overrides are applied in a *trailing* flat-config block, so they win over the defaults wired in by `tailwindcssConfigs`.
166
+
167
+ **Ergonomic shortcut** *(set defaults via `tailwindcss.noArbitraryPx`)*
168
+
169
+ ```ts
170
+ defineConfig({
171
+ tailwindcss: {
172
+ preset: 'recommended',
173
+ noArbitraryPx: {
174
+ baseFontSize: 16, // default — divide px by this to get rem
175
+ unit: 'rem', // default — output unit ('rem' | 'em')
176
+ severity: 'error', // default — 'off' | 'warn' | 'error'
177
+ },
178
+ },
179
+ })
180
+ ```
181
+
182
+ | `noArbitraryPx` value | Behavior |
183
+ | ---------------------------------- | --------------------------------------------------- |
184
+ | `true` *(default)* | Enabled with defaults (`baseFontSize: 16`, `rem`). |
185
+ | `false` | Disabled. |
186
+ | `{ baseFontSize, unit, severity }` | Override any subset of the defaults. |
187
+
188
+ If both are set, the standard `rules` override wins (it's the last block applied).
189
+
190
+ What the autofix does (with `baseFontSize: 16`):
191
+
192
+ | Before | After |
193
+ | ----------------------- | ------------------------ |
194
+ | `w-[16px]` | `w-[1rem]` |
195
+ | `m-[-16px]` | `m-[-1rem]` |
196
+ | `tracking-[.5px]` | `tracking-[0.03125rem]` |
197
+ | `p-[16px_8px]` | `p-[1rem_0.5rem]` |
198
+ | `[gap:24px]` | `[gap:1.5rem]` |
199
+ | `w-[calc(100%-16px)]` | `w-[calc(100%-1rem)]` |
200
+ | `md:hover:w-[16px]` | `md:hover:w-[1rem]` |
201
+
202
+ The rule fires on:
203
+
204
+ - JSX `className` strings and template literals
205
+ - Vue SFC static `class="…"` attributes (via `vue-eslint-parser`)
206
+ - Vue dynamic `:class` bindings, including string literals inside arrays / objects
207
+ - Function-call arguments and tagged template literals (`clsx`, `cn`, `cva`, `tw`, …)
208
+
209
+ ### Use the plugin directly
210
+
211
+ If you don't want the full Tailwind preset (or just prefer wiring rules yourself), import `mazPlugin` and register it in your own flat-config block. This is also the way to use `maz/tailwind-*` rules **without** enabling `tailwindcss` in `defineConfig`:
212
+
213
+ ```ts
214
+ import { mazPlugin } from '@maz-ui/eslint-config'
215
+
216
+ export default [{
217
+ files: ['**/*.{ts,tsx,vue}'],
218
+ plugins: { maz: mazPlugin },
219
+ rules: {
220
+ 'maz/tailwind-no-arbitrary-px': ['error', { baseFontSize: 16, unit: 'rem' }],
221
+ },
222
+ }]
223
+ ```
224
+
138
225
  ## What it includes
139
226
 
140
227
  - **Antfu base** — TypeScript-aware rules, Stylistic formatting, modern import order.
141
228
  - **SonarJS** — code quality and complexity heuristics, with a relaxed set for `*.spec.ts` / `*.test.ts`.
142
229
  - **Vue rules** (when Vue/Nuxt is detected) — block-tag order, naming conventions, template a11y.
143
230
  - **Tailwind plugin** (opt-in) — class ordering, duplicate / deprecated / unknown / conflicting class detection — see [Tailwind support](#tailwind-support).
231
+ - **`maz/*` custom rules** — namespaced ESLint plugin shipped with the preset; see [Custom rules](#custom-rules).
144
232
  - **Markdown** — prose linting baseline.
145
233
  - **vueAccessibility** (opt-in) — `eslint-plugin-vuejs-accessibility` rules with the AudioWorklet globals fix.
146
234
 
@@ -151,6 +239,7 @@ The plugin recognizes the most common class-name utilities out of the box (`clsx
151
239
  ```ts
152
240
  import {
153
241
  baseRules,
242
+ mazPlugin,
154
243
  sonarjsRules,
155
244
  tailwindcssConfigs,
156
245
  vueRules,
@@ -158,14 +247,19 @@ import {
158
247
 
159
248
  export default [
160
249
  {
250
+ plugins: { maz: mazPlugin },
161
251
  rules: {
162
252
  ...baseRules(true), // production = true → no-console: 'error'
163
253
  ...sonarjsRules,
164
254
  ...vueRules,
255
+ 'maz/tailwind-no-arbitrary-px': 'error',
165
256
  },
166
257
  },
167
258
  // Drop in just the Tailwind block, with whatever preset and settings you want.
168
- ...tailwindcssConfigs('stylistic', { entryPoint: 'src/main.css' }),
259
+ ...tailwindcssConfigs('stylistic', {
260
+ entryPoint: 'src/main.css',
261
+ noArbitraryPx: { unit: 'em' },
262
+ }),
169
263
  ]
170
264
  ```
171
265
 
@@ -151,7 +151,7 @@ Never worry about imports again with automatic component resolution.
151
151
 
152
152
  ::: warning Troubleshooting
153
153
 
154
- If your are already using [`MazComponentsResolver`](./resolvers.md#mazcomponentsresolver), you should place `MazIconsResolver` before `MazComponentsResolver` in the `resolvers` array.
154
+ If your are already using [`MazComponentsResolver`](../../guide/resolvers.md#mazcomponentsresolver), you should place `MazIconsResolver` before `MazComponentsResolver` in the `resolvers` array.
155
155
 
156
156
  :::
157
157
 
@@ -0,0 +1,87 @@
1
+ ---
2
+ title: execPromise
3
+ description: Promise-based wrapper around `child_process.exec` with structured stdout/stderr/error logging, package-scoped prefixes, and per-call log silencing.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { execPromise, logger } from '@maz-ui/node'
14
+
15
+ try {
16
+ const { stdout } = await execPromise('npm --version')
17
+ logger.log('npm version:', stdout.trim())
18
+ }
19
+ catch (error) {
20
+ logger.error('Command failed', error)
21
+ }
22
+ ```
23
+
24
+ ## API
25
+
26
+ ```ts
27
+ function execPromise(
28
+ command: string,
29
+ options?: ExecPromiseOptions,
30
+ ): Promise<{ stdout: string, stderr: string }>
31
+
32
+ interface ExecPromiseOptions {
33
+ logger?: CustomLogger
34
+ packageName?: string
35
+ noSuccess?: boolean
36
+ noStdout?: boolean
37
+ noStderr?: boolean
38
+ noError?: boolean
39
+ logLevel?: LogLevel
40
+ cwd?: string
41
+ }
42
+ ```
43
+
44
+ ### Options
45
+
46
+ | Option | Type | Default | Description |
47
+ | ------------- | ------------- | ----------- | --------------------------------------------------------------------------------- |
48
+ | `logger` | `CustomLogger` | built-in | Custom logger (must expose `log`, `error`, `info`, `warn`, `debug` methods). |
49
+ | `packageName` | `string` | — | Prepended to logs as `[name]: ` — useful when many commands share a logger. |
50
+ | `noSuccess` | `boolean` | `false` | Skip the `info` line printed when the command finishes successfully. |
51
+ | `noStdout` | `boolean` | `false` | Don't pipe stdout to the logger (still returned in the promise result). |
52
+ | `noStderr` | `boolean` | `false` | Don't pipe stderr to the logger (still returned in the promise result). |
53
+ | `noError` | `boolean` | `false` | Don't log errors before rejecting. |
54
+ | `logLevel` | `LogLevel` | unchanged | Temporarily sets the default logger's level for this call. |
55
+ | `cwd` | `string` | `process.cwd()` | Working directory for the command. |
56
+
57
+ The returned promise **resolves** with `{ stdout, stderr }` on success and **rejects** with the exec error on failure.
58
+
59
+ ## Examples
60
+
61
+ Run a build silently, only reporting success/failure:
62
+
63
+ ```ts
64
+ await execPromise('npm run build', {
65
+ packageName: 'build',
66
+ noStdout: true,
67
+ noStderr: true,
68
+ })
69
+ ```
70
+
71
+ Use a custom logger for an isolated subsystem:
72
+
73
+ ```ts
74
+ import { createLogger, execPromise } from '@maz-ui/node'
75
+
76
+ const ciLogger = createLogger({ level: 2 })
77
+
78
+ await execPromise('npm test', {
79
+ logger: ciLogger,
80
+ packageName: 'tests',
81
+ })
82
+ ```
83
+
84
+ ## Notes
85
+
86
+ - `execPromise` uses Node's `child_process.exec`, which buffers all output in memory. For commands that produce very large streams, prefer `child_process.spawn` directly.
87
+ - `stdout`/`stderr` are still returned in the promise result even when `noStdout`/`noStderr` are set — the flags only affect logging.
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: '@maz-ui/node'
3
+ description: Lightweight Node.js utilities — promise-based shell execution, an opinionated consola-backed logger, and a banner printer for CLIs.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ <NpmBadge package="@maz-ui/node" />
11
+
12
+ `@maz-ui/node` powers the CLIs and build scripts inside the maz-ui ecosystem. It's intentionally tiny: an `exec` wrapper that returns a real `Promise`, a colourful logger built on [consola](https://github.com/unjs/consola), and a banner helper using [figlet](https://github.com/patorjk/figlet.js).
13
+
14
+ ## Installation
15
+
16
+ ::: code-group
17
+
18
+ ```bash [pnpm]
19
+ pnpm add @maz-ui/node
20
+ ```
21
+
22
+ ```bash [npm]
23
+ npm install @maz-ui/node
24
+ ```
25
+
26
+ ```bash [yarn]
27
+ yarn add @maz-ui/node
28
+ ```
29
+
30
+ :::
31
+
32
+ ## Basic usage
33
+
34
+ ```ts
35
+ import { execPromise, logger, printBanner } from '@maz-ui/node'
36
+
37
+ printBanner({ name: 'my-cli', version: '1.0.0' })
38
+
39
+ logger.info('Running tests…')
40
+ await execPromise('npm test', { packageName: 'tests' })
41
+ logger.success('Done')
42
+ ```
43
+
44
+ ## What's inside
45
+
46
+ - [`execPromise`](./exec-promise) — Promise-based `child_process.exec` with structured logging.
47
+ - [`logger` / `createLogger`](./logger) — consola-backed logger with semantic log levels and helpers (`box`, `divider`, `brand`, …).
48
+ - [`printBanner`](./print-banner) — ASCII-art banner printer (figlet) with versioning, dividers and clearing.
49
+
50
+ ## Requirements
51
+
52
+ - Node.js >= 18.0.0
53
+ - ESM only — published as `"type": "module"`.