@dragunio/fe-libs 0.1.12 → 0.1.13

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/dist/index.d.mts CHANGED
@@ -526,11 +526,26 @@ type CurrencyInputProps = Omit<NumberInputProps, 'suffix' | 'endAdornment'> & {
526
526
  declare function CurrencyInput({ suffix, currencies, currency, defaultCurrency, onCurrencyChange, className, disabled, ...props }: CurrencyInputProps): react.JSX.Element;
527
527
 
528
528
  type DateRange = [Date | null, Date | null];
529
+ /** Text of the picker. `weekdays` runs from Monday to Sunday. */
530
+ type DateTimePickerLabels = {
531
+ weekdays: readonly [string, string, string, string, string, string, string];
532
+ today: string;
533
+ time: string;
534
+ start: string;
535
+ end: string;
536
+ previousMonth: string;
537
+ nextMonth: string;
538
+ dialog: string;
539
+ selectDateTime: string;
540
+ selectDateRange: string;
541
+ };
529
542
  type DateTimeBaseProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> & FieldBaseProps & {
530
543
  format?: string;
531
544
  disabled?: boolean;
532
545
  placeholder?: string;
533
546
  locale?: string;
547
+ /** Overrides the text chosen from `locale` (Vietnamese for `vi*`, otherwise English). */
548
+ labels?: Partial<DateTimePickerLabels>;
534
549
  };
535
550
  type DateTimePickerSingleProps = DateTimeBaseProps & {
536
551
  mode?: 'single';
@@ -1017,4 +1032,4 @@ declare function NotFoundLost(props: NotFoundSceneProps): react.JSX.Element;
1017
1032
  /** A 404 page with a stable random design, or an explicitly selected variant. */
1018
1033
  declare function NotFound({ variant, ...props }: NotFoundProps): react.JSX.Element;
1019
1034
 
1020
- export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, Button, ButtonBar, type ButtonBarAction, type ButtonBarItem, type ButtonBarProps, type ButtonColor, type ButtonHierarchy, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipStatus, type ChipVariant, type ColumnResizeHandler, type ControlLabelPosition, type Currency, CurrencyInput, type CurrencyInputProps, type DateRange, DateTimePicker, type DateTimePickerProps, type DateTimePickerRangeProps, type DateTimePickerSingleProps, type DescriptionDisplay, Drawer, type DrawerProps, type DrawerSide, type DrawerWidth, type DrawerWidthPreset, DrawerWidths, EmailInput, type EmailInputProps, ExpandableSection, type ExpandableSectionProps, FILE_UPLOAD_ACCEPTS, type FieldError, FilePreview, type FilePreviewActionHandler, type FilePreviewCloseReason, type FilePreviewKind, type FilePreviewProps, FileUpload, type FileUploadAccept, type FileUploadFileType, type FileUploadProps, type FileUploadRejection, type FileUploadRejectionCode, type InputValidator, Loading, type LoadingProps, type LoadingSize, Message, type MessageOptions, type MessageProps, type MessageSeverity, Modal, type ModalAction, type ModalProps, type ModalSize, NotFound, NotFoundCaveman, NotFoundLost, type NotFoundProps, type NotFoundSceneProps, type NotFoundVariant, NotFoundYeti, NumberInput, type NumberInputProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, PhoneNumberInput, type PhoneNumberInputProps, ProgressBar, type ProgressBarProps, type ProgressBarSize, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioValue, Selection, type SelectionOption, type SelectionOverflow, type SelectionProps, type SelectionValue, Skeleton, SkeletonBox, type SkeletonBoxProps, SkeletonCircle, SkeletonLine, type SkeletonProps, type SkeletonSizeProps, SkeletonSquare, type SkeletonVariant, Snackbar, type SnackbarAnchorOrigin, type SnackbarProps, type TabChangeEvent, type TabItem, Table, TableBody, TableCaption, TableCell, type TableCellProps, type TableColumn, type TableColumnWidths, type TableData, TableHead, TableHeader, type TableHeaderProps, type TablePaginationPosition, type TableProps, type TableResizeHandler, TableRow, Tabs, type TabsProps, type TabsScrollButtons, type TabsVariant, TextArea, type TextAreaProps, TextInput, type TextInputProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, type ValidatedTextInputProps, type ValidationTiming, formatFileSize, formatNumber, getFilePreviewKind, getIconSize, message, normalizePhoneNumber, validateEmail, validatePassword, validatePhoneNumber };
1035
+ export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, Button, ButtonBar, type ButtonBarAction, type ButtonBarItem, type ButtonBarProps, type ButtonColor, type ButtonHierarchy, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipStatus, type ChipVariant, type ColumnResizeHandler, type ControlLabelPosition, type Currency, CurrencyInput, type CurrencyInputProps, type DateRange, DateTimePicker, type DateTimePickerLabels, type DateTimePickerProps, type DateTimePickerRangeProps, type DateTimePickerSingleProps, type DescriptionDisplay, Drawer, type DrawerProps, type DrawerSide, type DrawerWidth, type DrawerWidthPreset, DrawerWidths, EmailInput, type EmailInputProps, ExpandableSection, type ExpandableSectionProps, FILE_UPLOAD_ACCEPTS, type FieldError, FilePreview, type FilePreviewActionHandler, type FilePreviewCloseReason, type FilePreviewKind, type FilePreviewProps, FileUpload, type FileUploadAccept, type FileUploadFileType, type FileUploadProps, type FileUploadRejection, type FileUploadRejectionCode, type InputValidator, Loading, type LoadingProps, type LoadingSize, Message, type MessageOptions, type MessageProps, type MessageSeverity, Modal, type ModalAction, type ModalProps, type ModalSize, NotFound, NotFoundCaveman, NotFoundLost, type NotFoundProps, type NotFoundSceneProps, type NotFoundVariant, NotFoundYeti, NumberInput, type NumberInputProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, PhoneNumberInput, type PhoneNumberInputProps, ProgressBar, type ProgressBarProps, type ProgressBarSize, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioValue, Selection, type SelectionOption, type SelectionOverflow, type SelectionProps, type SelectionValue, Skeleton, SkeletonBox, type SkeletonBoxProps, SkeletonCircle, SkeletonLine, type SkeletonProps, type SkeletonSizeProps, SkeletonSquare, type SkeletonVariant, Snackbar, type SnackbarAnchorOrigin, type SnackbarProps, type TabChangeEvent, type TabItem, Table, TableBody, TableCaption, TableCell, type TableCellProps, type TableColumn, type TableColumnWidths, type TableData, TableHead, TableHeader, type TableHeaderProps, type TablePaginationPosition, type TableProps, type TableResizeHandler, TableRow, Tabs, type TabsProps, type TabsScrollButtons, type TabsVariant, TextArea, type TextAreaProps, TextInput, type TextInputProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, type ValidatedTextInputProps, type ValidationTiming, formatFileSize, formatNumber, getFilePreviewKind, getIconSize, message, normalizePhoneNumber, validateEmail, validatePassword, validatePhoneNumber };
package/dist/index.d.ts CHANGED
@@ -526,11 +526,26 @@ type CurrencyInputProps = Omit<NumberInputProps, 'suffix' | 'endAdornment'> & {
526
526
  declare function CurrencyInput({ suffix, currencies, currency, defaultCurrency, onCurrencyChange, className, disabled, ...props }: CurrencyInputProps): react.JSX.Element;
527
527
 
528
528
  type DateRange = [Date | null, Date | null];
529
+ /** Text of the picker. `weekdays` runs from Monday to Sunday. */
530
+ type DateTimePickerLabels = {
531
+ weekdays: readonly [string, string, string, string, string, string, string];
532
+ today: string;
533
+ time: string;
534
+ start: string;
535
+ end: string;
536
+ previousMonth: string;
537
+ nextMonth: string;
538
+ dialog: string;
539
+ selectDateTime: string;
540
+ selectDateRange: string;
541
+ };
529
542
  type DateTimeBaseProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> & FieldBaseProps & {
530
543
  format?: string;
531
544
  disabled?: boolean;
532
545
  placeholder?: string;
533
546
  locale?: string;
547
+ /** Overrides the text chosen from `locale` (Vietnamese for `vi*`, otherwise English). */
548
+ labels?: Partial<DateTimePickerLabels>;
534
549
  };
535
550
  type DateTimePickerSingleProps = DateTimeBaseProps & {
536
551
  mode?: 'single';
@@ -1017,4 +1032,4 @@ declare function NotFoundLost(props: NotFoundSceneProps): react.JSX.Element;
1017
1032
  /** A 404 page with a stable random design, or an explicitly selected variant. */
1018
1033
  declare function NotFound({ variant, ...props }: NotFoundProps): react.JSX.Element;
1019
1034
 
1020
- export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, Button, ButtonBar, type ButtonBarAction, type ButtonBarItem, type ButtonBarProps, type ButtonColor, type ButtonHierarchy, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipStatus, type ChipVariant, type ColumnResizeHandler, type ControlLabelPosition, type Currency, CurrencyInput, type CurrencyInputProps, type DateRange, DateTimePicker, type DateTimePickerProps, type DateTimePickerRangeProps, type DateTimePickerSingleProps, type DescriptionDisplay, Drawer, type DrawerProps, type DrawerSide, type DrawerWidth, type DrawerWidthPreset, DrawerWidths, EmailInput, type EmailInputProps, ExpandableSection, type ExpandableSectionProps, FILE_UPLOAD_ACCEPTS, type FieldError, FilePreview, type FilePreviewActionHandler, type FilePreviewCloseReason, type FilePreviewKind, type FilePreviewProps, FileUpload, type FileUploadAccept, type FileUploadFileType, type FileUploadProps, type FileUploadRejection, type FileUploadRejectionCode, type InputValidator, Loading, type LoadingProps, type LoadingSize, Message, type MessageOptions, type MessageProps, type MessageSeverity, Modal, type ModalAction, type ModalProps, type ModalSize, NotFound, NotFoundCaveman, NotFoundLost, type NotFoundProps, type NotFoundSceneProps, type NotFoundVariant, NotFoundYeti, NumberInput, type NumberInputProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, PhoneNumberInput, type PhoneNumberInputProps, ProgressBar, type ProgressBarProps, type ProgressBarSize, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioValue, Selection, type SelectionOption, type SelectionOverflow, type SelectionProps, type SelectionValue, Skeleton, SkeletonBox, type SkeletonBoxProps, SkeletonCircle, SkeletonLine, type SkeletonProps, type SkeletonSizeProps, SkeletonSquare, type SkeletonVariant, Snackbar, type SnackbarAnchorOrigin, type SnackbarProps, type TabChangeEvent, type TabItem, Table, TableBody, TableCaption, TableCell, type TableCellProps, type TableColumn, type TableColumnWidths, type TableData, TableHead, TableHeader, type TableHeaderProps, type TablePaginationPosition, type TableProps, type TableResizeHandler, TableRow, Tabs, type TabsProps, type TabsScrollButtons, type TabsVariant, TextArea, type TextAreaProps, TextInput, type TextInputProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, type ValidatedTextInputProps, type ValidationTiming, formatFileSize, formatNumber, getFilePreviewKind, getIconSize, message, normalizePhoneNumber, validateEmail, validatePassword, validatePhoneNumber };
1035
+ export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarShape, type AvatarSize, Button, ButtonBar, type ButtonBarAction, type ButtonBarItem, type ButtonBarProps, type ButtonColor, type ButtonHierarchy, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipStatus, type ChipVariant, type ColumnResizeHandler, type ControlLabelPosition, type Currency, CurrencyInput, type CurrencyInputProps, type DateRange, DateTimePicker, type DateTimePickerLabels, type DateTimePickerProps, type DateTimePickerRangeProps, type DateTimePickerSingleProps, type DescriptionDisplay, Drawer, type DrawerProps, type DrawerSide, type DrawerWidth, type DrawerWidthPreset, DrawerWidths, EmailInput, type EmailInputProps, ExpandableSection, type ExpandableSectionProps, FILE_UPLOAD_ACCEPTS, type FieldError, FilePreview, type FilePreviewActionHandler, type FilePreviewCloseReason, type FilePreviewKind, type FilePreviewProps, FileUpload, type FileUploadAccept, type FileUploadFileType, type FileUploadProps, type FileUploadRejection, type FileUploadRejectionCode, type InputValidator, Loading, type LoadingProps, type LoadingSize, Message, type MessageOptions, type MessageProps, type MessageSeverity, Modal, type ModalAction, type ModalProps, type ModalSize, NotFound, NotFoundCaveman, NotFoundLost, type NotFoundProps, type NotFoundSceneProps, type NotFoundVariant, NotFoundYeti, NumberInput, type NumberInputProps, Pagination, type PaginationProps, PasswordInput, type PasswordInputProps, PhoneNumberInput, type PhoneNumberInputProps, ProgressBar, type ProgressBarProps, type ProgressBarSize, RadioButton, type RadioButtonProps, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioValue, Selection, type SelectionOption, type SelectionOverflow, type SelectionProps, type SelectionValue, Skeleton, SkeletonBox, type SkeletonBoxProps, SkeletonCircle, SkeletonLine, type SkeletonProps, type SkeletonSizeProps, SkeletonSquare, type SkeletonVariant, Snackbar, type SnackbarAnchorOrigin, type SnackbarProps, type TabChangeEvent, type TabItem, Table, TableBody, TableCaption, TableCell, type TableCellProps, type TableColumn, type TableColumnWidths, type TableData, TableHead, TableHeader, type TableHeaderProps, type TablePaginationPosition, type TableProps, type TableResizeHandler, TableRow, Tabs, type TabsProps, type TabsScrollButtons, type TabsVariant, TextArea, type TextAreaProps, TextInput, type TextInputProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, type ValidatedTextInputProps, type ValidationTiming, formatFileSize, formatNumber, getFilePreviewKind, getIconSize, message, normalizePhoneNumber, validateEmail, validatePassword, validatePhoneNumber };
package/dist/index.js CHANGED
@@ -2819,6 +2819,30 @@ function CurrencyInput({
2819
2819
  // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
2820
2820
  var import_react20 = require("react");
2821
2821
  var import_jsx_runtime22 = require("react/jsx-runtime");
2822
+ var LABELS_EN = {
2823
+ weekdays: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
2824
+ today: "Today",
2825
+ time: "Time",
2826
+ start: "Start",
2827
+ end: "End",
2828
+ previousMonth: "Previous month",
2829
+ nextMonth: "Next month",
2830
+ dialog: "Date and time picker",
2831
+ selectDateTime: "Select date and time",
2832
+ selectDateRange: "Select date range"
2833
+ };
2834
+ var LABELS_VI = {
2835
+ weekdays: ["T2", "T3", "T4", "T5", "T6", "T7", "CN"],
2836
+ today: "H\xF4m nay",
2837
+ time: "Gi\u1EDD",
2838
+ start: "B\u1EAFt \u0111\u1EA7u",
2839
+ end: "K\u1EBFt th\xFAc",
2840
+ previousMonth: "Th\xE1ng tr\u01B0\u1EDBc",
2841
+ nextMonth: "Th\xE1ng sau",
2842
+ dialog: "Ch\u1ECDn ng\xE0y v\xE0 gi\u1EDD",
2843
+ selectDateTime: "Ch\u1ECDn ng\xE0y v\xE0 gi\u1EDD",
2844
+ selectDateRange: "Ch\u1ECDn kho\u1EA3ng ng\xE0y"
2845
+ };
2822
2846
  var pad = (value) => String(value).padStart(2, "0");
2823
2847
  function formatDate(date, format) {
2824
2848
  return format.replace(/yyyy/g, String(date.getFullYear())).replace(/MM/g, pad(date.getMonth() + 1)).replace(/dd/g, pad(date.getDate())).replace(/HH/g, pad(date.getHours())).replace(/mm/g, pad(date.getMinutes()));
@@ -2848,12 +2872,17 @@ function DateTimePicker(props) {
2848
2872
  disabled,
2849
2873
  placeholder,
2850
2874
  locale = "en-US",
2875
+ labels,
2851
2876
  className,
2852
2877
  mode = "single",
2853
2878
  id,
2854
2879
  "aria-describedby": ariaDescribedBy,
2855
2880
  "aria-labelledby": ariaLabelledBy
2856
2881
  } = props;
2882
+ const text = {
2883
+ ...locale.toLowerCase().startsWith("vi") ? LABELS_VI : LABELS_EN,
2884
+ ...labels
2885
+ };
2857
2886
  const generatedId = (0, import_react20.useId)();
2858
2887
  const triggerId = id ?? generatedId + "-trigger";
2859
2888
  const labelId = generatedId + "-label";
@@ -2941,6 +2970,15 @@ function DateTimePicker(props) {
2941
2970
  { length: 42 },
2942
2971
  (_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1)
2943
2972
  );
2973
+ const today = /* @__PURE__ */ new Date();
2974
+ const selectToday = () => {
2975
+ setMonth(today);
2976
+ selectDay(today);
2977
+ };
2978
+ const toggleOpen = () => {
2979
+ if (!open) setMonth((isRange ? rangeValue[0] : singleValue) ?? today);
2980
+ setOpen(!open);
2981
+ };
2944
2982
  const selectedForTime = isRange ? editingEnd ? rangeValue[1] : rangeValue[0] : singleValue;
2945
2983
  const setTime = (time) => {
2946
2984
  if (!selectedForTime) return;
@@ -2981,7 +3019,7 @@ function DateTimePicker(props) {
2981
3019
  "aria-labelledby": labelledBy,
2982
3020
  "aria-describedby": describedBy,
2983
3021
  "aria-expanded": open,
2984
- onClick: () => setOpen((current) => !current),
3022
+ onClick: toggleOpen,
2985
3023
  children: [
2986
3024
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
2987
3025
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
@@ -2989,7 +3027,7 @@ function DateTimePicker(props) {
2989
3027
  {
2990
3028
  className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
2991
3029
  children: [
2992
- shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
3030
+ shownValue || placeholder || (isRange ? text.selectDateRange : text.selectDateTime),
2993
3031
  isRequired && placeholder && !shownValue && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
2994
3032
  ]
2995
3033
  }
@@ -3002,14 +3040,14 @@ function DateTimePicker(props) {
3002
3040
  {
3003
3041
  className: "fe-datetime-picker__popper",
3004
3042
  role: "dialog",
3005
- "aria-label": "Date and time picker",
3043
+ "aria-label": text.dialog,
3006
3044
  children: [
3007
3045
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__month", children: [
3008
3046
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3009
3047
  "button",
3010
3048
  {
3011
3049
  type: "button",
3012
- "aria-label": "Previous month",
3050
+ "aria-label": text.previousMonth,
3013
3051
  onClick: () => setMonth(
3014
3052
  (current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
3015
3053
  ),
@@ -3024,7 +3062,7 @@ function DateTimePicker(props) {
3024
3062
  "button",
3025
3063
  {
3026
3064
  type: "button",
3027
- "aria-label": "Next month",
3065
+ "aria-label": text.nextMonth,
3028
3066
  onClick: () => setMonth(
3029
3067
  (current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
3030
3068
  ),
@@ -3032,17 +3070,20 @@ function DateTimePicker(props) {
3032
3070
  }
3033
3071
  )
3034
3072
  ] }),
3035
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: day }, day)) }),
3073
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__weekdays", children: text.weekdays.map((day) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: day }, day)) }),
3036
3074
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
3037
3075
  const inMonth = day.getMonth() === month.getMonth();
3038
3076
  const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
3039
3077
  const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
3078
+ const isToday = sameDay(day, today);
3040
3079
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3041
3080
  "button",
3042
3081
  {
3043
3082
  type: "button",
3083
+ "aria-current": isToday ? "date" : void 0,
3044
3084
  className: [
3045
3085
  !inMonth && "is-other-month",
3086
+ isToday && "is-today",
3046
3087
  selected && "is-selected",
3047
3088
  inRange && "is-in-range"
3048
3089
  ].filter(Boolean).join(" "),
@@ -3052,6 +3093,7 @@ function DateTimePicker(props) {
3052
3093
  day.toISOString()
3053
3094
  );
3054
3095
  }) }),
3096
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__footer", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", onClick: selectToday, children: text.today }) }),
3055
3097
  isRange && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
