@maz-ui/mcp 5.0.0-beta.2 → 5.0.0-beta.25

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 (146) 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 +25 -25
  6. package/docs/generated-docs/maz-btn.doc.md +1 -1
  7. package/docs/generated-docs/maz-checkbox.doc.md +16 -17
  8. package/docs/generated-docs/maz-circular-progress-bar.doc.md +1 -1
  9. package/docs/generated-docs/maz-code-highlight.doc.md +11 -0
  10. package/docs/generated-docs/maz-date-picker.doc.md +41 -41
  11. package/docs/generated-docs/maz-drawer.doc.md +7 -8
  12. package/docs/generated-docs/maz-expand-animation.doc.md +4 -4
  13. package/docs/generated-docs/maz-fullscreen-loader.doc.md +5 -5
  14. package/docs/generated-docs/maz-gallery.doc.md +15 -15
  15. package/docs/generated-docs/maz-input-code.doc.md +16 -16
  16. package/docs/generated-docs/maz-input-phone-number.doc.md +42 -38
  17. package/docs/generated-docs/maz-input-price.doc.md +14 -14
  18. package/docs/generated-docs/maz-input-tags.doc.md +16 -16
  19. package/docs/generated-docs/maz-input.doc.md +33 -33
  20. package/docs/generated-docs/maz-lazy-img.doc.md +14 -14
  21. package/docs/generated-docs/maz-loading-bar.doc.md +4 -4
  22. package/docs/generated-docs/maz-markdown-editor.doc.md +65 -0
  23. package/docs/generated-docs/maz-popover.doc.md +1 -1
  24. package/docs/generated-docs/maz-pull-to-refresh.doc.md +10 -10
  25. package/docs/generated-docs/maz-radio-buttons.doc.md +17 -17
  26. package/docs/generated-docs/maz-radio.doc.md +16 -16
  27. package/docs/generated-docs/maz-reading-progress-bar.doc.md +4 -4
  28. package/docs/generated-docs/maz-sidebar-content.doc.md +5 -0
  29. package/docs/generated-docs/maz-sidebar-footer.doc.md +5 -0
  30. package/docs/generated-docs/maz-sidebar-group.doc.md +11 -0
  31. package/docs/generated-docs/maz-sidebar-header.doc.md +5 -0
  32. package/docs/generated-docs/maz-sidebar-menu-button.doc.md +27 -0
  33. package/docs/generated-docs/maz-sidebar-menu-item.doc.md +5 -0
  34. package/docs/generated-docs/maz-sidebar-menu-sub.doc.md +16 -0
  35. package/docs/generated-docs/maz-sidebar-menu.doc.md +5 -0
  36. package/docs/generated-docs/maz-sidebar-separator.doc.md +0 -0
  37. package/docs/generated-docs/maz-sidebar-trigger.doc.md +5 -0
  38. package/docs/generated-docs/maz-sidebar.doc.md +36 -0
  39. package/docs/generated-docs/maz-slider.doc.md +1 -1
  40. package/docs/generated-docs/maz-spinner.doc.md +4 -4
  41. package/docs/generated-docs/maz-switch.doc.md +14 -14
  42. package/docs/generated-docs/maz-table.doc.md +5 -5
  43. package/docs/generated-docs/maz-textarea.doc.md +25 -24
  44. package/docs/generated-docs/maz-ticker.doc.md +1 -1
  45. package/docs/generated-docs/maz-timeline.doc.md +4 -4
  46. package/docs/generated-docs/maz-window-mockup.doc.md +23 -0
  47. package/docs/src/blog/v4.md +1 -1
  48. package/docs/src/blog/v5.md +5 -7
  49. package/docs/src/components/maz-btn.md +1 -1
  50. package/docs/src/components/maz-code-highlight.md +233 -0
  51. package/docs/src/components/maz-container.md +2 -2
  52. package/docs/src/components/maz-date-picker.md +1 -1
  53. package/docs/src/components/maz-dialog.md +46 -0
  54. package/docs/src/components/maz-icon.md +2 -2
  55. package/docs/src/components/maz-input-phone-number.md +106 -103
  56. package/docs/src/components/maz-markdown-editor.md +369 -0
  57. package/docs/src/components/maz-sidebar.md +719 -0
  58. package/docs/src/components/maz-textarea.md +27 -1
  59. package/docs/src/components/maz-timeline.md +60 -0
  60. package/docs/src/components/maz-window-mockup.md +249 -0
  61. package/docs/src/directives/click-outside.md +8 -15
  62. package/docs/src/directives/fullscreen-img.md +1 -1
  63. package/docs/src/directives/lazy-img.md +5 -5
  64. package/docs/src/directives/tooltip.md +24 -1
  65. package/docs/src/directives/zoom-img.md +1 -1
  66. package/docs/src/ecosystem/eslint-config.md +95 -1
  67. package/docs/src/{guide/icons.md → ecosystem/icons/index.md} +1 -1
  68. package/docs/src/ecosystem/node/exec-promise.md +87 -0
  69. package/docs/src/ecosystem/node/index.md +53 -0
  70. package/docs/src/ecosystem/node/logger.md +146 -0
  71. package/docs/src/ecosystem/node/print-banner.md +93 -0
  72. package/docs/src/{guide → ecosystem}/nuxt.md +81 -47
  73. package/docs/src/{guide → ecosystem}/themes.md +153 -72
  74. package/docs/src/{guide → ecosystem}/translations.md +1 -1
  75. package/docs/src/ecosystem/utils/camel-case.md +31 -0
  76. package/docs/src/{helpers → ecosystem/utils}/capitalize.md +2 -3
  77. package/docs/src/ecosystem/utils/check-availability.md +79 -0
  78. package/docs/src/ecosystem/utils/cookie.md +80 -0
  79. package/docs/src/{helpers → ecosystem/utils}/currency.md +2 -2
  80. package/docs/src/{helpers → ecosystem/utils}/date.md +2 -2
  81. package/docs/src/ecosystem/utils/debounce-callback.md +38 -0
  82. package/docs/src/ecosystem/utils/debounce-id.md +69 -0
  83. package/docs/src/ecosystem/utils/debounce.md +65 -0
  84. package/docs/src/ecosystem/utils/fetch-locale-ip.md +33 -0
  85. package/docs/src/ecosystem/utils/format-json.md +33 -0
  86. package/docs/src/ecosystem/utils/format-phone-number.md +37 -0
  87. package/docs/src/ecosystem/utils/get-browser-locale.md +29 -0
  88. package/docs/src/ecosystem/utils/get-error-message.md +39 -0
  89. package/docs/src/ecosystem/utils/idle-timeout.md +90 -0
  90. package/docs/src/ecosystem/utils/index.md +60 -0
  91. package/docs/src/ecosystem/utils/is-client.md +32 -0
  92. package/docs/src/ecosystem/utils/is-equal.md +38 -0
  93. package/docs/src/ecosystem/utils/is-server.md +31 -0
  94. package/docs/src/ecosystem/utils/is-standalone-mode.md +43 -0
  95. package/docs/src/ecosystem/utils/kebab-case.md +36 -0
  96. package/docs/src/ecosystem/utils/normalize-string.md +77 -0
  97. package/docs/src/{helpers → ecosystem/utils}/number.md +2 -2
  98. package/docs/src/ecosystem/utils/pascal-case.md +35 -0
  99. package/docs/src/ecosystem/utils/script-loader.md +77 -0
  100. package/docs/src/ecosystem/utils/sleep.md +59 -0
  101. package/docs/src/ecosystem/utils/snake-case.md +36 -0
  102. package/docs/src/ecosystem/utils/swipe-handler.md +91 -0
  103. package/docs/src/ecosystem/utils/textarea-autogrow.md +41 -0
  104. package/docs/src/ecosystem/utils/throttle-id.md +48 -0
  105. package/docs/src/ecosystem/utils/throttle.md +57 -0
  106. package/docs/src/ecosystem/utils/truthy-filter.md +31 -0
  107. package/docs/src/ecosystem/utils/types/deep-key-of.md +48 -0
  108. package/docs/src/ecosystem/utils/types/deep-partial.md +42 -0
  109. package/docs/src/ecosystem/utils/types/deep-required.md +39 -0
  110. package/docs/src/ecosystem/utils/types/flatten-object-keys.md +44 -0
  111. package/docs/src/ecosystem/utils/types/generic-instance-type.md +42 -0
  112. package/docs/src/ecosystem/utils/types/infer-maybe-ref.md +35 -0
  113. package/docs/src/ecosystem/utils/upper-first.md +32 -0
  114. package/docs/src/ecosystem/utils/user-visibility.md +69 -0
  115. package/docs/src/guide/getting-started.md +15 -13
  116. package/docs/src/guide/global-defaults.md +101 -0
  117. package/docs/src/guide/maz-ui-provider.md +6 -3
  118. package/docs/src/guide/migration-v4.md +13 -9
  119. package/docs/src/guide/migration-v5.md +67 -12
  120. package/docs/src/guide/resolvers.md +7 -7
  121. package/docs/src/guide/tailwind.md +4 -0
  122. package/docs/src/guide/vue.md +4 -4
  123. package/docs/src/index.md +12 -12
  124. package/docs/src/plugins/aos.md +1 -1
  125. package/docs/src/plugins/wait.md +1 -1
  126. package/package.json +6 -5
  127. package/docs/src/helpers/camel-case.md +0 -14
  128. package/docs/src/helpers/check-availability.md +0 -14
  129. package/docs/src/helpers/debounce-callback.md +0 -14
  130. package/docs/src/helpers/debounce-id.md +0 -14
  131. package/docs/src/helpers/debounce.md +0 -14
  132. package/docs/src/helpers/is-client.md +0 -14
  133. package/docs/src/helpers/is-equal.md +0 -14
  134. package/docs/src/helpers/is-standalone-mode.md +0 -14
  135. package/docs/src/helpers/kebab-case.md +0 -14
  136. package/docs/src/helpers/normalize-string.md +0 -14
  137. package/docs/src/helpers/pascal-case.md +0 -14
  138. package/docs/src/helpers/script-loader.md +0 -14
  139. package/docs/src/helpers/sleep.md +0 -14
  140. package/docs/src/helpers/snake-case.md +0 -14
  141. package/docs/src/helpers/throttle-id.md +0 -14
  142. package/docs/src/helpers/throttle.md +0 -14
  143. /package/docs/src/{guide → ecosystem/icons}/icon-set.md +0 -0
  144. /package/docs/src/{guide → ecosystem}/mcp.md +0 -0
  145. /package/docs/src/{helpers → ecosystem/utils}/country-code-to-unicode-flag.md +0 -0
  146. /package/docs/src/{helpers → ecosystem/utils}/get-country-flag-url.md +0 -0
