analytica-frontend-lib 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.css CHANGED
@@ -5,6 +5,7 @@
5
5
  :root,
6
6
  :host {
7
7
  --font-sans:
8
+ "Roboto",
8
9
  ui-sans-serif,
9
10
  system-ui,
10
11
  sans-serif,
@@ -26,6 +27,8 @@
26
27
  --text-xs--line-height: calc(1 / 0.75);
27
28
  --text-sm: 0.875rem;
28
29
  --text-sm--line-height: calc(1.25 / 0.875);
30
+ --text-base: 1rem;
31
+ --text-base--line-height: calc(1.5 / 1);
29
32
  --text-lg: 1.125rem;
30
33
  --text-lg--line-height: calc(1.75 / 1.125);
31
34
  --text-xl: 1.25rem;
@@ -49,12 +52,14 @@
49
52
  --font-weight-black: 900;
50
53
  --radius-sm: 0.25rem;
51
54
  --radius-md: 0.375rem;
55
+ --radius-lg: 0.5rem;
52
56
  --radius-xl: 0.75rem;
53
57
  --default-transition-duration: 150ms;
54
58
  --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
55
59
  --default-font-family: var(--font-sans);
56
60
  --default-mono-font-family: var(--font-mono);
57
61
  --color-primary-50: #999999;
62
+ --color-primary-100: #808080;
58
63
  --color-primary-400: #525252;
59
64
  --color-primary-500: #333333;
60
65
  --color-primary-600: #292929;
@@ -63,6 +68,7 @@
63
68
  --color-primary-950: #080808;
64
69
  --color-text: #fefeff;
65
70
  --color-text-400: #a3a3a3;
71
+ --color-text-500: #8c8c8c;
66
72
  --color-text-600: #737373;
67
73
  --color-text-700: #525252;
68
74
  --color-text-800: #404040;
@@ -76,6 +82,8 @@
76
82
  --color-border-50: #f3f3f3;
77
83
  --color-border-100: #e6e6e6;
78
84
  --color-border-200: #dddcdb;
85
+ --color-border-400: #a5a3a3;
86
+ --color-border-500: #8c8d8d;
79
87
  --color-success-300: #66b584;
80
88
  --color-success-400: #489766;
81
89
  --color-success-500: #348352;
@@ -310,6 +318,9 @@
310
318
  .absolute {
311
319
  position: absolute;
312
320
  }
321
+ .fixed {
322
+ position: fixed;
323
+ }
313
324
  .relative {
314
325
  position: relative;
315
326
  }
@@ -331,6 +342,24 @@
331
342
  .z-50 {
332
343
  z-index: 50;
333
344
  }
345
+ .container {
346
+ width: 100%;
347
+ @media (width >= 40rem) {
348
+ max-width: 40rem;
349
+ }
350
+ @media (width >= 48rem) {
351
+ max-width: 48rem;
352
+ }
353
+ @media (width >= 64rem) {
354
+ max-width: 64rem;
355
+ }
356
+ @media (width >= 80rem) {
357
+ max-width: 80rem;
358
+ }
359
+ @media (width >= 96rem) {
360
+ max-width: 96rem;
361
+ }
362
+ }
334
363
  .mx-2 {
335
364
  margin-inline: calc(var(--spacing) * 2);
336
365
  }
@@ -340,9 +369,15 @@
340
369
  .my-4 {
341
370
  margin-block: calc(var(--spacing) * 4);
342
371
  }
372
+ .mt-1\.5 {
373
+ margin-top: calc(var(--spacing) * 1.5);
374
+ }
343
375
  .mt-2 {
344
376
  margin-top: calc(var(--spacing) * 2);
345
377
  }
378
+ .mt-4 {
379
+ margin-top: calc(var(--spacing) * 4);
380
+ }
346
381
  .mr-2 {
347
382
  margin-right: calc(var(--spacing) * 2);
348
383
  }
@@ -352,18 +387,33 @@
352
387
  .mb-3 {
353
388
  margin-bottom: calc(var(--spacing) * 3);
354
389
  }
390
+ .mb-4 {
391
+ margin-bottom: calc(var(--spacing) * 4);
392
+ }
393
+ .mb-6 {
394
+ margin-bottom: calc(var(--spacing) * 6);
395
+ }
396
+ .mb-8 {
397
+ margin-bottom: calc(var(--spacing) * 8);
398
+ }
355
399
  .ml-2 {
356
400
  margin-left: calc(var(--spacing) * 2);
357
401
  }
358
402
  .flex {
359
403
  display: flex;
360
404
  }
405
+ .grid {
406
+ display: grid;
407
+ }
361
408
  .inline-flex {
362
409
  display: inline-flex;
363
410
  }
364
411
  .table {
365
412
  display: table;
366
413
  }
414
+ .h-4 {
415
+ height: calc(var(--spacing) * 4);
416
+ }
367
417
  .h-5 {
368
418
  height: calc(var(--spacing) * 5);
369
419
  }
@@ -376,9 +426,18 @@
376
426
  .h-10 {
377
427
  height: calc(var(--spacing) * 10);
378
428
  }
429
+ .h-\[21px\] {
430
+ height: 21px;
431
+ }
432
+ .h-\[27px\] {
433
+ height: 27px;
434
+ }
379
435
  .h-px {
380
436
  height: 1px;
381
437
  }
438
+ .w-4 {
439
+ width: calc(var(--spacing) * 4);
440
+ }
382
441
  .w-5 {
383
442
  width: calc(var(--spacing) * 5);
384
443
  }
@@ -388,6 +447,9 @@
388
447
  .w-8 {
389
448
  width: calc(var(--spacing) * 8);
390
449
  }
450
+ .w-10 {
451
+ width: calc(var(--spacing) * 10);
452
+ }
391
453
  .w-full {
392
454
  width: 100%;
393
455
  }
@@ -410,6 +472,9 @@
410
472
  .cursor-pointer {
411
473
  cursor: pointer;
412
474
  }
475
+ .grid-cols-2 {
476
+ grid-template-columns: repeat(2, minmax(0, 1fr));
477
+ }
413
478
  .flex-col {
414
479
  flex-direction: column;
415
480
  }
@@ -422,6 +487,9 @@
422
487
  .items-center {
423
488
  align-items: center;
424
489
  }
490
+ .items-end {
491
+ align-items: flex-end;
492
+ }
425
493
  .justify-center {
426
494
  justify-content: center;
427
495
  }
@@ -431,6 +499,9 @@
431
499
  .gap-0\.5 {
432
500
  gap: calc(var(--spacing) * 0.5);
433
501
  }
502
+ .gap-1\.5 {
503
+ gap: calc(var(--spacing) * 1.5);
504
+ }
434
505
  .gap-2 {
435
506
  gap: calc(var(--spacing) * 2);
436
507
  }
@@ -449,9 +520,15 @@
449
520
  .overflow-hidden {
450
521
  overflow: hidden;
451
522
  }
523
+ .rounded {
524
+ border-radius: 0.25rem;
525
+ }
452
526
  .rounded-full {
453
527
  border-radius: calc(infinity * 1px);
454
528
  }
529
+ .rounded-lg {
530
+ border-radius: var(--radius-lg);
531
+ }
455
532
  .rounded-md {
456
533
  border-radius: var(--radius-md);
457
534
  }
@@ -465,6 +542,14 @@
465
542
  border-style: var(--tw-border-style);
466
543
  border-width: 1px;
467
544
  }
