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.
 
 
 

182 satır
4.5 KiB

  1. import * as React from 'react';
  2. import clsx from 'clsx';
  3. import { Button } from '@tesseract-design/web-base';
  4. /**
  5. * Derived HTML element of the {@link ActionButton} component.
  6. */
  7. export type ActionButtonDerivedElement = HTMLButtonElement;
  8. /**
  9. * Props of the {@link ActionButton} component.
  10. */
  11. export interface ActionButtonProps extends Omit<React.HTMLProps<ActionButtonDerivedElement>, 'type' | 'size'> {
  12. /**
  13. * Type of the component.
  14. */
  15. type?: Button.Type;
  16. /**
  17. * Variant of the component.
  18. */
  19. variant?: Button.Variant;
  20. /**
  21. * Should the component occupy the whole width of its parent?
  22. */
  23. block?: boolean;
  24. /**
  25. * Complementary content of the component.
  26. */
  27. subtext?: React.ReactNode;
  28. /**
  29. * Short complementary content displayed at the edge of the component.
  30. */
  31. badge?: React.ReactNode;
  32. /**
  33. * Is this component part of a menu?
  34. */
  35. menuItem?: boolean;
  36. /**
  37. * Size of the component.
  38. */
  39. size?: Button.Size;
  40. /**
  41. * Should the component's content use minimal space?
  42. */
  43. compact?: boolean;
  44. /**
  45. * Should the children's height be variable?
  46. */
  47. variableChildrenHeight?: boolean;
  48. }
  49. /**
  50. * Component for performing an action upon activation (e.g. when clicked).
  51. *
  52. * This component functions as a regular button.
  53. */
  54. export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionButtonProps>((
  55. {
  56. type = 'button' as const,
  57. variant = 'bare' as const,
  58. subtext,
  59. badge,
  60. menuItem = false as const,
  61. children,
  62. size = 'medium' as const,
  63. compact = false as const,
  64. className,
  65. block = false as const,
  66. variableChildrenHeight = false as const,
  67. ...etcProps
  68. },
  69. forwardedRef,
  70. ) => (
  71. <button
  72. {...etcProps}
  73. data-testid="button"
  74. type={type}
  75. ref={forwardedRef}
  76. className={clsx(
  77. 'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none select-none',
  78. 'focus:outline-0 focus:ring-4',
  79. 'active:ring-tertiary/50',
  80. 'disabled:opacity-50 disabled:cursor-not-allowed',
  81. {
  82. 'flex w-full': block,
  83. 'inline-flex max-w-full align-middle': !block,
  84. },
  85. {
  86. 'pl-2 gap-2': compact,
  87. 'pl-4 gap-4': !compact,
  88. 'pr-4': !(compact || menuItem),
  89. 'pr-2': compact || menuItem,
  90. },
  91. {
  92. 'border-2 border-primary focus:border-secondary active:border-tertiary disabled:border-primary': variant !== 'bare',
  93. 'bg-negative text-primary focus:text-secondary active:text-tertiary disabled:text-primary': variant !== 'filled',
  94. 'bg-primary text-negative focus:bg-secondary active:bg-tertiary focus:text-negative active:text-negative disabled:bg-primary': variant === 'filled',
  95. },
  96. {
  97. 'h-10': size === 'small',
  98. 'h-12': size === 'medium',
  99. 'h-16': size === 'large',
  100. },
  101. className,
  102. )}
  103. >
  104. <span
  105. className={clsx(
  106. 'flex-auto min-w-0',
  107. {
  108. 'text-left': compact || menuItem,
  109. 'text-center': !(compact || menuItem),
  110. },
  111. )}
  112. >
  113. <span
  114. className={clsx(
  115. 'block uppercase font-bold h-[1.1em] w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded',
  116. {
  117. 'h-[1.1em]': !variableChildrenHeight,
  118. },
  119. )}
  120. data-testid="children"
  121. >
  122. {children}
  123. </span>
  124. {subtext && (
  125. <>
  126. <span className="sr-only">
  127. {' - '}
  128. </span>
  129. <span
  130. className="block h-[1.3em] w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded font-bold text-xs"
  131. data-testid="subtext"
  132. >
  133. {subtext}
  134. </span>
  135. </>
  136. )}
  137. </span>
  138. {badge && (
  139. <>
  140. <span className="sr-only">
  141. {' - '}
  142. </span>
  143. <span
  144. data-testid="badge"
  145. >
  146. {badge}
  147. </span>
  148. </>
  149. )}
  150. {menuItem && (
  151. <span
  152. data-testid="menuItemIndicator"
  153. >
  154. <svg
  155. className="w-6 h-6 fill-none stroke-current stroke-2 linejoin-round linecap-round"
  156. viewBox="0 0 24 24"
  157. role="presentation"
  158. >
  159. <polyline points="9 18 15 12 9 6" />
  160. </svg>
  161. </span>
  162. )}
  163. </button>
  164. ));
  165. ActionButton.displayName = 'ActionButton' as const;
  166. ActionButton.defaultProps = {
  167. type: 'button' as const,
  168. variant: 'bare' as const,
  169. block: false as const,
  170. subtext: undefined,
  171. badge: undefined,
  172. menuItem: false as const,
  173. size: 'medium' as const,
  174. compact: false as const,
  175. variableChildrenHeight: false as const,
  176. };