@@ -0,0 +1,79 @@
1
+ ---
2
+ title: checkAvailability
3
+ description: Poll a getter until a value is available (or matches an expected value), then run a callback — with timeout and configurable retry interval.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Useful for waiting on a third-party SDK to attach itself to `window`, on a Vue ref to be populated after mount, or on any asynchronously-available value.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { checkAvailability } from '@maz-ui/utils'
16
+
17
+ checkAvailability(
18
+ () => window.Stripe,
19
+ (Stripe) => {
20
+ const stripe = Stripe('pk_...')
21
+ },
22
+ )
23
+ ```
24
+
25
+ ## API
26
+
27
+ ```ts
28
+ function checkAvailability<T>(
29
+ getRef: () => T | null | undefined,
30
+ callback: (value: NonNullable<T>) => void,
31
+ options?: {
32
+ maxAttempts?: number
33
+ interval?: number
34
+ expectedValue?: T
35
+ errorMessage?: string
36
+ onError?: (error: Error) => void
37
+ },
38
+ ): void
39
+ ```
40
+
41
+ | Option | Type | Default | Description |
42
+ | --------------- | ---------- | ------- | ---------------------------------------------------------------------- |
43
+ | `maxAttempts` | `number` | `20` | Number of polls before giving up |
44
+ | `interval` | `number` | `100` | Delay between polls, in milliseconds |
45
+ | `expectedValue` | `T` | — | When set, callback fires only when `getRef()` strictly equals this value |
46
+ | `errorMessage` | `string` | — | Custom error message when `maxAttempts` is exceeded |
47
+ | `onError` | `Function` | — | Called with the timeout `Error` instead of throwing |
48
+
49
+ With default options, the helper polls every 100 ms up to 20 times — a 2 second timeout in total.
50
+
51
+ ## Examples
52
+
53
+ Wait for a global SDK with a custom timeout:
54
+
55
+ ```ts
56
+ checkAvailability(
57
+ () => window.gtag,
58
+ (gtag) => {
59
+ gtag('event', 'page_view')
60
+ },
61
+ {
62
+ maxAttempts: 50,
63
+ interval: 200,
64
+ onError: (err) => {
65
+ console.warn('gtag never loaded', err)
66
+ },
67
+ },
68
+ )
69
+ ```
70
+
71
+ Wait for a specific value (e.g. SDK becomes ready):
72
+
73
+ ```ts
74
+ checkAvailability(
75
+ () => window.__SDK_STATE__,
76
+ () => boot(),
77
+ { expectedValue: 'ready' },
78
+ )
79
+ ```
@@ -0,0 +1,80 @@
1
+ ---
2
+ title: cookie
3
+ description: Read, write and delete browser cookies with full attribute support — `path`, `domain`, `maxAge`, `expires`, `secure`, `sameSite`, `partitioned`.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ The module exports three functions: `getCookie`, `setCookie`, `deleteCookie`. Reads work both on the client (via `document.cookie`) and on the server (when you pass the raw `Cookie` header).
11
+
12
+ ## getCookie
13
+
14
+ ```ts
15
+ import { getCookie } from '@maz-ui/utils'
16
+
17
+ const theme = getCookie('theme') // 'dark' | null
18
+ ```
19
+
20
+ ```ts
21
+ function getCookie(key: string, cookieHeader?: string): string | null
22
+ ```
23
+
24
+ | Parameter | Type | Description |
25
+ | -------------- | -------- | -------------------------------------------------------------------------------------------- |
26
+ | `key` | `string` | Cookie name |
27
+ | `cookieHeader` | `string` | (Optional) Raw `Cookie` request header — pass during SSR (e.g. from `useSSRContext()` in Nuxt) |
28
+
29
+ Returns the URL-decoded value, or `null` when the cookie is absent.
30
+
31
+ ## setCookie
32
+
33
+ ```ts
34
+ import { setCookie } from '@maz-ui/utils'
35
+
36
+ setCookie('theme', 'dark')
37
+
38
+ setCookie('session', token, {
39
+ maxAge: 60 * 60, // 1 hour
40
+ secure: true,
41
+ sameSite: 'Strict',
42
+ })
43
+ ```
44
+
45
+ ```ts
46
+ function setCookie(key: string, value: string, options?: CookieOptions): void
47
+ ```
48
+
49
+ No-op on the server.
50
+
51
+ ### Options
52
+
53
+ | Option | Type | Default | Description |
54
+ | ------------- | --------- | ---------------- | --------------------------------------------------------------------------------- |
55
+ | `path` | `string` | `'/'` | Path attribute. Pass `null` to omit. |
56
+ | `domain` | `string` | — | Domain attribute. |
57
+ | `maxAge` | `number` | `31_536_000` (1y) | Lifetime in seconds. Pass `null` for a session cookie. |
58
+ | `expires` | `Date` | — | Explicit expiration date. Takes precedence over `maxAge`. |
59
+ | `secure` | `boolean` | — | Restrict to HTTPS. |
60
+ | `sameSite` | `'Lax' \| 'Strict' \| 'None'` | `'Lax'` | Same-site policy. Pass `null` to omit. |
61
+ | `partitioned` | `boolean` | — | Mark the cookie as partitioned (CHIPS). |
62
+
63
+ ::: warning `HttpOnly`
64
+ `HttpOnly` cannot be set from `document.cookie` — browsers reject it. Use a server-set cookie for that.
65
+ :::
66
+
67
+ ## deleteCookie
68
+
69
+ ```ts
70
+ import { deleteCookie } from '@maz-ui/utils'
71
+
72
+ deleteCookie('session')
73
+ deleteCookie('analytics-id', { domain: '.example.com' })
74
+ ```
75
+
76
+ ```ts
77
+ function deleteCookie(key: string, options?: Pick<CookieOptions, 'path' | 'domain'>): void
78
+ ```
79
+
80
+ For the deletion to take effect, `path` and `domain` must match the values used when the cookie was set.
@@ -16,7 +16,7 @@ Enter only numbers
16
16
  <MazInput v-model="numberValue" type="number" />
17
17
 
18
18
  <div
19
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-surface-300);"
19
+ style="padding: 16px; margin-top: 16px; background-color: var(--maz-color-surface-300);"
20
20
  class="flex flex-center rounded gap-05"
21
21
  >
22
22
  formatted value: <strong>{{ priceFormatted }}</strong>
@@ -38,7 +38,7 @@ const priceFormatted = computed(() =>
38
38
  <MazInput v-model="numberValue" type="number" />
39
39
 
40
40
  <div
41
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-surface-300);"
41
+ style="padding: 16px; margin-top: 16px; background-color: var(--maz-color-surface-300);"
42
42
  >
43
43
  {{ priceFormatted }}
44
44
  </div>
@@ -12,7 +12,7 @@ description: The module formatDate is a function that formats dates with the nat
12
12
  <MazInput v-model="dateValue" type="date" />
13
13
 
14
14
  <div
15
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-surface-300);"
15
+ style="padding: 16px; margin-top: 16px; background-color: var(--maz-color-surface-300);"
16
16
  class="flex flex-center rounded gap-05"
17
17
  >
18
18
  formatted value: <strong>{{ dateFormatted }}</strong>
@@ -34,7 +34,7 @@ const dateFormatted = computed(() =>
34
34
  <MazInput v-model="dateValue" type="date" />
35
35
 
36
36
  <div
37
- style="padding: 16px; margin-top: 16px; background-color: var(--maz-surface-300);"
37
+ style="padding: 16px; margin-top: 16px; background-color: var(--maz-color-surface-300);"
38
38
  >
39
39
  {{ dateFormatted }}
40
40
  </div>
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: debounceCallback
3
+ description: Module-scoped one-shot debounce — schedule a callback that gets reset on each new call.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Unlike [`debounce`](./debounce), which builds a debounced wrapper around a function, `debounceCallback` is a procedural helper: each call schedules a callback after `delay` ms, cancelling any previous pending callback.
11
+
12
+ ::: warning Shared module state
13
+ `debounceCallback` uses a single module-level timer. All consumers of this function share the same timer slot, so calling it from two unrelated places will cancel each other. Use [`debounceId`](./debounce-id) for isolated debounces.
14
+ :::
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { debounceCallback } from '@maz-ui/utils'
20
+
21
+ debounceCallback(() => {
22
+ console.log('runs only if no other call happens in the next 300 ms')
23
+ }, 300)
24
+ ```
25
+
26
+ ## API
27
+
28
+ ```ts
29
+ function debounceCallback(
30
+ callback: (...args: unknown[]) => unknown,
31
+ delay: number,
32
+ ): void
33
+ ```
34
+
35
+ | Parameter | Type | Description |
36
+ | ---------- | ---------- | ------------------------------------------ |
37
+ | `callback` | `Function` | Function to run after the quiet window |
38
+ | `delay` | `number` | Quiet window before firing, in milliseconds |
@@ -0,0 +1,69 @@
1
+ ---
2
+ title: debounceId
3
+ description: Debounce an async function with isolated state per identifier — only the last call resolves, others are cancelled.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ `debounceId` is the right tool when:
11
+
12
+ - You need to debounce **async** work and `await` the result.
13
+ - You want **per-key isolation** — debounces for `'search'` shouldn't interfere with debounces for `'autosave'`.
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { debounceId } from '@maz-ui/utils'
19
+
20
+ const searchUsers = debounceId(
21
+ 'user-search',
22
+ async (query: string) => {
23
+ const res = await fetch(`/api/users?q=${query}`)
24
+ return res.json()
25
+ },
26
+ 300,
27
+ )
28
+
29
+ const users = await searchUsers('alice')
30
+ ```
31
+
32
+ ## API
33
+
34
+ ```ts
35
+ function debounceId<T, Args extends unknown[]>(
36
+ identifier: string,
37
+ func: (...args: Args) => T | Promise<T>,
38
+ delay: number,
39
+ ): (...args: Args) => Promise<T>
40
+ ```
41
+
42
+ | Parameter | Type | Description |
43
+ | ------------ | --------------- | ------------------------------------------------------------ |
44
+ | `identifier` | `string` | Unique key — calls with the same key share a debounce timer |
45
+ | `func` | `Function` | The async (or sync) function to debounce |
46
+ | `delay` | `number` | Quiet window before the call resolves, in ms |
47
+
48
+ Returns a function that always returns a `Promise<T>`. Earlier pending promises are cancelled — only the last invocation resolves.
49
+
50
+ ## Examples
51
+
52
+ Autosave a form, keyed by document ID, so concurrent edits to different documents don't share state:
53
+
54
+ ```ts
55
+ import { debounceId } from '@maz-ui/utils'
56
+
57
+ async function saveDocument(id: string, payload: unknown) {
58
+ const save = debounceId(
59
+ `doc-${id}`,
60
+ (body: unknown) => fetch(`/docs/${id}`, { method: 'PUT', body: JSON.stringify(body) }),
61
+ 500,
62
+ )
63
+ return save(payload)
64
+ }
65
+ ```
66
+
67
+ ## Related
68
+
69
+ - [`throttleId`](./throttle-id) — same shape, but throttles instead of debounces.
@@ -0,0 +1,65 @@
1
+ ---
2
+ title: debounce
3
+ description: Wrap a function so it only runs after a quiet period — every new call resets the timer.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Useful for input handlers, resize listeners, search-as-you-type and any callback that should not fire on every event.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { debounce } from '@maz-ui/utils'
16
+
17
+ const onSearch = debounce((query: string) => {
18
+ console.log('searching for', query)
19
+ }, 300)
20
+
21
+ onSearch('h')
22
+ onSearch('he')
23
+ onSearch('hel')
24
+ // only the last call (with "hel") runs, 300 ms after the third call
25
+ ```
26
+
27
+ ## API
28
+
29
+ ```ts
30
+ function debounce<F extends (...args: any[]) => any>(
31
+ fn: F,
32
+ delay: number,
33
+ ): (...args: Parameters<F>) => void
34
+ ```
35
+
36
+ | Parameter | Type | Description |
37
+ | --------- | ---------- | --------------------------------------------- |
38
+ | `fn` | `Function` | The function to debounce |
39
+ | `delay` | `number` | Quiet window in milliseconds before `fn` runs |
40
+
41
+ The returned function shares no state with other debounced wrappers — each call to `debounce()` creates a fresh timer.
42
+
43
+ ## Examples
44
+
45
+ Debounce a Vue input handler:
46
+
47
+ ```vue
48
+ <script setup lang="ts">
49
+ import { debounce } from '@maz-ui/utils'
50
+
51
+ const onInput = debounce((event: Event) => {
52
+ console.log((event.target as HTMLInputElement).value)
53
+ }, 250)
54
+ </script>
55
+
56
+ <template>
57
+ <input @input="onInput">
58
+ </template>
59
+ ```
60
+
61
+ ## Related
62
+
63
+ - [`debounceId`](./debounce-id) — debounce an async function, keyed by an identifier, returning a promise.
64
+ - [`debounceCallback`](./debounce-callback) — module-scoped one-shot debounce.
65
+ - [`throttle`](./throttle) — rate-limits instead of waiting for silence.
@@ -0,0 +1,33 @@
1
+ ---
2
+ title: fetchLocaleIp
3
+ description: Resolve the visitor's ISO country code from their IP address using the free `ipwho.is` service.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Useful for pre-filling locale-aware UI — phone-number country selectors, currency hints, default language — before the user has interacted with the page.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { fetchLocaleIp } from '@maz-ui/utils'
16
+
17
+ const countryCode = await fetchLocaleIp()
18
+ // 'FR' | 'US' | … or undefined if the request fails
19
+ ```
20
+
21
+ ## API
22
+
23
+ ```ts
24
+ function fetchLocaleIp(): Promise<string | undefined>
25
+ ```
26
+
27
+ Returns the ISO 3166-1 alpha-2 country code (e.g. `'FR'`), or `undefined` if the request fails. Errors are caught and logged via `console.error` — the call never throws.
28
+
29
+ ## Notes
30
+
31
+ - Hits `https://ipwho.is` — a public, no-key service. Consider rate limits and privacy for production usage.
32
+ - Returns `undefined` rather than throwing so a fallback path (default locale, manual selection) can be wired without `try/catch`.
33
+ - For a static locale source, see [`getBrowserLocale`](./get-browser-locale).
@@ -0,0 +1,33 @@
1
+ ---
2
+ title: formatJson
3
+ description: Tiny wrapper around `JSON.stringify` with sensible default indentation.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { formatJson } from '@maz-ui/utils'
14
+
15
+ formatJson({ name: 'Alice', age: 30 })
16
+ // {
17
+ // "name": "Alice",
18
+ // "age": 30
19
+ // }
20
+
21
+ formatJson({ a: 1 }, 4) // → indent with 4 spaces
22
+ ```
23
+
24
+ ## API
25
+
26
+ ```ts
27
+ function formatJson(json: unknown, indent?: number): string
28
+ ```
29
+
30
+ | Parameter | Type | Default | Description |
31
+ | --------- | --------- | ------- | ---------------------------------------- |
32
+ | `json` | `unknown` | — | Any JSON-serialisable value |
33
+ | `indent` | `number` | `2` | Number of spaces per indentation level |
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: formatPhoneNumber
3
+ description: Format an arbitrary phone-number string into its international representation using `libphonenumber-js`.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ If the input can't be parsed, the original string is returned unchanged.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { formatPhoneNumber } from '@maz-ui/utils'
16
+
17
+ formatPhoneNumber('+33612345678') // → '+33 6 12 34 56 78'
18
+ formatPhoneNumber('0612345678') // → '0612345678' (unparseable without country context — returned as-is)
19
+ ```
20
+
21
+ ## API
22
+
23
+ ```ts
24
+ function formatPhoneNumber(phoneNumber: string): string
25
+ ```
26
+
27
+ | Parameter | Type | Description |
28
+ | ------------- | -------- | ---------------------------------------- |
29
+ | `phoneNumber` | `string` | The phone number to format (E.164 ideal) |
30
+
31
+ Throws a `TypeError` when `phoneNumber` is empty.
32
+
33
+ ## Notes
34
+
35
+ - For maximum portability, supply the input in E.164 (`+CCXXXXXXXXX`). Otherwise, parsing falls back to passing the input through unchanged.
36
+ - For interactive phone-number input with country selection, see the [`MazInputPhoneNumber`](/components/maz-input-phone-number) component.
37
+ - Built on [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js).
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: getBrowserLocale
3
+ description: Read the user's browser language tag (e.g. `'fr-FR'`, `'en-US'`) — returns `undefined` on the server.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { getBrowserLocale } from '@maz-ui/utils'
14
+
15
+ const locale = getBrowserLocale() // 'fr-FR' | 'en-US' | … | undefined
16
+ ```
17
+
18
+ ## API
19
+
20
+ ```ts
21
+ function getBrowserLocale(): string | undefined
22
+ ```
23
+
24
+ Returns `navigator.language` on the client. On the server (no `navigator`), returns `undefined`.
25
+
26
+ ## Notes
27
+
28
+ - For IP-based country detection instead of the browser-declared locale, see [`fetchLocaleIp`](./fetch-locale-ip).
29
+ - The returned tag follows [BCP 47](https://www.rfc-editor.org/info/bcp47).
@@ -0,0 +1,39 @@
1
+ ---
2
+ title: getErrorMessage
3
+ description: Extract a human-readable message from anything thrown — `Error`, `string`, `{ message }` objects, or arbitrary values.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Especially useful inside `catch` blocks where the caught value is typed `unknown`.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { getErrorMessage } from '@maz-ui/utils'
16
+
17
+ try {
18
+ await doSomething()
19
+ }
20
+ catch (error) {
21
+ console.error(getErrorMessage(error))
22
+ }
23
+ ```
24
+
25
+ ## API
26
+
27
+ ```ts
28
+ function getErrorMessage(error: unknown): string
29
+ ```
30
+
31
+ ## Resolution rules
32
+
33
+ The helper inspects `error` in this order:
34
+
35
+ 1. `error instanceof Error` → returns `error.message`.
36
+ 2. `typeof error === 'string'` → returns `error` as-is.
37
+ 3. `error` is a plain object with a `message` property → returns `String(error.message)`.
38
+ 4. `error` is otherwise truthy → returns `String(error)`.
39
+ 5. `error` is falsy → returns `'An unexpected error occurred'`.
@@ -0,0 +1,90 @@
1
+ ---
2
+ title: IdleTimeout
3
+ description: Detect user inactivity (mouse, keyboard, touch, scroll) and run a callback when the user becomes idle.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ `IdleTimeout` listens for a range of user-input events (`mousedown`, `keydown`, `touchstart`, `wheel`, …) on a target element. When none of them fire for `timeout` ms, the user is considered idle and your callback is invoked.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { IdleTimeout } from '@maz-ui/utils'
16
+
17
+ const watcher = new IdleTimeout(
18
+ ({ isIdle }) => {
19
+ if (isIdle) {
20
+ console.log('User went idle')
21
+ }
22
+ else {
23
+ console.log('User is back')
24
+ }
25
+ },
26
+ { timeout: 60_000 }, // 1 minute
27
+ )
28
+
29
+ // later
30
+ watcher.destroy()
31
+ ```
32
+
33
+ ## API
34
+
35
+ ```ts
36
+ class IdleTimeout {
37
+ constructor(callback: IdleTimeoutCallback, options?: IdleTimeoutOptions)
38
+
39
+ start(): void
40
+ pause(): void
41
+ resume(): void
42
+ reset(): void
43
+ destroy(): void
44
+
45
+ readonly destroyed: boolean
46
+ idle: boolean
47
+ timeout: number
48
+ }
49
+
50
+ type IdleTimeoutCallback = (payload: {
51
+ isIdle: boolean
52
+ eventType?: string
53
+ instance: IdleTimeout
54
+ }) => unknown
55
+ ```
56
+
57
+ ### Options
58
+
59
+ | Option | Type | Default | Description |
60
+ | ----------- | -------------------------- | ----------- | -------------------------------------------------------------------------------------- |
61
+ | `timeout` | `number` | `300_000` | Idle duration in milliseconds (default 5 minutes). |
62
+ | `element` | `HTMLElement \| Document` | `document.body` | Element to attach event listeners to. |
63
+ | `once` | `boolean` | `false` | When `true`, automatically calls `destroy()` after the first idle trigger. |
64
+ | `immediate` | `boolean` | `true` | Fire the callback once on construction. Useful to set `false` in SSR contexts. |
65
+
66
+ ### Methods
67
+
68
+ - **`start()`** — Attach listeners and (re)start the timer. The constructor calls this automatically on the client.
69
+ - **`pause()` / `resume()`** — Freeze and unfreeze the countdown without losing the elapsed time.
70
+ - **`reset()`** — Restart the timer from scratch.
71
+ - **`destroy()`** — Detach all listeners. The watcher cannot be reused after destroy.
72
+
73
+ ## Examples
74
+
75
+ Auto-logout after 10 minutes of inactivity:
76
+
77
+ ```ts
78
+ const idle = new IdleTimeout(
79
+ ({ isIdle }) => {
80
+ if (isIdle) {
81
+ logout()
82
+ }
83
+ },
84
+ { timeout: 10 * 60 * 1000, once: true },
85
+ )
86
+ ```
87
+
88
+ ## Related
89
+
90
+ - [`UserVisibility`](./user-visibility) — track tab focus / visibility instead of in-page activity.