@suphark/ui 0.24.0 → 0.25.1

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/package.json +1 -1
  3. package/src/components/app-shell/command-palette.tsx +8 -1
  4. package/src/components/data-table/data-table-sortable.tsx +154 -0
  5. package/src/components/data-table/data-table-toolbar.tsx +33 -4
  6. package/src/components/data-table/data-table.tsx +30 -142
  7. package/src/components/data-table/index.ts +9 -9
  8. package/src/components/data-table/use-data-table.ts +8 -5
  9. package/src/components/pwa/pull-to-refresh.tsx +21 -1
  10. package/src/components/shared/action-menu.tsx +25 -6
  11. package/src/components/shared/auth-parts.tsx +5 -3
  12. package/src/components/shared/button/confirm-action-button.tsx +17 -3
  13. package/src/components/shared/chat-thread.tsx +7 -0
  14. package/src/components/shared/client-redirect.tsx +16 -1
  15. package/src/components/shared/form/date-time-picker.tsx +150 -0
  16. package/src/components/shared/form/form-field-autocomplete.tsx +93 -0
  17. package/src/components/shared/form/form-field-input.tsx +23 -81
  18. package/src/components/shared/form/number-input.tsx +154 -0
  19. package/src/components/shared/form/tags-input.tsx +197 -0
  20. package/src/components/shared/form/time-picker.tsx +321 -0
  21. package/src/components/shared/month-stepper.tsx +10 -4
  22. package/src/components/shared/row-actions.tsx +9 -3
  23. package/src/components/shared/settings-layout.tsx +17 -6
  24. package/src/components/shared/step-form.tsx +304 -0
  25. package/src/components/shared/time/client-date-formatter.tsx +2 -1
  26. package/src/components/shared/tree-view.tsx +6 -2
  27. package/src/components/shared/ui-text.tsx +68 -0
  28. package/src/data-table.ts +12 -1
  29. package/src/hooks/use-table-search-params.ts +10 -2
  30. package/src/hooks/use-ticker.ts +11 -5
  31. package/src/index.ts +430 -66
  32. package/src/lib/formatters.ts +1 -1
  33. package/src/lib/month.ts +14 -2
  34. package/src/next.ts +38 -1
package/src/index.ts CHANGED
@@ -26,7 +26,20 @@ export {
26
26
  PasswordInput,
27
27
  ProviderButtons,
28
28
  } from "./components/shared/auth-parts";
