ngx-opalbytes-components 1.25.1 → 1.26.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/README.md CHANGED
@@ -243,7 +243,9 @@ src/
243
243
  | ├── kpi/
244
244
  | ├── links-button/
245
245
  | ├── paginator/
246
+ | ├── radio/
246
247
  | ├── skeleton/
248
+ | ├── slide-toggle/
247
249
  | ├── stepper/
248
250
  | ├── tab-group/
249
251
  | ├── tab-panel/
@@ -928,6 +930,332 @@ Um componente de alternância (toggle switch) que funciona com `ngModel` ou `for
928
930
 
929
931
  ---
930
932
 
933
+ ### `CaoSlideToggleComponent`
934
+
935
+ Um switch (slide toggle) acessível e customizável, com suporte a `ngModel` e formulários reativos via `ControlValueAccessor`. O visual é construído com trilho e thumb animados, sem depender do Material em runtime.
936
+
937
+ **Seletor:** `<cao-slide-toggle>`
938
+
939
+ **Interface `ICaoSlideToggleChangeEvent`**
940
+
941
+ | Propriedade | Tipo | Descrição |
942
+ | --- | --- | --- |
943
+ | `checked` | `boolean` | Novo estado do switch. |
944
+ | `source` | `CaoSlideToggleComponent` | Instância que originou o evento. |
945
+
946
+ **Atributos (Inputs)**
947
+
948
+ | Atributo | Tipo | Padrão | Descrição |
949
+ | --- | --- | --- | --- |
950
+ | `checked` | `boolean` | `false` | Estado inicial/atual do switch. |
951
+ | `isDisabled` | `boolean` | `false` | Desabilita o componente. |
952
+ | `disabled` | `boolean` | `false` | Alias de `isDisabled` (mesmo comportamento). |
953
+ | `label` | `string` | `''` | Texto do label. Também aceita conteúdo projetado (`<ng-content>`). |
954
+ | `labelPosition` | `'before' \| 'after'` | `'after'` | Posição do label em relação ao switch. |
955
+ | `name` | `string` | `''` | Atributo `name` do input nativo. |
956
+ | `id` | `string` | `''` | Atributo `id` do input nativo. |
957
+ | `ariaLabel` | `string` | `''` | Atributo `aria-label` do switch. |
958
+ | `required` | `boolean` | `false` | Marca o input como obrigatório. |
959
+ | `dataCy` | `string` | `''` | Atributo para testes E2E com Cypress. |
960
+ | `trackColor` | `string` | `#d1d5db` | Cor do trilho desligado. |
961
+ | `trackCheckedColor` | `string` | `#4f46e5` | Cor do trilho ligado. |
962
+ | `thumbColor` | `string` | `#ffffff` | Cor do thumb desligado. |
963
+ | `thumbCheckedColor` | `string` | `#ffffff` | Cor do thumb ligado. |
964
+ | `disabledTrackColor` | `string` | `#e5e7eb` | Cor do trilho desabilitado. |
965
+ | `disabledThumbColor` | `string` | `#f3f4f6` | Cor do thumb desabilitado. |
966
+ | `labelColor` | `string` | `#111827` | Cor do label. |
967
+ | `disabledLabelColor` | `string` | `#9ca3af` | Cor do label desabilitado. |
968
+ | `focusRingColor` | `string` | `rgba(79, 70, 229, 0.35)` | Cor do anel de foco. |
969
+ | `trackWidth` | `string` | `36px` | Largura do trilho. |
970
+ | `trackHeight` | `string` | `20px` | Altura do trilho. |
971
+ | `thumbSize` | `string` | `16px` | Tamanho do thumb. |
972
+ | `animationDuration` | `string` | `200ms` | Duração da animação. |
973
+ | `thumbIcon` | `string` | `''` | Ícone exibido no thumb desligado. Pode ser um nome Lucide ou uma URL de imagem. |
974
+ | `thumbCheckedIcon` | `string` | `''` | Ícone exibido no thumb ligado. Se vazio, usa `thumbIcon`. |
975
+ | `isLucideThumbIcon` | `boolean` | `false` | Interpreta os ícones do thumb como nomes Lucide. Quando `false`, usa `<img>`. |
976
+ | `thumbIconColor` | `string` | `''` | Cor do ícone Lucide no estado desligado. |
977
+ | `thumbCheckedIconColor` | `string` | `''` | Cor do ícone Lucide no estado ligado. Se vazio, usa `thumbIconColor`. |
978
+ | `thumbIconSize` | `string \| number` | `12` | Tamanho do ícone do thumb. |
979
+ | `thumbIconStrokeWidth` | `string \| number` | `2` | Espessura do traço do ícone Lucide. |
980
+
981
+ **Eventos (Outputs)**
982
+
983
+ | Evento | Tipo | Descrição |
984
+ | --- | --- | --- |
985
+ | `checkedChange` | `EventEmitter<boolean>` | Emitido quando o estado muda. |
986
+ | `toggleChange` | `EventEmitter<ICaoSlideToggleChangeEvent>` | Emitido com o novo estado e a origem. |
987
+
988
+ **Métodos**
989
+
990
+ | Método | Descrição |
991
+ | --- | --- |
992
+ | `toggle()` | Alterna o estado, se não estiver desabilitado. |
993
+ | `setChecked(value: boolean)` | Define o estado programaticamente, se não estiver desabilitado. |
994
+ | `enable()` | Habilita o componente. |
995
+ | `disable()` | Desabilita o componente. |
996
+ | `writeValue(value)` | Implementação de `ControlValueAccessor`. |
997
+ | `setDisabledState(isDisabled)` | Implementação de `ControlValueAccessor`. |
998
+
999
+ **CSS Custom Properties**
1000
+
1001
+ | Propriedade | Padrão | Descrição |
1002
+ | --- | --- | --- |
1003
+ | `--cao-slide-toggle-track` | `#d1d5db` | Cor do trilho desligado. |
1004
+ | `--cao-slide-toggle-track-checked` | `#4f46e5` | Cor do trilho ligado. |
1005
+ | `--cao-slide-toggle-thumb` | `#ffffff` | Cor do thumb desligado. |
1006
+ | `--cao-slide-toggle-thumb-checked` | `#ffffff` | Cor do thumb ligado. |
1007
+ | `--cao-slide-toggle-track-disabled` | `#e5e7eb` | Cor do trilho desabilitado. |
1008
+ | `--cao-slide-toggle-thumb-disabled` | `#f3f4f6` | Cor do thumb desabilitado. |
1009
+ | `--cao-slide-toggle-label` | `#111827` | Cor do label. |
1010
+ | `--cao-slide-toggle-label-disabled` | `#9ca3af` | Cor do label desabilitado. |
1011
+ | `--cao-slide-toggle-focus-ring` | `rgba(79, 70, 229, 0.35)` | Cor do anel de foco. |
1012
+ | `--cao-slide-toggle-track-width` | `36px` | Largura do trilho. |
1013
+ | `--cao-slide-toggle-track-height` | `20px` | Altura do trilho. |
1014
+ | `--cao-slide-toggle-thumb-size` | `16px` | Tamanho do thumb. |
1015
+ | `--cao-slide-toggle-duration` | `200ms` | Duração da animação. |
1016
+
1017
+ **Exemplo com `ngModel`:**
1018
+
1019
+ ```html
1020
+ <cao-slide-toggle
1021
+ label="Ativar notificações"
1022
+ [(ngModel)]="notificacoesAtivas"
1023
+ (checkedChange)="onCheckedChange($event)">
1024
+ </cao-slide-toggle>
1025
+ ```
1026
+
1027
+ **Exemplo com formulário reativo e cores customizadas:**
1028
+
1029
+ ```html
1030
+ <cao-slide-toggle
1031
+ label="Modo escuro"
1032
+ [formControl]="modoEscuro"
1033
+ trackCheckedColor="#16a34a"
1034
+ thumbCheckedColor="#ffffff"
1035
+ trackColor="#fca5a5"
1036
+ labelColor="#166534"
1037
+ labelPosition="before">
1038
+ </cao-slide-toggle>
1039
+ ```
1040
+
1041
+ **Exemplo com ícones Lucide no thumb:**
1042
+
1043
+ ```html
1044
+ <cao-slide-toggle
1045
+ label="Notificações"
1046
+ [(ngModel)]="notificacoesAtivas"
1047
+ thumbIcon="x"
1048
+ thumbCheckedIcon="check"
1049
+ [isLucideThumbIcon]="true"
1050
+ thumbIconColor="#6b7280"
1051
+ thumbCheckedIconColor="#16a34a"
1052
+ [thumbIconSize]="12"
1053
+ [thumbIconStrokeWidth]="2.5">
1054
+ </cao-slide-toggle>
1055
+ ```
1056
+
1057
+ **Exemplo com imagem no thumb:**
1058
+
1059
+ ```html
1060
+ <cao-slide-toggle
1061
+ label="Ícone customizado"
1062
+ [(ngModel)]="ativo"
1063
+ thumbIcon="assets/icone-desligado.svg"
1064
+ thumbCheckedIcon="assets/icone-ligado.svg"
1065
+ [isLucideThumbIcon]="false"
1066
+ [thumbIconSize]="10">
1067
+ </cao-slide-toggle>
1068
+ ```
1069
+
1070
+ Se `thumbCheckedIcon` não for informado, o componente reutiliza `thumbIcon` no estado ligado.
1071
+
1072
+ **Exemplo desabilitado programaticamente:**
1073
+
1074
+ ```typescript
1075
+ @ViewChild(CaoSlideToggleComponent)
1076
+ slideToggle!: CaoSlideToggleComponent;
1077
+
1078
+ bloquear(): void {
1079
+ this.slideToggle.disable();
1080
+ }
1081
+
1082
+ liberar(): void {
1083
+ this.slideToggle.enable();
1084
+ }
1085
+ ```
1086
+
1087
+ **Observações:**
1088
+
1089
+ - Usa um `input type="checkbox"` com `role="switch"`, com suporte a `Espaço`, `Enter`, foco visível e leitores de tela.
1090
+ - Funciona com `ngModel`, `formControlName` e `FormControl.disable()`.
1091
+ - As cores podem ser definidas por inputs ou por CSS custom properties.
1092
+
1093
+ ---
1094
+
1095
+ ### `CaoRadioGroupComponent` e `CaoRadioButtonComponent`
1096
+
1097
+ Sistema de radio buttons no estilo do Material, com navegação por teclado, suporte a formulários e customização de cores. O grupo é o dono do valor selecionado; os botões apenas declaram seu `value` e o label.
1098
+
1099
+ **Seletores:**
1100
+ - `<cao-radio-group>` — container do grupo
1101
+ - `<cao-radio-button>` — opção individual (deve ficar dentro do grupo)
1102
+
1103
+ **Interface `ICaoRadioChangeEvent`**
1104
+
1105
+ | Propriedade | Tipo | Descrição |
1106
+ | --- | --- | --- |
1107
+ | `value` | `unknown` | Valor recém-selecionado. |
1108
+ | `source` | `CaoRadioButtonComponent` | Botão que originou o evento. |
1109
+
1110
+ #### Atributos do `CaoRadioGroupComponent` (Inputs)
1111
+
1112
+ | Atributo | Tipo | Padrão | Descrição |
1113
+ | --- | --- | --- | --- |
1114
+ | `value` | `any` | `undefined` | Valor selecionado. Também funciona via `ngModel`/`formControlName`. |
1115
+ | `name` | `string` | gerado automaticamente | Nome compartilhado pelos inputs nativos do grupo. |
1116
+ | `isDisabled` | `boolean` | `false` | Desabilita todas as opções. |
1117
+ | `disabled` | `boolean` | `false` | Alias de `isDisabled`. |
1118
+ | `required` | `boolean` | `false` | Marca o grupo como obrigatório. |
1119
+ | `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Direção do layout. |
1120
+ | `labelPosition` | `'before' \| 'after'` | `'after'` | Posição padrão dos labels. |
1121
+ | `color` | `string` | `#4f46e5` | Cor da opção selecionada (borda e ponto). |
1122
+ | `unselectedColor` | `string` | `#6b7280` | Cor da borda da opção não selecionada. |
1123
+ | `disabledColor` | `string` | `#d1d5db` | Cor da opção desabilitada. |
1124
+ | `labelColor` | `string` | `#111827` | Cor dos labels. |
1125
+ | `disabledLabelColor` | `string` | `#9ca3af` | Cor dos labels desabilitados. |
1126
+ | `focusRingColor` | `string` | `rgba(79, 70, 229, 0.35)` | Cor do anel de foco. |
1127
+ | `size` | `string` | `20px` | Tamanho do círculo. |
1128
+ | `animationDuration` | `string` | `200ms` | Duração das animações. |
1129
+ | `gap` | `string` | `8px` | Espaçamento entre as opções. |
1130
+ | `compareWith` | `(option, value) => boolean` | `===` | Comparador customizado de valores. |
1131
+ | `ariaLabel` | `string` | `''` | Atributo `aria-label` do grupo. |
1132
+ | `ariaLabelledBy` | `string` | `''` | Atributo `aria-labelledby` do grupo. |
1133
+ | `dataCy` | `string` | `''` | Atributo para testes E2E. |
1134
+
1135
+ #### Eventos do `CaoRadioGroupComponent` (Outputs)
1136
+
1137
+ | Evento | Tipo | Descrição |
1138
+ | --- | --- | --- |
1139
+ | `valueChange` | `EventEmitter<any>` | Emitido quando o valor selecionado muda. |
1140
+ | `selectionChange` | `EventEmitter<ICaoRadioChangeEvent>` | Emitido com o valor e o botão de origem. |
1141
+
1142
+ #### Métodos do `CaoRadioGroupComponent`
1143
+
1144
+ | Método | Descrição |
1145
+ | --- | --- |
1146
+ | `enable()` | Habilita o grupo e todas as opções. |
1147
+ | `disable()` | Desabilita o grupo e todas as opções. |
1148
+ | `isValueSelected(value)` | Verifica se um valor está selecionado usando `compareWith`. |
1149
+ | `markAsTouched()` | Marca o controle como tocado. |
1150
+ | `writeValue(value)` | Implementação de `ControlValueAccessor`. |
1151
+ | `setDisabledState(isDisabled)` | Implementação de `ControlValueAccessor`. |
1152
+
1153
+ #### Atributos do `CaoRadioButtonComponent` (Inputs)
1154
+
1155
+ | Atributo | Tipo | Padrão | Descrição |
1156
+ | --- | --- | --- | --- |
1157
+ | `value` | `any` | `undefined` | **Obrigatório.** Valor único da opção dentro do grupo. |
1158
+ | `label` | `string` | `''` | Texto do label. Também aceita conteúdo projetado. |
1159
+ | `isDisabled` | `boolean` | `false` | Desabilita apenas esta opção. |
1160
+ | `disabled` | `boolean` | `false` | Alias de `isDisabled`. |
1161
+ | `labelPosition` | `'before' \| 'after'` | herda do grupo | Posição do label desta opção. |
1162
+ | `name` | `string` | herda do grupo | Sobrescreve o nome do grupo para esta opção. |
1163
+ | `id` | `string` | gerado automaticamente | Atributo `id` do input. |
1164
+ | `ariaLabel` | `string` | `''` | Atributo `aria-label` da opção. |
1165
+ | `ariaLabelledBy` | `string` | `''` | Atributo `aria-labelledby` da opção. |
1166
+ | `dataCy` | `string` | `''` | Atributo para testes E2E. |
1167
+ | `color` | `string` | herda do grupo | Cor da opção selecionada. |
1168
+ | `unselectedColor` | `string` | herda do grupo | Cor da borda não selecionada. |
1169
+ | `disabledColor` | `string` | herda do grupo | Cor da opção desabilitada. |
1170
+ | `labelColor` | `string` | herda do grupo | Cor do label. |
1171
+ | `disabledLabelColor` | `string` | herda do grupo | Cor do label desabilitado. |
1172
+ | `focusRingColor` | `string` | herda do grupo | Cor do anel de foco. |
1173
+ | `size` | `string` | herda do grupo | Tamanho do círculo. |
1174
+ | `animationDuration` | `string` | herda do grupo | Duração das animações. |
1175
+
1176
+ #### Métodos do `CaoRadioButtonComponent`
1177
+
1178
+ | Método | Descrição |
1179
+ | --- | --- |
1180
+ | `select()` | Seleciona a opção no grupo, se estiver habilitada. |
1181
+ | `enable()` | Habilita apenas esta opção. |
1182
+ | `disable()` | Desabilita apenas esta opção. |
1183
+
1184
+ **CSS Custom Properties**
1185
+
1186
+ | Propriedade | Padrão | Descrição |
1187
+ | --- | --- | --- |
1188
+ | `--cao-radio-color` | `#4f46e5` | Cor da opção selecionada. |
1189
+ | `--cao-radio-unselected` | `#6b7280` | Cor da borda não selecionada. |
1190
+ | `--cao-radio-disabled` | `#d1d5db` | Cor da opção desabilitada. |
1191
+ | `--cao-radio-label` | `#111827` | Cor do label. |
1192
+ | `--cao-radio-label-disabled` | `#9ca3af` | Cor do label desabilitado. |
1193
+ | `--cao-radio-focus-ring` | `rgba(79, 70, 229, 0.35)` | Cor do anel de foco. |
1194
+ | `--cao-radio-size` | `20px` | Tamanho do círculo. |
1195
+ | `--cao-radio-duration` | `200ms` | Duração das animações. |
1196
+ | `--cao-radio-gap` | `8px` | Espaçamento entre opções. |
1197
+
1198
+ **Exemplo com `ngModel`:**
1199
+
1200
+ ```html
1201
+ <cao-radio-group [(ngModel)]="planoSelecionado" ariaLabel="Escolha um plano">
1202
+ <cao-radio-button value="basico" label="Básico"></cao-radio-button>
1203
+ <cao-radio-button value="profissional" label="Profissional"></cao-radio-button>
1204
+ <cao-radio-button value="empresarial" label="Empresarial"></cao-radio-button>
1205
+ </cao-radio-group>
1206
+ ```
1207
+
1208
+ **Exemplo com formulário reativo, layout horizontal e cores customizadas:**
1209
+
1210
+ ```html
1211
+ <cao-radio-group
1212
+ [formControl]="periodo"
1213
+ orientation="horizontal"
1214
+ gap="16px"
1215
+ color="#16a34a"
1216
+ unselectedColor="#94a3b8"
1217
+ labelColor="#166534">
1218
+ <cao-radio-button value="manha" label="Manhã"></cao-radio-button>
1219
+ <cao-radio-button value="tarde" label="Tarde"></cao-radio-button>
1220
+ <cao-radio-button value="noite" label="Noite"></cao-radio-button>
1221
+ </cao-radio-group>
1222
+ ```
1223
+
1224
+ **Exemplo com disabled geral e por opção:**
1225
+
1226
+ ```html
1227
+ <cao-radio-group [(ngModel)]="opcao" [isDisabled]="formularioBloqueado">
1228
+ <cao-radio-button value="a" label="Disponível"></cao-radio-button>
1229
+ <cao-radio-button value="b" label="Indisponível" [isDisabled]="true"></cao-radio-button>
1230
+ </cao-radio-group>
1231
+ ```
1232
+
1233
+ **Exemplo com `compareWith` para valores objetos:**
1234
+
1235
+ ```html
1236
+ <cao-radio-group [(ngModel)]="usuarioSelecionado" [compareWith]="compararUsuarios">
1237
+ @for (usuario of usuarios; track usuario.id) {
1238
+ <cao-radio-button [value]="usuario" [label]="usuario.nome"></cao-radio-button>
1239
+ }
1240
+ </cao-radio-group>
1241
+ ```
1242
+
1243
+ ```typescript
1244
+ compararUsuarios(a: Usuario | null, b: Usuario | null): boolean {
1245
+ return a?.id === b?.id;
1246
+ }
1247
+ ```
1248
+
1249
+ **Observações:**
1250
+
1251
+ - Cada `<cao-radio-button>` deve estar dentro de um `<cao-radio-group>`.
1252
+ - O grupo usa `role="radiogroup"` e inputs nativos `type="radio"` com o mesmo `name`, garantindo navegação por setas, foco e leitores de tela.
1253
+ - `FormControl.disable()` desabilita o grupo inteiro, assim como `isDisabled`/`disabled`.
1254
+ - Cores e tamanhos podem ser definidos no grupo (herdados por todas as opções) ou individualmente em cada botão.
1255
+ - Métodos `enable()`/`disable()` permitem controlar o estado programaticamente.
1256
+
1257
+ ---
1258
+
931
1259
  ### `DropDown`
932
1260
  Um menu suspenso (dropdown) com busca, que funciona com `ngModel` ou `formControlName`.
933
1261