accordion.stories.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // @ts-nocheck
  2. import { createEffect, createSignal } from "solid-js"
  3. import * as mod from "./accordion"
  4. import { create } from "../storybook/scaffold"
  5. const docs = `### Overview
  6. Accordion for collapsible content sections with optional multi-open behavior.
  7. Use one trigger per item; keep content concise.
  8. ### API
  9. - Root supports Kobalte Accordion props: \`value\`, \`multiple\`, \`collapsible\`, \`onChange\`.
  10. - Compose with \`Accordion.Item\`, \`Header\`, \`Trigger\`, \`Content\`.
  11. ### Variants and states
  12. - Single or multiple open items.
  13. - Collapsible or fixed-open behavior.
  14. ### Behavior
  15. - Controlled via \`value\`/\`onChange\` when provided.
  16. ### Accessibility
  17. - TODO: confirm keyboard navigation from Kobalte Accordion.
  18. ### Theming/tokens
  19. - Uses \`data-component="accordion"\` and slot data attributes.
  20. `
  21. const story = create({ title: "UI/Accordion", mod })
  22. export default {
  23. title: "UI/Accordion",
  24. id: "components-accordion",
  25. component: story.meta.component,
  26. tags: ["autodocs"],
  27. parameters: {
  28. docs: {
  29. description: {
  30. component: docs,
  31. },
  32. },
  33. },
  34. }
  35. export const Basic = {
  36. args: {
  37. collapsible: true,
  38. multiple: false,
  39. value: "first",
  40. },
  41. argTypes: {
  42. collapsible: { control: "boolean" },
  43. multiple: { control: "boolean" },
  44. value: {
  45. control: "select",
  46. options: ["first", "second", "none"],
  47. mapping: {
  48. none: undefined,
  49. },
  50. },
  51. },
  52. render: (props) => {
  53. const [value, setValue] = createSignal(props.value)
  54. createEffect(() => {
  55. setValue(props.value)
  56. })
  57. const current = () => {
  58. if (props.multiple) {
  59. if (Array.isArray(value())) return value()
  60. if (value()) return [value()]
  61. return []
  62. }
  63. if (Array.isArray(value())) return value()[0]
  64. return value()
  65. }
  66. return (
  67. <div style={{ display: "grid", gap: "8px", width: "420px" }}>
  68. <mod.Accordion collapsible={props.collapsible} multiple={props.multiple} value={current()} onChange={setValue}>
  69. <mod.Accordion.Item value="first">
  70. <mod.Accordion.Header>
  71. <mod.Accordion.Trigger>First</mod.Accordion.Trigger>
  72. </mod.Accordion.Header>
  73. <mod.Accordion.Content>
  74. <div style={{ color: "var(--text-weak)", padding: "8px 0" }}>Accordion content.</div>
  75. </mod.Accordion.Content>
  76. </mod.Accordion.Item>
  77. <mod.Accordion.Item value="second">
  78. <mod.Accordion.Header>
  79. <mod.Accordion.Trigger>Second</mod.Accordion.Trigger>
  80. </mod.Accordion.Header>
  81. <mod.Accordion.Content>
  82. <div style={{ color: "var(--text-weak)", padding: "8px 0" }}>More content.</div>
  83. </mod.Accordion.Content>
  84. </mod.Accordion.Item>
  85. </mod.Accordion>
  86. </div>
  87. )
  88. },
  89. }
  90. export const Multiple = {
  91. args: {
  92. collapsible: true,
  93. multiple: true,
  94. value: ["first", "second"],
  95. },
  96. render: (props) => (
  97. <mod.Accordion collapsible={props.collapsible} multiple={props.multiple} value={props.value}>
  98. <mod.Accordion.Item value="first">
  99. <mod.Accordion.Header>
  100. <mod.Accordion.Trigger>First</mod.Accordion.Trigger>
  101. </mod.Accordion.Header>
  102. <mod.Accordion.Content>
  103. <div style={{ color: "var(--text-weak)", padding: "8px 0" }}>Accordion content.</div>
  104. </mod.Accordion.Content>
  105. </mod.Accordion.Item>
  106. <mod.Accordion.Item value="second">
  107. <mod.Accordion.Header>
  108. <mod.Accordion.Trigger>Second</mod.Accordion.Trigger>
  109. </mod.Accordion.Header>
  110. <mod.Accordion.Content>
  111. <div style={{ color: "var(--text-weak)", padding: "8px 0" }}>More content.</div>
  112. </mod.Accordion.Content>
  113. </mod.Accordion.Item>
  114. </mod.Accordion>
  115. ),
  116. }
  117. export const NonCollapsible = {
  118. args: {
  119. collapsible: false,
  120. multiple: false,
  121. value: "first",
  122. },
  123. render: (props) => (
  124. <mod.Accordion collapsible={props.collapsible} multiple={props.multiple} value={props.value}>
  125. <mod.Accordion.Item value="first">
  126. <mod.Accordion.Header>
  127. <mod.Accordion.Trigger>First</mod.Accordion.Trigger>
  128. </mod.Accordion.Header>
  129. <mod.Accordion.Content>
  130. <div style={{ color: "var(--text-weak)", padding: "8px 0" }}>Accordion content.</div>
  131. </mod.Accordion.Content>
  132. </mod.Accordion.Item>
  133. </mod.Accordion>
  134. ),
  135. }