@1doc/1ds-react 0.0.1 → 2.7.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.
Files changed (101) hide show
  1. package/CHANGELOG.md +667 -0
  2. package/README.md +138 -6
  3. package/package.json +43 -10
  4. package/src/index.ts +161 -16
  5. package/src/teste/AttachmentCard.test.tsx +161 -0
  6. package/src/teste/Chart.test.tsx +233 -0
  7. package/src/teste/Combobox.test.tsx +251 -0
  8. package/src/teste/DataTable.test.tsx +70 -0
  9. package/src/teste/DatePicker.test.tsx +86 -0
  10. package/src/teste/Drawer.test.tsx +265 -0
  11. package/src/teste/Dropdown.test.tsx +217 -0
  12. package/src/teste/Input.test.tsx +64 -0
  13. package/src/teste/Kanban.test.tsx +333 -0
  14. package/src/teste/MultiSelect.test.tsx +73 -0
  15. package/src/teste/Podium.test.tsx +107 -0
  16. package/src/teste/Popover.test.tsx +221 -0
  17. package/src/teste/SegmentedControl.test.tsx +183 -0
  18. package/src/teste/Timeline.test.tsx +100 -0
  19. package/src/teste/Tree.test.tsx +74 -0
  20. package/src/teste/setup.ts +7 -0
  21. package/src/utils/bandeiras.ts +22 -0
  22. package/src/utils/chart.ts +682 -0
  23. package/src/utils/density.ts +27 -0
  24. package/src/utils/overlay-stack.ts +26 -0
  25. package/src/utils/theme.ts +63 -47
  26. package/src/utils/toast.ts +89 -0
  27. package/vitest.config.ts +28 -0
  28. package/dist/components/Alert/Alert.css +0 -188
  29. package/dist/components/Alert/Alert.d.ts +0 -65
  30. package/dist/components/Alert/Alert.js +0 -56
  31. package/dist/components/Avatar/Avatar.css +0 -88
  32. package/dist/components/Avatar/Avatar.d.ts +0 -34
  33. package/dist/components/Avatar/Avatar.js +0 -16
  34. package/dist/components/Avatar/AvatarGroup.d.ts +0 -12
  35. package/dist/components/Avatar/AvatarGroup.js +0 -8
  36. package/dist/components/Badge/Badge.css +0 -155
  37. package/dist/components/Badge/Badge.d.ts +0 -46
  38. package/dist/components/Badge/Badge.js +0 -17
  39. package/dist/components/Button/Button.css +0 -199
  40. package/dist/components/Button/Button.d.ts +0 -23
  41. package/dist/components/Button/Button.js +0 -62
  42. package/dist/components/Checkbox/Checkbox.css +0 -122
  43. package/dist/components/Checkbox/Checkbox.d.ts +0 -21
  44. package/dist/components/Checkbox/Checkbox.js +0 -49
  45. package/dist/components/Divider/Divider.css +0 -81
  46. package/dist/components/Divider/Divider.d.ts +0 -18
  47. package/dist/components/Divider/Divider.js +0 -26
  48. package/dist/components/Grid/Grid.css +0 -154
  49. package/dist/components/Grid/Grid.d.ts +0 -21
  50. package/dist/components/Grid/Grid.js +0 -53
  51. package/dist/components/Icon/Icon.css +0 -41
  52. package/dist/components/Icon/Icon.d.ts +0 -12
  53. package/dist/components/Icon/Icon.js +0 -29
  54. package/dist/components/Input/Input.css +0 -190
  55. package/dist/components/Input/Input.d.ts +0 -32
  56. package/dist/components/Input/Input.js +0 -58
  57. package/dist/components/Link/Link.css +0 -76
  58. package/dist/components/Link/Link.d.ts +0 -15
  59. package/dist/components/Link/Link.js +0 -19
  60. package/dist/components/Logo/Logo.css +0 -32
  61. package/dist/components/Logo/Logo.d.ts +0 -10
  62. package/dist/components/Logo/Logo.js +0 -16
  63. package/dist/components/Modal/Modal.css +0 -155
  64. package/dist/components/Modal/Modal.d.ts +0 -36
  65. package/dist/components/Modal/Modal.js +0 -55
  66. package/dist/components/Radio/Radio.css +0 -114
  67. package/dist/components/Radio/Radio.d.ts +0 -19
  68. package/dist/components/Radio/Radio.js +0 -39
  69. package/dist/components/Select/Select.css +0 -291
  70. package/dist/components/Select/Select.d.ts +0 -38
  71. package/dist/components/Select/Select.js +0 -246
  72. package/dist/components/Spinner/Spinner.css +0 -60
  73. package/dist/components/Spinner/Spinner.d.ts +0 -16
  74. package/dist/components/Spinner/Spinner.js +0 -16
  75. package/dist/components/Switch/Switch.css +0 -127
  76. package/dist/components/Switch/Switch.d.ts +0 -18
  77. package/dist/components/Switch/Switch.js +0 -57
  78. package/dist/components/Tabs/Tab.d.ts +0 -19
  79. package/dist/components/Tabs/Tab.js +0 -76
  80. package/dist/components/Tabs/TabContent.d.ts +0 -15
  81. package/dist/components/Tabs/TabContent.js +0 -11
  82. package/dist/components/Tabs/Tabs.css +0 -124
  83. package/dist/components/Tabs/Tabs.d.ts +0 -20
  84. package/dist/components/Tabs/Tabs.js +0 -14
  85. package/dist/components/Tabs/TabsContent.d.ts +0 -16
  86. package/dist/components/Tabs/TabsContent.js +0 -12
  87. package/dist/components/Tabs/tabs.context.d.ts +0 -2
  88. package/dist/components/Tabs/tabs.context.js +0 -2
  89. package/dist/components/Tag/Tag.css +0 -140
  90. package/dist/components/Tag/Tag.d.ts +0 -63
  91. package/dist/components/Tag/Tag.js +0 -48
  92. package/dist/components/Text/Text.css +0 -1213
  93. package/dist/components/Text/Text.d.ts +0 -70
  94. package/dist/components/Text/Text.js +0 -89
  95. package/dist/components/Textarea/Textarea.css +0 -133
  96. package/dist/components/Textarea/Textarea.d.ts +0 -28
  97. package/dist/components/Textarea/Textarea.js +0 -72
  98. package/dist/index.d.ts +0 -25
  99. package/dist/index.js +0 -27
  100. package/dist/utils/theme.d.ts +0 -30
  101. package/dist/utils/theme.js +0 -106
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pilha global de overlays de diálogo abertos (Modal, ConfirmDialog).
3
+ *
4
+ * Motivação (simulação de adoção, time SaaS RH): Modal e ConfirmDialog
5
+ * escutavam Esc no document de forma independente — um único Esc com um
6
+ * ConfirmDialog empilhado sobre um Modal fechava os dois. Com a pilha,
7
+ * apenas o overlay do TOPO reage ao Esc.
8
+ *
9
+ * Singleton por bundle (estado de módulo), compartilhado entre os
10
+ * componentes gerados React e Vue.
11
+ */
12
+ const stack: string[] = [];
13
+
14
+ /** Registra um overlay aberto no topo da pilha (idempotente). */
15
+ export const pushOverlay = (id: string): void => {
16
+ if (!stack.includes(id)) stack.push(id);
17
+ };
18
+
19
+ /** Remove um overlay da pilha (ao fechar ou desmontar). */
20
+ export const removeOverlay = (id: string): void => {
21
+ const index = stack.indexOf(id);
22
+ if (index !== -1) stack.splice(index, 1);
23
+ };
24
+
25
+ /** true se o overlay é o do topo — o único que deve reagir ao Esc. */
26
+ export const isTopOverlay = (id: string): boolean => stack.length > 0 && stack[stack.length - 1] === id
@@ -1,12 +1,14 @@
1
1
  /**
2
- * Tipos de temas disponíveis no Design System
2
+ * Tipos de temas oficiais do Design System
3
3
  */
