@fluencypassdevs/cycle 1.28.0 → 1.30.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 (61) hide show
  1. package/bin/components.generated.mjs +218 -10
  2. package/dist/{chunk-JPEQ4BYK.js → chunk-5AH2PNYW.js} +68 -3
  3. package/dist/chunk-5AH2PNYW.js.map +1 -0
  4. package/dist/{chunk-32NHCUEZ.js → chunk-C6VTOLNM.js} +2 -2
  5. package/dist/{chunk-32NHCUEZ.js.map → chunk-C6VTOLNM.js.map} +1 -1
  6. package/dist/{chunk-RPU3FY62.js → chunk-CLL76ZXJ.js} +3 -3
  7. package/dist/{chunk-RPU3FY62.js.map → chunk-CLL76ZXJ.js.map} +1 -1
  8. package/dist/chunk-KSAVYUNJ.js +3 -0
  9. package/dist/chunk-KSAVYUNJ.js.map +1 -0
  10. package/dist/{chunk-NKBTC4IF.js → chunk-MOSB7T52.js} +3 -3
  11. package/dist/{chunk-NKBTC4IF.js.map → chunk-MOSB7T52.js.map} +1 -1
  12. package/dist/{chunk-2KFWBA76.js → chunk-MQTQIX4N.js} +3 -3
  13. package/dist/{chunk-2KFWBA76.js.map → chunk-MQTQIX4N.js.map} +1 -1
  14. package/dist/{chunk-AHHT4FZS.js → chunk-NMIDTIUE.js} +3 -3
  15. package/dist/{chunk-AHHT4FZS.js.map → chunk-NMIDTIUE.js.map} +1 -1
  16. package/dist/{chunk-OLYW5LVG.js → chunk-NYO2JMQ7.js} +3 -3
  17. package/dist/{chunk-OLYW5LVG.js.map → chunk-NYO2JMQ7.js.map} +1 -1
  18. package/dist/{chunk-CLMO3IRS.js → chunk-OFGJDRRR.js} +61 -50
  19. package/dist/chunk-OFGJDRRR.js.map +1 -0
  20. package/dist/{chunk-T73O7F3B.js → chunk-R3RHMROE.js} +3 -3
  21. package/dist/{chunk-T73O7F3B.js.map → chunk-R3RHMROE.js.map} +1 -1
  22. package/dist/{chunk-GI7MEYSN.js → chunk-T5U4Q37E.js} +3 -3
  23. package/dist/{chunk-GI7MEYSN.js.map → chunk-T5U4Q37E.js.map} +1 -1
  24. package/dist/chunk-TJ4O3VAL.js +274 -0
  25. package/dist/chunk-TJ4O3VAL.js.map +1 -0
  26. package/dist/chunk-VE4QISBD.js +3 -0
  27. package/dist/chunk-VE4QISBD.js.map +1 -0
  28. package/dist/chunk-VMUNB4RA.js +102 -0
  29. package/dist/chunk-VMUNB4RA.js.map +1 -0
  30. package/dist/{chunk-KSEDDFGG.js → chunk-VZ2GYSNK.js} +3 -3
  31. package/dist/{chunk-KSEDDFGG.js.map → chunk-VZ2GYSNK.js.map} +1 -1
  32. package/dist/{chunk-LALM2LHM.js → chunk-W62WANUP.js} +2 -2
  33. package/dist/{chunk-LALM2LHM.js.map → chunk-W62WANUP.js.map} +1 -1
  34. package/dist/composites/chat-thread.d.ts +18 -7
  35. package/dist/composites/chat-thread.js +10 -7
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +22 -18
  38. package/dist/marketing/effects/index.js +1 -1
  39. package/dist/marketing/motion/index.js +1 -1
  40. package/dist/ui/alert-dialog.js +3 -2
  41. package/dist/ui/alert.d.ts +1 -1
  42. package/dist/ui/badge.js +2 -1
  43. package/dist/ui/button.js +2 -1
  44. package/dist/ui/chat-message.js +4 -3
  45. package/dist/ui/chat-panel.js +3 -2
  46. package/dist/ui/command.js +4 -3
  47. package/dist/ui/dialog.js +3 -2
  48. package/dist/ui/error-state.d.ts +61 -0
  49. package/dist/ui/error-state.js +10 -0
  50. package/dist/ui/error-state.js.map +1 -0
  51. package/dist/ui/like-dislike.js +3 -2
  52. package/dist/ui/live-waiting.js +3 -2
  53. package/dist/ui/message-bar.d.ts +4 -1
  54. package/dist/ui/message-bar.js +4 -1
  55. package/dist/ui/pagination.js +3 -2
  56. package/dist/ui/status-banner.d.ts +32 -0
  57. package/dist/ui/status-banner.js +12 -0
  58. package/dist/ui/status-banner.js.map +1 -0
  59. package/package.json +1 -1
  60. package/dist/chunk-CLMO3IRS.js.map +0 -1
  61. package/dist/chunk-JPEQ4BYK.js.map +0 -1
