Design system.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

127 行
3.2 KiB

  1. import * as React from 'react';
  2. import clsx from 'clsx';
  3. import plugin from 'tailwindcss/plugin';
  4. /**
  5. * Derived HTML element of the {@link ColorPicker} component.
  6. */
  7. export type ColorPickerDerivedElement = HTMLInputElement;
  8. /**
  9. * Props of the {@link ColorPicker} component.
  10. */
  11. export interface ColorPickerProps extends Omit<React.HTMLProps<ColorPickerDerivedElement>, 'size' | 'type' | 'label'> {
  12. square?: boolean;
  13. size?: 'small' | 'medium' | 'large';
  14. }
  15. export const colorPickerPlugin = plugin(({ addComponents }) => {
  16. addComponents({
  17. '.color-picker': {
  18. '&::-webkit-color-swatch-wrapper': {
  19. 'padding': '0',
  20. },
  21. '&::-webkit-color-swatch': {
  22. 'border': '0',
  23. },
  24. '&::-moz-color-swatch': {
  25. 'border': '0',
  26. },
  27. },
  28. });
  29. });
  30. /**
  31. * Component for picking a color.
  32. */
  33. export const ColorPicker = React.forwardRef<
  34. ColorPickerDerivedElement,
  35. ColorPickerProps
  36. >((
  37. {
  38. className,
  39. id: idProp,
  40. style,
  41. square = false as const,
  42. size = 'medium' as const,
  43. ...etcProps
  44. },
  45. forwardedRef,
  46. ) => (
  47. <div
  48. className={clsx(
  49. 'inline-block align-center relative ring-secondary/50 rounded overflow-hidden box-border group has-[:disabled]:opacity-50',
  50. 'rounded focus-within:ring-4 active:ring-tertiary/50',
  51. {
  52. 'w-8': square && size === 'small',
  53. 'w-12': square && size === 'medium',
  54. 'w-16': square && size === 'large',
  55. },
  56. {
  57. 'w-16': !square && size === 'small',
  58. 'w-24': !square && size === 'medium',
  59. 'w-32': !square && size === 'large',
  60. },
  61. className,
  62. )}
  63. style={style}
  64. >
  65. <span
  66. className={clsx(
  67. 'block w-full',
  68. {
  69. 'p-[25%]': square,
  70. 'p-[12.5%]': !square,
  71. },
  72. )}
  73. >
  74. <input
  75. {...etcProps}
  76. className={clsx(
  77. 'color-picker absolute top-0 left-0 w-full h-full overflow-hidden cursor-pointer disabled:cursor-not-allowed',
  78. 'focus:outline-0',
  79. )}
  80. ref={forwardedRef}
  81. id={idProp}
  82. type="color"
  83. />
  84. </span>
  85. <span
  86. className={clsx(
  87. 'border-y-4 border-l-4 border-r-2 absolute top-0 left-0 h-full pointer-events-none border-[#000000]',
  88. {
  89. 'w-1/2': square,
  90. 'w-3/4': !square,
  91. },
  92. )}
  93. />
  94. <span
  95. className={clsx(
  96. 'absolute flex items-center justify-center top-0 right-0 h-full pointer-events-none bg-negative text-primary group-has-[:disabled]:text-primary group-active:text-tertiary group-focus-within:text-secondary',
  97. {
  98. 'w-1/2': square,
  99. 'w-1/4': !square,
  100. },
  101. )}
  102. >
  103. <svg
  104. className="w-6 h-6 fill-none stroke-current stroke-2 linejoin-round linecap-round"
  105. viewBox="0 0 24 24"
  106. role="presentation"
  107. >
  108. <polyline points="6 9 12 15 18 9" />
  109. </svg>
  110. </span>
  111. <span
  112. className="border-2 absolute top-0 left-0 w-full h-full pointer-events-none border-primary group-active:border-tertiary group-has-[:disabled]:border-primary group-focus-within:border-secondary"
  113. />
  114. </div>
  115. ));
  116. ColorPicker.displayName = 'ColorPicker';
  117. ColorPicker.defaultProps = {
  118. square: false as const,
  119. size: 'medium' as const,
  120. };