tabs.tsx 2.7 KB

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