marker.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import * as React from 'react';
  2. import { mergeProps } from '@base-ui/react/merge-props';
  3. import { useRender } from '@base-ui/react/use-render';
  4. import { cva, type VariantProps } from 'class-variance-authority';
  5. import { cn } from '@/lib/utils';
  6. const markerVariants = cva(
  7. "gap-2 text-sm text-muted-foreground [a]:hover:text-foreground [a]:underline-offset-3 [a]:underline [&_svg:not([class*='size-'])]:size-4 min-h-4 text-left group/marker relative flex w-full items-center",
  8. {
  9. variants: {
  10. variant: {
  11. default: '',
  12. separator:
  13. 'before:h-px before:min-w-0 before:flex-1 before:bg-border after:h-px after:min-w-0 after:flex-1 after:bg-border before:mr-1 after:ml-1',
  14. border: 'border-b border-border pb-2',
  15. },
  16. },
  17. },
  18. );
  19. function Marker({
  20. className,
  21. variant = 'default',
  22. render,
  23. ...props
  24. }: useRender.ComponentProps<'div'> & VariantProps<typeof markerVariants>) {
  25. return useRender({
  26. defaultTagName: 'div',
  27. props: mergeProps<'div'>(
  28. {
  29. className: cn(markerVariants({ variant, className })),
  30. },
  31. props,
  32. ),
  33. render,
  34. state: {
  35. slot: 'marker',
  36. variant,
  37. },
  38. });
  39. }
  40. function MarkerIcon({ className, ...props }: React.ComponentProps<'span'>) {
  41. return (
  42. <span
  43. data-slot="marker-icon"
  44. aria-hidden="true"
  45. className={cn(
  46. "size-4 [&_svg:not([class*='size-'])]:size-4 shrink-0",
  47. className,
  48. )}
  49. {...props}
  50. />
  51. );
  52. }
  53. function MarkerContent({ className, ...props }: React.ComponentProps<'span'>) {
  54. return (
  55. <span
  56. data-slot="marker-content"
  57. className={cn(
  58. 'group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:hover:text-foreground *:[a]:underline *:[a]:underline-offset-3 min-w-0 wrap-break-word',
  59. className,
  60. )}
  61. {...props}
  62. />
  63. );
  64. }
  65. export { Marker, MarkerIcon, MarkerContent, markerVariants };