Website for showcasing all features of Tesseract Web.
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.
 
 

298 líneas
5.3 KiB

  1. import { css } from '@tesseract-design/css-utils';
  2. export enum ButtonSize {
  3. SMALL = 'small',
  4. MEDIUM = 'medium',
  5. LARGE = 'large',
  6. }
  7. export enum ButtonVariant {
  8. OUTLINE = 'outline',
  9. FILLED = 'filled',
  10. }
  11. export type ButtonBaseArgs = {
  12. size: ButtonSize,
  13. block: boolean,
  14. variant: ButtonVariant,
  15. border: boolean,
  16. disabled: boolean,
  17. compact: boolean,
  18. menuItem: boolean,
  19. }
  20. const MIN_HEIGHTS: Record<ButtonSize, string> = {
  21. [ButtonSize.SMALL]: '2.5rem',
  22. [ButtonSize.MEDIUM]: '3rem',
  23. [ButtonSize.LARGE]: '4rem',
  24. };
  25. export const Button = ({
  26. size,
  27. block,
  28. variant,
  29. disabled,
  30. compact,
  31. }: ButtonBaseArgs): string => css.cx(
  32. css`
  33. box-sizing: border-box;
  34. vertical-align: middle;
  35. appearance: none;
  36. font: inherit;
  37. font-family: var(--font-family-base, sans-serif);
  38. text-transform: uppercase;
  39. font-weight: bolder;
  40. border-radius: 0.25rem;
  41. justify-content: center;
  42. align-items: center;
  43. position: relative;
  44. border: 0;
  45. user-select: none;
  46. text-decoration: none;
  47. white-space: nowrap;
  48. line-height: 1;
  49. & > :first-child::before {
  50. box-shadow: 0 0 0 0 var(--color-accent, blue);
  51. transition-property: box-shadow;
  52. transition-duration: 150ms;
  53. transition-timing-function: linear;
  54. }
  55. &:disabled {
  56. opacity: 0.5;
  57. cursor: not-allowed;
  58. }
  59. &::-moz-focus-inner {
  60. outline: 0;
  61. border: 0;
  62. }
  63. &:focus > :first-child::before {
  64. box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
  65. }
  66. &:disabled > :first-child::before {
  67. box-shadow: 0 0 0 0 var(--color-accent, blue) !important;
  68. }
  69. `,
  70. css.dynamic({
  71. 'min-height': MIN_HEIGHTS[size],
  72. }),
  73. css.if (disabled) (
  74. css`
  75. --color-accent: var(--color-primary, blue);
  76. opacity: 0.5;
  77. cursor: not-allowed;
  78. `
  79. ).else (
  80. css`
  81. cursor: pointer;
  82. &:hover {
  83. --color-accent: var(--color-hover, blue);
  84. outline: 0;
  85. }
  86. &:focus {
  87. --color-accent: var(--color-hover, blue);
  88. outline: 0;
  89. }
  90. &:active {
  91. --color-accent: var(--color-active, red);
  92. outline: 0;
  93. }
  94. &:hover > :first-child::before {
  95. box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
  96. }
  97. `
  98. ),
  99. css.if (block) (
  100. css`
  101. width: 100%;
  102. display: flex;
  103. `
  104. ).else (
  105. css`
  106. display: inline-flex;
  107. `
  108. ),
  109. css.if (compact) (
  110. css`
  111. font-stretch: condensed;
  112. padding: 0 0.5rem;
  113. `
  114. ).else(
  115. css`
  116. padding: 0 1rem;
  117. `
  118. ),
  119. css.if (variant === ButtonVariant.FILLED) (
  120. css`
  121. background-color: var(--color-accent, blue);
  122. color: var(--color-bg, white) !important;
  123. `
  124. ),
  125. css.if (variant === ButtonVariant.OUTLINE) (
  126. css`
  127. background-color: var(--color-bg, white);
  128. color: var(--color-accent, blue);
  129. `
  130. ),
  131. );
  132. export const Border = ({
  133. border
  134. }: ButtonBaseArgs): string => css.cx(
  135. css.if (border) (
  136. css`
  137. border-color: var(--color-accent, blue);
  138. box-sizing: border-box;
  139. display: inline-block;
  140. border-width: 0.125rem;
  141. border-style: solid;
  142. position: absolute;
  143. top: 0;
  144. left: 0;
  145. width: 100%;
  146. height: 100%;
  147. border-radius: inherit;
  148. pointer-events: none;
  149. &::before {
  150. position: absolute;
  151. top: 0;
  152. left: 0;
  153. width: 100%;
  154. height: 100%;
  155. content: '';
  156. border-radius: 0.125rem;
  157. opacity: 0.5;
  158. pointer-events: none;
  159. }
  160. `
  161. ),
  162. );
  163. export const Label = ({
  164. compact,
  165. menuItem,
  166. }: ButtonBaseArgs): string => css.cx(
  167. css`
  168. display: block;
  169. flex-grow: 1;
  170. flex-basis: 0;
  171. min-width: 0;
  172. `,
  173. css.if (compact || menuItem) (
  174. css`
  175. text-align: left;
  176. `
  177. ).else (
  178. css`
  179. text-align: center;
  180. `
  181. ),
  182. css.if (compact) (
  183. css`
  184. & ~ :last-child {
  185. margin-right: -0.5rem;
  186. }
  187. `
  188. ).else (
  189. css`
  190. & ~ :last-child {
  191. margin-right: -1rem;
  192. }
  193. `
  194. ),
  195. );
  196. export const BadgeContainer = ({
  197. size,
  198. }: ButtonBaseArgs): string => css.cx(
  199. css`
  200. width: 2rem;
  201. text-align: center;
  202. flex-shrink: 0;
  203. & + * {
  204. margin-left: -0.5rem;
  205. }
  206. `,
  207. css.nest('&:last-child')(
  208. css.dynamic({
  209. width: MIN_HEIGHTS[size],
  210. })
  211. ),
  212. );
  213. export const OverflowText = (): string => css.cx(
  214. css`
  215. width: 100%;
  216. display: block;
  217. overflow: hidden;
  218. text-overflow: ellipsis;
  219. height: 1.1em;
  220. line-height: 1;
  221. `,
  222. );
  223. export const IndicatorWrapper = ({
  224. size
  225. }: ButtonBaseArgs): string => css.cx(
  226. css`
  227. flex-shrink: 0;
  228. box-sizing: border-box;
  229. display: grid;
  230. place-content: center;
  231. padding: 0 1rem;
  232. z-index: 1;
  233. pointer-events: none;
  234. line-height: 1;
  235. user-select: none;
  236. `,
  237. css.dynamic({
  238. width: `calc(${MIN_HEIGHTS[size]} * 0.75)`,
  239. height: MIN_HEIGHTS[size],
  240. }),
  241. );
  242. export const Indicator = () => css.cx(
  243. css`
  244. width: 1.5em;
  245. height: 1.5em;
  246. fill: none;
  247. stroke: currentColor;
  248. stroke-width: 2;
  249. stroke-linecap: round;
  250. stroke-linejoin: round;
  251. `,
  252. );
  253. export const MainText = () => css.cx(
  254. css`
  255. width: 100%;
  256. `,
  257. );
  258. export const Subtext = () => css.cx(
  259. css`
  260. display: block;
  261. height: 1.1em;
  262. line-height: 1.1;
  263. width: 100%;
  264. font-size: 0.875em;
  265. text-transform: none;
  266. font-weight: var(--font-weight-base, normal);
  267. `,
  268. );