aplance-ui 1.4.0 → 1.5.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 (38) hide show
  1. package/package.json +1 -1
  2. package/registry/components/primitives/icon/icon.tsx +4 -6
  3. package/registry/components/primitives/modal/modal.module.css +5 -0
  4. package/registry/components/primitives/modal/modal.tsx +32 -34
  5. package/registry/components/primitives/popover/popover.module.css +4 -2
  6. package/registry/components/primitives/popover/popover.tsx +16 -17
  7. package/registry/components/ui/accordion/accordion.module.css +52 -0
  8. package/registry/components/ui/accordion/accordion.tsx +97 -25
  9. package/registry/components/ui/avatar/avatar.tsx +2 -2
  10. package/registry/components/ui/breadcrumbs/breadcrumbs.module.css +9 -9
  11. package/registry/components/ui/button/button.module.css +43 -5
  12. package/registry/components/ui/button/button.tsx +2 -1
  13. package/registry/components/ui/copy-button/copy-button.module.css +2 -0
  14. package/registry/components/ui/data-table/data-table.module.css +68 -25
  15. package/registry/components/ui/data-table/data-table.tsx +1238 -1229
  16. package/registry/components/ui/data-table/filters.tsx +21 -0
  17. package/registry/components/ui/data-table/pagination-bar.tsx +31 -17
  18. package/registry/components/ui/data-table/types.ts +11 -1
  19. package/registry/components/ui/data-table/useDataTable.tsx +1 -2
  20. package/registry/components/ui/data-table/utils.ts +4 -3
  21. package/registry/components/ui/input-fields/common/input-field-common.module.css +8 -2
  22. package/registry/components/ui/input-fields/common/picker-popover-common.module.css +4 -0
  23. package/registry/components/ui/input-fields/custom-select/custom-select.module.css +115 -84
  24. package/registry/components/ui/input-fields/custom-select/custom-select.tsx +63 -11
  25. package/registry/components/ui/input-fields/date-picker/date-picker.tsx +51 -55
  26. package/registry/components/ui/input-fields/input/input.tsx +348 -348
  27. package/registry/components/ui/input-fields/media-input/media-input.tsx +3 -1
  28. package/registry/components/ui/input-fields/media-input/types.ts +8 -2
  29. package/registry/components/ui/input-fields/media-input/useMediaUpload.tsx +5 -5
  30. package/registry/components/ui/input-fields/media-input/utils.ts +18 -5
  31. package/registry/components/ui/scroll-rail/scroll-rail.module.css +104 -0
  32. package/registry/components/ui/scroll-rail/scroll-rail.tsx +159 -0
  33. package/registry/components/ui/tabs/tabs.module.css +8 -12
  34. package/registry/components/ui/tabs/tabs.tsx +75 -44
  35. package/registry/components/ui/tooltip/tooltip.module.css +8 -3
  36. package/registry/components/ui/tooltip/tooltip.tsx +16 -3
  37. package/registry/lib/string.ts +3 -3
  38. package/registry/registry.json +33 -3
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  useCallback,
3
- useEffect,
4
3
  useId,
5
4
  useMemo,
6
5
  useState,
@@ -151,12 +150,40 @@ export const DatePicker = (props: DatePickerProps) => {
151
150
  ? (currentValue as DateRange)
152
151
  : undefined;
153
152
 
153
+ const selectedSingleText = selectedSingle
154
+ ? toDateInputString(selectedSingle)
155
+ : "";
156
+ const selectedRangeFromText = selectedRange?.from
157
+ ? toDateInputString(selectedRange.from)
158
+ : "";
159
+ const selectedRangeToText = selectedRange?.to
160
+ ? toDateInputString(selectedRange.to)
161
+ : "";
162
+
154
163
  const [isOpen, setIsOpen] = useState(false);
155
- const [singleManualText, setSingleManualText] = useState("");
164
+ const [singleManualText, setSingleManualText] = useState(selectedSingleText);
156
165
  const [rangeManualText, setRangeManualText] = useState<{
157
166
  from: string;
158
167
  to: string;
159
- }>({ from: "", to: "" });
168
+ }>({ from: selectedRangeFromText, to: selectedRangeToText });
169
+
170
+ // The typed text follows the value whenever it changes, from outside or by
171
+ // a pick, in the render that sees the change.
172
+ const valueTextKey = isRange
173
+ ? `range:${selectedRangeFromText}|${selectedRangeToText}`
174
+ : `single:${selectedSingleText}`;
175
+ const [seenValueTextKey, setSeenValueTextKey] = useState(valueTextKey);
176
+ if (valueTextKey !== seenValueTextKey) {
177
+ setSeenValueTextKey(valueTextKey);
178
+ if (isRange) {
179
+ setRangeManualText({
180
+ from: selectedRangeFromText,
181
+ to: selectedRangeToText,
182
+ });
183
+ } else {
184
+ setSingleManualText(selectedSingleText);
185
+ }
186
+ }
160
187
 
