Website for showcasing all features of Tesseract Web.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

311 lines
6.5 KiB

  1. import { css } from '@tesseract-design/css-utils'
  2. export enum CheckControlAppearance {
  3. TICK_BOX = 'tick-box',
  4. BUTTON = 'button',
  5. SWITCH = 'switch',
  6. }
  7. export type CheckControlBaseArgs = {
  8. compact: boolean,
  9. appearance: CheckControlAppearance,
  10. block: boolean,
  11. type: string,
  12. }
  13. export const CheckStateContainer = ({
  14. appearance,
  15. type,
  16. }: CheckControlBaseArgs): string => css.cx(
  17. css`
  18. position: absolute;
  19. width: 1px;
  20. height: 1px;
  21. padding: 0;
  22. margin: -1px;
  23. overflow: hidden;
  24. clip: rect(0, 0, 0, 0);
  25. white-space: nowrap;
  26. border-width: 0;
  27. &:disabled + * {
  28. cursor: not-allowed;
  29. }
  30. &:first-child + * > :first-child + * + * {
  31. align-items: flex-start;
  32. text-align: left;
  33. }
  34. &:checked + * {
  35. --color-accent: var(--color-active, Highlight);
  36. outline: 0;
  37. }
  38. &:indeterminate[type="checkbox"] + * {
  39. --color-accent: var(--color-active, Highlight);
  40. outline: 0;
  41. }
  42. &:indeterminate[type="checkbox"] + * > :first-child + * > * > :first-child {
  43. display: none;
  44. }
  45. &:checked + * > :first-child + * > * > :first-child + * {
  46. display: none;
  47. }
  48. &:focus + * {
  49. --color-accent: var(--color-hover, red);
  50. outline: 0;
  51. }
  52. &:focus[type="checkbox"] + * {
  53. --color-accent: var(--color-hover, red);
  54. outline: 0;
  55. }
  56. &:focus + * > :first-child::before {
  57. box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
  58. }
  59. `,
  60. css.nest('&:checked + * > :first-child + * > *') (
  61. css.if (
  62. appearance === CheckControlAppearance.TICK_BOX
  63. || appearance === CheckControlAppearance.BUTTON
  64. ) (
  65. css.if (type === 'checkbox') (
  66. css`
  67. width: 1.5em;
  68. height: 1.5em;
  69. `
  70. ),
  71. css.if (type === 'radio') (
  72. css`
  73. width: 1em;
  74. height: 1em;
  75. `
  76. ),
  77. ),
  78. css.if (appearance === CheckControlAppearance.SWITCH) (
  79. css`
  80. width: 1em;
  81. height: 1em;
  82. margin-right: 0;
  83. margin-left: 1em;
  84. `
  85. ),
  86. ),
  87. css.nest('&:first-child + *') (
  88. css`
  89. cursor: pointer;
  90. `,
  91. css.if (appearance === CheckControlAppearance.BUTTON) (
  92. css`
  93. display: flex;
  94. `,
  95. ),
  96. css.if (appearance === CheckControlAppearance.SWITCH) (
  97. css`
  98. width: 1em;
  99. height: 1em;
  100. `,
  101. ),
  102. ),
  103. css.nest('&:indeterminate[type="checkbox"] + * > :first-child + * > *') (
  104. css.if (
  105. appearance === CheckControlAppearance.BUTTON
  106. || appearance === CheckControlAppearance.TICK_BOX
  107. ) (
  108. css`
  109. width: 1.5em;
  110. height: 1.5em;
  111. `
  112. ),
  113. css.if (appearance === CheckControlAppearance.SWITCH) (
  114. css`
  115. width: 1em;
  116. height: 1em;
  117. margin-right: 0.5em;
  118. margin-left: 0.5em;
  119. `
  120. )
  121. ),
  122. css.nest('&:indeterminate[type="checkbox"] + * > :first-child + * > * > :first-child + *') (
  123. css.if (
  124. appearance === CheckControlAppearance.BUTTON
  125. || appearance === CheckControlAppearance.TICK_BOX
  126. ) (
  127. css`
  128. display: block;
  129. `
  130. ),
  131. ),
  132. css.nest('&:checked + * > :first-child + * > * > :first-child') (
  133. css.if (
  134. appearance === CheckControlAppearance.BUTTON
  135. || appearance === CheckControlAppearance.TICK_BOX
  136. ) (
  137. css`
  138. display: block;
  139. `
  140. ),
  141. ),
  142. );
  143. export const ClickArea = (): string => css.cx(
  144. css`
  145. display: contents;
  146. `
  147. );
  148. export const CheckIndicatorArea = ({
  149. compact,
  150. appearance,
  151. type,
  152. }: CheckControlBaseArgs): string => css.cx(
  153. css`
  154. display: inline-grid;
  155. vertical-align: middle;
  156. place-content: center;
  157. position: relative;
  158. background-color: var(--color-bg, white);
  159. box-shadow: 0 0 0 0.125rem var(--color-bg, white);
  160. color: var(--color-accent, blue);
  161. overflow: hidden;
  162. &::before {
  163. content: '';
  164. width: 100%;
  165. height: 100%;
  166. position: absolute;
  167. top: 0;
  168. left: 0;
  169. border-radius: inherit;
  170. border-width: 0.125rem;
  171. border-style: solid;
  172. box-sizing: border-box;
  173. }
  174. `,
  175. css.if (appearance === CheckControlAppearance.TICK_BOX) (
  176. css`
  177. width: 1.5em;
  178. height: 1.5em;
  179. `,
  180. css.if (type === 'checkbox') (
  181. css`
  182. border-radius: 0.25rem;
  183. `
  184. ),
  185. css.if (type === 'radio') (
  186. css`
  187. border-radius: 50%;
  188. `
  189. ),
  190. ),
  191. css.if (appearance === CheckControlAppearance.BUTTON) (
  192. css`
  193. width: 1.5em;
  194. height: 1.5em;
  195. `,
  196. css.if (!compact) (
  197. css`
  198. margin-left: -0.25rem;
  199. `
  200. ),
  201. css.if (type === 'checkbox') (
  202. css`
  203. border-radius: 0.25rem;
  204. `
  205. ),
  206. css.if (type === 'radio') (
  207. css`
  208. border-radius: 50%;
  209. `
  210. ),
  211. ),
  212. css.if (appearance === CheckControlAppearance.SWITCH) (
  213. css`
  214. width: 2.5em;
  215. height: 1.5em;
  216. border-radius: 0.75em;
  217. `
  218. ),
  219. css.nest('& + *') (
  220. css.dynamic({
  221. 'margin-left': compact ? '0.375rem' : '0.75rem',
  222. })
  223. )
  224. );
  225. export const CheckIndicatorWrapper = ({
  226. appearance,
  227. }: CheckControlBaseArgs): string => css.cx(
  228. css`
  229. flex-shrink: 0;
  230. display: grid;
  231. position: relative;
  232. background-color: var(--color-accent, blue);
  233. overflow: hidden;
  234. border-radius: inherit;
  235. `,
  236. css.if(
  237. appearance === CheckControlAppearance.TICK_BOX
  238. || appearance === CheckControlAppearance.BUTTON
  239. ) (
  240. css`
  241. width: 0;
  242. height: 0;
  243. `
  244. ),
  245. css.if(appearance === CheckControlAppearance.SWITCH) (
  246. css`
  247. width: 1em;
  248. height: 1em;
  249. margin-right: 1em;
  250. transition-property: margin-left, margin-right;
  251. transition-duration: 150ms;
  252. transition-timing-function: ease-out;
  253. `
  254. ),
  255. );
  256. export const CheckIndicator = ({
  257. appearance,
  258. }: CheckControlBaseArgs) => css.cx(
  259. css`
  260. fill: none;
  261. stroke: var(--color-bg, white);
  262. stroke-width: 2;
  263. stroke-linecap: round;
  264. stroke-linejoin: round;
  265. width: 1.5em;
  266. height: 1.5em;
  267. `,
  268. css.if(appearance === CheckControlAppearance.SWITCH) (
  269. css`
  270. display: none;
  271. `
  272. )
  273. );
  274. export const ClickAreaWrapper = ({
  275. block,
  276. appearance,
  277. }: CheckControlBaseArgs) => css.cx(
  278. css`
  279. vertical-align: middle;
  280. `,
  281. css.dynamic({
  282. display: block ? 'block' : 'inline-block',
  283. }),
  284. css.if (appearance === CheckControlAppearance.TICK_BOX) (
  285. css`
  286. padding-left: 2.25rem;
  287. text-indent: -2.25rem;
  288. `
  289. ),
  290. css.if (appearance === CheckControlAppearance.SWITCH) (
  291. css`
  292. padding-left: 3.25rem;
  293. text-indent: -3.25rem;
  294. `
  295. ),
  296. );
  297. export const Subtext = () => css.cx(
  298. css`
  299. font-size: 0.875em;
  300. `
  301. );