react-bootstrap-plugins 1.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 +21 -0
- package/README.md +426 -0
- package/dist/DatePicker.cjs +2 -0
- package/dist/DatePicker.cjs.map +1 -0
- package/dist/DatePicker.d.ts +45 -0
- package/dist/DatePicker.js +2 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/Label.cjs +2 -0
- package/dist/Label.cjs.map +1 -0
- package/dist/Label.d.ts +16 -0
- package/dist/Label.js +2 -0
- package/dist/Label.js.map +1 -0
- package/dist/SearchSelect.cjs +2 -0
- package/dist/SearchSelect.cjs.map +1 -0
- package/dist/SearchSelect.d.ts +28 -0
- package/dist/SearchSelect.js +2 -0
- package/dist/SearchSelect.js.map +1 -0
- package/dist/chunk-46AJ2Q5H.js +2 -0
- package/dist/chunk-46AJ2Q5H.js.map +1 -0
- package/dist/chunk-4ISYCPRB.cjs +2 -0
- package/dist/chunk-4ISYCPRB.cjs.map +1 -0
- package/dist/chunk-CZV7QBHA.cjs +2 -0
- package/dist/chunk-CZV7QBHA.cjs.map +1 -0
- package/dist/chunk-DIUGH74M.js +2 -0
- package/dist/chunk-DIUGH74M.js.map +1 -0
- package/dist/chunk-F3KMQZXU.js +2 -0
- package/dist/chunk-F3KMQZXU.js.map +1 -0
- package/dist/chunk-HBS6VOGV.cjs +2 -0
- package/dist/chunk-HBS6VOGV.cjs.map +1 -0
- package/dist/chunk-NOGRIWSU.js +2 -0
- package/dist/chunk-NOGRIWSU.js.map +1 -0
- package/dist/chunk-QQNPKA7A.cjs +2 -0
- package/dist/chunk-QQNPKA7A.cjs.map +1 -0
- package/dist/css/css/datepicker-bootstrap.css +299 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +125 -0
- package/src/components/DatePicker.d.ts +45 -0
- package/src/components/DatePicker.jsx +690 -0
- package/src/components/Label.d.ts +16 -0
- package/src/components/Label.jsx +21 -0
- package/src/components/SearchSelect.d.ts +28 -0
- package/src/components/SearchSelect.jsx +152 -0
- package/src/css/datepicker-bootstrap.css +299 -0
- package/src/index.js +15 -0
- package/src/lib/cn.js +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tumwesigye Robert
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# react-bootstrap-plugins
|
|
2
|
+
|
|
3
|
+
> Production-grade Bootstrap 5 UI components for React 18+. Zero runtime dependencies. Tree-shakeable.
|
|
4
|
+
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🎯 **Zero runtime dependencies** — only React and React DOM as peer dependencies
|
|
12
|
+
- 🌳 **Tree-shakeable** — import only what you need; unused components are stripped at build time
|
|
13
|
+
- 🎨 **Bootstrap 5 native** — uses CSS custom properties (`--bs-*`), respects dark mode via `[data-bs-theme="dark"]`
|
|
14
|
+
- 📦 **ESM + CJS dual format** — works with any bundler (Vite, webpack, Turbopack, Rollup)
|
|
15
|
+
- 🔒 **TypeScript ready** — full `.d.ts` declarations included
|
|
16
|
+
- ♿ **Accessible** — ARIA attributes, keyboard navigation, screen-reader friendly
|
|
17
|
+
- 📱 **Responsive** — mobile-optimized layouts for all components
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install react-bootstrap-plugins
|
|
23
|
+
# or
|
|
24
|
+
pnpm add react-bootstrap-plugins
|
|
25
|
+
# or
|
|
26
|
+
yarn add react-bootstrap-plugins
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Peer Dependencies
|
|
30
|
+
|
|
31
|
+
Make sure you have React 18+ and Bootstrap 5 CSS loaded:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install react react-dom bootstrap
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
// In your app entry point
|
|
39
|
+
import 'bootstrap/dist/css/bootstrap.min.css'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Components
|
|
45
|
+
|
|
46
|
+
### DatePicker
|
|
47
|
+
|
|
48
|
+
A fully-featured date, time, and datetime picker with Bootstrap styling. Popover is rendered via React Portal — no z-index stacking issues with modals or sidebars.
|
|
49
|
+
|
|
50
|
+
#### Import
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
// Tree-shakeable single import (recommended)
|
|
54
|
+
import { DatePicker } from 'react-bootstrap-plugins/DatePicker'
|
|
55
|
+
|
|
56
|
+
// Or barrel import
|
|
57
|
+
import { DatePicker } from 'react-bootstrap-plugins'
|
|
58
|
+
|
|
59
|
+
// Required CSS (import once, anywhere in your app)
|
|
60
|
+
import 'react-bootstrap-plugins/css/datepicker.css'
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Basic Usage
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
import { useState } from 'react'
|
|
67
|
+
import { DatePicker } from 'react-bootstrap-plugins'
|
|
68
|
+
import 'react-bootstrap-plugins/css/datepicker.css'
|
|
69
|
+
|
|
70
|
+
function MyForm() {
|
|
71
|
+
const [date, setDate] = useState(null)
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<DatePicker
|
|
75
|
+
value={date}
|
|
76
|
+
onChange={(e) => setDate(e.target.value)}
|
|
77
|
+
placeholderText="Pick a date"
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Props
|
|
84
|
+
|
|
85
|
+
| Prop | Type | Default | Description |
|
|
86
|
+
|---|---|---|---|
|
|
87
|
+
| `mode` | `'date'` \| `'time'` \| `'datetime'` | `'date'` | Picker mode |
|
|
88
|
+
| `value` | `Date` \| `string` \| `null` | — | Currently selected value |
|
|
89
|
+
| `selected` | `Date` \| `null` | — | Alias for `value` |
|
|
90
|
+
| `onChange` | `(e) => void` | — | Synthetic event; `e.target.value` is formatted string |
|
|
91
|
+
| `dateFormat` | `string` | — | Custom format. Tokens: `yyyy`, `MM`, `dd`, `hh`, `mm`, `aa` |
|
|
92
|
+
| `placeholderText` | `string` | Auto | Placeholder when empty |
|
|
93
|
+
| `size` | `'sm'` \| `'lg'` | — | Bootstrap input size variant |
|
|
94
|
+
| `isClearable` | `boolean` | `false` | Show clear button |
|
|
95
|
+
| `disabled` | `boolean` | `false` | Disable the input |
|
|
96
|
+
| `minDate` | `Date` | — | Earliest selectable date |
|
|
97
|
+
| `maxDate` | `Date` | — | Latest selectable date |
|
|
98
|
+
| `timeIntervals` | `number` | `5` | Minute step in time picker |
|
|
99
|
+
| `timezone` | `string` | `'Kampala'` | Timezone label |
|
|
100
|
+
| `className` | `string` | — | Additional CSS classes on the input |
|
|
101
|
+
| `id` | `string` | — | Input element ID |
|
|
102
|
+
| `name` | `string` | — | Input name attribute |
|
|
103
|
+
|
|
104
|
+
#### Examples
|
|
105
|
+
|
|
106
|
+
**Date mode (default):**
|
|
107
|
+
```jsx
|
|
108
|
+
<DatePicker
|
|
109
|
+
name="dob"
|
|
110
|
+
value={birthDate}
|
|
111
|
+
onChange={(e) => setBirthDate(e.target.value)}
|
|
112
|
+
maxDate={new Date()}
|
|
113
|
+
isClearable
|
|
114
|
+
/>
|
|
115
|
+
// e.target.value → "2026-06-29"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Time mode:**
|
|
119
|
+
```jsx
|
|
120
|
+
<DatePicker
|
|
121
|
+
mode="time"
|
|
122
|
+
value={startTime}
|
|
123
|
+
onChange={(e) => setStartTime(e.target.value)}
|
|
124
|
+
timeIntervals={15}
|
|
125
|
+
/>
|
|
126
|
+
// e.target.value → "02:30 PM"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Datetime mode:**
|
|
130
|
+
```jsx
|
|
131
|
+
<DatePicker
|
|
132
|
+
mode="datetime"
|
|
133
|
+
value={appointmentDateTime}
|
|
134
|
+
onChange={(e) => setAppointmentDateTime(e.target.value)}
|
|
135
|
+
dateFormat="dd/MM/yyyy hh:mm aa"
|
|
136
|
+
/>
|
|
137
|
+
// e.target.value → "29/06/2026 02:30 PM"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**With Bootstrap form layout:**
|
|
141
|
+
```jsx
|
|
142
|
+
<div className="mb-3">
|
|
143
|
+
<label htmlFor="eventDate" className="form-label">Event Date</label>
|
|
144
|
+
<DatePicker
|
|
145
|
+
id="eventDate"
|
|
146
|
+
name="eventDate"
|
|
147
|
+
value={eventDate}
|
|
148
|
+
onChange={(e) => setEventDate(e.target.value)}
|
|
149
|
+
minDate={new Date()}
|
|
150
|
+
className="form-control-lg"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### SearchSelect
|
|
158
|
+
|
|
159
|
+
A filterable, searchable select dropdown. Supports both primitive arrays and object arrays with configurable label/value keys.
|
|
160
|
+
|
|
161
|
+
#### Import
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
import SearchSelect from 'react-bootstrap-plugins/SearchSelect'
|
|
165
|
+
// or
|
|
166
|
+
import { SearchSelect } from 'react-bootstrap-plugins'
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Basic Usage
|
|
170
|
+
|
|
171
|
+
**Primitive array (strings/numbers):**
|
|
172
|
+
```jsx
|
|
173
|
+
import { useState } from 'react'
|
|
174
|
+
import { SearchSelect } from 'react-bootstrap-plugins'
|
|
175
|
+
|
|
176
|
+
function FruitPicker() {
|
|
177
|
+
const [fruit, setFruit] = useState('')
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<SearchSelect
|
|
181
|
+
options={['Apple', 'Banana', 'Orange', 'Mango', 'Pineapple']}
|
|
182
|
+
placeholder="Choose a fruit..."
|
|
183
|
+
value={fruit}
|
|
184
|
+
onChange={(val) => setFruit(val)}
|
|
185
|
+
/>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Object array with label/value mapping:**
|
|
191
|
+
```jsx
|
|
192
|
+
function UserPicker() {
|
|
193
|
+
const [userId, setUserId] = useState(null)
|
|
194
|
+
|
|
195
|
+
const users = [
|
|
196
|
+
{ id: 101, fullName: 'Alice Johnson', email: 'alice@example.com' },
|
|
197
|
+
{ id: 102, fullName: 'Bob Smith', email: 'bob@example.com' },
|
|
198
|
+
{ id: 103, fullName: 'Charlie Brown', email: 'charlie@example.com' },
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<SearchSelect
|
|
203
|
+
options={users}
|
|
204
|
+
labelKey="fullName"
|
|
205
|
+
valueKey="id"
|
|
206
|
+
placeholder="Select a user..."
|
|
207
|
+
value={userId}
|
|
208
|
+
onChange={(id) => setUserId(id)}
|
|
209
|
+
/>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Props
|
|
215
|
+
|
|
216
|
+
| Prop | Type | Default | Description |
|
|
217
|
+
|---|---|---|---|
|
|
218
|
+
| `options` | `Array<string\|number\|boolean\|object>` | `[]` | Selectable options |
|
|
219
|
+
| `labelKey` | `string` | `'label'` | Key for display text (object options only) |
|
|
220
|
+
| `valueKey` | `string` | `'value'` | Key for the value (object options only) |
|
|
221
|
+
| `placeholder` | `string` | `'Select...'` | Placeholder text |
|
|
222
|
+
| `value` | `any` | `null` | Currently selected value |
|
|
223
|
+
| `onChange` | `(value: any) => void` | — | Called with selected value |
|
|
224
|
+
| `id` | `string` | `'filterable-select'` | Input element ID |
|
|
225
|
+
| `disabled` | `boolean` | `false` | Disable the input |
|
|
226
|
+
| `className` | `string` | — | Additional CSS classes on wrapper |
|
|
227
|
+
|
|
228
|
+
#### Inside Bootstrap Input Groups
|
|
229
|
+
|
|
230
|
+
```jsx
|
|
231
|
+
<div className="input-group mb-3">
|
|
232
|
+
<span className="input-group-text">Subject</span>
|
|
233
|
+
<SearchSelect
|
|
234
|
+
options={subjects}
|
|
235
|
+
labelKey="name"
|
|
236
|
+
valueKey="id"
|
|
237
|
+
placeholder="Search subject..."
|
|
238
|
+
value={subjectId}
|
|
239
|
+
onChange={setSubjectId}
|
|
240
|
+
/>
|
|
241
|
+
</div>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### Label
|
|
247
|
+
|
|
248
|
+
A simple form label with a Bootstrap-styled required field indicator.
|
|
249
|
+
|
|
250
|
+
#### Import
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
import { Label } from 'react-bootstrap-plugins/Label'
|
|
254
|
+
// or
|
|
255
|
+
import { Label } from 'react-bootstrap-plugins'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Basic Usage
|
|
259
|
+
|
|
260
|
+
```jsx
|
|
261
|
+
import { Label } from 'react-bootstrap-plugins'
|
|
262
|
+
|
|
263
|
+
<Label hf="studentName" label="Student Name" />
|
|
264
|
+
// Renders: <label for="studentName">Student Name <b class="text-danger">*</b></label>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### Props
|
|
268
|
+
|
|
269
|
+
| Prop | Type | Default | Description |
|
|
270
|
+
|---|---|---|---|
|
|
271
|
+
| `hf` | `string` | `'default'` | `htmlFor` attribute — matches input `id` |
|
|
272
|
+
| `label` | `string` | `'Title'` | Label text |
|
|
273
|
+
| `required` | `boolean` | `true` | Show red asterisk |
|
|
274
|
+
| `className` | `string` | — | Additional CSS classes |
|
|
275
|
+
|
|
276
|
+
#### Examples
|
|
277
|
+
|
|
278
|
+
**With required indicator:**
|
|
279
|
+
```jsx
|
|
280
|
+
<Label hf="email" label="Email Address" required />
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Optional field (no asterisk):**
|
|
284
|
+
```jsx
|
|
285
|
+
<Label hf="middleName" label="Middle Name" required={false} />
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**With Bootstrap grid:**
|
|
289
|
+
```jsx
|
|
290
|
+
<div className="mb-3 row">
|
|
291
|
+
<div className="col-sm-3">
|
|
292
|
+
<Label hf="phone" label="Phone Number" className="col-form-label" />
|
|
293
|
+
</div>
|
|
294
|
+
<div className="col-sm-9">
|
|
295
|
+
<input id="phone" type="tel" className="form-control" />
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Import Patterns
|
|
303
|
+
|
|
304
|
+
All patterns are tree-shakeable. Your bundler will only include the code you actually import.
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
// Single component — smallest bundle
|
|
308
|
+
import { DatePicker } from 'react-bootstrap-plugins/DatePicker'
|
|
309
|
+
|
|
310
|
+
// Multiple named — tree-shaken
|
|
311
|
+
import { DatePicker, Label } from 'react-bootstrap-plugins'
|
|
312
|
+
|
|
313
|
+
// All components
|
|
314
|
+
import { DatePicker, SearchSelect, Label } from 'react-bootstrap-plugins'
|
|
315
|
+
|
|
316
|
+
// CSS (required for DatePicker)
|
|
317
|
+
import 'react-bootstrap-plugins/css/datepicker.css'
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Dark Mode
|
|
323
|
+
|
|
324
|
+
All components respect Bootstrap 5's dark mode. Set `data-bs-theme="dark"` on any parent element:
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<html data-bs-theme="dark">
|
|
328
|
+
<!-- DatePicker popover, dropdown, and all styling adapt automatically -->
|
|
329
|
+
</html>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Or toggle dynamically:
|
|
333
|
+
|
|
334
|
+
```jsx
|
|
335
|
+
function App() {
|
|
336
|
+
const [theme, setTheme] = useState('light')
|
|
337
|
+
|
|
338
|
+
return (
|
|
339
|
+
<div data-bs-theme={theme}>
|
|
340
|
+
<DatePicker value={date} onChange={handleDate} />
|
|
341
|
+
</div>
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Bundle Size
|
|
349
|
+
|
|
350
|
+
| Import | Approx. Size (min+gzip) |
|
|
351
|
+
|---|---|
|
|
352
|
+
| `DatePicker` (with CSS) | ~5.5 KB |
|
|
353
|
+
| `SearchSelect` | ~1.2 KB |
|
|
354
|
+
| `Label` | ~0.3 KB |
|
|
355
|
+
| All three (barrel) | ~6.5 KB |
|
|
356
|
+
|
|
357
|
+
Measured with ESM, tree-shaken, minified, gzipped. Your actual size depends on your bundler configuration.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Browser Support
|
|
362
|
+
|
|
363
|
+
- Chrome 90+
|
|
364
|
+
- Firefox 90+
|
|
365
|
+
- Safari 15+
|
|
366
|
+
- Edge 90+
|
|
367
|
+
|
|
368
|
+
Requires `ResizeObserver` (all modern browsers), CSS Grid, and CSS Custom Properties.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Security
|
|
373
|
+
|
|
374
|
+
- All user content rendered as React text nodes — no raw HTML injection surfaces
|
|
375
|
+
- No dynamic code evaluation or runtime code generation
|
|
376
|
+
- DatePicker input is `readOnly` — displayed value is always the formatted date, never raw user input
|
|
377
|
+
- Synthetic events use safe, explicit value construction
|
|
378
|
+
- Popover content is isolated from the input DOM tree via React Portal
|
|
379
|
+
|
|
380
|
+
Report security issues to: security@allios.app
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Development
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Clone and install
|
|
388
|
+
git clone https://github.com/allios/react-bootstrap-plugins.git
|
|
389
|
+
cd react-bootstrap-plugins
|
|
390
|
+
pnpm install
|
|
391
|
+
|
|
392
|
+
# Build
|
|
393
|
+
pnpm run build
|
|
394
|
+
|
|
395
|
+
# Watch mode (rebuild on changes)
|
|
396
|
+
pnpm run dev
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Project Structure
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
src/
|
|
403
|
+
├── index.js Barrel export
|
|
404
|
+
├── lib/cn.js Internal classname utility
|
|
405
|
+
├── components/
|
|
406
|
+
│ ├── DatePicker.jsx Date/time/datetime picker
|
|
407
|
+
│ ├── SearchSelect.jsx Searchable select dropdown
|
|
408
|
+
│ ├── Label.jsx Form label
|
|
409
|
+
│ └── *.d.ts TypeScript declarations
|
|
410
|
+
└── css/
|
|
411
|
+
└── datepicker-bootstrap.css
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## License
|
|
417
|
+
|
|
418
|
+
MIT © [Tumwesigye Robert](https://allios.app)
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Related
|
|
423
|
+
|
|
424
|
+
- [Bootstrap 5](https://getbootstrap.com/) — CSS framework this package integrates with
|
|
425
|
+
- [React](https://react.dev/) — UI library
|
|
426
|
+
- [AlliOs](https://allios.app) — Multi-tenant SaaS ecosystem this package originated from
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunk4ISYCPRB_cjs=require('./chunk-4ISYCPRB.cjs');require('./chunk-QQNPKA7A.cjs');Object.defineProperty(exports,"DatePicker",{enumerable:true,get:function(){return chunk4ISYCPRB_cjs.a}});//# sourceMappingURL=DatePicker.cjs.map
|
|
2
|
+
//# sourceMappingURL=DatePicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"DatePicker.cjs"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
export interface DatePickerProps {
|
|
4
|
+
/** Picker mode (default 'date') */
|
|
5
|
+
mode?: 'date' | 'time' | 'datetime'
|
|
6
|
+
/** Currently selected Date (alias for `value`) */
|
|
7
|
+
selected?: Date | null
|
|
8
|
+
/** Currently selected Date */
|
|
9
|
+
value?: Date | string | number | null
|
|
10
|
+
/**
|
|
11
|
+
* Synthetic event handler — `e.target.value` is a pre-formatted string:
|
|
12
|
+
* - date → `"YYYY-MM-DD"`
|
|
13
|
+
* - time → `"hh:mm AA"`
|
|
14
|
+
* - datetime → `"YYYY-MM-DD hh:mm AA"`
|
|
15
|
+
*/
|
|
16
|
+
onChange?: (e: { target: { value: string | null; name: string; type: string } }) => void
|
|
17
|
+
/** Display format — tokens: yyyy, MM, dd, hh, mm, aa */
|
|
18
|
+
dateFormat?: string
|
|
19
|
+
/** Placeholder text when empty */
|
|
20
|
+
placeholderText?: string
|
|
21
|
+
/** Bootstrap size variant */
|
|
22
|
+
size?: 'sm' | 'lg'
|
|
23
|
+
/** Show a clear button on the input */
|
|
24
|
+
isClearable?: boolean
|
|
25
|
+
/** Disable the input */
|
|
26
|
+
disabled?: boolean
|
|
27
|
+
/** Earliest selectable date */
|
|
28
|
+
minDate?: Date
|
|
29
|
+
/** Latest selectable date */
|
|
30
|
+
maxDate?: Date
|
|
31
|
+
/** Minute step in the time list (default 5) */
|
|
32
|
+
timeIntervals?: number
|
|
33
|
+
/** Timezone identifier for display (default 'Kampala') */
|
|
34
|
+
timezone?: string
|
|
35
|
+
/** Additional CSS classes on the input */
|
|
36
|
+
className?: string
|
|
37
|
+
/** Input element ID */
|
|
38
|
+
id?: string
|
|
39
|
+
/** Input name attribute */
|
|
40
|
+
name?: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const DatePicker: React.ForwardRefExoticComponent<
|
|
44
|
+
DatePickerProps & React.RefAttributes<HTMLInputElement>
|
|
45
|
+
>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"DatePicker.js"}
|
package/dist/Label.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"Label.cjs"}
|
package/dist/Label.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
export interface LabelProps {
|
|
4
|
+
/** Additional CSS classes */
|
|
5
|
+
className?: string
|
|
6
|
+
/** htmlFor attribute — associates label with input ID (default 'default') */
|
|
7
|
+
hf?: string
|
|
8
|
+
/** Whether to show the required asterisk (default true) */
|
|
9
|
+
required?: boolean
|
|
10
|
+
/** Label text content (default 'Title') */
|
|
11
|
+
label?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const Label: React.ForwardRefExoticComponent<
|
|
15
|
+
LabelProps & React.RefAttributes<HTMLLabelElement>
|
|
16
|
+
>
|
package/dist/Label.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"Label.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"SearchSelect.cjs"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
export interface SearchSelectProps<T = any> {
|
|
4
|
+
/** Additional CSS classes on the wrapper */
|
|
5
|
+
className?: string
|
|
6
|
+
/** Selectable options — primitives (string/number/boolean) or objects */
|
|
7
|
+
options?: T[] | Array<string | number | boolean>
|
|
8
|
+
/** Key for display text when options are objects (default 'label') */
|
|
9
|
+
labelKey?: string
|
|
10
|
+
/** Key for the value when options are objects (default 'value') */
|
|
11
|
+
valueKey?: string
|
|
12
|
+
/** Placeholder text (default 'Select...') */
|
|
13
|
+
placeholder?: string
|
|
14
|
+
/** Currently selected value */
|
|
15
|
+
value?: any
|
|
16
|
+
/** Called with the selected value when user picks */
|
|
17
|
+
onChange?: (value: any) => void
|
|
18
|
+
/** Input element ID */
|
|
19
|
+
id?: string
|
|
20
|
+
/** Disable the input */
|
|
21
|
+
disabled?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare const SearchSelect: React.ForwardRefExoticComponent<
|
|
25
|
+
SearchSelectProps & React.RefAttributes<HTMLDivElement>
|
|
26
|
+
>
|
|
27
|
+
|
|
28
|
+
export default SearchSelect
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"SearchSelect.js"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function f(...t){let s=[];for(let e of t)if(e){if(typeof e=="string")s.push(e);else if(Array.isArray(e)){let o=f(...e);o&&s.push(o);}else if(typeof e=="object")for(let[o,n]of Object.entries(e))n&&s.push(o);}return s.join(" ")}export{f as a};//# sourceMappingURL=chunk-46AJ2Q5H.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-46AJ2Q5H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/cn.js"],"names":["cn","args","classes","arg","nested","key","value"],"mappings":"AAeO,SAASA,CAAAA,CAAAA,GAAMC,CAAAA,CAAM,CAC1B,IAAMC,CAAAA,CAAU,EAAC,CAEjB,IAAA,IAAWC,CAAAA,IAAOF,CAAAA,CAChB,GAAKE,CAAAA,CAAAA,CAEL,GAAI,OAAOA,CAAAA,EAAQ,QAAA,CACjBD,CAAAA,CAAQ,IAAA,CAAKC,CAAG,CAAA,CAAA,KAAA,GACP,KAAA,CAAM,OAAA,CAAQA,CAAG,CAAA,CAAG,CAC7B,IAAMC,CAAAA,CAASJ,CAAAA,CAAG,GAAGG,CAAG,CAAA,CACpBC,CAAAA,EAAQF,CAAAA,CAAQ,IAAA,CAAKE,CAAM,EACjC,CAAA,KAAA,GAAW,OAAOD,CAAAA,EAAQ,QAAA,CACxB,IAAA,GAAW,CAACE,CAAAA,CAAKC,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQH,CAAG,CAAA,CACvCG,CAAAA,EAAOJ,CAAAA,CAAQ,IAAA,CAAKG,CAAG,EAAA,CAKjC,OAAOH,CAAAA,CAAQ,IAAA,CAAK,GAAG,CACzB","file":"chunk-46AJ2Q5H.js","sourcesContent":["/**\n * Utility for conditionally joining CSS class names together.\n * Filters out falsy values and joins with space.\n *\n * @param {...any} args - Class name strings, objects, or arrays\n * @returns {string} Joined class string\n *\n * @example\n * cn('btn', isActive && 'btn-primary', 'px-3')\n * // => 'btn btn-primary px-3'\n *\n * @example\n * cn('base-class', { 'active': isActive, 'disabled': isDisabled })\n * // => 'base-class active' (when isActive=true, isDisabled=false)\n */\nexport function cn(...args) {\n const classes = []\n\n for (const arg of args) {\n if (!arg) continue\n\n if (typeof arg === 'string') {\n classes.push(arg)\n } else if (Array.isArray(arg)) {\n const nested = cn(...arg)\n if (nested) classes.push(nested)\n } else if (typeof arg === 'object') {\n for (const [key, value] of Object.entries(arg)) {\n if (value) classes.push(key)\n }\n }\n }\n\n return classes.join(' ')\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunkQQNPKA7A_cjs=require('./chunk-QQNPKA7A.cjs'),i=require('react'),reactDom=require('react-dom'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var i__namespace=/*#__PURE__*/_interopNamespace(i);var Ye=["Su","Mo","Tu","We","Th","Fr","Sa"],Ce=["January","February","March","April","May","June","July","August","September","October","November","December"],Ee=Array.from({length:60},(n,t)=>t),g=12,V=(n,t)=>new Date(n,t+1,0).getDate(),ne=(n,t)=>n&&t&&n.getFullYear()===t.getFullYear()&&n.getMonth()===t.getMonth()&&n.getDate()===t.getDate(),Ae=(n,t,r)=>!(t&&n<new Date(t.getFullYear(),t.getMonth(),t.getDate())||r&&n>new Date(r.getFullYear(),r.getMonth(),r.getDate())),Ie=(n,t)=>{let r=new Date(n,t,1).getDay(),m=V(n,t),p=[],b=V(n,t-1);for(let d=r-1;d>=0;d--){let D=b-d;p.push({day:D,date:new Date(n,t-1,D),isOutside:true});}for(let d=1;d<=m;d++)p.push({day:d,date:new Date(n,t,d),isOutside:false});let y=42-p.length;for(let d=1;d<=y;d++)p.push({day:d,date:new Date(n,t+1,d),isOutside:true});return p},L=(n,t,r)=>{if(!n||isNaN(n.getTime()))return "";let m=n.getFullYear(),p=String(n.getMonth()+1).padStart(2,"0"),b=String(n.getDate()).padStart(2,"0"),y=n.getHours(),d=String(n.getMinutes()).padStart(2,"0"),D=y>=12?"PM":"AM";y=y%12||12;let k=String(y).padStart(2,"0");if(r)return r.replace("yyyy",m).replace("MM",p).replace("dd",b).replace("hh",k).replace("mm",d).replace("aa",D);switch(t){case "time":return `${k}:${d} ${D}`;case "datetime":return `${m}-${p}-${b} ${k}:${d} ${D}`;default:return `${m}-${p}-${b}`}},O=(n,t,r="date")=>({target:{value:n,name:t,type:r},preventDefault:()=>{},stopPropagation:()=>{},nativeEvent:null}),Te={date:300,time:300,datetime:400,year:250},Fe=n=>{if(!n)return document.documentElement;let t=n.parentElement;for(;t;){let r=window.getComputedStyle(t),m=r.overflowY||r.overflow;if(m==="auto"||m==="scroll")return t;t=t.parentElement;}return document.documentElement},Oe=(n,t)=>{if(!n)return {};let r=n.getBoundingClientRect(),m=t||300,p=window.innerHeight-r.bottom,b=r.top,y=p<m&&b>p,d=Math.max(r.width,window.innerWidth<576?220:260);return {position:"fixed",top:y?Math.max(4,r.top-m-4):r.bottom+4,left:Math.max(4,Math.min(r.left,window.innerWidth-d-4)),minWidth:d,maxWidth:window.innerWidth-8,zIndex:1070}},$e=i__namespace.forwardRef(({className:n,mode:t="date",selected:r,value:m,onChange:p,dateFormat:b,placeholderText:y,size:d,isClearable:D=false,disabled:k=false,minDate:q,maxDate:z,timeIntervals:We=5,timezone:_e="Kampala",id:se,name:N,...re},$)=>{let ie=e=>{if(!e)return null;if(e instanceof Date)return isNaN(e.getTime())?null:e;if(typeof e=="string"||typeof e=="number"){let a=new Date(e);if(!isNaN(a.getTime()))return a;if(typeof e=="string"){let l=e.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/i);if(l){let c=parseInt(l[1],10),h=parseInt(l[2],10),_=l[3].toUpperCase();c===12&&_==="AM"&&(c=0),c!==12&&_==="PM"&&(c+=12);let X=new Date;return new Date(X.getFullYear(),X.getMonth(),X.getDate(),c,h,0,0)}let u=e.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{1,2}):(\d{2})\s*(AM|PM)$/i);if(u){let c=parseInt(u[4],10),h=parseInt(u[5],10),_=u[6].toUpperCase();return c===12&&_==="AM"&&(c=0),c!==12&&_==="PM"&&(c+=12),new Date(parseInt(u[1]),parseInt(u[2])-1,parseInt(u[3]),c,h,0,0)}}return null}return null},o=i__namespace.useMemo(()=>ie(r??m),[r instanceof Date?r.getTime():r,m instanceof Date?m.getTime():m]),Z=t==="date"||t==="datetime",S=t==="time"||t==="datetime",[R,I]=i__namespace.useState(false),[P,K]=i__namespace.useState(()=>o?o.getFullYear():new Date().getFullYear()),[v,J]=i__namespace.useState(()=>o?o.getMonth():new Date().getMonth()),[w,x]=i__namespace.useState(o),[Y,ee]=i__namespace.useState(()=>o&&o.getHours()%12||12),[C,te]=i__namespace.useState(()=>o?o.getMinutes():0),[E,ae]=i__namespace.useState(()=>o&&o.getHours()>=12?"PM":"AM"),[U,T]=i__namespace.useState(false),[j,B]=i__namespace.useState(()=>Math.floor((o?o.getFullYear():new Date().getFullYear())/g)*g),[oe,ce]=i__namespace.useState({}),F=i__namespace.useRef(null),H=i__namespace.useRef(null),G=i__namespace.useRef(null);i__namespace.useEffect(()=>{let e=document.createElement("div");return e.className="datepicker-portal-root",document.body.appendChild(e),G.current=e,()=>{e.parentNode&&document.body.removeChild(e),G.current=null;}},[]),i__namespace.useEffect(()=>{o&&!isNaN(o.getTime())?(x(o),K(o.getFullYear()),J(o.getMonth()),ee(o.getHours()%12||12),te(o.getMinutes()),ae(o.getHours()>=12?"PM":"AM"),B(Math.floor(o.getFullYear()/g)*g)):x(null);},[o]),i__namespace.useEffect(()=>{if(!R)return;let e=()=>H.current?H.current.getBoundingClientRect().height:Te[U?"year":t]||300,a=Fe(F.current),l=()=>{requestAnimationFrame(()=>{ce(Oe(F.current,e()));});};return l(),a.addEventListener("scroll",l,{passive:true}),window.addEventListener("resize",l),()=>{a.removeEventListener("scroll",l),window.removeEventListener("resize",l);}},[R,t,U]),i__namespace.useEffect(()=>{if(!R)return;let e=a=>{H.current&&!H.current.contains(a.target)&&F.current&&!F.current.contains(a.target)&&(I(false),T(false));};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[R]);let A=(e,a,l,u)=>{let c=new Date(e),h=a%12;return u==="PM"&&(h+=12),h===12&&u==="AM"&&(h=0),c.setHours(h,l,0,0),c},W=e=>{if(!e||isNaN(e.getTime()))return;let a=L(e,t,b);p?.(O(a,N,t));},le=e=>{if(!e){p?.(O(null,N,t)),I(false),T(false);return}W(e),t==="date"&&(I(false),T(false));},de=e=>{if(x(e),t==="date")le(e);else if(t==="datetime"){let a=A(e,Y,C,E);W(a);}},ue=Ie(P,v),pe=()=>{let e=P,a=v;v===0?(e=P-1,a=11):a=v-1,K(e),J(a);let l=w||new Date,u=V(e,a),c=new Date(e,a,Math.min(l.getDate(),u));x(c),W(S?A(c,Y,C,E):c);},me=()=>{let e=P,a=v;v===11?(e=P+1,a=0):a=v+1,K(e),J(a);let l=w||new Date,u=V(e,a),c=new Date(e,a,Math.min(l.getDate(),u));x(c),W(S?A(c,Y,C,E):c);},fe=new Date,be=q?new Date(q.getFullYear(),q.getMonth(),q.getDate()):null,ge=z?new Date(z.getFullYear(),z.getMonth(),z.getDate()):null,ye=e=>{if(ee(e),S){let a=A(w||new Date,e,C,E);p?.(O(L(a,t,b),N,t));}},ve=e=>{if(te(e),S){let a=A(w||new Date,Y,e,E);p?.(O(L(a,t,b),N,t));}},we=e=>{if(ae(e),S){let a=A(w||new Date,Y,C,e);p?.(O(L(a,t,b),N,t));}},he=()=>{B(Math.floor(P/g)*g),T(true);},Me=e=>{K(e),T(false);let a=w||new Date,l=V(e,v),u=new Date(e,v,Math.min(a.getDate(),l));x(u),W(S?A(u,Y,C,E):u);},Q=Math.floor(j/g)*g,De=Array.from({length:g},(e,a)=>Q+a),ke=e=>{e.stopPropagation(),x(null),p?.(O(null,N));},Ne=e=>{e.key==="Escape"&&(I(false),T(false),F.current?.blur()),(e.key==="ArrowDown"||e.key==="Enter"||e.key===" ")&&(e.preventDefault(),I(true));},Se=i__namespace.useCallback(e=>{F.current=e,typeof $=="function"?$(e):$&&($.current=e);},[$]),Re=y??(t==="time"?"Select time":t==="datetime"?"Select date & time":"Select date"),Pe=jsxRuntime.jsxs("div",{ref:H,className:chunkQQNPKA7A_cjs.a("datepicker-popover card border shadow-sm",t==="datetime"&&"datepicker-popover--wide"),style:oe,children:[U&&Z&&jsxRuntime.jsxs("div",{className:"datepicker-year-picker p-3",children:[jsxRuntime.jsxs("div",{className:"d-flex align-items-center justify-content-between mb-2",children:[jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-outline-secondary border-0 px-1",onClick:()=>B(j-g),"aria-label":"Previous years",children:"\u2039"}),jsxRuntime.jsxs("span",{className:"fw-semibold small",children:[Q," \u2013 ",Q+g-1]}),jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-outline-secondary border-0 px-1",onClick:()=>B(j+g),"aria-label":"Next years",children:"\u203A"})]}),jsxRuntime.jsx("div",{className:"datepicker-year-grid",children:De.map(e=>{let a=e===new Date().getFullYear(),l=w&&e===w.getFullYear();return jsxRuntime.jsx("button",{type:"button",className:chunkQQNPKA7A_cjs.a("datepicker-year-cell btn btn-sm",l&&"btn-primary",!l&&a&&"btn-outline-primary",!l&&!a&&"btn-light border"),onClick:()=>Me(e),children:e},e)})})]}),!U&&jsxRuntime.jsx(jsxRuntime.Fragment,{children:jsxRuntime.jsxs("div",{className:chunkQQNPKA7A_cjs.a("d-flex",t==="datetime"?"flex-row":"flex-column"),children:[Z&&jsxRuntime.jsxs("div",{className:"datepicker-calendar p-2",children:[jsxRuntime.jsxs("div",{className:"d-flex align-items-center justify-content-between mb-2",children:[jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-outline-secondary border-0 px-1",onClick:pe,"aria-label":"Previous month",children:"\u2039"}),jsxRuntime.jsxs("div",{className:"d-flex align-items-center gap-1",children:[jsxRuntime.jsx("span",{className:"fw-semibold small",children:Ce[v]}),jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-link text-decoration-none text-primary fw-semibold small p-0",onClick:he,"aria-label":"Choose year",children:P})]}),jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-outline-secondary border-0 px-1",onClick:me,"aria-label":"Next month",children:"\u203A"})]}),jsxRuntime.jsx("div",{className:"datepicker-days-header",children:Ye.map(e=>jsxRuntime.jsx("div",{className:"datepicker-day-label",children:e},e))}),jsxRuntime.jsx("div",{className:"datepicker-days-grid",children:ue.map((e,a)=>{let l=ne(e.date,fe),u=w&&ne(e.date,w),c=Ae(e.date,be,ge),h=e.isOutside||!c;return jsxRuntime.jsx("button",{type:"button",disabled:h,className:chunkQQNPKA7A_cjs.a("datepicker-day",l&&"datepicker-day--today",u&&"datepicker-day--selected",e.isOutside&&"datepicker-day--outside",!c&&"datepicker-day--disabled"),onClick:()=>de(e.date),tabIndex:e.isOutside?-1:0,children:e.day},a)})})]}),t==="datetime"&&jsxRuntime.jsx("div",{className:"vr mx-1 my-2"}),S&&jsxRuntime.jsxs("div",{className:"datepicker-time p-2 d-flex flex-column",style:{minWidth:180},children:[t==="datetime"&&jsxRuntime.jsx("div",{className:"small fw-semibold text-muted text-center mb-1",children:"Time"}),jsxRuntime.jsxs("div",{className:"d-flex justify-content-center gap-2",children:[jsxRuntime.jsxs("div",{className:"datepicker-time-col",children:[jsxRuntime.jsx("div",{className:"datepicker-time-col-label",children:"Hour"}),jsxRuntime.jsx("div",{className:"datepicker-time-col-scroll",children:Array.from({length:12},(e,a)=>a+1).map(e=>jsxRuntime.jsx("button",{type:"button",className:chunkQQNPKA7A_cjs.a("datepicker-time-item",e===Y&&"active"),onClick:()=>ye(e),children:String(e).padStart(2,"0")},e))})]}),jsxRuntime.jsx("span",{className:"datepicker-time-separator",children:":"}),jsxRuntime.jsxs("div",{className:"datepicker-time-col",children:[jsxRuntime.jsx("div",{className:"datepicker-time-col-label",children:"Min"}),jsxRuntime.jsx("div",{className:"datepicker-time-col-scroll",children:Ee.map(e=>jsxRuntime.jsx("button",{type:"button",className:chunkQQNPKA7A_cjs.a("datepicker-time-item",e===C&&"active"),onClick:()=>ve(e),children:String(e).padStart(2,"0")},e))})]}),jsxRuntime.jsxs("div",{className:"datepicker-time-col",children:[jsxRuntime.jsx("div",{className:"datepicker-time-col-label",children:"\xA0"}),jsxRuntime.jsx("div",{className:"d-flex flex-column gap-1 mt-1",children:["AM","PM"].map(e=>jsxRuntime.jsx("button",{type:"button",className:chunkQQNPKA7A_cjs.a("datepicker-time-item","datepicker-time-item--ampm",E===e&&"active"),onClick:()=>we(e),children:e},e))})]})]})]})]})})]});return jsxRuntime.jsxs("div",{className:"position-relative d-inline-block w-100",style:{minWidth:0},children:[jsxRuntime.jsxs("div",{className:"position-relative",children:[jsxRuntime.jsx("input",{ref:Se,id:se,name:N,type:"text",readOnly:true,disabled:k,className:chunkQQNPKA7A_cjs.a("form-control",d==="sm"&&"form-control-sm",d==="lg"&&"form-control-lg","pe-5",n),placeholder:Re,value:L(o,t,b),onClick:()=>!k&&I(!R),onKeyDown:Ne,"aria-haspopup":"dialog","aria-expanded":R,autoComplete:"off",...re}),D&&o&&!k&&jsxRuntime.jsx("button",{type:"button",className:"btn btn-sm btn-link position-absolute top-50 end-0 translate-middle-y pe-2 text-secondary",style:{zIndex:2},onClick:ke,tabIndex:-1,"aria-label":"Clear",children:"\xD7"})]}),R&&!k&&G.current&&reactDom.createPortal(Pe,G.current)]})});$e.displayName="DatePicker";exports.a=$e;//# sourceMappingURL=chunk-4ISYCPRB.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-4ISYCPRB.cjs.map
|