161
188
  const resolvedRangeMonthCount = isRange
162
189
  ? Math.max(1, numberOfMonths ?? calendar?.numberOfMonths ?? 2)
@@ -223,53 +250,26 @@ export const DatePicker = (props: DatePickerProps) => {
223
250
  const resolvedPlaceholder =
224
251
  placeholder ?? (isRange ? "Select date range..." : "Select date...");
225
252
 
226
- const selectedSingleText = selectedSingle
227
- ? toDateInputString(selectedSingle)
228
- : "";
229
- const selectedRangeFromText = selectedRange?.from
230
- ? toDateInputString(selectedRange.from)
231
- : "";
232
- const selectedRangeToText = selectedRange?.to
233
- ? toDateInputString(selectedRange.to)
234
- : "";
235
-
236
- useEffect(() => {
237
- if (!isRange || resolvedRangeMonthCount <= 1) return;
238
-
239
- setRangeCalendarMonths((prev) => {
240
- if (prev.length === resolvedRangeMonthCount) return prev;
241
-
242
- const seed = prev[0] ??
243
- toMonthStart(selectedRange?.from ?? selectedRange?.to ?? new Date());
244
-
245
- return Array.from({ length: resolvedRangeMonthCount }, (_, index) =>
246
- prev[index] ?? addMonthOffset(seed, index),
247
- );
248
- });
249
- }, [
250
- isRange,
251
- resolvedRangeMonthCount,
252
- selectedRange?.from,
253
- selectedRange?.to,
254
- ]);
255
-
256
- useEffect(() => {
257
- if (isRange) {
258
- setRangeManualText({
259
- from: selectedRangeFromText,
260
- to: selectedRangeToText,
261
- });
262
- return;
263
- }
264
-
265
- setSingleManualText(selectedSingleText);
266
- }, [isRange, selectedRangeFromText, selectedRangeToText, selectedSingleText]);
267
-
268
- // Sync visible calendar months when popover opens or value changes externally
269
- useEffect(() => {
270
- if (!isOpen) return;
253
+ // One month per calendar shown: when the count changes, the months follow.
254
+ if (
255
+ isRange &&
256
+ resolvedRangeMonthCount > 1 &&
257
+ rangeCalendarMonths.length !== resolvedRangeMonthCount
258
+ ) {
259
+ const seed = rangeCalendarMonths[0] ??
260
+ toMonthStart(selectedRange?.from ?? selectedRange?.to ?? new Date());
261
+ setRangeCalendarMonths(
262
+ Array.from({ length: resolvedRangeMonthCount }, (_, index) =>
263
+ rangeCalendarMonths[index] ?? addMonthOffset(seed, index),
264
+ ),
265
+ );
266
+ }
271
267
 
272
- if (isRange) {
268
+ // Opening shows the months of the value, in the render that opens it.
269
+ const [wasOpen, setWasOpen] = useState(isOpen);
270
+ if (isOpen !== wasOpen) {
271
+ setWasOpen(isOpen);
272
+ if (isOpen && isRange) {
273
273
  const fromMonth = selectedRange?.from
274
274
  ? toMonthStart(selectedRange.from)
275
275
  : undefined;
@@ -298,14 +298,10 @@ export const DatePicker = (props: DatePickerProps) => {
298
298
 
299
299
  const target = selectedRange?.from ?? selectedRange?.to;
300
300
  if (target) setCalendarMonth(toMonthStart(target));
301
- return;
302
- }
303
-
304
- if (selectedSingle) {
301
+ } else if (isOpen && selectedSingle) {
305
302
  setCalendarMonth(toMonthStart(selectedSingle));
306
303
  }
307
- // eslint-disable-next-line react-hooks/exhaustive-deps
308
- }, [isOpen]);
304
+ }
309
305
 
310
306
  const displayText = useMemo(() => {
311
307
  if (formatDisplay) {