|
| 1 | +import { Meta, Story, Controls, Canvas } from "@storybook/blocks"; |
| 2 | + |
| 3 | +import * as MultipleSelectStories from "./MultipleSelect.stories"; |
| 4 | + |
| 5 | +<Meta |
| 6 | + of={MultipleSelectStories} |
| 7 | + parameters={{ |
| 8 | + layout: "centered", |
| 9 | + docs: { |
| 10 | + story: { |
| 11 | + inline: true, |
| 12 | + iframeHeight: 200, |
| 13 | + }, |
| 14 | + }, |
| 15 | + }} |
| 16 | +/> |
| 17 | + |
| 18 | +# MultipleSelect |
| 19 | + |
| 20 | +A flexible multi-select component with grouped options, exclusive selections, and collapsible sections. |
| 21 | + |
| 22 | +## Props |
| 23 | + |
| 24 | +### Component Props |
| 25 | + |
| 26 | +- **`options`**: `MultipleSelectGroup[]` - Array of option groups |
| 27 | +- **`defaultValue`**: `Record<string, string[]>` - Initial selections per group |
| 28 | +- **`placeholder`**: `string` - Text shown when nothing selected if defaultValue then placeholder will be ignored |
| 29 | +- **`className`**: `string` - Popover container CSS classes |
| 30 | +- **`variants`**: `object` - Style customizations with the following options: |
| 31 | + - **`color`**: `"default" | "grey"` - Controls the overall color scheme |
| 32 | + - **`size`**: `"default" | "sm"` - Controls component sizing |
| 33 | + - **`rounded`**: `"default"` - Controls border radius styling |
| 34 | + - **`itemsPosition`**: `"start" | "end" | "center"` - Controls alignment of items in the list |
| 35 | + - **`headerPosition`**: `"start" | "end" | "center"` - Controls alignment of group headers |
| 36 | + - **`triggerTextColor`**: `"default" | "red" | "green"` - Controls the trigger text color |
| 37 | + - **`itemsColor`**: `"default" | "light-grey"` - Controls the color of items and their icons |
| 38 | +- **`onChange`**: `(values: Record<string, string[]>) => void` - Selection change handler |
| 39 | + |
| 40 | +### Group Properties (`MultipleSelectGroup`) |
| 41 | + |
| 42 | +- **`groupLabel?`**: `string` - Group name (omit for ungrouped items) |
| 43 | +- **`multiple?`**: `boolean` - Allow multiple selections (default: true) |
| 44 | +- **`collapsible?`**: `boolean` - Enable group toggle |
| 45 | +- **`items`**: `MultipleSelectItem[]` - Array of options |
| 46 | + |
| 47 | +### Item Properties (`MultipleSelectItem`) |
| 48 | + |
| 49 | +- **`value`**: `string` - Unique identifier |
| 50 | +- **`label`**: `string` - Display text |
| 51 | +- **`exclusive?`**: `boolean` - Clear other selections when chosen |
| 52 | +- **`exclusiveScope?`**: `"group" | "global"` - Clear scope for exclusive items |
| 53 | +- **`iconType?`**: `IconType` - Optional icon identifier check `@/primitives/Icon story` |
| 54 | +- **`icon?`**: `React.ComponentType` - Optional icon component used if no iconType is provided |
| 55 | +- **`itemClassName?`**: `string` - Item-specific CSS classes |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +<Canvas of={MultipleSelectStories.FilterExample}> |
| 60 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 61 | + <Story |
| 62 | + of={MultipleSelectStories.FilterExample} |
| 63 | + parameters={{ |
| 64 | + docs: { |
| 65 | + canvas: { sourceState: "shown" }, |
| 66 | + }, |
| 67 | + }} |
| 68 | + /> |
| 69 | + </div> |
| 70 | +</Canvas> |
| 71 | +<Controls of={MultipleSelectStories.FilterExample} /> |
| 72 | + |
| 73 | +## Stories |
| 74 | + |
| 75 | +Below are several usage examples showcasing common patterns and advanced features. |
| 76 | + |
| 77 | +### 1. Basic |
| 78 | + |
| 79 | +<Canvas of={MultipleSelectStories.Basic}> |
| 80 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 81 | + <Story |
| 82 | + of={MultipleSelectStories.Basic} |
| 83 | + parameters={{ |
| 84 | + layout: "centered", |
| 85 | + docs: { |
| 86 | + canvas: { sourceState: "shown" }, |
| 87 | + }, |
| 88 | + }} |
| 89 | + /> |
| 90 | + </div> |
| 91 | +</Canvas> |
| 92 | + |
| 93 | +**Description** |
| 94 | +A single ungrouped set of items (no group label) with simple placeholder text. |
| 95 | + |
| 96 | +- **Options**: 3 items, no exclusivity. |
| 97 | +- **`onChange`** logs the selection to console. |
| 98 | + |
| 99 | +### 2. OrderByExample |
| 100 | + |
| 101 | +<Canvas of={MultipleSelectStories.OrderByExample}> |
| 102 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 103 | + <Story |
| 104 | + of={MultipleSelectStories.OrderByExample} |
| 105 | + parameters={{ |
| 106 | + layout: "centered", |
| 107 | + docs: { |
| 108 | + canvas: { sourceState: "shown" }, |
| 109 | + }, |
| 110 | + }} |
| 111 | + /> |
| 112 | + </div> |
| 113 | +</Canvas> |
| 114 | + |
| 115 | +**Description** Demonstrates **exclusive items** across two single-select groups (“Order by time” and |
| 116 | +“Order by name”). Each item has `exclusive: true, exclusiveScope: 'global'`, ensuring that if you pick |
| 117 | +“Recent,” it clears any “A-Z” or “Z-A” selection. |
| 118 | + |
| 119 | +- **`defaultValue`** sets the initial selection to `["Recent"]` in the “ORDER BY TIME” group. |
| 120 | +- **`variants`** example usage for adjusting text color, alignment, etc. |
| 121 | + |
| 122 | +### 3. FilterExample |
| 123 | + |
| 124 | +<Canvas of={MultipleSelectStories.FilterExample}> |
| 125 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 126 | + <Story |
| 127 | + of={MultipleSelectStories.FilterExample} |
| 128 | + parameters={{ |
| 129 | + layout: "centered", |
| 130 | + docs: { |
| 131 | + canvas: { sourceState: "shown" }, |
| 132 | + }, |
| 133 | + }} |
| 134 | + /> |
| 135 | + </div> |
| 136 | +</Canvas> |
| 137 | + |
| 138 | +**Description** A **filter** scenario with an **“All”** exclusive item for resetting. |
| 139 | + |
| 140 | +- “All” is in an **ungrouped** set with `exclusive: true, exclusiveScope: 'global'`. |
| 141 | +- Two collapsible groups, “Network” and “Status,” each with `multiple: true`. |
| 142 | +- **`defaultValue`** starts with “All” selected in the ungrouped items. |
| 143 | + |
| 144 | +### 4. MixedSelectionTypes |
| 145 | + |
| 146 | +<Canvas of={MultipleSelectStories.MixedSelectionTypes}> |
| 147 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 148 | + <Story |
| 149 | + of={MultipleSelectStories.MixedSelectionTypes} |
| 150 | + parameters={{ |
| 151 | + layout: "centered", |
| 152 | + docs: { |
| 153 | + canvas: { sourceState: "shown" }, |
| 154 | + }, |
| 155 | + }} |
| 156 | + /> |
| 157 | + </div> |
| 158 | +</Canvas> |
| 159 | + |
| 160 | +**Description** Shows a combination of: |
| 161 | + |
| 162 | +- A group with an **exclusive** item called “Reset All.” |
| 163 | +- Another group that’s **multi-select** with standard options. |
| 164 | + |
| 165 | +This approach is useful when you have a special action (like “Reset” or “Clear All”) plus normal multi-select items. |
| 166 | + |
| 167 | +### 5. WithVariants |
| 168 | + |
| 169 | +<Canvas of={MultipleSelectStories.WithVariants}> |
| 170 | + <div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "1rem" }}> |
| 171 | + <Story |
| 172 | + of={MultipleSelectStories.WithVariants} |
| 173 | + parameters={{ |
| 174 | + layout: "centered", |
| 175 | + docs: { |
| 176 | + canvas: { sourceState: "shown" }, |
| 177 | + }, |
| 178 | + }} |
| 179 | + /> |
| 180 | + </div> |
| 181 | +</Canvas> |
| 182 | + |
| 183 | +**Description** |
| 184 | +Showcases using **all variant props** (`triggerTextColor`, `headerPosition`, `itemsPosition`, etc.) or whatever your **MultipleSelect** has to customize. |
| 185 | + |
| 186 | +- You can set text color, alignment, plus a collapsible group. |
| 187 | +- Useful to see how to pass styling variants from **tailwind-variants** to the component. |
| 188 | + |
| 189 | +--- |
| 190 | + |
| 191 | +## Tips & Best Practices |
| 192 | + |
| 193 | +1. **Use `defaultValue`** for initial selections, or manage selections outside if you want it to be “controlled.” |
| 194 | +2. **`exclusive`** items are great for “select all,” “select none,” or “reset.” |
| 195 | +3. **Collapsible groups** let you nest large sets of items without overwhelming the user. |
| 196 | + |
| 197 | +--- |
| 198 | + |
| 199 | +## Conclusion |
| 200 | + |
| 201 | +`MultipleSelect` is highly **configurable** for your needs: from a simple single group with no advanced logic, to multi-group filters, collapsible sections, exclusive “all” items, or complex order-by pickers. |
| 202 | + |
| 203 | +Check out the source code & stories for additional usage details. |
0 commit comments