@vector-business-services/cristal-ds-web 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, InputHTMLAttributes, HTMLAttributes, ButtonHTMLAttributes, CSSProperties, SyntheticEvent, MouseEvent, RefObject } from 'react';
2
+ import { ReactNode, InputHTMLAttributes, HTMLAttributes, ButtonHTMLAttributes, CSSProperties, RefObject, SyntheticEvent, MouseEvent } from 'react';
3
3
  import { AutoCompleteProps as AutoCompleteProps$1 } from 'primereact/autocomplete';
4
4
  import { CheckboxChangeEvent } from 'primereact/checkbox';
5
5
  import { ChipRemoveEvent } from 'primereact/chip';
@@ -271,6 +271,32 @@ interface DrawerProps {
271
271
  }
272
272
  declare function Drawer({ visible, onHide, title, subtitle, side, behavior, size, modal, onBack, backLabel, closeLabel, footer, children, id, className, }: DrawerProps): react.JSX.Element;
273
273
 
274
+ /** Type no Figma: Plain (rótulo curto, uma linha) e Rich (texto de até 300px, quebra linha). */
275
+ type TooltipType = 'plain' | 'rich';
276
+ type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
277
+ interface TooltipProps {
278
+ /** Elemento que mostra o tooltip: ref, elemento ou seletor CSS. */
279
+ target: RefObject<HTMLElement | null> | HTMLElement | string;
280
+ /** Texto do tooltip (Label no Plain, Text no Rich). */
281
+ content: ReactNode;
282
+ type?: TooltipType;
283
+ /** Lado do alvo. O Prime inverte o lado se faltar espaço na tela. */
284
+ position?: TooltipPosition;
285
+ /** O que abre o tooltip; o padrão abre no hover e no foco do teclado. */
286
+ event?: 'hover' | 'focus' | 'both';
287
+ showDelay?: number;
288
+ hideDelay?: number;
289
+ disabled?: boolean;
290
+ /**
291
+ * Liga o texto ao alvo como descrição (aria-describedby). Padrão: true. Use false quando o texto
292
+ * já é o nome do alvo (como no IconButton), para o leitor de tela não ler duas vezes.
293
+ */
294
+ describe?: boolean;
295
+ id?: string;
296
+ className?: string;
297
+ }
298
+ declare function Tooltip({ target, content, type, position, event, showDelay, hideDelay, disabled, describe, id, className, }: TooltipProps): react.JSX.Element;
299
+
274
300
  /**
275
301
  * Hierarchy no Figma: Primary (Filled), Secondary (Tonal), Tertiary (Outlined) e Other (Icon),
276
302
  * que aqui é `ghost`: só o ícone, com fundo no hover.
@@ -285,6 +311,13 @@ interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>,
285
311
  icon: ReactNode;
286
312
  /** Obrigatório: o botão não tem texto, então é isso que o leitor de tela anuncia. */
287
313
  'aria-label': string;
314
+ /**
315
+ * Tooltip do botão. Padrão: o próprio `aria-label`, para quem vê saber o que o ícone faz. Um
316
+ * texto diferente vira também a descrição do botão; `false` tira o tooltip.
317
+ */
318
+ tooltip?: ReactNode | false;
319
+ /** Lado do tooltip. Padrão: bottom. */
320
+ tooltipPosition?: TooltipPosition;
288
321
  }
289
322
  declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
290
323
 
@@ -554,9 +587,17 @@ interface PageHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
554
587
  segmentControl?: ReactNode;
555
588
  /** Botões das ferramentas (Show Buttons no Figma), 8px entre eles. */
556
589
  actions?: ReactNode;
557
- /** Mostra o botão de expandir, o último das ferramentas. */
558
- onExpand?: () => void;
590
+ /**
591
+ * Mostra o botão de expandir, o último das ferramentas. Recebe o novo estado: true ao expandir,
592
+ * false ao recolher.
593
+ */
594
+ onExpand?: (expanded: boolean) => void;
595
+ /** Expandido (controlado). Sem ele, o PageHeader alterna sozinho a cada clique. */
596
+ expanded?: boolean;
597
+ /** Nome do botão recolhido (ArrowsOutSimple). */
559
598
  expandLabel?: string;
