@djangocfg/ui-core 2.1.532 → 2.1.533

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-core",
3
- "version": "2.1.532",
3
+ "version": "2.1.533",
4
4
  "description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -128,7 +128,7 @@
128
128
  "check:contrast": "node scripts/check-preset-contrast.mjs"
129
129
  },
130
130
  "peerDependencies": {
131
- "@djangocfg/i18n": "^2.1.532",
131
+ "@djangocfg/i18n": "^2.1.533",
132
132
  "consola": "^3.4.2",
133
133
  "lucide-react": "^0.545.0",
134
134
  "moment": "^2.30.1",
@@ -206,8 +206,8 @@
206
206
  "@chenglou/pretext": "^0.0.8"
207
207
  },
208
208
  "devDependencies": {
209
- "@djangocfg/i18n": "^2.1.532",
210
- "@djangocfg/typescript-config": "^2.1.532",
209
+ "@djangocfg/i18n": "^2.1.533",
210
+ "@djangocfg/typescript-config": "^2.1.533",
211
211
  "@types/node": "^24.13.3",
212
212
  "@types/react": "19.2.15",
213
213
  "@types/react-dom": "19.2.3",
@@ -18,12 +18,32 @@ export interface SliderProps extends React.ComponentPropsWithoutRef<typeof Slide
18
18
  storageType?: StorageType
19
19
  /** TTL in ms */
20
20
  storageTtl?: number
21
+ /**
22
+ * Rendered inside the track, behind the filled range.
23
+ *
24
+ * For a second quantity that shares the track's scale — a media player's
25
+ * buffered extent is the case this exists for. Positioned by the caller and
26
+ * never interactive: the slider owns every pointer event on the track.
27
+ */
28
+ trackDecoration?: React.ReactNode
29
+ /**
30
+ * Extra classes for the track, the filled range and the thumb.
31
+ *
32
+ * These parts live inside this component, so a consumer cannot reach them:
33
+ * a descendant selector would have to name classes it does not own, and
34
+ * arbitrary Tailwind variants targeting them are not reliably generated.
35
+ * A media scrubber needs a hairline track and a thumb that only appears on
36
+ * hover, which is what these exist for.
37
+ */
38
+ trackClassName?: string
39
+ rangeClassName?: string
40
+ thumbClassName?: string
21
41
  }
22
42
 
23
43
  const Slider = React.forwardRef<
24
44
  React.ElementRef<typeof SliderPrimitive.Root>,
25
45
  SliderProps
26
- >(({ className, orientation = 'horizontal', storageKey, storageType, storageTtl, onValueChange, ...props }, ref) => {
46
+ >(({ className, orientation = 'horizontal', storageKey, storageType, storageTtl, trackDecoration, trackClassName, rangeClassName, thumbClassName, onValueChange, ...props }, ref) => {
27
47
  const isVertical = orientation === 'vertical';
28
48
 
29
49
  const storageOptions: UseStoredValueOptions | undefined =
@@ -55,6 +75,7 @@ const Slider = React.forwardRef<
55
75
  return (
56
76
  <SliderPrimitive.Root
57
77
  ref={ref}
78
+ data-slot="slider"
58
79
  orientation={orientation}
59
80
  className={cn(
60
81
  "relative flex touch-none select-none",
@@ -66,19 +87,39 @@ const Slider = React.forwardRef<
66
87
  {...sliderProps}
67
88
  >
68
89
  <SliderPrimitive.Track
90
+ data-slot="slider-track"
69
91
  className={cn(
70
92
  "relative overflow-hidden rounded-full bg-primary/20",
71
- isVertical ? "w-1.5 h-full grow" : "h-1.5 w-full grow"
93
+ isVertical ? "w-1.5 h-full grow" : "h-1.5 w-full grow",
94
+ trackClassName
72
95
  )}
73
96
  >
97
+ {/* Renders BEHIND the range, inside the track, so a consumer that has a
98
+ secondary quantity to show (a media player's buffered extent) does not
99
+ have to fork this component or overlay a second element. */}
100
+ {trackDecoration}
74
101
  <SliderPrimitive.Range
102
+ data-slot="slider-range"
75
103
  className={cn(
76
104
  "absolute bg-primary",
77
- isVertical ? "w-full bottom-0" : "h-full left-0"
105
+ isVertical ? "w-full bottom-0" : "h-full left-0",
106
+ rangeClassName
78
107
  )}
79
108
  />
80
109
  </SliderPrimitive.Track>
81
- <SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
110
+ {/* The accessible name and value text belong on the THUMB: that is where
111
+ Radix puts `role="slider"`, so a label left on the Root names a
112
+ generic element and the control itself stays anonymous. */}
113
+ <SliderPrimitive.Thumb
114
+ data-slot="slider-thumb"
115
+ aria-label={props['aria-label']}
116
+ aria-labelledby={props['aria-labelledby']}
117
+ aria-valuetext={props['aria-valuetext']}
118
+ className={cn(
119
+ "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
120
+ thumbClassName
121
+ )}
122
+ />
82
123
  </SliderPrimitive.Root>
83
124
  );
84
125
  })
@@ -99,7 +99,7 @@ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './over
99
99
  // ─────────────────────────────────────────────────────────────────────────────
100
100
  export { navigationMenuTriggerStyle, NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuIndicator, NavigationMenuViewport } from './navigation/navigation-menu';
101
101
  export { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem, MenubarSeparator, MenubarLabel, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarPortal, MenubarSubContent, MenubarSubTrigger, MenubarGroup, MenubarSub, MenubarShortcut } from './navigation/menubar';
102
- export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup } from './navigation/dropdown-menu';
102
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, revealOnRowInteraction } from './navigation/dropdown-menu';
103
103
  export { ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger } from './navigation/context-menu';
104
104
  export { PopoverRowButton } from './navigation/popover-row-button';
105
105
  export type { PopoverRowButtonProps } from './navigation/popover-row-button';
@@ -11,6 +11,24 @@ const DropdownMenu = DropdownMenuPrimitive.Root
11
11
 
12
12
  const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
13
13
 
14
+ /**
15
+ * Classes for a trigger that stays hidden until the row is hovered or focused
16
+ * — the `…` on a list row, a tab, a tree item.
17
+ *
18
+ * The last clause is the one that is easy to miss and impossible to see in a
19
+ * screenshot of a closed menu: while the menu is OPEN, Radix has moved focus
20
+ * into the portalled panel and the pointer has left the row, so both reveal
21
+ * conditions are false and the trigger fades out under the menu it just
22
+ * opened. `data-state` is set by Radix on any trigger, so this composes with
23
+ * the primitive and with `MenuBuilder` alike.
24
+ *
25
+ * The row must be a `group`. Compose with `cn()` and the row's own sizing.
26
+ */
27
+ const revealOnRowInteraction =
28
+ "opacity-0 transition-opacity group-hover:opacity-100 " +
29
+ "group-focus-within:opacity-100 focus-visible:opacity-100 " +
30
+ "data-[state=open]:opacity-100 motion-reduce:transition-none"
31
+
14
32
  const DropdownMenuGroup = DropdownMenuPrimitive.Group
15
33
 
16
34
  const DropdownMenuPortal = DropdownMenuPrimitive.Portal
@@ -232,6 +250,7 @@ DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
232
250
  export {
233
251
  DropdownMenu,
234
252
  DropdownMenuTrigger,
253
+ revealOnRowInteraction,
235
254
  DropdownMenuContent,
236
255
  DropdownMenuItem,
237
256
  DropdownMenuCheckboxItem,