@djangocfg/ui-core 2.1.65 → 2.1.67

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.65",
3
+ "version": "2.1.67",
4
4
  "description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -102,7 +102,7 @@
102
102
  "vaul": "1.1.2"
103
103
  },
104
104
  "devDependencies": {
105
- "@djangocfg/typescript-config": "^2.1.65",
105
+ "@djangocfg/typescript-config": "^2.1.67",
106
106
  "@types/node": "^24.7.2",
107
107
  "@types/react": "^19.1.0",
108
108
  "@types/react-dom": "^19.1.0",
@@ -1,209 +0,0 @@
1
- "use client"
2
-
3
- import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
4
- import * as React from 'react';
5
- import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker';
6
-
7
- import { Button, buttonVariants } from '../../components/button';
8
- import { cn } from '../../lib/utils';
9
-
10
- function Calendar({
11
- className,
12
- classNames,
13
- showOutsideDays = true,
14
- captionLayout = "label",
15
- buttonVariant = "ghost",
16
- formatters,
17
- components,
18
- ...props
19
- }: React.ComponentProps<typeof DayPicker> & {
20
- buttonVariant?: React.ComponentProps<typeof Button>["variant"]
21
- }) {
22
- const defaultClassNames = getDefaultClassNames()
23
-
24
- return (
25
- <DayPicker
26
- showOutsideDays={showOutsideDays}
27
- className={cn(
28
- "bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
29
- String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
30
- String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
31
- className
32
- )}
33
- captionLayout={captionLayout}
34
- formatters={{
35
- formatMonthDropdown: (date) =>
36
- date.toLocaleString("default", { month: "short" }),
37
- ...formatters,
38
- }}
39
- classNames={{
40
- root: cn("w-fit", defaultClassNames.root),
41
- months: cn(
42
- "relative flex flex-col gap-4 md:flex-row",
43
- defaultClassNames.months
44
- ),
45
- month: cn("flex w-full min-w-[calc(var(--cell-size)*7)] flex-col gap-4", defaultClassNames.month),
46
- nav: cn(
47
- "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
48
- defaultClassNames.nav
49
- ),
50
- button_previous: cn(
51
- buttonVariants({ variant: buttonVariant }),
52
- "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
53
- defaultClassNames.button_previous
54
- ),
55
- button_next: cn(
56
- buttonVariants({ variant: buttonVariant }),
57
- "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
58
- defaultClassNames.button_next
59
- ),
60
- month_caption: cn(
61
- "flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
62
- defaultClassNames.month_caption
63
- ),
64
- dropdowns: cn(
65
- "flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
66
- defaultClassNames.dropdowns
67
- ),
68
- dropdown_root: cn(
69
- "has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
70
- defaultClassNames.dropdown_root
71
- ),
72
- dropdown: cn(
73
- "bg-popover absolute inset-0 opacity-0",
74
- defaultClassNames.dropdown
75
- ),
76
- caption_label: cn(
77
- "select-none font-medium",
78
- captionLayout === "label"
79
- ? "text-sm"
80
- : "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
81
- defaultClassNames.caption_label
82
- ),
83
- table: "w-full border-collapse",
84
- weekdays: cn("flex", defaultClassNames.weekdays),
85
- weekday: cn(
86
- "text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
87
- defaultClassNames.weekday
88
- ),
89
- week: cn("mt-2 flex w-full", defaultClassNames.week),
90
- week_number_header: cn(
91
- "w-[--cell-size] select-none",
92
- defaultClassNames.week_number_header
93
- ),
94
- week_number: cn(
95
- "text-muted-foreground select-none text-[0.8rem]",
96
- defaultClassNames.week_number
97
- ),
98
- day: cn(
99
- "group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
100
- defaultClassNames.day
101
- ),
102
- range_start: cn(
103
- "bg-accent rounded-l-md",
104
- defaultClassNames.range_start
105
- ),
106
- range_middle: cn("rounded-none", defaultClassNames.range_middle),
107
- range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
108
- today: cn(
109
- "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
110
- defaultClassNames.today
111
- ),
112
- outside: cn(
113
- "text-muted-foreground aria-selected:text-muted-foreground",
114
- defaultClassNames.outside
115
- ),
116
- disabled: cn(
117
- "text-muted-foreground opacity-50",
118
- defaultClassNames.disabled
119
- ),
120
- hidden: cn("invisible", defaultClassNames.hidden),
121
- ...classNames,
122
- }}
123
- components={{
124
- Root: ({ className, rootRef, ...props }) => {
125
- return (
126
- <div
127
- data-slot="calendar"
128
- ref={rootRef}
129
- className={cn(className)}
130
- {...props}
131
- />
132
- )
133
- },
134
- Chevron: ({ className, orientation, ...props }) => {
135
- if (orientation === "left") {
136
- return (
137
- <ChevronLeftIcon className={cn("size-4", className)} {...props} />
138
- )
139
- }
140
-
141
- if (orientation === "right") {
142
- return (
143
- <ChevronRightIcon
144
- className={cn("size-4", className)}
145
- {...props}
146
- />
147
- )
148
- }
149
-
150
- return (
151
- <ChevronDownIcon className={cn("size-4", className)} {...props} />
152
- )
153
- },
154
- DayButton: CalendarDayButton,
155
- WeekNumber: ({ children, ...props }) => {
156
- return (
157
- <td {...props}>
158
- <div className="flex size-[--cell-size] items-center justify-center text-center">
159
- {children}
160
- </div>
161
- </td>
162
- )
163
- },
164
- ...components,
165
- }}
166
- {...props}
167
- />
168
- )
169
- }
170
-
171
- function CalendarDayButton({
172
- className,
173
- day,
174
- modifiers,
175
- ...props
176
- }: React.ComponentProps<typeof DayButton>) {
177
- const defaultClassNames = getDefaultClassNames()
178
-
179
- const ref = React.useRef<HTMLButtonElement>(null)
180
- React.useEffect(() => {
181
- if (modifiers.focused) ref.current?.focus()
182
- }, [modifiers.focused])
183
-
184
- return (
185
- <Button
186
- ref={ref}
187
- variant="ghost"
188
- size="icon"
189
- data-day={day.date.toLocaleDateString()}
190
- data-selected-single={
191
- modifiers.selected &&
192
- !modifiers.range_start &&
193
- !modifiers.range_end &&
194
- !modifiers.range_middle
195
- }
196
- data-range-start={modifiers.range_start}
197
- data-range-end={modifiers.range_end}
198
- data-range-middle={modifiers.range_middle}
199
- className={cn(
200
- "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
201
- defaultClassNames.day,
202
- className
203
- )}
204
- {...props}
205
- />
206
- )
207
- }
208
-
209
- export { Calendar, CalendarDayButton }
@@ -1,192 +0,0 @@
1
- 'use client'
2
-
3
- import { format } from 'date-fns';
4
- import { CalendarIcon } from 'lucide-react';
5
- import * as React from 'react';
6
-
7
- import { Button } from '../../components/button';
8
- import { Popover, PopoverContent, PopoverTrigger } from '../../components/popover';
9
- import { cn } from '../../lib/utils';
10
- import { Calendar } from './calendar';
11
-
12
- import type { SelectSingleEventHandler } from 'react-day-picker'
13
-
14
- // =============================================================================
15
- // DatePicker - Single date selection with popover
16
- // =============================================================================
17
-
18
- export interface DatePickerProps {
19
- /** Selected date */
20
- value?: Date
21
- /** Callback when date changes */
22
- onChange?: (date: Date | undefined) => void
23
- /** Placeholder text when no date selected */
24
- placeholder?: string
25
- /** Date format string (date-fns format) */
26
- dateFormat?: string
27
- /** Disable the picker */
28
- disabled?: boolean
29
- /** Minimum selectable date */
30
- fromDate?: Date
31
- /** Maximum selectable date */
32
- toDate?: Date
33
- /** Additional class names for the trigger button */
34
- className?: string
35
- /** Button variant */
36
- variant?: 'default' | 'outline' | 'ghost'
37
- /** Align popover */
38
- align?: 'start' | 'center' | 'end'
39
- }
40
-
41
- const DatePicker = React.forwardRef<HTMLButtonElement, DatePickerProps>(
42
- (
43
- {
44
- value,
45
- onChange,
46
- placeholder = 'Pick a date',
47
- dateFormat = 'PPP',
48
- disabled = false,
49
- fromDate,
50
- toDate,
51
- className,
52
- variant = 'outline',
53
- align = 'start',
54
- },
55
- ref
56
- ) => {
57
- const [open, setOpen] = React.useState(false)
58
-
59
- const handleSelect: SelectSingleEventHandler = (date) => {
60
- onChange?.(date)
61
- setOpen(false)
62
- }
63
-
64
- return (
65
- <Popover open={open} onOpenChange={setOpen}>
66
- <PopoverTrigger asChild>
67
- <Button
68
- ref={ref}
69
- variant={variant}
70
- disabled={disabled}
71
- className={cn(
72
- 'w-full justify-start text-left font-normal',
73
- !value && 'text-muted-foreground',
74
- className
75
- )}
76
- >
77
- <CalendarIcon className="mr-2 h-4 w-4" />
78
- {value ? format(value, dateFormat) : placeholder}
79
- </Button>
80
- </PopoverTrigger>
81
- <PopoverContent className="w-auto p-0" align={align}>
82
- <Calendar
83
- mode="single"
84
- selected={value}
85
- onSelect={handleSelect}
86
- disabled={disabled}
87
- fromDate={fromDate}
88
- toDate={toDate}
89
- initialFocus
90
- />
91
- </PopoverContent>
92
- </Popover>
93
- )
94
- }
95
- )
96
- DatePicker.displayName = 'DatePicker'
97
-
98
- // =============================================================================
99
- // DateRangePicker - Date range selection with popover
100
- // =============================================================================
101
-
102
- export interface DateRange {
103
- from?: Date
104
- to?: Date
105
- }
106
-
107
- export interface DateRangePickerProps {
108
- /** Selected date range */
109
- value?: DateRange
110
- /** Callback when range changes */
111
- onChange?: (range: DateRange | undefined) => void
112
- /** Placeholder text when no range selected */
113
- placeholder?: string
114
- /** Date format string (date-fns format) */
115
- dateFormat?: string
116
- /** Disable the picker */
117
- disabled?: boolean
118
- /** Minimum selectable date */
119
- fromDate?: Date
120
- /** Maximum selectable date */
121
- toDate?: Date
122
- /** Number of months to display */
123
- numberOfMonths?: number
124
- /** Additional class names for the trigger button */
125
- className?: string
126
- /** Button variant */
127
- variant?: 'default' | 'outline' | 'ghost'
128
- /** Align popover */
129
- align?: 'start' | 'center' | 'end'
130
- }
131
-
132
- const DateRangePicker = React.forwardRef<HTMLButtonElement, DateRangePickerProps>(
133
- (
134
- {
135
- value,
136
- onChange,
137
- placeholder = 'Pick a date range',
138
- dateFormat = 'LLL dd, y',
139
- disabled = false,
140
- fromDate,
141
- toDate,
142
- numberOfMonths = 2,
143
- className,
144
- variant = 'outline',
145
- align = 'start',
146
- },
147
- ref
148
- ) => {
149
- const [open, setOpen] = React.useState(false)
150
-
151
- const formatRange = () => {
152
- if (!value?.from) return placeholder
153
- if (!value.to) return format(value.from, dateFormat)
154
- return `${format(value.from, dateFormat)} - ${format(value.to, dateFormat)}`
155
- }
156
-
157
- return (
158
- <Popover open={open} onOpenChange={setOpen}>
159
- <PopoverTrigger asChild>
160
- <Button
161
- ref={ref}
162
- variant={variant}
163
- disabled={disabled}
164
- className={cn(
165
- 'w-full justify-start text-left font-normal',
166
- !value?.from && 'text-muted-foreground',
167
- className
168
- )}
169
- >
170
- <CalendarIcon className="mr-2 h-4 w-4" />
171
- {formatRange()}
172
- </Button>
173
- </PopoverTrigger>
174
- <PopoverContent className="w-auto p-0" align={align}>
175
- <Calendar
176
- mode="range"
177
- selected={value?.from ? { from: value.from, to: value.to } : undefined}
178
- onSelect={onChange}
179
- disabled={disabled}
180
- fromDate={fromDate}
181
- toDate={toDate}
182
- numberOfMonths={numberOfMonths}
183
- initialFocus
184
- />
185
- </PopoverContent>
186
- </Popover>
187
- )
188
- }
189
- )
190
- DateRangePicker.displayName = 'DateRangePicker'
191
-
192
- export { DatePicker, DateRangePicker }