4
- export type Theme =
5
- | "1doc"
6
- | "1ds-red"
7
- | "1ds-green"
8
- | "1ds-orange"
9
- | "1ds-yellow";
4
+ export type Theme = "1doc" | "1ds-red" | "1ds-green" | "1ds-orange" | "1ds-yellow" | "1ds-purple" | "1doc-dark" | "1ds-red-dark" | "1ds-green-dark" | "1ds-orange-dark" | "1ds-yellow-dark" | "1ds-purple-dark" | "1doc-high-contrast";
5
+
6
+ /**
7
+ * Nome de tema aceito pelas APIs: um tema oficial OU um tema custom de
8
+ * marca própria registrado via registerTheme() (white-label).
9
+ * O truque `(string & {})` preserva o autocomplete dos oficiais.
10
+ */
11
+ export type ThemeName = Theme | (string & {});
10
12
 
11
13
  /**
12
14
  * Chave do localStorage para armazenar o tema selecionado
@@ -18,14 +20,43 @@ const THEME_STORAGE_KEY = "umds-theme";
18
20
  */
19
21
  const DEFAULT_THEME: Theme = "1doc";
20
22
 
23
+ /**
24
+ * Temas oficiais (fonte única para validação e getAvailableThemes)
25
+ */
26
+ const OFFICIAL_THEMES: Theme[] = ["1doc", "1ds-red", "1ds-green", "1ds-orange", "1ds-yellow", "1ds-purple", "1doc-dark", "1ds-red-dark", "1ds-green-dark", "1ds-orange-dark", "1ds-yellow-dark", "1ds-purple-dark", "1doc-high-contrast"];
27
+
28
+ /**
29
+ * Temas custom registrados em runtime (white-label).
30
+ */
31
+ const customThemes: string[] = [];
32
+
33
+ /**
34
+ * Registra um tema de marca própria (white-label) para que setTheme,
35
+ * getTheme, initTheme e onThemeChange o aceitem como válido.
36
+ *
37
+ * O CSS do tema é responsabilidade do consumidor: um arquivo com
38
+ * `[data-theme="<nome>"]` sobrescrevendo os tokens de tema
39
+ * (`--umds-theme-*`) ou os semânticos (`--umds-semantic-color-*`),
40
+ * carregado após o semantic.css.
41
+ *
42
+ * @example
43
+ * registerTheme("acme");
44
+ * registerTheme("acme-dark");
45
+ * setTheme("acme"); // agora válido e persistido
46
+ */
47
+ export const registerTheme = (theme: string): void => {
48
+ if (!customThemes.includes(theme) && !OFFICIAL_THEMES.includes(theme as Theme)) {
49
+ customThemes.push(theme);
50
+ }
51
+ };
52
+
21
53
  /**
22
54
  * Define o tema ativo no documento
23
- * @param theme - Nome do tema a ser aplicado
55
+ * @param theme - Nome do tema a ser aplicado (oficial ou registrado)
24
56
  */
