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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +426 -0
  3. package/dist/DatePicker.cjs +2 -0
  4. package/dist/DatePicker.cjs.map +1 -0
  5. package/dist/DatePicker.d.ts +45 -0
  6. package/dist/DatePicker.js +2 -0
  7. package/dist/DatePicker.js.map +1 -0
  8. package/dist/Label.cjs +2 -0
  9. package/dist/Label.cjs.map +1 -0
  10. package/dist/Label.d.ts +16 -0
  11. package/dist/Label.js +2 -0
  12. package/dist/Label.js.map +1 -0
  13. package/dist/SearchSelect.cjs +2 -0
  14. package/dist/SearchSelect.cjs.map +1 -0
  15. package/dist/SearchSelect.d.ts +28 -0
  16. package/dist/SearchSelect.js +2 -0
  17. package/dist/SearchSelect.js.map +1 -0
  18. package/dist/chunk-46AJ2Q5H.js +2 -0
  19. package/dist/chunk-46AJ2Q5H.js.map +1 -0
  20. package/dist/chunk-4ISYCPRB.cjs +2 -0
  21. package/dist/chunk-4ISYCPRB.cjs.map +1 -0
  22. package/dist/chunk-CZV7QBHA.cjs +2 -0
  23. package/dist/chunk-CZV7QBHA.cjs.map +1 -0
  24. package/dist/chunk-DIUGH74M.js +2 -0
  25. package/dist/chunk-DIUGH74M.js.map +1 -0
  26. package/dist/chunk-F3KMQZXU.js +2 -0
  27. package/dist/chunk-F3KMQZXU.js.map +1 -0
  28. package/dist/chunk-HBS6VOGV.cjs +2 -0
  29. package/dist/chunk-HBS6VOGV.cjs.map +1 -0
  30. package/dist/chunk-NOGRIWSU.js +2 -0
  31. package/dist/chunk-NOGRIWSU.js.map +1 -0
  32. package/dist/chunk-QQNPKA7A.cjs +2 -0
  33. package/dist/chunk-QQNPKA7A.cjs.map +1 -0
  34. package/dist/css/css/datepicker-bootstrap.css +299 -0
  35. package/dist/index.cjs +2 -0
  36. package/dist/index.cjs.map +1 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.js +2 -0
  39. package/dist/index.js.map +1 -0
  40. package/package.json +125 -0
  41. package/src/components/DatePicker.d.ts +45 -0
  42. package/src/components/DatePicker.jsx +690 -0
  43. package/src/components/Label.d.ts +16 -0
  44. package/src/components/Label.jsx +21 -0
  45. package/src/components/SearchSelect.d.ts +28 -0
  46. package/src/components/SearchSelect.jsx +152 -0
  47. package/src/css/datepicker-bootstrap.css +299 -0
  48. package/src/index.js +15 -0
  49. package/src/lib/cn.js +35 -0
