kitunga-web 0.1.87 → 0.1.89

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 (22) hide show
  1. package/README.md +116 -0
  2. package/dist/features/buttons/components/Btns/Button.module.css +5 -5
  3. package/dist/features/data-display/components/Cards/MetricCard.module.css +1 -1
  4. package/dist/features/data-display/components/Table/LineItemsTable.module.css +1 -1
  5. package/dist/features/data-display/components/Table/Table.module.css +1 -1
  6. package/dist/features/feedback/components/FlowNotice/FlowNotice.module.css +2 -2
  7. package/dist/features/feedback/components/Tooltips/ProgressChecklistTooltip.module.css +4 -4
  8. package/dist/features/inputs/components/Inputs/NumberInput.module.css +2 -2
  9. package/dist/features/inputs/components/Inputs/PhoneInput/PhoneInput.module.css +1 -1
  10. package/dist/features/inputs/components/Inputs/SearchInput.module.css +34 -21
  11. package/dist/features/inputs/components/Inputs/StepperInput.module.css +9 -14
  12. package/dist/features/inputs/components/Inputs/TaxIdInput/TaxIdInput.module.css +2 -2
  13. package/dist/features/inputs/components/Inputs/TextareaInput.d.ts.map +1 -1
  14. package/dist/features/inputs/components/Inputs/TextareaInput.js +2 -3
  15. package/dist/features/inputs/components/Inputs/TextareaInput.js.map +1 -1
  16. package/dist/features/inputs/components/Inputs/TextareaInput.module.css +60 -60
  17. package/dist/features/navigation/components/Menu/SharedMenuItem.module.css +11 -3
  18. package/dist/features/overlays/components/DeleteModal/ComprehensiveDeleteModal.module.css +3 -3
  19. package/dist/features/overlays/components/PrerequisiteGuardModal/PrerequisiteGuardModal.module.css +4 -4
  20. package/dist/features/selects/components/Selects/CustomSelect.module.css +2 -2
  21. package/dist/shared/styles/tokens.css +3 -3
  22. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # 🎨 Kitunga Web