545
+ .border-2 {
546
+ border-style: var(--tw-border-style);
547
+ border-width: 2px;
548
+ }
549
+ .border-\[3px\] {
550
+ border-style: var(--tw-border-style);
551
+ border-width: 3px;
552
+ }
468
553
  .border-t {
469
554
  border-top-style: var(--tw-border-style);
470
555
  border-top-width: 1px;
@@ -489,18 +574,36 @@
489
574
  .border-border-200 {
490
575
  border-color: var(--color-border-200);
491
576
  }
577
+ .border-border-400 {
578
+ border-color: var(--color-border-400);
579
+ }
580
+ .border-border-500 {
581
+ border-color: var(--color-border-500);
582
+ }
492
583
  .border-error-300 {
493
584
  border-color: var(--color-error-300);
494
585
  }
495
586
  .border-error-500 {
496
587
  border-color: var(--color-error-500);
497
588
  }
589
+ .border-error-700 {
590
+ border-color: var(--color-error-700);
591
+ }
498
592
  .border-indicator-error {
499
593
  border-color: var(--color-indicator-error);
500
594
  }
595
+ .border-indicator-info {
596
+ border-color: var(--color-indicator-info);
597
+ }
501
598
  .border-indicator-primary {
502
599
  border-color: var(--color-indicator-primary);
503
600
  }
601
+ .border-primary-600 {
602
+ border-color: var(--color-primary-600);
603
+ }
604
+ .border-primary-800 {
605
+ border-color: var(--color-primary-800);
606
+ }
504
607
  .border-primary-950 {
505
608
  border-color: var(--color-primary-950);
506
609
  }
@@ -510,6 +613,9 @@
510
613
  .border-success-500 {
511
614
  border-color: var(--color-success-500);
512
615
  }
616
+ .\!bg-primary-50 {
617
+ background-color: var(--color-primary-50) !important;
618
+ }
513
619
  .bg-background {
514
620
  background-color: var(--color-background);
515
621
  }
@@ -528,6 +634,12 @@
528
634
  .bg-primary-50 {
529
635
  background-color: var(--color-primary-50);
530
636
  }
637
+ .bg-primary-600 {
638
+ background-color: var(--color-primary-600);
639
+ }
640
+ .bg-primary-800 {
641
+ background-color: var(--color-primary-800);
642
+ }
531
643
  .bg-primary-950 {
532
644
  background-color: var(--color-primary-950);
533
645
  }
@@ -549,6 +661,9 @@
549
661
  .p-4 {
550
662
  padding: calc(var(--spacing) * 4);
551
663
  }
664
+ .p-6 {
665
+ padding: calc(var(--spacing) * 6);
666
+ }
552
667
  .p-8 {
553
668
  padding: calc(var(--spacing) * 8);
554
669
  }
@@ -621,6 +736,10 @@
621
736
  font-size: var(--text-6xl);
622
737
  line-height: var(--tw-leading, var(--text-6xl--line-height));
623
738
  }