3056
3098
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3057
3099
  "button",
@@ -3059,7 +3101,7 @@ function DateTimePicker(props) {
3059
3101
  type: "button",
3060
3102
  className: !editingEnd ? "is-active" : "",
3061
3103
  onClick: () => setEditingEnd(false),
3062
- children: "Start"
3104
+ children: text.start
3063
3105
  }
3064
3106
  ),
3065
3107
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
@@ -3068,12 +3110,12 @@ function DateTimePicker(props) {
3068
3110
  type: "button",
3069
3111
  className: editingEnd ? "is-active" : "",
3070
3112
  onClick: () => setEditingEnd(true),
3071
- children: "End"
3113
+ children: text.end
3072
3114
  }
3073
3115
  )
3074
3116
  ] }),
3075
3117
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "fe-datetime-picker__time", children: [
3076
- "Time",
3118
+ text.time,
3077
3119
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3078
3120
  "input",
3079
3121
  {
package/dist/index.mjs CHANGED
@@ -2519,6 +2519,30 @@ function CurrencyInput({
2519
2519
  // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
2520
2520
  import { useEffect as useEffect7, useId as useId9, useRef as useRef9, useState as useState14 } from "react";
2521
2521
  import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
2522
+ var LABELS_EN = {
2523
+ weekdays: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
2524
+ today: "Today",
2525
+ time: "Time",
2526
+ start: "Start",
2527
+ end: "End",
2528
+ previousMonth: "Previous month",
2529
+ nextMonth: "Next month",
2530
+ dialog: "Date and time picker",
2531
+ selectDateTime: "Select date and time",
2532
+ selectDateRange: "Select date range"
2533
+ };
2534
+ var LABELS_VI = {
2535
+ weekdays: ["T2", "T3", "T4", "T5", "T6", "T7", "CN"],
2536
+ today: "H\xF4m nay",
2537
+ time: "Gi\u1EDD",
2538
+ start: "B\u1EAFt \u0111\u1EA7u",
2539
+ end: "K\u1EBFt th\xFAc",
2540
+ previousMonth: "Th\xE1ng tr\u01B0\u1EDBc",
2541
+ nextMonth: "Th\xE1ng sau",
2542
+ dialog: "Ch\u1ECDn ng\xE0y v\xE0 gi\u1EDD",
2543
+ selectDateTime: "Ch\u1ECDn ng\xE0y v\xE0 gi\u1EDD",
2544
+ selectDateRange: "Ch\u1ECDn kho\u1EA3ng ng\xE0y"
2545
+ };
2522
2546
  var pad = (value) => String(value).padStart(2, "0");
2523
2547
  function formatDate(date, format) {
2524
2548
  return format.replace(/yyyy/g, String(date.getFullYear())).replace(/MM/g, pad(date.getMonth() + 1)).replace(/dd/g, pad(date.getDate())).replace(/HH/g, pad(date.getHours())).replace(/mm/g, pad(date.getMinutes()));
@@ -2548,12 +2572,17 @@ function DateTimePicker(props) {
2548
2572
  disabled,
2549
2573
  placeholder,
2550
2574
  locale = "en-US",
2575
+ labels,
2551
2576
  className,
2552
2577
  mode = "single",
2553
2578
  id,
2554
2579
  "aria-describedby": ariaDescribedBy,
2555
2580
  "aria-labelledby": ariaLabelledBy
2556
2581
  } = props;
2582
+ const text = {
2583
+ ...locale.toLowerCase().startsWith("vi") ? LABELS_VI : LABELS_EN,
2584
+ ...labels
2585
+ };
2557
2586
  const generatedId = useId9();
2558
2587
  const triggerId = id ?? generatedId + "-trigger";
2559
2588
  const labelId = generatedId + "-label";
@@ -2641,6 +2670,15 @@ function DateTimePicker(props) {
2641
2670
  { length: 42 },
2642
2671
  (_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1)
2643
2672
  );
2673
+ const today = /* @__PURE__ */ new Date();
2674
+ const selectToday = () => {
2675
+ setMonth(today);
2676
+ selectDay(today);
2677
+ };
2678
+ const toggleOpen = () => {
2679
+ if (!open) setMonth((isRange ? rangeValue[0] : singleValue) ?? today);
2680
+ setOpen(!open);
2681
+ };
2644
2682
  const selectedForTime = isRange ? editingEnd ? rangeValue[1] : rangeValue[0] : singleValue;
2645
2683
  const setTime = (time) => {
2646
2684
  if (!selectedForTime) return;
@@ -2681,7 +2719,7 @@ function DateTimePicker(props) {
2681
2719
  "aria-labelledby": labelledBy,
2682
2720
  "aria-describedby": describedBy,
2683
2721
  "aria-expanded": open,
2684
- onClick: () => setOpen((current) => !current),
2722
+ onClick: toggleOpen,
2685
2723
  children: [
2686
2724
  /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", children: "\u25F7" }),
2687
2725
  /* @__PURE__ */ jsxs14(
@@ -2689,7 +2727,7 @@ function DateTimePicker(props) {
2689
2727
  {
2690
2728
  className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
2691
2729
  children: [
2692
- shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
2730
+ shownValue || placeholder || (isRange ? text.selectDateRange : text.selectDateTime),
2693
2731
  isRequired && placeholder && !shownValue && /* @__PURE__ */ jsx18("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
2694
2732
  ]
2695
2733
  }
@@ -2702,14 +2740,14 @@ function DateTimePicker(props) {
2702
2740
  {
2703
2741
  className: "fe-datetime-picker__popper",
2704
2742
  role: "dialog",
2705
- "aria-label": "Date and time picker",
2743
+ "aria-label": text.dialog,
2706
2744
  children: [
2707
2745
  /* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__month", children: [
2708
2746
  /* @__PURE__ */ jsx18(
2709
2747
  "button",
2710
2748
  {
2711
2749
  type: "button",
2712
- "aria-label": "Previous month",
2750
+ "aria-label": text.previousMonth,
2713
2751
  onClick: () => setMonth(
2714
2752
  (current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
2715
2753
  ),
@@ -2724,7 +2762,7 @@ function DateTimePicker(props) {
2724
2762
  "button",
2725
2763
  {
2726
2764
  type: "button",
2727
- "aria-label": "Next month",
2765
+ "aria-label": text.nextMonth,
2728
2766
  onClick: () => setMonth(
2729
2767
  (current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
2730
2768
  ),
@@ -2732,17 +2770,20 @@ function DateTimePicker(props) {
2732
2770
  }
2733
2771
  )
2734
2772
  ] }),
2735
- /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx18("span", { children: day }, day)) }),
2773
+ /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__weekdays", children: text.weekdays.map((day) => /* @__PURE__ */ jsx18("span", { children: day }, day)) }),
2736
2774
  /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
2737
2775
  const inMonth = day.getMonth() === month.getMonth();
2738
2776
  const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
2739
2777
  const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
2778
+ const isToday = sameDay(day, today);
2740
2779
  return /* @__PURE__ */ jsx18(
2741
2780
  "button",
2742
2781
  {
2743
2782
  type: "button",
2783
+ "aria-current": isToday ? "date" : void 0,
2744
2784
  className: [
2745
2785
  !inMonth && "is-other-month",
2786
+ isToday && "is-today",
2746
2787
  selected && "is-selected",
2747
2788
  inRange && "is-in-range"
2748
2789
  ].filter(Boolean).join(" "),
@@ -2752,6 +2793,7 @@ function DateTimePicker(props) {
2752
2793
  day.toISOString()
2753
2794
  );
2754
2795
  }) }),
2796
+ /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__footer", children: /* @__PURE__ */ jsx18("button", { type: "button", onClick: selectToday, children: text.today }) }),
2755
2797
  isRange && /* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__range-tabs", children: [
2756
2798
  /* @__PURE__ */ jsx18(
2757
2799
  "button",
@@ -2759,7 +2801,7 @@ function DateTimePicker(props) {
2759
2801
  type: "button",
2760
2802
  className: !editingEnd ? "is-active" : "",
2761
2803
  onClick: () => setEditingEnd(false),
2762
- children: "Start"
2804
+ children: text.start
2763
2805
  }
2764
2806
  ),
2765
2807
  /* @__PURE__ */ jsx18(
@@ -2768,12 +2810,12 @@ function DateTimePicker(props) {
2768
2810
  type: "button",
2769
2811
  className: editingEnd ? "is-active" : "",
2770
2812
  onClick: () => setEditingEnd(true),
2771
- children: "End"
2813
+ children: text.end
2772
2814
  }
2773
2815
  )
2774
2816
  ] }),
2775
2817
  /* @__PURE__ */ jsxs14("label", { className: "fe-datetime-picker__time", children: [
2776
- "Time",
2818
+ text.time,
2777
2819
  /* @__PURE__ */ jsx18(
2778
2820
  "input",
2779
2821
  {
package/dist/styles.css CHANGED
@@ -1711,6 +1711,34 @@ table[data-fe-table][data-resizing] {
1711
1711
  .fe-datetime-picker__days button.is-other-month {
1712
1712
  color: #aab0bb;
1713
1713
  }
1714
+ .fe-datetime-picker__days button.is-today {
1715
+ box-shadow: inset 0 0 0 1.5px #2878f0;
1716
+ color: #1e60cc;
1717
+ font-weight: 700;
1718
+ }
1719
+ .fe-datetime-picker__days button.is-today.is-selected {
1720
+ box-shadow: inset 0 0 0 1.5px #2878f0, inset 0 0 0 3px #fff;
1721
+ color: #fff;
1722
+ }
1723
+ .fe-datetime-picker__footer {
1724
+ display: flex;
1725
+ justify-content: center;
1726
+ margin-top: 8px;
1727
+ }
1728
+ .fe-datetime-picker__footer button {
1729
+ padding: 5px 12px;
1730
+ border: 0;
1731
+ border-radius: 8px;
1732
+ background: transparent;
1733
+ color: #1e60cc;
1734
+ font: inherit;
1735
+ font-size: 13px;
1736
+ font-weight: 600;
1737
+ cursor: pointer;
1738
+ }
1739
+ .fe-datetime-picker__footer button:hover {
1740
+ background: #f0f5ff;
1741
+ }
1714
1742
  .fe-datetime-picker__range-tabs {
1715
1743
  display: flex;
1716
1744
  gap: 4px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dragunio/fe-libs",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Reusable React components, icons, and table primitives.",
5
5
  "license": "MIT",
6
6
  "repository": {