2
+
3
+ > Biblioteca de componentes UI da Sinangu — usada pelos projectos Masolo.
4
+
5
+ ## 📋 Visão Geral
6
+
7
+ O **Kitunga Web** é a biblioteca de componentes partilhados usada nos frontends da Sinangu. Inclui inputs, botões, cartões, estados vazios e outros elementos reutilizáveis construídos com **React**, **TypeScript**, **Next.js** e **CSS Modules**.
8
+
9
+ ## 🛠️ Stack Tecnológica
10
+
11
+ - **React** >= 18
12
+ - **Next.js** 16 com App Router
13
+ - **TypeScript**
14
+ - **CSS Modules**
15
+
16
+ ## 🚀 Início Rápido
17
+
18
+ ### Pré-requisitos
19
+ - Node.js >= 18.0.0
20
+ - pnpm >= 8.0.0
21
+
22
+ ### Instalação
23
+ ```bash
24
+ pnpm install
25
+ ```
26
+
27
+ ### Scripts disponíveis
28
+
29
+ ```bash
30
+ # Modo desenvolvimento (documentação + playground de componentes)
31
+ pnpm dev
32
+
33
+ # Build de produção do site de documentação
34
+ pnpm build
35
+
36
+ # Build da biblioteca para publicação
37
+ pnpm build:lib
38
+
39
+ # Publicar a biblioteca no npm
40
+ pnpm publish:lib
41
+
42
+ # Lint
43
+ pnpm lint
44
+ ```
45
+
46
+ ## ⚙️ Gestão com PM2
47
+
48
+ O `kitunga-web` corre em modo de desenvolvimento na porta `3005` (definida em `.env.local`) e é gerido pelo PM2 através do `ecosystem.config.cjs`.
49
+
50
+ ### Comandos úteis
51
+
52
+ ```bash
53
+ # Iniciar o processo (modo dev com hot reload)
54
+ pm2 start ecosystem.config.cjs
55
+
56
+ # Parar o processo
57
+ pm2 stop kitunga-web
58
+
59
+ # Remover o processo do PM2
60
+ pm2 delete kitunga-web
61
+
62
+ # Reiniciar com a configuração actual
63
+ pm2 reload ecosystem.config.cjs
64
+
65
+ # Ver logs em tempo real
66
+ pm2 logs kitunga-web
67
+
68
+ # Listar processos
69
+ pm2 list
70
+
71
+ # Guardar a lista de processos para reiniciar após reboot
72
+ pm2 save
73
+
74
+ # Limpar logs antigos
75
+ pm2 flush
76
+ ```
77
+
78
+ ### Modo desenvolvimento (hot reload)
79
+
80
+ Por omissão, o PM2 corre `pnpm dev`.
81
+
82
+ ```bash
83
+ pm2 start ecosystem.config.cjs
84
+ ```
85
+
86
+ ### Modo produção
87
+
88
+ 1. Gera o build do site:
89
+ ```bash
90
+ pnpm build
91
+ ```
92
+
93
+ 2. No `ecosystem.config.cjs`, muda `args` de `'dev'` para `'start'`:
94
+ ```js
95
+ args: 'start'
96
+ ```
97
+
98
+ 3. Actualiza o PM2:
99
+ ```bash
100
+ pm2 reload ecosystem.config.cjs
101
+ ```
102
+
103
+ ## 📦 Publicação da biblioteca
104
+
105
+ Antes de consumir as alterações noutros projectos (como o `masolo-messenger-web`), é necessário gerar e publicar a biblioteca:
106
+
107
+ ```bash
108
+ pnpm build:lib
109
+ pnpm publish:lib
110
+ ```
111
+
112
+ Depois actualiza a versão no `package.json` do projecto consumidor e corre `pnpm install`.
113
+
114
+ ## 📄 Licença
115
+
116
+ Sinangu — Todos os direitos reservados.
@@ -49,13 +49,13 @@
49
49
 
50
50
  /* Variants */
51
51
  .primary {
52
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
52
+ background: var(--color-primary);
53
53
  color: white;
54
54
  padding: var(--spacing-sm-md) var(--spacing-md);
55
55
  }
56
56
 
57
57
  .primary:hover:not(:disabled) {
58
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
58
+ background: var(--color-primary-dark);
59
59
  }
60
60
 
61
61
  .secondary {
@@ -104,7 +104,7 @@
104
104
  position: absolute;
105
105
  inset: 0;
106
106
  padding: 2px;
107
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
107
+ background: var(--color-primary);
108
108
  border-radius: inherit;
109
109
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
110
110
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
@@ -114,12 +114,12 @@
114
114
  }
115
115
 
116
116
  .outline:hover:not(:disabled) {
117
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
117
+ background: var(--color-primary-dark);
118
118
  color: white;
119
119
  }
120
120
 
121
121
  .outline:hover:not(:disabled)::before {
122
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
122
+ background: var(--color-primary-dark);
123
123
  }
124
124
 
125
125
  .round {
@@ -66,7 +66,7 @@
66
66
 
67
67
  /* Color variants */
68
68
  .blue .iconContainer {
69
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
69
+ background: var(--color-primary);
70
70
  }
71
71
 
72
72
  .green .iconContainer {
@@ -162,7 +162,7 @@
162
162
  width: fit-content;
163
163
  border: none;
164
164
  background: transparent;
165
- color: var(--color-blue-600);
165
+ color: var(--color-primary);
166
166
  cursor: pointer;
167
167
  display: inline-flex;
168
168
  align-items: center;
@@ -212,7 +212,7 @@
212
212
  }
213
213
  .badgeMode {
214
214
  background-color: #dbeafe;
215
- color: #1d4ed8;
215
+ color: var(--color-primary);
216
216
  }
217
217
 
218
218
  /* Ações */
@@ -117,6 +117,6 @@
117
117
 
118
118
  .info .icon,
119
119
  .info .progressBar {
120
- color: #1d4ed8;
121
- background: #3b82f6;
120
+ color: var(--color-primary);
121
+ background: var(--color-info);
122
122
  }
@@ -104,7 +104,7 @@
104
104
 
105
105
  .progressFill {
106
106
  height: 100%;
107
- background: linear-gradient(90deg, var(--bg-interactive) 0%, var(--bg-interactive-hover) 100%);
107
+ background: var(--color-primary);
108
108
  border-radius: 3px;
109
109
  transition: width 0.3s ease;
110
110
  }
@@ -141,7 +141,7 @@
141
141
  }
