select.stories.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import type { Meta, StoryObj } from "@storybook/react";
  2. import { Select } from "../../ui/src/lib/select/select";
  3. const thousandOptions = (() => {
  4. return Array.from({ length: 1000 }, (_, i) => `Option ${i}`);
  5. })();
  6. const meta = {
  7. title: "UI/Select",
  8. component: Select,
  9. parameters: {
  10. layout: "centered",
  11. },
  12. } satisfies Meta<typeof Select>;
  13. export default meta;
  14. type Story = StoryObj<typeof Select>;
  15. export const Default: Story = {
  16. args: {
  17. placeholder: "Select a fruit",
  18. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  19. label: "default",
  20. },
  21. };
  22. export const Searchable: Story = {
  23. args: {
  24. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  25. placeholder: "searchable select",
  26. searchable: true,
  27. },
  28. };
  29. export const Inline: Story = {
  30. args: {
  31. placeholder: "inline select",
  32. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  33. isInline: true,
  34. },
  35. };
  36. export const Required: Story = {
  37. args: {
  38. placeholder: "Select a fruit",
  39. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  40. label: "required",
  41. required: true,
  42. },
  43. };
  44. export const Disabled: Story = {
  45. args: {
  46. placeholder: "Select a fruit",
  47. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  48. label: "disabled select",
  49. disabled: true,
  50. },
  51. };
  52. export const WithComplexOptions: Story = {
  53. args: {
  54. placeholder: "Select a fruit",
  55. value: "Blueberry",
  56. searchable: true,
  57. options: [
  58. {
  59. value: "Apple",
  60. disabled: true,
  61. },
  62. {
  63. value: "Banana",
  64. label: (
  65. <>
  66. <span>Banana</span>
  67. <span className="text-sm"> - 10</span>
  68. <span className="text-lg"> other element</span>
  69. </>
  70. ),
  71. },
  72. {
  73. value: "Blueberry",
  74. label: (
  75. <>
  76. <span>Blueberry</span>
  77. <span className="text-sm"> - 15</span>
  78. </>
  79. ),
  80. disabled: true,
  81. },
  82. "Grapes",
  83. "Pineapple",
  84. ] as any[],
  85. label: "Fancy option",
  86. },
  87. };
  88. export const WithCustomTestId: Story = {
  89. args: {
  90. placeholder: "custom testid",
  91. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  92. "data-testid": "my-select",
  93. } as any,
  94. };
  95. export const WithManyOptions: Story = {
  96. args: {
  97. options: thousandOptions as any[],
  98. label: "Thousand options",
  99. },
  100. };
  101. export const WithManyOptionsSearchableVirtualList: Story = {
  102. args: {
  103. options: thousandOptions as any[],
  104. label: "Thousand options (searchable + virtual list)",
  105. searchable: true,
  106. isVirtualList: true,
  107. },
  108. };
  109. export const Loading: Story = {
  110. args: {
  111. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  112. label: "In progress",
  113. isLoading: true,
  114. },
  115. };
  116. export const MultipleSelect: Story = {
  117. args: {
  118. placeholder: "Multiple Selector",
  119. options: [
  120. "Apple",
  121. "Banana",
  122. "Blueberry",
  123. { label: "Grapes", children: ["Small", "Large", "Green", "Red"] },
  124. "Pineapple",
  125. ] as any[],
  126. multiple: true,
  127. searchable: true,
  128. },
  129. };
  130. export const MultipleSelectWithValues: Story = {
  131. args: {
  132. value: ["Blueberry", "Banana"],
  133. options: ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] as any[],
  134. multiple: true,
  135. },
  136. };
  137. export const BooleanValues: Story = {
  138. args: {
  139. options: [
  140. { label: "Yes", value: true },
  141. { label: "No", value: false },
  142. ] as any[],
  143. label: "Boolean values",
  144. },
  145. };
  146. export const WithRenderSelected: Story = {
  147. args: {
  148. options: [
  149. { label: "Yes", value: true },
  150. { label: "No", value: false },
  151. ] as any[],
  152. label: "Boolean values with renderSelected",
  153. renderSelected: (selectedOptions, placeholder) => {
  154. if (selectedOptions.length > 0) {
  155. return `${selectedOptions
  156. .map((option) => (typeof option === "string" ? option : (option as any).label))
  157. .join(", ")} and such`;
  158. }
  159. return placeholder;
  160. },
  161. multiple: true,
  162. },
  163. };
  164. export const WithCustomRenderSelected: Story = {
  165. args: {
  166. options: [
  167. { label: "Yes", value: true },
  168. { label: "No", value: false },
  169. ] as any[],
  170. label: "Boolean values with renderSelected",
  171. renderSelected: () => "Always show this",
  172. },
  173. };