@delightui/components 0.1.104 → 0.1.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +104 -1
  2. package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
  3. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  4. package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  5. package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  6. package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  7. package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
  8. package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  9. package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
  10. package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
  11. package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
  12. package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
  13. package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
  14. package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
  15. package/dist/cjs/components/molecules/index.d.ts +2 -0
  16. package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
  17. package/dist/cjs/components/utils/index.d.ts +2 -0
  18. package/dist/cjs/library.css +13 -0
  19. package/dist/cjs/library.js +2 -2
  20. package/dist/cjs/library.js.map +1 -1
  21. package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
  22. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
  23. package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
  24. package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
  25. package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
  26. package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
  27. package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
  28. package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
  29. package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
  30. package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
  31. package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
  32. package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
  33. package/dist/esm/components/molecules/Select/index.d.ts +2 -9
  34. package/dist/esm/components/molecules/index.d.ts +2 -0
  35. package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
  36. package/dist/esm/components/utils/index.d.ts +2 -0
  37. package/dist/esm/library.css +13 -0
  38. package/dist/esm/library.js +3 -3
  39. package/dist/esm/library.js.map +1 -1
  40. package/dist/index.d.ts +156 -12
  41. package/docs/README.md +264 -0
  42. package/docs/components/atoms/ActionImage.md +119 -0
  43. package/docs/components/atoms/Button.md +197 -0
  44. package/docs/components/atoms/Checkbox.md +299 -0
  45. package/docs/components/atoms/CheckboxItem.md +314 -0
  46. package/docs/components/atoms/Chip.md +380 -0
  47. package/docs/components/atoms/CustomToggle.md +270 -0
  48. package/docs/components/atoms/Icon.md +365 -0
  49. package/docs/components/atoms/IconButton.md +407 -0
  50. package/docs/components/atoms/Image.md +448 -0
  51. package/docs/components/atoms/Input.md +430 -0
  52. package/docs/components/atoms/ListItem.md +502 -0
  53. package/docs/components/atoms/Password.md +472 -0
  54. package/docs/components/atoms/RadioButton.md +614 -0
  55. package/docs/components/atoms/RadioButtonItem.md +588 -0
  56. package/docs/components/atoms/ResponsiveComponent.md +612 -0
  57. package/docs/components/atoms/SelectListItem.md +609 -0
  58. package/docs/components/atoms/Slider.md +605 -0
  59. package/docs/components/atoms/Spinner.md +605 -0
  60. package/docs/components/atoms/Text.md +463 -0
  61. package/docs/components/atoms/TextArea.md +670 -0
  62. package/docs/components/atoms/ToastNotification.md +668 -0
  63. package/docs/components/atoms/Toggle.md +737 -0
  64. package/docs/components/atoms/ToggleButton.md +751 -0
  65. package/docs/components/atoms/Tooltip.md +391 -0
  66. package/docs/components/molecules/Accordion.md +440 -0
  67. package/docs/components/molecules/AccordionGroup.md +547 -0
  68. package/docs/components/molecules/ActionCard.md +546 -0
  69. package/docs/components/molecules/Breadcrumb.md +403 -0
  70. package/docs/components/molecules/Breadcrumbs.md +485 -0
  71. package/docs/components/molecules/ButtonGroup.md +383 -0
  72. package/docs/components/molecules/Card.md +298 -0
  73. package/docs/components/molecules/ChipInput.md +646 -0
  74. package/docs/components/molecules/ContextMenu.md +768 -0
  75. package/docs/components/molecules/CustomTimeSelector.md +116 -0
  76. package/docs/components/molecules/DatePicker.md +516 -0
  77. package/docs/components/molecules/DateTimeSelector.md +166 -0
  78. package/docs/components/molecules/FormField.md +312 -0
  79. package/docs/components/molecules/Grid.md +577 -0
  80. package/docs/components/molecules/GridItem.md +834 -0
  81. package/docs/components/molecules/GridList.md +244 -0
  82. package/docs/components/molecules/List.md +485 -0
  83. package/docs/components/molecules/Modal.md +470 -0
  84. package/docs/components/molecules/ModalFooter.md +702 -0
  85. package/docs/components/molecules/ModalHeader.md +756 -0
  86. package/docs/components/molecules/ModalProvider.md +205 -0
  87. package/docs/components/molecules/Nav.md +530 -0
  88. package/docs/components/molecules/NavItem.md +572 -0
  89. package/docs/components/molecules/NavLink.md +499 -0
  90. package/docs/components/molecules/Option.md +521 -0
  91. package/docs/components/molecules/Pagination.md +592 -0
  92. package/docs/components/molecules/PaginationNumberField.md +722 -0
  93. package/docs/components/molecules/Popover.md +516 -0
  94. package/docs/components/molecules/ProgressBar.md +624 -0
  95. package/docs/components/molecules/RadioGroup.md +831 -0
  96. package/docs/components/molecules/RepeaterList.md +185 -0
  97. package/docs/components/molecules/Select.md +402 -0
  98. package/docs/components/molecules/SortableTrigger.md +82 -0
  99. package/docs/components/molecules/useModal.md +379 -0
  100. package/docs/components/organisms/Dropzone.md +346 -0
  101. package/docs/components/organisms/DropzoneClear.md +135 -0
  102. package/docs/components/organisms/DropzoneContent.md +216 -0
  103. package/docs/components/organisms/DropzoneFilename.md +191 -0
  104. package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
  105. package/docs/components/organisms/DropzoneTrigger.md +209 -0
  106. package/docs/components/organisms/Form.md +533 -0
  107. package/docs/components/organisms/SlideOutPanel.md +662 -0
  108. package/docs/components/organisms/TabContent.md +902 -0
  109. package/docs/components/organisms/TabItem.md +1091 -0
  110. package/docs/components/organisms/Table.md +611 -0
  111. package/docs/components/organisms/TableBody.md +679 -0
  112. package/docs/components/organisms/TableCell.md +482 -0
  113. package/docs/components/organisms/TableHeader.md +513 -0
  114. package/docs/components/organisms/TableHeaderCell.md +661 -0
  115. package/docs/components/organisms/TableRow.md +715 -0
  116. package/docs/components/organisms/Tabs.md +1330 -0
  117. package/docs/components/utils/ConditionalView.md +568 -0
  118. package/docs/components/utils/RenderStateView.md +726 -0
  119. package/docs/components/utils/WrapTextNodes.md +614 -0
  120. package/package.json +3 -2
