@minutemailer/kit 1.1.2 → 1.1.4

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.
@@ -0,0 +1,13 @@
1
+ export type MoreOption = {
2
+ value: string;
3
+ name: string;
4
+ variant?: 'default' | 'destructive';
5
+ disabled?: boolean;
6
+ };
7
+ export interface MoreProps {
8
+ options: MoreOption[];
9
+ loading?: boolean;
10
+ onChange?: (value: string) => void;
11
+ disabled?: boolean;
12
+ }
13
+ export declare function More({ options, loading, onChange, disabled, }: MoreProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../components/ui/dropdown-menu.js';
3
+ import { Button } from '../components/ui/button.js';
4
+ import { Ellipsis } from 'lucide-react';
5
+ import Spinner from '../icons/Spinner.js';
6
+ export function More({ options, loading = false, onChange, disabled = false, }) {
7
+ const handleSelect = (value) => {
8
+ if (onChange) {
9
+ onChange(value);
10
+ }
11
+ };
12
+ return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", disabled: disabled || loading, "aria-label": "More options", children: loading ? _jsx(Spinner, {}) : _jsx(Ellipsis, {}) }) }), _jsx(DropdownMenuContent, { align: "end", children: options.map((option) => (_jsx(DropdownMenuItem, { variant: option.variant, disabled: option.disabled, onSelect: () => handleSelect(option.value), children: option.name }, option.value))) })] }));
13
+ }
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import { DayButton, DayPicker } from 'react-day-picker';
3
+ import { Button } from '../../components/ui/button.js';
4
+ declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, ...props }: React.ComponentProps<typeof DayPicker> & {
5
+ buttonVariant?: React.ComponentProps<typeof Button>['variant'];
6
+ }): import("react/jsx-runtime").JSX.Element;
7
+ declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): import("react/jsx-runtime").JSX.Element;
8
+ export { Calendar, CalendarDayButton };
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, } from 'lucide-react';
4
+ import { DayPicker, getDefaultClassNames } from 'react-day-picker';
5
+ import { cn } from '../../utils/utils.js';
6
+ import { Button, buttonVariants } from '../../components/ui/button.js';
7
+ function Calendar({ className, classNames, showOutsideDays = true, captionLayout = 'label', buttonVariant = 'ghost', formatters, components, ...props }) {
8
+ const defaultClassNames = getDefaultClassNames();
9
+ return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, className: cn('bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent', String.raw `rtl:**:[.rdp-button\_next>svg]:rotate-180`, String.raw `rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className), captionLayout: captionLayout, formatters: {
10
+ formatMonthDropdown: (date) => date.toLocaleString('default', { month: 'short' }),
11
+ ...formatters,
12
+ }, classNames: {
13
+ root: cn('w-fit', defaultClassNames.root),
14
+ months: cn('flex gap-4 flex-col md:flex-row relative', defaultClassNames.months),
15
+ month: cn('flex flex-col w-full gap-4', defaultClassNames.month),
16
+ nav: cn('flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between', defaultClassNames.nav),
17
+ button_previous: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none', defaultClassNames.button_previous),
18
+ button_next: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none', defaultClassNames.button_next),
19
+ month_caption: cn('flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)', defaultClassNames.month_caption),
20
+ dropdowns: cn('w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5', defaultClassNames.dropdowns),
21
+ dropdown_root: cn('relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md', defaultClassNames.dropdown_root),
22
+ dropdown: cn('absolute bg-popover inset-0 opacity-0', defaultClassNames.dropdown),
23
+ caption_label: cn('select-none font-medium', captionLayout === 'label'
24
+ ? 'text-sm'
25
+ : 'rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5', defaultClassNames.caption_label),
26
+ table: 'w-full border-collapse',
27
+ weekdays: cn('flex', defaultClassNames.weekdays),
28
+ weekday: cn('text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none', defaultClassNames.weekday),
29
+ week: cn('flex w-full mt-2', defaultClassNames.week),
30
+ week_number_header: cn('select-none w-(--cell-size)', defaultClassNames.week_number_header),
31
+ week_number: cn('text-[0.8rem] select-none text-muted-foreground', defaultClassNames.week_number),
32
+ day: cn('relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none', defaultClassNames.day),
33
+ range_start: cn('rounded-l-md bg-accent', defaultClassNames.range_start),
34
+ range_middle: cn('rounded-none', defaultClassNames.range_middle),
35
+ range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
36
+ today: cn('bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none', defaultClassNames.today),
37
+ outside: cn('text-muted-foreground aria-selected:text-muted-foreground', defaultClassNames.outside),
38
+ disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),
39
+ hidden: cn('invisible', defaultClassNames.hidden),
40
+ ...classNames,
41
+ }, components: {
42
+ Root: ({ className, rootRef, ...props }) => {
43
+ return (_jsx("div", { "data-slot": "calendar", ref: rootRef, className: cn(className), ...props }));
44
+ },
45
+ Chevron: ({ className, orientation, ...props }) => {
46
+ if (orientation === 'left') {
47
+ return (_jsx(ChevronLeftIcon, { className: cn('size-4', className), ...props }));
48
+ }
49
+ if (orientation === 'right') {
50
+ return (_jsx(ChevronRightIcon, { className: cn('size-4', className), ...props }));
51
+ }
52
+ return (_jsx(ChevronDownIcon, { className: cn('size-4', className), ...props }));
53
+ },
54
+ DayButton: CalendarDayButton,
55
+ WeekNumber: ({ children, ...props }) => {
56
+ return (_jsx("td", { ...props, children: _jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children: children }) }));
57
+ },
58
+ ...components,
59
+ }, ...props }));
60
+ }
61
+ function CalendarDayButton({ className, day, modifiers, ...props }) {
62
+ const defaultClassNames = getDefaultClassNames();
63
+ const ref = React.useRef(null);
64
+ React.useEffect(() => {
65
+ if (modifiers.focused)
66
+ ref.current?.focus();
67
+ }, [modifiers.focused]);
68
+ return (_jsx(Button, { ref: ref, variant: "ghost", size: "icon", "data-day": day.date.toLocaleDateString(), "data-selected-single": modifiers.selected &&
69
+ !modifiers.range_start &&
70
+ !modifiers.range_end &&
71
+ !modifiers.range_middle, "data-range-start": modifiers.range_start, "data-range-end": modifiers.range_end, "data-range-middle": modifiers.range_middle, className: cn('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 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70', defaultClassNames.day, className), ...props }));
72
+ }
73
+ export { Calendar, CalendarDayButton };
@@ -0,0 +1,24 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ import { Label } from '../../components/ui/label.js';
3
+ declare function FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>): import("react/jsx-runtime").JSX.Element;
4
+ declare function FieldLegend({ className, variant, ...props }: React.ComponentProps<'legend'> & {
5
+ variant?: 'legend' | 'label';
6
+ }): import("react/jsx-runtime").JSX.Element;
7
+ declare function FieldGroup({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
8
+ declare const fieldVariants: (props?: ({
9
+ orientation?: "horizontal" | "vertical" | "responsive" | null | undefined;
10
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
11
+ declare function Field({ className, orientation, ...props }: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>): import("react/jsx-runtime").JSX.Element;
12
+ declare function FieldContent({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
13
+ declare function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>): import("react/jsx-runtime").JSX.Element;
14
+ declare function FieldTitle({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
15
+ declare function FieldDescription({ className, ...props }: React.ComponentProps<'p'>): import("react/jsx-runtime").JSX.Element;
16
+ declare function FieldSeparator({ children, className, ...props }: React.ComponentProps<'div'> & {
17
+ children?: React.ReactNode;
18
+ }): import("react/jsx-runtime").JSX.Element;
19
+ declare function FieldError({ className, children, errors, ...props }: React.ComponentProps<'div'> & {
20
+ errors?: Array<{
21
+ message?: string;
22
+ } | undefined>;
23
+ }): import("react/jsx-runtime").JSX.Element | null;
24
+ export { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle, };
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from '../../utils/utils.js';
5
+ import { Label } from '../../components/ui/label.js';
6
+ import { Separator } from '../../components/ui/separator.js';
7
+ function FieldSet({ className, ...props }) {
8
+ return (_jsx("fieldset", { "data-slot": "field-set", className: cn('flex flex-col gap-6', 'has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3', className), ...props }));
9
+ }
10
+ function FieldLegend({ className, variant = 'legend', ...props }) {
11
+ return (_jsx("legend", { "data-slot": "field-legend", "data-variant": variant, className: cn('mb-3 font-medium', 'data-[variant=legend]:text-base', 'data-[variant=label]:text-sm', className), ...props }));
12
+ }
13
+ function FieldGroup({ className, ...props }) {
14
+ return (_jsx("div", { "data-slot": "field-group", className: cn('group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4', className), ...props }));
15
+ }
16
+ const fieldVariants = cva('group/field flex w-full gap-3 data-[invalid=true]:text-destructive', {
17
+ variants: {
18
+ orientation: {
19
+ vertical: ['flex-col [&>*]:w-full [&>.sr-only]:w-auto'],
20
+ horizontal: [
21
+ 'flex-row items-center',
22
+ '[&>[data-slot=field-label]]:flex-auto',
23
+ 'has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
24
+ ],
25
+ responsive: [
26
+ 'flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto',
27
+ '@md/field-group:[&>[data-slot=field-label]]:flex-auto',
28
+ '@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
29
+ ],
30
+ },
31
+ },
32
+ defaultVariants: {
33
+ orientation: 'vertical',
34
+ },
35
+ });
36
+ function Field({ className, orientation = 'vertical', ...props }) {
37
+ return (_jsx("div", { role: "group", "data-slot": "field", "data-orientation": orientation, className: cn(fieldVariants({ orientation }), className), ...props }));
38
+ }
39
+ function FieldContent({ className, ...props }) {
40
+ return (_jsx("div", { "data-slot": "field-content", className: cn('group/field-content flex flex-1 flex-col gap-1.5 leading-snug', className), ...props }));
41
+ }
42
+ function FieldLabel({ className, ...props }) {
43
+ return (_jsx(Label, { "data-slot": "field-label", className: cn('group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50', 'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4', 'has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10', className), ...props }));
44
+ }
45
+ function FieldTitle({ className, ...props }) {
46
+ return (_jsx("div", { "data-slot": "field-label", className: cn('flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50', className), ...props }));
47
+ }
48
+ function FieldDescription({ className, ...props }) {
49
+ return (_jsx("p", { "data-slot": "field-description", className: cn('text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance', 'last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5', '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4', className), ...props }));
50
+ }
51
+ function FieldSeparator({ children, className, ...props }) {
52
+ return (_jsxs("div", { "data-slot": "field-separator", "data-content": !!children, className: cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className), ...props, children: [_jsx(Separator, { className: "absolute inset-0 top-1/2" }), children && (_jsx("span", { className: "bg-background text-muted-foreground relative mx-auto block w-fit px-2", "data-slot": "field-separator-content", children: children }))] }));
53
+ }
54
+ function FieldError({ className, children, errors, ...props }) {
55
+ const content = useMemo(() => {
56
+ if (children) {
57
+ return children;
58
+ }
59
+ if (!errors?.length) {
60
+ return null;
61
+ }
62
+ const uniqueErrors = [
63
+ ...new Map(errors.map((error) => [error?.message, error])).values(),
64
+ ];
65
+ if (uniqueErrors?.length == 1) {
66
+ return uniqueErrors[0]?.message;
67
+ }
68
+ return (_jsx("ul", { className: "ml-4 flex list-disc flex-col gap-1", children: uniqueErrors.map((error, index) => error?.message && _jsx("li", { children: error.message }, index)) }));
69
+ }, [children, errors]);
70
+ if (!content) {
71
+ return null;
72
+ }
73
+ return (_jsx("div", { role: "alert", "data-slot": "field-error", className: cn('text-destructive text-sm font-normal', className), ...props, children: content }));
74
+ }
75
+ export { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle, };
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
3
+ declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
+ declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
5
+ declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
6
+ declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): import("react/jsx-runtime").JSX.Element;
7
+ export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
3
+ import { cn } from '../../utils/utils.js';
4
+ function Popover({ ...props }) {
5
+ return _jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
6
+ }
7
+ function PopoverTrigger({ ...props }) {
8
+ return _jsx(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
9
+ }
10
+ function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }) {
11
+ return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn('bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden', className), ...props }) }));
12
+ }
13
+ function PopoverAnchor({ ...props }) {
14
+ return _jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
15
+ }
16
+ export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
@@ -0,0 +1,2 @@
1
+ declare function Spinner({ className, ...props }: React.ComponentProps<'svg'>): import("react/jsx-runtime").JSX.Element;
2
+ export { Spinner };
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Loader2Icon } from 'lucide-react';
3
+ import { cn } from '../../utils/utils.js';
4
+ function Spinner({ className, ...props }) {
5
+ return (_jsx(Loader2Icon, { role: "status", "aria-label": "Loading", className: cn('size-4 animate-spin', className), ...props }));
6
+ }
7
+ export { Spinner };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minutemailer/kit",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Minutemailer UI Kit",
5
5
  "license": "MIT",
6
6
  "author": "Minutemailer",
@@ -22,8 +22,8 @@
22
22
  "react-dom": "^19.0.0 || ^18.0.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@storybook/addon-docs": "^9.1.10",
26
- "@storybook/react-vite": "^9.1.10",
25
+ "@storybook/addon-docs": "^10.0.2",
26
+ "@storybook/react-vite": "^10.0.2",
27
27
  "@svgr/cli": "^8.1.0",
28
28
  "@types/react": "^19.2.0",
29
29
  "@types/react-dom": "^19.2.0",
@@ -33,7 +33,7 @@
33
33
  "react-dom": "^19.2.0",
34
34
  "sass": "^1.93.2",
35
35
  "shadcn": "^3.3.1",
36
- "storybook": "^9.1.10",
36
+ "storybook": "^10.0.2",
37
37
  "tsc-alias": "^1.8.16",
38
38
  "typedoc": "^0.28.13",
39
39
  "typedoc-material-theme": "^1.4.0",
@@ -47,14 +47,17 @@
47
47
  "@radix-ui/react-dialog": "^1.1.15",
48
48
  "@radix-ui/react-dropdown-menu": "^2.1.16",
49
49
  "@radix-ui/react-label": "^2.1.7",
50
+ "@radix-ui/react-popover": "^1.1.15",
50
51
  "@radix-ui/react-separator": "^1.1.7",
51
52
  "@radix-ui/react-slot": "^1.2.3",
52
53
  "@radix-ui/react-tooltip": "^1.2.8",
53
54
  "@tailwindcss/vite": "^4.1.14",
54
55
  "class-variance-authority": "^0.7.1",
55
56
  "clsx": "^2.1.1",
57
+ "date-fns": "^4.1.0",
56
58
  "lucide-react": "^0.544.0",
57
59
  "next-themes": "^0.4.6",
60
+ "react-day-picker": "^9.11.1",
58
61
  "react-hook-form": "^7.63.0",
59
62
  "sonner": "^2.0.7",
60
63
  "tailwind-merge": "^3.3.1",