142
142
 
143
143
  .completedIcon {
144
- color: var(--bg-interactive, #3b82f6) !important;
144
+ color: var(--color-primary) !important;
145
145
  }
146
146
 
147
147
  .itemText {
@@ -149,13 +149,13 @@
149
149
  }
150
150
 
151
151
  .completedText {
152
- color: var(--bg-interactive, #3b82f6) !important;
152
+ color: var(--color-primary) !important;
153
153
  font-size: 0.85rem !important;
154
154
  flex: 1;
155
155
  }
156
156
 
157
157
  .completedTailIcon {
158
- color: var(--bg-interactive, #3b82f6) !important;
158
+ color: var(--color-primary) !important;
159
159
  margin-left: var(--spacing-xs);
160
160
  }
161
161
 
@@ -95,11 +95,11 @@
95
95
  }
96
96
 
97
97
  .sm {
98
- height: 32px;
98
+ height: 35px;
99
99
  }
100
100
 
101
101
  .sm .textInput {
102
- height: 32px;
102
+ height: 35px;
103
103
  font-size: 0.75rem;
104
104
  }
105
105
 
@@ -205,7 +205,7 @@
205
205
  }
206
206
 
207
207
  .sm {
208
- height: 32px;
208
+ height: 35px;
209
209
  }
210
210
 
211
211
  .sm .textInput {
@@ -3,7 +3,6 @@
3
3
  display: flex;
4
4
  align-items: center;
5
5
  width: 100%;
6
- max-width: 450px;
7
6
  }
8
7
 
9
8
  .inputWrapperMain {
@@ -16,6 +15,11 @@
16
15
  .searchIcon {
17
16
  position: absolute;
18
17
  left: var(--spacing-md);
18
+ top: 50%;
19
+ transform: translateY(-50%);
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
19
23
  color: var(--text-tertiary);
20
24
  pointer-events: none;
21
25
  z-index: 1;
@@ -23,14 +27,17 @@
23
27
 
24
28
  .searchInput {
25
29
  width: 100%;
26
- padding: var(--spacing-sm-large) 2.5rem var(--spacing-sm-large) 2.5rem;
30
+ padding: 0 2.5rem 0 2.8rem;
27
31
  border: 1px solid var(--border-divider);
28
32
  border-radius: var(--radius-sm);
29
33
  font-size: 0.9rem;
30
34
  background-color: var(--bg-secondary);
31
35
  color: var(--text-primary);
32
36
  transition: all var(--transition-fast);
33
- margin-top: 1.5px;
37
+ }
38
+
39
+ .searchInput::placeholder {
40
+ color: var(--text-tertiary);
34
41
  }
35
42
 
36
43
  .searchInput:focus {
@@ -40,9 +47,17 @@
40
47
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
41
48
  }
42
49
 
50
+ .searchInput:disabled {
51
+ background-color: var(--bg-secondary);
52
+ color: var(--text-tertiary);
53
+ cursor: not-allowed;
54
+ }
55
+
43
56
  .clearButton {
44
57
  position: absolute;
45
58
  right: var(--spacing-sm);
59
+ top: 50%;
60
+ transform: translateY(-50%);
46
61
  width: 24px;
47
62
  height: 24px;
48
63
  display: flex;
@@ -62,20 +77,17 @@
62
77
  color: var(--text-primary);
63
78
  }
64
79
 
65
- /* Sizes */
80
+ /* Sizes — régua do design system (Button): sm 35 / md 40 / lg 45.
81
+ A altura vem de height (padding só horizontal no .searchInput). */
66
82
  .sm {
67
- height: 32px;
68
- max-width: 300px;
83
+ height: 35px;
69
84
  }
70
85
 
86
+ /* sm: como no TextInput — só muda height + font-size. O ícone fica a
87
+ spacing-md da borda e o padding-left 2.8rem em TODOS os sizes. */
71
88
  .sm .searchInput {
72
- height: 32px;
89
+ height: 35px;
73
90
  font-size: 0.75rem;
74
- padding: var(--spacing-sm) 2rem var(--spacing-sm) 2rem;
75
- }
76
-
77
- .sm .searchIcon {
78
- left: var(--spacing-sm);
79
91
  }
80
92
 
81
93
  .sm .clearButton {
@@ -84,19 +96,21 @@
84
96
  right: var(--spacing-xs);
85
97
  }
86
98
 
99
+ .md {
100
+ height: 40px;
101
+ }
102
+
103
+ .md .searchInput {
104
+ height: 40px;
105
+ }
106
+
87
107
  .lg {
88
- height: 48px;
89
- max-width: 600px;
108
+ height: 45px;
90
109
  }
91
110
 
92
111
  .lg .searchInput {
93
- height: 48px;
112
+ height: 45px;
94
113
  font-size: 1rem;
95
- padding: var(--spacing-md) 3rem var(--spacing-md) 3rem;
96
- }
97
-
98
- .lg .searchIcon {
99
- left: var(--spacing-md);
100
114
  }
101
115
 
102
116
  .lg .clearButton {
@@ -104,4 +118,3 @@
104
118
  height: 28px;
105
119
  right: var(--spacing-md);
106
120
  }
107
-
@@ -21,26 +21,21 @@
21
21
  .button:first-of-type {
22
22
  background: transparent;
23
23
  border-color: var(--border-divider);
24
- color: var(--color-blue-600);
24
+ color: var(--color-primary);
25
25
  }
26
26
 
27
27
  .button:last-of-type {
28
28
  background: transparent;
29
29
  border-color: var(--border-divider);
30
- color: var(--color-blue-600);
30
+ color: var(--color-primary);
31
31
  }
32
32
 
33
33
  .button:hover:not(:disabled) {
34
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
34
+ background: var(--color-primary);
35
35
  color: #fff;
36
36
  border-color: transparent;
37
37
  }
38
38
 
39
- .button:last-of-type:hover:not(:disabled) {
40
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
41
- color: #fff;
42
- }
43
-
44
39
  .button:disabled {
45
40
  opacity: 0.4;
46
41
  cursor: not-allowed;
@@ -66,12 +61,12 @@
66
61
  }
67
62
 
68
63
  .sm .button {
69
- width: 32px;
70
- height: 32px;
64
+ width: 35px;
65
+ height: 35px;
71
66
  }
72
67
 
73
68
  .sm .input {
74
- width: 32px;
69
+ width: 35px;
75
70
  font-size: 0.95rem;
76
71
  }
77
72
 
@@ -86,11 +81,11 @@
86
81
  }
87
82
 
88
83
  .lg .button {
89
- width: 44px;
90
- height: 44px;
84
+ width: 45px;
85
+ height: 45px;
91
86
  }
92
87
 
93
88
  .lg .input {
94
- width: 44px;
89
+ width: 45px;
95
90
  font-size: 1.05rem;
96
91
  }
@@ -215,7 +215,7 @@
215
215
  }
216
216
 
217
217
  .sm {
218
- min-height: 32px;
218
+ min-height: 35px;
219
219
  }
220
220
 
221
221
  .sm .maskOverlay,
@@ -234,7 +234,7 @@
234
234
  }