@@ -0,0 +1,185 @@
1
+ # RepeaterList
2
+
3
+ ## Description
4
+
5
+ A simple list rendering component that iterates over an array of data and renders each item using a specified component. It provides a minimal, lightweight approach to rendering collections without additional layout or styling, making it perfect for simple repetitive content rendering.
6
+
7
+ ## Aliases
8
+
9
+ - RepeaterList
10
+ - ItemRepeater
11
+ - DataRepeater
12
+ - ComponentRepeater
13
+
14
+ ## Props Breakdown
15
+
16
+ | Prop | Type | Default | Required | Description |
17
+ |------|------|---------|----------|-------------|
18
+ | `data` | `T[]` | - | Yes | Array of data items to render |
19
+ | `component` | `React.ComponentType<T>` | - | Yes | Component to render for each data item |
20
+
21
+ ## Examples
22
+
23
+ ### Basic Usage
24
+ ```tsx
25
+ import { RepeaterList } from '@delightui/components';
26
+
27
+ const ListItem = ({ name, email }) => (
28
+ <div className="user-item">
29
+ <span>{name}</span>
30
+ <span>{email}</span>
31
+ </div>
32
+ );
33
+
34
+ function BasicRepeaterExample() {
35
+ const users = [
36
+ { name: 'John Doe', email: 'john@example.com' },
37
+ { name: 'Jane Smith', email: 'jane@example.com' },
38
+ { name: 'Bob Johnson', email: 'bob@example.com' },
39
+ ];
40
+
41
+ return (
42
+ <div className="user-list">
43
+ <RepeaterList data={users} component={ListItem} />
44
+ </div>
45
+ );
46
+ }
47
+ ```
48
+
49
+ ### Simple Text List
50
+ ```tsx
51
+ function SimpleTextExample() {
52
+ const items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];
53
+
54
+ const TextItem = ({ children }) => (
55
+ <li className="fruit-item">{children}</li>
56
+ );
57
+
58
+ // Transform strings to objects for the component
59
+ const data = items.map(item => ({ children: item }));
60
+
61
+ return (
62
+ <ul className="fruit-list">
63
+ <RepeaterList data={data} component={TextItem} />
64
+ </ul>
65
+ );
66
+ }
67
+ ```
68
+
69
+ ### Card Repeater
70
+ ```tsx
71
+ import { Card, Text, Button } from '@delightui/components';
72
+
73
+ function CardRepeaterExample() {
74
+ const products = [
75
+ { id: 1, name: 'Laptop', price: 999, description: 'High-performance laptop' },
76
+ { id: 2, name: 'Phone', price: 699, description: 'Latest smartphone' },
77
+ { id: 3, name: 'Tablet', price: 399, description: 'Portable tablet device' },
78
+ ];
79
+
80
+ const ProductCard = ({ name, price, description, onAddToCart }) => (
81
+ <Card className="product-card">
82
+ <Text type="Heading" size="Medium">{name}</Text>
83
+ <Text type="Body" color="Secondary">{description}</Text>
84
+ <Text type="Heading" size="Small">${price}</Text>
85
+ <Button onClick={() => onAddToCart(id)}>Add to Cart</Button>
86
+ </Card>
87
+ );
88
+
89
+ const handleAddToCart = (productId) => {
90
+ console.log('Added to cart:', productId);
91
+ };
92
+
93
+ return (
94
+ <div className="product-grid">
95
+ <RepeaterList
96
+ data={products.map(product => ({
97
+ ...product,
98
+ onAddToCart: handleAddToCart
99
+ }))}
100
+ component={ProductCard}
101
+ />
102
+ </div>
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### Navigation Menu
108
+ ```tsx
109
+ function NavigationExample() {
110
+ const menuItems = [
111
+ { label: 'Home', href: '/', icon: 'Home' },
112
+ { label: 'Products', href: '/products', icon: 'ShoppingBag' },
113
+ { label: 'About', href: '/about', icon: 'Info' },
114
+ { label: 'Contact', href: '/contact', icon: 'Mail' },
115
+ ];
116
+
117
+ const MenuItem = ({ label, href, icon }) => (
118
+ <a href={href} className="menu-item">
119
+ <Icon icon={icon} size="Small" />
120
+ <span>{label}</span>
121
+ </a>
122
+ );
123
+
124
+ return (
125
+ <nav className="navigation">
126
+ <RepeaterList data={menuItems} component={MenuItem} />
127
+ </nav>
128
+ );
129
+ }
130
+ ```
131
+
132
+ ### Status List
133
+ ```tsx
134
+ function StatusListExample() {
135
+ const statuses = [
136
+ { id: 1, message: 'System is running normally', type: 'success', timestamp: '2024-01-15 10:30:00' },
137
+ { id: 2, message: 'Minor delay in processing', type: 'warning', timestamp: '2024-01-15 10:25:00' },
138
+ { id: 3, message: 'Maintenance completed', type: 'info', timestamp: '2024-01-15 10:20:00' },
139
+ ];
140
+
141
+ const StatusItem = ({ message, type, timestamp }) => (
142
+ <div className={`status-item status-${type}`}>
143
+ <div className="status-message">{message}</div>
144
+ <div className="status-timestamp">{timestamp}</div>
145
+ </div>
146
+ );
147
+
148
+ return (
149
+ <div className="status-feed">
150
+ <RepeaterList data={statuses} component={StatusItem} />
151
+ </div>
152
+ );
153
+ }
154
+ ```
155
+
156
+ ### Comment Thread
157
+ ```tsx
158
+ function CommentThreadExample() {
159
+ const comments = [
160
+ { id: 1, author: 'Alice', content: 'Great post!', likes: 5, timestamp: '2 hours ago' },
161
+ { id: 2, author: 'Bob', content: 'Thanks for sharing this.', likes: 2, timestamp: '1 hour ago' },
162
+ { id: 3, author: 'Charlie', content: 'Very informative.', likes: 8, timestamp: '30 minutes ago' },
163
+ ];
164
+
165
+ const CommentItem = ({ author, content, likes, timestamp }) => (
166
+ <div className="comment">
167
+ <div className="comment-header">
168
+ <strong>{author}</strong>
169
+ <span className="comment-time">{timestamp}</span>
170
+ </div>
171
+ <div className="comment-content">{content}</div>
172
+ <div className="comment-actions">
173
+ <button className="like-button">👍 {likes}</button>
174
+ <button className="reply-button">Reply</button>
175
+ </div>
176
+ </div>
177
+ );
178
+
179
+ return (
180
+ <div className="comment-thread">
181
+ <RepeaterList data={comments} component={CommentItem} />
182
+ </div>
183
+ );
184
+ }
185
+ ```
@@ -0,0 +1,402 @@
1
+ # Select
2
+
3
+ ## Description
4
+
5
+ A dropdown selection component that allows users to choose from a list of options. Supports single and multiple selections, custom icons, placeholder text, and integrates seamlessly with form validation. Built with accessibility and keyboard navigation in mind.
6
+
7
+ ## Aliases
8
+
9
+ - Select
10
+ - Dropdown
11
+ - ComboBox
12
+ - Picker
13
+ - OptionList
14
+
15
+ ## Props Breakdown
16
+
17
+ **Extends:** `HTMLAttributes<HTMLElement>` (excluding `style`, `children`, `onClick`) + `ControlledFormComponentProps<FieldValue>`
18
+
19
+ | Prop | Type | Default | Required | Description |
20
+ |------|------|---------|----------|-------------|
21
+ | `children` | `ReactElement<OptionProps> \| ReactElement<OptionProps>[]` | - | Yes | Options to render in the dropdown |
22
+ | `placeholder` | `string` | - | No | Placeholder text when no option is selected |
23
+ | `leadingIcon` | `ReactNode` | - | No | Icon displayed before the select input |
24
+ | `expandIcon` | `ReactNode` | - | No | Custom expand/collapse icon |
25
+ | `selectedView` | `React.FC<any>` | - | No | Component to render selected items |
26
+ | `popoverOffset` | `[number, number]` | - | No | Offset for the dropdown popover position |
27
+ | `menuProps` | `ContentProps` | - | No | Additional props for the dropdown menu |
28
+ | `multiple` | `boolean` | `false` | No | Whether multiple selection is allowed |
29
+ | `hasDefaultOption` | `boolean` | `false` | No | Whether to include a default empty option |
30
+ | `defaultOpen` | `boolean` | `false` | No | Whether the dropdown is open by default |
31
+ | `open` | `boolean` | `false` | No | Controls the open state in controlled mode |
32
+ | `state` | `'Default' \| 'Error'` | `'Default'` | No | Visual state of the select component |
33
+
34
+ Plus all `ControlledFormComponentProps` (initialValue, value, onValueChange, disabled, required, invalid, id).
35
+
36
+ ## Examples
37
+
38
+ ### Basic Usage
39
+ ```tsx
40
+ import { Select, Option } from '@delightui/components';
41
+
42
+ function BasicExample() {
43
+ return (
44
+ <Select placeholder="Choose an option">
45
+ <Option value="option1">Option 1</Option>
46
+ <Option value="option2">Option 2</Option>
47
+ <Option value="option3">Option 3</Option>
48
+ </Select>
49
+ );
50
+ }
51
+ ```
52
+
53
+ ### Controlled Select
54
+ ```tsx
55
+ function ControlledExample() {
56
+ const [selectedValue, setSelectedValue] = useState('');
57
+
58
+ return (
59
+ <Select
60
+ value={selectedValue}
61
+ onValueChange={setSelectedValue}
62
+ placeholder="Select a country"
63
+ >
64
+ <Option value="us">United States</Option>
65
+ <Option value="uk">United Kingdom</Option>
66
+ <Option value="ca">Canada</Option>
67
+ <Option value="au">Australia</Option>
68
+ </Select>
69
+ );
70
+ }
71
+ ```
72
+
73
+ ### Multiple Selection
74
+ ```tsx
75
+ function MultipleSelectionExample() {
76
+ const [selectedValues, setSelectedValues] = useState([]);
77
+
78
+ return (
79
+ <Select
80
+ multiple
81
+ value={selectedValues}
82
+ onValueChange={setSelectedValues}
83
+ placeholder="Select multiple options"
84
+ >
85
+ <Option value="red">Red</Option>
86
+ <Option value="green">Green</Option>
87
+ <Option value="blue">Blue</Option>
88
+ <Option value="yellow">Yellow</Option>
89
+ <Option value="purple">Purple</Option>
90
+ </Select>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ### Select with Icons
96
+ ```tsx
97
+ function IconSelectExample() {
98
+ return (
99
+ <div className="icon-selects">
100
+ <Select
101
+ leadingIcon={<Icon icon="Location" />}
102
+ placeholder="Select location"
103
+ >
104
+ <Option value="ny">New York</Option>
105
+ <Option value="la">Los Angeles</Option>
106
+ <Option value="sf">San Francisco</Option>
107
+ </Select>
108
+
109
+ <Select
110
+ leadingIcon={<Icon icon="Person" />}
111
+ expandIcon={<Icon icon="ExpandMore" />}
112
+ placeholder="Select user"
113
+ >
114
+ <Option value="john">John Doe</Option>
115
+ <Option value="jane">Jane Smith</Option>
116
+ <Option value="bob">Bob Johnson</Option>
117
+ </Select>
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ### Form Integration
124
+ ```tsx
125
+ function FormSelectExample() {
126
+ const handleSubmit = (values, setError) => {
127
+ if (!values.category) {
128
+ setError('category', 'Please select a category');
129
+ return;
130
+ }
131
+ console.log('Form submitted:', values);
132
+ };
133
+
134
+ return (
135
+ <Form onSubmit={handleSubmit}>
136
+ <FormField name="title" label="Title" required>
137
+ <Input placeholder="Enter title" />
138
+ </FormField>
139
+
140
+ <FormField name="category" label="Category" required>
141
+ <Select placeholder="Choose a category">
142
+ <Option value="tech">Technology</Option>
143
+ <Option value="business">Business</Option>
144
+ <Option value="design">Design</Option>
145
+ <Option value="marketing">Marketing</Option>
146
+ </Select>
147
+ </FormField>
148
+
149
+ <FormField name="tags" label="Tags">
150
+ <Select multiple placeholder="Select tags">
151
+ <Option value="urgent">Urgent</Option>
152
+ <Option value="important">Important</Option>
153
+ <Option value="draft">Draft</Option>
154
+ <Option value="review">Needs Review</Option>
155
+ </Select>
156
+ </FormField>
157
+
158
+ <Button actionType="submit">Submit</Button>
159
+ </Form>
160
+ );
161
+ }
162
+ ```
163
+
164
+ ### Select with Validation
165
+ ```tsx
166
+ function ValidationSelectExample() {
167
+ const [selected, setSelected] = useState('');
168
+ const [error, setError] = useState('');
169
+
170
+ const handleChange = (value) => {
171
+ setSelected(value);
172
+ if (value) {
173
+ setError('');
174
+ }
175
+ };
176
+
177
+ const validateSelection = () => {
178
+ if (!selected) {
179
+ setError('Please make a selection');
180
+ return false;
181
+ }
182
+ return true;
183
+ };
184
+
185
+ return (
186
+ <div className="validation-select">
187
+ <Select
188
+ value={selected}
189
+ onValueChange={handleChange}
190
+ placeholder="Select an option"
191
+ state={error ? 'Error' : 'Default'}
192
+ >
193
+ <Option value="option1">Option 1</Option>
194
+ <Option value="option2">Option 2</Option>
195
+ <Option value="option3">Option 3</Option>
196
+ </Select>
197
+
198
+ {error && (
199
+ <Text type="BodySmall" className="error-message">
200
+ {error}
201
+ </Text>
202
+ )}
203
+
204
+ <Button onClick={validateSelection}>
205
+ Validate Selection
206
+ </Button>
207
+ </div>
208
+ );
209
+ }
210
+ ```
211
+
212
+ ### Disabled Select
213
+ ```tsx
214
+ function DisabledSelectExample() {
215
+ return (
216
+ <div className="disabled-selects">
217
+ <Select disabled placeholder="Disabled select">
218
+ <Option value="option1">Option 1</Option>
219
+ <Option value="option2">Option 2</Option>
220
+ </Select>
221
+
222
+ <Select
223
+ disabled
224
+ value="option1"
225
+ placeholder="Disabled with value"
226
+ >
227
+ <Option value="option1">Selected Option</Option>
228
+ <Option value="option2">Option 2</Option>
229
+ </Select>
230
+ </div>
231
+ );
232
+ }
233
+ ```
234
+
235
+ ### Select with Groups
236
+ ```tsx
237
+ function GroupedSelectExample() {
238
+ return (
239
+ <Select placeholder="Select a framework">
240
+ {/* Frontend Options */}
241
+ <Option disabled>Frontend</Option>
242
+ <Option value="react">React</Option>
243
+ <Option value="vue">Vue.js</Option>
244
+ <Option value="angular">Angular</Option>
245
+
246
+ {/* Backend Options */}
247
+ <Option disabled>Backend</Option>
248
+ <Option value="node">Node.js</Option>
249
+ <Option value="python">Python</Option>
250
+ <Option value="ruby">Ruby</Option>
251
+
252
+ {/* Database Options */}
253
+ <Option disabled>Database</Option>
254
+ <Option value="mongodb">MongoDB</Option>
255
+ <Option value="postgresql">PostgreSQL</Option>
256
+ <Option value="mysql">MySQL</Option>
257
+ </Select>
258
+ );
259
+ }
260
+ ```
261
+
262
+ ### Searchable Select
263
+ ```tsx
264
+ function SearchableSelectExample() {
265
+ const [searchTerm, setSearchTerm] = useState('');
266
+ const options = [
267
+ { value: 'apple', label: 'Apple' },
268
+ { value: 'banana', label: 'Banana' },
269
+ { value: 'cherry', label: 'Cherry' },
270
+ { value: 'date', label: 'Date' },
271
+ { value: 'elderberry', label: 'Elderberry' }
272
+ ];
273
+
274
+ const filteredOptions = options.filter(option =>
275
+ option.label.toLowerCase().includes(searchTerm.toLowerCase())
276
+ );
277
+
278
+ const OptionComponent = ({ value, label }) => (
279
+ <Option value={value}>
280
+ {label}
281
+ </Option>
282
+ );
283
+
284
+ return (
285
+ <div className="searchable-select">
286
+ <Input
287
+ placeholder="Search options..."
288
+ value={searchTerm}
289
+ onValueChange={setSearchTerm}
290
+ leadingIcon={<Icon icon="Search" />}
291
+ />
292
+
293
+ <Select placeholder="Select a fruit">
294
+ <List
295
+ data={filteredOptions}
296
+ component={OptionComponent}
297
+ keyExtractor={(option) => option.value}
298
+ />
299
+ </Select>
300
+ </div>
301
+ );
302
+ }
303
+ ```
304
+
305
+ ### Custom Selected View
306
+ ```tsx
307
+ function CustomSelectedViewExample() {
308
+ const CustomSelectedView = ({ selectedItems }) => {
309
+ const ChipComponent = ({ value, label }) => (
310
+ <Chip size="Small">
311
+ {label}
312
+ </Chip>
313
+ );
314
+
315
+ return (
316
+ <div className="custom-selected">
317
+ {selectedItems.length > 0 ? (
318
+ <div className="selected-items">
319
+ <List
320
+ data={selectedItems.slice(0, 2)}
321
+ component={ChipComponent}
322
+ keyExtractor={(item) => item.value}
323
+ />
324
+ {selectedItems.length > 2 && (
325
+ <Text type="BodySmall">
326
+ +{selectedItems.length - 2} more
327
+ </Text>
328
+ )}
329
+ </div>
330
+ ) : (
331
+ <Text type="BodyMedium" className="placeholder">
332
+ Select items...
333
+ </Text>
334
+ )}
335
+ </div>
336
+ );
337
+ };
338
+
339
+ return (
340
+ <Select
341
+ multiple
342
+ selectedView={CustomSelectedView}
343
+ placeholder="Select multiple items"
344
+ >
345
+ <Option value="item1">Item 1</Option>
346
+ <Option value="item2">Item 2</Option>
347
+ <Option value="item3">Item 3</Option>
348
+ <Option value="item4">Item 4</Option>
349
+ <Option value="item5">Item 5</Option>
350
+ </Select>
351
+ );
352
+ }
353
+ ```
354
+
355
+ ### Dynamic Options
356
+ ```tsx
357
+ function DynamicOptionsExample() {
358
+ const [category, setCategory] = useState('');
359
+ const [subcategory, setSubcategory] = useState('');
360
+
361
+ const subcategories = {
362
+ tech: ['Frontend', 'Backend', 'Mobile', 'DevOps'],
363
+ business: ['Marketing', 'Sales', 'Operations', 'Strategy'],
364
+ design: ['UI/UX', 'Graphic', 'Product', 'Branding']
365
+ };
366
+
367
+ return (
368
+ <div className="dynamic-selects">
369
+ <Select
370
+ value={category}
371
+ onValueChange={(value) => {
372
+ setCategory(value);
373
+ setSubcategory(''); // Reset subcategory when category changes
374
+ }}
375
+ placeholder="Select category"
376
+ >
377
+ <Option value="tech">Technology</Option>
378
+ <Option value="business">Business</Option>
379
+ <Option value="design">Design</Option>
380
+ </Select>
381
+
382
+ {category && (
383
+ <Select
384
+ value={subcategory}
385
+ onValueChange={setSubcategory}
386
+ placeholder="Select subcategory"
387
+ >
388
+ <List
389
+ data={subcategories[category].map(sub => ({ label: sub, value: sub.toLowerCase() }))}
390
+ component={({ label, value }) => (
391
+ <Option value={value}>
392
+ {label}
393
+ </Option>
394
+ )}
395
+ keyExtractor={(item) => item.value}
396
+ />
397
+ </Select>
398
+ )}
399
+ </div>
400
+ );
401
+ }
402
+ ```
@@ -0,0 +1,82 @@
1
+ # SortableTrigger
2
+
3
+ ## Description
4
+
5
+ A trigger component that initiates drag-and-drop functionality for sortable list items. It provides a dedicated draggable handle with proper visual feedback and accessibility features, allowing users to easily identify and interact with sortable elements.
6
+
7
+ ## Aliases
8
+
9
+ - SortableTrigger
10
+ - DragHandle
11
+ - DragTrigger
12
+ - SortHandle
13
+
14
+ ## Props Breakdown
15
+
16
+ **Extends:** Standard HTML button attributes
17
+
18
+ | Prop | Type | Default | Required | Description |
19
+ |------|------|---------|----------|-------------|
20
+ | `children` | `ReactNode` | - | No | Content to display within the trigger (usually an icon) |
21
+ | `className` | `string` | - | No | Additional CSS class names |
22
+ | `disabled` | `boolean` | `false` | No | Whether the drag trigger is disabled |
23
+ | `onDragStart` | `(event: DragEvent) => void` | - | No | Callback fired when drag starts |
24
+
25
+ ## Examples
26
+
27
+ ### Basic Drag Handle
28
+ ```tsx
29
+ import { SortableTrigger, Icon } from '@delightui/components';
30
+
31
+ function BasicTriggerExample() {
32
+ return (
33
+ <div className="sortable-item">
34
+ <SortableTrigger>
35
+ <Icon icon="DragHandle" size="Small" />
36
+ </SortableTrigger>
37
+ <span>Draggable content</span>
38
+ </div>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ### Custom Styled Trigger
44
+ ```tsx
45
+ function CustomStyledTriggerExample() {
46
+ return (
47
+ <div className="task-item">
48
+ <SortableTrigger className="custom-drag-handle">
49
+ ⋮⋮
50
+ </SortableTrigger>
51
+
52
+ <div className="task-content">
53
+ <h4>Task Title</h4>
54
+ <p>Task description</p>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ### Conditional Trigger
62
+ ```tsx
63
+ function ConditionalTriggerExample() {
64
+ const [canReorder, setCanReorder] = useState(true);
65
+
66
+ return (
67
+ <div className="item-with-conditional-trigger">
68
+ <SortableTrigger disabled={!canReorder}>
69
+ <Icon icon="DragHandle" size="Small" />
70
+ </SortableTrigger>
71
+
72
+ <div className="item-content">
73
+ Content that can be reordered
74
+ </div>
75
+
76
+ <button onClick={() => setCanReorder(!canReorder)}>
77
+ {canReorder ? 'Disable' : 'Enable'} Reordering
78
+ </button>
79
+ </div>
80
+ );
81
+ }
82
+ ```