maz-ui 5.0.0 → 5.1.0-beta.0

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 (186) hide show
  1. package/dist/assets/{MazDropzone.DJ8au25t.css → MazDropzone.BW2grpTi.css} +1 -1
  2. package/dist/chunks/{MazDrawer.DANxKYxJ.js → MazDrawer.CC8zomfx.js} +2 -2
  3. package/dist/chunks/{MazDropzone.POH3pmfi.js → MazDropzone.Dez5j0WP.js} +2 -2
  4. package/dist/components/MazDrawer.js +1 -1
  5. package/dist/components/MazDropzone.js +1 -1
  6. package/dist/components/MazDropzone.vue.d.ts +2 -2
  7. package/dist/components/MazInputPrice.vue.d.ts +1 -1
  8. package/dist/components/index.js +2 -2
  9. package/docs/README.md +207 -0
  10. package/docs/agents/agents-md.md +52 -0
  11. package/docs/agents/claude-rule.md +52 -0
  12. package/docs/components/maz-accordion.md +76 -0
  13. package/docs/components/maz-alert.md +241 -0
  14. package/docs/components/maz-animated-counter.md +87 -0
  15. package/docs/components/maz-animated-element.md +46 -0
  16. package/docs/components/maz-animated-text.md +53 -0
  17. package/docs/components/maz-avatar.md +193 -0
  18. package/docs/components/maz-backdrop.md +178 -0
  19. package/docs/components/maz-badge.md +167 -0
  20. package/docs/components/maz-bottom-sheet.md +257 -0
  21. package/docs/components/maz-btn-group.md +316 -0
  22. package/docs/components/maz-btn.md +423 -0
  23. package/docs/components/maz-card-spotlight.md +84 -0
  24. package/docs/components/maz-card.md +321 -0
  25. package/docs/components/maz-carousel.md +153 -0
  26. package/docs/components/maz-chart.md +206 -0
  27. package/docs/components/maz-checkbox.md +138 -0
  28. package/docs/components/maz-checklist.md +251 -0
  29. package/docs/components/maz-circular-progress-bar.md +109 -0
  30. package/docs/components/maz-code-highlight.md +155 -0
  31. package/docs/components/maz-container.md +241 -0
  32. package/docs/components/maz-date-picker.md +791 -0
  33. package/docs/components/maz-dialog-confirm.md +215 -0
  34. package/docs/components/maz-dialog.md +143 -0
  35. package/docs/components/maz-drawer.md +106 -0
  36. package/docs/components/maz-dropdown.md +419 -0
  37. package/docs/components/maz-dropzone.md +387 -0
  38. package/docs/components/maz-expand-animation.md +82 -0
  39. package/docs/components/maz-fullscreen-loader.md +58 -0
  40. package/docs/components/maz-gallery.md +79 -0
  41. package/docs/components/maz-icon.md +203 -0
  42. package/docs/components/maz-input-code.md +73 -0
  43. package/docs/components/maz-input-number.md +79 -0
  44. package/docs/components/maz-input-phone-number.md +536 -0
  45. package/docs/components/maz-input-price.md +68 -0
  46. package/docs/components/maz-input-tags.md +112 -0
  47. package/docs/components/maz-input.md +334 -0
  48. package/docs/components/maz-lazy-img.md +113 -0
  49. package/docs/components/maz-link.md +146 -0
  50. package/docs/components/maz-loading-bar.md +38 -0
  51. package/docs/components/maz-markdown-editor.md +320 -0
  52. package/docs/components/maz-pagination.md +82 -0
  53. package/docs/components/maz-popover.md +794 -0
  54. package/docs/components/maz-pull-to-refresh.md +222 -0
  55. package/docs/components/maz-radio-buttons.md +313 -0
  56. package/docs/components/maz-radio.md +119 -0
  57. package/docs/components/maz-read-more.md +209 -0
  58. package/docs/components/maz-reading-progress-bar.md +96 -0
  59. package/docs/components/maz-select-country.md +513 -0
  60. package/docs/components/maz-select.md +318 -0
  61. package/docs/components/maz-sidebar-content.md +25 -0
  62. package/docs/components/maz-sidebar-footer.md +25 -0
  63. package/docs/components/maz-sidebar-group.md +27 -0
  64. package/docs/components/maz-sidebar-header.md +25 -0
  65. package/docs/components/maz-sidebar-menu-button.md +41 -0
  66. package/docs/components/maz-sidebar-menu-item.md +25 -0
  67. package/docs/components/maz-sidebar-menu-sub.md +32 -0
  68. package/docs/components/maz-sidebar-menu.md +25 -0
  69. package/docs/components/maz-sidebar-separator.md +21 -0
  70. package/docs/components/maz-sidebar-trigger.md +25 -0
  71. package/docs/components/maz-sidebar.md +507 -0
  72. package/docs/components/maz-skeleton.md +226 -0
  73. package/docs/components/maz-slider.md +165 -0
  74. package/docs/components/maz-spinner.md +84 -0
  75. package/docs/components/maz-stepper.md +301 -0
  76. package/docs/components/maz-switch.md +86 -0
  77. package/docs/components/maz-table-cell.md +27 -0
  78. package/docs/components/maz-table-row.md +28 -0
  79. package/docs/components/maz-table-title.md +27 -0
  80. package/docs/components/maz-table-virtualizer.md +31 -0
  81. package/docs/components/maz-table.md +426 -0
  82. package/docs/components/maz-tabs-bar.md +43 -0
  83. package/docs/components/maz-tabs-content-item.md +27 -0
  84. package/docs/components/maz-tabs-content.md +27 -0
  85. package/docs/components/maz-tabs.md +308 -0
  86. package/docs/components/maz-textarea.md +255 -0
  87. package/docs/components/maz-ticker.md +427 -0
  88. package/docs/components/maz-timeline.md +304 -0
  89. package/docs/components/maz-ui-provider.md +26 -0
  90. package/docs/components/maz-window-mockup.md +182 -0
  91. package/docs/composables/use-aos.md +41 -0
  92. package/docs/composables/use-breakpoints.md +42 -0
  93. package/docs/composables/use-dialog.md +58 -0
  94. package/docs/composables/use-display-names.md +130 -0
  95. package/docs/composables/use-drag.md +185 -0
  96. package/docs/composables/use-form-validator.md +1123 -0
  97. package/docs/composables/use-idle-timeout.md +172 -0
  98. package/docs/composables/use-pull-to-refresh.md +86 -0
  99. package/docs/composables/use-reading-time.md +132 -0
  100. package/docs/composables/use-string-matching.md +41 -0
  101. package/docs/composables/use-swipe.md +171 -0
  102. package/docs/composables/use-timer.md +104 -0
  103. package/docs/composables/use-toast.md +50 -0
  104. package/docs/composables/use-user-visibility.md +127 -0
  105. package/docs/composables/use-wait.md +50 -0
  106. package/docs/composables/use-window-size.md +25 -0
  107. package/docs/directives/click-outside.md +182 -0
  108. package/docs/directives/fullscreen-img.md +83 -0
  109. package/docs/directives/lazy-img.md +182 -0
  110. package/docs/directives/tooltip.md +298 -0
  111. package/docs/directives/zoom-img.md +100 -0
  112. package/docs/ecosystem/eslint-config.md +289 -0
  113. package/docs/ecosystem/icons/icon-set.md +25 -0
  114. package/docs/ecosystem/icons/index.md +584 -0
  115. package/docs/ecosystem/mcp.md +165 -0
  116. package/docs/ecosystem/node/exec-promise.md +93 -0
  117. package/docs/ecosystem/node/index.md +53 -0
  118. package/docs/ecosystem/node/logger.md +152 -0
  119. package/docs/ecosystem/node/print-banner.md +101 -0
  120. package/docs/ecosystem/node/setup-agents.md +102 -0
  121. package/docs/ecosystem/nuxt.md +551 -0
  122. package/docs/ecosystem/stylelint-config.md +310 -0
  123. package/docs/ecosystem/themes.md +966 -0
  124. package/docs/ecosystem/translations.md +1173 -0
  125. package/docs/ecosystem/utils/camel-case.md +37 -0
  126. package/docs/ecosystem/utils/capitalize.md +37 -0
  127. package/docs/ecosystem/utils/check-availability.md +85 -0
  128. package/docs/ecosystem/utils/cookie.md +86 -0
  129. package/docs/ecosystem/utils/country-code-to-unicode-flag.md +128 -0
  130. package/docs/ecosystem/utils/currency.md +53 -0
  131. package/docs/ecosystem/utils/date.md +53 -0
  132. package/docs/ecosystem/utils/debounce-callback.md +44 -0
  133. package/docs/ecosystem/utils/debounce-id.md +75 -0
  134. package/docs/ecosystem/utils/debounce.md +71 -0
  135. package/docs/ecosystem/utils/fetch-locale-ip.md +39 -0
  136. package/docs/ecosystem/utils/format-json.md +39 -0
  137. package/docs/ecosystem/utils/format-phone-number.md +43 -0
  138. package/docs/ecosystem/utils/get-browser-locale.md +35 -0
  139. package/docs/ecosystem/utils/get-country-flag-url.md +67 -0
  140. package/docs/ecosystem/utils/get-error-message.md +45 -0
  141. package/docs/ecosystem/utils/idle-timeout.md +96 -0
  142. package/docs/ecosystem/utils/index.md +57 -0
  143. package/docs/ecosystem/utils/is-client.md +38 -0
  144. package/docs/ecosystem/utils/is-equal.md +44 -0
  145. package/docs/ecosystem/utils/is-ios.md +43 -0
  146. package/docs/ecosystem/utils/is-server.md +37 -0
  147. package/docs/ecosystem/utils/is-standalone-mode.md +49 -0
  148. package/docs/ecosystem/utils/kebab-case.md +42 -0
  149. package/docs/ecosystem/utils/normalize-string.md +83 -0
  150. package/docs/ecosystem/utils/number.md +51 -0
  151. package/docs/ecosystem/utils/pascal-case.md +41 -0
  152. package/docs/ecosystem/utils/prevent-ios-input-zoom.md +72 -0
  153. package/docs/ecosystem/utils/script-loader.md +85 -0
  154. package/docs/ecosystem/utils/sleep.md +65 -0
  155. package/docs/ecosystem/utils/snake-case.md +42 -0
  156. package/docs/ecosystem/utils/swipe-handler.md +97 -0
  157. package/docs/ecosystem/utils/textarea-autogrow.md +47 -0
  158. package/docs/ecosystem/utils/throttle-id.md +54 -0
  159. package/docs/ecosystem/utils/throttle.md +63 -0
  160. package/docs/ecosystem/utils/truthy-filter.md +37 -0
  161. package/docs/ecosystem/utils/types/deep-key-of.md +54 -0
  162. package/docs/ecosystem/utils/types/deep-partial.md +48 -0
  163. package/docs/ecosystem/utils/types/deep-required.md +45 -0
  164. package/docs/ecosystem/utils/types/flatten-object-keys.md +50 -0
  165. package/docs/ecosystem/utils/types/generic-instance-type.md +48 -0
  166. package/docs/ecosystem/utils/types/infer-maybe-ref.md +41 -0
  167. package/docs/ecosystem/utils/upper-first.md +38 -0
  168. package/docs/ecosystem/utils/user-visibility.md +75 -0
  169. package/docs/guide/ai-agents.md +237 -0
  170. package/docs/guide/browser-support.md +88 -0
  171. package/docs/guide/getting-started.md +191 -0
  172. package/docs/guide/global-defaults.md +103 -0
  173. package/docs/guide/maz-ui-provider.md +231 -0
  174. package/docs/guide/migration-v5.md +871 -0
  175. package/docs/guide/resolvers.md +650 -0
  176. package/docs/guide/tailwind.md +483 -0
  177. package/docs/guide/vue.md +286 -0
  178. package/docs/manifest.json +1 -0
  179. package/docs/plugins/aos.md +312 -0
  180. package/docs/plugins/dialog.md +269 -0
  181. package/docs/plugins/toast.md +221 -0
  182. package/docs/plugins/wait.md +78 -0
  183. package/docs/reference/icons.md +46 -0
  184. package/docs/reference/tailwind-tokens.md +191 -0
  185. package/docs/rules.md +57 -0
  186. package/package.json +31 -4