235
235
 
236
236
  .lg {
237
- min-height: 48px;
237
+ min-height: 45px;
238
238
  }
239
239
 
240
240
  .lg .maskOverlay,
@@ -1 +1 @@
1
- {"version":3,"file":"TextareaInput.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/TextareaInput.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,QAAA,MAAM,aAAa,oHA4ElB,CAAC;AAIF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"TextareaInput.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/TextareaInput.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,QAAA,MAAM,aAAa,oHAsFlB,CAAC;AAIF,eAAe,aAAa,CAAC"}
@@ -14,14 +14,13 @@ import { forwardRef, useImperativeHandle, useRef } from 'react';
14
14
  import { X } from 'lucide-react';
15
15
  import styles from './TextareaInput.module.css';
16
16
  const TextareaInput = forwardRef((_a, ref) => {
17
- var { size = 'md', containerClassName = '', className = '', leftIcon, value = '', onChange, showClearButton = true, clearButtonLabel = 'Limpar campo', disabled = false, readOnly = false, hasError, errorMessage } = _a, rest = __rest(_a, ["size", "containerClassName", "className", "leftIcon", "value", "onChange", "showClearButton", "clearButtonLabel", "disabled", "readOnly", "hasError", "errorMessage"]);
17
+ var { size = 'md', containerClassName = '', className = '', leftIcon, value = '', onChange, showClearButton = true, clearButtonLabel = 'Limpar campo', disabled = false, readOnly = false, maxLength, hasError, errorMessage } = _a, rest = __rest(_a, ["size", "containerClassName", "className", "leftIcon", "value", "onChange", "showClearButton", "clearButtonLabel", "disabled", "readOnly", "maxLength", "hasError", "errorMessage"]);
18
18
  const textareaRef = useRef(null);
19
19
  useImperativeHandle(ref, () => textareaRef.current);
20
20
  const isError = hasError || !!errorMessage;
21
21
  const containerClasses = [
22
22
  styles.inputContainer,
23
23
  styles[size],
24
- leftIcon ? styles.hasLeftIcon : '',
25
24
  containerClassName,
26
25
  ]
27
26
  .filter(Boolean)
@@ -38,7 +37,7 @@ const TextareaInput = forwardRef((_a, ref) => {
38
37
  onChange === null || onChange === void 0 ? void 0 : onChange(event.target.value);
39
38
  };
40
39
  const shouldShowClearButton = showClearButton && !!(value === null || value === void 0 ? void 0 : value.length) && !disabled && !readOnly;
41
- return (_jsxs("div", { className: containerClasses.concat(isError ? ` ${styles.hasError}` : ''), children: [leftIcon && _jsx("span", { className: styles.inputIcon, children: leftIcon }), _jsx("textarea", Object.assign({ ref: textareaRef, className: `${textareaClasses} ${isError ? styles.inputError : ''}`, value: value, onChange: handleChange, disabled: disabled, readOnly: readOnly, autoComplete: "off" }, rest)), shouldShowClearButton && (_jsx("button", { type: "button", className: styles.clearButton, onClick: handleClear, "aria-label": clearButtonLabel, tabIndex: -1, children: _jsx(X, { size: 16 }) })), errorMessage && _jsx("span", { className: styles.errorText, children: errorMessage })] }));
40
+ return (_jsxs("div", { className: containerClasses.concat(isError ? ` ${styles.hasError}` : ''), children: [_jsxs("div", { className: styles.field, children: [leftIcon && _jsx("span", { className: styles.inputIcon, children: leftIcon }), _jsx("textarea", Object.assign({ ref: textareaRef, className: `${textareaClasses} ${isError ? styles.inputError : ''}`, value: value, onChange: handleChange, disabled: disabled, readOnly: readOnly, autoComplete: "off" }, rest)), maxLength !== undefined && (_jsxs("span", { className: styles.charCounter, children: [(value !== null && value !== void 0 ? value : '').length, "/", maxLength] })), shouldShowClearButton && (_jsx("button", { type: "button", className: styles.clearButton, onClick: handleClear, "aria-label": clearButtonLabel, tabIndex: -1, children: _jsx(X, { size: 16 }) }))] }), errorMessage && _jsx("span", { className: styles.errorText, children: errorMessage })] }));
42
41
  });
43
42
  TextareaInput.displayName = 'TextareaInput';
44
43
  export default TextareaInput;
@@ -1 +1 @@
1
- {"version":3,"file":"TextareaInput.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/TextareaInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TextareaInput.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/TextareaInput.tsx"],"names":[],"mappings":"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"}
@@ -1,22 +1,54 @@
1
1
  .inputContainer {
2
- position: relative;
3
2
  display: flex;
4
- align-items: flex-start;
3
+ flex-direction: column;
5
4
  width: 100%;
6
5
  }
7
6
 
8
- .textArea {
7
+ /* A caixa visual: o ícone é um filho flex NORMAL — o spacing-md do padding
8
+ afasta-o das bordas e o gap spacing-md afasta-o do texto. Nada de absolute
9
+ "grudado" por cima do campo. */
10
+ .field {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: flex-start;
14
+ gap: var(--spacing-md);
9
15
  width: 100%;
10
- padding: var(--spacing-sm) var(--spacing-md);
16
+ padding: var(--spacing-md);
11
17
  border: 1px solid var(--border-divider);
12
18
  border-radius: var(--radius-sm);
13
- font-size: 0.9rem;
14
19
  background-color: var(--bg-secondary);
15
- color: var(--text-primary);
16
20
  transition: all var(--transition-fast);
21
+ }
22
+
23
+ .field:focus-within {
24
+ border-color: var(--border-focus);
25
+ background-color: var(--bg-primary);
26
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
27
+ }
28
+
29
+ .inputIcon {
30
+ display: flex;
31
+ align-items: center;
32
+ flex-shrink: 0;
33
+ color: var(--text-tertiary);
34
+ /* Alinha o ícone com a primeira linha de texto (line-height 1.35 do
35
+ textArea × font-size do size). */
36
+ height: calc(0.9rem * 1.35);
37
+ }
38
+
39
+ .textArea {
40
+ flex: 1;
41
+ min-width: 0;
42
+ align-self: stretch;
43
+ padding: 0;
44
+ border: none;
45
+ background: transparent;
46
+ font-size: 0.9rem;
47
+ font-family: inherit;
48
+ color: var(--text-primary);
17
49
  resize: vertical;
18
- min-height: 96px;
19
50
  line-height: 1.35;
51
+ min-height: 0;
20
52
  }
21
53
 
22
54
  .textArea::placeholder {
@@ -25,34 +57,16 @@
25
57
 
26
58
  .textArea:focus {
27
59
  outline: none;
28
- border-color: var(--border-focus);
29
- background-color: var(--bg-primary);
30
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
31
- }
32
-
33
- .textArea:-webkit-autofill,
34
- .textArea:-webkit-autofill:hover,
35
- .textArea:-webkit-autofill:focus,
36
- .textArea:-webkit-autofill:active {
37
- -webkit-box-shadow: 0 0 0 1000px var(--bg-secondary) inset;
38
- box-shadow: 0 0 0 1000px var(--bg-secondary) inset;
39
- background-color: var(--bg-secondary) !important;
40
- -webkit-text-fill-color: var(--text-primary);
41
- color: var(--text-primary);
42
- caret-color: var(--text-primary);
43
60
  }
44
61
 
45
62
  .textArea:disabled,
46
63
  .textArea[readonly] {
47
- background-color: var(--bg-secondary);
48
64
  color: var(--text-tertiary);
49
65
  cursor: not-allowed;
50
66
  }
51
67
 
52
68
  .clearButton {
53
- position: absolute;
54
- right: var(--spacing-sm);
55
- top: var(--spacing-sm);
69
+ flex-shrink: 0;
56
70
  width: 24px;
57
71
  height: 24px;
58
72
  display: flex;
@@ -64,7 +78,6 @@
64
78
  color: var(--text-tertiary);
65
79
  cursor: pointer;
66
80
  transition: all var(--transition-fast);
67
- z-index: 1;
68
81
  }
69
82
 
70
83
  .clearButton:hover {
@@ -72,69 +85,60 @@
72
85
  color: var(--text-primary);
73
86
  }
74
87
 
75
- .inputIcon {
88
+ /* Contador de caracteres — vive na faixa de padding inferior da .field
89
+ (o textarea acaba 16px acima do fundo da caixa), por isso nunca pisa
90
+ o texto e fica ao lado do grip nativo de resize. */
91
+ .charCounter {
76
92
  position: absolute;
77
- left: var(--spacing-md);
78
- top: var(--spacing-sm);
93
+ right: var(--spacing-sm);
94
+ bottom: 3px;
95
+ font-size: 0.7rem;
79
96
  color: var(--text-tertiary);
80
97
  pointer-events: none;
81
- z-index: 1;
82
98
  }
83
99
 
84
- .hasLeftIcon .textArea {
85
- padding-left: 2.5rem;
86
- }
87
-
88
- .sm {
100
+ /* Sizes — a min-height mora na caixa (.field), o textarea estica dentro.
101
+ Só mudam font-size, min-height e a linha que alinha o ícone. */
102
+ .sm .field {
89
103
  min-height: 80px;
90
104
  }
91
105
 
92
106
  .sm .textArea {
93
107
  font-size: 0.75rem;
94
- padding: var(--spacing-sm) var(--spacing-lg);
95
- min-height: 80px;
108
+ }
109
+
110
+ .sm .inputIcon {
111
+ height: calc(0.75rem * 1.35);
96
112
  }
97
113
 
98
114
  .sm .clearButton {
99
115
  width: 20px;
100
116
  height: 20px;
101
- right: var(--spacing-xs);
102
- top: var(--spacing-xs);
103
- }
104
-
105
- .md {
106
- min-height: 96px;
107
117
  }
108
118
 
109
- .md .textArea {
119
+ .md .field {
110
120
  min-height: 96px;
111
121
  }
112
122
 
113
- .lg {
123
+ .lg .field {
114
124
  min-height: 120px;
115
125
  }
116
126
 
117
127
  .lg .textArea {
118
128
  font-size: 1rem;
119
- padding: var(--spacing-md) var(--spacing-xl);
120
- min-height: 120px;
121
129
  }
122
130
 
123
- /* lg + leftIcon: preservar padding-left do hasLeftIcon */
124
- .lg.hasLeftIcon .textArea {
125
- padding-left: 2.5rem;
131
+ .lg .inputIcon {
132
+ height: calc(1rem * 1.35);
126
133
  }
127
134
 
128
135
  .lg .clearButton {
129
136
  width: 28px;
130
137
  height: 28px;
131
- right: var(--spacing-md);
132
- top: var(--spacing-sm);
133
138
  }
134
139
 
135
-
136
- .inputContainer.hasError {
137
- flex-direction: column;
140
+ .inputContainer.hasError .field {
141
+ border-color: #ef4444;
138
142
  }
139
143
 
140
144
  .errorText {
@@ -143,7 +147,3 @@
143
147
  margin-top: 4px;
144
148
  display: block;
145
149
  }
146
-
147
- .inputError {
148
- border-color: #ef4444 !important;
149
- }
@@ -71,22 +71,30 @@
71
71
  background-color: var(--bg-hover-normal);
72
72
  }
73
73
 
74
- /* Active styles */
74
+ /* Active styles — azul #007AFF; hover escurece só um pouco (#0062D6). */
75
75
  .menuItem.activeItem > .menuLink {
76
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
76
+ background: var(--bg-interactive);
77
77
  color: #ffffff;
78
78
  }
79
79
 
80
+ .menuItem.activeItem > .menuLink:hover {
81
+ background: var(--bg-interactive-hover);
82
+ }
83
+
80
84
  .expandedItem.activeItem > .menuLink .menuText,
81
85
  .expandedItem.activeItem > .menuLink .iconWrapper {
82
86
  color: #ffffff;
83
87
  }
84
88
 
85
89
  .collapsedItem.activeItem > .menuLink {
86
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
90
+ background: var(--bg-interactive);
87
91
  color: #ffffff;
88
92
  }
89
93
 
94
+ .collapsedItem.activeItem > .menuLink:hover {
95
+ background: var(--bg-interactive-hover);
96
+ }
97
+
90
98
  .collapsedItem.activeItem > .menuLink .menuText {
91
99
  color: #ffffff;
92
100
  }
@@ -125,7 +125,7 @@
125
125
 
126
126
  .badgeInfo {
127
127
  background: rgba(59, 130, 246, 0.12);
128
- color: #1d4ed8;
128
+ color: var(--color-primary);
129
129
  border-color: rgba(59, 130, 246, 0.4);
130
130
  }
131
131
 
@@ -235,13 +235,13 @@
235
235
  cursor: pointer;
236
236
  font-size: 0.75rem;
237
237
  font-weight: 600;
238
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
238
+ background: var(--color-primary);
239
239
  color: #fff;
240
240
  transition: var(--transition-fast);
241
241
  }
242
242
 
243
243
  .actionButton:hover {
244
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
244
+ background: var(--color-primary-dark);
245
245
  }
246
246
 
247
247
  .footer {
@@ -177,7 +177,7 @@
177
177
 
178
178
  .iconInfo {
179
179
  background: rgba(59, 130, 246, 0.14);
180
- color: #1d4ed8;
180
+ color: var(--color-primary);
181
181
  }
182
182
 
183
183
  .iconWarning {
@@ -246,7 +246,7 @@
246
246
 
247
247
  .badgeInfo {
248
248
  background: rgba(59, 130, 246, 0.12);
249
- color: #1d4ed8;
249
+ color: var(--color-primary);
250
250
  border-color: rgba(59, 130, 246, 0.4);
251
251
  }
252
252
 
@@ -285,13 +285,13 @@
285
285
  cursor: pointer;
286
286
  font-size: 0.75rem;
287
287
  font-weight: 600;
288
- background: linear-gradient(135deg, #3b82f6, #1d4ed8);
288
+ background: var(--color-primary);
289
289
  color: #fff;
290
290
  transition: var(--transition-fast);
291
291
  }
292
292
 
293
293
  .actionButton:hover {
294
- background: linear-gradient(135deg, #1d4ed8, #1e3a8a);
294
+ background: var(--color-primary-dark);
295
295
  }
296
296
 
297
297
  .footer {
@@ -71,7 +71,7 @@
71
71
  }
72
72
 
73
73
  .customSelect.sm .selectedValue {
74
- height: 32px;
74
+ height: 35px;
75
75
  }
76
76
 
77
77
  .customSelect.sm .valueText {
@@ -209,7 +209,7 @@
209
209
  }
210
210
 
211
211
  .customSelect.sm .option {
212
- height: 32px;
212
+ height: 35px;
213
213
  }
214
214
 
215
215
  .customSelect.sm .option span {
@@ -1,8 +1,8 @@
1
1
  :root {
2
2
  /* Cores Principais */
3
- --color-primary: #1E40AF;
3
+ --color-primary: #007AFF;
4
4
  --color-primary-light: #3B82F6;
5
- --color-primary-dark: #1E3A8A;
5
+ --color-primary-dark: #0062D6;
6
6
  --color-secondary: #0891B2;
7
7
  --color-secondary-light: #06B6D4;
8
8
  --color-accent: #F59E0B;
@@ -36,7 +36,7 @@
36
36
  --bg-accent: var(--color-primary-light);
37
37
  --bg-hover-primary: #f1f1f196;
38
38
  --bg-hover-normal: #f1f3f4;
39
- --bg-interactive: var(--color-primary-light);
39
+ --bg-interactive: var(--color-primary);
40
40
  --bg-interactive-hover: var(--color-primary-dark);
41
41
  --bg-interactive-active: var(--color-primary);
42
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitunga-web",
3
- "version": "0.1.87",
3
+ "version": "0.1.89",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {