@1doc/1ds-react 2.8.0 → 2.10.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.
- package/CHANGELOG.md +1540 -0
- package/dist/components/AILabel/AILabel.js +1 -1
- package/dist/components/Accordion/Accordion.css +13 -0
- package/dist/components/Accordion/Accordion.d.ts +9 -2
- package/dist/components/Accordion/Accordion.js +1 -0
- package/dist/components/AppSubheader/AppSubheader.css +10 -1
- package/dist/components/AttachmentCard/AttachmentCard.css +26 -8
- package/dist/components/AttachmentCard/AttachmentCard.d.ts +22 -2
- package/dist/components/AttachmentCard/AttachmentCard.js +47 -3
- package/dist/components/Avatar/Avatar.css +7 -2
- package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
- package/dist/components/Avatar/AvatarGroup.js +22 -8
- package/dist/components/Badge/Badge.css +67 -2
- package/dist/components/Badge/Badge.d.ts +23 -4
- package/dist/components/Badge/Badge.js +4 -0
- package/dist/components/Box/Box.css +83 -0
- package/dist/components/Box/Box.d.ts +82 -2
- package/dist/components/Box/Box.js +42 -2
- package/dist/components/Button/Button.css +29 -0
- package/dist/components/Button/Button.d.ts +4 -4
- package/dist/components/Button/Button.js +4 -1
- package/dist/components/Calendar/Calendar.css +245 -0
- package/dist/components/Calendar/Calendar.d.ts +126 -0
- package/dist/components/Calendar/Calendar.js +320 -0
- package/dist/components/Chips/Chips.css +38 -0
- package/dist/components/Chips/Chips.d.ts +5 -2
- package/dist/components/Chips/Chips.js +2 -1
- package/dist/components/Coachmark/Coachmark.css +128 -0
- package/dist/components/Coachmark/Coachmark.d.ts +87 -0
- package/dist/components/Coachmark/Coachmark.js +362 -0
- package/dist/components/CodeBlock/CodeBlock.css +96 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
- package/dist/components/CodeBlock/CodeBlock.js +103 -0
- package/dist/components/ColorPicker/ColorPicker.css +140 -0
- package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
- package/dist/components/ColorPicker/ColorPicker.js +219 -0
- package/dist/components/Combobox/Combobox.css +8 -0
- package/dist/components/DataTable/DataTable.css +254 -0
- package/dist/components/DataTable/DataTable.d.ts +81 -5
- package/dist/components/DataTable/DataTable.js +335 -19
- package/dist/components/DatePicker/DatePicker.css +8 -0
- package/dist/components/DatePicker/DatePicker.js +10 -1
- package/dist/components/DescriptionList/DescriptionList.css +127 -0
- package/dist/components/DescriptionList/DescriptionList.d.ts +62 -0
- package/dist/components/DescriptionList/DescriptionList.js +52 -0
- package/dist/components/EmptyState/EmptyState.d.ts +4 -2
- package/dist/components/EmptyState/EmptyState.js +2 -2
- package/dist/components/FileInput/FileInput.css +16 -0
- package/dist/components/FileInput/FileInput.d.ts +4 -2
- package/dist/components/FileInput/FileInput.js +8 -2
- package/dist/components/Grid/Grid.js +5 -5
- package/dist/components/IconPicker/IconPicker.css +107 -0
- package/dist/components/IconPicker/IconPicker.d.ts +74 -0
- package/dist/components/IconPicker/IconPicker.js +194 -0
- package/dist/components/Input/Input.css +59 -0
- package/dist/components/Input/Input.d.ts +17 -1
- package/dist/components/Input/Input.js +67 -5
- package/dist/components/Kanban/Kanban.css +4 -0
- package/dist/components/Kbd/Kbd.css +66 -0
- package/dist/components/Kbd/Kbd.d.ts +32 -0
- package/dist/components/Kbd/Kbd.js +40 -0
- package/dist/components/List/List.css +136 -0
- package/dist/components/List/List.d.ts +82 -0
- package/dist/components/List/List.js +53 -0
- package/dist/components/List/ListItem.d.ts +97 -0
- package/dist/components/List/ListItem.js +82 -0
- package/dist/components/Modal/Modal.css +80 -0
- package/dist/components/Modal/Modal.d.ts +33 -6
- package/dist/components/Modal/Modal.js +101 -6
- package/dist/components/MultiSelect/MultiSelect.css +8 -0
- package/dist/components/MultiSelect/MultiSelect.js +10 -1
- package/dist/components/OrgChart/OrgChart.css +149 -0
- package/dist/components/OrgChart/OrgChart.d.ts +83 -0
- package/dist/components/OrgChart/OrgChart.js +297 -0
- package/dist/components/OtpInput/OtpInput.css +93 -0
- package/dist/components/OtpInput/OtpInput.d.ts +60 -0
- package/dist/components/OtpInput/OtpInput.js +215 -0
- package/dist/components/PhoneInput/PhoneInput.css +8 -0
- package/dist/components/Popover/Popover.d.ts +7 -0
- package/dist/components/Popover/Popover.js +11 -1
- package/dist/components/RichTextEditor/RichTextEditor.css +250 -0
- package/dist/components/RichTextEditor/RichTextEditor.d.ts +97 -0
- package/dist/components/RichTextEditor/RichTextEditor.js +951 -0
- package/dist/components/SegmentedControl/SegmentedControl.css +24 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +10 -2
- package/dist/components/Select/Select.css +164 -0
- package/dist/components/Select/Select.d.ts +34 -0
- package/dist/components/Select/Select.js +258 -28
- package/dist/components/Stack/Stack.css +49 -0
- package/dist/components/Stack/Stack.d.ts +65 -7
- package/dist/components/Stack/Stack.js +30 -2
- package/dist/components/StatCard/StatCard.css +138 -0
- package/dist/components/StatCard/StatCard.d.ts +26 -0
- package/dist/components/StatCard/StatCard.js +13 -1
- package/dist/components/Tabs/Tab.d.ts +15 -0
- package/dist/components/Tabs/Tab.js +30 -1
- package/dist/components/Tabs/Tabs.css +132 -0
- package/dist/components/Tabs/Tabs.d.ts +7 -0
- package/dist/components/Tabs/Tabs.js +13 -2
- package/dist/components/Tag/Tag.css +85 -2
- package/dist/components/Tag/Tag.d.ts +13 -6
- package/dist/components/Tag/Tag.js +1 -0
- package/dist/components/Text/Text.js +2 -2
- package/dist/components/Textarea/Textarea.css +8 -0
- package/dist/components/TimePicker/TimePicker.css +8 -0
- package/dist/components/Toast/Toast.css +32 -0
- package/dist/components/Toast/Toast.d.ts +18 -0
- package/dist/components/Toast/Toast.js +14 -1
- package/dist/components/Toast/ToastStack.js +8 -1
- package/dist/components/Tooltip/Tooltip.css +25 -0
- package/dist/components/Tooltip/Tooltip.d.ts +11 -0
- package/dist/components/Tooltip/Tooltip.js +18 -3
- package/dist/index.d.ts +25 -0
- package/dist/index.js +14 -0
- package/dist/teste/AILabel.test.d.ts +1 -0
- package/dist/teste/AILabel.test.js +33 -0
- package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
- package/dist/teste/AccordionConteudoLivre.test.js +29 -0
- package/dist/teste/AccordionTituloNeutro.test.d.ts +1 -0
- package/dist/teste/AccordionTituloNeutro.test.js +23 -0
- package/dist/teste/AppSubheaderRegiao.test.d.ts +1 -0
- package/dist/teste/AppSubheaderRegiao.test.js +13 -0
- package/dist/teste/AtributosRepassados.test.d.ts +1 -0
- package/dist/teste/AtributosRepassados.test.js +52 -0
- package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
- package/dist/teste/AttachmentCardIA.test.js +89 -0
- package/dist/teste/AttachmentCardLista.test.d.ts +1 -0
- package/dist/teste/AttachmentCardLista.test.js +49 -0
- package/dist/teste/AttachmentCardSm.test.d.ts +1 -0
- package/dist/teste/AttachmentCardSm.test.js +26 -0
- package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
- package/dist/teste/AvatarGroupOverlap.test.js +56 -0
- package/dist/teste/BadgeNeutroColado.test.d.ts +1 -0
- package/dist/teste/BadgeNeutroColado.test.js +11 -0
- package/dist/teste/BadgeTag.test.d.ts +1 -0
- package/dist/teste/BadgeTag.test.js +55 -0
- package/dist/teste/BoxItemFlex.test.d.ts +1 -0
- package/dist/teste/BoxItemFlex.test.js +54 -0
- package/dist/teste/BoxLayout.test.d.ts +1 -0
- package/dist/teste/BoxLayout.test.js +35 -0
- package/dist/teste/Button.test.d.ts +1 -0
- package/dist/teste/Button.test.js +27 -0
- package/dist/teste/Calendar.test.d.ts +1 -0
- package/dist/teste/Calendar.test.js +221 -0
- package/dist/teste/CalendarCabecalho.test.d.ts +1 -0
- package/dist/teste/CalendarCabecalho.test.js +11 -0
- package/dist/teste/ChipsXs.test.d.ts +1 -0
- package/dist/teste/ChipsXs.test.js +31 -0
- package/dist/teste/Coachmark.test.d.ts +1 -0
- package/dist/teste/Coachmark.test.js +149 -0
- package/dist/teste/CoachmarkSemVeu.test.d.ts +1 -0
- package/dist/teste/CoachmarkSemVeu.test.js +85 -0
- package/dist/teste/ColorPicker.test.d.ts +1 -0
- package/dist/teste/ColorPicker.test.js +132 -0
- package/dist/teste/ColorPickerXs.test.d.ts +1 -0
- package/dist/teste/ColorPickerXs.test.js +21 -0
- package/dist/teste/DataTableArvoreEVariantes.test.d.ts +1 -0
- package/dist/teste/DataTableArvoreEVariantes.test.js +190 -0
- package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
- package/dist/teste/DataTableCelulaLivre.test.js +76 -0
- package/dist/teste/DataTableDocumento.test.d.ts +1 -0
- package/dist/teste/DataTableDocumento.test.js +92 -0
- package/dist/teste/DatePicker.test.js +23 -0
- package/dist/teste/DescriptionListCompacta.test.d.ts +1 -0
- package/dist/teste/DescriptionListCompacta.test.js +22 -0
- package/dist/teste/EmptyStateTituloRico.test.d.ts +1 -0
- package/dist/teste/EmptyStateTituloRico.test.js +23 -0
- package/dist/teste/FileInputTrigger.test.d.ts +1 -0
- package/dist/teste/FileInputTrigger.test.js +53 -0
- package/dist/teste/IconPicker.test.d.ts +1 -0
- package/dist/teste/IconPicker.test.js +130 -0
- package/dist/teste/InputAgrupado.test.d.ts +1 -0
- package/dist/teste/InputAgrupado.test.js +24 -0
- package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
- package/dist/teste/InputMascaraEAfins.test.js +99 -0
- package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
- package/dist/teste/KbdCodeBlock.test.js +95 -0
- package/dist/teste/List.test.d.ts +1 -0
- package/dist/teste/List.test.js +153 -0
- package/dist/teste/ListItemTooltipStandalone.test.d.ts +1 -0
- package/dist/teste/ListItemTooltipStandalone.test.js +39 -0
- package/dist/teste/ModalVariantes.test.d.ts +1 -0
- package/dist/teste/ModalVariantes.test.js +151 -0
- package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
- package/dist/teste/NomeAcessivelSsr.test.js +88 -0
- package/dist/teste/OrgChart.test.d.ts +1 -0
- package/dist/teste/OrgChart.test.js +162 -0
- package/dist/teste/OtpInput.test.d.ts +1 -0
- package/dist/teste/OtpInput.test.js +143 -0
- package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
- package/dist/teste/PopoverMaxHeight.test.js +38 -0
- package/dist/teste/RichTextEditor.test.d.ts +1 -0
- package/dist/teste/RichTextEditor.test.js +287 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.d.ts +1 -0
- package/dist/teste/RichTextEditorAlinhaImagemTabela.test.js +212 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.d.ts +1 -0
- package/dist/teste/RichTextEditorEstiloDeTexto.test.js +120 -0
- package/dist/teste/SegmentedControlContador.test.d.ts +1 -0
- package/dist/teste/SegmentedControlContador.test.js +39 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.d.ts +1 -0
- package/dist/teste/SelectAbertoControladoEFlutuante.test.js +145 -0
- package/dist/teste/SelectFiltroCorETamanho.test.d.ts +1 -0
- package/dist/teste/SelectFiltroCorETamanho.test.js +77 -0
- package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
- package/dist/teste/SelectPlacementFiltro.test.js +88 -0
- package/dist/teste/Stack.test.d.ts +1 -0
- package/dist/teste/Stack.test.js +57 -0
- package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
- package/dist/teste/StatCardRotuloTopo.test.js +34 -0
- package/dist/teste/StatCardSecundariaETom.test.d.ts +1 -0
- package/dist/teste/StatCardSecundariaETom.test.js +45 -0
- package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
- package/dist/teste/TabsContadorFechavel.test.js +79 -0
- package/dist/teste/ToastAcaoEDetalhes.test.d.ts +1 -0
- package/dist/teste/ToastAcaoEDetalhes.test.js +94 -0
- package/dist/teste/TooltipDark.test.d.ts +1 -0
- package/dist/teste/TooltipDark.test.js +31 -0
- package/dist/utils/calendario.d.ts +28 -0
- package/dist/utils/calendario.js +73 -0
- package/dist/utils/html-seguro.d.ts +45 -0
- package/dist/utils/html-seguro.js +208 -0
- package/dist/utils/paleta-de-cores.d.ts +26 -0
- package/dist/utils/paleta-de-cores.js +10 -0
- package/dist/utils/texto.d.ts +5 -0
- package/dist/utils/texto.js +5 -0
- package/dist/utils/toast.d.ts +10 -1
- package/dist/utils/toast.js +2 -1
- package/package.json +3 -3
- package/src/index.ts +26 -0
- package/src/teste/AILabel.test.tsx +41 -0
- package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
- package/src/teste/AccordionTituloNeutro.test.tsx +25 -0
- package/src/teste/AppSubheaderRegiao.test.tsx +17 -0
- package/src/teste/AtributosRepassados.test.tsx +73 -0
- package/src/teste/AttachmentCardIA.test.tsx +126 -0
- package/src/teste/AttachmentCardLista.test.tsx +53 -0
- package/src/teste/AttachmentCardSm.test.tsx +29 -0
- package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
- package/src/teste/BadgeNeutroColado.test.tsx +15 -0
- package/src/teste/BadgeTag.test.tsx +85 -0
- package/src/teste/BoxItemFlex.test.tsx +81 -0
- package/src/teste/BoxLayout.test.tsx +50 -0
- package/src/teste/Button.test.tsx +39 -0
- package/src/teste/Calendar.test.tsx +282 -0
- package/src/teste/CalendarCabecalho.test.tsx +11 -0
- package/src/teste/ChipsXs.test.tsx +41 -0
- package/src/teste/Coachmark.test.tsx +198 -0
- package/src/teste/CoachmarkSemVeu.test.tsx +101 -0
- package/src/teste/ColorPicker.test.tsx +153 -0
- package/src/teste/ColorPickerXs.test.tsx +22 -0
- package/src/teste/DataTableArvoreEVariantes.test.tsx +240 -0
- package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
- package/src/teste/DataTableDocumento.test.tsx +102 -0
- package/src/teste/DatePicker.test.tsx +38 -0
- package/src/teste/DescriptionListCompacta.test.tsx +24 -0
- package/src/teste/EmptyStateTituloRico.test.tsx +34 -0
- package/src/teste/FileInputTrigger.test.tsx +89 -0
- package/src/teste/IconPicker.test.tsx +145 -0
- package/src/teste/InputAgrupado.test.tsx +26 -0
- package/src/teste/InputMascaraEAfins.test.tsx +124 -0
- package/src/teste/KbdCodeBlock.test.tsx +106 -0
- package/src/teste/List.test.tsx +269 -0
- package/src/teste/ListItemTooltipStandalone.test.tsx +64 -0
- package/src/teste/ModalVariantes.test.tsx +173 -0
- package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
- package/src/teste/OrgChart.test.tsx +183 -0
- package/src/teste/OtpInput.test.tsx +163 -0
- package/src/teste/PopoverMaxHeight.test.tsx +47 -0
- package/src/teste/RichTextEditor.test.tsx +329 -0
- package/src/teste/RichTextEditorAlinhaImagemTabela.test.tsx +238 -0
- package/src/teste/RichTextEditorEstiloDeTexto.test.tsx +137 -0
- package/src/teste/SegmentedControlContador.test.tsx +43 -0
- package/src/teste/SelectAbertoControladoEFlutuante.test.tsx +180 -0
- package/src/teste/SelectFiltroCorETamanho.test.tsx +90 -0
- package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
- package/src/teste/Stack.test.tsx +80 -0
- package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
- package/src/teste/StatCardSecundariaETom.test.tsx +51 -0
- package/src/teste/TabsContadorFechavel.test.tsx +144 -0
- package/src/teste/ToastAcaoEDetalhes.test.tsx +109 -0
- package/src/teste/TooltipDark.test.tsx +51 -0
- package/src/utils/calendario.ts +78 -0
- package/src/utils/html-seguro.ts +197 -0
- package/src/utils/paleta-de-cores.ts +34 -0
- package/src/utils/texto.ts +5 -0
- package/src/utils/toast.ts +12 -2
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import './Calendar.css';
|
|
2
|
+
/**
|
|
3
|
+
* Evento do Calendar.
|
|
4
|
+
* @property {string} id - Identidade do evento (opcional)
|
|
5
|
+
* @property {string} date - Dia do evento: `YYYY-MM-DD` (ou um `Date`)
|
|
6
|
+
* @property {string} title - Texto do evento
|
|
7
|
+
* @property {string} color - Cor de DADO do evento: nome de um token (`--umds-primitive-blue-pure`) ou uma cor. Padrão: o primário. A cor vai no fundo suave e na barra do lado; o texto é sempre escuro (a cor nunca fica sozinha).
|
|
8
|
+
* @property {string} time - Horário, mostrado antes do título (ex.: "09:00")
|
|
9
|
+
*/
|
|
10
|
+
export interface CalendarEvent {
|
|
11
|
+
id?: string;
|
|
12
|
+
date: any;
|
|
13
|
+
title: string;
|
|
14
|
+
color?: string;
|
|
15
|
+
time?: string;
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
}
|
|
18
|
+
/** Um dia da grade, já pronto para desenhar. */
|
|
19
|
+
/** Um dia da grade, já pronto para desenhar. */
|
|
20
|
+
export interface CalendarDayCell {
|
|
21
|
+
iso: string;
|
|
22
|
+
day: number;
|
|
23
|
+
outside: boolean;
|
|
24
|
+
today: boolean;
|
|
25
|
+
selected: boolean;
|
|
26
|
+
tabIndex: number;
|
|
27
|
+
label: string;
|
|
28
|
+
classes: string;
|
|
29
|
+
visible: CalendarEvent[];
|
|
30
|
+
hidden: number;
|
|
31
|
+
moreText: string;
|
|
32
|
+
moreAria: string;
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Calendar — agenda com eventos por dia, em visão de mês ou de semana.
|
|
37
|
+
*
|
|
38
|
+
* `events` é uma lista plana (`{ date, title, color? }`): o componente agrupa
|
|
39
|
+
* por dia. A cor é cor de DADO (um token, como o do `ColorPicker`), aplicada num
|
|
40
|
+
* fundo suave com uma barra do lado; o texto do evento é sempre escuro, então a
|
|
41
|
+
* cor nunca é a única informação.
|
|
42
|
+
*
|
|
43
|
+
* Mês: cada dia mostra até `maxVisible` eventos e um "+N" para o resto
|
|
44
|
+
* (`onMoreClick` recebe o dia e os eventos escondidos). O corte é por QUANTIDADE,
|
|
45
|
+
* não por altura. Semana: sete colunas, todos os eventos de cada dia.
|
|
46
|
+
*
|
|
47
|
+
* É uma grade acessível (`role="grid"`): um Tab entra no dia em foco (hoje, ou o
|
|
48
|
+
* primeiro), as setas movem de dia (mudando de mês ou de semana se for preciso),
|
|
49
|
+
* Home e End vão às pontas da semana, PageUp e PageDown trocam de mês (ou de
|
|
50
|
+
* semana), Enter e Espaço acionam `onDayClick`. Os eventos do dia em foco entram
|
|
51
|
+
* na ordem de Tab depois dele.
|
|
52
|
+
*
|
|
53
|
+
* A data mostrada (`date`) e a visão (`view`) são controláveis (`onDateChange`,
|
|
54
|
+
* `onViewChange`) ou internas (`defaultDate`, `defaultView`). O cabeçalho aceita
|
|
55
|
+
* um filtro de escopo à esquerda e a legenda à direita: no React, as props `headerStart`
|
|
56
|
+
* e `headerEnd` (um nó); no Vue, os slots `#header-start` e `#header-end` (com hífen: o
|
|
57
|
+
* Vue lê o nome do slot como está, e `#headerStart` não chega). Nomes de mês e de dia saem do `Intl` no `locale` pedido;
|
|
58
|
+
* os demais textos são props.
|
|
59
|
+
* @property {CalendarEvent[]} events - Eventos (lista plana)
|
|
60
|
+
* @property {string} view - Visão: 'month' | 'week' (controlada)
|
|
61
|
+
* @property {string} defaultView - Visão inicial (não controlada; padrão 'month')
|
|
62
|
+
* @property {string} date - Data de referência `YYYY-MM-DD`: o mês ou a semana que ela contém é o que se vê (controlada)
|
|
63
|
+
* @property {string} defaultDate - Data inicial (não controlada; padrão hoje)
|
|
64
|
+
* @property {string} selectedDate - Dia marcado como selecionado (`YYYY-MM-DD`)
|
|
65
|
+
* @property {string} today - O "hoje" do calendário (`YYYY-MM-DD`; padrão a data do sistema). Útil em testes e em demonstração.
|
|
66
|
+
* @property {number} weekStartsOn - Primeiro dia da semana: 0 domingo (padrão) | 1 segunda
|
|
67
|
+
* @property {number} maxVisible - Eventos por dia na visão de mês antes do "+N" (padrão 3)
|
|
68
|
+
* @property {string} locale - Idioma dos nomes de mês e de dia (padrão 'pt-BR')
|
|
69
|
+
* @property {string} ariaLabel - Nome acessível da grade (padrão: o título, ex.: "Maio 2026")
|
|
70
|
+
* @property {string} previousLabel - Nome do botão de voltar (padrão "Anterior")
|
|
71
|
+
* @property {string} nextLabel - Nome do botão de avançar (padrão "Próximo")
|
|
72
|
+
* @property {string} todayLabel - Texto do botão de hoje (padrão "Hoje")
|
|
73
|
+
* @property {string} monthLabel - Texto da visão de mês (padrão "Mês")
|
|
74
|
+
* @property {string} weekLabel - Texto da visão de semana (padrão "Semana")
|
|
75
|
+
* @property {string} viewLabel - Nome do seletor de visão (padrão "Visão")
|
|
76
|
+
* @property {boolean} hideViewSwitcher - Esconde o seletor Mês/Semana
|
|
77
|
+
* @property {string} moreLabel - Texto do "+N"; `{count}` vira o número (padrão "+{count}")
|
|
78
|
+
* @property {string} moreAriaLabel - Nome do "+N"; `{count}` e `{date}` são trocados (padrão "{count} eventos a mais em {date}")
|
|
79
|
+
* @property {function} dayLabel - Nome acessível de cada dia: `(iso, quantidade) => texto` (padrão: "sexta-feira, 15 de maio de 2026, 2 eventos", no `locale`)
|
|
80
|
+
* @property {function} onDayClick - Clique (ou Enter) num dia: recebe `YYYY-MM-DD`
|
|
81
|
+
* @property {function} onEventClick - Clique num evento: recebe o evento
|
|
82
|
+
* @property {function} onMoreClick - Clique no "+N": recebe o dia e a lista dos eventos escondidos
|
|
83
|
+
* @property {function} onDateChange - Mudou a data de referência (navegação): recebe `YYYY-MM-DD`
|
|
84
|
+
* @property {function} onViewChange - Mudou a visão: recebe 'month' | 'week'
|
|
85
|
+
* @property {string} className - Classes CSS adicionais
|
|
86
|
+
* @slot header-start - Só no Vue (`#header-start`, com hífen). Cabeçalho, à esquerda: um filtro de escopo. No React, a prop `headerStart`.
|
|
87
|
+
* @slot header-end - Só no Vue (`#header-end`, com hífen). Cabeçalho, antes do seletor de visão: a legenda. No React, a prop `headerEnd`.
|
|
88
|
+
* @quandoUsar Mostrar prazos, vencimentos e compromissos distribuídos no tempo: agenda de documentos, de tarefas, de assinaturas.
|
|
89
|
+
* @quandoNaoUsar Para escolher UMA data num campo, use `DatePicker`. Para uma sequência de acontecimentos sem grade de dias, use `Timeline`. Para uma grade de horas (agenda com horário de início e fim), este componente não serve: não tem eixo de horas.
|
|
90
|
+
*/
|
|
91
|
+
/** Um dia da grade, já pronto para desenhar. */
|
|
92
|
+
export interface CalendarProps {
|
|
93
|
+
events?: CalendarEvent[];
|
|
94
|
+
view?: "month" | "week";
|
|
95
|
+
defaultView?: "month" | "week";
|
|
96
|
+
date?: string;
|
|
97
|
+
defaultDate?: string;
|
|
98
|
+
selectedDate?: string;
|
|
99
|
+
today?: string;
|
|
100
|
+
weekStartsOn?: 0 | 1;
|
|
101
|
+
maxVisible?: number;
|
|
102
|
+
locale?: string;
|
|
103
|
+
ariaLabel?: string;
|
|
104
|
+
previousLabel?: string;
|
|
105
|
+
nextLabel?: string;
|
|
106
|
+
todayLabel?: string;
|
|
107
|
+
monthLabel?: string;
|
|
108
|
+
weekLabel?: string;
|
|
109
|
+
viewLabel?: string;
|
|
110
|
+
hideViewSwitcher?: boolean;
|
|
111
|
+
moreLabel?: string;
|
|
112
|
+
moreAriaLabel?: string;
|
|
113
|
+
dayLabel?: (iso: string, count: number) => string;
|
|
114
|
+
className?: string;
|
|
115
|
+
/** Cabeçalho, à esquerda: um filtro de escopo. React: o nó nesta prop. Vue: o slot `#header-start` (com hífen). */
|
|
116
|
+
headerStart?: any;
|
|
117
|
+
/** Cabeçalho, à direita, antes do seletor de visão: a legenda. React: o nó nesta prop. Vue: o slot `#header-end` (com hífen). */
|
|
118
|
+
headerEnd?: any;
|
|
119
|
+
onDayClick?: (iso: string) => void;
|
|
120
|
+
onEventClick?: (event: CalendarEvent) => void;
|
|
121
|
+
onMoreClick?: (iso: string, hidden: CalendarEvent[]) => void;
|
|
122
|
+
onDateChange?: (iso: string) => void;
|
|
123
|
+
onViewChange?: (view: "month" | "week") => void;
|
|
124
|
+
}
|
|
125
|
+
declare function Calendar(props: CalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
126
|
+
export default Calendar;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import './Calendar.css';
|
|
4
|
+
import { useState, useRef, useEffect } from "react";
|
|
5
|
+
import { faChevronLeft, faChevronRight, } from "@fortawesome/free-solid-svg-icons";
|
|
6
|
+
import Button from "../Button/Button";
|
|
7
|
+
import Icon from "../Icon/Icon";
|
|
8
|
+
import SegmentedControl from "../SegmentedControl/SegmentedControl";
|
|
9
|
+
import { addDays, addMonths, isSameMonth, monthMatrix, normalizeIso, parseIso, startOfWeek, toIso, weekDays, } from "../../utils/calendario";
|
|
10
|
+
function Calendar(props) {
|
|
11
|
+
const rootRef = useRef(null);
|
|
12
|
+
const focoPendenteRef = useRef("");
|
|
13
|
+
const [internalDate, setInternalDate] = useState(() => "");
|
|
14
|
+
const [internalView, setInternalView] = useState(() => props.defaultView === "week" ? "week" : "month");
|
|
15
|
+
const [focusIso, setFocusIso] = useState(() => "");
|
|
16
|
+
function todayIso() {
|
|
17
|
+
return normalizeIso(props.today) || toIso(new Date());
|
|
18
|
+
}
|
|
19
|
+
function refIso() {
|
|
20
|
+
const informada = normalizeIso(props.date) ||
|
|
21
|
+
normalizeIso(internalDate) ||
|
|
22
|
+
normalizeIso(props.defaultDate);
|
|
23
|
+
return informada || todayIso();
|
|
24
|
+
}
|
|
25
|
+
function viewValue() {
|
|
26
|
+
const bruta = props.view !== undefined ? props.view : internalView;
|
|
27
|
+
return bruta === "week" ? "week" : "month";
|
|
28
|
+
}
|
|
29
|
+
function weekStart() {
|
|
30
|
+
return props.weekStartsOn === 1 ? 1 : 0;
|
|
31
|
+
}
|
|
32
|
+
function localeText() {
|
|
33
|
+
return props.locale || "pt-BR";
|
|
34
|
+
}
|
|
35
|
+
function limite() {
|
|
36
|
+
return props.maxVisible && props.maxVisible > 0 ? props.maxVisible : 3;
|
|
37
|
+
}
|
|
38
|
+
function rangeRows() {
|
|
39
|
+
return viewValue() === "week"
|
|
40
|
+
? [weekDays(refIso(), weekStart())]
|
|
41
|
+
: monthMatrix(refIso(), weekStart());
|
|
42
|
+
}
|
|
43
|
+
function formatar(iso, opcoes) {
|
|
44
|
+
const texto = new Intl.DateTimeFormat(localeText(), opcoes).format(parseIso(iso));
|
|
45
|
+
const limpo = texto.replace(".", "");
|
|
46
|
+
return limpo.charAt(0).toUpperCase() + limpo.slice(1);
|
|
47
|
+
}
|
|
48
|
+
function titleText() {
|
|
49
|
+
if (viewValue() === "week") {
|
|
50
|
+
const dias = weekDays(refIso(), weekStart());
|
|
51
|
+
const formato = new Intl.DateTimeFormat(localeText(), {
|
|
52
|
+
day: "numeric",
|
|
53
|
+
month: "short",
|
|
54
|
+
year: "numeric",
|
|
55
|
+
});
|
|
56
|
+
const inicio = parseIso(dias[0]);
|
|
57
|
+
const fim = parseIso(dias[6]);
|
|
58
|
+
const anyFormato = formato;
|
|
59
|
+
return typeof anyFormato.formatRange === "function"
|
|
60
|
+
? anyFormato.formatRange(inicio, fim)
|
|
61
|
+
: formato.format(inicio) + " – " + formato.format(fim);
|
|
62
|
+
}
|
|
63
|
+
return (formatar(refIso(), {
|
|
64
|
+
month: "long",
|
|
65
|
+
}) +
|
|
66
|
+
" " +
|
|
67
|
+
parseIso(refIso()).getFullYear());
|
|
68
|
+
}
|
|
69
|
+
function weekdayHeads() {
|
|
70
|
+
const base = rangeRows()[0] || [];
|
|
71
|
+
return base.map((iso) => ({
|
|
72
|
+
iso,
|
|
73
|
+
short: formatar(iso, {
|
|
74
|
+
weekday: "short",
|
|
75
|
+
}),
|
|
76
|
+
full: formatar(iso, {
|
|
77
|
+
weekday: "long",
|
|
78
|
+
}),
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
function gridLabel() {
|
|
82
|
+
return props.ariaLabel || titleText();
|
|
83
|
+
}
|
|
84
|
+
function monthText() {
|
|
85
|
+
return props.monthLabel || "Mês";
|
|
86
|
+
}
|
|
87
|
+
function weekText() {
|
|
88
|
+
return props.weekLabel || "Semana";
|
|
89
|
+
}
|
|
90
|
+
function viewOptions() {
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
value: "month",
|
|
94
|
+
label: monthText(),
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
value: "week",
|
|
98
|
+
label: weekText(),
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
function rootClasses() {
|
|
103
|
+
return ["umds-calendar", "umds-calendar--" + viewValue(), props.className]
|
|
104
|
+
.filter(Boolean)
|
|
105
|
+
.join(" ");
|
|
106
|
+
}
|
|
107
|
+
function tabIso() {
|
|
108
|
+
const todos = rangeRows().reduce((soma, linha) => soma.concat(linha), []);
|
|
109
|
+
const dentro = (iso) => todos.indexOf(iso) !== -1 &&
|
|
110
|
+
(viewValue() === "week" || isSameMonth(iso, refIso()));
|
|
111
|
+
if (focusIso && dentro(focusIso))
|
|
112
|
+
return focusIso;
|
|
113
|
+
if (dentro(todayIso()))
|
|
114
|
+
return todayIso();
|
|
115
|
+
return viewValue() === "week" ? todos[0] : refIso().slice(0, 8) + "01";
|
|
116
|
+
}
|
|
117
|
+
function eventMap() {
|
|
118
|
+
const mapa = {};
|
|
119
|
+
const lista = props.events || [];
|
|
120
|
+
for (let i = 0; i < lista.length; i++) {
|
|
121
|
+
const dia = normalizeIso(lista[i].date);
|
|
122
|
+
if (!dia)
|
|
123
|
+
continue;
|
|
124
|
+
if (!mapa[dia])
|
|
125
|
+
mapa[dia] = [];
|
|
126
|
+
mapa[dia].push(lista[i]);
|
|
127
|
+
}
|
|
128
|
+
for (const dia in mapa) {
|
|
129
|
+
mapa[dia].sort((a, b) => String(a.time || "").localeCompare(String(b.time || "")));
|
|
130
|
+
}
|
|
131
|
+
return mapa;
|
|
132
|
+
}
|
|
133
|
+
function nomeDoDia(iso, quantidade) {
|
|
134
|
+
if (props.dayLabel)
|
|
135
|
+
return props.dayLabel(iso, quantidade);
|
|
136
|
+
const data = new Intl.DateTimeFormat(localeText(), {
|
|
137
|
+
weekday: "long",
|
|
138
|
+
day: "numeric",
|
|
139
|
+
month: "long",
|
|
140
|
+
year: "numeric",
|
|
141
|
+
}).format(parseIso(iso));
|
|
142
|
+
const eventos = quantidade === 0
|
|
143
|
+
? "sem eventos"
|
|
144
|
+
: quantidade === 1
|
|
145
|
+
? "1 evento"
|
|
146
|
+
: quantidade + " eventos";
|
|
147
|
+
return data + ", " + eventos;
|
|
148
|
+
}
|
|
149
|
+
function textoDoMais(quantidade) {
|
|
150
|
+
return (props.moreLabel || "+{count}").replace("{count}", String(quantidade));
|
|
151
|
+
}
|
|
152
|
+
function nomeDoMais(iso, quantidade) {
|
|
153
|
+
const modelo = props.moreAriaLabel || "{count} eventos a mais em {date}";
|
|
154
|
+
const data = new Intl.DateTimeFormat(localeText(), {
|
|
155
|
+
day: "numeric",
|
|
156
|
+
month: "long",
|
|
157
|
+
}).format(parseIso(iso));
|
|
158
|
+
return modelo
|
|
159
|
+
.replace("{count}", String(quantidade))
|
|
160
|
+
.replace("{date}", data);
|
|
161
|
+
}
|
|
162
|
+
function weeks() {
|
|
163
|
+
const hoje = todayIso();
|
|
164
|
+
const foco = tabIso();
|
|
165
|
+
const selecionado = normalizeIso(props.selectedDate);
|
|
166
|
+
const emSemana = viewValue() === "week";
|
|
167
|
+
return rangeRows().map((linha) => ({
|
|
168
|
+
key: linha[0],
|
|
169
|
+
days: linha.map((iso) => {
|
|
170
|
+
const doDia = eventMap()[iso] || [];
|
|
171
|
+
const fora = !emSemana && !isSameMonth(iso, refIso());
|
|
172
|
+
const visiveis = emSemana ? doDia : doDia.slice(0, limite());
|
|
173
|
+
const escondidos = doDia.length - visiveis.length;
|
|
174
|
+
return {
|
|
175
|
+
iso,
|
|
176
|
+
day: parseIso(iso).getDate(),
|
|
177
|
+
outside: fora,
|
|
178
|
+
today: iso === hoje,
|
|
179
|
+
selected: iso === selecionado,
|
|
180
|
+
tabIndex: iso === foco ? 0 : -1,
|
|
181
|
+
label: nomeDoDia(iso, doDia.length),
|
|
182
|
+
classes: [
|
|
183
|
+
"umds-calendar__cell",
|
|
184
|
+
fora ? "umds-calendar__cell--outside" : "",
|
|
185
|
+
iso === hoje ? "umds-calendar__cell--today" : "",
|
|
186
|
+
iso === selecionado ? "umds-calendar__cell--selected" : "",
|
|
187
|
+
]
|
|
188
|
+
.filter(Boolean)
|
|
189
|
+
.join(" "),
|
|
190
|
+
visible: visiveis,
|
|
191
|
+
hidden: escondidos,
|
|
192
|
+
moreText: textoDoMais(escondidos),
|
|
193
|
+
moreAria: nomeDoMais(iso, escondidos),
|
|
194
|
+
};
|
|
195
|
+
}),
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
function corCss(cor) {
|
|
199
|
+
const base = cor || "--umds-semantic-color-primary-pure";
|
|
200
|
+
return base.indexOf("--") === 0 ? "var(" + base + ")" : base;
|
|
201
|
+
}
|
|
202
|
+
function eventStyle(evento) {
|
|
203
|
+
const cor = corCss(evento.color || "");
|
|
204
|
+
return {
|
|
205
|
+
borderLeftColor: cor,
|
|
206
|
+
backgroundColor: "color-mix(in srgb, " +
|
|
207
|
+
cor +
|
|
208
|
+
" 16%, var(--umds-semantic-color-background-white))",
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function mudarData(iso) {
|
|
212
|
+
setInternalDate(iso);
|
|
213
|
+
if (props.onDateChange)
|
|
214
|
+
props.onDateChange(iso);
|
|
215
|
+
}
|
|
216
|
+
function mudarVisao(valor) {
|
|
217
|
+
const visao = valor === "week" ? "week" : "month";
|
|
218
|
+
if (visao === viewValue())
|
|
219
|
+
return;
|
|
220
|
+
setInternalView(visao);
|
|
221
|
+
if (props.onViewChange)
|
|
222
|
+
props.onViewChange(visao);
|
|
223
|
+
}
|
|
224
|
+
function handlePrevious() {
|
|
225
|
+
mudarData(viewValue() === "week" ? addDays(refIso(), -7) : addMonths(refIso(), -1));
|
|
226
|
+
}
|
|
227
|
+
function handleNext() {
|
|
228
|
+
mudarData(viewValue() === "week" ? addDays(refIso(), 7) : addMonths(refIso(), 1));
|
|
229
|
+
}
|
|
230
|
+
function handleToday() {
|
|
231
|
+
mudarData(todayIso());
|
|
232
|
+
}
|
|
233
|
+
function irParaDia(iso) {
|
|
234
|
+
const visivel = rangeRows().some((linha) => linha.indexOf(iso) !== -1);
|
|
235
|
+
const nesteMes = viewValue() === "week" || isSameMonth(iso, refIso());
|
|
236
|
+
if (!visivel || !nesteMes)
|
|
237
|
+
mudarData(iso);
|
|
238
|
+
if (iso === focusIso && visivel && nesteMes) {
|
|
239
|
+
focarDia(iso);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
setFocusIso(iso);
|
|
243
|
+
focoPendenteRef.current = iso;
|
|
244
|
+
}
|
|
245
|
+
function focarDia(iso) {
|
|
246
|
+
if (!rootRef.current)
|
|
247
|
+
return;
|
|
248
|
+
const celula = rootRef.current.querySelector('[data-date="' + iso + '"]');
|
|
249
|
+
if (celula)
|
|
250
|
+
celula.focus();
|
|
251
|
+
}
|
|
252
|
+
function handleCellKeyDown(event, iso) {
|
|
253
|
+
if (!event || event.altKey || event.ctrlKey || event.metaKey)
|
|
254
|
+
return;
|
|
255
|
+
// Só o próprio dia navega: a tecla vinda de um evento dentro dele não.
|
|
256
|
+
if (event.target !== event.currentTarget)
|
|
257
|
+
return;
|
|
258
|
+
const tecla = event.key;
|
|
259
|
+
let alvo = "";
|
|
260
|
+
if (tecla === "ArrowLeft")
|
|
261
|
+
alvo = addDays(iso, -1);
|
|
262
|
+
else if (tecla === "ArrowRight")
|
|
263
|
+
alvo = addDays(iso, 1);
|
|
264
|
+
else if (tecla === "ArrowUp")
|
|
265
|
+
alvo = addDays(iso, -7);
|
|
266
|
+
else if (tecla === "ArrowDown")
|
|
267
|
+
alvo = addDays(iso, 7);
|
|
268
|
+
else if (tecla === "Home")
|
|
269
|
+
alvo = startOfWeek(iso, weekStart());
|
|
270
|
+
else if (tecla === "End")
|
|
271
|
+
alvo = addDays(startOfWeek(iso, weekStart()), 6);
|
|
272
|
+
else if (tecla === "PageUp")
|
|
273
|
+
alvo = viewValue() === "week" ? addDays(iso, -7) : addMonths(iso, -1);
|
|
274
|
+
else if (tecla === "PageDown")
|
|
275
|
+
alvo = viewValue() === "week" ? addDays(iso, 7) : addMonths(iso, 1);
|
|
276
|
+
else if (tecla === "Enter" || tecla === " ") {
|
|
277
|
+
event.preventDefault();
|
|
278
|
+
handleDayClick(iso);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
else
|
|
282
|
+
return;
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
irParaDia(alvo);
|
|
285
|
+
}
|
|
286
|
+
function handleCellFocus(event, iso) {
|
|
287
|
+
// Só o foco no próprio dia conta: o foco num evento dentro dele não muda o dia.
|
|
288
|
+
if (event && event.target !== event.currentTarget)
|
|
289
|
+
return;
|
|
290
|
+
if (focusIso !== iso)
|
|
291
|
+
setFocusIso(iso);
|
|
292
|
+
}
|
|
293
|
+
function handleDayClick(iso) {
|
|
294
|
+
setFocusIso(iso);
|
|
295
|
+
if (props.onDayClick)
|
|
296
|
+
props.onDayClick(iso);
|
|
297
|
+
}
|
|
298
|
+
function handleEventClick(event, evento) {
|
|
299
|
+
if (event && event.stopPropagation)
|
|
300
|
+
event.stopPropagation();
|
|
301
|
+
if (props.onEventClick)
|
|
302
|
+
props.onEventClick(evento);
|
|
303
|
+
}
|
|
304
|
+
function handleMoreClick(event, iso) {
|
|
305
|
+
if (event && event.stopPropagation)
|
|
306
|
+
event.stopPropagation();
|
|
307
|
+
const todos = eventMap()[iso] || [];
|
|
308
|
+
if (props.onMoreClick)
|
|
309
|
+
props.onMoreClick(iso, todos.slice(limite()));
|
|
310
|
+
}
|
|
311
|
+
useEffect(() => {
|
|
312
|
+
if (focoPendenteRef.current) {
|
|
313
|
+
const alvo = focoPendenteRef.current;
|
|
314
|
+
focoPendenteRef.current = "";
|
|
315
|
+
focarDia(alvo);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return (_jsxs("div", { ref: rootRef, className: rootClasses(), children: [_jsxs("div", { className: "umds-calendar__toolbar", children: [_jsx("div", { className: "umds-calendar__toolbar-start", children: props.headerStart ? _jsx(_Fragment, { children: props.headerStart }) : null }), _jsxs("div", { className: "umds-calendar__nav", children: [_jsx(Button, { variant: "icon", size: "sm", ariaLabel: props.previousLabel || "Anterior", onClick: (event) => handlePrevious(), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: faChevronLeft }) }), _jsx("span", { "aria-live": "polite", className: "umds-calendar__title", children: titleText() }), _jsx(Button, { variant: "icon", size: "sm", ariaLabel: props.nextLabel || "Próximo", onClick: (event) => handleNext(), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: faChevronRight }) }), _jsx(Button, { variant: "secondary", size: "sm", onClick: (event) => handleToday(), children: props.todayLabel || "Hoje" })] }), _jsxs("div", { className: "umds-calendar__toolbar-end", children: [props.headerEnd ? _jsx(_Fragment, { children: props.headerEnd }) : null, !props.hideViewSwitcher ? (_jsx("div", { role: "group", "aria-label": props.viewLabel || "Visão", children: _jsx(SegmentedControl, { size: "sm", options: viewOptions(), value: viewValue(), onChange: (valor) => mudarVisao(valor) }) })) : null] })] }), _jsxs("div", { role: "grid", className: "umds-calendar__grid", "aria-label": gridLabel(), children: [_jsx("div", { role: "row", className: "umds-calendar__weekdays", children: weekdayHeads()?.map((cabecalho) => (_jsx("div", { role: "columnheader", className: "umds-calendar__weekday", "aria-label": cabecalho.full, children: _jsx("span", { "aria-hidden": "true", children: cabecalho.short }) }, cabecalho.iso))) }), weeks()?.map((semana) => (_jsx("div", { role: "row", className: "umds-calendar__week", children: semana.days?.map((dia) => (_jsxs("div", { role: "gridcell", "data-date": dia.iso, tabIndex: dia.tabIndex, "aria-label": dia.label, "aria-selected": dia.selected ? "true" : undefined, "aria-current": dia.today ? "date" : undefined, onClick: (event) => handleDayClick(dia.iso), onKeyDown: (event) => handleCellKeyDown(event, dia.iso), onFocus: (event) => handleCellFocus(event, dia.iso), className: dia.classes, children: [_jsx("span", { "aria-hidden": "true", className: "umds-calendar__day-number", children: dia.day }), _jsxs("div", { className: "umds-calendar__events", children: [dia.visible?.map((evento, posicao) => (_jsxs("button", { type: "button", className: "umds-calendar__event", style: eventStyle(evento), tabIndex: dia.tabIndex, title: evento.title, onClick: (event) => handleEventClick(event, evento), children: [evento.time ? (_jsx("span", { className: "umds-calendar__event-time", children: evento.time })) : null, _jsx("span", { className: "umds-calendar__event-title", children: evento.title })] }, evento.id || dia.iso + "-" + posicao))), dia.hidden > 0 ? (_jsx("button", { type: "button", className: "umds-calendar__more", tabIndex: dia.tabIndex, "aria-label": dia.moreAria, onClick: (event) => handleMoreClick(event, dia.iso), children: dia.moreText })) : null] })] }, dia.iso))) }, semana.key)))] })] }));
|
|
319
|
+
}
|
|
320
|
+
export default Calendar;
|
|
@@ -28,6 +28,14 @@
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/* ── Tamanhos ── */
|
|
31
|
+
/* xs: 20px de altura (16 + 4, dois degraus do DS somados; sem token próprio).
|
|
32
|
+
Fonte de 12px: a escala do DS não tem o 11px do CrisDoc. */
|
|
33
|
+
.umds-chip--xs {
|
|
34
|
+
height: calc(var(--umds-primitive-spacing-xxxs) + var(--umds-primitive-spacing-quarck));
|
|
35
|
+
padding: 0 var(--umds-primitive-spacing-nano); /* 8px */
|
|
36
|
+
font-size: var(--umds-primitive-font-size-xxxs); /* 12px */
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
.umds-chip--sm {
|
|
32
40
|
height: 24px; /* dimensão do protótipo sem token 1DS */
|
|
33
41
|
padding: 0 8px; /* dimensão do protótipo sem token 1DS */
|
|
@@ -124,6 +132,36 @@
|
|
|
124
132
|
|
|
125
133
|
/* Ícone do X (Icon FA "xmark") — tamanho via customSize no .lite.tsx (8px sm / 10px md) */
|
|
126
134
|
|
|
135
|
+
/* ── × em círculo (circularRemove) ──
|
|
136
|
+
O círculo é um ::before de 14px na cor do texto do chip com 15% de opacidade
|
|
137
|
+
(tinge cada variante sem cor própria); o glifo fica por cima. */
|
|
138
|
+
.umds-chip--remove-circle .umds-chip__remove {
|
|
139
|
+
position: relative;
|
|
140
|
+
opacity: 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.umds-chip--remove-circle .umds-chip__remove::before {
|
|
144
|
+
content: "";
|
|
145
|
+
position: absolute;
|
|
146
|
+
top: 50%;
|
|
147
|
+
left: 50%;
|
|
148
|
+
width: 14px; /* círculo de 14px, como o CrisDoc */
|
|
149
|
+
height: 14px;
|
|
150
|
+
transform: translate(-50%, -50%);
|
|
151
|
+
border-radius: var(--umds-primitive-border-radius-circular);
|
|
152
|
+
background-color: currentColor;
|
|
153
|
+
opacity: 0.15;
|
|
154
|
+
transition: opacity var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.umds-chip--remove-circle .umds-chip__remove:hover:not(:disabled)::before {
|
|
158
|
+
opacity: 0.3;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.umds-chip--remove-circle .umds-chip__remove > * {
|
|
162
|
+
position: relative; /* o glifo fica acima do círculo */
|
|
163
|
+
}
|
|
164
|
+
|
|
127
165
|
/* ── Filter chip (onClick/selected) ── */
|
|
128
166
|
/* Botão transparente do label: herda tudo do chip — visual em repouso idêntico. */
|
|
129
167
|
.umds-chip__action {
|
|
@@ -5,7 +5,8 @@ import './Chips.css';
|
|
|
5
5
|
* @property {string} label - Texto exibido no chip (obrigatório)
|
|
6
6
|
* @property {boolean} removable - Exibe o botão × para remover o chip
|
|
7
7
|
* @property {boolean} disabled - Desabilita o chip (visual esmaecido e sem interação)
|
|
8
|
-
* @property {string} size - Tamanho do chip: 'sm' | 'md'
|
|
8
|
+
* @property {string} size - Tamanho do chip: 'xs' (20px, para dentro de card e linha de lista) | 'sm' (24px) | 'md' (28px)
|
|
9
|
+
* @property {boolean} circularRemove - Põe o × do chip removível dentro de um círculo tingido da cor do chip (o marcador do card da inbox). Só vale com `removable`.
|
|
9
10
|
* @property {string} variant - Variante visual: 'default' | 'primary' | 'positive' | 'negative' | 'info'
|
|
10
11
|
* @property {boolean} selected - Estado selecionado (filter chip) — vira aria-pressed
|
|
11
12
|
* @property {function} onClick - Torna o chip acionável (filter chip): o label vira um
|
|
@@ -19,7 +20,9 @@ export interface ChipsProps {
|
|
|
19
20
|
label: string;
|
|
20
21
|
removable?: boolean;
|
|
21
22
|
disabled?: boolean;
|
|
22
|
-
size?: "sm" | "md";
|
|
23
|
+
size?: "xs" | "sm" | "md";
|
|
24
|
+
/** × dentro de um círculo tingido da cor do chip. Só vale com `removable`. @default false */
|
|
25
|
+
circularRemove?: boolean;
|
|
23
26
|
variant?: "default" | "primary" | "positive" | "negative" | "info";
|
|
24
27
|
/** Estado selecionado do filter chip (comunicado via aria-pressed) */
|
|
25
28
|
selected?: boolean;
|
|
@@ -11,6 +11,7 @@ function Chips(props) {
|
|
|
11
11
|
`umds-chip--${props.variant || "default"}`,
|
|
12
12
|
props.disabled ? "umds-chip--disabled" : "",
|
|
13
13
|
props.removable ? "umds-chip--removable" : "",
|
|
14
|
+
props.removable && props.circularRemove ? "umds-chip--remove-circle" : "",
|
|
14
15
|
props.selected ? "umds-chip--selected" : "",
|
|
15
16
|
props.onClick ? "umds-chip--clickable" : "",
|
|
16
17
|
props.className,
|
|
@@ -19,7 +20,7 @@ function Chips(props) {
|
|
|
19
20
|
.join(" ");
|
|
20
21
|
}
|
|
21
22
|
function iconSize() {
|
|
22
|
-
return props.size === "sm" ? "8px" : "10px";
|
|
23
|
+
return props.size === "sm" || props.size === "xs" ? "8px" : "10px";
|
|
23
24
|
}
|
|
24
25
|
function removeLabelText() {
|
|
25
26
|
return (props.removeAriaLabel || "Remover") + " " + props.label;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* ─────────────────────────────────────────────
|
|
2
|
+
COACHMARK
|
|
3
|
+
Tour guiado: véu com recorte no alvo e um cartão que o aponta.
|
|
4
|
+
|
|
5
|
+
O recorte é uma caixa transparente cuja SOMBRA enorme escurece o resto da
|
|
6
|
+
página (um buraco no véu sem máscara nem SVG). Quando o passo não tem alvo,
|
|
7
|
+
o véu é cheio e o cartão vai ao centro.
|
|
8
|
+
|
|
9
|
+
Cores: semânticos · Medidas: primitivos
|
|
10
|
+
───────────────────────────────────────────── */
|
|
11
|
+
|
|
12
|
+
.umds-coachmark {
|
|
13
|
+
position: fixed;
|
|
14
|
+
top: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
z-index: var(--umds-semantic-layer-popover);
|
|
19
|
+
font-family: var(--umds-semantic-font-family-base);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Captura o clique: a página atrás fica inerte durante o tour. */
|
|
23
|
+
.umds-coachmark__veil {
|
|
24
|
+
position: absolute;
|
|
25
|
+
top: 0;
|
|
26
|
+
left: 0;
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.umds-coachmark--no-target .umds-coachmark__veil {
|
|
32
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token de scrim/overlay (candidato a novo token); mesmo valor do Modal */
|
|
33
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.umds-coachmark__cutout {
|
|
37
|
+
position: absolute;
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
border-radius: var(--umds-primitive-border-radius-sm);
|
|
41
|
+
/* 100vmax: maior que qualquer tela, o recorte nunca deixa a borda do véu à mostra. */
|
|
42
|
+
/* stylelint-disable-next-line 1ds/cor-por-token -- o DS não tem token de scrim/overlay (candidato a novo token); mesmo valor do Modal */
|
|
43
|
+
box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.4);
|
|
44
|
+
transition:
|
|
45
|
+
top var(--umds-semantic-motion-duration-base) var(--umds-semantic-motion-easing-standard),
|
|
46
|
+
left var(--umds-semantic-motion-duration-base) var(--umds-semantic-motion-easing-standard),
|
|
47
|
+
width var(--umds-semantic-motion-duration-base) var(--umds-semantic-motion-easing-standard),
|
|
48
|
+
height var(--umds-semantic-motion-duration-base) var(--umds-semantic-motion-easing-standard);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* ── Cartão ── */
|
|
52
|
+
.umds-coachmark__card {
|
|
53
|
+
position: absolute;
|
|
54
|
+
top: 0;
|
|
55
|
+
left: 0;
|
|
56
|
+
box-sizing: border-box;
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
gap: var(--umds-primitive-spacing-nano); /* 8px */
|
|
60
|
+
/* 360px: 200px + 160px da escala; nunca passa da tela. */
|
|
61
|
+
width: calc(var(--umds-primitive-spacing-giant) + var(--umds-primitive-spacing-huge));
|
|
62
|
+
max-width: calc(100vw - var(--umds-primitive-spacing-xs));
|
|
63
|
+
padding: var(--umds-primitive-spacing-xxs); /* 24px */
|
|
64
|
+
background: var(--umds-semantic-color-background-white);
|
|
65
|
+
color: var(--umds-semantic-color-neutral-dark-pure);
|
|
66
|
+
border-radius: var(--umds-primitive-border-radius-md); /* 16px */
|
|
67
|
+
box-shadow: var(--umds-primitive-shadow-level-3);
|
|
68
|
+
outline: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.umds-coachmark__card--centered {
|
|
72
|
+
top: 50%;
|
|
73
|
+
left: 50%;
|
|
74
|
+
transform: translate(-50%, -50%);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.umds-coachmark__card:focus-visible {
|
|
78
|
+
outline: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-primary-pure);
|
|
79
|
+
outline-offset: calc(var(--umds-primitive-border-width-thin) * -1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.umds-coachmark__footer {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: space-between;
|
|
86
|
+
gap: var(--umds-primitive-spacing-nano); /* 8px */
|
|
87
|
+
margin-top: var(--umds-primitive-spacing-nano);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.umds-coachmark__actions {
|
|
91
|
+
display: inline-flex;
|
|
92
|
+
gap: var(--umds-primitive-spacing-nano); /* 8px */
|
|
93
|
+
margin-left: auto;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Só para leitor de tela: "2 de 8: título", a cada passo. */
|
|
97
|
+
.umds-coachmark__sr {
|
|
98
|
+
position: absolute;
|
|
99
|
+
width: 1px;
|
|
100
|
+
height: 1px;
|
|
101
|
+
padding: 0;
|
|
102
|
+
margin: -1px;
|
|
103
|
+
overflow: hidden;
|
|
104
|
+
clip: rect(0, 0, 0, 0);
|
|
105
|
+
clip-path: inset(50%);
|
|
106
|
+
white-space: nowrap;
|
|
107
|
+
border: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* ── modal={false}: sem véu nem recorte, a página segue clicável ──
|
|
111
|
+
A raiz cobre a tela só para posicionar o cartão; quem recebe o ponteiro é o cartão. */
|
|
112
|
+
.umds-coachmark--modeless {
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.umds-coachmark--modeless .umds-coachmark__card {
|
|
117
|
+
pointer-events: auto;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@media (forced-colors: active) {
|
|
121
|
+
.umds-coachmark__card {
|
|
122
|
+
border: var(--umds-primitive-border-width-thin) solid CanvasText;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.umds-coachmark__cutout {
|
|
126
|
+
outline: var(--umds-primitive-border-width-thin) solid Highlight;
|
|
127
|
+
}
|
|
128
|
+
}
|