@viraui/react 0.0.25 → 0.0.27

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/catalog.json +116 -68
  2. package/dist/components/accordion/accordion-item.d.ts +58 -0
  3. package/dist/components/accordion/accordion-item.js +65 -0
  4. package/dist/components/accordion/accordion.css +1 -0
  5. package/dist/components/accordion/accordion.d.ts +26 -0
  6. package/dist/components/accordion/accordion.guide.json +30 -0
  7. package/dist/components/accordion/accordion.js +22 -0
  8. package/dist/components/accordion/accordion.module.js +17 -0
  9. package/dist/components/accordion/index.d.ts +3 -0
  10. package/dist/components/avatar/avatar.css +1 -1
  11. package/dist/components/avatar/avatar.guide.json +25 -1
  12. package/dist/components/avatar/avatar.js +1 -1
  13. package/dist/components/avatar/avatar.module.js +8 -4
  14. package/dist/components/avatar-group/avatar-group.css +2 -2
  15. package/dist/components/avatar-group/avatar-group.guide.json +27 -1
  16. package/dist/components/avatar-group/avatar-group.js +2 -2
  17. package/dist/components/avatar-group/avatar-group.module.js +12 -6
  18. package/dist/components/basic-input/basic-input.css +1 -1
  19. package/dist/components/basic-input/basic-input.js +3 -3
  20. package/dist/components/basic-input/basic-input.module.js +4 -2
  21. package/dist/components/basic-input/field-label.css +1 -1
  22. package/dist/components/basic-input/field-label.module.js +4 -2
  23. package/dist/components/bleed/bleed.css +1 -0
  24. package/dist/components/bleed/bleed.d.ts +26 -0
  25. package/dist/components/bleed/bleed.guide.json +39 -0
  26. package/dist/components/bleed/bleed.js +24 -0
  27. package/dist/components/bleed/bleed.module.js +5 -0
  28. package/dist/components/bleed/index.d.ts +2 -0
  29. package/dist/components/button/button.css +1 -1
  30. package/dist/components/button/button.guide.json +33 -3
  31. package/dist/components/button/button.js +1 -1
  32. package/dist/components/button/button.module.js +8 -4
  33. package/dist/components/checkbox/checkbox-group.js +2 -2
  34. package/dist/components/checkbox/checkbox.css +1 -1
  35. package/dist/components/checkbox/checkbox.js +1 -1
  36. package/dist/components/checkbox/checkbox.module.js +16 -8
  37. package/dist/components/chip/chip.css +1 -1
  38. package/dist/components/chip/chip.guide.json +26 -1
  39. package/dist/components/chip/chip.module.js +10 -5
  40. package/dist/components/clamp-text/clamp-text.css +1 -1
  41. package/dist/components/clamp-text/clamp-text.guide.json +15 -1
  42. package/dist/components/clamp-text/clamp-text.js +1 -1
  43. package/dist/components/clamp-text/clamp-text.module.js +4 -2
  44. package/dist/components/dialog/dialog-close.js +2 -2
  45. package/dist/components/dialog/dialog-indent-background.js +2 -2
  46. package/dist/components/dialog/dialog-indent.js +2 -2
  47. package/dist/components/dialog/dialog-sheet.js +3 -3
  48. package/dist/components/dialog/dialog-trigger.js +2 -2
  49. package/dist/components/dialog/dialog.css +1 -1
  50. package/dist/components/dialog/dialog.d.ts +5 -4
  51. package/dist/components/dialog/dialog.guide.json +15 -1
  52. package/dist/components/dialog/dialog.js +4 -3
  53. package/dist/components/dialog/dialog.module.js +24 -12
  54. package/dist/components/elevator/elevator.js +2 -2
  55. package/dist/components/fieldset/fieldset.js +1 -1
  56. package/dist/components/icon/icon.module.js +4 -2
  57. package/dist/components/icon-button/icon-button.js +2 -2
  58. package/dist/components/index.d.ts +21 -13
  59. package/dist/components/linear-progress/linear-progress.css +1 -1
  60. package/dist/components/linear-progress/linear-progress.guide.json +14 -1
  61. package/dist/components/linear-progress/linear-progress.js +1 -1
  62. package/dist/components/linear-progress/linear-progress.module.js +8 -4
  63. package/dist/components/masonry/masonry.css +1 -1
  64. package/dist/components/masonry/masonry.guide.json +42 -1
  65. package/dist/components/masonry/masonry.js +3 -3
  66. package/dist/components/masonry/masonry.module.js +6 -3
  67. package/dist/components/meter/index.d.ts +2 -0
  68. package/dist/components/meter/meter.css +1 -0
  69. package/dist/components/meter/meter.d.ts +44 -0
  70. package/dist/components/meter/meter.guide.json +39 -0
  71. package/dist/components/meter/meter.js +59 -0
  72. package/dist/components/meter/meter.module.js +11 -0
  73. package/dist/components/popover/index.d.ts +4 -0
  74. package/dist/components/popover/popover-sheet.d.ts +65 -0
  75. package/dist/components/popover/popover-sheet.js +79 -0
  76. package/dist/components/popover/popover.css +1 -0
  77. package/dist/components/popover/popover.d.ts +74 -0
  78. package/dist/components/popover/popover.guide.json +28 -0
  79. package/dist/components/popover/popover.js +23 -0
  80. package/dist/components/popover/popover.module.js +13 -0
  81. package/dist/components/progressive-blur/progressive-blur.css +1 -1
  82. package/dist/components/progressive-blur/progressive-blur.guide.json +15 -1
  83. package/dist/components/progressive-blur/progressive-blur.js +1 -1
  84. package/dist/components/progressive-blur/progressive-blur.module.js +6 -3
  85. package/dist/components/radio/radio-group.d.ts +1 -1
  86. package/dist/components/radio/radio-group.js +2 -2
  87. package/dist/components/radio/radio.css +1 -1
  88. package/dist/components/radio/radio.js +1 -1
  89. package/dist/components/radio/radio.module.js +8 -4
  90. package/dist/components/select/select-group.js +1 -1
  91. package/dist/components/select/select-option.js +3 -3
  92. package/dist/components/select/select.css +1 -1
  93. package/dist/components/select/select.guide.json +26 -1
  94. package/dist/components/select/select.js +5 -4
  95. package/dist/components/select/select.module.js +36 -18
  96. package/dist/components/separator/separator.css +1 -1
  97. package/dist/components/separator/separator.js +1 -1
  98. package/dist/components/separator/separator.module.js +4 -2
  99. package/dist/components/shimmer/shimmer.css +1 -1
  100. package/dist/components/shimmer/shimmer.guide.json +39 -1
  101. package/dist/components/shimmer/shimmer.js +4 -4
  102. package/dist/components/shimmer/shimmer.module.js +4 -2
  103. package/dist/components/skeleton/skeleton.css +1 -1
  104. package/dist/components/skeleton/skeleton.guide.json +50 -1
  105. package/dist/components/skeleton/skeleton.js +5 -5
  106. package/dist/components/skeleton/skeleton.module.js +4 -2
  107. package/dist/components/slider/slider.css +1 -1
  108. package/dist/components/slider/slider.guide.json +20 -1
  109. package/dist/components/slider/slider.js +1 -1
  110. package/dist/components/slider/slider.module.js +20 -10
  111. package/dist/components/spinner/spinner.css +1 -1
  112. package/dist/components/spinner/spinner.guide.json +15 -1
  113. package/dist/components/spinner/spinner.module.js +6 -3
  114. package/dist/components/stack/stack.css +1 -1
  115. package/dist/components/stack/stack.guide.json +77 -1
  116. package/dist/components/stack/stack.js +8 -8
  117. package/dist/components/stack/stack.module.js +4 -2
  118. package/dist/components/static-noise/static-noise.module.js +6 -3
  119. package/dist/components/surface/surface-radius-context.js +7 -7
  120. package/dist/components/surface/surface.css +1 -1
  121. package/dist/components/surface/surface.d.ts +1 -1
  122. package/dist/components/surface/surface.guide.json +85 -1
  123. package/dist/components/surface/surface.js +6 -6
  124. package/dist/components/surface/surface.module.js +4 -2
  125. package/dist/components/switch/switch.css +1 -1
  126. package/dist/components/switch/switch.guide.json +32 -1
  127. package/dist/components/switch/switch.js +1 -1
  128. package/dist/components/switch/switch.module.js +10 -5
  129. package/dist/components/tabs/tabs-indicator.js +2 -2
  130. package/dist/components/tabs/tabs-list.js +2 -2
  131. package/dist/components/tabs/tabs-panel.js +2 -2
  132. package/dist/components/tabs/tabs-tab.js +2 -2
  133. package/dist/components/tabs/tabs-viewport.js +2 -2
  134. package/dist/components/tabs/tabs.css +1 -1
  135. package/dist/components/tabs/tabs.guide.json +8 -1
  136. package/dist/components/tabs/tabs.js +2 -2
  137. package/dist/components/tabs/tabs.module.js +16 -8
  138. package/dist/components/text/text.css +1 -1
  139. package/dist/components/text/text.guide.json +125 -1
  140. package/dist/components/text/text.js +11 -11
  141. package/dist/components/text/text.module.js +4 -2
  142. package/dist/components/textarea/textarea.css +1 -1
  143. package/dist/components/textarea/textarea.guide.json +14 -1
  144. package/dist/components/textarea/textarea.js +1 -1
  145. package/dist/components/textarea/textarea.module.js +10 -5
  146. package/dist/components/textfield/textfield.css +1 -1
  147. package/dist/components/textfield/textfield.guide.json +20 -1
  148. package/dist/components/textfield/textfield.js +1 -1
  149. package/dist/components/textfield/textfield.module.js +14 -7
  150. package/dist/components/title/title.css +1 -1
  151. package/dist/components/title/title.guide.json +123 -1
  152. package/dist/components/title/title.js +11 -11
  153. package/dist/components/title/title.module.js +4 -2
  154. package/dist/components/toast/toast-action.js +2 -2
  155. package/dist/components/toast/toast-banner.js +1 -1
  156. package/dist/components/toast/toast-viewport.js +2 -2
  157. package/dist/components/toast/toast.css +1 -1
  158. package/dist/components/toast/toast.module.js +8 -4
  159. package/dist/components/toggle-button/index.d.ts +2 -0
  160. package/dist/components/toggle-button/toggle-button.d.ts +39 -0
  161. package/dist/components/toggle-button/toggle-button.guide.json +25 -0
  162. package/dist/components/toggle-button/toggle-button.js +25 -0
  163. package/dist/components/toggle-group/index.d.ts +2 -0
  164. package/dist/components/toggle-group/toggle-group.d.ts +11 -0
  165. package/dist/components/toggle-group/toggle-group.guide.json +26 -0
  166. package/dist/components/toggle-group/toggle-group.js +15 -0
  167. package/dist/components/tooltip/index.d.ts +6 -0
  168. package/dist/components/tooltip/tooltip-content.d.ts +15 -0
  169. package/dist/components/tooltip/tooltip-content.js +32 -0
  170. package/dist/components/tooltip/tooltip.css +1 -0
  171. package/dist/components/tooltip/tooltip.d.ts +13 -0
  172. package/dist/components/tooltip/tooltip.guide.json +25 -0
  173. package/dist/components/tooltip/tooltip.js +20 -0
  174. package/dist/components/tooltip/tooltip.module.js +11 -0
  175. package/dist/components/typewriter/index.d.ts +3 -0
  176. package/dist/components/typewriter/typewriter.css +1 -0
  177. package/dist/components/typewriter/typewriter.d.ts +68 -0
  178. package/dist/components/typewriter/typewriter.guide.json +39 -0
  179. package/dist/components/typewriter/typewriter.js +105 -0
  180. package/dist/components/typewriter/typewriter.module.js +18 -0
  181. package/dist/components/typewriter/typewriter.utils.d.ts +23 -0
  182. package/dist/components/typewriter/typewriter.utils.js +100 -0
  183. package/dist/index.js +26 -16
  184. package/dist/preflight-surface.json +17 -4
  185. package/dist/preflight.css +1 -1
  186. package/package.json +6 -6