599
+ /** Nome do botão expandido (ArrowsInSimple). */
600
+ collapseLabel?: string;
560
601
  /** Abas abaixo do título (Show Tabs no Figma). */
561
602
  tabs?: PageHeaderTab[];
562
603
  /** Aba ativa (controlado). Sem ela, o PageHeader controla sozinho. */
@@ -791,26 +832,5 @@ interface ToastProps {
791
832
  }
792
833
  declare const Toast: react.ForwardRefExoticComponent<ToastProps & react.RefAttributes<ToastHandle>>;
793
834
 
794
- /** Type no Figma: Plain (rótulo curto, uma linha) e Rich (texto de até 300px, quebra linha). */
795
- type TooltipType = 'plain' | 'rich';
796
- type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
797
- interface TooltipProps {
798
- /** Elemento que mostra o tooltip: ref, elemento ou seletor CSS. */
799
- target: RefObject<HTMLElement | null> | HTMLElement | string;
800
- /** Texto do tooltip (Label no Plain, Text no Rich). */
801
- content: ReactNode;
802
- type?: TooltipType;
803
- /** Lado do alvo. O Prime inverte o lado se faltar espaço na tela. */
804
- position?: TooltipPosition;
805
- /** O que abre o tooltip; o padrão abre no hover e no foco do teclado. */
806
- event?: 'hover' | 'focus' | 'both';
807
- showDelay?: number;
808
- hideDelay?: number;
809
- disabled?: boolean;
810
- id?: string;
811
- className?: string;
812
- }
813
- declare function Tooltip({ target, content, type, position, event, showDelay, hideDelay, disabled, id, className, }: TooltipProps): react.JSX.Element;
814
-
815
835
  export { Accordion, AccordionTab, AutoComplete, Badge, Button, Card, Chart, Checkbox, Chip, Divider, Drawer, IconButton, Input, Menu, MenuPrincipal, Menubar, Message, Modal, MultiSelect, PageHeader, Paginator, Panel, Radio, ScrollPanel, SegmentControl, Select, Switch, TabPanel, Tabs, Tag, Toast, Tooltip };
816
836
  export type { AccordionProps, AccordionTabProps, AutoCompleteProps, AutoCompleteSize, AutoCompleteVariant, BadgeProps, BadgeSize, BadgeVariant, ButtonProps, ButtonSize, ButtonVariant, CardPadding, CardProps, ChartAxis, ChartColor, ChartProps, ChartSeries, CheckboxLabelSize, CheckboxPosition, CheckboxProps, ChipProps, ChipSize, ChipVariant, DividerOrientation, DividerProps, DividerVariant, DrawerBehavior, DrawerProps, DrawerSide, DrawerSize, IconButtonProps, IconButtonSize, IconButtonVariant, InputProps, InputSize, InputVariant, MenuDensity, MenuHandle, MenuItem, MenuPrincipalEntry, MenuPrincipalGroup, MenuPrincipalHandle, MenuPrincipalItem, MenuPrincipalProps, MenuProps, MenubarProps, MenubarTool, MenubarUser, MessageProps, MessageType, ModalProps, ModalSize, MultiSelectDensity, MultiSelectProps, MultiSelectSize, MultiSelectVariant, PageHeaderProps, PageHeaderTab, PageHeaderVariant, PaginatorPageChangeEvent, PaginatorProps, PanelProps, RadioLabelSize, RadioProps, ScrollPanelProps, SegmentControlOption, SegmentControlProps, SegmentControlVariant, SelectProps, SelectSize, SelectVariant, SwitchLabelPosition, SwitchProps, SwitchSize, TabPanelProps, TabsProps, TagProps, TagSize, TagVariant, ToastHandle, ToastMessage, ToastPosition, ToastProps, ToastType, TooltipPosition, TooltipProps, TooltipType };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, InputHTMLAttributes, HTMLAttributes, ButtonHTMLAttributes, CSSProperties, SyntheticEvent, MouseEvent, RefObject } from 'react';
