Design system.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

131 líneas
3.5 KiB

  1. import * as React from 'react';
  2. import { useFallbackId } from '@modal-sh/react-utils';
  3. import { tailwind } from '@tesseract-design/web-base';
  4. const { tw } = tailwind;
  5. const RadioTickBoxDerivedElementComponent = 'input' as const;
  6. /**
  7. * Derived HTML element of the {@link RadioTickBox} component.
  8. */
  9. export type RadioTickBoxDerivedElement = HTMLElementTagNameMap[
  10. typeof RadioTickBoxDerivedElementComponent
  11. ];
  12. /**
  13. * Props of the {@link RadioTickBox} component.
  14. */
  15. export interface RadioTickBoxProps extends Omit<React.InputHTMLAttributes<RadioTickBoxDerivedElement>, 'type' | 'size'> {
  16. /**
  17. * Should the component occupy the whole width of its parent?
  18. */
  19. block?: boolean;
  20. /**
  21. * Complementary content of the component.
  22. */
  23. subtext?: React.ReactNode;
  24. }
  25. export const radioTickBoxPlugin: tailwind.PluginCreator = ({ addComponents }) => {
  26. addComponents({
  27. '.radio-tick-box': {
  28. '& + label + label > :first-child > :first-child': {
  29. 'display': 'none',
  30. },
  31. '&:checked + label + label > :first-child > :first-child': {
  32. 'display': 'block',
  33. },
  34. },
  35. });
  36. };
  37. /**
  38. * Component for selecting a single value from an array of choices grouped by name.
  39. *
  40. * This component is displayed as a tick box, i.e. a typical radio button.
  41. */
  42. export const RadioTickBox = React.forwardRef<RadioTickBoxDerivedElement, RadioTickBoxProps>((
  43. {
  44. children,
  45. block = false as const,
  46. id: idProp,
  47. className,
  48. subtext,
  49. style,
  50. ...etcProps
  51. },
  52. forwardedRef,
  53. ) => {
  54. const id = useFallbackId(idProp);
  55. return (
  56. <div
  57. className={tw(
  58. 'gap-x-4 flex-wrap',
  59. block && 'flex',
  60. !block && 'inline-flex align-center',
  61. className,
  62. )}
  63. style={style}
  64. data-testid="base"
  65. >
  66. <RadioTickBoxDerivedElementComponent
  67. {...etcProps}
  68. ref={forwardedRef}
  69. type="radio"
  70. id={id}
  71. className="sr-only peer/radio radio-tick-box"
  72. />
  73. <label
  74. htmlFor={id}
  75. className="peer/children order-2 cursor-pointer peer-disabled/radio:cursor-not-allowed"
  76. >
  77. <span
  78. data-testid="children"
  79. >
  80. {children}
  81. </span>
  82. </label>
  83. <label
  84. htmlFor={id}
  85. className={tw(
  86. 'order-1 block rounded-full ring-secondary/50 overflow-hidden gap-4 leading-none select-none cursor-pointer',
  87. 'peer-focus/radio:outline-0 peer-focus/radio:ring-4 peer-focus/radio:ring-secondary/50',
  88. 'active:ring-tertiary/50 active:ring-4',
  89. 'peer-active/children:ring-tertiary/50 peer-active/children:ring-4 peer-active/children:text-tertiary',
  90. 'peer-disabled/radio:opacity-50 peer-disabled/radio:cursor-not-allowed peer-disabled/radio:ring-0',
  91. 'text-primary peer-disabled/radio:text-primary peer-focus/radio:text-secondary peer-checked/radio:text-tertiary active:text-tertiary',
  92. )}
  93. >
  94. <span
  95. className={tw(
  96. 'w-6 h-6 block rounded-full border-2 p-0.5 box-border border-current',
  97. )}
  98. >
  99. <span
  100. className={tw(
  101. 'w-full h-full rounded-full bg-current text-current',
  102. )}
  103. />
  104. </span>
  105. </label>
  106. {subtext && (
  107. <div
  108. className="block w-full text-xs pl-10 order-3"
  109. data-testid="subtext"
  110. >
  111. {subtext}
  112. </div>
  113. )}
  114. </div>
  115. );
  116. });
  117. RadioTickBox.displayName = 'RadioTickBox' as const;
  118. RadioTickBox.defaultProps = {
  119. block: false as const,
  120. subtext: undefined,
  121. };