739
+ .text-base {
740
+ font-size: var(--text-base);
741
+ line-height: var(--tw-leading, var(--text-base--line-height));
742
+ }
624
743
  .text-lg {
625
744
  font-size: var(--text-lg);
626
745
  line-height: var(--tw-leading, var(--text-lg--line-height));
@@ -641,6 +760,10 @@
641
760
  font-size: var(--text-xs);
642
761
  line-height: var(--tw-leading, var(--text-xs--line-height));
643
762
  }
763
+ .leading-\[150\%\] {
764
+ --tw-leading: 150%;
765
+ line-height: 150%;
766
+ }
644
767
  .font-black {
645
768
  --tw-font-weight: var(--font-weight-black);
646
769
  font-weight: var(--font-weight-black);
@@ -676,9 +799,15 @@
676
799
  .whitespace-nowrap {
677
800
  white-space: nowrap;
678
801
  }
802
+ .\!text-primary-950 {
803
+ color: var(--color-primary-950) !important;
804
+ }
679
805
  .text-error-500 {
680
806
  color: var(--color-error-500);
681
807
  }
808
+ .text-error-600 {
809
+ color: var(--color-error-600);
810
+ }
682
811
  .text-primary-950 {
683
812
  color: var(--color-primary-950);
684
813
  }
@@ -691,6 +820,9 @@
691
820
  .text-text-400 {
692
821
  color: var(--color-text-400);
693
822
  }
823
+ .text-text-500 {
824
+ color: var(--color-text-500);
825
+ }
694
826
  .text-text-600 {
695
827
  color: var(--color-text-600);
696
828
  }
@@ -709,6 +841,12 @@
709
841
  .capitalize {
710
842
  text-transform: capitalize;
711
843
  }
844
+ .italic {
845
+ font-style: italic;
846
+ }
847
+ .opacity-40 {
848
+ opacity: 40%;
849
+ }
712
850
  .opacity-50 {
713
851
  opacity: 50%;
714
852
  }
@@ -748,6 +886,12 @@
748
886
  var(--tw-ring-shadow),
749
887
  var(--tw-shadow);
750
888
  }
