@rentnerkev/select 0.0.0
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/LICENSE +22 -0
- package/README.md +156 -0
- package/dist/Internal/Tooltip.d.ts +16 -0
- package/dist/Internal/Tooltip.d.ts.map +1 -0
- package/dist/Internal/Tooltip.js +13 -0
- package/dist/Internal/Tooltip.js.map +1 -0
- package/dist/Select.d.ts +3 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/Select.js +160 -0
- package/dist/Select.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RentnerKev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# @rentnerkev/select
|
|
2
|
+
|
|
3
|
+
Eine flexible React-Select-Komponente mit Einzel- und Mehrfachauswahl, Formularvalidierung und anpassbarem Tailwind-Design.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Installiere das Paket mit npm oder Bun:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @rentnerkev/select
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Schnellstart
|
|
14
|
+
|
|
15
|
+
### 1. Komponente verwenden
|
|
16
|
+
|
|
17
|
+
Importiere `CustomSelect` und nutze es in deinen Komponenten.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { CustomSelect } from '@rentnerkev/select'
|
|
21
|
+
import { useState } from 'react'
|
|
22
|
+
import { User } from 'lucide-react'
|
|
23
|
+
|
|
24
|
+
function MyComponent() {
|
|
25
|
+
const [selectedValue, setSelectedValue] = useState('')
|
|
26
|
+
|
|
27
|
+
const options = [
|
|
28
|
+
{
|
|
29
|
+
value: 'max-mustermann',
|
|
30
|
+
label: 'Max - Mustermann',
|
|
31
|
+
subOption: 'Musterstraße 12, 10115 Berlin',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: 'erika-musterfrau',
|
|
35
|
+
label: 'Erika - Musterfrau',
|
|
36
|
+
subOption: 'Hafenweg 4, 20457 Hamburg',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: 'tim-schneider',
|
|
40
|
+
label: 'Tim - Schneider',
|
|
41
|
+
subOption: 'Königsallee 22, 40212 Düsseldorf',
|
|
42
|
+
},
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className="w-64">
|
|
47
|
+
<CustomSelect
|
|
48
|
+
id="fruit"
|
|
49
|
+
name="fruit"
|
|
50
|
+
value={selectedValue}
|
|
51
|
+
onValueChange={setSelectedValue}
|
|
52
|
+
options={options}
|
|
53
|
+
placeholder="Kontakt auswählen"
|
|
54
|
+
required
|
|
55
|
+
className="w-30 h-10"
|
|
56
|
+
fallbackOption="Du hast noch keine Früchte angelegt!"
|
|
57
|
+
icon={<User className="h-4 w-4" />}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. In Formularen mit required
|
|
65
|
+
|
|
66
|
+
`required` ist standardmäßig deaktiviert. Wenn du es setzt und beim Submit noch kein Wert ausgewählt wurde, wird der Select rot, das linke Icon wird durch ein Ausrufezeichen ersetzt und der Fehlertext wird im Tooltip angezeigt. Das ist das praktisch, wenn der Placeholder wie "Bereich auswählen" nur ein Hinweis und keine echte Auswahl sein soll.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { CustomSelect } from '@rentnerkev/select'
|
|
70
|
+
import { BriefcaseBusiness } from 'lucide-react'
|
|
71
|
+
import { useState } from 'react'
|
|
72
|
+
|
|
73
|
+
function RequiredSelectForm() {
|
|
74
|
+
const [department, setDepartment] = useState('')
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<form
|
|
78
|
+
onSubmit={(event) => {
|
|
79
|
+
event.preventDefault()
|
|
80
|
+
event.currentTarget.reportValidity()
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
<CustomSelect
|
|
84
|
+
id="department"
|
|
85
|
+
name="department"
|
|
86
|
+
value={department}
|
|
87
|
+
onValueChange={setDepartment}
|
|
88
|
+
options={[
|
|
89
|
+
{ value: 'beratung', label: 'Beratung' },
|
|
90
|
+
{ value: 'support', label: 'Support' },
|
|
91
|
+
{ value: 'vertrieb', label: 'Vertrieb' },
|
|
92
|
+
]}
|
|
93
|
+
placeholder="Bereich auswählen"
|
|
94
|
+
required
|
|
95
|
+
icon={<BriefcaseBusiness className="h-4 w-4" />}
|
|
96
|
+
/>
|
|
97
|
+
|
|
98
|
+
<button type="submit">Absenden</button>
|
|
99
|
+
</form>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Typdefinitionen
|
|
105
|
+
|
|
106
|
+
### `CustomSelect`-Props
|
|
107
|
+
|
|
108
|
+
Die Komponente nimmt folgende Parameter entgegen:
|
|
109
|
+
|
|
110
|
+
| Parameter | Typ | Beschreibung |
|
|
111
|
+
| ---------------- | ------------------------- | ------------------------------------------------------------------------ |
|
|
112
|
+
| `id` | `string` | (Optional) ID für den sichtbaren Trigger, nützlich für Labels. |
|
|
113
|
+
| `name` | `string` | (Optional) Name für Formular-Submit und native Validierung. |
|
|
114
|
+
| `value` | `string` | Der aktuell ausgewählte Wert. |
|
|
115
|
+
| `onValueChange` | `(value: string) => void` | Callback-Funktion, die bei Änderung aufgerufen wird. |
|
|
116
|
+
| `options` | `Option[]` | Ein Array von Optionen (siehe unten). |
|
|
117
|
+
| `required` | `boolean` | (Optional) Aktiviert Pflichtfeld-Validierung. Default ist `false`. |
|
|
118
|
+
| `className` | `string` | (Optional) Überträgt classes an die Select-Komponente. |
|
|
119
|
+
| `placeholder` | `string` | (Optional) Text, der angezeigt wird, wenn nichts ausgewählt ist. |
|
|
120
|
+
| `icon` | `React.ReactNode` | (Optional) Ein Icon, das links im Select angezeigt wird. |
|
|
121
|
+
| `fallbackOption` | `string` | (Optional) Text, der angezeigt wird, wenn keine Optionen vorhanden sind. |
|
|
122
|
+
| `multiple` | `boolean` | (Optional) Aktiviert die Mehrfachauswahl. Default ist false. |
|
|
123
|
+
| `minSelection` | `number` | (Optional) Bestimmt die Mindestanzahl an auszuwählenden Optionen. |
|
|
124
|
+
| `maxSelection` | `number` | (Optional) Bestimmt die maximale Anzahl an auszuwählenden Optionen. |
|
|
125
|
+
|
|
126
|
+
### Option
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
interface Option {
|
|
130
|
+
value: string
|
|
131
|
+
label: string
|
|
132
|
+
subOption?: string
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`subOption` ist optional und wird kleiner unter dem Label angezeigt. Das funktioniert sowohl in der geöffneten Auswahl als auch im geschlossenen Select. Das ist das nützlich für Zusatzinfos wie Adressen, Kundennummern oder Rollen.
|
|
137
|
+
|
|
138
|
+
## CSS-Integration
|
|
139
|
+
|
|
140
|
+
Füge die folgenden Zeilen in deine Haupt-CSS-Datei ein, um die Stile zu konfigurieren.
|
|
141
|
+
|
|
142
|
+
```css
|
|
143
|
+
@import 'tailwindcss';
|
|
144
|
+
@source "../node_modules/@rentnerkev/select";
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Entwicklung
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
bun install
|
|
151
|
+
bun run verify
|
|
152
|
+
bun run playground:dev
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`bun run verify` prüft Typen, Oxlint, Oxfmt, den Paket-Build und den
|
|
156
|
+
veröffentlichten Paketinhalt per Dry Run.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
interface TooltipCustomDesign {
|
|
3
|
+
baseClasses?: string;
|
|
4
|
+
animationClasses?: string;
|
|
5
|
+
contentClasses?: string;
|
|
6
|
+
arrowClasses?: string;
|
|
7
|
+
}
|
|
8
|
+
interface TooltipProps {
|
|
9
|
+
children: ReactElement;
|
|
10
|
+
content: ReactNode;
|
|
11
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
12
|
+
customDesign?: TooltipCustomDesign;
|
|
13
|
+
}
|
|
14
|
+
export declare function CustomTooltip({ children, content, side, customDesign, }: TooltipProps): import("react").JSX.Element;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=Tooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/Internal/Tooltip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEpD,UAAU,mBAAmB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAUD,UAAU,YAAY;IAClB,QAAQ,EAAE,YAAY,CAAA;IACtB,OAAO,EAAE,SAAS,CAAA;IAClB,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC1C,YAAY,CAAC,EAAE,mBAAmB,CAAA;CACrC;AAED,wBAAgB,aAAa,CAAC,EAC1B,QAAQ,EACR,OAAO,EACP,IAAY,EACZ,YAAY,GACf,EAAE,YAAY,+BA0Bd"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
3
|
+
const defaultTooltipDesign = {
|
|
4
|
+
baseClasses: 'data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 rounded-lg border border-border-dark bg-surface-dark px-3 py-1.5 text-xs font-medium text-gray-200 shadow-xl data-[side=bottom]:slide-in-from-top-2',
|
|
5
|
+
animationClasses: 'animate-in fade-in zoom-in-95',
|
|
6
|
+
contentClasses: '',
|
|
7
|
+
arrowClasses: 'fill-surface-dark stroke-border-dark',
|
|
8
|
+
};
|
|
9
|
+
export function CustomTooltip({ children, content, side = 'top', customDesign, }) {
|
|
10
|
+
const design = { ...defaultTooltipDesign, ...customDesign };
|
|
11
|
+
return (_jsx(TooltipPrimitive.Provider, { children: _jsxs(TooltipPrimitive.Root, { delayDuration: 200, children: [_jsx(TooltipPrimitive.Trigger, { asChild: true, children: children }), _jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { sideOffset: 8, side: side, className: `z-[9999] ${design.baseClasses} ${design.animationClasses} ${design.contentClasses}`, children: [content, _jsx(TooltipPrimitive.Arrow, { width: 12, height: 6, className: design.arrowClasses })] }) })] }) }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=Tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../src/Internal/Tooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAU3D,MAAM,oBAAoB,GAAkC;IACxD,WAAW,EACP,0QAA0Q;IAC9Q,gBAAgB,EAAE,+BAA+B;IACjD,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,sCAAsC;CACvD,CAAA;AASD,MAAM,UAAU,aAAa,CAAC,EAC1B,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,KAAK,EACZ,YAAY,GACD;IACX,MAAM,MAAM,GAAG,EAAE,GAAG,oBAAoB,EAAE,GAAG,YAAY,EAAE,CAAA;IAE3D,OAAO,CACH,KAAC,gBAAgB,CAAC,QAAQ,cACtB,MAAC,gBAAgB,CAAC,IAAI,IAAC,aAAa,EAAE,GAAG,aACrC,KAAC,gBAAgB,CAAC,OAAO,IAAC,OAAO,kBAC5B,QAAQ,GACc,EAC3B,KAAC,gBAAgB,CAAC,MAAM,cACpB,MAAC,gBAAgB,CAAC,OAAO,IACrB,UAAU,EAAE,CAAC,EACb,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,YAAY,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,cAAc,EAAE,aAE9F,OAAO,EACR,KAAC,gBAAgB,CAAC,KAAK,IACnB,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,CAAC,EACT,SAAS,EAAE,MAAM,CAAC,YAAY,GAChC,IACqB,GACL,IACN,GACA,CAC/B,CAAA;AACL,CAAC"}
|
package/dist/Select.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CustomSelectProps } from './types.js';
|
|
2
|
+
export declare function CustomSelect({ id, name, value, onValueChange, options, required, icon, placeholder, className, fallbackOption, multiple, minSelection, maxSelection, }: CustomSelectProps): import("react").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../src/Select.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,wBAAgB,YAAY,CAAC,EACzB,EAAE,EACF,IAAI,EACJ,KAAK,EACL,aAAa,EACb,OAAO,EACP,QAAgB,EAChB,IAAI,EACJ,WAAW,EACX,SAAS,EACT,cAAc,EACd,QAAgB,EAChB,YAAY,EACZ,YAAY,GACf,EAAE,iBAAiB,+BAoUnB"}
|
package/dist/Select.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
3
|
+
import { CustomTooltip } from './Internal/Tooltip.js';
|
|
4
|
+
import { AlertCircle, Check, ChevronDown } from 'lucide-react';
|
|
5
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
export function CustomSelect({ id, name, value, onValueChange, options, required = false, icon, placeholder, className, fallbackOption, multiple = false, minSelection, maxSelection, }) {
|
|
7
|
+
const [open, setOpen] = useState(false);
|
|
8
|
+
const [searchValue, setSearchValue] = useState('');
|
|
9
|
+
const [isTouched, setIsTouched] = useState(false);
|
|
10
|
+
const searchInputRef = useRef(null);
|
|
11
|
+
const validationInputRef = useRef(null);
|
|
12
|
+
const shouldKeepOpen = useRef(false);
|
|
13
|
+
const selectedValues = useMemo(() => {
|
|
14
|
+
if (!value)
|
|
15
|
+
return [];
|
|
16
|
+
return multiple ? value.split(',') : [value];
|
|
17
|
+
}, [value, multiple]);
|
|
18
|
+
const error = useMemo(() => {
|
|
19
|
+
if (required && selectedValues.length === 0) {
|
|
20
|
+
return 'Dieses Feld ist erforderlich';
|
|
21
|
+
}
|
|
22
|
+
if (multiple &&
|
|
23
|
+
minSelection !== undefined &&
|
|
24
|
+
selectedValues.length < minSelection) {
|
|
25
|
+
return `Mindestens ${minSelection} Optionen auswählen`;
|
|
26
|
+
}
|
|
27
|
+
if (multiple &&
|
|
28
|
+
maxSelection !== undefined &&
|
|
29
|
+
selectedValues.length > maxSelection) {
|
|
30
|
+
return `Maximal ${maxSelection} Optionen auswählen`;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}, [required, multiple, minSelection, maxSelection, selectedValues]);
|
|
34
|
+
const hasError = isTouched && error !== null;
|
|
35
|
+
const hasLeftIcon = Boolean(icon || hasError);
|
|
36
|
+
const filteredOptions = useMemo(() => {
|
|
37
|
+
const normalizedSearch = searchValue.trim().toLowerCase();
|
|
38
|
+
if (!normalizedSearch) {
|
|
39
|
+
return options;
|
|
40
|
+
}
|
|
41
|
+
return options.filter((option) => {
|
|
42
|
+
const label = option.label.toLowerCase();
|
|
43
|
+
const optionValue = option.value.toLowerCase();
|
|
44
|
+
const subOption = option.subOption?.toLowerCase() || '';
|
|
45
|
+
return (label.includes(normalizedSearch) ||
|
|
46
|
+
optionValue.includes(normalizedSearch) ||
|
|
47
|
+
subOption.includes(normalizedSearch));
|
|
48
|
+
});
|
|
49
|
+
}, [options, searchValue]);
|
|
50
|
+
const selectedOptions = useMemo(() => {
|
|
51
|
+
return options.filter((option) => selectedValues.includes(option.value));
|
|
52
|
+
}, [options, selectedValues]);
|
|
53
|
+
function handleValueChange(nextValue) {
|
|
54
|
+
if (multiple) {
|
|
55
|
+
let nextArray = selectedValues.includes(nextValue)
|
|
56
|
+
? selectedValues.filter((v) => v !== nextValue)
|
|
57
|
+
: [...selectedValues, nextValue];
|
|
58
|
+
if (maxSelection !== undefined &&
|
|
59
|
+
nextArray.length > maxSelection &&
|
|
60
|
+
!selectedValues.includes(nextValue)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
onValueChange(nextArray.join(','));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
setSearchValue('');
|
|
67
|
+
onValueChange(nextValue);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function handleInvalid(event) {
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
setIsTouched(true);
|
|
73
|
+
}
|
|
74
|
+
const focusSearchInput = useCallback(() => {
|
|
75
|
+
requestAnimationFrame(() => searchInputRef.current?.focus());
|
|
76
|
+
window.setTimeout(() => searchInputRef.current?.focus(), 0);
|
|
77
|
+
}, []);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (open) {
|
|
80
|
+
focusSearchInput();
|
|
81
|
+
}
|
|
82
|
+
}, [open, focusSearchInput]);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
validationInputRef.current?.setCustomValidity(error || '');
|
|
85
|
+
}, [error]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const input = validationInputRef.current;
|
|
88
|
+
const form = input?.form;
|
|
89
|
+
if (!input || !form) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const currentInput = input;
|
|
93
|
+
function handleFormSubmit() {
|
|
94
|
+
if (currentInput.validity.valid) {
|
|
95
|
+
setIsTouched(false);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
form.addEventListener('submit', handleFormSubmit);
|
|
99
|
+
return () => {
|
|
100
|
+
form.removeEventListener('submit', handleFormSubmit);
|
|
101
|
+
};
|
|
102
|
+
}, []);
|
|
103
|
+
return (_jsxs(SelectPrimitive.Root, { open: open, onOpenChange: (nextOpen) => {
|
|
104
|
+
if (multiple && !nextOpen && shouldKeepOpen.current) {
|
|
105
|
+
shouldKeepOpen.current = false;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
setOpen(nextOpen);
|
|
109
|
+
if (nextOpen) {
|
|
110
|
+
focusSearchInput();
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
setSearchValue('');
|
|
114
|
+
}
|
|
115
|
+
}, value: multiple ? '' : value, onValueChange: handleValueChange, children: [_jsxs("div", { className: "group relative", children: [_jsx("input", { ref: validationInputRef, name: name, value: value, onChange: () => undefined, onInvalid: handleInvalid, required: required, tabIndex: -1, "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-1/2 h-px w-px -translate-y-1/2 opacity-0" }), hasLeftIcon && (_jsx("div", { className: "absolute left-2.5 top-1/2 -translate-y-1/2 z-10 text-gray-500", children: hasError ? (_jsx(CustomTooltip, { content: error || '', side: "bottom", children: _jsx(AlertCircle, { className: "h-4 w-4 text-red-500" }) })) : (_jsx("span", { className: "pointer-events-none flex items-center transition-colors group-focus-within:text-primary [&>svg]:h-4 [&>svg]:w-4", children: icon })) })), _jsxs(SelectPrimitive.Trigger, { id: id, "aria-invalid": hasError, className: `bg-input-dark border text-[11px] text-gray-300 rounded-lg ${hasLeftIcon ? 'pl-8' : 'pl-3'} pr-8 py-2 outline-none w-full uppercase font-bold tracking-wider cursor-pointer flex items-center justify-between transition-colors min-w-45 ${hasError
|
|
116
|
+
? 'border-red-500 focus:ring-2 focus:ring-red-500/50 data-[state=open]:border-red-500'
|
|
117
|
+
: 'border-border-dark focus:border-primary data-[state=open]:border-primary'} ${className || ''}`, children: [_jsx("span", { className: "min-w-0 flex-1 text-left", children: selectedOptions.length > 0 ? (_jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "truncate leading-4", children: selectedOptions
|
|
118
|
+
.map((o) => o.label)
|
|
119
|
+
.join(', ') }), selectedOptions.length === 1 &&
|
|
120
|
+
selectedOptions[0].subOption && (_jsx("span", { className: "truncate text-[10px] font-semibold leading-3 tracking-normal text-gray-500 normal-case", children: selectedOptions[0].subOption }))] })) : (_jsx(SelectPrimitive.Value, { placeholder: placeholder })) }), _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDown, { className: "h-4 w-4 opacity-50 absolute right-2.5 top-1/2 -translate-y-1/2" }) })] })] }), _jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { position: "popper", sideOffset: 4, onFocusCapture: (event) => {
|
|
121
|
+
if (event.target !== searchInputRef.current &&
|
|
122
|
+
searchInputRef.current) {
|
|
123
|
+
event.stopPropagation();
|
|
124
|
+
focusSearchInput();
|
|
125
|
+
}
|
|
126
|
+
}, onKeyDownCapture: (event) => {
|
|
127
|
+
if (event.target === searchInputRef.current ||
|
|
128
|
+
event.ctrlKey ||
|
|
129
|
+
event.altKey ||
|
|
130
|
+
event.metaKey ||
|
|
131
|
+
event.key.length !== 1) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
setSearchValue((current) => `${current}${event.key}`);
|
|
137
|
+
focusSearchInput();
|
|
138
|
+
}, className: "z-9998 w-(--radix-select-trigger-width) min-w-45 overflow-hidden rounded-lg border border-border-dark bg-surface-dark shadow-xl animate-in fade-in zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", children: [_jsx("div", { className: "border-b border-border-dark p-1", children: _jsx("input", { ref: searchInputRef, "aria-label": "Optionen suchen", value: searchValue, onChange: (event) => setSearchValue(event.target.value), onPointerDownCapture: (event) => event.stopPropagation(), onKeyDownCapture: (event) => {
|
|
139
|
+
if (event.key !== 'Escape') {
|
|
140
|
+
event.stopPropagation();
|
|
141
|
+
}
|
|
142
|
+
}, onKeyDown: (event) => {
|
|
143
|
+
if (event.key !== 'Escape') {
|
|
144
|
+
event.stopPropagation();
|
|
145
|
+
}
|
|
146
|
+
}, placeholder: "Suchen...", className: "h-8 w-full rounded-md border border-border-dark bg-input-dark px-2 text-[11px] font-bold uppercase tracking-wider text-gray-300 outline-none placeholder:text-gray-500 focus:border-primary" }) }), _jsx("div", { className: "rentnerselect-scrollbar max-h-[min(var(--radix-select-content-available-height),16rem)] overflow-y-scroll scrollbar-gutter-stable", children: _jsx(SelectPrimitive.Viewport, { className: "p-1", children: filteredOptions.length > 0 ? (filteredOptions.map((option) => (_jsxs(SelectPrimitive.Item, { value: option.value, onPointerDown: () => {
|
|
147
|
+
if (multiple) {
|
|
148
|
+
shouldKeepOpen.current = true;
|
|
149
|
+
}
|
|
150
|
+
}, onKeyDown: (e) => {
|
|
151
|
+
if (multiple &&
|
|
152
|
+
(e.key === 'Enter' ||
|
|
153
|
+
e.key === ' ')) {
|
|
154
|
+
shouldKeepOpen.current = true;
|
|
155
|
+
}
|
|
156
|
+
}, className: "relative flex w-full cursor-pointer select-none items-center rounded-md py-2 pl-8 pr-2 text-[11px] font-bold uppercase tracking-wider text-gray-300 outline-none focus:bg-primary/20 focus:text-primary transition-colors data-disabled:opacity-50", children: [_jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: multiple ? (selectedValues.includes(option.value) && (_jsx(Check, { className: "h-4 w-4" }))) : (_jsx(SelectPrimitive.ItemIndicator, { children: _jsx(Check, { className: "h-4 w-4" }) })) }), _jsx(SelectPrimitive.ItemText, { children: _jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "truncate leading-4", children: option.label }), option.subOption && (_jsx("span", { className: "truncate text-[10px] font-semibold leading-3 tracking-normal text-gray-500 normal-case", children: option.subOption }))] }) })] }, option.value)))) : (_jsx("div", { className: "relative flex w-full select-none items-center rounded-md py-2 pl-8 pr-2 text-[11px] font-bold uppercase tracking-wider text-gray-500 opacity-60 outline-none italic cursor-not-allowed", children: searchValue.trim()
|
|
157
|
+
? 'Keine Ergebnisse'
|
|
158
|
+
: fallbackOption || 'Keine Optionen' })) }) })] }) })] }));
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../src/Select.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface Option {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
subOption?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CustomSelectProps {
|
|
8
|
+
id?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
value: string;
|
|
11
|
+
onValueChange: (value: string) => void;
|
|
12
|
+
options: Array<Option>;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
icon?: ReactNode;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
fallbackOption?: string;
|
|
18
|
+
multiple?: boolean;
|
|
19
|
+
minSelection?: number;
|
|
20
|
+
maxSelection?: number;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rentnerkev/select",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Accessible, searchable React select with single and multiple selection support.",
|
|
5
|
+
"author": "RentnerKev",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bun -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\" && tsc",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"prepare": "bun run build",
|
|
18
|
+
"pack:check": "bun pm pack --dry-run",
|
|
19
|
+
"playground:dev": "bun --cwd playground dev",
|
|
20
|
+
"playground:build": "bun --cwd playground build",
|
|
21
|
+
"lint": "oxlint .",
|
|
22
|
+
"lint:fix": "oxlint --fix .",
|
|
23
|
+
"format": "oxfmt .",
|
|
24
|
+
"format:check": "oxfmt --check .",
|
|
25
|
+
"verify": "bun run typecheck && bun run lint && bun run format:check && bun run build && bun run pack:check"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/RentnerKev/RentnerSelect.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/RentnerKev/RentnerSelect#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/RentnerKev/RentnerSelect/issues"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"registry": "https://registry.npmjs.org"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"react": "^19.2.8",
|
|
41
|
+
"react-dom": "^19.2.8"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/react": "^19.2.18",
|
|
45
|
+
"@types/react-dom": "^19.2.4",
|
|
46
|
+
"oxfmt": "^0.66.0",
|
|
47
|
+
"oxlint": "^1.79.0",
|
|
48
|
+
"react": "^19.3.0",
|
|
49
|
+
"react-dom": "^19.3.0",
|
|
50
|
+
"typescript": "^7.0.2"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@radix-ui/react-select": "^2.3.7",
|
|
54
|
+
"@radix-ui/react-tooltip": "^1.2.16",
|
|
55
|
+
"lucide-react": "^1.33.0"
|
|
56
|
+
},
|
|
57
|
+
"exports": {
|
|
58
|
+
".": {
|
|
59
|
+
"import": "./dist/index.js",
|
|
60
|
+
"types": "./dist/index.d.ts"
|
|
61
|
+
},
|
|
62
|
+
"./select": {
|
|
63
|
+
"import": "./dist/Select.js",
|
|
64
|
+
"types": "./dist/Select.d.ts"
|
|
65
|
+
},
|
|
66
|
+
"./types": {
|
|
67
|
+
"import": "./dist/types.js",
|
|
68
|
+
"types": "./dist/types.d.ts"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"packageManager": "bun@1.4.2"
|
|
72
|
+
}
|