{"_id":"@bitcoindevke/multiselect","_rev":"2-7f40748707855c3f1d60b38998969a21","name":"@bitcoindevke/multiselect","dist-tags":{"latest":"0.0.7"},"versions":{"0.0.6":{"name":"@bitcoindevke/multiselect","version":"0.0.6","_id":"@bitcoindevke/multiselect@0.0.6","maintainers":[{"name":"bitcoindevke","email":"kiplagatbrian18@gmail.com"}],"homepage":"https://github.com/briankiplagat/multiselect#readme","dist":{"shasum":"0f5a3d7c70d3ec3ee73b6c35870acecd78de5cb1","tarball":"https://registry.npmjs.org/@bitcoindevke/multiselect/-/multiselect-0.0.6.tgz","fileCount":19,"integrity":"sha512-VluhXifW2Cvbu1M80uLefyWdlqm/nulCDJwthsu0FwJ2JxNm+txfyAV3i/OJivY1m+Lxjn5okO3VFvomV0+yGg==","signatures":[{"sig":"MEUCIQD/Xk33j1OSlCQQ4iAq4a0YuuJqb97yc4lUvS9ezINWXQIgZiWUKEKyE8Obg9MH8W2kbqJdLwltYuKVD5PaFwd/ryM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58089},"type":"module","_from":"file:bitcoindevke-multiselect-0.0.6.tgz","private":false,"scripts":{"dev":"vite","lint":"eslint ./src && prettier --check ./src","build":"tsc && vite build","check":"tsc --noEmit","update":"pnpm update -i -L -r","preview":"vite preview","release":"changeset publish","lint:fix":"eslint ./src --fix"},"_npmUser":{"name":"bitcoindevke","email":"kiplagatbrian18@gmail.com"},"_resolved":"/tmp/615b6a08e14d3b6116f8bf4c0951c22c/bitcoindevke-multiselect-0.0.6.tgz","_integrity":"sha512-VluhXifW2Cvbu1M80uLefyWdlqm/nulCDJwthsu0FwJ2JxNm+txfyAV3i/OJivY1m+Lxjn5okO3VFvomV0+yGg==","_npmVersion":"10.9.2","description":"multiselect for webflow.","directories":{},"_nodeVersion":"22.15.0","dependencies":{"@finsweet/ts-utils":"^0.40.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","eslint":"^9.19.0","prettier":"^3.4.2","@eslint/js":"^9.19.0","typescript":"~5.8.3","@changesets/cli":"^2.27.12","typescript-eslint":"^8.23.0","@finsweet/tsconfig":"^1.4.2","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.3","@finsweet/eslint-config":"^3.0.3","@changesets/changelog-git":"^0.2.0","eslint-plugin-simple-import-sort":"^12.1.1"},"_npmOperationalInternal":{"tmp":"tmp/multiselect_0.0.6_1746642602404_0.791920855364721","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@bitcoindevke/multiselect","private":false,"description":"multiselect for webflow.","homepage":"https://github.com/briankiplagat/multiselect#readme","version":"0.0.7","type":"module","devDependencies":{"@changesets/changelog-git":"^0.2.0","@changesets/cli":"^2.27.12","@eslint/js":"^9.19.0","@finsweet/eslint-config":"^3.0.3","@finsweet/tsconfig":"^1.4.2","cross-env":"^7.0.3","esbuild":"^0.24.2","eslint":"^9.19.0","eslint-config-prettier":"^10.0.1","eslint-plugin-prettier":"^5.2.3","eslint-plugin-simple-import-sort":"^12.1.1","prettier":"^3.4.2","typescript":"~5.8.3","typescript-eslint":"^8.23.0","vite":"^6.3.5"},"dependencies":{"@finsweet/ts-utils":"^0.40.0"},"publishConfig":{"access":"public"},"scripts":{"dev":"cross-env NODE_ENV=development node ./bin/build.js","build":"cross-env NODE_ENV=production node ./bin/build.js","preview":"vite preview","lint":"eslint ./src && prettier --check ./src","lint:fix":"eslint ./src --fix","check":"tsc --noEmit","release":"changeset publish","update":"pnpm update -i -L -r"},"_id":"@bitcoindevke/multiselect@0.0.7","_integrity":"sha512-WO2ZNQkYelNPqRCmdc8B2/X/pd/bQN9kB4GCbkKJAXRwTPrXFb767OEoa/e/Usf82WyrXDl+s90xHEtwdyD8JA==","_resolved":"/tmp/f3d6107b77579708d3d9ea29b5fd7216/bitcoindevke-multiselect-0.0.7.tgz","_from":"file:bitcoindevke-multiselect-0.0.7.tgz","_nodeVersion":"22.15.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-WO2ZNQkYelNPqRCmdc8B2/X/pd/bQN9kB4GCbkKJAXRwTPrXFb767OEoa/e/Usf82WyrXDl+s90xHEtwdyD8JA==","shasum":"dd16b5b050372a4c8665858fa51d3580ce4796c0","tarball":"https://registry.npmjs.org/@bitcoindevke/multiselect/-/multiselect-0.0.7.tgz","fileCount":22,"unpackedSize":60675,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDidKjeHjv4fOqgivNxZrCtyJtoRGz8NTtjjEPIzUsGOwIgHlip21FV+4xGaW+iTMaw3fdDdZIRNOt0v1MfLdBfm7U="}]},"_npmUser":{"name":"bitcoindevke","email":"kiplagatbrian18@gmail.com"},"directories":{},"maintainers":[{"name":"bitcoindevke","email":"kiplagatbrian18@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/multiselect_0.0.7_1746644243599_0.7266279760074135"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-07T18:30:02.312Z","modified":"2025-05-07T18:57:24.015Z","0.0.6":"2025-05-07T18:30:02.611Z","0.0.7":"2025-05-07T18:57:23.852Z"},"homepage":"https://github.com/briankiplagat/multiselect#readme","description":"multiselect for webflow.","maintainers":[{"name":"bitcoindevke","email":"kiplagatbrian18@gmail.com"}],"readme":"# Bobby Select - Flexible Multiselect Component\n\nA highly customizable, accessible, and feature-rich multiselect component built with TypeScript. Designed to work both in forms and as standalone UI elements.\n\n## Features\n\n- **Flexible Usage**: Works seamlessly inside forms or as a standalone component\n- **Customizable Appearance**: Control appearance through various configuration options\n- **Keyboard Navigation**: Full keyboard support for accessibility\n- **Form Integration**: Proper form association with validation\n- **Custom Styling**: Isolated styling through attribute selectors (no class conflicts)\n- **Accessible**: Built with ARIA attributes for screen readers\n- **Multiple Display Modes**: Different tag display options including \"below input\" layout\n- **Lightweight**: No dependencies, just vanilla TypeScript\n\n## Installation\n\n1. Copy the source files into your project:\n\n   - `src/constants.ts`\n   - `src/multiSelect.ts`\n   - `src/styles.ts`\n\n2. Import and use the component in your application:\n   ```typescript\n   import { MultiSelect } from \"./path/to/multiSelect.ts\";\n   ```\n\n## Usage\n\n### Basic Example\n\n```typescript\nconst container = document.getElementById(\"my-select\");\nif (container) {\n  new MultiSelect({\n    container,\n    options: [\n      { value: \"option1\", label: \"Option 1\" },\n      { value: \"option2\", label: \"Option 2\" },\n      { value: \"option3\", label: \"Option 3\" },\n    ],\n    placeholder: \"Select options...\",\n    onChange: (selected) => {\n      console.log(\"Selected values:\", selected);\n    },\n  });\n}\n```\n\n### Form Integration\n\n```typescript\nconst formSelect = document.getElementById(\"form-select\");\nif (formSelect) {\n  new MultiSelect({\n    container: formSelect,\n    options: options,\n    name: \"my-field\",\n    placeholder: \"Select items...\",\n    required: true,\n    formAssociated: true,\n    validationMessage: \"Please select at least one option\",\n  });\n}\n```\n\n### Skills Input Example\n\n```typescript\nconst skillsInput = document.getElementById(\"skills-input\");\nif (skillsInput) {\n  new MultiSelect({\n    container: skillsInput,\n    options: skillsOptions,\n    placeholder: \"Add skills...\",\n    allowCreation: true,\n    searchable: true,\n    clearable: true,\n    hideDropdownOnSelect: true,\n    onCreateOption: (value) => {\n      return { value, label: value };\n    },\n  });\n}\n```\n\n## Configuration Options\n\nThe component accepts the following configuration options:\n\n### Required\n\n- `container`: HTMLElement - The container where the multiselect will be rendered\n- `options`: Array of `Option` objects with `value` and `label` properties\n\n### Appearance\n\n- `name?`: string - Name attribute for form association\n- `placeholder?`: string - Placeholder text for the input\n- `className?`: string - Additional class names for the container\n- `maxWidth?`: string - Maximum width of the component\n- `maxHeight?`: string - Maximum height of the dropdown\n\n### Behavior\n\n- `selected?`: string[] - Pre-selected values\n- `disabled?`: boolean - Whether the component is disabled\n- `readOnly?`: boolean - Whether the component is read-only\n- `required?`: boolean - Whether selection is required (for forms)\n- `clearable?`: boolean - Show clear button to remove all selections\n- `searchable?`: boolean - Enable filtering options by typing\n- `allowCreation?`: boolean - Allow creating new options\n- `hideDropdownOnSelect?`: boolean - Close dropdown after selecting an option\n- `maxItems?`: number - Maximum number of items that can be selected\n- `maxTags?`: number - Maximum number of tags to display before showing a count\n\n### Validation\n\n- `formAssociated?`: boolean - Whether to associate with a form via hidden input\n- `validationMessage?`: string - Custom validation message\n- `customValidation?`: Function - Custom validation function\n\n### Callbacks\n\n- `onChange?`: Function - Called when selection changes\n- `onOpen?`: Function - Called when dropdown opens\n- `onClose?`: Function - Called when dropdown closes\n- `onCreateOption?`: Function - Called when a new option is created\n- `onFocus?`: Function - Called when the component receives focus\n- `onBlur?`: Function - Called when the component loses focus\n\n## API Methods\n\nOnce instantiated, the component instance provides the following methods:\n\n```typescript\nconst multiSelect = new MultiSelect({\n  /* config */\n});\n\n// Get selected values\nconst selected = multiSelect.getSelected();\n\n// Set selected values\nmultiSelect.setSelected([\"value1\", \"value2\"]);\n\n// Add a new option\nmultiSelect.addOption({ value: \"newOption\", label: \"New Option\" });\n\n// Clear all selections\nmultiSelect.clear();\n\n// Open dropdown\nmultiSelect.open();\n\n// Close dropdown\nmultiSelect.close();\n\n// Enable component\nmultiSelect.enable();\n\n// Disable component\nmultiSelect.disable();\n\n// Set read-only state\nmultiSelect.setReadOnly(true);\n\n// Validate current selection\nconst validation = multiSelect.validate();\n\n// Destroy component and remove event listeners\nmultiSelect.destroy();\n```\n\n## Customizing Attribute Names\n\nThe component uses custom attributes instead of classes to avoid styling conflicts. You can easily change the attribute prefix in `constants.ts`:\n\n```typescript\n// Change this value to customize the attribute namespace\nexport const COMPONENT_PREFIX = \"bobby-select\";\n```\n\nAll attributes and CSS will automatically update to use your custom prefix.\n\n## Browser Support\n\n- All modern browsers (Chrome, Firefox, Safari, Edge)\n- IE11 with appropriate polyfills for template literals and other ES6+ features\n\n## License\n\nMIT\n\n## Contributing\n\nFeel free to submit issues or pull requests to improve the component.\n","readmeFilename":"README.md"}