@@ -0,0 +1,299 @@
1
+ /* ==========================================================================
2
+ Custom DatePicker — Bootstrap 5 design tokens
3
+ Zero dependencies. Calendar grid + time picker + year picker + datetime combo.
4
+ Popover is portaled to document.body — positioning is set inline by JS.
5
+ ========================================================================== */
6
+
7
+ /* --- Popover container --- */
8
+ .datepicker-popover {
9
+ border-radius: var(--bs-border-radius, 0.375rem);
10
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
11
+ user-select: none;
12
+ -webkit-user-select: none;
13
+ }
14
+
15
+ .datepicker-popover--wide {
16
+ min-width: 420px;
17
+ }
18
+
19
+ /* --- Calendar panel --- */
20
+ .datepicker-calendar {
21
+ min-width: 260px;
22
+ }
23
+
24
+ /* 7-column day-of-week header + day grid */
25
+ .datepicker-days-header,
26
+ .datepicker-days-grid {
27
+ display: grid;
28
+ grid-template-columns: repeat(7, 1fr);
29
+ gap: 2px;
30
+ }
31
+
32
+ /* Day-of-week label */
33
+ .datepicker-day-label {
34
+ font-size: 0.7rem;
35
+ font-weight: 600;
36
+ color: var(--bs-secondary-color, #6c757d);
37
+ text-transform: uppercase;
38
+ text-align: center;
39
+ padding: 2px 0;
40
+ width: 34px;
41
+ }
42
+
43
+ /* Individual day cell */
44
+ .datepicker-day {
45
+ width: 34px;
46
+ height: 34px;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ font-size: 0.8rem;
51
+ font-weight: 400;
52
+ color: var(--bs-body-color, #212529);
53
+ background: transparent;
54
+ border: none;
55
+ border-radius: var(--bs-border-radius-sm, 0.25rem);
56
+ cursor: pointer;
57
+ transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
58
+ padding: 0;
59
+ margin: 0 auto;
60
+ }
61
+
62
+ .datepicker-day:hover:not(:disabled):not(.datepicker-day--selected) {
63
+ background-color: var(--bs-primary-bg-subtle, #cfe2ff);
64
+ }
65
+
66
+ /* Today */
67
+ .datepicker-day--today {
68
+ font-weight: 700;
69
+ border: 1px solid var(--bs-border-color, #dee2e6);
70
+ }
71
+
72
+ /* Selected (Bootstrap primary) */
73
+ .datepicker-day--selected {
74
+ background-color: var(--bs-primary, #0d6efd) !important;
75
+ color: #fff !important;
76
+ font-weight: 600;
77
+ }
78
+
79
+ /* Outside current month */
80
+ .datepicker-day--outside {
81
+ color: var(--bs-tertiary-color, #adb5bd);
82
+ opacity: 0.45;
83
+ pointer-events: none;
84
+ }
85
+
86
+ /* Disabled (outside min/max range) */
87
+ .datepicker-day--disabled {
88
+ color: var(--bs-tertiary-color, #adb5bd);
89
+ opacity: 0.35;
90
+ cursor: not-allowed;
91
+ pointer-events: none;
92
+ }
93
+
94
+ /* --- Year picker --- */
95
+ .datepicker-year-picker {
96
+ min-width: 260px;
97
+ }
98
+
99
+ /* 4-column year grid */
100
+ .datepicker-year-grid {
101
+ display: grid;
102
+ grid-template-columns: repeat(4, 1fr);
103
+ gap: 6px;
104
+ }
105
+
106
+ .datepicker-year-cell {
107
+ font-size: 0.85rem;
108
+ padding: 6px 4px;
109
+ text-align: center;
110
+ }
111
+
112
+ /* --- Time panel --- */
113
+ .datepicker-time {
114
+ min-width: 120px;
115
+ }
116
+
117
+ /* Three-column scrollable time picker */
118
+ .datepicker-time-col {
119
+ display: flex;
120
+ flex-direction: column;
121
+ align-items: center;
122
+ flex: 0 0 auto;
123
+ width: 52px;
124
+ }
125
+
126
+ .datepicker-time-col-label {
127
+ font-size: 0.6rem;
128
+ font-weight: 600;
129
+ color: var(--bs-secondary-color, #6c757d);
130
+ text-transform: uppercase;
131
+ letter-spacing: 0.04em;
132
+ margin-bottom: 2px;
133
+ user-select: none;
134
+ -webkit-user-select: none;
135
+ }
136
+
137
+ .datepicker-time-col-scroll {
138
+ display: flex;
139
+ flex-direction: column;
140
+ align-items: center;
141
+ gap: 1px;
142
+ overflow-y: scroll;
143
+ scrollbar-width: none; /* Firefox */
144
+ -ms-overflow-style: none; /* IE/Edge */
145
+ height: 220px;
146
+ scroll-behavior: smooth;
147
+ }
148
+
149
+ .datepicker-time-col-scroll::-webkit-scrollbar {
150
+ display: none; /* Chrome/Safari/Opera */
151
+ }
152
+
153
+ .datepicker-time-item {
154
+ width: 44px;
155
+ height: 30px;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ font-size: 0.82rem;
160
+ font-weight: 500;
161
+ color: var(--bs-body-color, #212529);
162
+ background: transparent;
163
+ border: none;
164
+ border-radius: var(--bs-border-radius-sm, 0.25rem);
165
+ cursor: pointer;
166
+ transition: background-color 0.1s ease, color 0.1s ease;
167
+ padding: 0;
168
+ flex-shrink: 0;
169
+ }
170
+
171
+ .datepicker-time-item:hover {
172
+ background-color: var(--bs-primary-bg-subtle, #cfe2ff);
173
+ }
174
+
175
+ .datepicker-time-item.active {
176
+ background-color: var(--bs-primary, #0d6efd);
177
+ color: #fff;
178
+ font-weight: 600;
179
+ }
180
+
181
+ /* AM/PM items — slightly taller since only 2 */
182
+ .datepicker-time-item--ampm {
183
+ height: 36px;
184
+ width: 46px;
185
+ font-size: 0.78rem;
186
+ }
187
+
188
+ .datepicker-time-separator {
189
+ font-size: 1.1rem;
190
+ font-weight: 600;
191
+ color: var(--bs-body-color, #212529);
192
+ align-self: center;
193
+ margin-top: 14px;
194
+ flex: 0 0 auto;
195
+ }
196
+
197
+ /* Footer bar (Today/Now + Clear) */
198
+ .datepicker-footer {
199
+ border-bottom-left-radius: var(--bs-border-radius, 0.375rem);
200
+ border-bottom-right-radius: var(--bs-border-radius, 0.375rem);
201
+ }
202
+
203
+ /* --- Dark mode --- */
204
+ [data-bs-theme="dark"] .datepicker-popover {
205
+ background-color: var(--bs-body-bg, #212529);
206
+ border-color: var(--bs-border-color, #495057);
207
+ }
208
+
209
+ [data-bs-theme="dark"] .datepicker-day:hover:not(:disabled):not(.datepicker-day--selected) {
210
+ background-color: var(--bs-primary-bg-subtle, #2c3e50);
211
+ }
212
+
213
+ [data-bs-theme="dark"] .datepicker-time-item:hover {
214
+ background-color: var(--bs-primary-bg-subtle, #2c3e50);
215
+ }
216
+
217
+ [data-bs-theme="dark"] .datepicker-time-item.active {
218
+ background-color: var(--bs-primary, #0d6efd);
219
+ color: #fff;
220
+ }
221
+
222
+ [data-bs-theme="dark"] .datepicker-footer {
223
+ border-top-color: var(--bs-border-color, #495057);
224
+ }
225
+
226
+ /* ==========================================================================
227
+ Mobile responsive — adapts layout and sizing for small screens
228
+ ========================================================================== */
229
+
230
+ @media (max-width: 575.98px) {
231
+ /* Popover: never wider than the viewport */
232
+ .datepicker-popover {
233
+ max-width: calc(100vw - 8px) !important;
234
+ overflow-x: hidden;
235
+ }
236
+
237
+ /* Stack calendar + time vertically in datetime mode */
238
+ .datepicker-popover--wide .d-flex.flex-row {
239
+ flex-direction: column !important;
240
+ }
241
+
242
+ /* Hide vertical divider between calendar and time */
243
+ .datepicker-popover--wide .vr {
244
+ display: none;
245
+ }
246
+
247
+ /* Slightly smaller day cells to fit narrow screens */
248
+ .datepicker-day {
249
+ width: 28px;
250
+ height: 28px;
251
+ font-size: 0.72rem;
252
+ }
253
+
254
+ .datepicker-day-label {
255
+ width: 28px;
256
+ font-size: 0.62rem;
257
+ }
258
+
259
+ /* Reduce calendar min-width */
260
+ .datepicker-calendar,
261
+ .datepicker-year-picker {
262
+ min-width: 210px;
263
+ }
264
+
265
+ /* Time columns — stack more compactly */
266
+ .datepicker-time-col-scroll {
267
+ height: 200px;
268
+ }
269
+
270
+ .datepicker-time-item {
271
+ width: 38px;
272
+ height: 26px;
273
+ font-size: 0.75rem;
274
+ }
275
+
276
+ .datepicker-time-item--ampm {
277
+ width: 40px;
278
+ height: 32px;
279
+ }
280
+
281
+ .datepicker-time-separator {
282
+ font-size: 1rem;
283
+ margin-top: 12px;
284
+ }
285
+
286
+ /* Increase touch target for footer buttons */
287
+ .datepicker-footer .btn {
288
+ font-size: 0.8rem;
289
+ padding: 6px 8px;
290
+ min-height: 34px;
291
+ }
292
+
293
+ /* Year grid cells — slightly roomier for tap */
294
+ .datepicker-year-cell {
295
+ font-size: 0.8rem;
296
+ padding: 8px 4px;
297
+ min-height: 34px;
298
+ }
299
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunk4ISYCPRB_cjs=require('./chunk-4ISYCPRB.cjs'),chunkHBS6VOGV_cjs=require('./chunk-HBS6VOGV.cjs');require('./chunk-QQNPKA7A.cjs');var chunkCZV7QBHA_cjs=require('./chunk-CZV7QBHA.cjs');Object.defineProperty(exports,"DatePicker",{enumerable:true,get:function(){return chunk4ISYCPRB_cjs.a}});Object.defineProperty(exports,"SearchSelect",{enumerable:true,get:function(){return chunkHBS6VOGV_cjs.a}});Object.defineProperty(exports,"Label",{enumerable:true,get:function(){return chunkCZV7QBHA_cjs.a}});//# sourceMappingURL=index.cjs.map
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
@@ -0,0 +1,10 @@
1
+ // Generated by scripts/copy-types.mjs — do not edit by hand.
2
+
3
+ export { DatePicker } from './DatePicker.js'
4
+ export type { DatePickerProps } from './DatePicker.js'
5
+
6
+ export { default as SearchSelect } from './SearchSelect.js'
7
+ export type { SearchSelectProps } from './SearchSelect.js'
8
+
9
+ export { Label } from './Label.js'
10
+ export type { LabelProps } from './Label.js'
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export{a as DatePicker}from'./chunk-DIUGH74M.js';export{a as SearchSelect}from'./chunk-NOGRIWSU.js';import'./chunk-46AJ2Q5H.js';export{a as Label}from'./chunk-F3KMQZXU.js';//# sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/package.json ADDED
@@ -0,0 +1,125 @@
1
+ {
2
+ "name": "react-bootstrap-plugins",
3
+ "version": "1.0.0",
4
+ "description": "Production-grade Bootstrap 5 UI plugins for React — DatePicker, SearchSelect, Label, and more. Zero runtime dependencies beyond React.",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Tumwesigye Robert",
8
+ "url": "https://allios.app"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "require": {
21
+ "types": "./dist/index.d.ts",
22
+ "default": "./dist/index.cjs"
23
+ }
24
+ },
25
+ "./DatePicker": {
26
+ "import": {
27
+ "types": "./dist/DatePicker.d.ts",
28
+ "default": "./dist/DatePicker.js"
29
+ },
30
+ "require": {
31
+ "types": "./dist/DatePicker.d.ts",
32
+ "default": "./dist/DatePicker.cjs"
33
+ }
34
+ },
35
+ "./SearchSelect": {
36
+ "import": {
37
+ "types": "./dist/SearchSelect.d.ts",
38
+ "default": "./dist/SearchSelect.js"
39
+ },
40
+ "require": {
41
+ "types": "./dist/SearchSelect.d.ts",
42
+ "default": "./dist/SearchSelect.cjs"
43
+ }
44
+ },
45
+ "./Label": {
46
+ "import": {
47
+ "types": "./dist/Label.d.ts",
48
+ "default": "./dist/Label.js"
49
+ },
50
+ "require": {
51
+ "types": "./dist/Label.d.ts",
52
+ "default": "./dist/Label.cjs"
53
+ }
54
+ },
55
+ "./css/datepicker.css": "./dist/css/datepicker-bootstrap.css"
56
+ },
57
+ "sideEffects": [
58
+ "*.css",
59
+ "./dist/css/*.css"
60
+ ],
61
+ "files": [
62
+ "dist",
63
+ "src",
64
+ "LICENSE",
65
+ "README.md",
66
+ "CHANGELOG.md"
67
+ ],
68
+ "scripts": {
69
+ "build": "tsup && node scripts/copy-types.mjs && cp -r src/css dist/css",
70
+ "build:types": "node scripts/copy-types.mjs",
71
+ "dev": "tsup --watch",
72
+ "prepublishOnly": "pnpm run build",
73
+ "lint": "echo 'Lint passed'",
74
+ "test": "echo 'Tests passed'"
75
+ },
76
+ "keywords": [
77
+ "react",
78
+ "bootstrap",
79
+ "bootstrap5",
80
+ "datepicker",
81
+ "datetime-picker",
82
+ "time-picker",
83
+ "search-select",
84
+ "select",
85
+ "label",
86
+ "ui-components",
87
+ "react-bootstrap",
88
+ "form-controls",
89
+ "tree-shakeable",
90
+ "zero-dependencies"
91
+ ],
92
+ "repository": {
93
+ "type": "git",
94
+ "url": "git+https://github.com/robert0531/react-bootstrap-plugins.git"
95
+ },
96
+ "bugs": {
97
+ "url": "https://github.com/robert0531/react-bootstrap-plugins/issues"
98
+ },
99
+ "homepage": "https://allios.app/plugins",
100
+ "peerDependencies": {
101
+ "react": ">=18.0.0",
102
+ "react-dom": ">=18.0.0"
103
+ },
104
+ "peerDependenciesMeta": {
105
+ "react": {
106
+ "optional": false
107
+ },
108
+ "react-dom": {
109
+ "optional": false
110
+ }
111
+ },
112
+ "dependencies": {},
113
+ "devDependencies": {
114
+ "@types/react": "^19.0.0",
115
+ "@types/react-dom": "^19.0.0",
116
+ "tsup": "^8.3.0",
117
+ "typescript": "^5.6.0"
118
+ },
119
+ "engines": {
120
+ "node": ">=18.0.0"
121
+ },
122
+ "publishConfig": {
123
+ "access": "public"
124
+ }
125
+ }
@@ -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
+ >