Design system.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

129 satır
3.5 KiB

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