@djangocfg/ui-core 2.1.556 → 2.1.557

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 (32) hide show
  1. package/README.md +2 -2
  2. package/package.json +5 -5
  3. package/src/components/data/calendar/calendar.tsx +1 -1
  4. package/src/components/data/toggle/index.tsx +1 -1
  5. package/src/components/forms/button/index.tsx +6 -1
  6. package/src/components/forms/checkbox/index.tsx +1 -1
  7. package/src/components/forms/filter-button/index.tsx +145 -0
  8. package/src/components/forms/mask-input/index.tsx +1 -1
  9. package/src/components/forms/segmented-input/index.tsx +1 -1
  10. package/src/components/forms/tags-input/index.tsx +1 -1
  11. package/src/components/index.ts +4 -0
  12. package/src/components/layout/filter-bar/index.tsx +48 -0
  13. package/src/components/navigation/command/index.tsx +19 -40
  14. package/src/components/navigation/tabs/index.tsx +102 -17
  15. package/src/components/navigation/tabs/use-tab-indicator.ts +68 -0
  16. package/src/components/overlay/drawer/index.tsx +113 -15
  17. package/src/components/overlay/popover/index.tsx +8 -2
  18. package/src/components/overlay/side-panel/index.tsx +77 -8
  19. package/src/components/select/combobox-async.tsx +26 -32
  20. package/src/components/select/combobox.tsx +36 -40
  21. package/src/components/select/country-select.tsx +21 -9
  22. package/src/components/select/language-select.tsx +21 -9
  23. package/src/components/select/multi-select-pro-async.tsx +3 -2
  24. package/src/components/select/multi-select-pro.tsx +3 -2
  25. package/src/components/select/multi-select.tsx +9 -30
  26. package/src/components/select/select.tsx +1 -1
  27. package/src/components/select/trigger.ts +23 -0
  28. package/src/components/select/use-highlight.ts +68 -0
  29. package/src/styles/css/utilities/filter-bar.css +61 -0
  30. package/src/styles/css/utilities/overlay.css +78 -0
  31. package/src/styles/css/utilities/tabs.css +53 -0
  32. package/src/styles/css/utilities.css +2 -0
@@ -22,3 +22,81 @@
22
22
  backdrop-filter: blur(var(--overlay-blur, 0px));
23
23
  -webkit-backdrop-filter: blur(var(--overlay-blur, 0px));
24
24
  }
