@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.
- package/dist/mcp.d.mts +22 -9
- package/dist/mcp.d.ts +22 -9
- package/dist/mcp.mjs +160 -83
- package/docs/src/blog/v4.md +1 -1
- package/docs/src/blog/v5.md +4 -4
- package/docs/src/components/maz-btn.md +1 -1
- package/docs/src/components/maz-date-picker.md +1 -1
- package/docs/src/components/maz-icon.md +2 -2
- package/docs/src/directives/click-outside.md +1 -1
- package/docs/src/directives/fullscreen-img.md +1 -1
- package/docs/src/directives/lazy-img.md +1 -1
- package/docs/src/directives/tooltip.md +1 -1
- package/docs/src/directives/zoom-img.md +1 -1
- package/docs/src/{guide/icons.md → ecosystem/icons/index.md} +1 -1
- package/docs/src/ecosystem/node/exec-promise.md +87 -0
- package/docs/src/ecosystem/node/index.md +53 -0
- package/docs/src/ecosystem/node/logger.md +146 -0
- package/docs/src/ecosystem/node/print-banner.md +93 -0
- package/docs/src/{guide → ecosystem}/nuxt.md +1 -1
- package/docs/src/{guide → ecosystem}/themes.md +4 -4
- package/docs/src/{guide → ecosystem}/translations.md +1 -1
- package/docs/src/ecosystem/utils/camel-case.md +31 -0
- package/docs/src/ecosystem/utils/check-availability.md +79 -0
- package/docs/src/ecosystem/utils/cookie.md +80 -0
- package/docs/src/ecosystem/utils/debounce-callback.md +38 -0
- package/docs/src/ecosystem/utils/debounce-id.md +69 -0
- package/docs/src/ecosystem/utils/debounce.md +65 -0
- package/docs/src/ecosystem/utils/fetch-locale-ip.md +33 -0
- package/docs/src/ecosystem/utils/format-json.md +33 -0
- package/docs/src/ecosystem/utils/format-phone-number.md +37 -0
- package/docs/src/ecosystem/utils/get-browser-locale.md +29 -0
- package/docs/src/ecosystem/utils/get-error-message.md +39 -0
- package/docs/src/ecosystem/utils/idle-timeout.md +90 -0
- package/docs/src/ecosystem/utils/index.md +60 -0
- package/docs/src/ecosystem/utils/is-client.md +32 -0
- package/docs/src/ecosystem/utils/is-equal.md +38 -0
- package/docs/src/ecosystem/utils/is-server.md +31 -0
- package/docs/src/ecosystem/utils/is-standalone-mode.md +43 -0
- package/docs/src/ecosystem/utils/kebab-case.md +36 -0
- package/docs/src/ecosystem/utils/normalize-string.md +77 -0
- package/docs/src/ecosystem/utils/pascal-case.md +35 -0
- package/docs/src/ecosystem/utils/script-loader.md +77 -0
- package/docs/src/ecosystem/utils/sleep.md +59 -0
- package/docs/src/ecosystem/utils/snake-case.md +36 -0
- package/docs/src/ecosystem/utils/swipe-handler.md +91 -0
- package/docs/src/ecosystem/utils/textarea-autogrow.md +41 -0
- package/docs/src/ecosystem/utils/throttle-id.md +48 -0
- package/docs/src/ecosystem/utils/throttle.md +57 -0
- package/docs/src/ecosystem/utils/truthy-filter.md +31 -0
- package/docs/src/ecosystem/utils/types/deep-key-of.md +48 -0
- package/docs/src/ecosystem/utils/types/deep-partial.md +42 -0
- package/docs/src/ecosystem/utils/types/deep-required.md +39 -0
- package/docs/src/ecosystem/utils/types/flatten-object-keys.md +44 -0
- package/docs/src/ecosystem/utils/types/generic-instance-type.md +42 -0
- package/docs/src/ecosystem/utils/types/infer-maybe-ref.md +35 -0
- package/docs/src/ecosystem/utils/upper-first.md +32 -0
- package/docs/src/ecosystem/utils/user-visibility.md +69 -0
- package/docs/src/guide/getting-started.md +2 -2
- package/docs/src/guide/migration-v4.md +6 -6
- package/docs/src/guide/resolvers.md +7 -7
- package/docs/src/guide/vue.md +4 -4
- package/docs/src/index.md +12 -12
- package/docs/src/plugins/aos.md +1 -1
- package/package.json +5 -4
- package/docs/src/helpers/camel-case.md +0 -14
- package/docs/src/helpers/check-availability.md +0 -14
- package/docs/src/helpers/debounce-callback.md +0 -14
- package/docs/src/helpers/debounce-id.md +0 -14
- package/docs/src/helpers/debounce.md +0 -14
- package/docs/src/helpers/is-client.md +0 -14
- package/docs/src/helpers/is-equal.md +0 -14
- package/docs/src/helpers/is-standalone-mode.md +0 -14
- package/docs/src/helpers/kebab-case.md +0 -14
- package/docs/src/helpers/normalize-string.md +0 -14
- package/docs/src/helpers/pascal-case.md +0 -14
- package/docs/src/helpers/script-loader.md +0 -14
- package/docs/src/helpers/sleep.md +0 -14
- package/docs/src/helpers/snake-case.md +0 -14
- package/docs/src/helpers/throttle-id.md +0 -14
- package/docs/src/helpers/throttle.md +0 -14
- /package/docs/src/{guide → ecosystem/icons}/icon-set.md +0 -0
- /package/docs/src/{guide → ecosystem}/mcp.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/capitalize.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/country-code-to-unicode-flag.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/currency.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/date.md +0 -0
- /package/docs/src/{helpers → ecosystem/utils}/get-country-flag-url.md +0 -0
- /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
|
+
```
|