2
+ import { ReactNode, InputHTMLAttributes, HTMLAttributes, ButtonHTMLAttributes, CSSProperties, RefObject, SyntheticEvent, MouseEvent } from 'react';
3
3
  import { AutoCompleteProps as AutoCompleteProps$1 } from 'primereact/autocomplete';
4
4
  import { CheckboxChangeEvent } from 'primereact/checkbox';
5
5
  import { ChipRemoveEvent } from 'primereact/chip';
@@ -271,6 +271,32 @@ interface DrawerProps {
271
271
  }
272
272
  declare function Drawer({ visible, onHide, title, subtitle, side, behavior, size, modal, onBack, backLabel, closeLabel, footer, children, id, className, }: DrawerProps): react.JSX.Element;
273
273
 
274
+ /** Type no Figma: Plain (rótulo curto, uma linha) e Rich (texto de até 300px, quebra linha). */
275
+ type TooltipType = 'plain' | 'rich';
276
+ type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
277
+ interface TooltipProps {
278
+ /** Elemento que mostra o tooltip: ref, elemento ou seletor CSS. */
279
+ target: RefObject<HTMLElement | null> | HTMLElement | string;
280
+ /** Texto do tooltip (Label no Plain, Text no Rich). */
281
+ content: ReactNode;
282
+ type?: TooltipType;
283
+ /** Lado do alvo. O Prime inverte o lado se faltar espaço na tela. */
284
+ position?: TooltipPosition;
285
+ /** O que abre o tooltip; o padrão abre no hover e no foco do teclado. */
286
+ event?: 'hover' | 'focus' | 'both';
287
+ showDelay?: number;
288
+ hideDelay?: number;
289
+ disabled?: boolean;
290
+ /**
291
+ * Liga o texto ao alvo como descrição (aria-describedby). Padrão: true. Use false quando o texto
292
+ * já é o nome do alvo (como no IconButton), para o leitor de tela não ler duas vezes.
293
+ */
294
+ describe?: boolean;
295
+ id?: string;
296
+ className?: string;
297
+ }
298
+ declare function Tooltip({ target, content, type, position, event, showDelay, hideDelay, disabled, describe, id, className, }: TooltipProps): react.JSX.Element;
299
+
274
300
  /**
275
301
  * Hierarchy no Figma: Primary (Filled), Secondary (Tonal), Tertiary (Outlined) e Other (Icon),
276
302
  * que aqui é `ghost`: só o ícone, com fundo no hover.
@@ -285,6 +311,13 @@ interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>,
285
311
  icon: ReactNode;
286
312
  /** Obrigatório: o botão não tem texto, então é isso que o leitor de tela anuncia. */
287
313
  'aria-label': string;
314
+ /**
315
+ * Tooltip do botão. Padrão: o próprio `aria-label`, para quem vê saber o que o ícone faz. Um
316
+ * texto diferente vira também a descrição do botão; `false` tira o tooltip.
317
+ */
318
+ tooltip?: ReactNode | false;
319
+ /** Lado do tooltip. Padrão: bottom. */
320
+ tooltipPosition?: TooltipPosition;
288
321
  }
289
322
  declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
290
323
 
@@ -554,9 +587,17 @@ interface PageHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
554
587
  segmentControl?: ReactNode;
555
588
  /** Botões das ferramentas (Show Buttons no Figma), 8px entre eles. */
556
589
  actions?: ReactNode;
557
- /** Mostra o botão de expandir, o último das ferramentas. */
558
- onExpand?: () => void;
590
+ /**
591
+ * Mostra o botão de expandir, o último das ferramentas. Recebe o novo estado: true ao expandir,
592
+ * false ao recolher.
593
+ */
594
+ onExpand?: (expanded: boolean) => void;
595
+ /** Expandido (controlado). Sem ele, o PageHeader alterna sozinho a cada clique. */
596
+ expanded?: boolean;
597
+ /** Nome do botão recolhido (ArrowsOutSimple). */
559
598
  expandLabel?: string;
599
+ /** Nome do botão expandido (ArrowsInSimple). */
600
+ collapseLabel?: string;
560
601
  /** Abas abaixo do título (Show Tabs no Figma). */
561
602
  tabs?: PageHeaderTab[];