25
- export const setTheme = (theme: Theme): void => {
57
+ export const setTheme = (theme: ThemeName): void => {
26
58
  if (typeof document !== "undefined") {
27
59
  document.documentElement.setAttribute("data-theme", theme);
28
-
29
60
  try {
30
61
  localStorage.setItem(THEME_STORAGE_KEY, theme);
31
62
  } catch (e) {
@@ -36,17 +67,19 @@ export const setTheme = (theme: Theme): void => {
36
67
  };
37
68
 
38
69
  /**
39
- * Obtém o tema atual, considerando localStorage e preferências do sistema
70
+ * Obtém o tema atual, considerando localStorage e preferências do sistema.
71
+ * Temas custom precisam estar registrados (registerTheme) ANTES da leitura,
72
+ * senão o valor persistido é descartado em favor do padrão.
40
73
  * @returns O tema atualmente selecionado
41
74
  */
42
- export const getTheme = (): Theme => {
75
+ export const getTheme = (): ThemeName => {
43
76
  if (typeof window === "undefined") {
44
77
  return DEFAULT_THEME;
45
78
  }
46
79
 
47
80
  // 1. Tenta buscar do localStorage
48
81
  try {
49
- const stored = localStorage.getItem(THEME_STORAGE_KEY) as Theme | null;
82
+ const stored = localStorage.getItem(THEME_STORAGE_KEY);
50
83
  if (stored && isValidTheme(stored)) {
51
84
  return stored;
52
85
  }
@@ -55,9 +88,7 @@ export const getTheme = (): Theme => {
55
88
  }
56
89
 
57
90
  // 2. Tenta buscar do atributo data-theme do HTML
58
- const currentTheme = document.documentElement.getAttribute(
59
- "data-theme",
60
- ) as Theme | null;
91
+ const currentTheme = document.documentElement.getAttribute("data-theme");
61
92
  if (currentTheme && isValidTheme(currentTheme)) {
62
93
  return currentTheme;
63
94
  }
@@ -68,7 +99,9 @@ export const getTheme = (): Theme => {
68
99
 
69
100
  /**
70
101
  * Inicializa o tema ao carregar a página
71
- * Deve ser chamado o mais cedo possível para evitar flash de conteúdo
102
+ * Deve ser chamado o mais cedo possível para evitar flash de conteúdo.
103
+ * White-label: chame registerTheme() antes de initTheme() para que o tema
104
+ * custom persistido no localStorage seja restaurado.
72
105
  */
73
106
  export const initTheme = (): void => {
74
107
  const theme = getTheme();
@@ -76,27 +109,20 @@ export const initTheme = (): void => {
76
109
  };
77
110
 
78
111
  /**
79
- * Valida se uma string é um tema válido
112
+ * Valida se uma string é um tema válido (oficial ou registrado)
80
113
  * @param theme - String a ser validada
81
114
  * @returns true se o tema é válido
82
115
  */
83
- function isValidTheme(theme: string): theme is Theme {
84
- const validThemes: Theme[] = [
85
- "1doc",
86
- "1ds-red",
87
- "1ds-green",
88
- "1ds-orange",
89
- "1ds-yellow",
90
- ];
91
- return validThemes.includes(theme as Theme);
116
+ function isValidTheme(theme: string): boolean {
117
+ return OFFICIAL_THEMES.includes(theme as Theme) || customThemes.includes(theme);
92
118
  }
93
119
 
94
120
  /**
95
- * Retorna todos os temas disponíveis
121
+ * Retorna todos os temas disponíveis (oficiais + registrados)
96
122
  * @returns Array com todos os temas disponíveis
97
123
  */
98
- export const getAvailableThemes = (): Theme[] => {
99
- return ["1doc", "1ds-red", "1ds-green", "1ds-orange", "1ds-yellow"];
124
+ export const getAvailableThemes = (): ThemeName[] => {
125
+ return [...OFFICIAL_THEMES, ...customThemes];
100
126
  };
101
127
 
102
128
  /**
@@ -104,33 +130,23 @@ export const getAvailableThemes = (): Theme[] => {
104
130
  * @param callback - Função a ser executada quando o tema mudar
105
131
  * @returns Função para remover o listener
106
132
  */
107
- export const onThemeChange = (
108
- callback: (theme: Theme) => void,
109
- ): (() => void) => {
133
+ export const onThemeChange = (callback: (theme: ThemeName) => void): (() => void) => {
110
134
  if (typeof window === "undefined") {
111
135
  return () => {};
112
136
  }
113
-
114
- const observer = new MutationObserver((mutations) => {
115
- mutations.forEach((mutation) => {
116
- if (
117
- mutation.type === "attributes" &&
118
- mutation.attributeName === "data-theme"
119
- ) {
120
- const newTheme = document.documentElement.getAttribute(
121
- "data-theme",
122
- ) as Theme;
137
+ const observer = new MutationObserver(mutations => {
138
+ mutations.forEach(mutation => {
139
+ if (mutation.type === "attributes" && mutation.attributeName === "data-theme") {
140
+ const newTheme = document.documentElement.getAttribute("data-theme");
123
141
  if (newTheme && isValidTheme(newTheme)) {
124
142
  callback(newTheme);
125
143
  }
126
144
  }
127
145
  });
128
146
  });
129
-
130
147
  observer.observe(document.documentElement, {
131
148
  attributes: true,
132
- attributeFilter: ["data-theme"],
149
+ attributeFilter: ["data-theme"]
133
150
  });
134
-
135
151
  return () => observer.disconnect();
136
- };
152
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Gerenciador imperativo de toasts com fila (achado 4/5 times na simulação
3
+ * de adoção: o Toast declarativo obrigava cada app a criar um host próprio,
4
+ * e mensagens em sequência se atropelavam).
5
+ *
6
+ * Uso:
7
+ * 1. Monte UM `<ToastStack />` na raiz do app (define a posição da pilha).
8
+ * 2. Dispare de qualquer lugar: `toast({ message: "Salvo!", variant: "positive" })`.
9
+ *
10
+ * O componente declarativo `<Toast />` continua existindo como primitiva
11
+ * para casos controlados simples.
12
+ *
13
+ * Framework-agnóstico: estado de módulo + pub/sub (singleton por bundle),
14
+ * consumido pelos ToastStack gerados de React e Vue.
15
+ */
16
+
17
+ export type ToastVariant = "positive" | "negative" | "info";
18
+ export interface ToastOptions {
19
+ /** Mensagem principal do toast */
20
+ message: string;
21
+ /** Descrição adicional abaixo da mensagem */
22
+ description?: string;
23
+ /** Variante semântica @default 'info' */
24
+ variant?: ToastVariant;
25
+ /** Auto-dismiss em ms; 0 = não fecha sozinho @default 5000 */
26
+ duration?: number;
27
+ /** Exibe o botão de fechar @default true */
28
+ closable?: boolean;
29
+ }
30
+ export interface ToastData {
31
+ id: number;
32
+ message: string;
33
+ description?: string;
34
+ variant: ToastVariant;
35
+ duration: number;
36
+ closable: boolean;
37
+ }
38
+ type ToastListener = (items: ToastData[]) => void;
39
+ let sequence = 0;
40
+ let items: ToastData[] = [];
41
+ const listeners: ToastListener[] = [];
42
+ const notify = (): void => {
43
+ const snapshot = [...items];
44
+ listeners.forEach(listener => listener(snapshot));
45
+ };
46
+
47
+ /** Enfileira um toast e retorna o id (para dismiss programático). */
48
+ export const toast = (options: ToastOptions): number => {
49
+ sequence += 1;
50
+ const id = sequence;
51
+ items = [...items, {
52
+ variant: "info",
53
+ duration: 5000,
54
+ closable: true,
55
+ ...options,
56
+ id
57
+ }];
58
+ notify();
59
+ return id;
60
+ };
61
+
62
+ /** Remove um toast específico da pilha. */
63
+ export const dismissToast = (id: number): void => {
64
+ const next = items.filter(item => item.id !== id);
65
+ if (next.length !== items.length) {
66
+ items = next;
67
+ notify();
68
+ }
69
+ };
70
+
71
+ /** Limpa a pilha inteira. */
72
+ export const dismissAllToasts = (): void => {
73
+ if (items.length === 0) return;
74
+ items = [];
75
+ notify();
76
+ };
77
+
78
+ /**
79
+ * Inscreve um listener (chamado imediatamente com o estado atual).
80
+ * Retorna a função de desinscrição. Usado pelo ToastStack.
81
+ */
82
+ export const subscribeToasts = (listener: ToastListener): (() => void) => {
83
+ listeners.push(listener);
84
+ listener([...items]);
85
+ return () => {
86
+ const index = listeners.indexOf(listener);
87
+ if (index !== -1) listeners.splice(index, 1);
88
+ };
89
+ }
@@ -0,0 +1,28 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ /**
4
+ * Testes unitários dos componentes GERADOS em React.
5
+ *
6
+ * Por que aqui e não no `core`: o `.lite.tsx` não roda — é fonte para o
7
+ * Mitosis. O que o consumidor instala é o gerado, e é dele que o teste tem de
8
+ * falar. Um teste que passa no core e quebra no gerado não serve.
9
+ *
10
+ * O que estes testes cobrem, e a esteira visual não: comportamento. Tecla,
11
+ * foco, o que o callback recebe, o que o `aria-` diz. A esteira garante que a
12
+ * tela não mudou; o teste garante que ela ainda FUNCIONA.
13
+ */
14
+ export default defineConfig({
15
+ test: {
16
+ environment: "jsdom",
17
+ globals: true,
18
+ setupFiles: ["./src/teste/setup.ts"],
19
+ // Os testes vivem em `src/teste/`, e NÃO ao lado do componente: a pasta
20
+ // `src/components` é gerada pelo Mitosis, está no .gitignore e é reescrita
21
+ // a cada build — um teste ali não seria versionado e sumiria no build.
22
+ include: ["src/teste/**/*.test.tsx"],
23
+ // O CSS dos componentes é importado por efeito colateral (`import "./X.css"`).
24
+ // Sem processá-lo, o import resolve para vazio — que é o que se quer: o
25
+ // teste é de comportamento, e estilo quem verifica é a regressão visual.
26
+ css: false,
27
+ },
28
+ });
@@ -1,188 +0,0 @@
1
- /* ============================================
2
- Alert Component
3
- Tipos: neutral, success, warning, error
4
- Variantes: soft, solid
5
- ============================================ */
6
-
7
- .umds-alert {
8
- display: flex;
9
- align-items: flex-start;
10
- gap: 16px;
11
- padding: 16px;
12
- border-radius: 8px;
13
- box-sizing: border-box;
14
- width: 475px;
15
- max-width: calc(100vw - 32px);
16
- transition: all 0.3s ease;
17
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
18
-
19
- font-family: var(--umds-semantic-font-family-base, 'Open Sans', 'Inter', sans-serif);
20
- position: fixed;
21
- z-index: 9999;
22
- }
23
-
24
- /* ----------------------------------------
25
- Positioning modifiers
26
- ---------------------------------------- */
27
- .umds-alert--top-right {
28
- top: 24px;
29
- right: 24px;
30
- }
31
- .umds-alert--top-left {
32
- top: 24px;
33
- left: 24px;
34
- }
35
- .umds-alert--top-center {
36
- top: 24px;
37
- left: 50%;
38
- transform: translateX(-50%);
39
- }
40
- .umds-alert--bottom-right {
41
- bottom: 24px;
42
- right: 24px;
43
- }
44
- .umds-alert--bottom-left {
45
- bottom: 24px;
46
- left: 24px;
47
- }
48
- .umds-alert--bottom-center {
49
- bottom: 24px;
50
- left: 50%;
51
- transform: translateX(-50%);
52
- }
53
-
54
- /* ----------------------------------------
55
- Internal elements
56
- ---------------------------------------- */
57
- .umds-alert__icon-wrapper {
58
- display: flex;
59
- align-items: flex-start;
60
- flex-shrink: 0;
61
- margin-top: 2px;
62
- }
63
-
64
- .umds-alert__content {
65
- display: flex;
66
- flex-direction: column;
67
- gap: 4px;
68
- flex: 1 1 0;
69
- min-width: 0;
70
- }
71
-
72
- .umds-alert__title-container {
73
- display: flex;
74
- width: 100%;
75
- align-items: flex-start;
76
- }
77
-
78
- .umds-alert__title-text {
79
- font-weight: var(--umds-primitive-font-weight-semibold, 600) !important;
80
- font-size: var(--umds-primitive-font-size-xxxxs, 12px) !important;
81
- margin: 0;
82
- line-height: normal;
83
- letter-spacing: 0.06px;
84
- }
85
-
86
- .umds-alert__description-text {
87
- font-weight: var(--umds-primitive-font-weight-regular, 400) !important;
88
- font-size: var(--umds-primitive-font-size-xxxxs, 12px) !important;
89
- margin: 0;
90
- line-height: normal;
91
- letter-spacing: 0.06px;
92
- }
93
-
94
- .umds-alert__actions {
95
- display: flex;
96
- gap: 8px;
97
- padding-top: 8px;
98
- align-items: flex-start;
99
- }
100
-
101
- .umds-alert__close {
102
- all: unset;
103
- display: flex;
104
- align-items: center;
105
- justify-content: center;
106
- flex-shrink: 0;
107
- width: 24px;
108
- height: 24px;
109
- cursor: pointer;
110
- border-radius: 4px;
111
- transition: opacity 0.2s ease, background-color 0.2s ease;
112
- }
113
-
114
- .umds-alert__close:hover,
115
- .umds-alert__close:focus-visible {
116
- opacity: 0.8;
117
- background-color: rgba(0, 0, 0, 0.05); /* very soft fallback highlight */
118
- }
119
-
120
- .umds-alert__close:focus-visible {
121
- outline: 2px solid var(--umds-semantic-color-primary-pure);
122
- outline-offset: 1px;
123
- }
124
-
125
- /* ----------------------------------------
126
- Theme Variantes: SOFT
127
- ---------------------------------------- */
128
-
129
- /* Neutral Soft */
130
- .umds-alert--soft.umds-alert--neutral {
131
- background-color: var(--umds-semantic-color-background-white, white);
132
- color: var(--umds-semantic-color-neutral-dark-pure, #333);
133
- }
134
-
135
- /* Warning Soft (Uses info tokens on 1ds standard for warning logic from figma) */
136
- .umds-alert--soft.umds-alert--warning {
137
- background-color: var(--umds-semantic-color-feedback-info-light, #ffe9d9);
138
- border: 1px solid var(--umds-semantic-color-feedback-info-pure, #db6816);
139
- color: var(--umds-semantic-color-feedback-info-dark, #99470c);
140
- }
141
-
142
- /* Success Soft */
143
- .umds-alert--soft.umds-alert--success {
144
- background-color: var(--umds-semantic-color-feedback-positive-light, #cef2e1);
145
- border: 1px solid var(--umds-semantic-color-feedback-positive-pure, #0f874e);
146
- color: var(--umds-semantic-color-feedback-positive-dark, #0f4c30);
147
- }
148
-
149
- /* Error Soft */
150
- .umds-alert--soft.umds-alert--error {
151
- background-color: var(--umds-semantic-color-feedback-negative-light, #ffe6ea);
152
- border: 1px solid var(--umds-semantic-color-feedback-negative-pure, #b2132e);
153
- color: var(--umds-semantic-color-feedback-negative-dark, #801224);
154
- }
155
-
156
- /* ----------------------------------------
157
- Theme Variantes: SOLID
158
- ---------------------------------------- */
159
-
160
- /* Neutral Solid */
161
- .umds-alert--solid.umds-alert--neutral {
162
- background-color: var(--umds-semantic-color-neutral-dark-pure, #333333);
163
- color: var(--umds-semantic-color-neutral-light-pure, #ffffff);
164
- }
165
-
166
- /* Warning Solid */
167
- .umds-alert--solid.umds-alert--warning {
168
- background-color: var(--umds-semantic-color-feedback-info-pure, #db6816);
169
- color: var(--umds-semantic-color-neutral-light-pure, #ffffff);
170
- }
171
-
172
- /* Success Solid */
173
- .umds-alert--solid.umds-alert--success {
174
- background-color: var(--umds-semantic-color-feedback-positive-pure, #0f874e);
175
- color: var(--umds-semantic-color-neutral-light-pure, #ffffff);
176
- }
177
-
178
- /* Error Solid */
179
- .umds-alert--solid.umds-alert--error {
180
- background-color: var(--umds-semantic-color-feedback-negative-pure, #b2132e);
181
- color: var(--umds-semantic-color-neutral-light-pure, #ffffff);
182
- }
183
-
184
- /* Overrides for close icon on SOLID */
185
- .umds-alert--solid .umds-alert__close:hover,
186
- .umds-alert--solid .umds-alert__close:focus-visible {
187
- background-color: rgba(255, 255, 255, 0.15);
188
- }
@@ -1,65 +0,0 @@
1
- import './Alert.css';
2
- /**
3
- * Componente Alert é utilizado para comunicar mensagens importantes que requerem a atenção imediata do usuário.
4
- * Pode indicar sucessos, avisos, erros ou informações relevantes de forma clara e destacada.
5
- */
6
- export interface AlertProps {
7
- /**
8
- * Título do alerta.
9
- */
10
- title?: string;
11
- /**
12
- * Propriedade obrigatória do aviso que explica do que se trata o alerta.
13
- */
14
- description?: string;
15
- /**
16
- * Tipo/Cor semântico do alerta.
17
- * @default 'neutral'
18
- */
19
- type?: "neutral" | "success" | "warning" | "error";
20
- /**
21
- * Estilo visual ('soft' para fundos claros; 'solid' para preenchimentos escuros/cores fortes).
22
- * @default 'soft'
23
- */
24
- variant?: "soft" | "solid";
25
- /**
26
- * Posição vertical na tela para a exibição flutuante.
27
- * @default 'top'
28
- */
29
- verticalPosition?: "top" | "bottom";
30
- /**
31
- * Posição horizontal na tela para a exibição flutuante.
32
- * @default 'right'
33
- */
34
- horizontalPosition?: "left" | "center" | "right";
35
- /**
36
- * Tempo em milissegundos que o alerta ficará na tela e desaparecerá.
37
- * Se 0, ou não definido, o alerta não desaparece de forma automática.
38
- * @default 0
39
- */
40
- time?: number;
41
- /**
42
- * Define ou não a visibilidade do ícone de dispensar o aviso.
43
- * @default false
44
- */
45
- dismissable?: boolean;
46
- /**
47
- * Possibilita uso de elementos HTML/Componentes JSX ou text simples no bloco de ação (links/etc).
48
- */
49
- content?: any;
50
- /**
51
- * Slot principal no Mitosis para o custom content generalizado.
52
- */
53
- children?: any;
54
- /**
55
- * Permite sobrescrever classes customizadas na raiz do container do alerta
56
- */
57
- className?: string;
58
- /**
59
- * Evento acionado ao clicar para fechar o alerta
60
- */
61
- onClose?: (event?: any) => void;
62
- [key: string]: any;
63
- }
64
- declare function Alert(props: AlertProps): import("react/jsx-runtime").JSX.Element;
65
- export default Alert;
@@ -1,56 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import './Alert.css';
3
- "use client";
4
- import { useState, useEffect } from "react";
5
- import Icon from "../Icon/Icon";
6
- import Text from "../Text/Text";
7
- function Alert(props) {
8
- const [visible, setVisible] = useState(() => true);
9
- const [timeoutId, setTimeoutId] = useState(() => 0);
10
- function classes() {
11
- return [
12
- "umds-alert",
13
- `umds-alert--${props.type || "neutral"}`,
14
- `umds-alert--${props.variant || "soft"}`,
15
- `umds-alert--${props.verticalPosition || "top"}-${props.horizontalPosition || "right"}`,
16
- props.className,
17
- ]
18
- .filter(Boolean)
19
- .join(" ");
20
- }
21
- function iconName() {
22
- const currentType = props.type || "neutral";
23
- if (currentType === "success")
24
- return "check-circle";
25
- if (currentType === "error")
26
- return "xmark-circle";
27
- if (currentType === "warning")
28
- return "warning-triangle";
29
- return "info-circle";
30
- }
31
- function handleClose(event) {
32
- if (event)
33
- event.stopPropagation();
34
- setVisible(false);
35
- if (props.onClose) {
36
- props.onClose(event);
37
- }
38
- }
39
- useEffect(() => {
40
- const timeProp = typeof props.time === "number" ? props.time : 0;
41
- if (timeProp > 0) {
42
- setTimeoutId(setTimeout(() => {
43
- handleClose(null);
44
- }, timeProp));
45
- }
46
- }, []);
47
- useEffect(() => {
48
- return () => {
49
- if (timeoutId) {
50
- clearTimeout(timeoutId);
51
- }
52
- };
53
- }, []);
54
- return (_jsx(_Fragment, { children: visible ? (_jsx(_Fragment, { children: _jsxs("div", { role: "alert", ...props, className: classes(), children: [_jsx("div", { className: "umds-alert__icon-wrapper", children: _jsx(Icon, { variant: "inherit", size: "md", name: iconName() }) }), _jsxs("div", { className: "umds-alert__content", children: [props.title ? (_jsx("div", { className: "umds-alert__title-container", children: _jsx(Text, { variant: "body2", as: "p", className: "umds-alert__title-text", children: props.title }) })) : null, props.description ? (_jsx(Text, { variant: "caption", as: "p", className: "umds-alert__description-text", children: props.description })) : null, props.content || props.children ? (_jsx("div", { className: "umds-alert__actions", children: _jsx(_Fragment, { children: props.content || "{props.content || props.children}" }) })) : null] }), props.dismissable ? (_jsx("button", { type: "button", "aria-label": "Dispensar alerta", className: "umds-alert__close", onClick: (event) => handleClose(event), children: _jsx(Icon, { name: "nav-arrow-up", variant: "inherit", size: "md" }) })) : null] }) })) : null }));
55
- }
56
- export default Alert;