react-bootstrap-plugins 1.0.5 → 2.1.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 (83) hide show
  1. package/README.md +14 -7
  2. package/dist/AutoTextarea.cjs +2 -0
  3. package/dist/AutoTextarea.d.cts +29 -0
  4. package/dist/AutoTextarea.d.ts +29 -0
  5. package/dist/AutoTextarea.js +2 -0
  6. package/dist/DatePicker.cjs +2 -2
  7. package/dist/DatePicker.d.cts +57 -0
  8. package/dist/DatePicker.d.ts +54 -42
  9. package/dist/DatePicker.js +2 -2
  10. package/dist/Label.cjs +2 -2
  11. package/dist/Label.d.cts +15 -0
  12. package/dist/Label.d.ts +12 -13
  13. package/dist/Label.js +2 -2
  14. package/dist/SearchSelect.cjs +2 -2
  15. package/dist/SearchSelect.d.cts +40 -0
  16. package/dist/SearchSelect.d.ts +37 -28
  17. package/dist/SearchSelect.js +2 -2
  18. package/dist/TableLoading.cjs +2 -2
  19. package/dist/TableLoading.d.cts +13 -0
  20. package/dist/TableLoading.d.ts +10 -10
  21. package/dist/TableLoading.js +2 -2
  22. package/dist/chunk-2Q4NZKMX.cjs +2 -0
  23. package/dist/chunk-5IOLZUVD.cjs +2 -0
  24. package/dist/chunk-7LXLWNUR.js +2 -0
  25. package/dist/chunk-AWU5XGMI.cjs +2 -0
  26. package/dist/chunk-HYB5IGJK.js +2 -0
  27. package/dist/chunk-KKWFIJKN.js +2 -0
  28. package/dist/chunk-M3OUUXZG.cjs +2 -0
  29. package/dist/chunk-NPQQDBFB.cjs +2 -0
  30. package/dist/chunk-OEFG7PNW.cjs +2 -0
  31. package/dist/chunk-RR7TBRGI.js +2 -0
  32. package/dist/chunk-WLMCWTO6.js +2 -0
  33. package/dist/chunk-ZCAQ7S2A.js +2 -0
  34. package/dist/css/datepicker.css +1 -299
  35. package/dist/css/plugins.css +1 -0
  36. package/dist/index.cjs +2 -2
  37. package/dist/index.d.cts +6 -0
  38. package/dist/index.d.ts +6 -13
  39. package/dist/index.js +2 -2
  40. package/docs/AUTOTEXTAREA.md +106 -0
  41. package/docs/DATEPICKER.md +3 -3
  42. package/package.json +25 -8
  43. package/dist/DatePicker.cjs.map +0 -1
  44. package/dist/DatePicker.js.map +0 -1
  45. package/dist/Label.cjs.map +0 -1
  46. package/dist/Label.js.map +0 -1
  47. package/dist/SearchSelect.cjs.map +0 -1
  48. package/dist/SearchSelect.js.map +0 -1
  49. package/dist/TableLoading.cjs.map +0 -1
  50. package/dist/TableLoading.js.map +0 -1
  51. package/dist/chunk-2JC4VIKL.cjs +0 -2
  52. package/dist/chunk-2JC4VIKL.cjs.map +0 -1
  53. package/dist/chunk-46AJ2Q5H.js +0 -2
  54. package/dist/chunk-46AJ2Q5H.js.map +0 -1
  55. package/dist/chunk-J4TRPVD4.cjs +0 -2
  56. package/dist/chunk-J4TRPVD4.cjs.map +0 -1
  57. package/dist/chunk-KZEOI42M.cjs +0 -2
  58. package/dist/chunk-KZEOI42M.cjs.map +0 -1
  59. package/dist/chunk-MQRJBL7S.cjs +0 -2
  60. package/dist/chunk-MQRJBL7S.cjs.map +0 -1
  61. package/dist/chunk-MTRPXJ3C.js +0 -2
  62. package/dist/chunk-MTRPXJ3C.js.map +0 -1
  63. package/dist/chunk-QQNPKA7A.cjs +0 -2
  64. package/dist/chunk-QQNPKA7A.cjs.map +0 -1
  65. package/dist/chunk-W6UBCMKG.js +0 -2
  66. package/dist/chunk-W6UBCMKG.js.map +0 -1
  67. package/dist/chunk-WPTHY5AJ.js +0 -2
  68. package/dist/chunk-WPTHY5AJ.js.map +0 -1
  69. package/dist/chunk-XFHLZ7I3.js +0 -2
  70. package/dist/chunk-XFHLZ7I3.js.map +0 -1
  71. package/dist/index.cjs.map +0 -1
  72. package/dist/index.js.map +0 -1
  73. package/src/components/DatePicker.d.ts +0 -45
  74. package/src/components/DatePicker.jsx +0 -691
  75. package/src/components/Label.d.ts +0 -16
  76. package/src/components/Label.jsx +0 -22
  77. package/src/components/SearchSelect.d.ts +0 -31
  78. package/src/components/SearchSelect.jsx +0 -155
  79. package/src/components/TableLoading.d.ts +0 -13
  80. package/src/components/TableLoading.jsx +0 -43
  81. package/src/css/datepicker.css +0 -299
  82. package/src/index.js +0 -16
  83. package/src/lib/cn.js +0 -35
