@maz-ui/mcp 5.0.0-beta.17 → 5.0.0-beta.19

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 (88) hide show
  1. package/dist/mcp.d.mts +22 -9
  2. package/dist/mcp.d.ts +22 -9
  3. package/dist/mcp.mjs +160 -83
  4. package/docs/src/blog/v4.md +1 -1
  5. package/docs/src/blog/v5.md +4 -4
  6. package/docs/src/components/maz-btn.md +1 -1
  7. package/docs/src/components/maz-date-picker.md +1 -1
  8. package/docs/src/components/maz-icon.md +2 -2
  9. package/docs/src/directives/click-outside.md +1 -1
  10. package/docs/src/directives/fullscreen-img.md +1 -1
  11. package/docs/src/directives/lazy-img.md +1 -1
  12. package/docs/src/directives/tooltip.md +1 -1
  13. package/docs/src/directives/zoom-img.md +1 -1
  14. package/docs/src/{guide/icons.md → ecosystem/icons/index.md} +1 -1
  15. package/docs/src/ecosystem/node/exec-promise.md +87 -0
  16. package/docs/src/ecosystem/node/index.md +53 -0
  17. package/docs/src/ecosystem/node/logger.md +146 -0
  18. package/docs/src/ecosystem/node/print-banner.md +93 -0
  19. package/docs/src/{guide → ecosystem}/nuxt.md +1 -1
  20. package/docs/src/{guide → ecosystem}/themes.md +4 -4
  21. package/docs/src/{guide → ecosystem}/translations.md +1 -1
  22. package/docs/src/ecosystem/utils/camel-case.md +31 -0
  23. package/docs/src/ecosystem/utils/check-availability.md +79 -0
  24. package/docs/src/ecosystem/utils/cookie.md +80 -0
  25. package/docs/src/ecosystem/utils/debounce-callback.md +38 -0
  26. package/docs/src/ecosystem/utils/debounce-id.md +69 -0
  27. package/docs/src/ecosystem/utils/debounce.md +65 -0
  28. package/docs/src/ecosystem/utils/fetch-locale-ip.md +33 -0
  29. package/docs/src/ecosystem/utils/format-json.md +33 -0
  30. package/docs/src/ecosystem/utils/format-phone-number.md +37 -0
  31. package/docs/src/ecosystem/utils/get-browser-locale.md +29 -0
  32. package/docs/src/ecosystem/utils/get-error-message.md +39 -0
  33. package/docs/src/ecosystem/utils/idle-timeout.md +90 -0
  34. package/docs/src/ecosystem/utils/index.md +60 -0
  35. package/docs/src/ecosystem/utils/is-client.md +32 -0
  36. package/docs/src/ecosystem/utils/is-equal.md +38 -0
  37. package/docs/src/ecosystem/utils/is-server.md +31 -0
  38. package/docs/src/ecosystem/utils/is-standalone-mode.md +43 -0
  39. package/docs/src/ecosystem/utils/kebab-case.md +36 -0
  40. package/docs/src/ecosystem/utils/normalize-string.md +77 -0
  41. package/docs/src/ecosystem/utils/pascal-case.md +35 -0
  42. package/docs/src/ecosystem/utils/script-loader.md +77 -0
  43. package/docs/src/ecosystem/utils/sleep.md +59 -0
  44. package/docs/src/ecosystem/utils/snake-case.md +36 -0
  45. package/docs/src/ecosystem/utils/swipe-handler.md +91 -0
  46. package/docs/src/ecosystem/utils/textarea-autogrow.md +41 -0
  47. package/docs/src/ecosystem/utils/throttle-id.md +48 -0
  48. package/docs/src/ecosystem/utils/throttle.md +57 -0
  49. package/docs/src/ecosystem/utils/truthy-filter.md +31 -0
  50. package/docs/src/ecosystem/utils/types/deep-key-of.md +48 -0
  51. package/docs/src/ecosystem/utils/types/deep-partial.md +42 -0
  52. package/docs/src/ecosystem/utils/types/deep-required.md +39 -0
  53. package/docs/src/ecosystem/utils/types/flatten-object-keys.md +44 -0
  54. package/docs/src/ecosystem/utils/types/generic-instance-type.md +42 -0
  55. package/docs/src/ecosystem/utils/types/infer-maybe-ref.md +35 -0
  56. package/docs/src/ecosystem/utils/upper-first.md +32 -0
  57. package/docs/src/ecosystem/utils/user-visibility.md +69 -0
  58. package/docs/src/guide/getting-started.md +2 -2
  59. package/docs/src/guide/migration-v4.md +6 -6
  60. package/docs/src/guide/resolvers.md +7 -7
  61. package/docs/src/guide/vue.md +4 -4
  62. package/docs/src/index.md +12 -12
  63. package/docs/src/plugins/aos.md +1 -1
  64. package/package.json +5 -4
  65. package/docs/src/helpers/camel-case.md +0 -14
  66. package/docs/src/helpers/check-availability.md +0 -14
  67. package/docs/src/helpers/debounce-callback.md +0 -14
  68. package/docs/src/helpers/debounce-id.md +0 -14
  69. package/docs/src/helpers/debounce.md +0 -14
  70. package/docs/src/helpers/is-client.md +0 -14
  71. package/docs/src/helpers/is-equal.md +0 -14
  72. package/docs/src/helpers/is-standalone-mode.md +0 -14
  73. package/docs/src/helpers/kebab-case.md +0 -14
  74. package/docs/src/helpers/normalize-string.md +0 -14
  75. package/docs/src/helpers/pascal-case.md +0 -14
  76. package/docs/src/helpers/script-loader.md +0 -14
  77. package/docs/src/helpers/sleep.md +0 -14
  78. package/docs/src/helpers/snake-case.md +0 -14
  79. package/docs/src/helpers/throttle-id.md +0 -14
  80. package/docs/src/helpers/throttle.md +0 -14
  81. /package/docs/src/{guide → ecosystem/icons}/icon-set.md +0 -0
  82. /package/docs/src/{guide → ecosystem}/mcp.md +0 -0
  83. /package/docs/src/{helpers → ecosystem/utils}/capitalize.md +0 -0
  84. /package/docs/src/{helpers → ecosystem/utils}/country-code-to-unicode-flag.md +0 -0
  85. /package/docs/src/{helpers → ecosystem/utils}/currency.md +0 -0
  86. /package/docs/src/{helpers → ecosystem/utils}/date.md +0 -0
  87. /package/docs/src/{helpers → ecosystem/utils}/get-country-flag-url.md +0 -0
  88. /package/docs/src/{helpers → ecosystem/utils}/number.md +0 -0
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: normalizeString
3
+ description: Powerful string normalizer — strip accents, normalize whitespace, remove special characters, change case, and apply Unicode normalization forms.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ The Swiss-army knife for turning user input into a safe, comparable, slug-ready string.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { normalizeString } from '@maz-ui/utils'
16
+
17
+ normalizeString(' Crème Brûlée ')
18
+ // → 'creme-brulee'
19
+
20
+ normalizeString('Élégant Café', { case: 'kebab-case' })
21
+ // → 'elegant-cafe'
22
+
23
+ normalizeString('My Article Title!', {
24
+ case: 'kebab-case',
25
+ removeSpecialCharacters: true,
26
+ })
27
+ // → 'my-article-title'
28
+ ```
29
+
30
+ ## API
31
+
32
+ ```ts
33
+ function normalizeString(
34
+ input: string | number | boolean,
35
+ options?: NormalizeStringOptions,
36
+ ): string
37
+ ```
38
+
39
+ ### Options
40
+
41
+ | Option | Type | Default | Description |
42
+ | -------------------------- | ------------ | ------------------ | -------------------------------------------------------------------------------------------- |
43
+ | `removeAccents` | `boolean` | `true` | Strip diacritics (`é → e`, `ç → c`, …) |
44
+ | `caseSensitive` | `boolean` | `false` | When `false`, lowercases the result unless `case` is set |
45
+ | `replaceSpaces` | `boolean` | `true` | Replace spaces with `-` |
46
+ | `removeSpecialCharacters` | `boolean` | `false` | Strip non-alphanumeric / non-dash characters (Latin alphabet only) |
47
+ | `trim` | `boolean` | `true` | Trim leading/trailing whitespace |
48
+ | `normalizeSpaces` | `boolean` | `true` | Collapse runs of whitespace into a single space |
49
+ | `removeNumbers` | `boolean` | `false` | Strip digits |
50
+ | `case` | `CaseFormat` | `undefined` | Force a target case: `kebab-case`, `camelCase`, `PascalCase`, `snake_case`, `lowercase`, `UPPERCASE` |
51
+ | `customNormalizationForms` | `string[]` | `['NFC', 'NFKD']` | Unicode [normalization forms](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) applied at the end |
52
+
53
+ ## Examples
54
+
55
+ Generate a URL-safe slug:
56
+
57
+ ```ts
58
+ const slug = normalizeString(post.title, {
59
+ case: 'kebab-case',
60
+ removeSpecialCharacters: true,
61
+ })
62
+ ```
63
+
64
+ Build a case-insensitive comparison key:
65
+
66
+ ```ts
67
+ const a = normalizeString('Éléphant')
68
+ const b = normalizeString('elephant')
69
+ a === b // true
70
+ ```
71
+
72
+ Preserve original casing but strip diacritics:
73
+
74
+ ```ts
75
+ normalizeString('Crème Brûlée', { caseSensitive: true, replaceSpaces: false })
76
+ // → 'Creme Brulee'
77
+ ```
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: pascalCase
3
+ description: Convert any common string casing — kebab, snake, space-separated, camelCase or UPPERCASE — to PascalCase.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { pascalCase } from '@maz-ui/utils'
14
+
15
+ pascalCase('my-component-name') // → 'MyComponentName'
16
+ pascalCase('hello_world') // → 'HelloWorld'
17
+ pascalCase('hello world') // → 'HelloWorld'
18
+ pascalCase('helloWorld') // → 'HelloWorld'
19
+ ```
20
+
21
+ ## API
22
+
23
+ ```ts
24
+ function pascalCase(str: string): string
25
+ ```
26
+
27
+ | Parameter | Type | Description |
28
+ | --------- | -------- | --------------------- |
29
+ | `str` | `string` | The string to convert |
30
+
31
+ ## Notes
32
+
33
+ - Detects `-`, `_` and space separators automatically.
34
+ - Handles ALL-CAPS inputs by lowercasing before re-capitalizing.
35
+ - For fine-grained control, use [`normalizeString`](./normalize-string) with `{ case: 'PascalCase' }`.
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: ScriptLoader
3
+ description: Class to inject and cache a <script> tag in document head, with an awaitable load promise — ideal for third-party SDKs.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ `ScriptLoader` handles deduplication (won't inject the same script twice), error reporting, and optional one-time loading semantics.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { ScriptLoader } from '@maz-ui/utils'
16
+
17
+ const loader = new ScriptLoader({
18
+ identifier: 'stripe-js',
19
+ src: 'https://js.stripe.com/v3/',
20
+ })
21
+
22
+ await loader.load()
23
+ // window.Stripe is now available
24
+ ```
25
+
26
+ ## API
27
+
28
+ ```ts
29
+ class ScriptLoader {
30
+ constructor(options: ScriptLoaderOptions)
31
+ load(): Promise<Event | undefined>
32
+ removeTag(tag: Element | string): void
33
+ }
34
+
35
+ interface ScriptLoaderOptions {
36
+ identifier: string
37
+ src: string
38
+ once?: boolean // default: true
39
+ async?: boolean // default: true
40
+ defer?: boolean // default: true
41
+ }
42
+ ```
43
+
44
+ | Option | Type | Default | Description |
45
+ | ------------ | --------- | ------- | ---------------------------------------------------------------------------- |
46
+ | `identifier` | `string` | — | Unique key used to deduplicate the script across calls (set as `data-identifier`) |
47
+ | `src` | `string` | — | Script URL |
48
+ | `once` | `boolean` | `true` | When `true`, skip injection if a script with the same identifier already loaded |
49
+ | `async` | `boolean` | `true` | Sets the `async` attribute on the `<script>` tag |
50
+ | `defer` | `boolean` | `true` | Sets the `defer` attribute on the `<script>` tag |
51
+
52
+ ### Methods
53
+
54
+ - **`load()`** — Inject the script (or resolve immediately if cached) and return a promise that resolves to the load `Event` once the script is ready.
55
+ - **`removeTag(tag)`** — Remove an injected `<script>` tag by element reference or identifier string.
56
+
57
+ ## Errors
58
+
59
+ `ScriptLoader` throws synchronously in two situations:
60
+
61
+ - `src` or `identifier` is missing.
62
+ - Called in a non-browser environment (no `window` available).
63
+
64
+ ## Examples
65
+
66
+ Reload a script on demand by disabling caching:
67
+
68
+ ```ts
69
+ const loader = new ScriptLoader({
70
+ identifier: 'my-widget',
71
+ src: '/widget.js',
72
+ once: false,
73
+ })
74
+
75
+ await loader.load() // first injection
76
+ await loader.load() // previous tag removed, new one injected
77
+ ```
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: sleep
3
+ description: Pause execution for a given number of milliseconds. Returns a promise that resolves after the delay.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { sleep } from '@maz-ui/utils'
14
+
15
+ await sleep(500)
16
+ console.log('Half a second later')
17
+ ```
18
+
19
+ ## API
20
+
21
+ ```ts
22
+ function sleep(duration: number): Promise<void>
23
+ ```
24
+
25
+ | Parameter | Type | Description |
26
+ | ---------- | -------- | --------------------- |
27
+ | `duration` | `number` | Delay in milliseconds |
28
+
29
+ Returns a `Promise<void>` that resolves once the delay elapses.
30
+
31
+ ## Examples
32
+
33
+ Chain delays in a sequence:
34
+
35
+ ```ts
36
+ async function rampUp() {
37
+ console.log('Starting')
38
+ await sleep(1000)
39
+ console.log('1s later')
40
+ await sleep(2000)
41
+ console.log('3s later')
42
+ }
43
+ ```
44
+
45
+ Use as a guard between retries with exponential backoff:
46
+
47
+ ```ts
48
+ async function withRetry(task: () => Promise<void>, attempts = 3) {
49
+ for (let i = 0; i < attempts; i++) {
50
+ try {
51
+ return await task()
52
+ }
53
+ catch {
54
+ await sleep(2 ** i * 100)
55
+ }
56
+ }
57
+ throw new Error('Max retries exceeded')
58
+ }
59
+ ```
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: snakeCase
3
+ description: Convert any common string casing to snake_case — handles camelCase, PascalCase, kebab-case, spaces and consecutive capitals.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { snakeCase } from '@maz-ui/utils'
14
+
15
+ snakeCase('myComponent') // → 'my_component'
16
+ snakeCase('MyComponent') // → 'my_component'
17
+ snakeCase('XMLParser') // → 'xml_parser'
18
+ snakeCase('hello-world') // → 'hello_world'
19
+ snakeCase('hello world') // → 'hello_world'
20
+ ```
21
+
22
+ ## API
23
+
24
+ ```ts
25
+ function snakeCase(str: string): string
26
+ ```
27
+
28
+ | Parameter | Type | Description |
29
+ | --------- | -------- | --------------------- |
30
+ | `str` | `string` | The string to convert |
31
+
32
+ ## Notes
33
+
34
+ - Consecutive uppercase letters are handled (e.g. `XMLParser` → `xml_parser`).
35
+ - Leading and trailing underscores are stripped.
36
+ - Multiple separators collapse into a single underscore.
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: Swipe
3
+ description: Detect directional touch swipes on an element with configurable threshold and optional mouse-wheel guards.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ `Swipe` attaches touch listeners to a DOM element and fires callbacks for left, right, up and down swipes once a configurable distance threshold is crossed.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { Swipe } from '@maz-ui/utils'
16
+
17
+ const swipe = new Swipe({
18
+ element: '#carousel',
19
+ immediate: true,
20
+ onLeft: () => carousel.next(),
21
+ onRight: () => carousel.prev(),
22
+ })
23
+
24
+ // later
25
+ swipe.stop()
26
+ ```
27
+
28
+ ## API
29
+
30
+ ```ts
31
+ class Swipe {
32
+ constructor(options: SwipeOptions)
33
+
34
+ start(element?: HTMLElement | string | null): void
35
+ stop(): void
36
+
37
+ xStart?: number
38
+ yStart?: number
39
+ xEnd?: number
40
+ yEnd?: number
41
+ xDiff?: number
42
+ yDiff?: number
43
+ }
44
+ ```
45
+
46
+ ### Options
47
+
48
+ | Option | Type | Default | Description |
49
+ | ---------------------------- | ----------------------------------- | ------- | -------------------------------------------------------------------------- |
50
+ | `element` | `HTMLElement \| string \| null` | `null` | Target element or CSS selector. |
51
+ | `threshold` | `number` | `50` | Minimum distance in px before a swipe is recognised. |
52
+ | `onLeft` / `onRight` / `onUp` / `onDown` | `(event: TouchEvent) => void` | — | Direction callbacks. |
53
+ | `onValuesChanged` | `(values: SwipeValues) => void` | — | Fires whenever start/end/diff values are updated — useful for live tracking. |
54
+ | `preventDefaultOnTouchMove` | `boolean` | `false` | Calls `event.preventDefault()` on `touchmove`. |
55
+ | `preventDefaultOnMouseWheel` | `boolean` | `false` | Calls `event.preventDefault()` on `mousewheel`. |
56
+ | `immediate` | `boolean` | `false` | Attach listeners immediately from the constructor. |
57
+ | `triggerOnEnd` | `boolean` | `false` | Fire direction callbacks on `touchend` instead of on every `touchmove`. |
58
+
59
+ ### Methods
60
+
61
+ - **`start(element?)`** — Begin listening. Optionally re-target a new element.
62
+ - **`stop()`** — Detach all listeners. Live values reset.
63
+
64
+ ## Examples
65
+
66
+ Slide-based gallery:
67
+
68
+ ```ts
69
+ new Swipe({
70
+ element: '.gallery',
71
+ immediate: true,
72
+ threshold: 80,
73
+ triggerOnEnd: true,
74
+ onLeft: () => gallery.next(),
75
+ onRight: () => gallery.previous(),
76
+ })
77
+ ```
78
+
79
+ Live progress while dragging:
80
+
81
+ ```ts
82
+ new Swipe({
83
+ element: '.draggable',
84
+ immediate: true,
85
+ onValuesChanged: ({ xDiff }) => {
86
+ if (typeof xDiff === 'number') {
87
+ drawer.style.transform = `translateX(${-xDiff}px)`
88
+ }
89
+ },
90
+ })
91
+ ```
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: TextareaAutogrow
3
+ description: Automatically resize a `<textarea>` element to fit its content as the user types or the window resizes.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ The helper disables manual resize, sets `box-sizing: border-box`, and updates `height` to match `scrollHeight` on input and (debounced) on window resize.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { TextareaAutogrow } from '@maz-ui/utils'
16
+
17
+ const textarea = document.querySelector<HTMLTextAreaElement>('textarea#bio')!
18
+ const autogrow = new TextareaAutogrow(textarea)
19
+
20
+ // later
21
+ autogrow.disconnect()
22
+ ```
23
+
24
+ ## API
25
+
26
+ ```ts
27
+ class TextareaAutogrow {
28
+ constructor(element: HTMLTextAreaElement)
29
+ disconnect(): void
30
+ }
31
+ ```
32
+
33
+ | Method | Description |
34
+ | -------------- | ----------------------------------------------------------------- |
35
+ | `disconnect()` | Detach the input and resize listeners. The textarea remains styled. |
36
+
37
+ ## Notes
38
+
39
+ - Listeners are attached on first focus — until then, the textarea is fully styled but the height isn't yet computed.
40
+ - Resize updates are debounced by 200 ms.
41
+ - For a Vue-idiomatic API, see the [`v-fullsize-textarea`](/directives/v-fullsize-textarea) directive.
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: throttleId
3
+ description: Throttle an async function with isolated state per identifier — runs immediately, then at most once per interval.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ `throttleId` is the async, keyed counterpart of [`throttle`](./throttle). The first call runs immediately and returns its promise; further calls within `interval` are coalesced and resolve to the result of the last replayed call.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { throttleId } from '@maz-ui/utils'
16
+
17
+ const trackEvent = throttleId(
18
+ 'analytics',
19
+ async (event: { name: string }) => {
20
+ return fetch('/track', { method: 'POST', body: JSON.stringify(event) })
21
+ },
22
+ 1000,
23
+ )
24
+
25
+ trackEvent({ name: 'scroll' })
26
+ trackEvent({ name: 'scroll' }) // coalesced into the first call
27
+ ```
28
+
29
+ ## API
30
+
31
+ ```ts
32
+ function throttleId<T, Args extends unknown[]>(
33
+ identifier: string,
34
+ func: (...args: Args) => T | Promise<T>,
35
+ interval: number,
36
+ ): (...args: Args) => Promise<T>
37
+ ```
38
+
39
+ | Parameter | Type | Description |
40
+ | ------------ | ---------- | ------------------------------------------------------ |
41
+ | `identifier` | `string` | Unique key isolating this throttle from others |
42
+ | `func` | `Function` | The async (or sync) function to throttle |
43
+ | `interval` | `number` | Minimum interval between executions, in milliseconds |
44
+
45
+ ## Related
46
+
47
+ - [`debounceId`](./debounce-id) — wait for silence instead of rate-limiting.
48
+ - [`throttle`](./throttle) — non-async, single-instance throttle.
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: throttle
3
+ description: Wrap a function so it runs immediately, then at most once every N milliseconds — perfect for scroll, mousemove and resize handlers.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Unlike [`debounce`](./debounce) — which waits for a quiet period — `throttle` lets the first call through and rate-limits the rest.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { throttle } from '@maz-ui/utils'
16
+
17
+ const onScroll = throttle(() => {
18
+ console.log('scroll position', window.scrollY)
19
+ }, 200)
20
+
21
+ window.addEventListener('scroll', onScroll)
22
+ ```
23
+
24
+ ## API
25
+
26
+ ```ts
27
+ function throttle<T extends (...args: any[]) => any>(
28
+ func: T,
29
+ limit: number,
30
+ ): (...args: Parameters<T>) => void
31
+ ```
32
+
33
+ | Parameter | Type | Description |
34
+ | --------- | ---------- | ------------------------------------------ |
35
+ | `func` | `Function` | The function to throttle |
36
+ | `limit` | `number` | Minimum interval between executions, in ms |
37
+
38
+ The first call always runs immediately. Subsequent calls within `limit` are coalesced — only the most recent set of arguments is replayed once the window elapses.
39
+
40
+ ## Examples
41
+
42
+ Throttle a window resize handler:
43
+
44
+ ```ts
45
+ import { throttle } from '@maz-ui/utils'
46
+
47
+ const onResize = throttle(() => {
48
+ console.log('width:', window.innerWidth)
49
+ }, 250)
50
+
51
+ window.addEventListener('resize', onResize)
52
+ ```
53
+
54
+ ## Related
55
+
56
+ - [`throttleId`](./throttle-id) — per-key throttle for async functions, returning a promise.
57
+ - [`debounce`](./debounce) — fires only once activity stops.
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: truthyFilter
3
+ description: Type guard that filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) while narrowing the TypeScript type.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Pass it directly to `Array.prototype.filter` to drop nullish/empty entries while telling TypeScript the result no longer contains those types.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { truthyFilter } from '@maz-ui/utils'
16
+
17
+ const items: (string | null | undefined)[] = ['a', null, 'b', undefined, '']
18
+ const cleaned = items.filter(truthyFilter)
19
+ // cleaned has type string[]
20
+ // cleaned = ['a', 'b']
21
+ ```
22
+
23
+ ## API
24
+
25
+ ```ts
26
+ type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T
27
+
28
+ function truthyFilter<T>(value: T): value is Truthy<T>
29
+ ```
30
+
31
+ The function returns `Boolean(value)` — its real value is in the type predicate, which narrows away the falsy variants for downstream type-checking.
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: DeepKeyOf
3
+ description: Recursively build a union of dot-separated key paths for any nested object type.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ Use it to type i18n keys, nested form paths, or any string that must reference a leaf of a known object shape.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import type { DeepKeyOf } from '@maz-ui/utils'
16
+
17
+ interface Config {
18
+ app: {
19
+ name: string
20
+ theme: {
21
+ mode: 'light' | 'dark'
22
+ primary: string
23
+ }
24
+ }
25
+ version: number
26
+ }
27
+
28
+ type Keys = DeepKeyOf<Config>
29
+ // → 'app.name' | 'app.theme.mode' | 'app.theme.primary' | 'version'
30
+ ```
31
+
32
+ ## API
33
+
34
+ ```ts
35
+ type DeepKeyOf<T> = T extends object
36
+ ? { [K in keyof T]: K extends string
37
+ ? T[K] extends object
38
+ ? `${K}.${DeepKeyOf<T[K]>}`
39
+ : K
40
+ : never
41
+ }[keyof T]
42
+ : never
43
+ ```
44
+
45
+ ## Notes
46
+
47
+ - Numeric and symbol keys are excluded — only `string`-keyed properties are walked.
48
+ - Array types are objects, so `DeepKeyOf<{ items: string[] }>` produces `'items.0' | 'items.1' | …` only if the array has tuple typing. With a regular `string[]`, the recursion terminates at `'items'`.
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: DeepPartial
3
+ description: Recursive variant of TypeScript's `Partial<T>` — every property at every depth becomes optional.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import type { DeepPartial } from '@maz-ui/utils'
14
+
15
+ interface UserSettings {
16
+ notifications: {
17
+ email: boolean
18
+ push: boolean
19
+ }
20
+ theme: {
21
+ primary: string
22
+ secondary: string
23
+ }
24
+ }
25
+
26
+ const update: DeepPartial<UserSettings> = {
27
+ notifications: { email: false },
28
+ }
29
+ ```
30
+
31
+ ## API
32
+
33
+ ```ts
34
+ type DeepPartial<T> = T extends object
35
+ ? { [P in keyof T]?: DeepPartial<T[P]> }
36
+ : T
37
+ ```
38
+
39
+ ## Notes
40
+
41
+ - Primitives (`string`, `number`, `boolean`, `null`, `undefined`, …) are returned unchanged.
42
+ - Useful for partial-update payloads (`PATCH` requests, merge functions, default-options patterns).
@@ -0,0 +1,39 @@
1
+ ---
2
+ title: DeepRequired
3
+ description: Recursive variant of TypeScript's `Required<T>` — strips `?` from every property at every depth.
4
+ ---
5
+
6
+ # {{ $frontmatter.title }}
7
+
8
+ {{ $frontmatter.description }}
9
+
10
+ The mirror image of [`DeepPartial`](./deep-partial). Useful when you want a fully-resolved internal type derived from a public options interface.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import type { DeepRequired } from '@maz-ui/utils'
16
+
17
+ interface Options {
18
+ cache?: {
19
+ ttl?: number
20
+ strategy?: 'memory' | 'disk'
21
+ }
22
+ }
23
+
24
+ type ResolvedOptions = DeepRequired<Options>
25
+ // {
26
+ // cache: {
27
+ // ttl: number
28
+ // strategy: 'memory' | 'disk'
29
+ // }
30
+ // }
31
+ ```
32
+
33
+ ## API
34
+
35
+ ```ts
36
+ type DeepRequired<T> = Required<{
37
+ [K in keyof T]: T[K] extends Required<T[K]> ? T[K] : DeepRequired<T[K]>
38
+ }>
39
+ ```