889
+ .ring-indicator-info\/20 {
890
+ --tw-ring-color: color-mix(in srgb, #5399ec 20%, transparent);
891
+ @supports (color: color-mix(in lab, red, red)) {
892
+ --tw-ring-color: color-mix(in oklab, var(--color-indicator-info) 20%, transparent);
893
+ }
894
+ }
751
895
  .ring-primary-950 {
752
896
  --tw-ring-color: var(--color-primary-950);
753
897
  }
@@ -759,6 +903,11 @@
759
903
  outline-style: var(--tw-outline-style);
760
904
  outline-width: 1px;
761
905
  }
906
+ .transition-all {
907
+ transition-property: all;
908
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
909
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
910
+ }
762
911
  .transition-colors {
763
912
  transition-property:
764
913
  color,
@@ -774,6 +923,10 @@
774
923
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
775
924
  transition-duration: var(--tw-duration, var(--default-transition-duration));
776
925
  }
926
+ .duration-200 {
927
+ --tw-duration: 200ms;
928
+ transition-duration: 200ms;
929
+ }
777
930
  .outline-none {
778
931
  --tw-outline-style: none;
779
932
  outline-style: none;
@@ -783,6 +936,13 @@
783
936
  -moz-user-select: none;
784
937
  user-select: none;
785
938
  }
939
+ .hover\:border-border-500 {
940
+ &:hover {
941
+ @media (hover: hover) {
942
+ border-color: var(--color-border-500);
943
+ }
944
+ }
945
+ }
786
946
  .hover\:border-error-400 {
787
947
  &:hover {
788
948
  @media (hover: hover) {
@@ -825,6 +985,13 @@
825
985
  }
826
986
  }
827
987
  }
988
+ .hover\:\!bg-primary-100 {
989
+ &:hover {
990
+ @media (hover: hover) {
991
+ background-color: var(--color-primary-100) !important;
992
+ }
993
+ }
994
+ }
828
995
  .hover\:bg-background-50 {
829
996
  &:hover {
830
997
  @media (hover: hover) {
@@ -915,6 +1082,12 @@
915
1082
  }
916
1083
  }
917
1084
  }