@@ -0,0 +1,63 @@
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
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/throttle"
6
+ ---
7
+
8
+ # throttle
9
+
10
+ > Wrap a function so it runs immediately, then at most once every N milliseconds - perfect for scroll, mousemove and resize handlers.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import { throttle } from '@maz-ui/utils/helpers/throttle'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/throttle
15
+
16
+ Unlike [`debounce`](./debounce.md) - which waits for a quiet period - `throttle` lets the first call through and rate-limits the rest.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import { throttle } from '@maz-ui/utils'
22
+
23
+ const onScroll = throttle(() => {
24
+ console.log('scroll position', window.scrollY)
25
+ }, 200)
26
+
27
+ window.addEventListener('scroll', onScroll)
28
+ ```
29
+
30
+ ## API
31
+
32
+ ```ts
33
+ function throttle<T extends (...args: any[]) => any>(
34
+ func: T,
35
+ limit: number,
36
+ ): (...args: Parameters<T>) => void
37
+ ```
38
+
39
+ | Parameter | Type | Description |
40
+ | --------- | ---------- | ------------------------------------------ |
41
+ | `func` | `Function` | The function to throttle |
42
+ | `limit` | `number` | Minimum interval between executions, in ms |
43
+
44
+ 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.
45
+
46
+ ## Examples
47
+
48
+ Throttle a window resize handler:
49
+
50
+ ```ts
51
+ import { throttle } from '@maz-ui/utils'
52
+
53
+ const onResize = throttle(() => {
54
+ console.log('width:', window.innerWidth)
55
+ }, 250)
56
+
57
+ window.addEventListener('resize', onResize)
58
+ ```
59
+
60
+ ## Related
61
+
62
+ - [`throttleId`](./throttle-id.md) - per-key throttle for async functions, returning a promise.
63
+ - [`debounce`](./debounce.md) - fires only once activity stops.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "truthyFilter"
3
+ description: "Type guard that filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) while narrowing the TypeScript type."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/truthy-filter"
6
+ ---
7
+
8
+ # truthyFilter
9
+
10
+ > Type guard that filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) while narrowing the TypeScript type.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import { truthyFilter } from '@maz-ui/utils/helpers/truthyFilter'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/truthy-filter
15
+
16
+ Pass it directly to `Array.prototype.filter` to drop nullish/empty entries while telling TypeScript the result no longer contains those types.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import { truthyFilter } from '@maz-ui/utils'
22
+
23
+ const items: (string | null | undefined)[] = ['a', null, 'b', undefined, '']
24
+ const cleaned = items.filter(truthyFilter)
25
+ // cleaned has type string[]
26
+ // cleaned = ['a', 'b']
27
+ ```
28
+
29
+ ## API
30
+
31
+ ```ts
32
+ type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T
33
+
34
+ function truthyFilter<T>(value: T): value is Truthy<T>
35
+ ```
36
+
37
+ 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,54 @@
1
+ ---
2
+ title: "DeepKeyOf"
3
+ description: "Recursively build a union of dot-separated key paths for any nested object type."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/deep-key-of"
6
+ ---
7
+
8
+ # DeepKeyOf
9
+
10
+ > Recursively build a union of dot-separated key paths for any nested object type.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { DeepKeyOf } from '@maz-ui/utils/ts-helpers/DeepKeyOf'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/deep-key-of
15
+
16
+ Use it to type i18n keys, nested form paths, or any string that must reference a leaf of a known object shape.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import type { DeepKeyOf } from '@maz-ui/utils'
22
+
23
+ interface Config {
24
+ app: {
25
+ name: string
26
+ theme: {
27
+ mode: 'light' | 'dark'
28
+ primary: string
29
+ }
30
+ }
31
+ version: number
32
+ }
33
+
34
+ type Keys = DeepKeyOf<Config>
35
+ // → 'app.name' | 'app.theme.mode' | 'app.theme.primary' | 'version'
36
+ ```
37
+
38
+ ## API
39
+
40
+ ```ts
41
+ type DeepKeyOf<T> = T extends object
42
+ ? { [K in keyof T]: K extends string
43
+ ? T[K] extends object
44
+ ? `${K}.${DeepKeyOf<T[K]>}`
45
+ : K
46
+ : never
47
+ }[keyof T]
48
+ : never
49
+ ```
50
+
51
+ ## Notes
52
+
53
+ - Numeric and symbol keys are excluded - only `string`-keyed properties are walked.
54
+ - 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,48 @@
1
+ ---
2
+ title: "DeepPartial"
3
+ description: "Recursive variant of TypeScript's `Partial<T>` - every property at every depth becomes optional."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/deep-partial"
6
+ ---
7
+
8
+ # DeepPartial
9
+
10
+ > Recursive variant of TypeScript's `Partial<T>` - every property at every depth becomes optional.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { DeepPartial } from '@maz-ui/utils/ts-helpers/DeepPartial'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/deep-partial
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import type { DeepPartial } from '@maz-ui/utils'
20
+
21
+ interface UserSettings {
22
+ notifications: {
23
+ email: boolean
24
+ push: boolean
25
+ }
26
+ theme: {
27
+ primary: string
28
+ secondary: string
29
+ }
30
+ }
31
+
32
+ const update: DeepPartial<UserSettings> = {
33
+ notifications: { email: false },
34
+ }
35
+ ```
36
+
37
+ ## API
38
+
39
+ ```ts
40
+ type DeepPartial<T> = T extends object
41
+ ? { [P in keyof T]?: DeepPartial<T[P]> }
42
+ : T
43
+ ```
44
+
45
+ ## Notes
46
+
47
+ - Primitives (`string`, `number`, `boolean`, `null`, `undefined`, …) are returned unchanged.
48
+ - Useful for partial-update payloads (`PATCH` requests, merge functions, default-options patterns).
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: "DeepRequired"
3
+ description: "Recursive variant of TypeScript's `Required<T>` - strips `?` from every property at every depth."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/deep-required"
6
+ ---
7
+
8
+ # DeepRequired
9
+
10
+ > Recursive variant of TypeScript's `Required<T>` - strips `?` from every property at every depth.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { DeepRequired } from '@maz-ui/utils/ts-helpers/DeepRequired'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/deep-required
15
+
16
+ The mirror image of [`DeepPartial`](./deep-partial.md). Useful when you want a fully-resolved internal type derived from a public options interface.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import type { DeepRequired } from '@maz-ui/utils'
22
+
23
+ interface Options {
24
+ cache?: {
25
+ ttl?: number
26
+ strategy?: 'memory' | 'disk'
27
+ }
28
+ }
29
+
30
+ type ResolvedOptions = DeepRequired<Options>
31
+ // {
32
+ // cache: {
33
+ // ttl: number
34
+ // strategy: 'memory' | 'disk'
35
+ // }
36
+ // }
37
+ ```
38
+
39
+ ## API
40
+
41
+ ```ts
42
+ type DeepRequired<T> = Required<{
43
+ [K in keyof T]: T[K] extends Required<T[K]> ? T[K] : DeepRequired<T[K]>
44
+ }>
45
+ ```
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: "FlattenObjectKeys"
3
+ description: "Build a union of dot-separated leaf paths for a nested object, with an optional prefix."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/flatten-object-keys"
6
+ ---
7
+
8
+ # FlattenObjectKeys
9
+
10
+ > Build a union of dot-separated leaf paths for a nested object, with an optional prefix.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { FlattenObjectKeys } from '@maz-ui/utils/ts-helpers/FlattenObjectKeys'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/flatten-object-keys
15
+
16
+ Similar to [`DeepKeyOf`](./deep-key-of.md) but only yields **leaf** paths (skips intermediate object keys), and accepts a `Prefix` parameter for namespacing.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import type { FlattenObjectKeys } from '@maz-ui/utils'
22
+
23
+ interface Config {
24
+ app: {
25
+ name: string
26
+ version: number
27
+ }
28
+ debug: boolean
29
+ }
30
+
31
+ type Leaves = FlattenObjectKeys<Config>
32
+ // → 'app.name' | 'app.version' | 'debug'
33
+
34
+ type Namespaced = FlattenObjectKeys<Config, 'config.'>
35
+ // → 'config.app.name' | 'config.app.version' | 'config.debug'
36
+ ```
37
+
38
+ ## API
39
+
40
+ ```ts
41
+ type FlattenObjectKeys<T extends Record<string, any>, Prefix extends string = ''> = {
42
+ [K in keyof T]: T[K] extends Record<string, any>
43
+ ? FlattenObjectKeys<T[K], `${Prefix}${K extends string ? K : ''}.`>
44
+ : `${Prefix}${K extends string ? K : ''}`
45
+ }[keyof T]
46
+ ```
47
+
48
+ ## Notes
49
+
50
+ - Unlike `DeepKeyOf`, intermediate object keys (e.g. `'app'` in the example) are not included - only the paths that resolve to non-object leaves.
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: "GenericInstanceType"
3
+ description: "Extract the public instance type from a generic Vue component - solves the limitation where `InstanceType<typeof Component>` returns `any` for generic SFCs."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/generic-instance-type"
6
+ ---
7
+
8
+ # GenericInstanceType
9
+
10
+ > Extract the public instance type from a generic Vue component - solves the limitation where `InstanceType<typeof Component>` returns `any` for generic SFCs.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { GenericInstanceType } from '@maz-ui/utils/ts-helpers/GenericInstanceType'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/generic-instance-type
15
+
16
+ Vue's `InstanceType<typeof Component>` does not work on **generic** components (`<script setup lang="ts" generic="T">`). `GenericInstanceType` walks the type to recover the exposed methods/refs typing.
17
+
18
+ See the underlying TypeScript / Vue Language Tools issue: [vuejs/language-tools#3206](https://github.com/vuejs/language-tools/issues/3206).
19
+
20
+ ## Usage
21
+
22
+ ```ts
23
+ import type { GenericInstanceType } from '@maz-ui/utils'
24
+ import { ref } from 'vue'
25
+ import MyGenericList from './MyGenericList.vue'
26
+
27
+ const listRef = ref<GenericInstanceType<typeof MyGenericList> | null>(null)
28
+
29
+ // listRef.value.focus() is fully typed
30
+ ```
31
+
32
+ ## API
33
+
34
+ ```ts
35
+ type GenericInstanceType<T> = T extends new (...args: any[]) => infer R
36
+ ? R
37
+ : T extends (...args: any[]) => infer R
38
+ ? R extends { __ctx?: infer K }
39
+ ? Exclude<K, void> extends { expose: (...args: infer Y) => void }
40
+ ? Y[0] & InstanceType<DefineComponent>
41
+ : any
42
+ : any
43
+ : any
44
+ ```
45
+
46
+ ## Notes
47
+
48
+ - Use this only for generic components. For non-generic SFCs, plain `InstanceType<typeof Component>` already works and is clearer.
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: "InferMaybeRef"
3
+ description: "Unwrap a Vue `Ref<U>` to its inner `U` - leaves non-ref types unchanged."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/types/infer-maybe-ref"
6
+ ---
7
+
8
+ # InferMaybeRef
9
+
10
+ > Unwrap a Vue `Ref<U>` to its inner `U` - leaves non-ref types unchanged.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import type { InferMaybeRef } from '@maz-ui/utils/ts-helpers/InferMaybeRef'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/types/infer-maybe-ref
15
+
16
+ Useful when authoring composables that accept either a plain value or a `Ref`, and you want a unified type for the inner value.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import type { InferMaybeRef } from '@maz-ui/utils'
22
+ import { ref } from 'vue'
23
+
24
+ const a = ref(42)
25
+ const b = 42
26
+
27
+ type A = InferMaybeRef<typeof a> // number
28
+ type B = InferMaybeRef<typeof b> // number
29
+ ```
30
+
31
+ ## API
32
+
33
+ ```ts
34
+ import type { Ref } from 'vue'
35
+
36
+ type InferMaybeRef<T> = T extends Ref<infer U> ? U : T
37
+ ```
38
+
39
+ ## Notes
40
+
41
+ - Pairs well with Vue's built-in [`unref()`](https://vuejs.org/api/reactivity-utilities.html#unref), which provides the same behaviour at runtime.
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: "upperFirst"
3
+ description: "Uppercase the first character of a string and leave the rest unchanged."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/upper-first"
6
+ ---
7
+
8
+ # upperFirst
9
+
10
+ > Uppercase the first character of a string and leave the rest unchanged.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import { upperFirst } from '@maz-ui/utils/helpers/upperFirst'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/upper-first
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { upperFirst } from '@maz-ui/utils'
20
+
21
+ upperFirst('hello') // → 'Hello'
22
+ upperFirst('hELLO') // → 'HELLO'
23
+ upperFirst('') // → ''
24
+ ```
25
+
26
+ ## API
27
+
28
+ ```ts
29
+ function upperFirst(value: string): string
30
+ ```
31
+
32
+ | Parameter | Type | Description |
33
+ | --------- | -------- | --------------------- |
34
+ | `value` | `string` | The string to process |
35
+
36
+ ## Notes
37
+
38
+ - Does **not** lowercase the remaining characters - use [`capitalize`](./capitalize.md) for the same behaviour when you control the input shape.
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: "UserVisibility"
3
+ description: "Track whether the user is currently looking at the tab using the Page Visibility API, with an optional grace timeout before declaring them away."
4
+ package: "@maz-ui/utils"
5
+ url: "https://maz-ui.com/ecosystem/utils/user-visibility"
6
+ ---
7
+
8
+ # UserVisibility
9
+
10
+ > Track whether the user is currently looking at the tab using the Page Visibility API, with an optional grace timeout before declaring them away.
11
+
12
+ - Package: `@maz-ui/utils`
13
+ - Import: `import { UserVisibility } from '@maz-ui/utils/helpers/userVisibility'`
14
+ - Web: https://maz-ui.com/ecosystem/utils/user-visibility
15
+
16
+ `UserVisibility` listens to `visibilitychange` events. When the tab becomes hidden, it waits `timeout` ms before invoking the callback with `isVisible: false` - this avoids spurious switches when the user briefly tabs away.
17
+
18
+ ## Usage
19
+
20
+ ```ts
21
+ import { UserVisibility } from '@maz-ui/utils'
22
+
23
+ const watcher = new UserVisibility(
24
+ ({ isVisible }) => {
25
+ if (isVisible) {
26
+ resumeVideo()
27
+ }
28
+ else {
29
+ pauseVideo()
30
+ }
31
+ },
32
+ { timeout: 3000 },
33
+ )
34
+
35
+ // later
36
+ watcher.destroy()
37
+ ```
38
+
39
+ ## API
40
+
41
+ ```ts
42
+ class UserVisibility {
43
+ constructor(callback: UserVisibilyCallback, options?: UserVisibilyOptions)
44
+
45
+ start(): void
46
+ destroy(): void
47
+ }
48
+
49
+ type UserVisibilyCallback = (payload: { isVisible: boolean }) => void
50
+ ```
51
+
52
+ ### Options
53
+
54
+ | Option | Type | Default | Description |
55
+ | ----------- | --------- | ------- | --------------------------------------------------------------------------------- |
56
+ | `timeout` | `number` | `5000` | Grace period in ms before a hidden tab fires the `isVisible: false` callback. |
57
+ | `immediate` | `boolean` | `true` | Fire the callback once on construction with the current visibility state. |
58
+ | `once` | `boolean` | `false` | Auto-destroy after the first callback invocation. |
59
+
60
+ ## Examples
61
+
62
+ Pause expensive timers when the user tabs away:
63
+
64
+ ```ts
65
+ new UserVisibility(
66
+ ({ isVisible }) => {
67
+ isVisible ? animations.resume() : animations.pause()
68
+ },
69
+ { timeout: 0 }, // react immediately
70
+ )
71
+ ```
72
+
73
+ ## Related
74
+
75
+ - [`IdleTimeout`](./idle-timeout.md) - track in-page activity instead of tab visibility.