@stackloop/ui 4.0.3 → 4.0.4
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.
- package/README.md +103 -1
- package/dist/MultiSelect.d.ts +23 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1443 -1118
- package/dist/index.js.map +1 -1
- package/dist/stackloop-ui.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -163,7 +163,7 @@ import { Button, Modal } from '@stackloop/ui'
|
|
|
163
163
|
|
|
164
164
|
Components with the `animate` prop:
|
|
165
165
|
|
|
166
|
-
- `AudioRecorder`, `Badge`, `BottomSheet`, `Button`, `Card`, `CameraCapture`, `Checkbox`, `CountrySelect`, `DatePicker`, `Drawer`, `Dropdown`, `DualSlider`, `FileUploader`, `FloatingActionButton`, `Input`, `Modal`, `Pagination`, `PhoneInput`, `RadioPills`, `Select`, `Slider`, `Spinner`, `StepProgress`, `Table`, `Textarea`, `ThumbnailGrid`, `Toggle`, `ToastProvider`
|
|
166
|
+
- `AudioRecorder`, `Badge`, `BottomSheet`, `Button`, `Card`, `CameraCapture`, `Checkbox`, `CountrySelect`, `DatePicker`, `Drawer`, `Dropdown`, `DualSlider`, `FileUploader`, `FloatingActionButton`, `Input`, `Modal`, `MultiSelect`, `Pagination`, `PhoneInput`, `RadioPills`, `Select`, `Slider`, `Spinner`, `StepProgress`, `Table`, `Textarea`, `ThumbnailGrid`, `Toggle`, `ToastProvider`
|
|
167
167
|
|
|
168
168
|
## Ripple Behavior
|
|
169
169
|
|
|
@@ -706,6 +706,108 @@ Call `setupRippleEffects()` only once per app (for example in `main.tsx`) to avo
|
|
|
706
706
|
/>
|
|
707
707
|
```
|
|
708
708
|
|
|
709
|
+
**MultiSelect**:
|
|
710
|
+
- **Description:** Multi-select component that allows selecting multiple items with chips display. Each selected item appears as a removable chip with an X button. Perfect for selecting multiple options like staff members, tags, skills, etc.
|
|
711
|
+
- **Props:**
|
|
712
|
+
- **`options`**: `{ value: string; label: string; icon?: ReactNode; disabled?: boolean }[]` — required. Array of selectable options with optional icons and disabled state.
|
|
713
|
+
- **`value`**: `string[]` — optional. Array of currently selected values (default: `[]`).
|
|
714
|
+
- **`onChange`**: `(values: string[]) => void` — required. Callback fired when selections change, receives array of selected values.
|
|
715
|
+
- **`placeholder`**: `string` — default: `'Select options...'`. Shown when no items are selected.
|
|
716
|
+
- **`label`**: `string` — optional. Label displayed above the multi-select.
|
|
717
|
+
- **`error`**: `string` — optional. Error message displayed below with error styling.
|
|
718
|
+
- **`hint`**: `string` — optional. Helper text displayed below when no error is present.
|
|
719
|
+
- **`searchable`**: `boolean` — default: `false`. Enables search input to filter options.
|
|
720
|
+
- **`clearable`**: `boolean` — default: `true`. Shows "Clear all" option in dropdown when items are selected.
|
|
721
|
+
- **`maxItems`**: `number` — optional. Maximum number of items that can be selected.
|
|
722
|
+
- **`chipVariant`**: `'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'` — default: `'primary'`. Styles for the selected item chips.
|
|
723
|
+
- **`required`**: `boolean` — optional. Displays asterisk (*) next to label and sets aria-required.
|
|
724
|
+
- **`disabled`**: `boolean` — optional. Disables the multi-select.
|
|
725
|
+
- **`className`**: `string` — optional. Additional CSS classes for the wrapper.
|
|
726
|
+
- **Features:**
|
|
727
|
+
- **Chips Display:** Selected items show as removable chips with X buttons inline in the button
|
|
728
|
+
- **Multi-Select:** Choose multiple items from a list with checkboxes in the dropdown
|
|
729
|
+
- **Form Integration:** Works seamlessly with form libraries (React Hook Form, Formik, etc.)
|
|
730
|
+
- **Validation Support:** Built-in error and hint display with animated transitions
|
|
731
|
+
- **Accessibility:** Full ARIA attributes, keyboard navigation, and screen reader support
|
|
732
|
+
- **Search:** Optional searchable mode with real-time filtering across all options
|
|
733
|
+
- **Icons:** Support for icons in options for better visual recognition
|
|
734
|
+
- **Disabled Options:** Individual options can be disabled
|
|
735
|
+
- **Max Items:** Optional limit on the number of items that can be selected
|
|
736
|
+
- **Clear All:** "Clear all" button in dropdown to remove all selected items at once
|
|
737
|
+
- **Remove Individual:** Click X on any chip to remove just that item
|
|
738
|
+
- **Touch-Friendly:** Optimized for mobile with proper touch targets
|
|
739
|
+
- **Usage:**
|
|
740
|
+
|
|
741
|
+
```jsx
|
|
742
|
+
import { MultiSelect } from '@stackloop/ui'
|
|
743
|
+
import { Users, Award, Code } from 'lucide-react'
|
|
744
|
+
|
|
745
|
+
// Basic multi-select for team members
|
|
746
|
+
const [selectedStaff, setSelectedStaff] = useState<string[]>([])
|
|
747
|
+
|
|
748
|
+
<MultiSelect
|
|
749
|
+
label="Select Staff Members"
|
|
750
|
+
options={[
|
|
751
|
+
{ value: 'john', label: 'John Doe' },
|
|
752
|
+
{ value: 'jane', label: 'Jane Smith' },
|
|
753
|
+
{ value: 'bob', label: 'Bob Johnson' }
|
|
754
|
+
]}
|
|
755
|
+
value={selectedStaff}
|
|
756
|
+
onChange={setSelectedStaff}
|
|
757
|
+
placeholder="Choose staff members..."
|
|
758
|
+
required
|
|
759
|
+
/>
|
|
760
|
+
|
|
761
|
+
// With icons and search
|
|
762
|
+
<MultiSelect
|
|
763
|
+
label="Skills"
|
|
764
|
+
options={[
|
|
765
|
+
{ value: 'react', label: 'React', icon: <Code /> },
|
|
766
|
+
{ value: 'vue', label: 'Vue.js', icon: <Code /> },
|
|
767
|
+
{ value: 'angular', label: 'Angular', icon: <Code /> },
|
|
768
|
+
{ value: 'node', label: 'Node.js', icon: <Code /> }
|
|
769
|
+
]}
|
|
770
|
+
value={skills}
|
|
771
|
+
onChange={setSkills}
|
|
772
|
+
searchable
|
|
773
|
+
placeholder="Select your skills"
|
|
774
|
+
/>
|
|
775
|
+
|
|
776
|
+
// With max items limit and chip styling
|
|
777
|
+
<MultiSelect
|
|
778
|
+
label="Team Members (Max 5)"
|
|
779
|
+
options={teamMembers}
|
|
780
|
+
value={selectedTeam}
|
|
781
|
+
onChange={setSelectedTeam}
|
|
782
|
+
maxItems={5}
|
|
783
|
+
chipVariant="primary"
|
|
784
|
+
error={errors.team}
|
|
785
|
+
hint="Select up to 5 team members for this project"
|
|
786
|
+
/>
|
|
787
|
+
|
|
788
|
+
// With React Hook Form
|
|
789
|
+
import { useForm, Controller } from 'react-hook-form'
|
|
790
|
+
|
|
791
|
+
const { control, formState: { errors } } = useForm()
|
|
792
|
+
|
|
793
|
+
<Controller
|
|
794
|
+
name="assignees"
|
|
795
|
+
control={control}
|
|
796
|
+
rules={{ validate: (v) => v?.length > 0 || 'Please select at least one assignee' }}
|
|
797
|
+
render={({ field }) => (
|
|
798
|
+
<MultiSelect
|
|
799
|
+
label="Assign to"
|
|
800
|
+
options={users}
|
|
801
|
+
value={field.value || []}
|
|
802
|
+
onChange={field.onChange}
|
|
803
|
+
error={errors.assignees?.message}
|
|
804
|
+
searchable
|
|
805
|
+
required
|
|
806
|
+
/>
|
|
807
|
+
)}
|
|
808
|
+
/>
|
|
809
|
+
```
|
|
810
|
+
|
|
709
811
|
**BottomSheet**:
|
|
710
812
|
- **Description:** Mobile bottom sheet with header and optional close button.
|
|
711
813
|
- **Props:**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface MultiSelectOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface MultiSelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange' | 'size'> {
|
|
9
|
+
options: MultiSelectOption[];
|
|
10
|
+
value?: string[];
|
|
11
|
+
onChange: (values: string[]) => void;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
hint?: string;
|
|
16
|
+
searchable?: boolean;
|
|
17
|
+
clearable?: boolean;
|
|
18
|
+
maxItems?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
animate?: boolean;
|
|
21
|
+
chipVariant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
|
22
|
+
}
|
|
23
|
+
export declare const MultiSelect: React.ForwardRefExoticComponent<MultiSelectProps & React.RefAttributes<HTMLDivElement>>;
|