1085
+ .focus\:outline-none {
1086
+ &:focus {
1087
+ --tw-outline-style: none;
1088
+ outline-style: none;
1089
+ }
1090
+ }
918
1091
  .focus-visible\:border-0 {
919
1092
  &:focus-visible {
920
1093
  border-style: var(--tw-border-style);
@@ -1501,6 +1674,7 @@
1501
1674
  @property --tw-skew-x { syntax: "*"; inherits: false; }
1502
1675
  @property --tw-skew-y { syntax: "*"; inherits: false; }
1503
1676
  @property --tw-border-style { syntax: "*"; inherits: false; initial-value: solid; }
1677
+ @property --tw-leading { syntax: "*"; inherits: false; }
1504
1678
  @property --tw-font-weight { syntax: "*"; inherits: false; }
1505
1679
  @property --tw-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }
1506
1680
  @property --tw-shadow-color { syntax: "*"; inherits: false; }
@@ -1517,6 +1691,7 @@
1517
1691
  @property --tw-ring-offset-color { syntax: "*"; inherits: false; initial-value: #fff; }
1518
1692
  @property --tw-ring-offset-shadow { syntax: "*"; inherits: false; initial-value: 0 0 #0000; }
1519
1693
  @property --tw-outline-style { syntax: "*"; inherits: false; initial-value: solid; }
1694
+ @property --tw-duration { syntax: "*"; inherits: false; }
1520
1695
  @layer properties {
1521
1696
  @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
1522
1697
  *,
@@ -1532,6 +1707,7 @@
1532
1707
  --tw-skew-x: initial;
1533
1708
  --tw-skew-y: initial;
1534
1709
  --tw-border-style: solid;
1710
+ --tw-leading: initial;
1535
1711
  --tw-font-weight: initial;
1536
1712
  --tw-shadow: 0 0 #0000;
1537
1713
  --tw-shadow-color: initial;
@@ -1548,6 +1724,7 @@
1548
1724
  --tw-ring-offset-color: #fff;
1549
1725
  --tw-ring-offset-shadow: 0 0 #0000;
1550
1726
  --tw-outline-style: solid;
1727
+ --tw-duration: initial;
1551
1728
  }
1552
1729
  }
1553
1730
  }
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
- import { ReactNode, ButtonHTMLAttributes, ElementType, ComponentPropsWithoutRef, HTMLAttributes, TdHTMLAttributes } from 'react';
3
+ import { ReactNode, ButtonHTMLAttributes, ElementType, ComponentPropsWithoutRef, InputHTMLAttributes, HTMLAttributes, TdHTMLAttributes } from 'react';
4
4
 
5
5
  /**
6
6
  * Button component props interface
@@ -184,6 +184,76 @@ type TextProps<T extends ElementType = 'p'> = BaseTextProps & {
184
184
  */
185
185
  declare const Text: <T extends ElementType = "p">({ children, size, weight, color, as, className, ...props }: TextProps<T>) => react_jsx_runtime.JSX.Element;
186
186
 
187
+ /**
188
+ * CheckBox size variants
189
+ */
190
+ type CheckBoxSize = 'small' | 'medium' | 'large';
191
+ /**
192
+ * CheckBox visual state
193
+ */
194
+ type CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';
195
+ /**
196
+ * CheckBox component props interface
197
+ */
198
+ type CheckBoxProps = {
199
+ /** Label text to display next to the checkbox */
200
+ label?: ReactNode;
201
+ /** Size variant of the checkbox */
202
+ size?: CheckBoxSize;
203
+ /** Visual state of the checkbox */
204
+ state?: CheckBoxState;
205
+ /** Indeterminate state for partial selections */
206
+ indeterminate?: boolean;
207
+ /** Error message to display */
208
+ errorMessage?: string;
209
+ /** Helper text to display */
210
+ helperText?: string;
211
+ /** Additional CSS classes */
212
+ className?: string;
213
+ /** Label CSS classes */
214
+ labelClassName?: string;
215
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;
216
+ /**
217
+ * CheckBox component for Analytica Ensino platforms
218
+ *
219
+ * A checkbox component with essential states, sizes and themes.
220
+ * Uses the Analytica Ensino Design System colors from styles.css with automatic
221
+ * light/dark mode support. Includes Text component integration for consistent typography.
222
+ *
223
+ * @example
224
+ * ```tsx
225
+ * // Basic checkbox
226
+ * <CheckBox label="Option" />
227
+ *
228
+ * // Small size
229
+ * <CheckBox size="small" label="Small option" />
230
+ *
231
+ * // Invalid state
232
+ * <CheckBox state="invalid" label="Required field" />
233
+ *
234
+ * // Disabled state
235
+ * <CheckBox disabled label="Disabled option" />
236
+ * ```
237
+ */
238
+ declare const CheckBox: react.ForwardRefExoticComponent<{
239
+ /** Label text to display next to the checkbox */
240
+ label?: ReactNode;
241
+ /** Size variant of the checkbox */
242
+ size?: CheckBoxSize;
243
+ /** Visual state of the checkbox */
244
+ state?: CheckBoxState;
245
+ /** Indeterminate state for partial selections */
246
+ indeterminate?: boolean;
247
+ /** Error message to display */
248
+ errorMessage?: string;
249
+ /** Helper text to display */
250
+ helperText?: string;
251
+ /** Additional CSS classes */
252
+ className?: string;
253
+ /** Label CSS classes */
254
+ labelClassName?: string;
255
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & react.RefAttributes<HTMLInputElement>>;
256
+
187
257
  type TableRowState = 'default' | 'selected' | 'invalid' | 'disabled';
188
258
  interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {
189
259
  state?: TableRowState;
@@ -275,4 +345,77 @@ declare const NavButton: react.ForwardRefExoticComponent<{
275
345
  className?: string;
276
346
  } & ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
277
347
 
278
- export { Button, DropdownMenu, DropdownMenuTrigger, IconRoundedButton, MenuContent, MenuItem, MenuLabel, MenuSeparator, NavButton, SelectionButton, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Text };
348
+ /**
349
+ * IconButton component props interface
350
+ */
351
+ type IconButtonProps = {
352
+ /** Ícone a ser exibido no botão */
353
+ icon: ReactNode;
354
+ /** Tamanho do botão */
355
+ size?: 'sm' | 'md';
356
+ /** Estado de seleção/ativo do botão - permanece ativo até ser clicado novamente ou outro botão ser ativado */
357
+ active?: boolean;
358
+ /** Additional CSS classes to apply */
359
+ className?: string;
360
+ } & ButtonHTMLAttributes<HTMLButtonElement>;
361
+ /**
362
+ * IconButton component for Analytica Ensino platforms
363
+ *
364
+ * Um botão compacto apenas com ícone, ideal para menus dropdown,
365
+ * barras de ferramentas e ações secundárias.
366
+ * Oferece dois tamanhos com estilo consistente.
367
+ * Estado ativo permanece até ser clicado novamente ou outro botão ser ativado.
368
+ * Compatível com Next.js 15 e React 19.
369
+ * Suporta forwardRef para acesso programático ao elemento DOM.
370
+ *
371
+ * @param icon - O ícone a ser exibido no botão
372
+ * @param size - Tamanho do botão (sm, md)
373
+ * @param active - Estado ativo/selecionado do botão
374
+ * @param className - Classes CSS adicionais
375
+ * @param props - Todos os outros atributos HTML padrão de button
376
+ * @returns Um elemento button compacto estilizado apenas com ícone
377
+ *
378
+ * @example
379
+ * ```tsx
380
+ * <IconButton
381
+ * icon={<MoreVerticalIcon />}
382
+ * size="sm"
383
+ * onClick={() => openMenu()}
384
+ * />
385
+ * ```
386
+ *
387
+ * @example
388
+ * ```tsx
389
+ * // Botão ativo em uma barra de ferramentas - permanece ativo até outro clique
390
+ * <IconButton
391
+ * icon={<BoldIcon />}
392
+ * active={isBold}
393
+ * onClick={toggleBold}
394
+ * />
395
+ * ```
396
+ *
397
+ * @example
398
+ * ```tsx
399
+ * // Usando ref para controle programático
400
+ * const buttonRef = useRef<HTMLButtonElement>(null);
401
+ *
402
+ * <IconButton
403
+ * ref={buttonRef}
404
+ * icon={<EditIcon />}
405
+ * size="md"
406
+ * onClick={() => startEditing()}
407
+ * />
408
+ * ```
409
+ */
410
+ declare const IconButton: react.ForwardRefExoticComponent<{
411
+ /** Ícone a ser exibido no botão */
412
+ icon: ReactNode;
413
+ /** Tamanho do botão */
414
+ size?: "sm" | "md";
415
+ /** Estado de seleção/ativo do botão - permanece ativo até ser clicado novamente ou outro botão ser ativado */
416
+ active?: boolean;
417
+ /** Additional CSS classes to apply */
418
+ className?: string;
419
+ } & ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
420
+
421
+ export { Button, CheckBox, type CheckBoxProps, DropdownMenu, DropdownMenuTrigger, IconButton, type IconButtonProps, IconRoundedButton, MenuContent, MenuItem, MenuLabel, MenuSeparator, NavButton, SelectionButton, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Text };