29
- export * from "./components/shared/button";
29
+ export {
30
+ ActionButton,
31
+ type ActionButtonProps,
32
+ AddNewButton,
33
+ CancelButton,
34
+ ConfirmButton,
35
+ CopyButton,
36
+ type CopyButtonProps,
37
+ DeleteButton,
38
+ FloatingSaveButton,
39
+ PrintButton,
40
+ SaveButton,
41
+ SubmitButton,
42
+ } from "./components/shared/button";
30
43
  export {
31
44
  type CalendarDayContext,
32
45
  type CalendarDayState,
@@ -77,6 +90,7 @@ export { EmptyState } from "./components/shared/empty-state";
77
90
  export { EnvSnippet, randomSecret } from "./components/shared/env-snippet";
78
91
  export { type FileKind, FileTypeIcon, getFileKind } from "./components/shared/file-type-icon";
79
92
  export { FilterBar, type FilterBarFilter } from "./components/shared/filter-bar";
93
+ export { DateTimePicker } from "./components/shared/form/date-time-picker";
80
94
  export { FormFieldBoolean } from "./components/shared/form/form-field-boolean";
81
95
  export { FormFieldColorSelect } from "./components/shared/form/form-field-color-select";
82
96
  export { FormFieldCombobox } from "./components/shared/form/form-field-combobox";
@@ -91,6 +105,7 @@ export { FormFieldRadioCards } from "./components/shared/form/form-field-radio-c
91
105
  export { FormFieldRadioGroup } from "./components/shared/form/form-field-radio-group";
92
106
  export { FormFieldSelect, type SelectOption } from "./components/shared/form/form-field-select";
93
107
  export { CheckboxField, LabeledField } from "./components/shared/form/labeled-field";
108
+ export { NumberInput } from "./components/shared/form/number-input";
94
109
  export { SearchInput, type SearchInputProps } from "./components/shared/form/search-input";
95
110
  export {
96
111
  SimpleSelect,
@@ -100,7 +115,15 @@ export {
100
115
  type SimpleSelectProps,
101
116
  } from "./components/shared/form/simple-select";
102
117
  export { SliderField, type SliderFieldProps } from "./components/shared/form/slider-field";
118
+ export { TagsInput } from "./components/shared/form/tags-input";
103
119
  export { TextareaField } from "./components/shared/form/textarea-field";
120
+ export {
121
+ parseTimeInput,
122
+ TimeColumns,
123
+ TimePicker,
124
+ type TimeValue,
125
+ toLocalDateTimeString,
126
+ } from "./components/shared/form/time-picker";
104
127
  export {
105
128
  type FormAction,
106
129
  FormMessage,
@@ -186,13 +209,21 @@ export { CardSkeleton, ListSkeleton, TableSkeleton } from "./components/shared/s
186
209
  export { SkipLink } from "./components/shared/skip-link";
187
210
  export { Stat, type StatDelta, StatGrid, type StatTone } from "./components/shared/stat";
188
211
  export { StatusBadge, statusTone, type Tone } from "./components/shared/status-badge";
212
+ export { StepForm, type StepFormStep } from "./components/shared/step-form";
189
213
  export { SwitcherChevron } from "./components/shared/switcher-chevron";
190
214
  export { CodeBlock, type CodeBlockProps } from "./components/shared/text/code-block";
191
215
  export {
192
216
  PrimarySecondaryText,
193
217
  type PrimarySecondaryTextProps,
194
218
  } from "./components/shared/text/primary-secondary-text";
195
- export * from "./components/shared/theme";
219
+ export {
220
+ type Theme,
221
+ ThemeMenuItems,
222
+ ThemeProvider,
223
+ ThemeSwitch,
224
+ ThemeToggle,
225
+ useTheme,
226
+ } from "./components/shared/theme";
196
227
  export { ClientDateFormatter } from "./components/shared/time/client-date-formatter";
197
228
  export { type TreeNode, TreeView, type TreeViewProps } from "./components/shared/tree-view";
198
229
  export {
@@ -212,71 +243,404 @@ export {
212
243
  export { type UserAvatarItem, UserAvatars } from "./components/shared/user-avatars";
213
244
  export { UserIdentity, type UserIdentityProps } from "./components/shared/user-identity";
214
245
  // ---------- shadcn/ui primitives ----------
215
- export * from "./components/ui/accordion";
216
- export * from "./components/ui/alert";
217
- export * from "./components/ui/alert-dialog";
218
- export * from "./components/ui/aspect-ratio";
219
- export * from "./components/ui/attachment";
220
- export * from "./components/ui/avatar";
221
- export * from "./components/ui/badge";
246
+ export {
247
+ Accordion,
248
+ AccordionContent,
249
+ AccordionItem,
250
+ AccordionTrigger,
251
+ } from "./components/ui/accordion";
252
+ export { Alert, AlertAction, AlertDescription, AlertTitle } from "./components/ui/alert";
253
+ export {
254
+ AlertDialog,
255
+ AlertDialogAction,
256
+ AlertDialogCancel,
257
+ AlertDialogContent,
258
+ AlertDialogDescription,
259
+ AlertDialogFooter,
260
+ AlertDialogHeader,
261
+ AlertDialogMedia,
262
+ AlertDialogOverlay,
263
+ AlertDialogPortal,
264
+ AlertDialogTitle,
265
+ AlertDialogTrigger,
266
+ } from "./components/ui/alert-dialog";
267
+ export { AspectRatio } from "./components/ui/aspect-ratio";
268
+ export {
269
+ Attachment,
270
+ AttachmentAction,
271
+ AttachmentActions,
272
+ AttachmentContent,
273
+ AttachmentDescription,
274
+ AttachmentGroup,
275
+ AttachmentMedia,
276
+ AttachmentTitle,
277
+ AttachmentTrigger,
278
+ } from "./components/ui/attachment";
279
+ export {
280
+ Avatar,
281
+ AvatarBadge,
282
+ AvatarFallback,
283
+ AvatarGroup,
284
+ AvatarGroupCount,
285
+ AvatarImage,
286
+ } from "./components/ui/avatar";
287
+ export { Badge, badgeVariants } from "./components/ui/badge";
222
288
  // toast.tsx (Base UI) ไม่อยู่ใน barrel: ชื่อ toast/Toaster ชนกับ sonner ที่แพ็กเกจใช้ — import ตรงจาก @suphark/ui/components/ui/toast ถ้าต้องการ
223
- export * from "./components/ui/breadcrumb";
224
- export * from "./components/ui/bubble";
225
- export * from "./components/ui/button";
226
- export * from "./components/ui/button-group";
227
- export * from "./components/ui/calendar";
228
- export * from "./components/ui/card";
229
- export * from "./components/ui/carousel";
230
- export * from "./components/ui/checkbox";
231
- export * from "./components/ui/collapsible";
232
- export * from "./components/ui/combobox";
233
- export * from "./components/ui/command";
234
- export * from "./components/ui/context-menu";
235
- export * from "./components/ui/date-picker";
236
- export * from "./components/ui/dialog";
237
- export * from "./components/ui/direction";
238
- export * from "./components/ui/drawer";
239
- export * from "./components/ui/dropdown-menu";
240
- export * from "./components/ui/empty";
241
- export * from "./components/ui/field";
242
- export * from "./components/ui/form";
243
- export * from "./components/ui/hover-card";
244
- export * from "./components/ui/input";
245
- export * from "./components/ui/input-group";
246
- export * from "./components/ui/input-otp";
247
- export * from "./components/ui/item";
248
- export * from "./components/ui/kbd";
249
- export * from "./components/ui/label";
250
- export * from "./components/ui/marker";
251
- export * from "./components/ui/menubar";
252
- export * from "./components/ui/message";
253
- export * from "./components/ui/message-scroller";
254
- export * from "./components/ui/native-select";
255
- export * from "./components/ui/navigation-menu";
256
- export * from "./components/ui/pagination";
257
- export * from "./components/ui/popover";
258
- export * from "./components/ui/progress";
259
- export * from "./components/ui/questionnaire";
260
- export * from "./components/ui/radio-group";
261
- export * from "./components/ui/relative-date";
262
- export * from "./components/ui/resizable";
263
- export * from "./components/ui/scroll-area";
264
- export * from "./components/ui/searchable-select";
265
- export * from "./components/ui/select";
266
- export * from "./components/ui/separator";
267
- export * from "./components/ui/sheet";
268
- export * from "./components/ui/sidebar";
269
- export * from "./components/ui/skeleton";
270
- export * from "./components/ui/slider";
271
- export * from "./components/ui/sonner";
272
- export * from "./components/ui/spinner";
273
- export * from "./components/ui/switch";
274
- export * from "./components/ui/table";
275
- export * from "./components/ui/tabs";
276
- export * from "./components/ui/textarea";
277
- export * from "./components/ui/toggle";
278
- export * from "./components/ui/toggle-group";
279
- export * from "./components/ui/tooltip";
289
+ export {
290
+ Breadcrumb,
291
+ BreadcrumbEllipsis,
292
+ BreadcrumbItem,
293
+ BreadcrumbLink,
294
+ BreadcrumbList,
295
+ BreadcrumbPage,
296
+ BreadcrumbSeparator,
297
+ } from "./components/ui/breadcrumb";
298
+ export { Bubble, BubbleContent, BubbleGroup, BubbleReactions } from "./components/ui/bubble";
299
+ export { Button, buttonVariants } from "./components/ui/button";
300
+ export {
301
+ ButtonGroup,
302
+ ButtonGroupSeparator,
303
+ ButtonGroupText,
304
+ buttonGroupVariants,
305
+ } from "./components/ui/button-group";
306
+ export { Calendar, CalendarDayButton } from "./components/ui/calendar";
307
+ export {
308
+ Card,
309
+ CardAction,
310
+ CardContent,
311
+ CardDescription,
312
+ CardFooter,
313
+ CardHeader,
314
+ CardTitle,
315
+ } from "./components/ui/card";
316
+ export {
317
+ Carousel,
318
+ type CarouselApi,
319
+ CarouselContent,
320
+ CarouselItem,
321
+ CarouselNext,
322
+ CarouselPrevious,
323
+ useCarousel,
324
+ } from "./components/ui/carousel";
325
+ export { Checkbox } from "./components/ui/checkbox";
326
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./components/ui/collapsible";
327
+ export {
328
+ ComboboxChip,
329
+ ComboboxChips,
330
+ ComboboxChipsInput,
331
+ ComboboxCollection,
332
+ ComboboxContent,
333
+ ComboboxEmpty,
334
+ ComboboxGroup,
335
+ ComboboxInput,
336
+ ComboboxItem,
337
+ ComboboxLabel,
338
+ ComboboxList,
339
+ ComboboxSeparator,
340
+ ComboboxTrigger,
341
+ ComboboxValue,
342
+ useComboboxAnchor,
343
+ } from "./components/ui/combobox";
344
+ export {
345
+ Command,
346
+ CommandDialog,
347
+ CommandEmpty,
348
+ CommandGroup,
349
+ CommandInput,
350
+ CommandItem,
351
+ CommandList,
352
+ CommandSeparator,
353
+ CommandShortcut,
354
+ } from "./components/ui/command";
355
+ export {
356
+ ContextMenu,
357
+ ContextMenuCheckboxItem,
358
+ ContextMenuContent,
359
+ ContextMenuGroup,
360
+ ContextMenuItem,
361
+ ContextMenuLabel,
362
+ ContextMenuPortal,
363
+ ContextMenuRadioGroup,
364
+ ContextMenuRadioItem,
365
+ ContextMenuSeparator,
366
+ ContextMenuShortcut,
367
+ ContextMenuSub,
368
+ ContextMenuSubContent,
369
+ ContextMenuSubTrigger,
370
+ ContextMenuTrigger,
371
+ } from "./components/ui/context-menu";
372
+ export { DatePicker, parseSmartDateInput } from "./components/ui/date-picker";
373
+ export {
374
+ Dialog,
375
+ DialogClose,
376
+ DialogContent,
377
+ DialogDescription,
378
+ DialogFooter,
379
+ DialogHeader,
380
+ DialogOverlay,
381
+ DialogPortal,
382
+ DialogTitle,
383
+ DialogTrigger,
384
+ } from "./components/ui/dialog";
385
+ export { DirectionProvider, useDirection } from "./components/ui/direction";
386
+ export {
387
+ Drawer,
388
+ DrawerClose,
389
+ DrawerContent,
390
+ DrawerDescription,
391
+ DrawerFooter,
392
+ DrawerHeader,
393
+ DrawerOverlay,
394
+ DrawerPortal,
395
+ DrawerSwipeHandle,
396
+ DrawerTitle,
397
+ DrawerTrigger,
398
+ } from "./components/ui/drawer";
399
+ export {
400
+ DropdownMenu,
401
+ DropdownMenuCheckboxItem,
402
+ DropdownMenuContent,
403
+ DropdownMenuGroup,
404
+ DropdownMenuItem,
405
+ DropdownMenuLabel,
406
+ DropdownMenuPortal,
407
+ DropdownMenuRadioGroup,
408
+ DropdownMenuRadioItem,
409
+ DropdownMenuSeparator,
410
+ DropdownMenuShortcut,
411
+ DropdownMenuSub,
412
+ DropdownMenuSubContent,
413
+ DropdownMenuSubTrigger,
414
+ DropdownMenuTrigger,
415
+ } from "./components/ui/dropdown-menu";
416
+ export {
417
+ Empty,
418
+ EmptyContent,
419
+ EmptyDescription,
420
+ EmptyHeader,
421
+ EmptyMedia,
422
+ EmptyTitle,
423
+ } from "./components/ui/empty";
424
+ export {
425
+ Field,
426
+ FieldContent,
427
+ FieldDescription,
428
+ FieldError,
429
+ FieldGroup,
430
+ FieldLabel,
431
+ FieldLegend,
432
+ FieldSeparator,
433
+ FieldSet,
434
+ FieldTitle,
435
+ } from "./components/ui/field";
436
+ export {
437
+ Form,
438
+ FormControl,
439
+ FormDescription,
440
+ FormField,
441
+ FormItem,
442
+ FormLabel,
443
+ useFormField,
444
+ } from "./components/ui/form";
445
+ export { HoverCard, HoverCardContent, HoverCardTrigger } from "./components/ui/hover-card";
446
+ export { Input } from "./components/ui/input";
447
+ export {
448
+ InputGroup,
449
+ InputGroupAddon,
450
+ InputGroupButton,
451
+ InputGroupInput,
452
+ InputGroupText,
453
+ InputGroupTextarea,
454
+ } from "./components/ui/input-group";
455
+ export {
456
+ InputOTP,
457
+ InputOTPGroup,
458
+ InputOTPSeparator,
459
+ InputOTPSlot,
460
+ } from "./components/ui/input-otp";
461
+ export {
462
+ Item,
463
+ ItemActions,
464
+ ItemContent,
465
+ ItemDescription,
466
+ ItemFooter,
467
+ ItemGroup,
468
+ ItemHeader,
469
+ ItemMedia,
470
+ ItemSeparator,
471
+ ItemTitle,
472
+ } from "./components/ui/item";
473
+ export { Kbd, KbdGroup } from "./components/ui/kbd";
474
+ export { Label } from "./components/ui/label";
475
+ export { Marker, MarkerContent, MarkerIcon, markerVariants } from "./components/ui/marker";
476
+ export {
477
+ Menubar,
478
+ MenubarCheckboxItem,
479
+ MenubarContent,
480
+ MenubarGroup,
481
+ MenubarItem,
482
+ MenubarLabel,
483
+ MenubarMenu,
484
+ MenubarPortal,
485
+ MenubarRadioGroup,
486
+ MenubarRadioItem,
487
+ MenubarSeparator,
488
+ MenubarShortcut,
489
+ MenubarSub,
490
+ MenubarSubContent,
491
+ MenubarSubTrigger,
492
+ MenubarTrigger,
493
+ } from "./components/ui/menubar";
494
+ export {
495
+ Message,
496
+ MessageAvatar,
497
+ MessageContent,
498
+ MessageFooter,
499
+ MessageGroup,
500
+ MessageHeader,
501
+ } from "./components/ui/message";
502
+ export {
503
+ MessageScroller,
504
+ MessageScrollerButton,
505
+ MessageScrollerContent,
506
+ MessageScrollerItem,
507
+ MessageScrollerProvider,
508
+ MessageScrollerViewport,
509
+ useMessageScroller,
510
+ useMessageScrollerScrollable,
511
+ useMessageScrollerVisibility,
512
+ } from "./components/ui/message-scroller";
513
+ export {
514
+ NativeSelect,
515
+ NativeSelectOptGroup,
516
+ NativeSelectOption,
517
+ } from "./components/ui/native-select";
518
+ export {
519
+ NavigationMenu,
520
+ NavigationMenuContent,
521
+ NavigationMenuIndicator,
522
+ NavigationMenuItem,
523
+ NavigationMenuLink,
524
+ NavigationMenuList,
525
+ NavigationMenuPositioner,
526
+ NavigationMenuTrigger,
527
+ navigationMenuTriggerStyle,
528
+ } from "./components/ui/navigation-menu";
529
+ export {
530
+ Pagination,
531
+ PaginationContent,
532
+ PaginationEllipsis,
533
+ PaginationItem,
534
+ PaginationLink,
535
+ PaginationNext,
536
+ PaginationPrevious,
537
+ } from "./components/ui/pagination";
538
+ export {
539
+ Popover,
540
+ PopoverContent,
541
+ PopoverDescription,
542
+ PopoverHeader,
543
+ PopoverTitle,
544
+ PopoverTrigger,
545
+ } from "./components/ui/popover";
546
+ export {
547
+ Progress,
548
+ ProgressIndicator,
549
+ ProgressLabel,
550
+ ProgressTrack,
551
+ ProgressValue,
552
+ } from "./components/ui/progress";
553
+ export {
554
+ Questionnaire,
555
+ QuestionnaireActions,
556
+ QuestionnaireChoice,
557
+ QuestionnaireChoiceDescription,
558
+ QuestionnaireChoices,
559
+ QuestionnaireDescription,
560
+ QuestionnaireError,
561
+ QuestionnaireInput,
562
+ QuestionnaireItem,
563
+ QuestionnaireNext,
564
+ QuestionnairePrevious,
565
+ QuestionnaireProgress,
566
+ QuestionnaireSkip,
567
+ QuestionnaireSubmit,
568
+ QuestionnaireTitle,
569
+ } from "./components/ui/questionnaire";
570
+ export { RadioGroup, RadioGroupItem } from "./components/ui/radio-group";
571
+ export { RelativeDate } from "./components/ui/relative-date";
572
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./components/ui/resizable";
573
+ export { ScrollArea, ScrollBar } from "./components/ui/scroll-area";
574
+ export { SearchableSelect, type SearchableSelectOption } from "./components/ui/searchable-select";
575
+ export {
576
+ Select,
577
+ SelectContent,
578
+ SelectGroup,
579
+ SelectItem,
580
+ SelectLabel,
581
+ SelectScrollDownButton,
582
+ SelectScrollUpButton,
583
+ SelectSeparator,
584
+ SelectTrigger,
585
+ SelectValue,
586
+ } from "./components/ui/select";
587
+ export { Separator } from "./components/ui/separator";
588
+ export {
589
+ Sheet,
590
+ SheetClose,
591
+ SheetContent,
592
+ SheetDescription,
593
+ SheetFooter,
594
+ SheetHeader,
595
+ SheetTitle,
596
+ SheetTrigger,
597
+ } from "./components/ui/sheet";
598
+ export {
599
+ Sidebar,
600
+ SidebarContent,
601
+ SidebarFooter,
602
+ SidebarGroup,
603
+ SidebarGroupAction,
604
+ SidebarGroupContent,
605
+ SidebarGroupLabel,
606
+ SidebarHeader,
607
+ SidebarInput,
608
+ SidebarInset,
609
+ SidebarMenu,
610
+ SidebarMenuAction,
611
+ SidebarMenuBadge,
612
+ SidebarMenuButton,
613
+ SidebarMenuItem,
614
+ SidebarMenuSkeleton,
615
+ SidebarMenuSub,
616
+ SidebarMenuSubButton,
617
+ SidebarMenuSubItem,
618
+ SidebarProvider,
619
+ SidebarRail,
620
+ SidebarSeparator,
621
+ SidebarTrigger,
622
+ useSidebar,
623
+ } from "./components/ui/sidebar";
624
+ export { Skeleton } from "./components/ui/skeleton";
625
+ export { Slider } from "./components/ui/slider";
626
+ export { Toaster } from "./components/ui/sonner";
627
+ export { Spinner } from "./components/ui/spinner";
628
+ export { Switch } from "./components/ui/switch";
629
+ export {
630
+ Table,
631
+ TableBody,
632
+ TableCaption,
633
+ TableCell,
634
+ TableFooter,
635
+ TableHead,
636
+ TableHeader,
637
+ TableRow,
638
+ } from "./components/ui/table";
639
+ export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from "./components/ui/tabs";
640
+ export { Textarea } from "./components/ui/textarea";
641
+ export { Toggle, toggleVariants } from "./components/ui/toggle";
642
+ export { ToggleGroup, ToggleGroupItem } from "./components/ui/toggle-group";
643
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip";
280
644
  // ---------- lib / hooks ----------
281
645
  export { useConfirm } from "./hooks/use-confirm";
282
646
  export { useCopyToClipboard } from "./hooks/use-copy-to-clipboard";
@@ -1,5 +1,5 @@
1
1
  import { differenceInCalendarDays, formatDistanceToNow } from "date-fns";
2
- import { th } from "date-fns/locale";
2
+ import { th } from "date-fns/locale/th";
3
3
 
4
4
  /**
5
5
  * ฟอร์แมตวันที่แบบไทยที่ primitives ใช้ร่วมกัน (DatePicker, RelativeDate)
package/src/lib/month.ts CHANGED
@@ -29,8 +29,20 @@ export function toMonthKey(date: Date): MonthKey {
29
29
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
30
30
  }
31
31
 
32
- export function currentMonthKey(now: Date = new Date()): MonthKey {
33
- return toMonthKey(now);
32
+ /**
33
+ * เดือนปัจจุบัน — ไม่ส่ง `timeZone` = โซนเวลาของเครื่อง
34
+ * ส่ง `timeZone` (เช่น "Asia/Bangkok") เมื่อค่าถูกคำนวณทั้งบน server (UTC) และ browser แล้วต้องตรงกัน (กัน hydration mismatch ต้นเดือน)
35
+ */
36
+ export function currentMonthKey(now: Date = new Date(), timeZone?: string): MonthKey {
37
+ if (!timeZone) return toMonthKey(now);
38
+ const parts = new Intl.DateTimeFormat("en-CA", {
39
+ timeZone,
40
+ year: "numeric",
41
+ month: "2-digit",
42
+ }).formatToParts(now);
43
+ const year = parts.find((p) => p.type === "year")?.value ?? String(now.getFullYear());
44
+ const month = parts.find((p) => p.type === "month")?.value ?? "01";
45
+ return `${year}-${month}`;
34
46
  }
35
47
 
36
48
  /** เลื่อนเดือน (ลบ = ย้อนหลัง) ข้ามปีให้เอง: shiftMonth("2026-01", -1) → "2025-12" */
package/src/next.ts CHANGED
@@ -4,7 +4,44 @@
4
4
  */
5
5
 
6
6
  // ---------- app shell (sidebar + header + เนื้อหา) ----------
7
- export * from "./components/app-shell";
7
+ export {
8
+ APP_MAIN_ID,
9
+ AppBrand,
10
+ type AppBrandProps,
11
+ AppNav,
12
+ type AppNavGroup,
13
+ AppNavGroupMenu,
14
+ type AppNavItem,
15
+ type AppNavPinProps,
16
+ AppShell,
17
+ type AppShellProps,
18
+ CommandPalette,
19
+ type CommandPaletteItem,
20
+ type CommandPaletteSection,
21
+ type CommandPaletteSectionItem,
22
+ type CommandPaletteText,
23
+ filterNav,
24
+ flattenNav,
25
+ HeaderBreadcrumbs,
26
+ type HeaderBreadcrumbsProps,
27
+ HeaderCrumb,
28
+ HeaderCrumbs,
29
+ isNavActive,
30
+ isTabActive,
31
+ MobileTabBar,
32
+ type MobileTabItem,
33
+ NavLink,
34
+ type OrganizationOption,
35
+ OrganizationSwitcher,
36
+ type OrganizationSwitcherProps,
37
+ SubNav,
38
+ searchNav,
39
+ TopTabs,
40
+ topLevelTabs,
41
+ UserMenu,
42
+ type UserMenuProps,
43
+ type UserMenuUser,
44
+ } from "./components/app-shell";
8
45
  export { LinkButton, type LinkButtonProps } from "./components/shared/button/base/link-button";
9
46
  export { ConfirmActionButton } from "./components/shared/button/confirm-action-button";
10
47
  export { RefreshButton } from "./components/shared/button/refresh-button";