562
603
  /** Aba ativa (controlado). Sem ela, o PageHeader controla sozinho. */
@@ -791,26 +832,5 @@ interface ToastProps {
791
832
  }
792
833
  declare const Toast: react.ForwardRefExoticComponent<ToastProps & react.RefAttributes<ToastHandle>>;
793
834
 
794
- /** Type no Figma: Plain (rótulo curto, uma linha) e Rich (texto de até 300px, quebra linha). */
795
- type TooltipType = 'plain' | 'rich';
796
- type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
797
- interface TooltipProps {
798
- /** Elemento que mostra o tooltip: ref, elemento ou seletor CSS. */
799
- target: RefObject<HTMLElement | null> | HTMLElement | string;
800
- /** Texto do tooltip (Label no Plain, Text no Rich). */
801
- content: ReactNode;
802
- type?: TooltipType;
803
- /** Lado do alvo. O Prime inverte o lado se faltar espaço na tela. */
804
- position?: TooltipPosition;
805
- /** O que abre o tooltip; o padrão abre no hover e no foco do teclado. */
806
- event?: 'hover' | 'focus' | 'both';
807
- showDelay?: number;
808
- hideDelay?: number;
809
- disabled?: boolean;
810
- id?: string;
811
- className?: string;
812
- }
813
- declare function Tooltip({ target, content, type, position, event, showDelay, hideDelay, disabled, id, className, }: TooltipProps): react.JSX.Element;
814
-
815
835
  export { Accordion, AccordionTab, AutoComplete, Badge, Button, Card, Chart, Checkbox, Chip, Divider, Drawer, IconButton, Input, Menu, MenuPrincipal, Menubar, Message, Modal, MultiSelect, PageHeader, Paginator, Panel, Radio, ScrollPanel, SegmentControl, Select, Switch, TabPanel, Tabs, Tag, Toast, Tooltip };
816
836
  export type { AccordionProps, AccordionTabProps, AutoCompleteProps, AutoCompleteSize, AutoCompleteVariant, BadgeProps, BadgeSize, BadgeVariant, ButtonProps, ButtonSize, ButtonVariant, CardPadding, CardProps, ChartAxis, ChartColor, ChartProps, ChartSeries, CheckboxLabelSize, CheckboxPosition, CheckboxProps, ChipProps, ChipSize, ChipVariant, DividerOrientation, DividerProps, DividerVariant, DrawerBehavior, DrawerProps, DrawerSide, DrawerSize, IconButtonProps, IconButtonSize, IconButtonVariant, InputProps, InputSize, InputVariant, MenuDensity, MenuHandle, MenuItem, MenuPrincipalEntry, MenuPrincipalGroup, MenuPrincipalHandle, MenuPrincipalItem, MenuPrincipalProps, MenuProps, MenubarProps, MenubarTool, MenubarUser, MessageProps, MessageType, ModalProps, ModalSize, MultiSelectDensity, MultiSelectProps, MultiSelectSize, MultiSelectVariant, PageHeaderProps, PageHeaderTab, PageHeaderVariant, PaginatorPageChangeEvent, PaginatorProps, PanelProps, RadioLabelSize, RadioProps, ScrollPanelProps, SegmentControlOption, SegmentControlProps, SegmentControlVariant, SelectProps, SelectSize, SelectVariant, SwitchLabelPosition, SwitchProps, SwitchSize, TabPanelProps, TabsProps, TagProps, TagSize, TagVariant, ToastHandle, ToastMessage, ToastPosition, ToastProps, ToastType, TooltipPosition, TooltipProps, TooltipType };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { forwardRef, useRef, useImperativeHandle, useState, Children, isValidElement, useId, useCallback, useEffect, useContext, cloneElement, useLayoutEffect, useMemo } from 'react';
2
2
  import { Accordion as Accordion$1, AccordionTab as AccordionTab$1 } from 'primereact/accordion';