@@ -1087,11 +1087,11 @@ export const COMPONENTS = [
1087
1087
  {
1088
1088
  "name": "MessageBar",
1089
1089
  "import": "import { MessageBar } from \"@fluencypassdevs/cycle\"",
1090
- "description": "Input bar para chat com IA. 6 estados: default, audio-only, active, disabled, recording, paused. UI-only: consumer implementa MediaRecorder + HTMLAudioElement via callbacks. Live waveform real durante recording (Web Audio API, rolling window estilo WhatsApp). RecordedWaveform real durante paused com peaks + barras tocadas/nao-tocadas + dot verde + click/drag-to-seek. Press-to-record no mobile (touch-only): long-press inicia, drag-up trava em hands-free, drag-left cancela, release < 1s cancela, release >= 1s envia. Vibracao haptica em lock/cancel. Suporta limite de duracao via maxRecordingDuration (segundos) com warning visual configuravel nos segundos finais (timer destructive + 'Xs restantes' aria-live) e callback onMaxDurationReached ao atingir o limite.",
1090
+ "description": "Input bar para chat com IA. 7 estados: default, audio-only, active, disabled, recording, paused, requesting (mic vira spinner enquanto o consumer aguarda getUserMedia). UI-only: consumer implementa MediaRecorder + HTMLAudioElement via callbacks. Live waveform real durante recording (Web Audio API, rolling window estilo WhatsApp). RecordedWaveform real durante paused com peaks + barras tocadas/nao-tocadas + dot verde + click/drag-to-seek. Press-to-record no mobile (touch-only): long-press inicia, drag-up trava em hands-free, drag-left cancela, release < 1s cancela, release >= 1s envia. Vibracao haptica em lock/cancel. Suporta limite de duracao via maxRecordingDuration (segundos) com warning visual configuravel nos segundos finais (timer destructive + 'Xs restantes' aria-live) e callback onMaxDurationReached ao atingir o limite.",
1091
1091
  "props": [
1092
1092
  {
1093
1093
  "name": "state",
1094
- "type": "\"default\" | \"audio-only\" | \"active\" | \"disabled\" | \"recording\" | \"paused\"",
1094
+ "type": "\"default\" | \"audio-only\" | \"active\" | \"disabled\" | \"recording\" | \"paused\" | \"requesting\"",
1095
1095
  "default": "\"default\""
1096
1096
  },
1097
1097
  {
@@ -1217,7 +1217,7 @@ export const COMPONENTS = [
1217
1217
  {
1218
1218
  "name": "ChatThread",
1219
1219
  "import": "import { ChatThread, type ChatThreadMessage } from \"@fluencypassdevs/cycle\"",
1220
- "description": "Composite 'tela de chat pronta' que junta ChatMessage + MessageBar + MessageRating. Gerencia state machine interno do MessageBar (default↔recording↔paused) baseado nos callbacks. Auto-scroll inteligente (preserva posicao se user subiu). Scroll infinito via onLoadMore. Banners configuraveis: offline, rateLimitedUntil (countdown), quotaExhausted (AlertDialog). Retry inline em msgs failed do user (B2) e regenerar resposta da IA (B3). Botao 'Parar resposta' durante thinking e OPT-IN via presenca de onStopResponse — sem callback, MessageBar some com animacao de saida e volta quando IA termina. requestRating per-message renderiza MessageRating inline embaixo da bubble da IA — escolha some imediato, callback onRate(messageId, value, label) permite consumer enviar como msg do user. initialThinking pra conversas que comecam com IA falando. Input controlled internamente. Animacoes fade+slide (200ms enter / 150ms leave). Suporta limite de duracao de gravacao via maxRecordingDuration (segundos) com warning visual configuravel e auto-pause ao atingir; override via onMaxDurationReached.",
1220
+ "description": "Composite 'tela de chat pronta' que junta ChatMessage + MessageBar + MessageRating. Gerencia state machine interno do MessageBar (default↔requesting↔recording↔paused) baseado nos callbacks. onStartRecording/onResumeRecording podem retornar Promise: MessageBar fica em requesting ate resolver; rejeitou → volta pro estado anterior + onRecordingError. Auto-scroll inteligente (preserva posicao se user subiu). Scroll infinito via onLoadMore. Banners configuraveis: offline, rateLimitedUntil (countdown), quotaExhausted (AlertDialog). Retry inline em msgs failed do user (B2) e regenerar resposta da IA (B3). Botao 'Parar resposta' durante thinking e OPT-IN via presenca de onStopResponse — sem callback, MessageBar some com animacao de saida e volta quando IA termina. requestRating per-message renderiza MessageRating inline embaixo da bubble da IA — escolha some imediato, callback onRate(messageId, value, label) permite consumer enviar como msg do user. initialThinking pra conversas que comecam com IA falando. Input controlled internamente. Animacoes fade+slide (200ms enter / 150ms leave). Suporta limite de duracao de gravacao via maxRecordingDuration (segundos) com warning visual configuravel e auto-pause ao atingir; override via onMaxDurationReached.",
1221
1221
  "props": [
1222
1222
  {
1223
1223
  "name": "messages",
@@ -1256,9 +1256,9 @@ export const COMPONENTS = [
1256
1256
  },
1257
1257
  {
1258
1258
  "name": "onStartRecording",
1259
- "type": "() => void",
1259
+ "type": "() => void | Promise<unknown>",
1260
1260
  "default": "-",
1261
- "note": "consumer chama getUserMedia + cria MediaRecorder"
1261
+ "note": "consumer chama getUserMedia + cria MediaRecorder. Retorne a Promise: MessageBar fica em requesting ate resolver e so entra em recording depois (evita 'gravando' sem microfone)"
1262
1262
  },
1263
1263
  {
1264
1264
  "name": "onPauseRecording",
@@ -1268,8 +1268,15 @@ export const COMPONENTS = [
1268
1268
  },
1269
1269
  {
1270
1270
  "name": "onResumeRecording",
1271
- "type": "() => void",
1272
- "default": "-"
1271
+ "type": "() => void | Promise<unknown>",
1272
+ "default": "-",
1273
+ "note": "mesma semantica de Promise do onStartRecording (rejeitou → volta pra paused)"
1274
+ },
1275
+ {
1276
+ "name": "onRecordingError",
1277
+ "type": "(error: unknown) => void",
1278
+ "default": "-",
1279
+ "note": "dispara quando a Promise de start/resume rejeita (ex.: permissao negada). Estado ja restaurado; consumer da o feedback"
1273
1280
  },
1274
1281
  {
1275
1282
  "name": "onCancelRecording",
@@ -1762,10 +1769,10 @@ export const COMPONENTS = [
1762
1769
  },
1763
1770
  {
1764
1771
  "name": "Empty",
1765
- "import": "import { Empty, EmptyIcon, EmptyTitle, EmptyDescription, EmptyContent } from \"@fluencypassdevs/cycle\"",
1766
- "description": "Estado vazio com icone/media, titulo, descricao e area para acoes.",
1772
+ "import": "import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent } from \"@fluencypassdevs/cycle\"",
1773
+ "description": "Estado vazio com icone/media, titulo, descricao e area para acoes. Para falhas, use ErrorState.",
1767
1774
  "props": [],
1768
- "example": "<Empty>\n <EmptyIcon><CycleIcon icon={Inbox} size=\"lg\" decorative /></EmptyIcon>\n <EmptyTitle>Nenhum resultado</EmptyTitle>\n <EmptyDescription>Tente ajustar os filtros.</EmptyDescription>\n <EmptyContent><Button>Limpar filtros</Button></EmptyContent>\n</Empty>",
1775
+ "example": "<Empty>\n <EmptyHeader>\n <EmptyMedia variant=\"icon\"><CycleIcon icon={Inbox} size=\"sm\" decorative /></EmptyMedia>\n <EmptyTitle>Nenhum resultado</EmptyTitle>\n <EmptyDescription>Tente ajustar os filtros.</EmptyDescription>\n </EmptyHeader>\n <EmptyContent><Button>Limpar filtros</Button></EmptyContent>\n</Empty>",
1769
1776
  "keywords": [
1770
1777
  "empty",
1771
1778
  "vazio",
@@ -1775,6 +1782,207 @@ export const COMPONENTS = [
1775
1782
  "estado"
1776
1783
  ]
1777
1784
  },
1785
+ {
1786
+ "name": "ErrorState",
1787
+ "import": "import { ErrorState } from \"@fluencypassdevs/cycle\"",
1788
+ "description": "Estado de erro. kind escolhe o cenario (not-found | forbidden | unauthorized | server | offline | generic), size escolhe pagina inteira ou secao. Titulo, descricao, icone e cor vem do preset. UI-only: retry/report sao callbacks do consumidor; navegacao via actions. Copy default so afirma o que o componente garante (sem \"ja fomos avisados\"); quem reporta sobrescreve title/description.",
1789
+ "props": [
1790
+ {
1791
+ "name": "kind",
1792
+ "type": "'not-found' | 'forbidden' | 'unauthorized' | 'server' | 'offline' | 'generic'",
1793
+ "default": "'generic'",
1794
+ "description": "Cenario. Define icone, copy e severidade. unauthorized = sessao expirada (401)."
1795
+ },
1796
+ {
1797
+ "name": "size",
1798
+ "type": "'page' | 'section'",
1799
+ "default": "'section'",
1800
+ "description": "Pagina inteira (foca o h1) ou bloco dentro da tela (role status/alert)."
1801
+ },
1802
+ {
1803
+ "name": "severity",
1804
+ "type": "'neutral' | 'warning' | 'critical'",
1805
+ "default": "derivado do kind",
1806
+ "description": "Cor do icone. not-found/forbidden neutro, offline warning, server/generic critical."
1807
+ },
1808
+ {
1809
+ "name": "title",
1810
+ "type": "ReactNode",
1811
+ "description": "Sobrescreve o titulo do preset."
1812
+ },
1813
+ {
1814
+ "name": "description",
1815
+ "type": "ReactNode",
1816
+ "description": "Sobrescreve a descricao do preset."
1817
+ },
1818
+ {
1819
+ "name": "code",
1820
+ "type": "string | number",
1821
+ "description": "Badge mono com codigo HTTP. Opcional, nunca no titulo."
1822
+ },
1823
+ {
1824
+ "name": "referenceId",
1825
+ "type": "string",
1826
+ "description": "'Referencia xxx' com botao copiar. Use error.digest do Next."
1827
+ },
1828
+ {
1829
+ "name": "onRetry",
1830
+ "type": "() => void",
1831
+ "description": "Renderiza 'Tentar novamente' (primario)."
1832
+ },
1833
+ {
1834
+ "name": "onReport",
1835
+ "type": "() => void",
1836
+ "description": "Renderiza link 'Relatar problema'. So em falha de sistema."
1837
+ },
1838
+ {
1839
+ "name": "actions",
1840
+ "type": "ReactNode",
1841
+ "description": "Seus botoes (ex.: Button asChild + Link para inicio). Max 1 primario + 1 secundario."
1842
+ },
1843
+ {
1844
+ "name": "media",
1845
+ "type": "ReactNode",
1846
+ "description": "Substitui o icone (ilustracao)."
1847
+ },
1848
+ {
1849
+ "name": "bordered",
1850
+ "type": "boolean",
1851
+ "default": "false",
1852
+ "description": "section: borda tracejada."
1853
+ },
1854
+ {
1855
+ "name": "autoFocus",
1856
+ "type": "boolean",
1857
+ "default": "true",
1858
+ "description": "page: foca o titulo ao montar."
1859
+ },
1860
+ {
1861
+ "name": "headingLevel",
1862
+ "type": "1 | 2 | 3 | 4",
1863
+ "default": "1 em page, 2 em section",
1864
+ "description": "Tag do titulo."
1865
+ },
1866
+ {
1867
+ "name": "retryLabel",
1868
+ "type": "string",
1869
+ "default": "'Tentar novamente'",
1870
+ "description": "Rotulo do botao de retry."
1871
+ },
1872
+ {
1873
+ "name": "reportLabel",
1874
+ "type": "string",
1875
+ "default": "'Relatar problema'",
1876
+ "description": "Rotulo do link de report."
1877
+ }
1878
+ ],
1879
+ "example": "// Secao que nao carregou\n<ErrorState onRetry={refetch} />\n\n// 404 em app/not-found.tsx\n<ErrorState kind=\"not-found\" size=\"page\" code={404}\n actions={<Button asChild><Link href=\"/\">Ir para o início</Link></Button>} />\n\n// 500 em app/error.tsx\n<ErrorState kind=\"server\" size=\"page\" code={500} referenceId={error.digest} onRetry={reset} />",
1880
+ "keywords": [
1881
+ "error",
1882
+ "erro",
1883
+ "falha",
1884
+ "404",
1885
+ "403",
1886
+ "500",
1887
+ "not found",
1888
+ "nao encontrado",
1889
+ "forbidden",
1890
+ "sem acesso",
1891
+ "offline",
1892
+ "sem conexao",
1893
+ "retry",
1894
+ "tentar novamente",
1895
+ "error boundary",
1896
+ "not-found.tsx",
1897
+ "error.tsx",
1898
+ "401",
1899
+ "unauthorized",
1900
+ "sessao expirada"
1901
+ ]
1902
+ },
1903
+ {
1904
+ "name": "ErrorStateMedia",
1905
+ "import": "import { ErrorState, ErrorStateMedia, ErrorStateTitle, ErrorStateDescription, ErrorStateActions, ErrorStateMeta } from \"@fluencypassdevs/cycle\"",
1906
+ "description": "Sub-componentes para composicao livre do ErrorState (mesma anatomia do Empty): Media (icone com cor da severidade), Title, Description, Actions, Meta (codigo/referencia).",
1907
+ "props": [],
1908
+ "example": "<ErrorState kind=\"server\" size=\"section\" title=\"Falhou o envio\" description=\"Seu texto foi mantido.\" onRetry={resend} />",
1909
+ "keywords": [
1910
+ "error state",
1911
+ "composicao",
1912
+ "media",
1913
+ "title",
1914
+ "description",
1915
+ "actions",
1916
+ "meta"
1917
+ ]
1918
+ },
1919
+ {
1920
+ "name": "StatusBanner",
1921
+ "import": "import { StatusBanner } from \"@fluencypassdevs/cycle\"",
1922
+ "description": "Banner persistente de status (nao e erro). kind offline (warning, WifiOff, texto \"Voce esta sem conexao. Confira o Wi-Fi ou os dados moveis.\"), rate-limit (neutro, countdown a partir de until), custom. UI-only: o consumidor decide quando mostrar.",
1923
+ "props": [
1924
+ {
1925
+ "name": "kind",
1926
+ "type": "'offline' | 'rate-limit' | 'custom'",
1927
+ "default": "'custom'",
1928
+ "description": "Preset de icone, cor e texto."
1929
+ },
1930
+ {
1931
+ "name": "variant",
1932
+ "type": "'neutral' | 'warning' | 'critical' | 'info'",
1933
+ "default": "derivado do kind",
1934
+ "description": "Cor."
1935
+ },
1936
+ {
1937
+ "name": "icon",
1938
+ "type": "LucideIcon",
1939
+ "description": "Icone a esquerda."
1940
+ },
1941
+ {
1942
+ "name": "children",
1943
+ "type": "ReactNode",
1944
+ "description": "Texto; sobrescreve o default do kind."
1945
+ },
1946
+ {
1947
+ "name": "until",
1948
+ "type": "number | null",
1949
+ "description": "rate-limit: timestamp (ms). Countdown em segundos."
1950
+ },
1951
+ {
1952
+ "name": "rateLimitText",
1953
+ "type": "(s: number) => string",
1954
+ "description": "Formato do countdown."
1955
+ },
1956
+ {
1957
+ "name": "action",
1958
+ "type": "{ label: string; onClick: () => void }",
1959
+ "description": "Link a direita."
1960
+ },
1961
+ {
1962
+ "name": "onDismiss",
1963
+ "type": "() => void",
1964
+ "description": "Renderiza X a direita."
1965
+ },
1966
+ {
1967
+ "name": "dismissLabel",
1968
+ "type": "string",
1969
+ "default": "'Fechar aviso'",
1970
+ "description": "aria-label do botao de fechar."
1971
+ }
1972
+ ],
1973
+ "example": "{isOffline && <StatusBanner kind=\"offline\" action={{ label: \"Tentar agora\", onClick: reconnect }} />}\n{rateLimitedUntil && <StatusBanner kind=\"rate-limit\" until={rateLimitedUntil} />}",
1974
+ "keywords": [
1975
+ "banner",
1976
+ "status",
1977
+ "offline",
1978
+ "sem conexao",
1979
+ "rate limit",
1980
+ "countdown",
1981
+ "aviso",
1982
+ "manutencao",
1983
+ "persistente"
1984
+ ]
1985
+ },
1778
1986
  {
1779
1987
  "name": "Skeleton",
1780
1988
  "import": "import { Skeleton } from \"@fluencypassdevs/cycle\"",
@@ -1,3 +1,4 @@
1
+ import { Spinner } from './chunk-TDBDX5NV.js';
1
2
  import { cn } from './chunk-W4KJCBMW.js';
2
3
  import { __objRest, __spreadProps, __spreadValues } from './chunk-2NMEKWO5.js';
3
4
  import * as React from 'react';
@@ -582,10 +583,15 @@ function MessageBar(_a) {
582
583
  const lastBaseStateRef = React.useRef(
583
584
  state === "audio-only" ? "audio-only" : "default"
584
585
  );
586
+ const requestingFromRef = React.useRef(null);
585
587
  React.useEffect(() => {
586
588
  const prev = prevStateRef.current;
589
+ if (state === "requesting" && prev !== "requesting") {
590
+ requestingFromRef.current = prev;
591
+ }
587
592
  if (state === "recording" && prev !== "paused" && prev !== "recording") {
588
- samplesRef.current = [];
593
+ const resuming = prev === "requesting" && requestingFromRef.current === "paused";
594
+ if (!resuming) samplesRef.current = [];
589
595
  }
590
596
  if (state === "default" || state === "audio-only") {
591
597
  lastBaseStateRef.current = state;
@@ -607,6 +613,16 @@ function MessageBar(_a) {
607
613
  pressDeltaRef.current = { x: dx, y: dy };
608
614
  setPressDelta({ x: dx, y: dy });
609
615
  };
616
+ const prevStateForPressRef = React.useRef(state);
617
+ React.useEffect(() => {
618
+ const prev = prevStateForPressRef.current;
619
+ prevStateForPressRef.current = state;
620
+ const backToBase = state === "default" || state === "audio-only" || state === "disabled";
621
+ if (prev === "requesting" && backToBase && isPressedRef.current) {
622
+ setIsPressed(false);
623
+ updateDelta(0, 0);
624
+ }
625
+ }, [state]);
610
626
  React.useEffect(() => {
611
627
  const onTouchMove = (e) => {
612
628
  if (isPressedRef.current) {
@@ -701,6 +717,55 @@ function MessageBar(_a) {
701
717
  onSendText == null ? void 0 : onSendText(value);
702
718
  }
703
719
  };
720
+ if (state === "requesting") {
721
+ const busyMic = /* @__PURE__ */ jsx(
722
+ "button",
723
+ {
724
+ type: "button",
725
+ disabled: true,
726
+ "aria-busy": "true",
727
+ "aria-label": "Pedindo acesso ao microfone",
728
+ className: "shrink-0 inline-flex items-center justify-center size-10 rounded-md bg-primary text-primary-foreground theme-brand opacity-70 cursor-wait",
729
+ children: /* @__PURE__ */ jsx(Spinner, { size: "sm" })
730
+ }
731
+ );
732
+ if (lastBaseStateRef.current === "audio-only") {
733
+ return /* @__PURE__ */ jsx(
734
+ "div",
735
+ __spreadProps(__spreadValues({
736
+ "data-slot": "message-bar",
737
+ "data-state": "requesting",
738
+ className: cn("flex items-center justify-center p-2", className)
739
+ }, props), {
740
+ children: busyMic
741
+ })
742
+ );
743
+ }
744
+ return /* @__PURE__ */ jsxs(
745
+ "div",
746
+ __spreadProps(__spreadValues({
747
+ "data-slot": "message-bar",
748
+ "data-state": "requesting",
749
+ className: cn("flex items-center gap-2 rounded-2xl bg-muted p-2", className)
750
+ }, props), {
751
+ children: [
752
+ /* @__PURE__ */ jsx(
753
+ "input",
754
+ {
755
+ type: "text",
756
+ value,
757
+ readOnly: true,
758
+ disabled: true,
759
+ placeholder,
760
+ className: "flex-1 min-w-0 bg-transparent px-3 py-2 text-base text-neutral-foreground placeholder:text-neutral-muted-foreground outline-none disabled:cursor-wait disabled:opacity-50",
761
+ "aria-label": "Mensagem"
762
+ }
763
+ ),
764
+ busyMic
765
+ ]
766
+ })
767
+ );
768
+ }
704
769
  if (state === "audio-only") {
705
770
  return /* @__PURE__ */ jsx(
706
771
  "div",
@@ -932,5 +997,5 @@ function MessageBar(_a) {
932
997
  }
933
998
 
934
999
  export { MessageBar };
935
- //# sourceMappingURL=chunk-JPEQ4BYK.js.map
936
- //# sourceMappingURL=chunk-JPEQ4BYK.js.map
1000
+ //# sourceMappingURL=chunk-5AH2PNYW.js.map
1001
+ //# sourceMappingURL=chunk-5AH2PNYW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/message-bar.tsx"],"names":["_a","_b"],"mappings":"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","file":"chunk-5AH2PNYW.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Mic, Send, Trash2, Pause, Play, Lock, ChevronUp, ChevronLeft } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Spinner } from \"@/components/ui/spinner\"\n\n/* ─── Types ───────────────────────────────────────────────────── */\n\n/**\n * Estados visuais do MessageBar:\n * - `default`: input texto + botao mic (estado inicial, sem texto digitado)\n * - `audio-only`: apenas botao mic centralizado (modo so audio)\n * - `active`: input texto com conteudo digitado + botao send\n * - `disabled`: input desabilitado\n * - `recording`: barra de gravacao (timer + waveform live + delete/pause/send)\n * - `paused`: gravacao pausada (timer + waveform + play/delete/mic/send)\n * - `requesting`: aguardando o consumer obter o microfone (getUserMedia pendente) —\n * mic vira spinner desabilitado. O ChatThread entra aqui quando `onStartRecording`\n * / `onResumeRecording` retornam Promise; consumers diretos podem usar tambem.\n */\nexport type MessageBarState =\n | \"default\"\n | \"audio-only\"\n | \"active\"\n | \"disabled\"\n | \"recording\"\n | \"paused\"\n | \"requesting\"\n\nexport interface MessageBarProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n /** Estado visual do componente (controlado pelo consumer) */\n state?: MessageBarState\n /** Valor do input de texto */\n value?: string\n /** Callback ao digitar */\n onChange?: (value: string) => void\n /** Callback ao enviar texto (Enter ou clique no botao send) */\n onSendText?: (text: string) => void\n /** Inicia gravacao (consumer chama MediaRecorder.start) */\n onStartRecording?: () => void\n /** Pausa gravacao */\n onPauseRecording?: () => void\n /** Retoma gravacao */\n onResumeRecording?: () => void\n /** Cancela/deleta gravacao */\n onCancelRecording?: () => void\n /** Envia o audio gravado */\n onSendAudio?: () => void\n /** Toggle play/pause do audio gravado durante o estado `paused` */\n onTogglePlay?: () => void\n /** Duracao da gravacao em segundos (controlado pelo consumer) */\n recordingDuration?: number\n /** Indica se esta tocando o audio (durante state=paused) */\n isPlaying?: boolean\n /**\n * MediaStream do microfone (durante state=recording). Quando fornecido,\n * o componente analisa em tempo real e renderiza as barras conforme a voz.\n * Sem stream → fallback para waveform decorativo.\n *\n * Como usar:\n * ```ts\n * const stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n * const recorder = new MediaRecorder(stream)\n * // Passa o MESMO stream pro MessageBar:\n * <MessageBar state=\"recording\" recordingStream={stream} ... />\n * ```\n */\n recordingStream?: MediaStream | null\n /**\n * Progresso do playback do audio gravado (0-1), usado durante state=paused.\n * Quando fornecido, o waveform mostra barras tocadas/nao tocadas + dot verde\n * sincronizado. Sem isso, o waveform mostra todas as barras como nao tocadas.\n *\n * Alimente via `requestAnimationFrame` enquanto o audio toca, NAO so via\n * `timeupdate` — esse evento dispara ~4x/s (250ms) e o dot pula em stop motion.\n * Ver exemplo na doc do MessageBar.\n */\n playbackProgress?: number\n /**\n * Callback ao clicar/arrastar no waveform durante state=paused.\n * Recebe o novo progresso (0-1); o consumer deve setar currentTime do audio.\n */\n onSeekPlayback?: (progress: number) => void\n /** Placeholder do input */\n placeholder?: string\n /**\n * Limite de duracao da gravacao em segundos. Quando omitido, sem limite\n * (comportamento default). Quando atingido, o componente dispara\n * `onMaxDurationReached` UMA VEZ — o ChatThread usa esse callback pra auto-pausar;\n * consumers diretos do MessageBar podem usar pra customizar.\n */\n maxRecordingDuration?: number\n /**\n * Quantos segundos antes do limite ativar o warning visual\n * (timer em vermelho + label \"Xs restantes\" abaixo). Default: 10.\n * Ignorado se `maxRecordingDuration` nao for passado.\n */\n warnAtSecondsLeft?: number\n /**\n * Callback disparado uma unica vez quando `recordingDuration` >= `maxRecordingDuration`.\n * Reseta automaticamente quando o componente sai do estado `recording`.\n */\n onMaxDurationReached?: () => void\n /**\n * Label do warning inline. Recebe quantos segundos restam, retorna string.\n * Default pt-BR: `(s) => \\`${s}s restantes\\``.\n */\n secondsLeftLabel?: (secondsLeft: number) => string\n}\n\n/* ─── Helpers ─────────────────────────────────────────────────── */\n\nfunction formatDuration(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"00:00\"\n const m = Math.floor(seconds / 60)\n const s = Math.floor(seconds % 60)\n return `${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`\n}\n\n/** Calcula estado de warning do timer durante gravacao.\n * - `isWarning` vira true quando faltam `warnAt` segundos ou menos.\n * - `secondsLeft` = max(0, max - elapsed).\n * Sem `max` ou valores invalidos, isWarning=false e secondsLeft=Infinity. */\nfunction getWarningState(\n elapsed: number,\n max: number | undefined,\n warnAt: number\n): { isWarning: boolean; secondsLeft: number } {\n if (!max || max <= 0) return { isWarning: false, secondsLeft: Infinity }\n const secondsLeft = Math.max(0, max - elapsed)\n return { isWarning: secondsLeft <= warnAt, secondsLeft }\n}\n\nconst DEFAULT_WARN_AT_SECONDS_LEFT = 10\nconst DEFAULT_SECONDS_LEFT_LABEL = (s: number) => `${s}s restantes`\n\n/* ─── Sub-componentes ─────────────────────────────────────────── */\n\n/** Botao mic vermelho coral (theme-brand) — usado em default, audio-only e durante press.\n * - `variant=\"large\"` aumenta para 64x64 (overlay durante press)\n * - `pressed` aplica scale-110 + opacity 90\n * - Aceita pointer events para suportar press-and-hold (mobile WhatsApp-style) */\nfunction MicButton({\n onClick,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onPointerCancel,\n size = \"default\",\n variant = \"default\",\n pressed = false,\n ariaLabel = \"Gravar audio\",\n className,\n style,\n}: {\n onClick?: () => void\n onPointerDown?: (e: React.PointerEvent<HTMLButtonElement>) => void\n onPointerMove?: (e: React.PointerEvent<HTMLButtonElement>) => void\n onPointerUp?: (e: React.PointerEvent<HTMLButtonElement>) => void\n onPointerCancel?: (e: React.PointerEvent<HTMLButtonElement>) => void\n size?: \"default\" | \"sm\"\n variant?: \"default\" | \"large\"\n pressed?: boolean\n ariaLabel?: string\n className?: string\n style?: React.CSSProperties\n}) {\n const buttonRef = React.useRef<HTMLButtonElement>(null)\n const hasPressFlow = !!onPointerDown\n\n /* touchstart non-passive — marca o gesto como NAO scroll desde o primeiro evento.\n * Critico pra Android Chrome (Blink): se o touchstart for passive (default no React),\n * o navegador classifica o gesto como \"potencialmente scroll\" e ignora preventDefault\n * posterior. Listener via addEventListener pra poder usar { passive: false }. */\n React.useEffect(() => {\n const btn = buttonRef.current\n if (!btn || !hasPressFlow) return\n const onTouchStart = (e: TouchEvent) => {\n e.preventDefault()\n }\n btn.addEventListener(\"touchstart\", onTouchStart, { passive: false })\n return () => btn.removeEventListener(\"touchstart\", onTouchStart)\n }, [hasPressFlow])\n\n const sizeClass =\n variant === \"large\" ? \"size-16\" : size === \"default\" ? \"size-10\" : \"size-8\"\n const radiusClass = variant === \"large\" ? \"rounded-lg\" : \"rounded-md\"\n return (\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={onClick}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerCancel}\n aria-pressed={pressed || undefined}\n className={cn(\n \"shrink-0 inline-flex items-center justify-center bg-primary text-primary-foreground theme-brand transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n sizeClass,\n radiusClass,\n pressed && \"opacity-90 select-none\",\n // touch-none aplicado sempre que ha press flow (nao so quando ja esta pressed),\n // pra Android Chrome nao classificar o touchstart como scroll\n (hasPressFlow || pressed) && \"touch-none\",\n className\n )}\n style={style}\n aria-label={ariaLabel}\n >\n <Mic className={variant === \"large\" ? \"size-6\" : \"size-5\"} />\n </button>\n )\n}\n\n/** Botao send verde (theme-positive) */\nfunction SendButton({\n onClick,\n disabled,\n ariaLabel = \"Enviar\",\n}: {\n onClick?: () => void\n disabled?: boolean\n ariaLabel?: string\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className=\"shrink-0 inline-flex items-center justify-center size-10 rounded-md bg-primary text-primary-foreground theme-positive transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:opacity-50 disabled:cursor-not-allowed\"\n aria-label={ariaLabel}\n >\n <Send className=\"size-5\" fill=\"currentColor\" strokeWidth={0} />\n </button>\n )\n}\n\n/** Botao icon-only neutral (trash, pause, play, mic durante paused) */\nfunction IconButton({\n onClick,\n icon: Icon,\n ariaLabel,\n filled = false,\n}: {\n onClick?: () => void\n icon: React.ComponentType<{ className?: string; fill?: string; strokeWidth?: number }>\n ariaLabel: string\n filled?: boolean\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"shrink-0 inline-flex items-center justify-center size-10 rounded-md text-neutral-foreground hover:bg-muted/50 transition-colors focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n aria-label={ariaLabel}\n >\n <Icon\n className=\"size-5\"\n {...(filled ? { fill: \"currentColor\", strokeWidth: 0 } : {})}\n />\n </button>\n )\n}\n\n/** Indicador de gravacao (red dot pulsando) */\nfunction RecordingIndicator() {\n return (\n <span className=\"shrink-0 relative inline-flex items-center justify-center size-3\" aria-label=\"Gravando\">\n <span className=\"absolute inset-0 rounded-full bg-primary theme-brand animate-ping opacity-75\" />\n <span className=\"relative size-2.5 rounded-full bg-primary theme-brand\" />\n </span>\n )\n}\n\n/** Helper: agrega N samples brutos em K barras (pico por chunk). Quando samples.length\n * < barCount, \"estica\" via lookup proporcional (cada barra pega o sample mais proximo). */\nfunction aggregateSamples(samples: number[], barCount: number): number[] {\n if (samples.length === 0 || barCount === 0) return new Array(barCount).fill(0)\n const result = new Array(barCount).fill(0)\n // Poucos samples: estica via lookup proporcional\n if (samples.length < barCount) {\n for (let i = 0; i < barCount; i++) {\n const idx = Math.floor((i / barCount) * samples.length)\n result[i] = samples[idx] ?? 0\n }\n return result\n }\n // Muitos samples: agrega pegando o pico (max) do chunk\n const chunkSize = samples.length / barCount\n for (let i = 0; i < barCount; i++) {\n const start = Math.floor(i * chunkSize)\n const end = Math.floor((i + 1) * chunkSize)\n let max = 0\n for (let j = start; j < end && j < samples.length; j++) {\n if (samples[j] > max) max = samples[j]\n }\n result[i] = max\n }\n return result\n}\n\n/** LiveWaveform — analise em tempo real do microfone via AnalyserNode.\n * Comportamento estilo WhatsApp:\n * - **Preenche toda a largura disponivel** (ResizeObserver detecta width e calcula limite max de barras)\n * - Cada bar = 2px wide, 2px gap (4px stride)\n * - **Comeca VAZIO**: primeiras barras entram pela DIREITA e empurram pra esquerda\n * - Depois que enche: rolling window (mais antiga sai esquerda, nova entra direita)\n * - Visualmente: container alinha barras com `justify-end` */\nfunction LiveWaveform({\n stream,\n samplesRef,\n}: {\n stream?: MediaStream | null\n /** Ref opcional: quando fornecido, acumula TODOS os samples brutos da gravacao (para usar no\n * state=paused via RecordedWaveform). O LiveWaveform mantem seu rolling window separado. */\n samplesRef?: React.MutableRefObject<number[]>\n}) {\n const STRIDE = 4 // 2px barra + 2px gap\n const MIN_BARS = 20\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [bars, setBars] = React.useState<number[]>([])\n const barCountRef = React.useRef<number>(MIN_BARS)\n\n /* ResizeObserver: ajusta o LIMITE de barras (nao o buffer atual, exceto se shrink). */\n React.useEffect(() => {\n const el = containerRef.current\n if (!el) return\n\n const updateBarCount = (width: number) => {\n const count = Math.max(MIN_BARS, Math.floor(width / STRIDE))\n barCountRef.current = count\n // Se o buffer atual passou do novo limite (shrink), trunca mantendo as mais recentes\n setBars((prev) => (prev.length > count ? prev.slice(prev.length - count) : prev))\n }\n\n updateBarCount(el.clientWidth)\n\n const ro = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width ?? 0\n updateBarCount(width)\n })\n ro.observe(el)\n\n return () => ro.disconnect()\n }, [])\n\n /* Audio analysis setup (so depende do stream) */\n React.useEffect(() => {\n if (!stream) {\n setBars([])\n return\n }\n\n const AudioContextClass =\n window.AudioContext ||\n (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext\n const audioContext = new AudioContextClass()\n const source = audioContext.createMediaStreamSource(stream)\n const analyser = audioContext.createAnalyser()\n analyser.fftSize = 256\n source.connect(analyser)\n\n const dataArray = new Uint8Array(analyser.frequencyBinCount)\n let rafId: number | null = null\n let lastUpdate = 0\n let cancelled = false\n\n const tick = (timestamp: number) => {\n if (cancelled) return\n // Throttle ~30fps (33ms entre samples)\n if (timestamp - lastUpdate >= 33) {\n lastUpdate = timestamp\n analyser.getByteTimeDomainData(dataArray)\n\n // RMS — amplitude media percebida\n let sum = 0\n for (let i = 0; i < dataArray.length; i++) {\n const v = (dataArray[i] - 128) / 128\n sum += v * v\n }\n const rms = Math.sqrt(sum / dataArray.length)\n\n // Acumula no ref do parent (para reaproveitar no state=paused via RecordedWaveform)\n if (samplesRef) samplesRef.current.push(rms)\n\n setBars((prev) => {\n // Enquanto nao encheu: append no final (vai aparecer na direita por causa do justify-end)\n if (prev.length < barCountRef.current) return [...prev, rms]\n // Cheio: rolling window (descarta mais antiga, adiciona nova)\n return [...prev.slice(1), rms]\n })\n }\n rafId = requestAnimationFrame(tick)\n }\n\n rafId = requestAnimationFrame(tick)\n\n return () => {\n cancelled = true\n if (rafId !== null) cancelAnimationFrame(rafId)\n void audioContext.close()\n }\n }, [stream, samplesRef])\n\n return (\n <div\n ref={containerRef}\n className=\"flex-1 relative h-8 min-w-0 overflow-hidden\"\n >\n <div className=\"absolute inset-y-0 left-0 right-0 flex items-center justify-end gap-[2px]\">\n {bars.map((amp, i) => {\n // Voz humana tende a ter RMS baixo (~0.05-0.3). Boost x4 para visual.\n const normalized = Math.min(amp * 4, 1)\n const height = Math.max(2, Math.round(normalized * 32))\n return (\n <div\n key={i}\n className=\"w-[2px] shrink-0 rounded-full bg-neutral-foreground\"\n style={{ height: `${height}px` }}\n />\n )\n })}\n </div>\n </div>\n )\n}\n\n/** RecordedWaveform — waveform real do audio ja gravado (usado no state=paused).\n * - Recebe samples brutos acumulados durante o recording (via samplesRef)\n * - Agrega em N barras via ResizeObserver (largura dinamica, igual ChatAudio)\n * - Barras tocadas (i / N <= progress) em `bg-neutral-foreground`, demais em `bg-neutral-ring`\n * - Dot verde sincronizado com o progresso\n * - Click/drag-to-seek via pointer events */\nfunction RecordedWaveform({\n samples,\n progress = 0,\n onSeek,\n}: {\n samples: number[]\n progress?: number\n onSeek?: (progress: number) => void\n}) {\n const STRIDE = 4 // 2px barra + 2px gap\n const MIN_BARS = 20\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [barCount, setBarCount] = React.useState<number>(MIN_BARS)\n\n React.useEffect(() => {\n const el = containerRef.current\n if (!el) return\n const updateBarCount = (width: number) => {\n const count = Math.max(MIN_BARS, Math.floor(width / STRIDE))\n setBarCount(count)\n }\n updateBarCount(el.clientWidth)\n const ro = new ResizeObserver((entries) => {\n updateBarCount(entries[0]?.contentRect.width ?? 0)\n })\n ro.observe(el)\n return () => ro.disconnect()\n }, [])\n\n // Agrega samples acumulados em barCount barras + normaliza para 0-1 (relativo ao pico)\n const bars = React.useMemo(() => {\n const aggregated = aggregateSamples(samples, barCount)\n const maxPeak = Math.max(...aggregated, 0.01)\n return aggregated.map((p) => p / maxPeak)\n }, [samples, barCount])\n\n const isDraggingRef = React.useRef(false)\n\n const seekFromClientX = React.useCallback(\n (clientX: number) => {\n const el = containerRef.current\n if (!el || !onSeek) return\n const rect = el.getBoundingClientRect()\n const x = clientX - rect.left\n const newProgress = Math.max(0, Math.min(x / rect.width, 1))\n onSeek(newProgress)\n },\n [onSeek]\n )\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!onSeek) return\n isDraggingRef.current = true\n e.currentTarget.setPointerCapture(e.pointerId)\n seekFromClientX(e.clientX)\n }\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return\n seekFromClientX(e.clientX)\n }\n const handlePointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return\n isDraggingRef.current = false\n e.currentTarget.releasePointerCapture(e.pointerId)\n }\n\n // Largura natural do layout das barras (px), usada para posicionar o dot em pixels\n const barsLayoutWidth = bars.length * STRIDE - 2\n\n return (\n <div\n ref={containerRef}\n className={cn(\n \"flex-1 relative h-8 min-w-0 overflow-hidden select-none\",\n onSeek && \"touch-none cursor-pointer\"\n )}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n role={onSeek ? \"slider\" : undefined}\n aria-label={onSeek ? \"Posicao do audio\" : undefined}\n aria-valuemin={onSeek ? 0 : undefined}\n aria-valuemax={onSeek ? 100 : undefined}\n aria-valuenow={onSeek ? Math.round(progress * 100) : undefined}\n >\n <div className=\"absolute inset-y-0 left-0 flex items-center gap-[2px]\">\n {bars.map((amp, i) => {\n const isPlayed = i / bars.length <= progress\n const height = Math.max(2, Math.round(amp * 32))\n return (\n <div\n key={i}\n className={cn(\n \"w-[2px] shrink-0 rounded-full\",\n isPlayed ? \"bg-neutral-foreground\" : \"bg-neutral-ring\"\n )}\n style={{ height: `${height}px` }}\n />\n )\n })}\n </div>\n {progress > 0 && (\n <div\n className=\"absolute top-1/2 z-10 -translate-y-1/2 -translate-x-1/2 size-3 rounded-full bg-[#098A5E] shadow-md pointer-events-none\"\n style={{ left: `${progress * barsLayoutWidth}px` }}\n aria-hidden=\"true\"\n />\n )}\n </div>\n )\n}\n\n/* ─── Press-to-record constants ───────────────────────────────── */\n\nconst LOCK_THRESHOLD = 120 // px arrastados pra cima → trava em modo hands-free\nconst CANCEL_THRESHOLD_RATIO = 0.65 // % da largura do MessageBar\nconst CANCEL_THRESHOLD_MIN = 140 // floor (telas pequenas — iPhone SE)\nconst CANCEL_THRESHOLD_MAX = 220 // ceiling (telas grandes — nao precisa atravessar a tela toda)\nconst MIN_DURATION = 1000 // ms — release antes disso cancela\n\n/** Calcula o threshold de cancel baseado na largura do container do MessageBar.\n * Sempre proporcional, com clamps min/max pra funcionar bem em telas pequenas (iPhone SE)\n * sem ficar trivialmente facil em telas grandes. */\nfunction computeCancelThreshold(containerWidth: number): number {\n return Math.min(\n CANCEL_THRESHOLD_MAX,\n Math.max(CANCEL_THRESHOLD_MIN, containerWidth * CANCEL_THRESHOLD_RATIO)\n )\n}\n\n/** PressedRecordingOverlay — UI exibida enquanto o usuario mantem o mic pressionado.\n * Inspirado no comportamento de gravacao de audio do WhatsApp.\n *\n * - Pill esquerda: live dot + timer + \"Deslize para cancelar\"\n * - Mic vermelho 64×64 (acompanha o cursor via translate clamped)\n * - Pill flutuante ACIMA do mic com lock + chevron up (indica \"deslize pra travar\")\n *\n * Variants:\n * - `default`: layout horizontal (cancel pill esquerda + mic direita)\n * - `audio-only`: layout horizontal centralizado (cancel pill curta + mic + timer pill) */\nfunction PressedRecordingOverlay({\n variant,\n duration,\n deltaX,\n deltaY,\n lockThreshold,\n cancelThreshold,\n isWarning,\n secondsLeft,\n secondsLeftLabel,\n}: {\n variant: \"default\" | \"audio-only\"\n duration: number\n deltaX: number\n deltaY: number\n lockThreshold: number\n cancelThreshold: number\n isWarning: boolean\n secondsLeft: number\n secondsLeftLabel: (s: number) => string\n}) {\n const aboutToLock = deltaY <= -lockThreshold\n const aboutToCancel = deltaX <= -cancelThreshold\n // Clamp: so move pra cima/esquerda (delta negativo); ignora positivos\n const clampedX = Math.min(0, deltaX)\n const clampedY = Math.min(0, deltaY)\n // Restringe a UM EIXO POR VEZ — sem movimento diagonal.\n // Detecta direcao dominante (maior magnitude) e zera o outro eixo.\n const absX = Math.abs(clampedX)\n const absY = Math.abs(clampedY)\n const micTranslateX = absX >= absY ? clampedX : 0\n const micTranslateY = absY > absX ? clampedY : 0\n\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"recording-pressed\"\n className={cn(\n \"flex items-center gap-2 p-2 sm:gap-3 sm:p-0 touch-none select-none\",\n variant === \"audio-only\" && \"justify-center\"\n )}\n >\n {/* Layout: cancel-pill + mic (default) | cancel-pill + mic + timer-pill (audio-only) */}\n {variant === \"audio-only\" ? (\n <div className=\"relative flex items-center gap-2\">\n {/* Cancel pill (compact) */}\n <div\n className={cn(\n \"flex items-center gap-1 rounded-full bg-muted h-7 px-3 transition-colors\",\n aboutToCancel && \"bg-destructive/10\"\n )}\n >\n <ChevronLeft className=\"size-3 text-muted-foreground\" />\n <span\n className={cn(\n \"text-xs\",\n aboutToCancel ? \"text-destructive font-medium\" : \"text-muted-foreground\"\n )}\n >\n Cancelar\n </span>\n </div>\n\n {/* Mic + lock pill (anchor) */}\n <div className=\"relative\">\n {/* Lock pill ACIMA do mic */}\n <div\n className={cn(\n \"absolute left-1/2 -translate-x-1/2 bottom-full mb-2 flex flex-col items-center gap-3 rounded-t-full bg-muted h-20 w-8 py-3 transition-transform\",\n aboutToLock && \"scale-125 ring-2 ring-[#0EA460]\"\n )}\n aria-hidden=\"true\"\n >\n <Lock className={cn(\"size-3\", aboutToLock ? \"text-[#0EA460]\" : \"text-muted-foreground\")} />\n <ChevronUp className=\"size-3 text-muted-foreground animate-bounce\" />\n </div>\n\n <MicButton\n variant=\"large\"\n pressed\n ariaLabel=\"Gravando — arraste para cima para travar, para esquerda para cancelar\"\n className={cn(aboutToCancel && \"animate-shake\")}\n style={\n aboutToCancel\n ? undefined\n : { transform: `translate(${micTranslateX}px, ${micTranslateY}px) scale(1.1)` }\n }\n />\n </div>\n\n {/* Timer pill — colore o texto e o RecordingIndicator quando proximo do limite */}\n <div className=\"flex flex-col items-center gap-0.5\">\n <div className=\"flex items-center gap-1 rounded-full bg-muted h-7 px-3\">\n <RecordingIndicator />\n <span\n className={cn(\n \"text-sm tabular-nums\",\n isWarning ? \"text-destructive font-medium\" : \"text-neutral-foreground\"\n )}\n >\n {formatDuration(duration)}\n </span>\n </div>\n {isWarning && (\n <span\n className=\"text-xs text-destructive tabular-nums\"\n aria-live=\"polite\"\n >\n {secondsLeftLabel(secondsLeft)}\n </span>\n )}\n </div>\n </div>\n ) : (\n // Variant default: cancel pill flex-1 + mic\n <>\n <div\n className={cn(\n \"flex-1 flex items-center justify-between gap-2 rounded-xl bg-muted px-4 py-3 h-14\",\n aboutToCancel && \"bg-destructive/10\"\n )}\n >\n <div className=\"flex flex-col items-start gap-0.5\">\n <div className=\"flex items-center gap-2\">\n <RecordingIndicator />\n <span\n className={cn(\n \"text-sm tabular-nums\",\n isWarning ? \"text-destructive font-medium\" : \"text-neutral-foreground\"\n )}\n >\n {formatDuration(duration)}\n </span>\n </div>\n {isWarning && (\n <span\n className=\"text-xs text-destructive tabular-nums\"\n aria-live=\"polite\"\n >\n {secondsLeftLabel(secondsLeft)}\n </span>\n )}\n </div>\n <div\n className={cn(\n \"flex items-center gap-1 text-xs\",\n aboutToCancel ? \"text-destructive font-medium\" : \"text-muted-foreground\"\n )}\n >\n <ChevronLeft className=\"size-3\" />\n <span>Deslize para cancelar</span>\n </div>\n </div>\n\n {/* Mic + lock pill */}\n <div className=\"relative\">\n <div\n className={cn(\n \"absolute left-1/2 -translate-x-1/2 bottom-full mb-2 flex flex-col items-center gap-3 rounded-t-full bg-muted h-20 w-8 py-3 transition-transform\",\n aboutToLock && \"scale-125 ring-2 ring-[#0EA460]\"\n )}\n aria-hidden=\"true\"\n >\n <Lock className={cn(\"size-3\", aboutToLock ? \"text-[#0EA460]\" : \"text-muted-foreground\")} />\n <ChevronUp className=\"size-3 text-muted-foreground animate-bounce\" />\n </div>\n\n <MicButton\n variant=\"large\"\n pressed\n ariaLabel=\"Gravando — arraste para cima para travar, para esquerda para cancelar\"\n className={cn(aboutToCancel && \"animate-shake\")}\n style={\n aboutToCancel\n ? undefined\n : { transform: `translate(${micTranslateX}px, ${micTranslateY}px) scale(1.1)` }\n }\n />\n </div>\n </>\n )}\n </div>\n )\n}\n\n/* ─── Component principal ─────────────────────────────────────── */\n\nfunction MessageBar({\n state = \"default\",\n value = \"\",\n onChange,\n onSendText,\n onStartRecording,\n onPauseRecording,\n onResumeRecording,\n onCancelRecording,\n onSendAudio,\n onTogglePlay,\n recordingDuration = 0,\n isPlaying = false,\n recordingStream,\n playbackProgress = 0,\n onSeekPlayback,\n placeholder = \"Digite sua mensagem...\",\n maxRecordingDuration,\n warnAtSecondsLeft = DEFAULT_WARN_AT_SECONDS_LEFT,\n onMaxDurationReached,\n secondsLeftLabel = DEFAULT_SECONDS_LEFT_LABEL,\n className,\n ...props\n}: MessageBarProps) {\n /* ─── Limite de duracao da gravacao ─── */\n const { isWarning: isDurationWarning, secondsLeft: durationSecondsLeft } =\n getWarningState(recordingDuration, maxRecordingDuration, warnAtSecondsLeft)\n\n // Dispara onMaxDurationReached uma unica vez quando o limite e atingido.\n // Reset ao sair do estado recording (proxima gravacao reativa o disparo).\n const maxReachedRef = React.useRef(false)\n React.useEffect(() => {\n if (!maxRecordingDuration || maxReachedRef.current) return\n if (recordingDuration >= maxRecordingDuration) {\n maxReachedRef.current = true\n onMaxDurationReached?.()\n }\n }, [recordingDuration, maxRecordingDuration, onMaxDurationReached])\n React.useEffect(() => {\n if (state !== \"recording\") maxReachedRef.current = false\n }, [state])\n // Acumula samples brutos do microfone durante recording — reaproveitado em paused via RecordedWaveform\n const samplesRef = React.useRef<number[]>([])\n\n // Reset dos samples quando inicia nova gravacao (transicao para recording a partir de outros estados)\n // Nao zera ao voltar de paused → recording (continua a mesma gravacao)\n const prevStateRef = React.useRef<MessageBarState>(state)\n // Lembra o ultimo base state (default/audio-only) pra escolher variant do overlay pressed\n const lastBaseStateRef = React.useRef<\"default\" | \"audio-only\">(\n state === \"audio-only\" ? \"audio-only\" : \"default\"\n )\n // De onde veio o `requesting` (paused = retomando gravacao existente; senao = gravacao nova)\n const requestingFromRef = React.useRef<MessageBarState | null>(null)\n React.useEffect(() => {\n const prev = prevStateRef.current\n if (state === \"requesting\" && prev !== \"requesting\") {\n requestingFromRef.current = prev\n }\n if (state === \"recording\" && prev !== \"paused\" && prev !== \"recording\") {\n // requesting → recording so zera se a gravacao e nova (nao veio de paused)\n const resuming = prev === \"requesting\" && requestingFromRef.current === \"paused\"\n if (!resuming) samplesRef.current = []\n }\n if (state === \"default\" || state === \"audio-only\") {\n lastBaseStateRef.current = state\n }\n prevStateRef.current = state\n }, [state])\n\n /* ─── Press-to-record (WhatsApp-like, touch-only) ───────────── */\n const [isPressed, setIsPressed] = React.useState(false)\n const [pressDelta, setPressDelta] = React.useState({ x: 0, y: 0 })\n // Cancel threshold dinamico — calculado baseado na largura do container no pointerdown\n const [pressCancelThreshold, setPressCancelThreshold] = React.useState(CANCEL_THRESHOLD_MAX)\n const pressDeltaRef = React.useRef({ x: 0, y: 0 })\n const pressCancelThresholdRef = React.useRef(CANCEL_THRESHOLD_MAX)\n const pressInfoRef = React.useRef({ startX: 0, startY: 0, startTime: 0, locked: false })\n // Ref sincronizada com isPressed — usada por listener permanente de touchmove\n // (instalado no mount, mas so preventDefault quando esta pressionado)\n const isPressedRef = React.useRef(false)\n // Refs pros callbacks — handlers do window leem a versao mais recente sem precisar reinstalar listeners\n const callbacksRef = React.useRef({ onStartRecording, onCancelRecording, onSendAudio })\n React.useEffect(() => {\n callbacksRef.current = { onStartRecording, onCancelRecording, onSendAudio }\n })\n\n const updateDelta = (dx: number, dy: number) => {\n pressDeltaRef.current = { x: dx, y: dy }\n setPressDelta({ x: dx, y: dy })\n }\n\n // Pedido de microfone falhou durante press-to-record (touch): requesting → base state.\n // Solta o press pra que o release nao dispare onSendAudio/onCancelRecording de uma\n // gravacao que nunca existiu.\n const prevStateForPressRef = React.useRef<MessageBarState>(state)\n React.useEffect(() => {\n const prev = prevStateForPressRef.current\n prevStateForPressRef.current = state\n const backToBase = state === \"default\" || state === \"audio-only\" || state === \"disabled\"\n if (prev === \"requesting\" && backToBase && isPressedRef.current) {\n setIsPressed(false)\n updateDelta(0, 0)\n }\n }, [state])\n\n /* Listener PERMANENTE de touchmove com preventDefault — instalado no mount.\n * Por que permanente: se instalar so quando isPressed=true (dentro do useEffect transient),\n * o iOS ja decidiu que o gesto e scroll/swipe ANTES do listener montar.\n * Solucao: listener sempre presente, com guard via isPressedRef.current. */\n React.useEffect(() => {\n const onTouchMove = (e: TouchEvent) => {\n if (isPressedRef.current) {\n e.preventDefault()\n }\n }\n window.addEventListener(\"touchmove\", onTouchMove, { passive: false })\n return () => window.removeEventListener(\"touchmove\", onTouchMove)\n }, [])\n\n const triggerHaptic = (ms = 50) => {\n if (typeof navigator !== \"undefined\" && typeof navigator.vibrate === \"function\") {\n try {\n navigator.vibrate(ms)\n } catch {\n /* ignore — alguns browsers podem rejeitar fora de user gesture */\n }\n }\n }\n\n // Listeners no window (sobrevivem a troca de DOM quando o overlay aparece e o MicButton original desmonta)\n // Sincroniza isPressedRef com isPressed pra o listener permanente de touchmove ler\n React.useEffect(() => {\n isPressedRef.current = isPressed\n }, [isPressed])\n\n // Listeners de pointer (transient): so existem durante o press flow\n React.useEffect(() => {\n if (!isPressed) return\n\n // touch-action: none em html + body bloqueia gestos nativos (backup, ja temos o\n // touchmove permanente com preventDefault)\n const prevHtmlTouchAction = document.documentElement.style.touchAction\n const prevBodyTouchAction = document.body.style.touchAction\n document.documentElement.style.touchAction = \"none\"\n document.body.style.touchAction = \"none\"\n\n const onMove = (e: PointerEvent) => {\n if (pressInfoRef.current.locked) return\n const { startX, startY } = pressInfoRef.current\n const dx = e.clientX - startX\n const dy = e.clientY - startY\n updateDelta(dx, dy)\n // Atinge lock threshold → trava em modo hands-free\n if (dy <= -LOCK_THRESHOLD) {\n pressInfoRef.current.locked = true\n triggerHaptic(50)\n setIsPressed(false)\n updateDelta(0, 0)\n }\n }\n\n const onEnd = () => {\n if (pressInfoRef.current.locked) return\n const { startTime } = pressInfoRef.current\n const elapsed = Date.now() - startTime\n const { x: dx } = pressDeltaRef.current\n\n setIsPressed(false)\n updateDelta(0, 0)\n\n if (dx <= -pressCancelThresholdRef.current || elapsed < MIN_DURATION) {\n triggerHaptic(50)\n callbacksRef.current.onCancelRecording?.()\n return\n }\n callbacksRef.current.onSendAudio?.()\n }\n\n window.addEventListener(\"pointermove\", onMove)\n window.addEventListener(\"pointerup\", onEnd)\n // pointercancel tratado como release (usa delta atual pra decidir cancel/send)\n window.addEventListener(\"pointercancel\", onEnd)\n return () => {\n window.removeEventListener(\"pointermove\", onMove)\n window.removeEventListener(\"pointerup\", onEnd)\n window.removeEventListener(\"pointercancel\", onEnd)\n document.documentElement.style.touchAction = prevHtmlTouchAction\n document.body.style.touchAction = prevBodyTouchAction\n }\n }, [isPressed])\n\n const handlePressStart = (e: React.PointerEvent<HTMLButtonElement>) => {\n // Desktop (mouse/pen): comportamento antigo de click — dispara onStartRecording, sai do flow press\n if (e.pointerType !== \"touch\") {\n onStartRecording?.()\n return\n }\n // Mede a largura do container do MessageBar pra calcular o cancel threshold adaptativo\n const wrapper = e.currentTarget.closest('[data-slot=\"message-bar\"]')\n const containerWidth =\n wrapper instanceof HTMLElement ? wrapper.clientWidth : window.innerWidth\n const threshold = computeCancelThreshold(containerWidth)\n pressCancelThresholdRef.current = threshold\n setPressCancelThreshold(threshold)\n\n pressInfoRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startTime: Date.now(),\n locked: false,\n }\n updateDelta(0, 0)\n setIsPressed(true)\n onStartRecording?.()\n }\n\n const pressHandlers = {\n onPointerDown: handlePressStart,\n }\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey && value.trim()) {\n e.preventDefault()\n onSendText?.(value)\n }\n }\n\n /* ─── State: requesting (aguardando permissao/stream do microfone) ── */\n if (state === \"requesting\") {\n const busyMic = (\n <button\n type=\"button\"\n disabled\n aria-busy=\"true\"\n aria-label=\"Pedindo acesso ao microfone\"\n className=\"shrink-0 inline-flex items-center justify-center size-10 rounded-md bg-primary text-primary-foreground theme-brand opacity-70 cursor-wait\"\n >\n <Spinner size=\"sm\" />\n </button>\n )\n if (lastBaseStateRef.current === \"audio-only\") {\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"requesting\"\n className={cn(\"flex items-center justify-center p-2\", className)}\n {...props}\n >\n {busyMic}\n </div>\n )\n }\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"requesting\"\n className={cn(\"flex items-center gap-2 rounded-2xl bg-muted p-2\", className)}\n {...props}\n >\n <input\n type=\"text\"\n value={value}\n readOnly\n disabled\n placeholder={placeholder}\n className=\"flex-1 min-w-0 bg-transparent px-3 py-2 text-base text-neutral-foreground placeholder:text-neutral-muted-foreground outline-none disabled:cursor-wait disabled:opacity-50\"\n aria-label=\"Mensagem\"\n />\n {busyMic}\n </div>\n )\n }\n\n /* ─── State: audio-only (so botao mic centralizado) ─────────── */\n if (state === \"audio-only\") {\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"audio-only\"\n className={cn(\"flex items-center justify-center p-2\", className)}\n {...props}\n >\n <MicButton {...pressHandlers} />\n </div>\n )\n }\n\n /* ─── State: recording + pressed (overlay WhatsApp-like) ────── */\n if (state === \"recording\" && isPressed) {\n return (\n <PressedRecordingOverlay\n variant={lastBaseStateRef.current}\n duration={recordingDuration}\n deltaX={pressDelta.x}\n deltaY={pressDelta.y}\n lockThreshold={LOCK_THRESHOLD}\n cancelThreshold={pressCancelThreshold}\n isWarning={isDurationWarning}\n secondsLeft={durationSecondsLeft}\n secondsLeftLabel={secondsLeftLabel}\n />\n )\n }\n\n /* ─── State: recording (hands-free, apos lock ou click no mic) ─ */\n if (state === \"recording\") {\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"recording\"\n className={cn(\n \"flex items-center gap-2 p-2 sm:gap-3 sm:p-0\",\n className\n )}\n {...props}\n >\n {/* Mobile: 2-row layout */}\n <div className=\"flex flex-col gap-2 w-full sm:contents\">\n {/* Top: trash + recording info + waveform (mobile) / inline (desktop) */}\n <div className=\"flex items-center gap-2 sm:contents\">\n {/* Trash — only inline at desktop, mobile shows in bottom row */}\n <div className=\"hidden sm:contents\">\n <IconButton\n onClick={onCancelRecording}\n icon={Trash2}\n ariaLabel=\"Cancelar gravacao\"\n />\n </div>\n\n {/* Recording bar — bg-muted container.\n Quando proximo do limite, o timer vira destructive + label \"Xs restantes\"\n aparece abaixo (aria-live polite anuncia pra screen readers). */}\n <div className=\"flex items-center gap-3 flex-1 rounded-2xl bg-muted px-4 py-3\">\n <RecordingIndicator />\n <div className=\"flex flex-col items-start gap-0.5 shrink-0\">\n <span\n className={cn(\n \"text-sm tabular-nums\",\n isDurationWarning ? \"text-destructive font-medium\" : \"text-neutral-foreground\"\n )}\n >\n {formatDuration(recordingDuration)}\n </span>\n {isDurationWarning && (\n <span\n className=\"text-xs text-destructive tabular-nums whitespace-nowrap\"\n aria-live=\"polite\"\n >\n {secondsLeftLabel(durationSecondsLeft)}\n </span>\n )}\n </div>\n <LiveWaveform stream={recordingStream} samplesRef={samplesRef} />\n {/* Pause inside the bar — only desktop */}\n <div className=\"hidden sm:contents\">\n <button\n type=\"button\"\n onClick={onPauseRecording}\n className=\"shrink-0 inline-flex items-center justify-center text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label=\"Pausar gravacao\"\n >\n <Pause className=\"size-5\" fill=\"currentColor\" strokeWidth={0} />\n </button>\n </div>\n </div>\n\n {/* Send — only inline at desktop */}\n <div className=\"hidden sm:contents\">\n <SendButton onClick={onSendAudio} ariaLabel=\"Enviar audio\" />\n </div>\n </div>\n\n {/* Bottom row — mobile only */}\n <div className=\"flex items-center justify-between sm:hidden\">\n <IconButton\n onClick={onCancelRecording}\n icon={Trash2}\n ariaLabel=\"Cancelar gravacao\"\n />\n <button\n type=\"button\"\n onClick={onPauseRecording}\n className=\"shrink-0 inline-flex items-center justify-center size-10 text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label=\"Pausar gravacao\"\n >\n <Pause className=\"size-5\" fill=\"currentColor\" strokeWidth={0} />\n </button>\n <SendButton onClick={onSendAudio} ariaLabel=\"Enviar audio\" />\n </div>\n </div>\n </div>\n )\n }\n\n /* ─── State: paused (com audio gravado) ──────────────────────── */\n if (state === \"paused\") {\n return (\n <div\n data-slot=\"message-bar\"\n data-state=\"paused\"\n className={cn(\n \"flex items-center gap-2 p-2 sm:gap-3 sm:p-0\",\n className\n )}\n {...props}\n >\n <div className=\"flex flex-col gap-2 w-full sm:contents\">\n <div className=\"flex items-center gap-2 sm:contents\">\n <div className=\"hidden sm:contents\">\n <IconButton\n onClick={onCancelRecording}\n icon={Trash2}\n ariaLabel=\"Cancelar gravacao\"\n />\n </div>\n\n <div className=\"flex items-center gap-3 flex-1 rounded-2xl bg-muted px-4 py-3\">\n <button\n type=\"button\"\n onClick={onTogglePlay}\n className=\"shrink-0 inline-flex items-center justify-center text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label={isPlaying ? \"Pausar\" : \"Reproduzir\"}\n >\n {isPlaying ? (\n <Pause className=\"size-5\" fill=\"currentColor\" strokeWidth={0} />\n ) : (\n <Play className=\"size-5\" fill=\"currentColor\" strokeWidth={0} />\n )}\n </button>\n <span className=\"shrink-0 text-sm text-neutral-foreground tabular-nums\">\n {formatDuration(recordingDuration)}\n </span>\n <RecordedWaveform\n samples={samplesRef.current}\n progress={playbackProgress}\n onSeek={onSeekPlayback}\n />\n {/* Mic inline — only desktop */}\n <div className=\"hidden sm:contents\">\n <button\n type=\"button\"\n onClick={onResumeRecording}\n className=\"shrink-0 inline-flex items-center justify-center text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label=\"Continuar gravacao\"\n >\n <Mic className=\"size-5\" />\n </button>\n </div>\n </div>\n\n <div className=\"hidden sm:contents\">\n <SendButton onClick={onSendAudio} ariaLabel=\"Enviar audio\" />\n </div>\n </div>\n\n {/* Bottom row — mobile only */}\n <div className=\"flex items-center justify-between sm:hidden\">\n <IconButton\n onClick={onCancelRecording}\n icon={Trash2}\n ariaLabel=\"Cancelar gravacao\"\n />\n <button\n type=\"button\"\n onClick={onResumeRecording}\n className=\"shrink-0 inline-flex items-center justify-center size-10 text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label=\"Continuar gravacao\"\n >\n <Mic className=\"size-5\" />\n </button>\n <SendButton onClick={onSendAudio} ariaLabel=\"Enviar audio\" />\n </div>\n </div>\n </div>\n )\n }\n\n /* ─── States: default | active | disabled (input + button) ──── */\n const isDisabled = state === \"disabled\"\n const isActive = state === \"active\" || (state === \"default\" && value.trim().length > 0)\n\n return (\n <div\n data-slot=\"message-bar\"\n data-state={state}\n className={cn(\n \"flex items-center gap-2 rounded-2xl bg-muted p-2\",\n className\n )}\n {...props}\n >\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange?.(e.target.value)}\n onKeyDown={handleKeyDown}\n disabled={isDisabled}\n placeholder={placeholder}\n className={cn(\n \"flex-1 min-w-0 bg-transparent px-3 py-2 text-base text-neutral-foreground placeholder:text-neutral-muted-foreground outline-none\",\n \"disabled:cursor-not-allowed disabled:opacity-50\"\n )}\n aria-label=\"Mensagem\"\n />\n {isActive ? (\n <SendButton\n onClick={() => value.trim() && onSendText?.(value)}\n disabled={!value.trim()}\n />\n ) : (\n <MicButton {...pressHandlers} />\n )}\n </div>\n )\n}\n\nexport { MessageBar }\n"]}
@@ -56,5 +56,5 @@ function Badge(_a) {
56
56
  }
57
57
 
58
58
  export { Badge, badgeVariants };
59
- //# sourceMappingURL=chunk-32NHCUEZ.js.map
60
- //# sourceMappingURL=chunk-32NHCUEZ.js.map
59
+ //# sourceMappingURL=chunk-C6VTOLNM.js.map
60
+ //# sourceMappingURL=chunk-C6VTOLNM.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../core/src/components/ui/badge.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,mRAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6DAAA;AAAA,QACF,SAAA,EACE,mEAAA;AAAA,QACF,WAAA,EACE,wJAAA;AAAA,QACF,OAAA,EACE,sFAAA;AAAA,QACF,KAAA,EACE,wDAAA;AAAA,QACF,IAAA,EACE,sDAAA;AAAA,QACF,KAAA,EACE,gCAAA;AAAA,QACF,OAAA,EACE,mEAAA;AAAA,QACF,QAAA,EACE,iCAAA;AAAA,QACF,oBAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,6DAAA;AAAA,QACT,EAAA,EAAI,gEAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAQA,SAAS,MAAM,EAAA,EAMA;AANA,EAAA,IAAA,EAAA,GAAA,EAAA,EACb;AAAA,IAAA,SAAA;AAAA,IACA,OAAA,GAAU,SAAA;AAAA,IACV,IAAA,GAAO,SAAA;AAAA,IACP,OAAA,GAAU;AAAA,GAvDZ,GAmDe,EAAA,EAKV,KAAA,GAAA,SAAA,CALU,EAAA,EAKV;AAAA,IAJH,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,MAAA;AAEnC,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,OAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,GAAG,aAAA,CAAc,EAAE,SAAS,IAAA,EAAM,GAAG,SAAS;AAAA,KAAA,EACrD,KAAA;AAAA,GACN;AAEJ","file":"chunk-32NHCUEZ.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@core/lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden border border-transparent whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&>svg]:pointer-events-none [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90\",\n outline:\n \"border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n ghost:\n \"[a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n link:\n \"text-primary underline-offset-4 [a&]:hover:underline\",\n muted:\n \"bg-muted text-muted-foreground\",\n success:\n \"theme-positive bg-background text-foreground border-foreground/20\",\n progress:\n \"bg-accent text-muted-foreground\",\n \"progress-completed\":\n \"theme-positive bg-accent text-accent-foreground\",\n },\n size: {\n default: \"rounded-full px-2 py-0.5 text-xs font-medium [&>svg]:size-3\",\n sm: \"rounded-md px-1.5 py-px text-[11px] font-medium [&>svg]:size-3\",\n lg: \"rounded-full px-3 py-1 text-sm font-medium [&>svg]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface BadgeProps\n extends React.ComponentProps<\"span\">,\n VariantProps<typeof badgeVariants> {\n asChild?: boolean\n}\n\nfunction Badge({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: BadgeProps) {\n const Comp = asChild ? Slot.Root : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant, size }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n"]}
1
+ {"version":3,"sources":["../../core/src/components/ui/badge.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,mRAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6DAAA;AAAA,QACF,SAAA,EACE,mEAAA;AAAA,QACF,WAAA,EACE,wJAAA;AAAA,QACF,OAAA,EACE,sFAAA;AAAA,QACF,KAAA,EACE,wDAAA;AAAA,QACF,IAAA,EACE,sDAAA;AAAA,QACF,KAAA,EACE,gCAAA;AAAA,QACF,OAAA,EACE,mEAAA;AAAA,QACF,QAAA,EACE,iCAAA;AAAA,QACF,oBAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,6DAAA;AAAA,QACT,EAAA,EAAI,gEAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAQA,SAAS,MAAM,EAAA,EAMA;AANA,EAAA,IAAA,EAAA,GAAA,EAAA,EACb;AAAA,IAAA,SAAA;AAAA,IACA,OAAA,GAAU,SAAA;AAAA,IACV,IAAA,GAAO,SAAA;AAAA,IACP,OAAA,GAAU;AAAA,GAvDZ,GAmDe,EAAA,EAKV,KAAA,GAAA,SAAA,CALU,EAAA,EAKV;AAAA,IAJH,WAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,MAAA;AAEnC,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,OAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,GAAG,aAAA,CAAc,EAAE,SAAS,IAAA,EAAM,GAAG,SAAS;AAAA,KAAA,EACrD,KAAA;AAAA,GACN;AAEJ","file":"chunk-C6VTOLNM.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@core/lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden border border-transparent whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&>svg]:pointer-events-none [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90\",\n outline:\n \"border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n ghost:\n \"[a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n link:\n \"text-primary underline-offset-4 [a&]:hover:underline\",\n muted:\n \"bg-muted text-muted-foreground\",\n success:\n \"theme-positive bg-background text-foreground border-foreground/20\",\n progress:\n \"bg-accent text-muted-foreground\",\n \"progress-completed\":\n \"theme-positive bg-accent text-accent-foreground\",\n },\n size: {\n default: \"rounded-full px-2 py-0.5 text-xs font-medium [&>svg]:size-3\",\n sm: \"rounded-md px-1.5 py-px text-[11px] font-medium [&>svg]:size-3\",\n lg: \"rounded-full px-3 py-1 text-sm font-medium [&>svg]:size-4\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface BadgeProps\n extends React.ComponentProps<\"span\">,\n VariantProps<typeof badgeVariants> {\n asChild?: boolean\n}\n\nfunction Badge({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: BadgeProps) {\n const Comp = asChild ? Slot.Root : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant, size }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n"]}
@@ -1,5 +1,5 @@
1
1
  import { CycleIcon } from './chunk-US5LXJTO.js';
2
- import { Button } from './chunk-LALM2LHM.js';
2
+ import { Button } from './chunk-W62WANUP.js';
3
3
  import { Textarea } from './chunk-KPE5CRIS.js';
4
4
  import { cn } from './chunk-W4KJCBMW.js';
5
5
  import { __objRest, __spreadProps, __spreadValues } from './chunk-2NMEKWO5.js';
@@ -253,5 +253,5 @@ function LikeDislike(_a) {
253
253
  }
254
254
 
255
255
  export { LikeDislike, likeDislikeVariants };
256
- //# sourceMappingURL=chunk-RPU3FY62.js.map
257
- //# sourceMappingURL=chunk-RPU3FY62.js.map
256
+ //# sourceMappingURL=chunk-CLL76ZXJ.js.map
257
+ //# sourceMappingURL=chunk-CLL76ZXJ.js.map