@minutemailer/kit 1.0.4 → 1.0.6
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/components/ui/alert.js +1 -1
- package/components/ui/avatar.js +1 -1
- package/components/ui/button.js +1 -1
- package/components/ui/checkbox.js +1 -1
- package/components/ui/dropdown-menu.js +1 -1
- package/components/ui/input.js +1 -1
- package/components/ui/label.js +1 -1
- package/components/ui/separator.js +1 -1
- package/components/ui/sheet.js +1 -1
- package/components/ui/sidebar.d.ts +4 -4
- package/components/ui/sidebar.js +8 -8
- package/components/ui/skeleton.js +1 -1
- package/components/ui/tooltip.js +1 -1
- package/icons/index.js +129 -261
- package/package.json +36 -22
- package/state/index.js +52 -64
- package/store/index.js +3 -6
- package/store/useSelector.d.ts +1 -1
- package/utils/index.js +6 -15
- package/components/ui/alert.tsx.js +0 -67
- package/components/ui/alert.tsx.js.map +0 -7
- package/components/ui/avatar.tsx.js +0 -54
- package/components/ui/avatar.tsx.js.map +0 -7
- package/components/ui/button.tsx.js +0 -51
- package/components/ui/button.tsx.js.map +0 -7
- package/components/ui/checkbox.tsx.js +0 -33
- package/components/ui/checkbox.tsx.js.map +0 -7
- package/components/ui/dropdown-menu.tsx.js +0 -244
- package/components/ui/dropdown-menu.tsx.js.map +0 -7
- package/components/ui/input.tsx.js +0 -22
- package/components/ui/input.tsx.js.map +0 -7
- package/components/ui/label.tsx.js +0 -24
- package/components/ui/label.tsx.js.map +0 -7
- package/components/ui/separator.tsx.js +0 -27
- package/components/ui/separator.tsx.js.map +0 -7
- package/components/ui/sheet.tsx.js +0 -128
- package/components/ui/sheet.tsx.js.map +0 -7
- package/components/ui/sidebar.tsx.js +0 -668
- package/components/ui/sidebar.tsx.js.map +0 -7
- package/components/ui/skeleton.tsx.js +0 -16
- package/components/ui/skeleton.tsx.js.map +0 -7
- package/components/ui/sonner.tsx.js +0 -23
- package/components/ui/sonner.tsx.js.map +0 -7
- package/components/ui/tooltip.tsx.js +0 -56
- package/components/ui/tooltip.tsx.js.map +0 -7
- package/icons/index.js.map +0 -7
- package/state/index.js.map +0 -7
- package/state/index.test.d.ts +0 -1
- package/state/index.test.js +0 -126
- package/store/index.js.map +0 -7
- package/store/store.test.d.ts +0 -12
- package/store/store.test.js +0 -51
- package/stories/Alert.stories.d.ts +0 -12
- package/stories/Alert.stories.js +0 -29
- package/stories/Button.stories.d.ts +0 -17
- package/stories/Button.stories.js +0 -61
- package/stories/Checkbox.stories.d.ts +0 -14
- package/stories/Checkbox.stories.js +0 -37
- package/stories/Input.stories.d.ts +0 -14
- package/stories/Input.stories.js +0 -31
- package/stories/Label.stories.d.ts +0 -9
- package/stories/Label.stories.js +0 -12
- package/stories/Separator.stories.d.ts +0 -10
- package/stories/Separator.stories.js +0 -13
- package/stories/Sidebar.stories.d.ts +0 -9
- package/stories/Sidebar.stories.js +0 -53
- package/stories/Skeleton.stories.d.ts +0 -9
- package/stories/Skeleton.stories.js +0 -10
- package/stories/Sonner.stories.d.ts +0 -11
- package/stories/Sonner.stories.js +0 -22
- package/stories/Todo.d.ts +0 -1
- package/stories/Todo.js +0 -75
- package/stories/Tooltip.stories.d.ts +0 -9
- package/stories/Tooltip.stories.js +0 -11
- package/stories/TrafficLights.d.ts +0 -3
- package/stories/TrafficLights.js +0 -37
- package/utils/capitalize/index.test.d.ts +0 -1
- package/utils/capitalize/index.test.js +0 -10
- package/utils/choice/index.test.d.ts +0 -1
- package/utils/choice/index.test.js +0 -21
- package/utils/index.js.map +0 -7
- package/utils/objToQuery/index.test.d.ts +0 -1
- package/utils/objToQuery/index.test.js +0 -17
- package/utils/replacePlaceholders/index.test.d.ts +0 -1
- package/utils/replacePlaceholders/index.test.js +0 -19
- package/utils/strToDate/index.test.d.ts +0 -1
- package/utils/strToDate/index.test.js +0 -45
- package/utils/zeroPad/index.test.d.ts +0 -1
- package/utils/zeroPad/index.test.js +0 -12
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { Checkbox } from '@/components/ui/checkbox';
|
|
4
|
-
import { Label } from '@/components/ui/label';
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'WIP/Checkbox',
|
|
7
|
-
component: Checkbox,
|
|
8
|
-
};
|
|
9
|
-
export default meta;
|
|
10
|
-
export const Default = {
|
|
11
|
-
args: {},
|
|
12
|
-
};
|
|
13
|
-
export const Checked = {
|
|
14
|
-
args: {
|
|
15
|
-
defaultChecked: true,
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
export const Disabled = {
|
|
19
|
-
args: {
|
|
20
|
-
disabled: true,
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
export const DisabledChecked = {
|
|
24
|
-
args: {
|
|
25
|
-
disabled: true,
|
|
26
|
-
defaultChecked: true,
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
export const WithLabel = {
|
|
30
|
-
render: (args) => (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Checkbox, { ...args, id: "terms" }), _jsx(Label, { htmlFor: "terms", children: "Accept terms and conditions" })] })),
|
|
31
|
-
};
|
|
32
|
-
export const Controlled = {
|
|
33
|
-
render: (args) => {
|
|
34
|
-
const [checked, setChecked] = React.useState(false);
|
|
35
|
-
return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Checkbox, { ...args, checked: checked, onCheckedChange: (v) => setChecked(Boolean(v)), "aria-label": checked ? 'Checked' : 'Unchecked', id: "controlled" }), _jsx(Label, { htmlFor: "controlled", children: checked ? 'Checked' : 'Unchecked' })] }));
|
|
36
|
-
},
|
|
37
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Input } from '@/components/ui/input';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Input;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
|
10
|
-
export declare const Disabled: Story;
|
|
11
|
-
export declare const File: Story;
|
|
12
|
-
export declare const WithPlaceholder: Story;
|
|
13
|
-
export declare const WithLabel: Story;
|
|
14
|
-
export declare const WithButton: Story;
|
package/stories/Input.stories.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Label } from '@/components/ui/label';
|
|
3
|
-
import { Input } from '@/components/ui/input';
|
|
4
|
-
import { Button } from '@/components/ui/button';
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'WIP/Input',
|
|
7
|
-
component: Input,
|
|
8
|
-
};
|
|
9
|
-
export default meta;
|
|
10
|
-
export const Default = {
|
|
11
|
-
args: {},
|
|
12
|
-
};
|
|
13
|
-
export const Disabled = {
|
|
14
|
-
args: {
|
|
15
|
-
disabled: true,
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
export const File = {
|
|
19
|
-
render: (args) => (_jsxs("div", { className: "grid w-full max-w-sm items-center gap-3", children: [_jsx(Label, { htmlFor: "picture", children: "Picture" }), _jsx(Input, { ...args, type: "file", id: "picture" })] })),
|
|
20
|
-
};
|
|
21
|
-
export const WithPlaceholder = {
|
|
22
|
-
args: {
|
|
23
|
-
placeholder: 'Type something...',
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
export const WithLabel = {
|
|
27
|
-
render: (args) => (_jsxs("div", { className: "grid w-full max-w-sm items-center gap-3", children: [_jsx(Label, { htmlFor: "email", children: "Email" }), _jsx(Input, { ...args, id: "email" })] })),
|
|
28
|
-
};
|
|
29
|
-
export const WithButton = {
|
|
30
|
-
render: (args) => (_jsxs("div", { className: "flex w-full max-w-sm items-center gap-2", children: [_jsx(Input, { type: "email", placeholder: "Email" }), _jsx(Button, { type: "button", variant: "outline", children: "Subscribe" })] })),
|
|
31
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Label } from '@/components/ui/label';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Label;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
package/stories/Label.stories.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Separator } from '@/components/ui/separator';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Separator;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
|
10
|
-
export declare const Vertical: Story;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Separator } from '@/components/ui/separator';
|
|
3
|
-
const meta = {
|
|
4
|
-
title: 'WIP/Separator',
|
|
5
|
-
component: Separator,
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
export const Default = {
|
|
9
|
-
args: {},
|
|
10
|
-
};
|
|
11
|
-
export const Vertical = {
|
|
12
|
-
render: (args) => (_jsx("div", { className: "h-10", children: _jsx(Separator, { orientation: "vertical", ...args }) })),
|
|
13
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Sidebar } from '@/components/ui/sidebar';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Sidebar;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, useSidebar, } from '@/components/ui/sidebar';
|
|
3
|
-
import { BadgeCheck, Bell, ChartPie, ChevronsUpDown, Command, Contact, CreditCard, House, LogOut, SidebarIcon, Sparkles, } from 'lucide-react';
|
|
4
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu';
|
|
5
|
-
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
6
|
-
import { Separator } from '@/components/ui/separator';
|
|
7
|
-
import { Button } from '@/components/ui/button';
|
|
8
|
-
const meta = {
|
|
9
|
-
title: 'WIP/Sidebar',
|
|
10
|
-
component: Sidebar,
|
|
11
|
-
};
|
|
12
|
-
export default meta;
|
|
13
|
-
const data = {
|
|
14
|
-
user: {
|
|
15
|
-
name: 'Oskar Glauser',
|
|
16
|
-
email: 'oskar@minutemailer.com',
|
|
17
|
-
avatar: 'https://www.gravatar.com/avatar/5e05baf3b97434b88ab1a4f5f00bf241?s=300&d=https%3A%2F%2Fui-avatars.com%2Fapi%2FOskar%2BGlauser%2F300%2Fe3504e%2Ffff',
|
|
18
|
-
},
|
|
19
|
-
projects: [
|
|
20
|
-
{
|
|
21
|
-
name: 'Dashboard',
|
|
22
|
-
url: '#',
|
|
23
|
-
icon: House,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
name: 'Contacts',
|
|
27
|
-
url: '#',
|
|
28
|
-
icon: Contact,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'Results',
|
|
32
|
-
url: '#',
|
|
33
|
-
icon: ChartPie,
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
};
|
|
37
|
-
function NavMain({ items, }) {
|
|
38
|
-
return (_jsx(SidebarGroup, { className: "group-data-[collapsible=icon]:sm", children: _jsx(SidebarMenu, { children: items.map((item) => (_jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { asChild: true, children: _jsxs("a", { href: item.url, children: [_jsx(item.icon, {}), _jsx("span", { children: item.name })] }) }) }, item.name))) }) }));
|
|
39
|
-
}
|
|
40
|
-
function NavUser({ user, }) {
|
|
41
|
-
const { isMobile } = useSidebar();
|
|
42
|
-
return (_jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(SidebarMenuButton, { size: "lg", className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground", children: [_jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [_jsx(AvatarImage, { src: user.avatar, alt: user.name }), _jsx(AvatarFallback, { className: "rounded-lg", children: "CN" })] }), _jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [_jsx("span", { className: "truncate font-medium", children: user.name }), _jsx("span", { className: "truncate text-xs", children: user.email })] }), _jsx(ChevronsUpDown, { className: "ml-auto size-4" })] }) }), _jsxs(DropdownMenuContent, { className: "w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg", side: isMobile ? 'bottom' : 'right', align: "end", sideOffset: 4, children: [_jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: _jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [_jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [_jsx(AvatarImage, { src: user.avatar, alt: user.name }), _jsx(AvatarFallback, { className: "rounded-lg", children: "CN" })] }), _jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [_jsx("span", { className: "truncate font-medium", children: user.name }), _jsx("span", { className: "truncate text-xs", children: user.email })] })] }) }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: _jsxs(DropdownMenuItem, { children: [_jsx(Sparkles, {}), "Upgrade to Pro"] }) }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuGroup, { children: [_jsxs(DropdownMenuItem, { children: [_jsx(BadgeCheck, {}), "Account"] }), _jsxs(DropdownMenuItem, { children: [_jsx(CreditCard, {}), "Billing"] }), _jsxs(DropdownMenuItem, { children: [_jsx(Bell, {}), "Notifications"] })] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { children: [_jsx(LogOut, {}), "Log out"] })] })] }) }) }));
|
|
43
|
-
}
|
|
44
|
-
function AppSidebar({ ...props }) {
|
|
45
|
-
return (_jsxs(Sidebar, { collapsible: "icon", className: "top-(--header-height) h-[calc(100svh-var(--header-height))]!", ...props, children: [_jsx(SidebarHeader, { children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { size: "lg", asChild: true, children: _jsxs("a", { href: "#", children: [_jsx("div", { className: "bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg", children: _jsx(Command, { className: "size-4" }) }), _jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [_jsx("span", { className: "truncate font-medium", children: "Minutemailer" }), _jsx("span", { className: "truncate text-xs", children: "Enterprise" })] })] }) }) }) }) }), _jsx(SidebarContent, { children: _jsx(NavMain, { items: data.projects }) }), _jsx(SidebarFooter, { children: _jsx(NavUser, { user: data.user }) })] }));
|
|
46
|
-
}
|
|
47
|
-
function SiteHeader() {
|
|
48
|
-
const { toggleSidebar } = useSidebar();
|
|
49
|
-
return (_jsx("header", { className: "bg-card sticky top-0 z-50 flex w-full items-center border-b", children: _jsxs("div", { className: "flex h-(--header-height) w-full items-center gap-2 px-4", children: [_jsx(Button, { className: "h-8 w-8", variant: "ghost", size: "icon", onClick: toggleSidebar, children: _jsx(SidebarIcon, {}) }), _jsx(Separator, { orientation: "vertical", className: "mr-2 h-4" })] }) }));
|
|
50
|
-
}
|
|
51
|
-
export const Default = {
|
|
52
|
-
render: (args) => (_jsx("div", { className: "fixed inset-0", children: _jsx("div", { className: "[--header-height:calc(--spacing(14))]", children: _jsxs(SidebarProvider, { className: "flex flex-col", children: [_jsx(SiteHeader, {}), _jsxs("div", { className: "flex flex-1", children: [_jsx(AppSidebar, {}), _jsx(SidebarInset, { children: _jsx("div", { className: "p-8 flex flex-1 flex-col gap-4", children: _jsxs("div", { className: "bg-white flex flex-1 flex-col gap-4 p-4", children: [_jsxs("div", { className: "grid auto-rows-min gap-4 md:grid-cols-3", children: [_jsx("div", { className: "bg-muted/50 aspect-video rounded-xl" }), _jsx("div", { className: "bg-muted/50 aspect-video rounded-xl" }), _jsx("div", { className: "bg-muted/50 aspect-video rounded-xl" })] }), _jsx("div", { className: "bg-muted/50 min-h-[100vh] flex-1 rounded-xl md:min-h-min" })] }) }) })] })] }) }) })),
|
|
53
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Skeleton } from '@/components/ui/skeleton';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Skeleton;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Skeleton } from '@/components/ui/skeleton';
|
|
3
|
-
const meta = {
|
|
4
|
-
title: 'WIP/Skeleton',
|
|
5
|
-
component: Skeleton,
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
export const Default = {
|
|
9
|
-
render: (args) => (_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx(Skeleton, { className: "h-12 w-12 rounded-full" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-[250px]" }), _jsx(Skeleton, { className: "h-4 w-[200px]" })] })] })),
|
|
10
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
declare const meta: {
|
|
3
|
-
title: string;
|
|
4
|
-
component: ({ ...props }: import("sonner").ToasterProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
parameters: {
|
|
6
|
-
layout: string;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
export default meta;
|
|
10
|
-
type Story = StoryObj<typeof meta>;
|
|
11
|
-
export declare const Playground: Story;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Toaster } from '@/components/ui/sonner';
|
|
3
|
-
import { toast } from 'sonner';
|
|
4
|
-
import { Button } from '@/components/ui/button';
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'WIP/Toast',
|
|
7
|
-
component: Toaster,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: 'centered',
|
|
10
|
-
},
|
|
11
|
-
};
|
|
12
|
-
export default meta;
|
|
13
|
-
function Demo() {
|
|
14
|
-
return (_jsx("div", { className: "flex flex-col gap-3", children: _jsxs("div", { className: "flex gap-3 flex-wrap", children: [_jsx(Button, { variant: "outline", onClick: () => toast('This is a toast'), children: "Show toast" }), _jsx(Button, { variant: "outline", onClick: () => toast.success('Everything went well!'), children: "Success" }), _jsx(Button, { variant: "outline", onClick: () => toast.error('Something went wrong'), children: "Error" }), _jsx(Button, { variant: "outline", onClick: () => toast.promise(new Promise((res) => setTimeout(res, 1500)), {
|
|
15
|
-
loading: 'Saving…',
|
|
16
|
-
success: 'Saved!',
|
|
17
|
-
error: 'Could not save',
|
|
18
|
-
}), children: "Promise" })] }) }));
|
|
19
|
-
}
|
|
20
|
-
export const Playground = {
|
|
21
|
-
render: () => _jsx(Demo, {}),
|
|
22
|
-
};
|
package/stories/Todo.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function Todo(): import("react/jsx-runtime").JSX.Element;
|
package/stories/Todo.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { createStore, useSelector } from '@/store';
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
const initialState = {
|
|
5
|
-
todos: [],
|
|
6
|
-
completed: 0,
|
|
7
|
-
total: 0,
|
|
8
|
-
};
|
|
9
|
-
const uniqueId = () => Math.random().toString(36).substring(2, 15);
|
|
10
|
-
const reducer = (state, action) => {
|
|
11
|
-
if (action.type === 'ADD_TODO') {
|
|
12
|
-
return {
|
|
13
|
-
...state,
|
|
14
|
-
todos: [
|
|
15
|
-
...state.todos,
|
|
16
|
-
{ id: uniqueId(), text: action.value, completed: false },
|
|
17
|
-
],
|
|
18
|
-
total: state.total + 1,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
if (action.type === 'COMPLETE_TODO') {
|
|
22
|
-
return {
|
|
23
|
-
...state,
|
|
24
|
-
todos: state.todos.map((todo) => todo.id === action.value ? { ...todo, completed: true } : todo),
|
|
25
|
-
completed: state.completed + 1,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
if (action.type === 'UNCOMPLETE_TODO') {
|
|
29
|
-
return {
|
|
30
|
-
...state,
|
|
31
|
-
todos: state.todos.map((todo) => todo.id === action.value ? { ...todo, completed: false } : todo),
|
|
32
|
-
completed: state.completed - 1,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
return state;
|
|
36
|
-
};
|
|
37
|
-
const store = createStore('todos', initialState, reducer, () => true, () => { }, 'todos');
|
|
38
|
-
function Todos() {
|
|
39
|
-
const todos = useSelector(store, (state) => state.todos);
|
|
40
|
-
return (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '1rem' }, children: todos.map((todo) => (_jsx("div", { style: {
|
|
41
|
-
display: 'flex',
|
|
42
|
-
alignItems: 'center',
|
|
43
|
-
gap: '1rem',
|
|
44
|
-
}, children: _jsxs("div", { className: "flex items-center space-x-3", children: [_jsx("button", { type: "button", role: "checkbox", "aria-checked": todo.completed, "data-state": todo.completed ? 'checked' : 'unchecked', value: "on", className: "peer size-5 shrink-0 rounded-sm border border-input ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-accent-foreground", id: "remember", tabIndex: 3, onClick: () => store.dispatch({
|
|
45
|
-
type: !todo.completed
|
|
46
|
-
? 'COMPLETE_TODO'
|
|
47
|
-
: 'UNCOMPLETE_TODO',
|
|
48
|
-
value: todo.id,
|
|
49
|
-
}), children: todo.completed && (_jsx("span", { "data-state": "checked", className: "flex items-center justify-center text-current", style: { pointerEvents: 'none' }, children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", className: "lucide lucide-check size-3.5 stroke-[3]", children: _jsx("path", { d: "M20 6 9 17l-5-5" }) }) })) }), _jsx("input", { "aria-hidden": "true", tabIndex: -1, type: "checkbox", value: "on", style: {
|
|
50
|
-
transform: 'translateX(-100%)',
|
|
51
|
-
position: 'absolute',
|
|
52
|
-
pointerEvents: 'none',
|
|
53
|
-
opacity: 0,
|
|
54
|
-
margin: 0,
|
|
55
|
-
width: '20px',
|
|
56
|
-
height: '20px',
|
|
57
|
-
} }), _jsx("label", { className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", htmlFor: "remember", children: todo.text })] }) }, todo.id))) }));
|
|
58
|
-
}
|
|
59
|
-
function Status() {
|
|
60
|
-
const total = useSelector(store, (state) => state.total);
|
|
61
|
-
const completed = useSelector(store, (state) => state.completed);
|
|
62
|
-
return (_jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: `${completed} / ${total} todos completed` }));
|
|
63
|
-
}
|
|
64
|
-
function Form() {
|
|
65
|
-
const [value, setValue] = useState('');
|
|
66
|
-
function onSubmit(e) {
|
|
67
|
-
e.preventDefault();
|
|
68
|
-
store.dispatch({ type: 'ADD_TODO', value: value });
|
|
69
|
-
setValue('');
|
|
70
|
-
}
|
|
71
|
-
return (_jsxs("form", { onSubmit: onSubmit, className: "flex gap-2 mb-6", children: [_jsx("input", { className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", placeholder: "Add a new todo", value: value, onChange: (e) => setValue(e.target.value) }), _jsx("button", { className: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 h-10 px-4 py-2 bg-black/80 hover:bg-black/70 text-white backdrop-blur-xl", type: "submit", children: "Add" })] }));
|
|
72
|
-
}
|
|
73
|
-
export default function Todo() {
|
|
74
|
-
return (_jsx("div", { children: _jsxs("div", { className: "max-w-md mx-auto p-6 bg-white rounded-lg border", children: [_jsx("h1", { className: "text-2xl font-bold text-center mb-6 sb-unstyled", children: "My Todo List" }), _jsx(Form, {}), _jsx(Todos, {}), _jsx(Status, {})] }) }));
|
|
75
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Tooltip } from '@/components/ui/tooltip';
|
|
3
|
-
declare const meta: {
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Tooltip;
|
|
6
|
-
};
|
|
7
|
-
export default meta;
|
|
8
|
-
type Story = StoryObj<typeof meta>;
|
|
9
|
-
export declare const Default: Story;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip';
|
|
3
|
-
import { Button } from '@/components/ui/button';
|
|
4
|
-
const meta = {
|
|
5
|
-
title: 'WIP/Tooltip',
|
|
6
|
-
component: Tooltip,
|
|
7
|
-
};
|
|
8
|
-
export default meta;
|
|
9
|
-
export const Default = {
|
|
10
|
-
render: (args) => (_jsxs(Tooltip, { ...args, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Hover" }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Add to library" }) })] })),
|
|
11
|
-
};
|
package/stories/TrafficLights.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
3
|
-
import { createMachine } from '@/state';
|
|
4
|
-
// Simple traffic light demo with minimal code
|
|
5
|
-
const SimpleTrafficLight = () => {
|
|
6
|
-
// Define our states, transitions and actions
|
|
7
|
-
const transitions = {
|
|
8
|
-
RED: { on: { NEXT: 'GREEN' } },
|
|
9
|
-
GREEN: { on: { NEXT: 'YELLOW' } },
|
|
10
|
-
YELLOW: { on: { NEXT: 'RED' } },
|
|
11
|
-
};
|
|
12
|
-
const actions = {
|
|
13
|
-
NEXT: (context) => ({
|
|
14
|
-
count: context.count + 1,
|
|
15
|
-
}),
|
|
16
|
-
};
|
|
17
|
-
// Create the machine with minimal context
|
|
18
|
-
const [machine] = useState(() => createMachine(transitions, actions, { count: 0 }, 'RED'));
|
|
19
|
-
// Get current state and count from the machine
|
|
20
|
-
const currentState = machine.useCurrentState();
|
|
21
|
-
const count = machine.useCurrentContext((ctx) => ctx.count);
|
|
22
|
-
// Auto-transition every 1.5 seconds
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
const timer = setTimeout(() => {
|
|
25
|
-
machine.action('NEXT');
|
|
26
|
-
}, 1500);
|
|
27
|
-
return () => clearTimeout(timer);
|
|
28
|
-
}, [currentState, machine]);
|
|
29
|
-
// Color mapping
|
|
30
|
-
const colors = {
|
|
31
|
-
RED: 'bg-rose-500',
|
|
32
|
-
YELLOW: 'bg-amber-400',
|
|
33
|
-
GREEN: 'bg-emerald-500',
|
|
34
|
-
};
|
|
35
|
-
return (_jsxs("div", { className: "flex flex-col items-start p-4", children: [_jsx("div", { className: "bg-gray-800 p-3 rounded-lg mb-4 flex flex-col items-start gap-2", children: Object.entries(colors).map(([state, color]) => (_jsx("div", { className: `w-16 h-16 m-2 rounded-full ${currentState === state ? color : 'bg-gray-300'}` }, state))) }), _jsxs("div", { children: [_jsxs("p", { children: ["Current: ", _jsx("strong", { children: currentState })] }), _jsxs("p", { children: ["Cycles: ", count] }), _jsx("button", { onClick: () => machine.action('NEXT'), className: "mt-2 bg-blue-500 text-white px-4 py-2 rounded", children: "Next State" })] })] }));
|
|
36
|
-
};
|
|
37
|
-
export default SimpleTrafficLight;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import capitalize from './index';
|
|
3
|
-
test('capitalize returns string', () => {
|
|
4
|
-
assert.isString(capitalize('foo'));
|
|
5
|
-
});
|
|
6
|
-
test('capitalize returns capitalized string', () => {
|
|
7
|
-
assert.equal(capitalize('foo'), 'Foo');
|
|
8
|
-
assert.equal(capitalize('foo bar'), 'Foo bar');
|
|
9
|
-
assert.equal(capitalize('foo bar baz'), 'Foo bar baz');
|
|
10
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import choice from './index';
|
|
3
|
-
test('No processing if no value is given', () => {
|
|
4
|
-
assert.equal(choice('foo'), 'foo');
|
|
5
|
-
assert.equal(choice('foo|bar'), 'foo|bar');
|
|
6
|
-
assert.equal(choice('{0} foo|{1} bar'), '{0} foo|{1} bar');
|
|
7
|
-
});
|
|
8
|
-
test('No processing if no pipes are given', () => {
|
|
9
|
-
assert.equal(choice('foo', 1), 'foo');
|
|
10
|
-
assert.equal(choice('foo', 2), 'foo');
|
|
11
|
-
});
|
|
12
|
-
test('Singular and plural', () => {
|
|
13
|
-
assert.equal(choice('person|people', 1), 'person');
|
|
14
|
-
assert.equal(choice('person|people', 2), 'people');
|
|
15
|
-
});
|
|
16
|
-
test('Match specific values with brackets', () => {
|
|
17
|
-
assert.equal(choice('[0] none|[1] person|[2,Inf] people', 0), 'none');
|
|
18
|
-
assert.equal(choice('[0] none|[1] person|[2,Inf] people', 1), 'person');
|
|
19
|
-
assert.equal(choice('[0] none|[1] person|[2,Inf] people', 2), 'people');
|
|
20
|
-
assert.equal(choice('[0] none|[1] person|[2,Inf] people', 3), 'people');
|
|
21
|
-
});
|
package/utils/index.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/utils/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { default as strToDate } from './strToDate';\nexport { default as zeroPad } from './zeroPad';\nexport { default as replacePlaceholders } from './replacePlaceholders';\nexport { default as choice } from './choice';\nexport { default as capitalize } from './capitalize';\nexport { default as objToQuery } from './objToQuery';\n"],
|
|
5
|
-
"mappings": "AAAA,SAAoB,WAAXA,gBAA4B;AACrC,SAAoB,WAAXA,gBAA0B;AACnC,SAAoB,WAAXA,gBAAsC;AAC/C,SAAoB,WAAXA,gBAAyB;AAClC,SAAoB,WAAXA,gBAA6B;AACtC,SAAoB,WAAXA,gBAA6B;",
|
|
6
|
-
"names": ["default"]
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import objToQuery from './index';
|
|
3
|
-
test('Returns string', () => {
|
|
4
|
-
assert.isString(objToQuery({}));
|
|
5
|
-
});
|
|
6
|
-
test('Returns query string', () => {
|
|
7
|
-
assert.equal(objToQuery({ foo: 'bar' }), 'foo=bar');
|
|
8
|
-
});
|
|
9
|
-
test('Returns query string with multiple params', () => {
|
|
10
|
-
assert.equal(objToQuery({ foo: 'bar', baz: 'qux' }), 'foo=bar&baz=qux');
|
|
11
|
-
});
|
|
12
|
-
test('Returns query string with multiple params and array values', () => {
|
|
13
|
-
assert.equal(objToQuery({ foo: 'bar', baz: ['qux', 'quux'] }), 'foo=bar&baz[]=qux&baz[]=quux');
|
|
14
|
-
});
|
|
15
|
-
test('Handles nested objects', () => {
|
|
16
|
-
assert.equal(objToQuery({ foo: 'bar', baz: { qux: 'quux' } }), 'foo=bar&baz[qux]=quux');
|
|
17
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import replacePlaceholders from './index';
|
|
3
|
-
test('Returns string', () => {
|
|
4
|
-
assert.isString(replacePlaceholders('foo', {}));
|
|
5
|
-
});
|
|
6
|
-
test('Can replace placeholders', () => {
|
|
7
|
-
assert.equal(replacePlaceholders('Hi :name', { name: 'Jane Doe' }), 'Hi Jane Doe');
|
|
8
|
-
});
|
|
9
|
-
test('Can replace multiple placeholders', () => {
|
|
10
|
-
assert.equal(replacePlaceholders('Hi :name, your age is :age', {
|
|
11
|
-
name: 'Jane Doe',
|
|
12
|
-
age: 42,
|
|
13
|
-
}), 'Hi Jane Doe, your age is 42');
|
|
14
|
-
});
|
|
15
|
-
test('Can replace multiple placeholders with same name', () => {
|
|
16
|
-
assert.equal(replacePlaceholders('Hi :name, is your name :name?', {
|
|
17
|
-
name: 'Jane Doe',
|
|
18
|
-
}), 'Hi Jane Doe, is your name Jane Doe?');
|
|
19
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import strToDate from './index';
|
|
3
|
-
test('strToDate returns Date for Date', () => {
|
|
4
|
-
assert.instanceOf(strToDate(new Date()), Date);
|
|
5
|
-
const date = new Date();
|
|
6
|
-
assert.equal(strToDate(date), date);
|
|
7
|
-
});
|
|
8
|
-
test('strToDate returns Date for all formats', () => {
|
|
9
|
-
assert.instanceOf(strToDate('2020-01-01'), Date);
|
|
10
|
-
assert.instanceOf(strToDate('2020-01-01 00:00:00'), Date);
|
|
11
|
-
assert.instanceOf(strToDate('2020-01-01T00:00:00'), Date);
|
|
12
|
-
assert.instanceOf(strToDate('2020-01-01T00:00:00Z'), Date);
|
|
13
|
-
assert.instanceOf(strToDate('2020-01-01T00:00:00+00:00'), Date);
|
|
14
|
-
});
|
|
15
|
-
test('strToDate returns null for invalid input', () => {
|
|
16
|
-
assert.isNull(strToDate());
|
|
17
|
-
assert.isNull(strToDate(null));
|
|
18
|
-
assert.isNull(strToDate(1));
|
|
19
|
-
assert.isNull(strToDate({}));
|
|
20
|
-
assert.isNull(strToDate([]));
|
|
21
|
-
assert.isNull(strToDate(''));
|
|
22
|
-
assert.isNull(strToDate('2020-01-01T00:00:00+00:00+00:00'));
|
|
23
|
-
assert.isNull(strToDate('2020-01-01 20:00:00+00:00+00:00'));
|
|
24
|
-
});
|
|
25
|
-
test('strToDate returns correct date', () => {
|
|
26
|
-
const date = strToDate('2020-01-01');
|
|
27
|
-
if (!date) {
|
|
28
|
-
throw new Error('Date is null');
|
|
29
|
-
}
|
|
30
|
-
assert.equal(date.getFullYear(), 2020);
|
|
31
|
-
assert.equal(date.getMonth(), 0);
|
|
32
|
-
assert.equal(date.getDate(), 1);
|
|
33
|
-
});
|
|
34
|
-
test('strToDate returns correct date and time', () => {
|
|
35
|
-
const date = strToDate('2020-01-01 20:00:00');
|
|
36
|
-
if (!date) {
|
|
37
|
-
throw new Error('Date is null');
|
|
38
|
-
}
|
|
39
|
-
assert.equal(date.getFullYear(), 2020);
|
|
40
|
-
assert.equal(date.getMonth(), 0);
|
|
41
|
-
assert.equal(date.getDate(), 1);
|
|
42
|
-
assert.equal(date.getHours(), 20);
|
|
43
|
-
assert.equal(date.getMinutes(), 0);
|
|
44
|
-
assert.equal(date.getSeconds(), 0);
|
|
45
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import zeroPad from './index';
|
|
3
|
-
test('zeroPad returns string', () => {
|
|
4
|
-
assert.isString(zeroPad(1));
|
|
5
|
-
});
|
|
6
|
-
test('zeroPad returns correct string', () => {
|
|
7
|
-
assert.equal(zeroPad(1), '01');
|
|
8
|
-
assert.equal(zeroPad(1, 3), '001');
|
|
9
|
-
assert.equal(zeroPad(1, 1), '1');
|
|
10
|
-
assert.equal(zeroPad(1, 0), '1');
|
|
11
|
-
assert.equal(zeroPad(1, -1), '1');
|
|
12
|
-
});
|