3
- import { WarningCircle, Info, Check, CircleNotch, CaretDown, MagnifyingGlass, ArrowLeft, ArrowsOutSimple, CaretUp, X, List, DribbbleLogo, SealWarning, XCircle, CheckCircle, Warning, CaretDoubleRight, CaretRight, CaretLeft, CaretDoubleLeft, Question } from '@phosphor-icons/react';
3
+ import { WarningCircle, Info, Check, CircleNotch, CaretDown, MagnifyingGlass, ArrowLeft, ArrowsInSimple, ArrowsOutSimple, CaretUp, X, List, DribbbleLogo, SealWarning, XCircle, CheckCircle, Warning, CaretDoubleRight, CaretRight, CaretLeft, CaretDoubleLeft, Question } from '@phosphor-icons/react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { AutoComplete as AutoComplete$1 } from 'primereact/autocomplete';
6
6
  import { Badge as Badge$1 } from 'primereact/badge';
@@ -86,6 +86,23 @@ var Accordion = forwardRef(function Accordion2({ multiple = false, activeIndex,
86
86
  }
87
87
  );
88
88
  });
89
+
90
+ // src/components/popup.ts
91
+ function seguirLado(painel, alvo) {
92
+ if (!(painel instanceof HTMLElement) || !alvo) return;
93
+ const marcar = () => {
94
+ const acima = painel.getBoundingClientRect().top < alvo.getBoundingClientRect().top;
95
+ if (acima) painel.setAttribute("data-cr-lado", "acima");
96
+ else painel.removeAttribute("data-cr-lado");
97
+ };
98
+ marcar();
99
+ new MutationObserver(marcar).observe(painel, { attributes: true, attributeFilter: ["style"] });
100
+ }
101
+ var painelDoCampo = (campo, seletorDoPainel) => {
102
+ const lista = campo?.getAttribute("aria-controls");
103
+ return lista ? document.getElementById(lista)?.closest(seletorDoPainel) : null;
104
+ };
105
+ var aoPosicionar = (onEnter) => ({ onEnter });
89
106
  var AutoComplete = forwardRef(function AutoComplete2({
90
107
  variant = "outline",
91
108
  size = "large",
@@ -138,6 +155,11 @@ var AutoComplete = forwardRef(function AutoComplete2({
138
155
  // O Prime mostra um spinner próprio enquanto busca; o Figma não define esse estado.
139
156
  loadingIcon: { className: "cr-autocomplete__loader" },
140
157
  panel: { className: "cr-autocomplete__panel" },
158
+ // Lado da lista (acima ou abaixo do campo), medido logo depois de o Prime posicionar.
159
+ transition: aoPosicionar(() => {
160
+ const campo = document.getElementById(id);
161
+ seguirLado(painelDoCampo(campo, ".cr-autocomplete__panel"), campo);
162
+ }),
141
163
  list: { className: "cr-autocomplete__list" },
142
164
  item: { className: "cr-autocomplete__item" }
143
165
  },
@@ -209,6 +231,11 @@ var Card = forwardRef(function Card2({ padding = "xsmall", outline = false, clas
209
231
  }
210
232
  );
211
233
  });
234
+ var usandoTeclado = false;
235
+ if (typeof document !== "undefined") {
236
+ document.addEventListener("keydown", () => usandoTeclado = true, true);
237
+ document.addEventListener("pointerdown", () => usandoTeclado = false, true);
238
+ }
212
239
  var resolveTargets = (target) => {
213
240
  if (typeof target === "string") return Array.from(document.querySelectorAll(target));
214
241
  if (target instanceof HTMLElement) return [target];
@@ -223,16 +250,27 @@ function Tooltip({
223
250
  showDelay,
224
251
  hideDelay,
225
252
  disabled,
253
+ describe = true,
226
254
  id,
227
255
  className
228
256
  }) {
229
257
  const autoId = useId();
230
258
  const tooltipId = id ?? autoId;
231
259
  useEffect(() => {
260
+ if (!describe) return;
232
261
  const elements = resolveTargets(target);
233
- elements.forEach((element) => element.setAttribute("aria-describedby", tooltipId));
234
- return () => elements.forEach((element) => element.removeAttribute("aria-describedby"));
235
- }, [target, tooltipId]);
262
+ const ids = (element) => (element.getAttribute("aria-describedby") ?? "").split(/\s+/).filter(Boolean);
263
+ const gravar = (element, lista) => lista.length ? element.setAttribute("aria-describedby", lista.join(" ")) : element.removeAttribute("aria-describedby");
264
+ elements.forEach((element) => {
265
+ if (!ids(element).includes(tooltipId)) gravar(element, [...ids(element), tooltipId]);
266
+ });
267
+ return () => elements.forEach(
268
+ (element) => gravar(
269
+ element,
270
+ ids(element).filter((idAtual) => idAtual !== tooltipId)
271
+ )
272
+ );
273
+ }, [target, tooltipId, describe]);
236
274
  const classes = ["cr-tooltip", `cr-tooltip--${type}`, className].filter(Boolean).join(" ");
237
275
  const pt = {
238
276
  root: (options) => {
@@ -253,6 +291,8 @@ function Tooltip({
253
291
  showDelay,
254
292
  hideDelay,
255
293
  disabled,
294
+ closeOnEscape: true,
295
+ onBeforeShow: (e) => e.originalEvent?.type !== "focus" || usandoTeclado,
256
296
  pt,
257
297
  children: content
258
298
  }
@@ -567,7 +607,10 @@ var Checkbox = forwardRef(function Checkbox2({
567
607
  value,
568
608
  icon: /* @__PURE__ */ jsx(Check, { size: 16 }),
569
609
  pt: {
570
- root: { className: "cr-checkbox__control" },
610
+ // Marcado pela prop do Cristal, não pelo atributo interno do Prime (data-p-highlight).
611
+ root: {
612
+ className: `cr-checkbox__control${checked ? " cr-checkbox__control--checked" : ""}`
613
+ },
571
614
  input: { className: "cr-checkbox__input" },
572
615
  box: { className: "cr-checkbox__box" },
573
616
  icon: { className: "cr-checkbox__icon", "aria-hidden": true }
@@ -656,24 +699,54 @@ var Divider = forwardRef(function Divider2({ orientation = "horizontal", variant
656
699
  }
657
700
  );
658
701
  });
659
- var IconButton = forwardRef(function IconButton2({ variant = "primary", size = "large", icon, type = "button", className, ...props }, ref) {
702
+ var IconButton = forwardRef(function IconButton2({
703
+ variant = "primary",
704
+ size = "large",
705
+ icon,
706
+ type = "button",
707
+ tooltip,
708
+ tooltipPosition,
709
+ className,
710
+ ...props
711
+ }, ref) {
712
+ const botao = useRef(null);
713
+ const ligar = useCallback(
714
+ (elemento) => {
715
+ botao.current = elemento;
716
+ if (typeof ref === "function") ref(elemento);
717
+ else if (ref) ref.current = elemento;
718
+ },
719
+ [ref]
720
+ );
721
+ const texto = tooltip ?? props["aria-label"];
660
722
  const classes = [
661
723
  "cr-icon-button",
662
724
  `cr-icon-button--${variant}`,
663
725
  `cr-icon-button--${size}`,
664
726
  className
665
727
  ].filter(Boolean).join(" ");
666
- return /* @__PURE__ */ jsx(
667
- Button$1,
668
- {
669
- unstyled: true,
670
- ref,
671
- type,
672
- className: classes,
673
- ...props,
674
- children: /* @__PURE__ */ jsx("span", { className: "cr-icon-button__icon", "aria-hidden": "true", children: icon })
675
- }
676
- );
728
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
729
+ /* @__PURE__ */ jsx(
730
+ Button$1,
731
+ {
732
+ unstyled: true,
733
+ ref: ligar,
734
+ type,
735
+ className: classes,
736
+ ...props,
737
+ children: /* @__PURE__ */ jsx("span", { className: "cr-icon-button__icon", "aria-hidden": "true", children: icon })
738
+ }
739
+ ),
740
+ texto !== false && /* @__PURE__ */ jsx(
741
+ Tooltip,
742
+ {
743
+ target: botao,
744
+ content: texto,
745
+ position: tooltipPosition,
746
+ describe: texto !== props["aria-label"]
747
+ }
748
+ )
749
+ ] });
677
750
  });
678
751
  var FOCAVEIS = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
679
752
  function Drawer({
@@ -896,10 +969,17 @@ var Menu = forwardRef(function Menu2({
896
969
  className
897
970
  }, ref) {
898
971
  const primeRef = useRef(null);
972
+ const alvo = useRef(null);
899
973
  const context = useContext(PrimeReactContext);
900
974
  useImperativeHandle(ref, () => ({
901
- toggle: (event) => primeRef.current?.toggle(event),
902
- show: (event) => primeRef.current?.show(event),
975
+ toggle: (event) => {
976
+ alvo.current = event.currentTarget;
977
+ primeRef.current?.toggle(event);
978
+ },
979
+ show: (event) => {
980
+ alvo.current = event.currentTarget;
981
+ primeRef.current?.show(event);
982
+ },
903
983
  hide: (event) => primeRef.current?.hide(event),
904
984
  getElement: () => primeRef.current?.getElement() ?? null
905
985
  }));
@@ -937,6 +1017,12 @@ var Menu = forwardRef(function Menu2({
937
1017
  };
938
1018
  },
939
1019
  content: { className: "cr-menu__content" },
1020
+ // Lado do popup (acima ou abaixo de quem o abriu), medido logo depois de o Prime posicionar.
1021
+ // Numa microtarefa: no onEnter o Prime ainda está religando a ref (getElement vem vazio); ela
1022
+ // roda logo depois, antes de a tela ser pintada.
1023
+ transition: aoPosicionar(
1024
+ () => queueMicrotask(() => seguirLado(primeRef.current?.getElement(), alvo.current))
1025
+ ),
940
1026
  action: { className: "cr-menu__action" },
941
1027
  label: { className: "cr-menu__label" }
942
1028
  };
@@ -1194,9 +1280,12 @@ var MenuPrincipal = forwardRef(
1194
1280
  const primeRef = useRef(null);
1195
1281
  const context = useContext(PrimeReactContext);
1196
1282
  const [baseDoAlvo, setBaseDoAlvo] = useState();
1283
+ const alvo = useRef(null);
1197
1284
  const medirAlvo = (event) => {
1198
- const alvo = event.currentTarget;
1199
- if (alvo instanceof Element) setBaseDoAlvo(alvo.getBoundingClientRect().bottom);
1285
+ const elemento = event.currentTarget;
1286
+ if (!(elemento instanceof Element)) return;
1287
+ alvo.current = elemento;
1288
+ setBaseDoAlvo(elemento.getBoundingClientRect().bottom);
1200
1289
  };
1201
1290
  useImperativeHandle(ref, () => ({
1202
1291
  toggle: (event) => {
@@ -1255,7 +1344,12 @@ var MenuPrincipal = forwardRef(
1255
1344
  menu: { className: "cr-menu-principal__list", "aria-label": ariaLabel },
1256
1345
  submenuHeader: { className: "cr-menu-principal__group" },
1257
1346
  separator: { className: "cr-menu-principal__separator" },
1258
- menuitem: { className: "cr-menu-principal__item" }
1347
+ menuitem: { className: "cr-menu-principal__item" },
1348
+ // Lado do popup, medido logo depois de o Prime posicionar.
1349
+ // Numa microtarefa: no onEnter o Prime ainda está religando a ref (como no Menu).
1350
+ transition: aoPosicionar(
1351
+ () => queueMicrotask(() => seguirLado(primeRef.current?.getElement(), alvo.current))
1352
+ )
1259
1353
  };
1260
1354
  const menu = /* @__PURE__ */ jsx(
1261
1355
  Menu$1,
@@ -1590,7 +1684,9 @@ var PageHeader = forwardRef(function PageHeader2({
1590
1684
  segmentControl,
1591
1685
  actions,
1592
1686
  onExpand,
1687
+ expanded,
1593
1688
  expandLabel = "Expandir",
1689
+ collapseLabel = "Recolher",
1594
1690
  tabs,
1595
1691
  activeTab,
1596
1692
  onTabChange,
@@ -1600,6 +1696,8 @@ var PageHeader = forwardRef(function PageHeader2({
1600
1696
  }, ref) {
1601
1697
  const [interna, setInterna] = useState(0);
1602
1698
  const ativa = activeTab ?? interna;
1699
+ const [expandidoInterno, setExpandidoInterno] = useState(false);
1700
+ const expandido = expanded ?? expandidoInterno;
1603
1701
  const tools = segmentControl || actions;
1604
1702
  const tabTemplate = (tab) => (
1605
1703
  // O TabMenu também passa o index da aba nas opções, além do que o tipo do MenuItem declara.
@@ -1647,9 +1745,12 @@ var PageHeader = forwardRef(function PageHeader2({
1647
1745
  className: "cr-page-header__expand",
1648
1746
  variant: "tertiary",
1649
1747
  size: "medium",
1650
- icon: /* @__PURE__ */ jsx(ArrowsOutSimple, {}),
1651
- "aria-label": expandLabel,
1652
- onClick: onExpand
1748
+ icon: expandido ? /* @__PURE__ */ jsx(ArrowsInSimple, {}) : /* @__PURE__ */ jsx(ArrowsOutSimple, {}),
1749
+ "aria-label": expandido ? collapseLabel : expandLabel,
1750
+ onClick: () => {
1751
+ setExpandidoInterno(!expandido);
1752
+ onExpand(!expandido);
1753
+ }
1653
1754
  }
1654
1755
  )
1655
1756
  ]
@@ -1735,9 +1836,23 @@ var Select = forwardRef(function Select2({
1735
1836
  input: { className: "cr-select__value" },
1736
1837
  trigger: { className: "cr-field__icon cr-select__trigger", "aria-hidden": true },
1737
1838
  panel: { className: "cr-select__panel" },
1839
+ // Lado da lista (acima ou abaixo do campo), medido logo depois de o Prime posicionar.
1840
+ transition: aoPosicionar(
1841
+ () => seguirLado(
1842
+ document.getElementById(listId)?.closest(".cr-select__panel"),
1843
+ document.getElementById(inputId)?.closest(".cr-select__control")
1844
+ )
1845
+ ),
1738
1846
  wrapper: { className: "cr-select__wrapper" },
1739
1847
  list: { className: "cr-select__list", id: listId },
1740
- item: { className: "cr-select__item" },
1848
+ // Selecionado e em foco (teclado) pelo contexto do pt, a API pública do Prime (não data-p-*).
1849
+ item: ({ context }) => ({
1850
+ className: [
1851
+ "cr-select__item",
1852
+ context.selected && "cr-select__item--selected",
1853
+ context.focused && "cr-select__item--focused"
1854
+ ].filter(Boolean).join(" ")
1855
+ }),
1741
1856
  emptyMessage: { className: "cr-select__item cr-select__empty" }
1742
1857
  };
1743
1858
  return /* @__PURE__ */ jsxs("div", { className: classes, children: [
@@ -1925,7 +2040,8 @@ var Radio = forwardRef(function Radio2({
1925
2040
  disabled,
1926
2041
  required,
1927
2042
  pt: {
1928
- root: { className: "cr-radio__control" },
2043
+ // Marcado pela prop do Cristal, não pelo atributo interno do Prime (data-p-checked).
2044
+ root: { className: `cr-radio__control${checked ? " cr-radio__control--checked" : ""}` },
1929
2045
  input: { className: "cr-radio__input" },
1930
2046
  box: { className: "cr-radio__box" },
1931
2047
  icon: { className: "cr-radio__icon" }
@@ -2065,7 +2181,12 @@ var Switch = forwardRef(function Switch2({
2065
2181
  disabled,
2066
2182
  name,
2067
2183
  pt: {
2068
- root: { className: "cr-switch__control", role: void 0, "aria-checked": void 0 },
2184
+ // Ligado pela prop do Cristal, não pelo atributo interno do Prime (data-p-highlight).
2185
+ root: {
2186
+ className: `cr-switch__control${checked ? " cr-switch__control--checked" : ""}`,
2187
+ role: void 0,
2188
+ "aria-checked": void 0
2189
+ },
2069
2190
  input: { className: "cr-switch__input" },
2070
2191
  slider: { className: "cr-switch__track" }
2071
2192
  }