@@ -1,299 +1 @@
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
- }
1
+ .input-group>.datepicker-wrapper,.input-group>.searchselect-wrapper{flex:auto;width:1%;min-width:0;position:relative}.input-group>.datepicker-wrapper:not(:first-child) .form-control,.input-group>.searchselect-wrapper:not(:first-child) .form-select{border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.datepicker-wrapper:not(:last-child) .form-control,.input-group>.searchselect-wrapper:not(:last-child) .form-select{border-top-right-radius:0;border-bottom-right-radius:0}.datepicker-popover{border-radius:var(--bs-border-radius,.375rem);-webkit-user-select:none;user-select:none;box-shadow:0 .5rem 1rem #00000026}.datepicker-popover--wide{min-width:420px}.datepicker-calendar{min-width:260px}.datepicker-days-header,.datepicker-days-grid{grid-template-columns:repeat(7,1fr);gap:2px;display:grid}.datepicker-day-label{color:var(--bs-secondary-color,#6c757d);text-transform:uppercase;text-align:center;width:34px;padding:2px 0;font-size:.7rem;font-weight:600}.datepicker-day{width:34px;height:34px;color:var(--bs-body-color,#212529);border-radius:var(--bs-border-radius-sm,.25rem);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;margin:0 auto;padding:0;font-size:.8rem;font-weight:400;transition:background-color .15s ease-in-out,color .15s ease-in-out;display:flex}.datepicker-day:hover:not(:disabled):not(.datepicker-day--selected){background-color:var(--bs-primary-bg-subtle,#cfe2ff)}.datepicker-day--today{border:1px solid var(--bs-border-color,#dee2e6);font-weight:700}.datepicker-day--selected{font-weight:600;background-color:var(--bs-primary,#0d6efd)!important;color:#fff!important}.datepicker-day--outside{color:var(--bs-tertiary-color,#adb5bd);opacity:.45;pointer-events:none}.datepicker-day--disabled{color:var(--bs-tertiary-color,#adb5bd);opacity:.35;cursor:not-allowed;pointer-events:none}.datepicker-year-picker{min-width:260px}.datepicker-year-grid{grid-template-columns:repeat(4,1fr);gap:6px;display:grid}.datepicker-year-cell{text-align:center;padding:6px 4px;font-size:.85rem}.datepicker-time{min-width:120px}.datepicker-time-col{flex-direction:column;flex:none;align-items:center;width:52px;display:flex}.datepicker-time-col-label{color:var(--bs-secondary-color,#6c757d);text-transform:uppercase;letter-spacing:.04em;-webkit-user-select:none;user-select:none;margin-bottom:2px;font-size:.6rem;font-weight:600}.datepicker-time-col-scroll{scrollbar-width:none;-ms-overflow-style:none;scroll-behavior:smooth;flex-direction:column;align-items:center;gap:1px;height:220px;display:flex;overflow-y:scroll}.datepicker-time-col-scroll::-webkit-scrollbar{display:none}.datepicker-time-item{width:44px;height:30px;color:var(--bs-body-color,#212529);border-radius:var(--bs-border-radius-sm,.25rem);cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;font-size:.82rem;font-weight:500;transition:background-color .1s,color .1s;display:flex}.datepicker-time-item:hover{background-color:var(--bs-primary-bg-subtle,#cfe2ff)}.datepicker-time-item.active{background-color:var(--bs-primary,#0d6efd);color:#fff;font-weight:600}.datepicker-time-item--ampm{width:46px;height:36px;font-size:.78rem}.datepicker-time-separator{color:var(--bs-body-color,#212529);flex:none;align-self:center;margin-top:14px;font-size:1.1rem;font-weight:600}.datepicker-footer{border-bottom-left-radius:var(--bs-border-radius,.375rem);border-bottom-right-radius:var(--bs-border-radius,.375rem)}[data-bs-theme=dark] .datepicker-popover{background-color:var(--bs-body-bg,#212529);border-color:var(--bs-border-color,#495057)}[data-bs-theme=dark] .datepicker-day:hover:not(:disabled):not(.datepicker-day--selected),[data-bs-theme=dark] .datepicker-time-item:hover{background-color:var(--bs-primary-bg-subtle,#2c3e50)}[data-bs-theme=dark] .datepicker-time-item.active{background-color:var(--bs-primary,#0d6efd);color:#fff}[data-bs-theme=dark] .datepicker-footer{border-top-color:var(--bs-border-color,#495057)}@media (max-width:575.98px){.datepicker-popover{overflow-x:hidden;max-width:calc(100vw - 8px)!important}.datepicker-popover--wide .d-flex.flex-row{flex-direction:column!important}.datepicker-popover--wide .vr{display:none}.datepicker-day{width:28px;height:28px;font-size:.72rem}.datepicker-day-label{width:28px;font-size:.62rem}.datepicker-calendar,.datepicker-year-picker{min-width:210px}.datepicker-time-col-scroll{height:200px}.datepicker-time-item{width:38px;height:26px;font-size:.75rem}.datepicker-time-item--ampm{width:40px;height:32px}.datepicker-time-separator{margin-top:12px;font-size:1rem}.datepicker-footer .btn{min-height:34px;padding:6px 8px;font-size:.8rem}.datepicker-year-cell{min-height:34px;padding:8px 4px;font-size:.8rem}}
@@ -0,0 +1 @@
1
+ .input-group>.datepicker-wrapper,.input-group>.searchselect-wrapper{flex:auto;width:1%;min-width:0;position:relative}.input-group>.datepicker-wrapper:not(:first-child) .form-control,.input-group>.searchselect-wrapper:not(:first-child) .form-select{border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.datepicker-wrapper:not(:last-child) .form-control,.input-group>.searchselect-wrapper:not(:last-child) .form-select{border-top-right-radius:0;border-bottom-right-radius:0}.datepicker-popover{border-radius:var(--bs-border-radius,.375rem);-webkit-user-select:none;user-select:none;box-shadow:0 .5rem 1rem #00000026}.datepicker-popover--wide{min-width:420px}.datepicker-calendar{min-width:260px}.datepicker-days-header,.datepicker-days-grid{grid-template-columns:repeat(7,1fr);gap:2px;display:grid}.datepicker-day-label{color:var(--bs-secondary-color,#6c757d);text-transform:uppercase;text-align:center;width:34px;padding:2px 0;font-size:.7rem;font-weight:600}.datepicker-day{width:34px;height:34px;color:var(--bs-body-color,#212529);border-radius:var(--bs-border-radius-sm,.25rem);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;margin:0 auto;padding:0;font-size:.8rem;font-weight:400;transition:background-color .15s ease-in-out,color .15s ease-in-out;display:flex}.datepicker-day:hover:not(:disabled):not(.datepicker-day--selected){background-color:var(--bs-primary-bg-subtle,#cfe2ff)}.datepicker-day--today{border:1px solid var(--bs-border-color,#dee2e6);font-weight:700}.datepicker-day--selected{font-weight:600;background-color:var(--bs-primary,#0d6efd)!important;color:#fff!important}.datepicker-day--outside{color:var(--bs-tertiary-color,#adb5bd);opacity:.45;pointer-events:none}.datepicker-day--disabled{color:var(--bs-tertiary-color,#adb5bd);opacity:.35;cursor:not-allowed;pointer-events:none}.datepicker-year-picker{min-width:260px}.datepicker-year-grid{grid-template-columns:repeat(4,1fr);gap:6px;display:grid}.datepicker-year-cell{text-align:center;padding:6px 4px;font-size:.85rem}.datepicker-time{min-width:120px}.datepicker-time-col{flex-direction:column;flex:none;align-items:center;width:52px;display:flex}.datepicker-time-col-label{color:var(--bs-secondary-color,#6c757d);text-transform:uppercase;letter-spacing:.04em;-webkit-user-select:none;user-select:none;margin-bottom:2px;font-size:.6rem;font-weight:600}.datepicker-time-col-scroll{scrollbar-width:none;-ms-overflow-style:none;scroll-behavior:smooth;flex-direction:column;align-items:center;gap:1px;height:220px;display:flex;overflow-y:scroll}.datepicker-time-col-scroll::-webkit-scrollbar{display:none}.datepicker-time-item{width:44px;height:30px;color:var(--bs-body-color,#212529);border-radius:var(--bs-border-radius-sm,.25rem);cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;font-size:.82rem;font-weight:500;transition:background-color .1s,color .1s;display:flex}.datepicker-time-item:hover{background-color:var(--bs-primary-bg-subtle,#cfe2ff)}.datepicker-time-item.active{background-color:var(--bs-primary,#0d6efd);color:#fff;font-weight:600}.datepicker-time-item--ampm{width:46px;height:36px;font-size:.78rem}.datepicker-time-separator{color:var(--bs-body-color,#212529);flex:none;align-self:center;margin-top:14px;font-size:1.1rem;font-weight:600}.datepicker-footer{border-bottom-left-radius:var(--bs-border-radius,.375rem);border-bottom-right-radius:var(--bs-border-radius,.375rem)}[data-bs-theme=dark] .datepicker-popover{background-color:var(--bs-body-bg,#212529);border-color:var(--bs-border-color,#495057)}[data-bs-theme=dark] .datepicker-day:hover:not(:disabled):not(.datepicker-day--selected),[data-bs-theme=dark] .datepicker-time-item:hover{background-color:var(--bs-primary-bg-subtle,#2c3e50)}[data-bs-theme=dark] .datepicker-time-item.active{background-color:var(--bs-primary,#0d6efd);color:#fff}[data-bs-theme=dark] .datepicker-footer{border-top-color:var(--bs-border-color,#495057)}@media (max-width:575.98px){.datepicker-popover{overflow-x:hidden;max-width:calc(100vw - 8px)!important}.datepicker-popover--wide .d-flex.flex-row{flex-direction:column!important}.datepicker-popover--wide .vr{display:none}.datepicker-day{width:28px;height:28px;font-size:.72rem}.datepicker-day-label{width:28px;font-size:.62rem}.datepicker-calendar,.datepicker-year-picker{min-width:210px}.datepicker-time-col-scroll{height:200px}.datepicker-time-item{width:38px;height:26px;font-size:.75rem}.datepicker-time-item--ampm{width:40px;height:32px}.datepicker-time-separator{margin-top:12px;font-size:1rem}.datepicker-footer .btn{min-height:34px;padding:6px 8px;font-size:.8rem}.datepicker-year-cell{min-height:34px;padding:8px 4px;font-size:.8rem}}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkKZEOI42M_cjs=require('./chunk-KZEOI42M.cjs'),chunkMQRJBL7S_cjs=require('./chunk-MQRJBL7S.cjs');require('./chunk-QQNPKA7A.cjs');var chunk2JC4VIKL_cjs=require('./chunk-2JC4VIKL.cjs'),chunkJ4TRPVD4_cjs=require('./chunk-J4TRPVD4.cjs');Object.defineProperty(exports,"DatePicker",{enumerable:true,get:function(){return chunkKZEOI42M_cjs.a}});Object.defineProperty(exports,"SearchSelect",{enumerable:true,get:function(){return chunkMQRJBL7S_cjs.a}});Object.defineProperty(exports,"Label",{enumerable:true,get:function(){return chunk2JC4VIKL_cjs.a}});Object.defineProperty(exports,"TableLoading",{enumerable:true,get:function(){return chunkJ4TRPVD4_cjs.a}});//# sourceMappingURL=index.cjs.map
2
- //# sourceMappingURL=index.cjs.map
1
+ 'use strict';var chunkOEFG7PNW_cjs=require('./chunk-OEFG7PNW.cjs'),chunkAWU5XGMI_cjs=require('./chunk-AWU5XGMI.cjs'),chunk2Q4NZKMX_cjs=require('./chunk-2Q4NZKMX.cjs'),chunk5IOLZUVD_cjs=require('./chunk-5IOLZUVD.cjs'),chunkM3OUUXZG_cjs=require('./chunk-M3OUUXZG.cjs');require('./chunk-NPQQDBFB.cjs');Object.defineProperty(exports,"DatePicker",{enumerable:true,get:function(){return chunkOEFG7PNW_cjs.a}});Object.defineProperty(exports,"SearchSelect",{enumerable:true,get:function(){return chunkAWU5XGMI_cjs.a}});Object.defineProperty(exports,"Label",{enumerable:true,get:function(){return chunk2Q4NZKMX_cjs.a}});Object.defineProperty(exports,"TableLoading",{enumerable:true,get:function(){return chunk5IOLZUVD_cjs.a}});Object.defineProperty(exports,"AutoTextarea",{enumerable:true,get:function(){return chunkM3OUUXZG_cjs.a}});//# sourceMappingURL=index.cjs.map
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJpbmRleC5janMifQ==
@@ -0,0 +1,6 @@
1
+ export { DatePicker, DatePickerChangeEvent, DatePickerProps } from './DatePicker.cjs';
2
+ export { SearchSelect, SearchSelectProps } from './SearchSelect.cjs';
3
+ export { Label, LabelProps } from './Label.cjs';
4
+ export { TableLoading, TableLoadingProps } from './TableLoading.cjs';
5
+ export { AutoTextarea, AutoTextareaProps } from './AutoTextarea.cjs';
6
+ import 'react';
package/dist/index.d.ts CHANGED
@@ -1,13 +1,6 @@
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 { 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'
11
-
12
- export { TableLoading } from './TableLoading.js'
13
- export type { TableLoadingProps } from './TableLoading.js'
1
+ export { DatePicker, DatePickerChangeEvent, DatePickerProps } from './DatePicker.js';
2
+ export { SearchSelect, SearchSelectProps } from './SearchSelect.js';
3
+ export { Label, LabelProps } from './Label.js';
4
+ export { TableLoading, TableLoadingProps } from './TableLoading.js';
5
+ export { AutoTextarea, AutoTextareaProps } from './AutoTextarea.js';
6
+ import 'react';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export{a as DatePicker}from'./chunk-MTRPXJ3C.js';export{a as SearchSelect}from'./chunk-XFHLZ7I3.js';import'./chunk-46AJ2Q5H.js';export{a as Label}from'./chunk-W6UBCMKG.js';export{a as TableLoading}from'./chunk-WPTHY5AJ.js';//# sourceMappingURL=index.js.map
2
- //# sourceMappingURL=index.js.map
1
+ export{a as DatePicker}from'./chunk-WLMCWTO6.js';export{a as SearchSelect}from'./chunk-ZCAQ7S2A.js';export{a as Label}from'./chunk-HYB5IGJK.js';export{a as TableLoading}from'./chunk-7LXLWNUR.js';export{a as AutoTextarea}from'./chunk-KKWFIJKN.js';import'./chunk-RR7TBRGI.js';//# sourceMappingURL=index.js.map
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJpbmRleC5qcyJ9
@@ -0,0 +1,106 @@
1
+ # AutoTextarea
2
+
3
+ > Bootstrap 5 textarea that automatically grows and shrinks to fit its content. Grows up to `maxRows` (or a pixel `maxHeight` cap), then becomes scrollable. Zero dependencies.
4
+
5
+ ---
6
+
7
+ ## Import
8
+
9
+ ```js
10
+ // Default import (recommended for single-component tree-shaking)
11
+ import AutoTextarea from 'react-bootstrap-plugins/AutoTextarea'
12
+
13
+ // Named import from individual entry point
14
+ import { AutoTextarea } from 'react-bootstrap-plugins/AutoTextarea'
15
+
16
+ // Barrel import
17
+ import { AutoTextarea } from 'react-bootstrap-plugins'
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Basic Usage
23
+
24
+ ```jsx
25
+ import { useState } from 'react'
26
+ import { AutoTextarea } from 'react-bootstrap-plugins'
27
+
28
+ function CommentForm() {
29
+ const [comment, setComment] = useState('')
30
+
31
+ return (
32
+ <AutoTextarea
33
+ name="comment"
34
+ value={comment}
35
+ onChange={e => setComment(e.target.value)}
36
+ placeholder="Write a comment…"
37
+ minRows={2}
38
+ maxRows={8}
39
+ />
40
+ )
41
+ }
42
+ ```
43
+
44
+ The textarea starts at `minRows` tall, grows line-by-line as the user types, and shows a scrollbar once content exceeds `maxRows`. It shrinks back down when content is removed.
45
+
46
+ ---
47
+
48
+ ## Capping Height in Pixels
49
+
50
+ When you need a hard pixel limit instead of a row count (e.g. fitting a fixed panel), pass `maxHeight`. It overrides the `maxRows`-derived limit — the textarea grows up to `maxHeight` pixels and becomes scrollable beyond it:
51
+
52
+ ```jsx
53
+ <AutoTextarea
54
+ value={notes}
55
+ onChange={e => setNotes(e.target.value)}
56
+ maxHeight={240} // grow to 240px, then scroll
57
+ />
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Props
63
+
64
+ Accepts all standard `<textarea>` props (except `rows`, which is managed internally), plus:
65
+
66
+ | Prop | Type | Default | Description |
67
+ |---|---|---|---|
68
+ | `minRows` | `number` | `2` | Minimum number of visible rows |
69
+ | `maxRows` | `number` | `8` | Maximum number of rows before scrolling |
70
+ | `maxHeight` | `number` | — | Hard cap on height in **pixels**. Overrides `maxRows` when provided; content beyond it scrolls |
71
+ | `value` | `string` | — | Controlled value |
72
+ | `onChange` | `function` | — | Change handler (`e.target.value`) |
73
+ | `className` | `string` | — | Additional classes merged with `form-control` |
74
+ | `style` | `object` | — | Inline styles merged onto the textarea |
75
+
76
+ A `ref` is forwarded to the underlying `<textarea>` element.
77
+
78
+ ---
79
+
80
+ ## Behavior Notes
81
+
82
+ - Height recalculates on every value change, on user input (works uncontrolled too), and on window resize (line wrapping changes with width).
83
+ - `resize` is disabled — the component owns its height. Override via `style={{ resize: 'vertical' }}` if you must.
84
+ - Row limits are computed from the element's real `line-height`, padding, and border, so they stay correct across font sizes and Bootstrap size utilities.
85
+
86
+ ---
87
+
88
+ ## Dark Mode
89
+
90
+ Uses Bootstrap's `form-control` class, which adapts automatically. Set `data-bs-theme="dark"` on any parent element.
91
+
92
+ ---
93
+
94
+ ## Bundle Size
95
+
96
+ ~0.4 KB (min+gzip).
97
+
98
+ ---
99
+
100
+ ## See Also
101
+
102
+ - [DatePicker](./DATEPICKER.md) — Date, time, and datetime picker
103
+ - [SearchSelect](./SEARCHSELECT.md) — Filterable, searchable select dropdown
104
+ - [Label](./LABEL.md) — Bootstrap-styled form label with required indicator
105
+ - [TableLoading](./TABLELOADING.md) — Placeholder loading skeleton for tables
106
+ - [Main README](../README.md) — Package overview, installation, and general info
@@ -17,7 +17,7 @@ import { DatePicker } from 'react-bootstrap-plugins/DatePicker'
17
17
  import { DatePicker } from 'react-bootstrap-plugins'
18
18
 
19
19
  // Required CSS (import once, anywhere in your app)
20
- import 'react-bootstrap-plugins/css/datepicker.css'
20
+ import 'react-bootstrap-plugins/css/plugins.css'
21
21
  ```
22
22
 
23
23
  ---
@@ -27,7 +27,7 @@ import 'react-bootstrap-plugins/css/datepicker.css'
27
27
  ```jsx
28
28
  import { useState } from 'react'
29
29
  import { DatePicker } from 'react-bootstrap-plugins'
30
- import 'react-bootstrap-plugins/css/datepicker.css'
30
+ import 'react-bootstrap-plugins/css/plugins.css'
31
31
 
32
32
  function MyForm() {
33
33
  const [date, setDate] = useState(null)
@@ -131,7 +131,7 @@ DatePicker requires a small CSS file for its popover calendar layout. Import it
131
131
 
132
132
  ```js
133
133
  // Recommended — uses the package exports map
134
- import 'react-bootstrap-plugins/css/datepicker.css'
134
+ import 'react-bootstrap-plugins/css/plugins.css'
135
135
  ```
136
136
 
137
137
  For troubleshooting CSS import issues, see the [main README](./README.md#css-imports).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-bootstrap-plugins",
3
- "version": "1.0.5",
3
+ "version": "2.1.0",
4
4
  "description": "Production-grade Bootstrap 5 UI plugins for React — DatePicker, SearchSelect, Label, TableLoading, and more. Zero runtime dependencies beyond React.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -62,23 +62,37 @@
62
62
  "default": "./dist/TableLoading.cjs"
63
63
  }
64
64
  },
65
+ "./AutoTextarea": {
66
+ "import": {
67
+ "types": "./dist/AutoTextarea.d.ts",
68
+ "default": "./dist/AutoTextarea.js"
69
+ },
70
+ "require": {
71
+ "types": "./dist/AutoTextarea.d.ts",
72
+ "default": "./dist/AutoTextarea.cjs"
73
+ }
74
+ },
75
+ "./css/plugins.css": "./dist/css/plugins.css",
65
76
  "./css/datepicker.css": "./dist/css/datepicker.css"
66
77
  },
67
78
  "sideEffects": [
68
79
  "*.css",
69
- "./dist/css/*.css"
80
+ "./dist/css/plugins.css",
81
+ "./dist/css/datepicker.css"
82
+ ],
83
+ "browserslist": [
84
+ "defaults and fully supports es6-module",
85
+ "maintained node versions"
70
86
  ],
71
87
  "files": [
72
88
  "docs",
73
89
  "dist",
74
- "src",
75
90
  "LICENSE",
76
- "README.md",
77
- "CHANGELOG.md"
91
+ "README.md"
78
92
  ],
79
93
  "scripts": {
80
- "build": "tsup && node scripts/copy-types.mjs && rm -rf dist/css && cp -r src/css dist/css",
81
- "build:types": "node scripts/copy-types.mjs",
94
+ "build": "tsup && node scripts/build-css.mjs",
95
+ "build:types": "tsup --dts-only",
82
96
  "dev": "tsup --watch",
83
97
  "prepublishOnly": "pnpm run build",
84
98
  "lint": "echo 'Lint passed'",
@@ -98,6 +112,9 @@
98
112
  "table-loading",
99
113
  "placeholder",
100
114
  "skeleton",
115
+ "textarea",
116
+ "auto-resize",
117
+ "autosize",
101
118
  "ui-components",
102
119
  "react-bootstrap",
103
120
  "form-controls",
@@ -124,10 +141,10 @@
124
141
  "optional": false
125
142
  }
126
143
  },
127
- "dependencies": {},
128
144
  "devDependencies": {
129
145
  "@types/react": "^19.0.0",
130
146
  "@types/react-dom": "^19.0.0",
147
+ "lightningcss": "^1.32.0",
131
148
  "tsup": "^8.3.0",
132
149
  "typescript": "^5.6.0"
133
150
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"DatePicker.cjs"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"DatePicker.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Label.cjs"}
package/dist/Label.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"Label.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"SearchSelect.cjs"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"SearchSelect.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"TableLoading.cjs"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"TableLoading.js"}
@@ -1,2 +0,0 @@
1
- 'use strict';var e=require('react'),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 e__namespace=/*#__PURE__*/_interopNamespace(e);var a=e__namespace.forwardRef(({className:l,hf:t="default",required:r=true,label:o="Title"},b)=>jsxRuntime.jsxs("label",{htmlFor:t,className:l,ref:b,children:[o,r?jsxRuntime.jsx("b",{className:"text-danger",children:"*"}):""]}));a.displayName="Label";var d=a;exports.a=a;exports.b=d;//# sourceMappingURL=chunk-2JC4VIKL.cjs.map
2
- //# sourceMappingURL=chunk-2JC4VIKL.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Label.jsx"],"names":["Label","e","className","hf","required","label","ref","jsxs","jsx","Label_default"],"mappings":"kbAUA,IAAMA,CAAAA,CAAcC,YAAA,CAAA,UAAA,CAAW,CAAC,CAAE,SAAA,CAAAC,CAAAA,CAAW,EAAA,CAAAC,CAAAA,CAAK,SAAA,CAAW,SAAAC,CAAAA,CAAW,IAAA,CAAM,KAAA,CAAAC,CAAAA,CAAQ,OAAQ,CAAA,CAAGC,IAE7FC,eAAAA,CAAC,OAAA,CAAA,CAAM,QAASJ,CAAAA,CAAI,SAAA,CAAWD,EAAW,GAAA,CAAKI,CAAAA,CAC5C,QAAA,CAAA,CAAAD,CAAAA,CAAOD,CAAAA,CAAWI,cAAAA,CAAC,KAAE,SAAA,CAAU,aAAA,CAAc,QAAA,CAAA,GAAA,CAAC,CAAA,CAAO,EAAA,CAAA,CACxD,CAEH,EAEDR,CAAAA,CAAM,WAAA,CAAc,OAAA,CAGpB,IAAOS,CAAAA,CAAQT","file":"chunk-2JC4VIKL.cjs","sourcesContent":["import * as React from 'react'\n\n/**\n * A simple Bootstrap-styled form label with an optional required indicator.\n *\n * @param {string} [className] - Additional CSS classes\n * @param {string} [hf='default'] - htmlFor attribute (associates label with input ID)\n * @param {boolean} [required=true] - Whether to show the required asterisk\n * @param {string} [label='Title'] - Label text content\n */\nconst Label = React.forwardRef(({ className, hf = 'default', required = true, label = 'Title' }, ref) => {\n return (\n <label htmlFor={hf} className={className} ref={ref}>\n {label}{required ? <b className=\"text-danger\">*</b> : ''}\n </label>\n )\n})\n\nLabel.displayName = 'Label'\n\nexport { Label }\nexport default Label\n"]}
@@ -1,2 +0,0 @@
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
@@ -1 +0,0 @@
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"]}
@@ -1,2 +0,0 @@
1
- 'use strict';require('react');var jsxRuntime=require('react/jsx-runtime');var e=({rows:l=5,columns:o=4})=>jsxRuntime.jsx(jsxRuntime.Fragment,{children:Array.from({length:l},(p,r)=>jsxRuntime.jsx("tr",{children:Array.from({length:o},(s,t)=>jsxRuntime.jsx("td",{className:"placeholder-glow",children:jsxRuntime.jsx("span",{className:"placeholder rounded py-2 col-12",style:{height:14,display:"block"}})},t))},r))});e.displayName="TableLoading";var c=e;exports.a=e;exports.b=c;//# sourceMappingURL=chunk-J4TRPVD4.cjs.map
2
- //# sourceMappingURL=chunk-J4TRPVD4.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/TableLoading.jsx"],"names":["TableLoading","rows","columns","jsx","Fragment","_","c","TableLoading_default"],"mappings":"0EAsBA,IAAMA,CAAAA,CAAe,CAAC,CAAE,IAAA,CAAAC,CAAAA,CAAO,CAAA,CAAG,QAAAC,CAAAA,CAAU,CAAE,CAAA,GAC5CC,cAAAA,CAAAC,mBAAAA,CAAA,CACG,QAAA,CAAA,KAAA,CAAM,IAAA,CAAK,CAAE,MAAA,CAAQH,CAAK,CAAA,CAAG,CAACI,CAAAA,CAAG,CAAA,GAChCF,cAAAA,CAAC,IAAA,CAAA,CACE,eAAM,IAAA,CAAK,CAAE,MAAA,CAAQD,CAAQ,CAAA,CAAG,CAACG,CAAAA,CAAGC,CAAAA,GACnCH,eAAC,IAAA,CAAA,CAAW,SAAA,CAAU,kBAAA,CACpB,QAAA,CAAAA,cAAAA,CAAC,MAAA,CAAA,CACC,SAAA,CAAU,iCAAA,CACV,MAAO,CAAE,MAAA,CAAQ,EAAA,CAAI,OAAA,CAAS,OAAQ,CAAA,CACxC,CAAA,CAAA,CAJOG,CAKT,CACD,CAAA,CAAA,CARM,CAST,CACD,CAAA,CACH,EAGFN,CAAAA,CAAa,WAAA,CAAc,cAAA,KAGpBO,CAAAA,CAAQP","file":"chunk-J4TRPVD4.cjs","sourcesContent":["import * as React from 'react'\n\n/**\n * Bootstrap 5 placeholder loading rows for table `<tbody>` elements.\n * Renders a grid of shimmer placeholders matching the table column count.\n *\n * @param {number} [rows=5] - Number of placeholder rows to render\n * @param {number} [columns=4] - Number of placeholder columns per row\n *\n * @example\n * // Inside a table\n * <table className=\"table\">\n * <thead><tr><th>Name</th><th>Class</th><th>Status</th></tr></thead>\n * <tbody>\n * {loading ? (\n * <TableLoading rows={8} columns={3} />\n * ) : (\n * data.map(row => <tr key={row.id}>...</tr>)\n * )}\n * </tbody>\n * </table>\n */\nconst TableLoading = ({ rows = 5, columns = 4 }) => (\n <>\n {Array.from({ length: rows }, (_, r) => (\n <tr key={r}>\n {Array.from({ length: columns }, (_, c) => (\n <td key={c} className=\"placeholder-glow\">\n <span\n className=\"placeholder rounded py-2 col-12\"\n style={{ height: 14, display: 'block' }}\n />\n </td>\n ))}\n </tr>\n ))}\n </>\n)\n\nTableLoading.displayName = 'TableLoading'\n\nexport { TableLoading }\nexport default TableLoading\n"]}