25
+
26
+ /**
27
+ * The scrolling list inside a popover — a combobox's options, a command menu's
28
+ * results, any panel long enough to need a limit.
29
+ *
30
+ * It is a ROLE, not a size. The 300px ceiling is what reads comfortably; the
31
+ * real constraint is the gap the popover has to the edge of the window, which
32
+ * Radix publishes as `--radix-popover-content-available-height` on the content
33
+ * element. Taking the smaller of the two is what keeps a list opened near the
34
+ * bottom of the screen from flipping above its trigger and being clipped by the
35
+ * viewport — the failure this class exists to prevent.
36
+ *
37
+ * Outside a popover the Radix variable is unset and the fallback leaves the
38
+ * plain ceiling, so the class is safe anywhere.
39
+ *
40
+ * Override `--popover-scroll-max` (per theme, or on one instance) to raise or
41
+ * lower the ceiling; the viewport clamp always still applies.
42
+ *
43
+ * It must sit on the element that ACTUALLY SCROLLS — for cmdk that is
44
+ * `CommandList`, whose highlight moves by `scrollIntoView({block:'nearest'})`
45
+ * and therefore acts on the nearest scrollable ancestor. Capping a wrapper
46
+ * instead hands the scrolling to a container cmdk cannot see, and the arrow
47
+ * keys walk the highlight out of view.
48
+ *
49
+ * Plain CSS rather than a JIT-scanned utility, for the same reason as
50
+ * `.bg-overlay` above: it must compile no matter whose source the Tailwind
51
+ * content scan covers.
52
+ */
53
+ .popover-scroll-region {
54
+ /* The VIEWPORT clamp deliberately lives on the panel (`.popover-panel`), not
55
+ here: this element is only part of the panel, and capping it alone lets the
56
+ siblings above it — a search input, a header — push the panel past the edge
57
+ anyway. Measured: available 193px, list 193px, panel 236px, top −35px.
58
+ Here the job is only the comfortable ceiling plus the actual scrolling;
59
+ `min-height: 0` is what lets the flex parent shrink it below its content
60
+ when the viewport, not the ceiling, is the binding constraint. */
61
+ max-height: var(--popover-scroll-max, 18.75rem);
62
+ min-height: 0;
63
+ overflow-y: auto;
64
+ overflow-x: hidden;
65
+ overscroll-behavior: contain;
66
+ }
67
+
68
+ /**
69
+ * The part of a snapped drawer that is actually on screen.
70
+ *
71
+ * With snap points the panel is FULL height and vaul slides it down to the
72
+ * active point, so everything below that point sits under the bottom edge of
73
+ * the window. A footer pinned with `mt-auto` therefore pins itself to the
74
+ * bottom of the PANEL — measured 344px below the viewport, unreachable even
75
+ * with the body scrolled to its end, which is what made a drawer's submit
76
+ * button impossible to reach.
77
+ *
78
+ * `--snap-point-height` is vaul's offset — how much of the panel is hidden —
79
+ * so the visible height is what remains. Constraining the content column to it
80
+ * puts the footer back at the edge the reader can see, at every snap point,
81
+ * with no JavaScript following the drag.
82
+ */
83
+ .drawer-snap-viewport {
84
+ display: flex;
85
+ flex-direction: column;
86
+ height: calc(100% - var(--snap-point-height, 0px));
87
+ min-height: 0;
88
+ }
89
+
90
+ /**
91
+ * A popover panel that must never grow past the window.
92
+ *
93
+ * `PopoverContent` carries this by default. The height Radix publishes already
94
+ * accounts for `collisionPadding`, so the panel keeps its gap from the edge,
95
+ * and the column layout lets a `.popover-scroll-region` child absorb whatever
96
+ * is left after fixed siblings (search field, footer) have taken their share.
97
+ */
98
+ .popover-panel {
99
+ display: flex;
100
+ flex-direction: column;
101
+ max-height: var(--radix-popover-content-available-height, none);
102
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The sliding indicator behind a segmented tab list.
3
+ *
4
+ * One pill that travels to the selected tab, rather than a highlight that
5
+ * disappears from one tab and reappears on the next. The movement is what
6
+ * carries the meaning: these options are mutually exclusive, and the pill is
7
+ * the single thing being moved between them.
8
+ *
9
+ * Position and size arrive as `--tab-indicator-x` / `--tab-indicator-w`, which
10
+ * the list measures from the active trigger — tabs here are labelled with real
11
+ * words and are never equal width, so a fixed `--step` (the usual CSS-only
12
+ * trick) would drift the moment a label changed. Only `transform` and `width`
13
+ * animate, so the pill stays on the compositor.
14
+ *
15
+ * The indicator is a pseudo-element on the LIST rather than a background on the
16
+ * trigger: a background cannot animate between two different elements, which is
17
+ * exactly why the default variant popped instead of sliding.
18
+ */
19
+ .tabs-sliding {
20
+ position: relative;
21
+ isolation: isolate;
22
+ }
23
+
24
+ .tabs-sliding::before {
25
+ content: "";
26
+ position: absolute;
27
+ z-index: -1;
28
+ top: var(--tab-indicator-inset, 0.25rem);
29
+ bottom: var(--tab-indicator-inset, 0.25rem);
30
+ left: 0;
31
+ width: var(--tab-indicator-w, 0);
32
+ transform: translate3d(var(--tab-indicator-x, 0), 0, 0);
33
+ border-radius: var(--tab-indicator-radius, var(--radius-sm));
34
+ background: var(--tab-indicator-bg, var(--background));
35
+ box-shadow: var(--tab-indicator-shadow, 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1));
36
+ transition:
37
+ transform 260ms cubic-bezier(0.32, 0.72, 0, 1),
38
+ width 260ms cubic-bezier(0.32, 0.72, 0, 1);
39
+ }
40
+
41
+ /* Before the first measurement the pill has no width, so there is nothing to
42
+ see travelling in from the left edge on mount. */
43
+ .tabs-sliding[data-tab-indicator="idle"]::before {
44
+ opacity: 0;
45
+ }
46
+
47
+ /* A reader who has asked for less motion gets the destination, not the
48
+ journey — the pill still marks the right tab, it simply stops sliding. */
49
+ @media (prefers-reduced-motion: reduce) {
50
+ .tabs-sliding::before {
51
+ transition: none;
52
+ }
53
+ }
@@ -12,6 +12,8 @@
12
12
  @import './utilities/controls.css';
13
13
  @import './utilities/datetime-field.css';
14
14
  @import './utilities/step.css';
15
+ @import './utilities/filter-bar.css';
16
+ @import './utilities/tabs.css';
15
17
  @import './utilities/animations.css';
16
18
  @import './utilities/glass.css';
17
19
  @import './utilities/marquee.css';