tabs.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { Tabs as Kobalte } from "@kobalte/core/tabs"
  2. import { Show, splitProps, type JSX } from "solid-js"
  3. import type { ComponentProps, ParentProps } from "solid-js"
  4. export interface TabsProps extends ComponentProps<typeof Kobalte> {
  5. variant?: "normal" | "alt"
  6. }
  7. export interface TabsListProps extends ComponentProps<typeof Kobalte.List> {}
  8. export interface TabsTriggerProps extends ComponentProps<typeof Kobalte.Trigger> {
  9. classes?: {
  10. button?: string
  11. }
  12. hideCloseButton?: boolean
  13. closeButton?: JSX.Element
  14. }
  15. export interface TabsContentProps extends ComponentProps<typeof Kobalte.Content> {}
  16. function TabsRoot(props: TabsProps) {
  17. const [split, rest] = splitProps(props, ["class", "classList", "variant"])
  18. return (
  19. <Kobalte
  20. {...rest}
  21. data-component="tabs"
  22. data-variant={split.variant || "normal"}
  23. classList={{
  24. ...(split.classList ?? {}),
  25. [split.class ?? ""]: !!split.class,
  26. }}
  27. />
  28. )
  29. }
  30. function TabsList(props: TabsListProps) {
  31. const [split, rest] = splitProps(props, ["class", "classList"])
  32. return (
  33. <Kobalte.List
  34. {...rest}
  35. data-slot="tabs-list"
  36. classList={{
  37. ...(split.classList ?? {}),
  38. [split.class ?? ""]: !!split.class,
  39. }}
  40. />
  41. )
  42. }
  43. function TabsTrigger(props: ParentProps<TabsTriggerProps>) {
  44. const [split, rest] = splitProps(props, [
  45. "class",
  46. "classList",
  47. "classes",
  48. "children",
  49. "closeButton",
  50. "hideCloseButton",
  51. ])
  52. return (
  53. <div
  54. data-slot="tabs-trigger-wrapper"
  55. classList={{
  56. ...(split.classList ?? {}),
  57. [split.class ?? ""]: !!split.class,
  58. }}
  59. >
  60. <Kobalte.Trigger
  61. {...rest}
  62. data-slot="tabs-trigger"
  63. classList={{ "group/tab": true, [split.classes?.button ?? ""]: split.classes?.button }}
  64. >
  65. {split.children}
  66. </Kobalte.Trigger>
  67. <Show when={split.closeButton}>
  68. {(closeButton) => (
  69. <div data-slot="tabs-trigger-close-button" data-hidden={split.hideCloseButton}>
  70. {closeButton()}
  71. </div>
  72. )}
  73. </Show>
  74. </div>
  75. )
  76. }
  77. function TabsContent(props: ParentProps<TabsContentProps>) {
  78. const [split, rest] = splitProps(props, ["class", "classList", "children"])
  79. return (
  80. <Kobalte.Content
  81. {...rest}
  82. data-slot="tabs-content"
  83. classList={{
  84. ...(split.classList ?? {}),
  85. [split.class ?? ""]: !!split.class,
  86. }}
  87. >
  88. {split.children}
  89. </Kobalte.Content>
  90. )
  91. }
  92. export const Tabs = Object.assign(TabsRoot, {
  93. List: TabsList,
  94. Trigger: TabsTrigger,
  95. Content: TabsContent,
  96. })