@emara/ui 1.1.0
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/.gitkeep +0 -0
- package/components/ui/accordion.stories.tsx +231 -0
- package/components/ui/accordion.tsx +250 -0
- package/components/ui/app-shell.stories.tsx +270 -0
- package/components/ui/app-shell.tsx +491 -0
- package/components/ui/avatar.stories.tsx +174 -0
- package/components/ui/avatar.tsx +257 -0
- package/components/ui/badge.stories.tsx +127 -0
- package/components/ui/badge.tsx +146 -0
- package/components/ui/breadcrumb.stories.tsx +92 -0
- package/components/ui/breadcrumb.tsx +302 -0
- package/components/ui/button.stories.tsx +186 -0
- package/components/ui/button.tsx +128 -0
- package/components/ui/card.stories.tsx +279 -0
- package/components/ui/card.tsx +250 -0
- package/components/ui/checkbox.stories.tsx +93 -0
- package/components/ui/checkbox.tsx +131 -0
- package/components/ui/combobox.stories.tsx +489 -0
- package/components/ui/combobox.tsx +874 -0
- package/components/ui/context-menu.stories.tsx +202 -0
- package/components/ui/context-menu.tsx +309 -0
- package/components/ui/data-table.stories.tsx +227 -0
- package/components/ui/data-table.tsx +539 -0
- package/components/ui/date-picker.stories.tsx +225 -0
- package/components/ui/date-picker.tsx +597 -0
- package/components/ui/dialog.stories.tsx +193 -0
- package/components/ui/dialog.tsx +262 -0
- package/components/ui/divider.stories.tsx +84 -0
- package/components/ui/divider.tsx +135 -0
- package/components/ui/drawer.stories.tsx +218 -0
- package/components/ui/drawer.tsx +329 -0
- package/components/ui/dropdown-menu.stories.tsx +270 -0
- package/components/ui/dropdown-menu.tsx +353 -0
- package/components/ui/empty-state.stories.tsx +121 -0
- package/components/ui/empty-state.tsx +289 -0
- package/components/ui/field-group.stories.tsx +201 -0
- package/components/ui/field-group.tsx +276 -0
- package/components/ui/form.stories.tsx +219 -0
- package/components/ui/form.tsx +542 -0
- package/components/ui/input.stories.tsx +154 -0
- package/components/ui/input.tsx +208 -0
- package/components/ui/label.stories.tsx +84 -0
- package/components/ui/label.tsx +98 -0
- package/components/ui/page-header.stories.tsx +136 -0
- package/components/ui/page-header.tsx +315 -0
- package/components/ui/pagination.stories.tsx +136 -0
- package/components/ui/pagination.tsx +427 -0
- package/components/ui/popover.stories.tsx +212 -0
- package/components/ui/popover.tsx +167 -0
- package/components/ui/radio-group.stories.tsx +96 -0
- package/components/ui/radio-group.tsx +250 -0
- package/components/ui/select.stories.tsx +203 -0
- package/components/ui/select.tsx +318 -0
- package/components/ui/sidebar.stories.tsx +186 -0
- package/components/ui/sidebar.tsx +623 -0
- package/components/ui/skeleton.stories.tsx +131 -0
- package/components/ui/skeleton.tsx +311 -0
- package/components/ui/switch.stories.tsx +74 -0
- package/components/ui/switch.tsx +186 -0
- package/components/ui/table.stories.tsx +107 -0
- package/components/ui/table.tsx +285 -0
- package/components/ui/tabs.stories.tsx +222 -0
- package/components/ui/tabs.tsx +287 -0
- package/components/ui/textarea.stories.tsx +96 -0
- package/components/ui/textarea.tsx +182 -0
- package/components/ui/toast.stories.tsx +169 -0
- package/components/ui/toast.tsx +250 -0
- package/components/ui/tooltip.stories.tsx +146 -0
- package/components/ui/tooltip.tsx +156 -0
- package/components/ui/top-bar.stories.tsx +182 -0
- package/components/ui/top-bar.tsx +155 -0
- package/dist/components/ui/accordion.d.ts +45 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/accordion.js +99 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/app-shell.d.ts +70 -0
- package/dist/components/ui/app-shell.d.ts.map +1 -0
- package/dist/components/ui/app-shell.js +199 -0
- package/dist/components/ui/app-shell.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +41 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +104 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +27 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +65 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +35 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +88 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +26 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +73 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/card.d.ts +52 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +96 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +18 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +59 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/combobox.d.ts +194 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +361 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +46 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/context-menu.js +95 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/data-table.d.ts +53 -0
- package/dist/components/ui/data-table.d.ts.map +1 -0
- package/dist/components/ui/data-table.js +163 -0
- package/dist/components/ui/data-table.js.map +1 -0
- package/dist/components/ui/date-picker.d.ts +103 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/date-picker.js +306 -0
- package/dist/components/ui/date-picker.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +40 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +110 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/divider.d.ts +30 -0
- package/dist/components/ui/divider.d.ts.map +1 -0
- package/dist/components/ui/divider.js +62 -0
- package/dist/components/ui/divider.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +56 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/drawer.js +147 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +63 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +116 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/empty-state.d.ts +43 -0
- package/dist/components/ui/empty-state.d.ts.map +1 -0
- package/dist/components/ui/empty-state.js +128 -0
- package/dist/components/ui/empty-state.js.map +1 -0
- package/dist/components/ui/field-group.d.ts +38 -0
- package/dist/components/ui/field-group.d.ts.map +1 -0
- package/dist/components/ui/field-group.js +107 -0
- package/dist/components/ui/field-group.js.map +1 -0
- package/dist/components/ui/form.d.ts +67 -0
- package/dist/components/ui/form.d.ts.map +1 -0
- package/dist/components/ui/form.js +286 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/input.d.ts +36 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +99 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/label.d.ts +37 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +34 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +65 -0
- package/dist/components/ui/page-header.d.ts.map +1 -0
- package/dist/components/ui/page-header.js +140 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +67 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination.js +109 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.d.ts +28 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +85 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +35 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/radio-group.js +103 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/select.d.ts +42 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +86 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +59 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +189 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +77 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +115 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/switch.d.ts +26 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +84 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +52 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +109 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +42 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +163 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +26 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +96 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/toast.d.ts +77 -0
- package/dist/components/ui/toast.d.ts.map +1 -0
- package/dist/components/ui/toast.js +141 -0
- package/dist/components/ui/toast.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +31 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +71 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components/ui/top-bar.d.ts +30 -0
- package/dist/components/ui/top-bar.d.ts.map +1 -0
- package/dist/components/ui/top-bar.js +64 -0
- package/dist/components/ui/top-bar.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/lib/utils.ts +6 -0
- package/package.json +112 -0
- package/styles/globals.css +685 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
|
|
4
|
+
import { DatePicker } from "./date-picker";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof DatePicker> = {
|
|
7
|
+
title: "Forms/DatePicker",
|
|
8
|
+
component: DatePicker,
|
|
9
|
+
parameters: { layout: "centered" },
|
|
10
|
+
argTypes: {
|
|
11
|
+
size: { control: "select", options: ["xs", "sm", "md", "lg", "xl"] },
|
|
12
|
+
invalid: { control: "boolean" },
|
|
13
|
+
clearable: { control: "boolean" },
|
|
14
|
+
disabled: { control: "boolean" },
|
|
15
|
+
locale: { control: "select", options: ["en-US", "fr-FR", "fr-MA", "ar-MA"] },
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default meta;
|
|
20
|
+
type Story = StoryObj<typeof DatePicker>;
|
|
21
|
+
|
|
22
|
+
export const Default: Story = {
|
|
23
|
+
render: (args) => (
|
|
24
|
+
<div className="w-72">
|
|
25
|
+
<DatePicker {...args} />
|
|
26
|
+
</div>
|
|
27
|
+
),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Controlled: Story = {
|
|
31
|
+
render: () => {
|
|
32
|
+
const Wrapper = () => {
|
|
33
|
+
const [date, setDate] = useState<Date | null>(null);
|
|
34
|
+
return (
|
|
35
|
+
<div className="w-72 space-y-2">
|
|
36
|
+
<DatePicker value={date} onValueChange={setDate} clearable />
|
|
37
|
+
<p className="text-muted-foreground text-xs">
|
|
38
|
+
value: {date ? date.toISOString().slice(0, 10) : "null"}
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
return <Wrapper />;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Sizes: Story = {
|
|
48
|
+
render: () => (
|
|
49
|
+
<div className="space-y-2">
|
|
50
|
+
<DatePicker size="xs" placeholder="xs" />
|
|
51
|
+
<DatePicker size="sm" placeholder="sm" />
|
|
52
|
+
<DatePicker size="md" placeholder="md" />
|
|
53
|
+
<DatePicker size="lg" placeholder="lg" />
|
|
54
|
+
<DatePicker size="xl" placeholder="xl" />
|
|
55
|
+
</div>
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const FrenchLocale: Story = {
|
|
60
|
+
render: () => (
|
|
61
|
+
<div className="w-72">
|
|
62
|
+
<DatePicker locale="fr-FR" defaultValue={new Date(2026, 0, 15)} format="PPP" />
|
|
63
|
+
</div>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const ArabicLocale: Story = {
|
|
68
|
+
render: () => (
|
|
69
|
+
<div className="w-72">
|
|
70
|
+
<DatePicker locale="ar-MA" defaultValue={new Date(2026, 0, 15)} format="PPP" />
|
|
71
|
+
</div>
|
|
72
|
+
),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const Clearable: Story = {
|
|
76
|
+
render: () => (
|
|
77
|
+
<div className="w-72">
|
|
78
|
+
<DatePicker clearable defaultValue={new Date()} />
|
|
79
|
+
</div>
|
|
80
|
+
),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const Invalid: Story = {
|
|
84
|
+
render: () => (
|
|
85
|
+
<div className="w-72">
|
|
86
|
+
<DatePicker invalid defaultValue={new Date()} />
|
|
87
|
+
</div>
|
|
88
|
+
),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const Disabled: Story = {
|
|
92
|
+
render: () => (
|
|
93
|
+
<div className="w-72">
|
|
94
|
+
<DatePicker disabled defaultValue={new Date()} />
|
|
95
|
+
</div>
|
|
96
|
+
),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const MinMax: Story = {
|
|
100
|
+
render: () => {
|
|
101
|
+
const today = new Date();
|
|
102
|
+
const oneMonthAgo = new Date(today);
|
|
103
|
+
oneMonthAgo.setMonth(today.getMonth() - 1);
|
|
104
|
+
const oneMonthFromNow = new Date(today);
|
|
105
|
+
oneMonthFromNow.setMonth(today.getMonth() + 1);
|
|
106
|
+
return (
|
|
107
|
+
<div className="w-72">
|
|
108
|
+
<DatePicker min={oneMonthAgo} max={oneMonthFromNow} placeholder="Within ±1 month" />
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const CustomFormat: Story = {
|
|
115
|
+
render: () => (
|
|
116
|
+
<div className="w-72">
|
|
117
|
+
<DatePicker defaultValue={new Date(2026, 0, 15)} format="EEEE, MMMM do yyyy" />
|
|
118
|
+
</div>
|
|
119
|
+
),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const WeekStartsOnMonday: Story = {
|
|
123
|
+
render: () => (
|
|
124
|
+
<div className="w-72">
|
|
125
|
+
<DatePicker weekStartsOn={1} defaultValue={new Date()} />
|
|
126
|
+
</div>
|
|
127
|
+
),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const WithWeekNumbers: Story = {
|
|
131
|
+
render: () => (
|
|
132
|
+
<div className="w-72">
|
|
133
|
+
<DatePicker showWeekNumbers defaultValue={new Date()} />
|
|
134
|
+
</div>
|
|
135
|
+
),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Range mode. Pick a start date, then an end date — in-range days fill with
|
|
140
|
+
* `--accent`, endpoints with `--primary`. While only the start is picked,
|
|
141
|
+
* the trigger shows the start followed by `rangeEndPlaceholder` ("Pick end
|
|
142
|
+
* date" by default).
|
|
143
|
+
*/
|
|
144
|
+
export const RangeMode: Story = {
|
|
145
|
+
render: () => {
|
|
146
|
+
const Wrapper = () => {
|
|
147
|
+
const [value, setValue] = useState<{ from: Date | undefined; to?: Date | undefined } | null>({
|
|
148
|
+
from: new Date(2026, 0, 5),
|
|
149
|
+
to: new Date(2026, 0, 12),
|
|
150
|
+
});
|
|
151
|
+
return (
|
|
152
|
+
<div className="w-80 space-y-2">
|
|
153
|
+
<DatePicker mode="range" value={value} onValueChange={(v) => setValue(v)} clearable />
|
|
154
|
+
<p className="text-muted-foreground text-xs">
|
|
155
|
+
value:{" "}
|
|
156
|
+
{value
|
|
157
|
+
? JSON.stringify({ from: value.from?.toDateString(), to: value.to?.toDateString() })
|
|
158
|
+
: "null"}
|
|
159
|
+
</p>
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
return <Wrapper />;
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Range mode rendered inline (no popover). Useful for filter sidebars.
|
|
169
|
+
*/
|
|
170
|
+
export const RangeModeInline: Story = {
|
|
171
|
+
render: () => <DatePicker mode="range" inline defaultValue={{ from: new Date(2026, 0, 5) }} />,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Range mode with quick-pick presets in a side column. Clicking a preset
|
|
176
|
+
* applies a {from, to} pair and closes the popover.
|
|
177
|
+
*/
|
|
178
|
+
export const RangeWithPresets: Story = {
|
|
179
|
+
render: () => {
|
|
180
|
+
const today = new Date();
|
|
181
|
+
const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
|
182
|
+
const minusDays = (n: number) => {
|
|
183
|
+
const d = new Date(startOfToday);
|
|
184
|
+
d.setDate(d.getDate() - n);
|
|
185
|
+
return d;
|
|
186
|
+
};
|
|
187
|
+
return (
|
|
188
|
+
<div className="w-[28rem]">
|
|
189
|
+
<DatePicker
|
|
190
|
+
mode="range"
|
|
191
|
+
presets={[
|
|
192
|
+
{ label: "Today", value: { from: startOfToday, to: startOfToday } },
|
|
193
|
+
{ label: "Yesterday", value: { from: minusDays(1), to: minusDays(1) } },
|
|
194
|
+
{ label: "Last 7 days", value: { from: minusDays(6), to: startOfToday } },
|
|
195
|
+
{ label: "Last 30 days", value: { from: minusDays(29), to: startOfToday } },
|
|
196
|
+
{
|
|
197
|
+
label: "This month",
|
|
198
|
+
value: { from: new Date(today.getFullYear(), today.getMonth(), 1), to: startOfToday },
|
|
199
|
+
},
|
|
200
|
+
]}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Multiple mode — pick any number of individual dates. Trigger shows the
|
|
209
|
+
* first two by default and collapses the rest into "+N more". Popover
|
|
210
|
+
* stays open after each pick so users can keep adding.
|
|
211
|
+
*/
|
|
212
|
+
export const MultipleMode: Story = {
|
|
213
|
+
render: () => {
|
|
214
|
+
const Wrapper = () => {
|
|
215
|
+
const [value, setValue] = useState<Date[]>([new Date(2026, 0, 5), new Date(2026, 0, 12)]);
|
|
216
|
+
return (
|
|
217
|
+
<div className="w-80 space-y-2">
|
|
218
|
+
<DatePicker mode="multiple" value={value} onValueChange={setValue} clearable />
|
|
219
|
+
<p className="text-muted-foreground text-xs">count: {value.length}</p>
|
|
220
|
+
</div>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
return <Wrapper />;
|
|
224
|
+
},
|
|
225
|
+
};
|