@@ -1 +1 @@
1
- .viraui__toast-module__Viewport_oSF5e{position:fixed;z-index:4;pointer-events:none;outline:0;inline-size:min(24rem,calc(100vw - 2 * var(--space-medium)));&[data-position=bottom-right]{inset-block-end:var(--space-medium);inset-inline-end:var(--space-medium)}&[data-position=bottom-left]{inset-block-end:var(--space-medium);inset-inline-start:var(--space-medium)}&[data-position=bottom-center]{inset-block-end:var(--space-medium);inset-inline:0;margin-inline:auto}&[data-position=top-right]{inset-block-start:var(--space-medium);inset-inline-end:var(--space-medium)}&[data-position=top-left]{inset-block-start:var(--space-medium);inset-inline-start:var(--space-medium)}&[data-position=top-center]{inset-block-start:var(--space-medium);inset-inline:0;margin-inline:auto}&[data-position=anchored]{inset:0;inline-size:auto}&>*{pointer-events:auto}}.viraui__toast-module__Banner_QkOlo{--gap:var(--space-small);--peek:var(--space-small);--scale:calc(max(0, 1 - (var(--toast-index, 0) * 0.1)));--shrink:calc(1 - var(--scale));--stack-height:var(--toast-frontmost-height,var(--toast-height,0px));--offset-y:calc(var(--toast-offset-y, 0px) * -1 + (var(--toast-index, 0) * var(--gap) * -1) + var(--toast-swipe-movement-y, 0px));position:absolute;inset-inline-end:0;inset-block-end:0;z-index:calc(1000 - var(--toast-index, 0));inline-size:100%;min-inline-size:16rem;will-change:translate,scale,opacity;block-size:var(--toast-frontmost-height,var(--toast-height,auto));transform-origin:bottom center;translate:var(--toast-swipe-movement-x,0) calc(var(--toast-swipe-movement-y, 0px) - (var(--toast-index, 0) * var(--peek)) - (var(--shrink) * var(--stack-height)));scale:var(--scale);transition:translate var(--duration-slow) var(--easing-elastic),scale var(--duration-slow) var(--easing-elastic),opacity var(--duration-slow) var(--easing-elastic);-webkit-user-select:none;user-select:none;&[data-expanded]{translate:var(--toast-swipe-movement-x,0) var(--offset-y);scale:1;block-size:var(--toast-height,auto)}&[data-starting-style]{translate:0 150%;scale:1}&[data-ending-style]{opacity:0;translate:0 150%;scale:1;&[data-swipe-direction=up]{translate:0 calc(var(--toast-swipe-movement-y, 0px) - 150%)}&[data-swipe-direction=down]{translate:0 calc(var(--toast-swipe-movement-y, 0px) + 150%)}&[data-swipe-direction=left]{translate:calc(var(--toast-swipe-movement-x, 0px) - 150%) var(--offset-y)}&[data-swipe-direction=right]{translate:calc(var(--toast-swipe-movement-x, 0px) + 150%) var(--offset-y)}}&[data-limited]{opacity:0}&:after{content:"";position:absolute;inset-block-start:100%;inset-inline-start:0;inline-size:100%;block-size:calc(var(--gap) + 1px)}@media (prefers-reduced-motion:reduce){transition:none}}:is(.viraui__toast-module__Viewport_oSF5e[data-position=bottom-left],.viraui__toast-module__Viewport_oSF5e[data-position=top-left]) .viraui__toast-module__Banner_QkOlo{inset-inline-end:auto;inset-inline-start:0}:is(.viraui__toast-module__Viewport_oSF5e[data-position=bottom-center],.viraui__toast-module__Viewport_oSF5e[data-position=top-center]) .viraui__toast-module__Banner_QkOlo{inset-inline:0;margin-inline:auto}.viraui__toast-module__Viewport_oSF5e[data-position^=top-] .viraui__toast-module__Banner_QkOlo{inset-block-end:auto;inset-block-start:0;transform-origin:top center;--offset-y:calc(var(--toast-offset-y, 0px) + (var(--toast-index, 0) * var(--gap)) + var(--toast-swipe-movement-y, 0px));translate:var(--toast-swipe-movement-x,0) calc(var(--toast-swipe-movement-y, 0px) + (var(--toast-index, 0) * var(--peek)) + (var(--shrink) * var(--stack-height)));scale:var(--scale);&:after{inset-block-start:auto;inset-block-end:100%}&[data-expanded]{translate:var(--toast-swipe-movement-x,0) var(--offset-y);scale:1}&[data-ending-style]:not([data-swipe-direction]),&[data-starting-style]{translate:0 -150%;scale:1}}.viraui__toast-module__Viewport_oSF5e[data-position=anchored] .viraui__toast-module__Banner_QkOlo{position:static;z-index:auto;min-inline-size:auto;block-size:auto;translate:0;scale:1;&:after{content:none}transition:translate var(--duration-slow) var(--easing-elastic),scale var(--duration-slow) var(--easing-elastic),opacity var(--duration-slow) var(--easing-elastic);&[data-ending-style],&[data-starting-style]{opacity:0;translate:0 var(--space-2x-small);scale:1}&[data-expanded]{translate:0;scale:1}}.viraui__toast-module__Content_5ODZr{overflow:hidden;transition:opacity .25s ease;&[data-behind]{opacity:0}&[data-expanded]{opacity:1}@media (prefers-reduced-motion:reduce){transition:none}}
1
+ .viraui__toast-module__Viewport_oSF5e{position:fixed;z-index:4;pointer-events:none;outline:0;inline-size:min(24rem,calc(100vw - 2 * var(--space-medium)));&[data-position=bottom-right]{inset-block-end:var(--space-medium);inset-inline-end:var(--space-medium)}&[data-position=bottom-left]{inset-block-end:var(--space-medium);inset-inline-start:var(--space-medium)}&[data-position=bottom-center]{inset-block-end:var(--space-medium);inset-inline:0;margin-inline:auto}&[data-position=top-right]{inset-block-start:var(--space-medium);inset-inline-end:var(--space-medium)}&[data-position=top-left]{inset-block-start:var(--space-medium);inset-inline-start:var(--space-medium)}&[data-position=top-center]{inset-block-start:var(--space-medium);inset-inline:0;margin-inline:auto}&[data-position=anchored]{inset:0;inline-size:auto}&>*{pointer-events:auto}}.viraui__toast-module__Banner_QkOlo{--gap:var(--space-small);--peek:var(--space-small);--scale:calc(max(0, 1 - (var(--toast-index, 0) * 0.1)));--shrink:calc(1 - var(--scale));--stack-height:var(--toast-frontmost-height,var(--toast-height,0px));--offset-y:calc(var(--toast-offset-y, 0px) * -1 + (var(--toast-index, 0) * var(--gap) * -1) + var(--toast-swipe-movement-y, 0px));position:absolute;inset-inline-end:0;inset-block-end:0;z-index:calc(1000 - var(--toast-index, 0));inline-size:100%;min-inline-size:16rem;will-change:transform,opacity;block-size:var(--toast-frontmost-height,var(--toast-height,auto));transform-origin:bottom center;transform:scale(var(--scale)) translateX(var(--toast-swipe-movement-x,0)) translateY(calc(var(--toast-swipe-movement-y, 0px) - (var(--toast-index, 0) * var(--peek)) - (var(--shrink) * var(--stack-height))));transition:transform var(--duration-slow) var(--easing-elastic),opacity var(--duration-slow) var(--easing-elastic);-webkit-user-select:none;user-select:none;&[data-swiping]{transition:none}&[data-expanded]{transform:scale(1) translateX(var(--toast-swipe-movement-x,0)) translateY(var(--offset-y));block-size:var(--toast-height,auto)}&[data-starting-style]{transform:scale(1) translateY(150%)}&[data-ending-style]{opacity:0;transform:scale(1) translateY(150%);&[data-swipe-direction=up]{transform:scale(1) translateY(calc(var(--toast-swipe-movement-y, 0px) - 150%))}&[data-swipe-direction=down]{transform:scale(1) translateY(calc(var(--toast-swipe-movement-y, 0px) + 150%))}&[data-swipe-direction=left]{transform:scale(1) translateX(calc(var(--toast-swipe-movement-x, 0px) - 150%)) translateY(var(--offset-y))}&[data-swipe-direction=right]{transform:scale(1) translateX(calc(var(--toast-swipe-movement-x, 0px) + 150%)) translateY(var(--offset-y))}}&[data-limited]{opacity:0}&:after{content:"";position:absolute;inset-block-start:100%;inset-inline-start:0;inline-size:100%;block-size:calc(var(--gap) + 1px)}@media (prefers-reduced-motion:reduce){transition:none}}:is(.viraui__toast-module__Viewport_oSF5e[data-position=bottom-left],.viraui__toast-module__Viewport_oSF5e[data-position=top-left]) .viraui__toast-module__Banner_QkOlo{inset-inline-end:auto;inset-inline-start:0}:is(.viraui__toast-module__Viewport_oSF5e[data-position=bottom-center],.viraui__toast-module__Viewport_oSF5e[data-position=top-center]) .viraui__toast-module__Banner_QkOlo{inset-inline:0;margin-inline:auto}.viraui__toast-module__Viewport_oSF5e[data-position^=top-] .viraui__toast-module__Banner_QkOlo{inset-block-end:auto;inset-block-start:0;transform-origin:top center;--offset-y:calc(var(--toast-offset-y, 0px) + (var(--toast-index, 0) * var(--gap)) + var(--toast-swipe-movement-y, 0px));transform:scale(var(--scale)) translateX(var(--toast-swipe-movement-x,0)) translateY(calc(var(--toast-swipe-movement-y, 0px) + (var(--toast-index, 0) * var(--peek)) + (var(--shrink) * var(--stack-height))));&:after{inset-block-start:auto;inset-block-end:100%}&[data-expanded]{transform:scale(1) translateX(var(--toast-swipe-movement-x,0)) translateY(var(--offset-y))}&[data-ending-style]:not([data-swipe-direction]),&[data-starting-style]{transform:scale(1) translateY(-150%)}}.viraui__toast-module__Viewport_oSF5e[data-position=anchored] .viraui__toast-module__Banner_QkOlo{position:static;z-index:auto;min-inline-size:auto;block-size:auto;transform:none;&:after{content:none}transition:transform var(--duration-slow) var(--easing-elastic),opacity var(--duration-slow) var(--easing-elastic);&[data-ending-style],&[data-starting-style]{opacity:0;transform:scale(1) translateY(var(--space-2x-small))}&[data-expanded]{transform:none}}.viraui__toast-module__Content_5ODZr{overflow:hidden;transition:opacity .25s ease;&[data-behind]{opacity:0}&[data-expanded]{opacity:1}@media (prefers-reduced-motion:reduce){transition:none}}
@@ -1,7 +1,11 @@
1
+ //#region src/components/toast/toast.module.css
2
+ var Viewport = "viraui__toast-module__Viewport_oSF5e";
3
+ var Banner = "viraui__toast-module__Banner_QkOlo";
4
+ var Content = "viraui__toast-module__Content_5ODZr";
1
5
  var toast_module_default = {
2
- Viewport: "viraui__toast-module__Viewport_oSF5e",
3
- Banner: "viraui__toast-module__Banner_QkOlo",
4
- Content: "viraui__toast-module__Content_5ODZr"
6
+ Viewport,
7
+ Banner,
8
+ Content
5
9
  };
6
10
  //#endregion
7
- export { toast_module_default as default };
11
+ export { Banner, Content, Viewport, toast_module_default as default };
@@ -0,0 +1,2 @@
1
+ export { ToggleButton } from './toggle-button';
2
+ export type { ToggleButtonProps } from './toggle-button';
@@ -0,0 +1,39 @@
1
+ import { Toggle as TogglePrimitive } from '@base-ui/react/toggle';
2
+ import { ButtonProps } from '../button/button';
3
+ import { IconButtonProps } from '../icon-button/icon-button';
4
+ import { ReactNode } from 'react';
5
+ /**
6
+ * Public ToggleButton props.
7
+ *
8
+ * Icon-only two-state control built on Base UI `Toggle` and `IconButton`.
9
+ * Requires an accessible name via `aria-label` or `aria-labelledby`.
10
+ *
11
+ * @default Base UI toggle pass-through props keep upstream defaults.
12
+ */
13
+ export type ToggleButtonProps = Omit<IconButtonProps, 'icon' | 'render' | 'variant'> & TogglePrimitive.Props & {
14
+ /**
15
+ * Icon shown while the toggle is not pressed.
16
+ *
17
+ * @default No default; required for every ToggleButton.
18
+ */
19
+ restingIcon: ReactNode;
20
+ /**
21
+ * Icon shown while the toggle is pressed.
22
+ *
23
+ * @default When omitted, `restingIcon` is shown in both states.
24
+ */
25
+ pressedIcon?: ReactNode;
26
+ /**
27
+ * Visual variant while the toggle is not pressed.
28
+ *
29
+ * @default 'flat'
30
+ */
31
+ variant?: ButtonProps['variant'];
32
+ /**
33
+ * Visual variant while the toggle is pressed.
34
+ *
35
+ * @default When omitted, `variant` is used in both states.
36
+ */
37
+ pressedVariant?: ButtonProps['variant'];
38
+ };
39
+ export declare const ToggleButton: React.FC<ToggleButtonProps>;
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "ToggleButton",
3
+ "summary": "Icon-only two-state toggle that swaps resting and optional pressed icons on Base UI Toggle state.",
4
+ "whenToUse": [
5
+ "Toolbar pin, favorite, or mute toggles identified only by icon",
6
+ "Compact on/off controls that share IconButton size, variant, and loading model",
7
+ "Two-state actions where pressed state should swap the visible glyph"
8
+ ],
9
+ "whenNotToUse": [
10
+ "Settings-style on/off fields — use Switch",
11
+ "One-shot actions with no pressed state — use IconButton"
12
+ ],
13
+ "accessibility": [
14
+ "Provide aria-label or aria-labelledby on every ToggleButton — icon alone is not a name",
15
+ "Base UI Toggle exposes aria-pressed on the rendered button",
16
+ "Keep the accessible name stable when loading state changes"
17
+ ],
18
+ "antiPatterns": [
19
+ "Using IconButton for persistent pressed toolbar state",
20
+ "Using Switch for compact icon-only toolbar toggles",
21
+ "Passing icon or render — ToggleButton owns icon swap and Toggle render wiring"
22
+ ],
23
+ "related": ["IconButton", "Button", "Switch", "ToggleGroup"],
24
+ "properties": {}
25
+ }
@@ -0,0 +1,25 @@
1
+ import { IconButton } from "../icon-button/icon-button.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Toggle } from "@base-ui/react/toggle";
4
+ //#region src/components/toggle-button/toggle-button.tsx
5
+ var ToggleButton = ({ restingIcon, pressedIcon, variant = "flat", pressedVariant, pressed, defaultPressed, onPressedChange, value, disabled, ref, ...otherProps }) => /* @__PURE__ */ jsx(Toggle, {
6
+ ref,
7
+ value,
8
+ pressed,
9
+ defaultPressed,
10
+ onPressedChange,
11
+ disabled,
12
+ nativeButton: true,
13
+ render: (toggleProps, state) => {
14
+ const { "aria-label": _toggleAriaLabel, "aria-labelledby": _toggleAriaLabelledBy, ...restToggleProps } = toggleProps;
15
+ return /* @__PURE__ */ jsx(IconButton, {
16
+ ...otherProps,
17
+ ...restToggleProps,
18
+ disabled,
19
+ variant: state.pressed ? pressedVariant ?? variant : variant,
20
+ icon: state.pressed ? pressedIcon ?? restingIcon : restingIcon
21
+ });
22
+ }
23
+ });
24
+ //#endregion
25
+ export { ToggleButton };
@@ -0,0 +1,2 @@
1
+ export { ToggleGroup } from './toggle-group';
2
+ export type { ToggleGroupProps } from './toggle-group';
@@ -0,0 +1,11 @@
1
+ import { ToggleGroup as ToggleGroupPrimitive } from '@base-ui/react/toggle-group';
2
+ /**
3
+ * Public ToggleGroup props.
4
+ *
5
+ * Thin wrapper around Base UI `ToggleGroup` with default toolbar spacing.
6
+ * Compose `ToggleButton` children each with `value` and an accessible name.
7
+ *
8
+ * @default Base UI pass-through props keep upstream defaults.
9
+ */
10
+ export type ToggleGroupProps = ToggleGroupPrimitive.Props;
11
+ export declare const ToggleGroup: React.FC<ToggleGroupProps>;
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "ToggleGroup",
3
+ "summary": "Toolbar toggle set with shared selection state and default Stack spacing on Base UI ToggleGroup.",
4
+ "whenToUse": [
5
+ "Segmented icon toolbars such as text alignment or formatting controls",
6
+ "Single- or multi-select pressed states across related ToggleButton items",
7
+ "Compact action clusters that need coordinated value and disabled state"
8
+ ],
9
+ "whenNotToUse": [
10
+ "Standalone one-off toggles — use ToggleButton",
11
+ "Settings-style on/off fields — use Switch",
12
+ "Tabbed panel navigation — use Tabs"
13
+ ],
14
+ "accessibility": [
15
+ "Provide aria-label or aria-labelledby on the ToggleGroup root",
16
+ "Provide aria-label or aria-labelledby on every ToggleButton child",
17
+ "Each ToggleButton exposes aria-pressed; group selection follows Base UI ToggleGroup semantics"
18
+ ],
19
+ "antiPatterns": [
20
+ "Omitting value on ToggleButton children inside a group",
21
+ "Using Switch for icon-only toolbar toggle sets",
22
+ "Embedding Surface chrome in the component — wrap demos or app chrome at the consumer"
23
+ ],
24
+ "related": ["ToggleButton", "IconButton", "Tabs"],
25
+ "properties": {}
26
+ }
@@ -0,0 +1,15 @@
1
+ import { Stack } from "../stack/stack.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { ToggleGroup } from "@base-ui/react/toggle-group";
4
+ //#region src/components/toggle-group/toggle-group.tsx
5
+ var ToggleGroup$1 = ({ children, orientation = "horizontal", ...otherProps }) => /* @__PURE__ */ jsx(ToggleGroup, {
6
+ ...otherProps,
7
+ orientation,
8
+ render: /* @__PURE__ */ jsx(Stack, {
9
+ direction: orientation === "vertical" ? "column" : "row",
10
+ fillChildren: false
11
+ }),
12
+ children
13
+ });
14
+ //#endregion
15
+ export { ToggleGroup$1 as ToggleGroup };
@@ -0,0 +1,6 @@
1
+ import { TooltipRoot, TooltipProvider as TooltipProviderNamespace, TooltipTrigger as TooltipTriggerNamespace } from '@base-ui/react/tooltip';
2
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip';
3
+ export type TooltipProps = TooltipRoot.Props;
4
+ export type TooltipProviderProps = TooltipProviderNamespace.Props;
5
+ export type TooltipTriggerProps = TooltipTriggerNamespace.Props;
6
+ export type { TooltipContentProps } from './tooltip-content';
@@ -0,0 +1,15 @@
1
+ import { TooltipPositioner } from '@base-ui/react/tooltip';
2
+ import type * as React from 'react';
3
+ type TooltipContentPositionerProps = Omit<TooltipPositioner.Props, 'className' | 'style' | 'render'>;
4
+ /**
5
+ * Public Tooltip.Content props.
6
+ *
7
+ * Encapsulates Portal + Positioner + Popup + Viewport. Positioning props forward
8
+ * to the Positioner; `sideOffset` defaults to `8`. Always renders the internal
9
+ * Viewport so multi-trigger content animations work by default.
10
+ *
11
+ * @default `sideOffset` is `8`.
12
+ */
13
+ export type TooltipContentProps = TooltipContentPositionerProps;
14
+ export declare const TooltipContent: React.FC<TooltipContentProps>;
15
+ export {};
@@ -0,0 +1,32 @@
1
+ import { Stack } from "../stack/stack.js";
2
+ import { Surface } from "../surface/surface.js";
3
+ import tooltip_module_default from "./tooltip.module.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Tooltip } from "@base-ui/react/tooltip";
6
+ //#region src/components/tooltip/tooltip-content.tsx
7
+ var TooltipContent = ({ children, sideOffset = 8, ...positionerProps }) => /* @__PURE__ */ jsx(Tooltip.Portal, { children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
8
+ className: tooltip_module_default.Positioner,
9
+ sideOffset,
10
+ ...positionerProps,
11
+ children: /* @__PURE__ */ jsx(Tooltip.Popup, {
12
+ className: tooltip_module_default.Popup,
13
+ role: "tooltip",
14
+ render: /* @__PURE__ */ jsx(Surface, {
15
+ color: 1,
16
+ border: "all",
17
+ radius: "medium",
18
+ vibrant: true
19
+ }),
20
+ children: /* @__PURE__ */ jsx(Tooltip.Viewport, {
21
+ className: tooltip_module_default.Viewport,
22
+ render: /* @__PURE__ */ jsx(Stack, {
23
+ vPadding: "small",
24
+ hPadding: "small",
25
+ fillChildren: false
26
+ }),
27
+ children
28
+ })
29
+ })
30
+ }) });
31
+ //#endregion
32
+ export { TooltipContent };
@@ -0,0 +1 @@
1
+ .viraui__tooltip-module__Positioner_ujuzd{--vui-tooltip-content-fade-duration:var(--duration-fast);width:var(--positioner-width);height:var(--positioner-height);max-width:var(--available-width);transition:top var(--duration-fast) var(--easing-standard),right var(--duration-fast) var(--easing-standard),bottom var(--duration-fast) var(--easing-standard),left var(--duration-fast) var(--easing-standard),transform var(--duration-fast) var(--easing-standard);&[data-instant=delay],&[data-instant=dismiss]{transition:none}@media (prefers-reduced-motion:reduce){transition:none}}.viraui__tooltip-module__Popup_5XA3-{position:relative;box-sizing:border-box;width:var(--popup-width,auto);height:var(--popup-height,auto);transform-origin:var(--transform-origin);transition:width var(--duration-fast) var(--easing-standard),height var(--duration-fast) var(--easing-standard),opacity var(--duration-fast) var(--easing-entrance),transform var(--duration-fast) var(--easing-entrance);&[data-ending-style],&[data-starting-style]{opacity:0;transform:scale(.96)}&[data-instant=delay],&[data-instant=dismiss]{transition:none}@media (prefers-reduced-motion:reduce){transition:none;&[data-ending-style],&[data-starting-style]{opacity:1;transform:none}}}.viraui__tooltip-module__Viewport_HdnYN{position:relative;display:grid;grid-template-columns:minmax(0,1fr);overflow:clip;width:100%;height:100%;&>[data-current],&>[data-previous]{grid-area:1/1;inline-size:calc(var(--popup-width) - 2px - var(--vui-stack-padding-inline-start) - var(--vui-stack-padding-inline-end))}&>[data-previous]{position:absolute;block-size:calc(var(--popup-height) - 2px - var(--vui-stack-padding-block-start) - var(--vui-stack-padding-block-end));overflow:clip;pointer-events:none;opacity:1;transition:opacity var(--vui-tooltip-content-fade-duration) var(--easing-standard)}&>[data-previous][data-ending-style]{opacity:0}&>[data-current]{opacity:1;transition:opacity var(--vui-tooltip-content-fade-duration) var(--easing-entrance)}&>[data-current][data-starting-style]{opacity:0}&[data-instant=delay]>[data-current],&[data-instant=delay]>[data-previous],&[data-instant=dismiss]>[data-current],&[data-instant=dismiss]>[data-previous]{transition:none}@media (prefers-reduced-motion:reduce){&>[data-current],&>[data-previous]{transition:none}&>[data-current][data-starting-style],&>[data-previous][data-ending-style]{opacity:1}}}
@@ -0,0 +1,13 @@
1
+ import { TooltipProvider as PrimitiveTooltipProvider, TooltipRoot, Tooltip as PrimitiveTooltip } from '@base-ui/react/tooltip';
2
+ import { TooltipContent, TooltipContentProps } from './tooltip-content';
3
+ import type * as React from 'react';
4
+ export declare const TooltipProvider: React.FC<import('@base-ui/react').TooltipProviderProps>;
5
+ export declare const TooltipTrigger: PrimitiveTooltip.Trigger;
6
+ type TooltipComponent = React.FC<TooltipRoot.Props> & {
7
+ Provider: React.FC<PrimitiveTooltipProvider.Props>;
8
+ Trigger: typeof PrimitiveTooltip.Trigger;
9
+ Content: React.FC<TooltipContentProps>;
10
+ createHandle: typeof PrimitiveTooltip.createHandle;
11
+ };
12
+ export declare const Tooltip: TooltipComponent;
13
+ export { TooltipContent };
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "Tooltip",
3
+ "summary": "Compound tooltip built on Base UI Tooltip with `Tooltip.Provider`, `Tooltip.Trigger`, `Tooltip.Content`, and `Tooltip.createHandle` for detached and multiple triggers; `Content` encapsulates Portal + Positioner + Popup + Viewport and animates position, size, and content between triggers.",
4
+ "whenToUse": [
5
+ "Short hints on hover or focus for toolbar controls and icon buttons",
6
+ "Per-trigger labels on shared tooltip roots using `payload` and Root render-function children",
7
+ "Adjacent controls that benefit from shared open/close delay via `Tooltip.Provider`"
8
+ ],
9
+ "whenNotToUse": [
10
+ "Rich interactive panels or forms (use Popover or Dialog)",
11
+ "System-wide transient alerts (use Toast)",
12
+ "Content that must stay open while the pointer moves into the popup (enable `disableHoverablePopup` only when needed)"
13
+ ],
14
+ "accessibility": [
15
+ "Match trigger `aria-label` to tooltip copy so sighted and assistive users get the same hint",
16
+ "Keep tooltip copy concise; use Popover when the hint needs paragraphs, links, or controls",
17
+ "Wrap regions with multiple tooltips in `Tooltip.Provider` for predictable delay grouping"
18
+ ],
19
+ "antiPatterns": [
20
+ "Putting essential-only information in a tooltip with no accessible name on the trigger",
21
+ "Expecting `Tooltip.Arrow` (it is intentionally not exported or rendered)",
22
+ "Using tooltip for modal or focus-trapped tasks"
23
+ ],
24
+ "related": ["Surface", "Button", "IconButton", "Stack", "Popover", "Icon"]
25
+ }
@@ -0,0 +1,20 @@
1
+ import './tooltip.css';
2
+ import { TooltipContent } from "./tooltip-content.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { Tooltip } from "@base-ui/react/tooltip";
5
+ //#region src/components/tooltip/tooltip.tsx
6
+ var TooltipProvider = Tooltip.Provider;
7
+ var TooltipTrigger = Tooltip.Trigger;
8
+ var TooltipRootComponent = ({ children, ...otherProps }) => /* @__PURE__ */ jsx(Tooltip.Root, {
9
+ ...otherProps,
10
+ children
11
+ });
12
+ var { Arrow: _TooltipArrow, Portal: _TooltipPortal, Positioner: _TooltipPositioner, Popup: _TooltipPopup, Viewport: _TooltipViewport } = Tooltip;
13
+ var Tooltip$1 = Object.assign(TooltipRootComponent, {
14
+ Provider: Tooltip.Provider,
15
+ Trigger: Tooltip.Trigger,
16
+ Content: TooltipContent,
17
+ createHandle: Tooltip.createHandle
18
+ });
19
+ //#endregion
20
+ export { Tooltip$1 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
@@ -0,0 +1,11 @@
1
+ //#region src/components/tooltip/tooltip.module.css
2
+ var Positioner = "viraui__tooltip-module__Positioner_ujuzd";
3
+ var Popup = "viraui__tooltip-module__Popup_5XA3-";
4
+ var Viewport = "viraui__tooltip-module__Viewport_HdnYN";
5
+ var tooltip_module_default = {
6
+ Positioner,
7
+ Popup,
8
+ Viewport
9
+ };
10
+ //#endregion
11
+ export { Popup, Positioner, Viewport, tooltip_module_default as default };
@@ -0,0 +1,3 @@
1
+ export { Typewriter } from './typewriter';
2
+ export type { TypewriterProps } from './typewriter';
3
+ export type { TypewriterCaret } from './typewriter.utils';
@@ -0,0 +1 @@
1
+ .viraui__typewriter-module__Typewriter_R3sbb{display:inline;position:relative;isolation:isolate}.viraui__typewriter-module__Display_-IGJh{display:inline;white-space:pre-wrap}.viraui__typewriter-module__Display_-IGJh[data-preserve-space]{display:inline-grid}.viraui__typewriter-module__Display_-IGJh[data-preserve-space]>:is(.viraui__typewriter-module__Ghost_R-Yy-,.viraui__typewriter-module__Typed_00NZ8){grid-area:1/1}.viraui__typewriter-module__Caret_96Yfs{display:inline-block;vertical-align:initial;color:var(--vui-typewriter-caret-color,currentcolor);animation:viraui__typewriter-module__typewriter-caret-blink_yLCpV 1.1s step-start infinite;@media (prefers-reduced-motion:reduce){animation:none}&[data-type=block]{inline-size:.55em;block-size:.95em;margin-inline-start:.04em;background-color:var(--vui-typewriter-caret-color,currentcolor);transform:translateY(.08em)}&[data-type=pipe]:before{content:"|"}&[data-type=underscore]:before{content:"_"}}.viraui__typewriter-module__Ghost_R-Yy-{visibility:hidden;-webkit-user-select:none;user-select:none}.viraui__typewriter-module__Typed_00NZ8{display:inline}.viraui__typewriter-module__A11y_B-rjF{position:absolute;inset-block-start:0;inset-inline-start:0;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;pointer-events:none}@keyframes viraui__typewriter-module__typewriter-caret-blink_yLCpV{50%{opacity:0}}
@@ -0,0 +1,68 @@
1
+ import { IntrinsicViraProps } from '../../core/props/intrinsic-vira-props';
2
+ import { TypewriterCaret } from './typewriter.utils';
3
+ import type * as React from 'react';
4
+ /**
5
+ * Public Typewriter props.
6
+ *
7
+ * Includes standard `span` attributes such as `id`, `className`, and event handlers,
8
+ * plus Vira-owned typewriter animation controls.
9
+ *
10
+ * @default Native span pass-through props keep React defaults.
11
+ */
12
+ export type TypewriterProps = React.ComponentPropsWithRef<'span'> & IntrinsicViraProps & {
13
+ /**
14
+ * Cycles through multiple phrases instead of a single `children` string.
15
+ *
16
+ * @default The animation uses string `children` when provided.
17
+ */
18
+ texts?: readonly string[];
19
+ /**
20
+ * Selects the caret style rendered after the typed text.
21
+ *
22
+ * @default 'pipe'
23
+ */
24
+ caret?: TypewriterCaret;
25
+ /**
26
+ * Overrides the caret color.
27
+ *
28
+ * @default The caret inherits `currentColor`.
29
+ */
30
+ caretColor?: string;
31
+ /**
32
+ * Sets the delay between typed characters in milliseconds.
33
+ *
34
+ * @default 40
35
+ */
36
+ speed?: number;
37
+ /**
38
+ * Sets the delay between deleted characters in milliseconds.
39
+ *
40
+ * @default 25
41
+ */
42
+ deleteSpeed?: number;
43
+ /**
44
+ * Sets the pause after a phrase completes before deletion starts, in milliseconds.
45
+ *
46
+ * @default 2000
47
+ */
48
+ pause?: number;
49
+ /**
50
+ * Sets the initial delay before typing starts, in milliseconds.
51
+ *
52
+ * @default 0
53
+ */
54
+ delay?: number;
55
+ /**
56
+ * Repeats the phrase cycle after the final phrase is deleted.
57
+ *
58
+ * @default true
59
+ */
60
+ loop?: boolean;
61
+ /**
62
+ * Reserves the full phrase width while characters are typed.
63
+ *
64
+ * @default false
65
+ */
66
+ preserveSpace?: boolean;
67
+ };
68
+ export declare const Typewriter: React.FC<TypewriterProps>;
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "Typewriter",
3
+ "summary": "Decorative inline typewriter animation that inherits typography and color from a parent text primitive.",
4
+ "whenToUse": [
5
+ "Hero or marketing copy that cycles through short phrases",
6
+ "Loading or status labels that reveal text progressively",
7
+ "Muted intro copy inside Text or Title where motion adds emphasis"
8
+ ],
9
+ "whenNotToUse": [
10
+ "Standalone accessible status updates without a surrounding labeled region",
11
+ "Long-form content better served by static Text",
12
+ "Cases where reduced-motion users must see every phrase in a multi-text cycle"
13
+ ],
14
+ "accessibility": [
15
+ "The visual display layer is aria-hidden; completed phrases announce through the polite live region",
16
+ "Reduced motion shows the current phrase immediately without cycling delays",
17
+ "Parent region owns loading or busy semantics when Typewriter is decorative"
18
+ ],
19
+ "antiPatterns": [
20
+ "Using Typewriter as the only source of critical status information",
21
+ "Embedding layout positioning rules inside the component stylesheet",
22
+ "Restarting animation on every parent render by passing unstable inline text arrays without stable content"
23
+ ],
24
+ "related": ["Text", "Title", "Shimmer"],
25
+ "properties": {
26
+ "react": {
27
+ "caretColor": {
28
+ "description": "Overrides the caret color.",
29
+ "refCss": "caret-color"
30
+ }
31
+ },
32
+ "css": {
33
+ "caret-color": {
34
+ "description": "Typewriter caret color.",
35
+ "refReact": "caretColor"
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,105 @@
1
+ "use client";
2
+ import './typewriter.css';
3
+ import { clsx } from "../../core/clsx.js";
4
+ import { extractIntrinsicViraProps } from "../../core/props/intrinsic-vira-props.js";
5
+ import typewriter_module_default from "./typewriter.module.js";
6
+ import { resolveTextsKey, runTypewriterAnimation, splitTextsKey } from "./typewriter.utils.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useEffect, useRef } from "react";
9
+ //#region src/components/typewriter/typewriter.tsx
10
+ var createCaretElement = (caret) => {
11
+ if (caret === "none") return null;
12
+ const element = document.createElement("span");
13
+ element.className = typewriter_module_default.Caret;
14
+ element.dataset.type = caret;
15
+ return element;
16
+ };
17
+ var Typewriter = ({ caret = "pipe", caretColor, children, className, delay = 0, deleteSpeed = 25, loop = true, pause = 2e3, preserveSpace = false, ref, speed = 40, style, texts, ...otherProps }) => {
18
+ const { componentProps, intrinsicAttributes } = extractIntrinsicViraProps(otherProps);
19
+ const displayRef = useRef(null);
20
+ const liveRef = useRef(null);
21
+ const textsKey = resolveTextsKey(texts, children);
22
+ const firstText = splitTextsKey(textsKey)[0] ?? "";
23
+ useEffect(() => {
24
+ const display = displayRef.current;
25
+ const live = liveRef.current;
26
+ if (!display || !textsKey) return;
27
+ const textNode = document.createTextNode("");
28
+ const caretElement = createCaretElement(caret);
29
+ let ghostTextNode = null;
30
+ const nodes = [];
31
+ if (preserveSpace) {
32
+ ghostTextNode = document.createTextNode("");
33
+ const ghost = document.createElement("span");
34
+ ghost.className = typewriter_module_default.Ghost;
35
+ ghost.appendChild(ghostTextNode);
36
+ nodes.push(ghost);
37
+ const typed = document.createElement("span");
38
+ typed.className = typewriter_module_default.Typed;
39
+ typed.appendChild(textNode);
40
+ if (caretElement) typed.appendChild(caretElement);
41
+ nodes.push(typed);
42
+ } else {
43
+ nodes.push(textNode);
44
+ if (caretElement) nodes.push(caretElement);
45
+ }
46
+ display.replaceChildren(...nodes);
47
+ const controller = new AbortController();
48
+ runTypewriterAnimation({
49
+ texts: splitTextsKey(textsKey),
50
+ loop,
51
+ typeDelay: speed,
52
+ deleteDelay: deleteSpeed,
53
+ pause,
54
+ delay,
55
+ textNode,
56
+ ghostTextNode,
57
+ reducedMotion: window.matchMedia("(prefers-reduced-motion: reduce)").matches,
58
+ onPhraseComplete: (text) => {
59
+ if (live) live.textContent = text;
60
+ },
61
+ signal: controller.signal
62
+ });
63
+ return () => {
64
+ controller.abort();
65
+ };
66
+ }, [
67
+ caret,
68
+ delay,
69
+ deleteSpeed,
70
+ loop,
71
+ pause,
72
+ preserveSpace,
73
+ speed,
74
+ textsKey
75
+ ]);
76
+ const dynamicStyle = {
77
+ ...caretColor && { "--vui-typewriter-caret-color": caretColor },
78
+ ...style
79
+ };
80
+ return /* @__PURE__ */ jsxs("span", {
81
+ ...componentProps,
82
+ ...intrinsicAttributes,
83
+ ref,
84
+ className: clsx(typewriter_module_default.Typewriter, className),
85
+ style: dynamicStyle,
86
+ children: [/* @__PURE__ */ jsx("span", {
87
+ ref: displayRef,
88
+ className: typewriter_module_default.Display,
89
+ "aria-hidden": "true",
90
+ ...preserveSpace && { "data-preserve-space": true },
91
+ children: preserveSpace && firstText && /* @__PURE__ */ jsx("span", {
92
+ className: typewriter_module_default.Ghost,
93
+ children: firstText
94
+ })
95
+ }), /* @__PURE__ */ jsx("span", {
96
+ ref: liveRef,
97
+ className: typewriter_module_default.A11y,
98
+ "aria-live": "polite",
99
+ "aria-atomic": "true",
100
+ children: firstText
101
+ })]
102
+ });
103
+ };
104
+ //#endregion
105
+ export { Typewriter };
@@ -0,0 +1,18 @@
1
+ //#region src/components/typewriter/typewriter.module.css
2
+ var Typewriter = "viraui__typewriter-module__Typewriter_R3sbb";
3
+ var Display = "viraui__typewriter-module__Display_-IGJh";
4
+ var Ghost = "viraui__typewriter-module__Ghost_R-Yy-";
5
+ var Typed = "viraui__typewriter-module__Typed_00NZ8";
6
+ var Caret = "viraui__typewriter-module__Caret_96Yfs";
7
+ var A11y = "viraui__typewriter-module__A11y_B-rjF";
8
+ var typewriter_module_default = {
9
+ Typewriter,
10
+ Display,
11
+ Ghost,
12
+ Typed,
13
+ Caret,
14
+ "typewriter-caret-blink": "viraui__typewriter-module__typewriter-caret-blink_yLCpV",
15
+ A11y
16
+ };
17
+ //#endregion
18
+ export { A11y, Caret, Display, Ghost, Typed, Typewriter, typewriter_module_default as default };
@@ -0,0 +1,23 @@
1
+ import type * as React from 'react';
2
+ export type TypewriterCaret = 'block' | 'underscore' | 'pipe' | 'none';
3
+ export declare const TYPEWRITER_TEXTS_SEPARATOR = "\0";
4
+ export declare const resolveTextsKey: (texts: readonly string[] | undefined, children: React.ReactNode) => string;
5
+ export declare const splitTextsKey: (textsKey: string) => string[];
6
+ /** ponytail: bust module cache so story tests can exercise Segmenter fallback */
7
+ export declare const clearGraphemeSegmenterCacheForTests: () => void;
8
+ export declare const splitGraphemes: (text: string) => string[];
9
+ export declare const commonPrefixLength: (previous: readonly string[], next: readonly string[]) => number;
10
+ export type RunTypewriterAnimationOptions = {
11
+ texts: readonly string[];
12
+ loop: boolean;
13
+ typeDelay: number;
14
+ deleteDelay: number;
15
+ pause: number;
16
+ delay: number;
17
+ textNode: Text;
18
+ ghostTextNode: Text | null;
19
+ reducedMotion: boolean;
20
+ onPhraseComplete: (text: string) => void;
21
+ signal: AbortSignal;
22
+ };
23
+ export declare const runTypewriterAnimation: ({ texts, loop, typeDelay, deleteDelay, pause, delay: initialDelay, reducedMotion, onPhraseComplete, signal, ...nodes }: RunTypewriterAnimationOptions) => Promise<void>;