@dragunio/fe-libs 0.1.11 → 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 +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +95 -15
- package/dist/index.mjs +95 -15
- package/dist/styles.css +66 -4
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -411,7 +411,21 @@ type SelectionProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'default
|
|
|
411
411
|
disabled?: boolean;
|
|
412
412
|
name?: string;
|
|
413
413
|
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
414
|
+
/**
|
|
415
|
+
* Caps the field width. Numbers are pixels (`240` → `240px`); strings are
|
|
416
|
+
* any CSS length (`'16rem'`, `'50%'`). The field still shrinks inside
|
|
417
|
+
* narrower containers.
|
|
418
|
+
*/
|
|
419
|
+
maxWidth?: number | string;
|
|
420
|
+
/**
|
|
421
|
+
* How a selected label longer than the field is shown:
|
|
422
|
+
* - `'ellipsis'` (default): one line ending in `…`; the full text appears
|
|
423
|
+
* in a tooltip on hover or focus.
|
|
424
|
+
* - `'wrap'`: the label wraps onto more lines and the field grows taller.
|
|
425
|
+
*/
|
|
426
|
+
overflow?: SelectionOverflow;
|
|
414
427
|
};
|
|
428
|
+
type SelectionOverflow = 'ellipsis' | 'wrap';
|
|
415
429
|
|
|
416
430
|
/** A rounded, searchable custom dropdown with single, multiple, and tag modes. */
|
|
417
431
|
declare const Selection: react.ForwardRefExoticComponent<Omit<react.HTMLAttributes<HTMLDivElement>, "value" | "defaultValue" | "onChange" | "onKeyDown"> & {
|
|
@@ -435,6 +449,8 @@ declare const Selection: react.ForwardRefExoticComponent<Omit<react.HTMLAttribut
|
|
|
435
449
|
disabled?: boolean;
|
|
436
450
|
name?: string;
|
|
437
451
|
onKeyDown?: react.KeyboardEventHandler<HTMLButtonElement>;
|
|
452
|
+
maxWidth?: number | string;
|
|
453
|
+
overflow?: SelectionOverflow;
|
|
438
454
|
} & react.RefAttributes<HTMLDivElement>>;
|
|
439
455
|
|
|
440
456
|
declare function formatNumber(value: number, decimals?: number, thousandSeparator?: string, decimalSeparator?: string): string;
|
|
@@ -510,11 +526,26 @@ type CurrencyInputProps = Omit<NumberInputProps, 'suffix' | 'endAdornment'> & {
|
|
|
510
526
|
declare function CurrencyInput({ suffix, currencies, currency, defaultCurrency, onCurrencyChange, className, disabled, ...props }: CurrencyInputProps): react.JSX.Element;
|
|
511
527
|
|
|
512
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
|
+
};
|
|
513
542
|
type DateTimeBaseProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> & FieldBaseProps & {
|
|
514
543
|
format?: string;
|
|
515
544
|
disabled?: boolean;
|
|
516
545
|
placeholder?: string;
|
|
517
546
|
locale?: string;
|
|
547
|
+
/** Overrides the text chosen from `locale` (Vietnamese for `vi*`, otherwise English). */
|
|
548
|
+
labels?: Partial<DateTimePickerLabels>;
|
|
518
549
|
};
|
|
519
550
|
type DateTimePickerSingleProps = DateTimeBaseProps & {
|
|
520
551
|
mode?: 'single';
|
|
@@ -1001,4 +1032,4 @@ declare function NotFoundLost(props: NotFoundSceneProps): react.JSX.Element;
|
|
|
1001
1032
|
/** A 404 page with a stable random design, or an explicitly selected variant. */
|
|
1002
1033
|
declare function NotFound({ variant, ...props }: NotFoundProps): react.JSX.Element;
|
|
1003
1034
|
|
|
1004
|
-
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 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
|
@@ -411,7 +411,21 @@ type SelectionProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'default
|
|
|
411
411
|
disabled?: boolean;
|
|
412
412
|
name?: string;
|
|
413
413
|
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
414
|
+
/**
|
|
415
|
+
* Caps the field width. Numbers are pixels (`240` → `240px`); strings are
|
|
416
|
+
* any CSS length (`'16rem'`, `'50%'`). The field still shrinks inside
|
|
417
|
+
* narrower containers.
|
|
418
|
+
*/
|
|
419
|
+
maxWidth?: number | string;
|
|
420
|
+
/**
|
|
421
|
+
* How a selected label longer than the field is shown:
|
|
422
|
+
* - `'ellipsis'` (default): one line ending in `…`; the full text appears
|
|
423
|
+
* in a tooltip on hover or focus.
|
|
424
|
+
* - `'wrap'`: the label wraps onto more lines and the field grows taller.
|
|
425
|
+
*/
|
|
426
|
+
overflow?: SelectionOverflow;
|
|
414
427
|
};
|
|
428
|
+
type SelectionOverflow = 'ellipsis' | 'wrap';
|
|
415
429
|
|
|
416
430
|
/** A rounded, searchable custom dropdown with single, multiple, and tag modes. */
|
|
417
431
|
declare const Selection: react.ForwardRefExoticComponent<Omit<react.HTMLAttributes<HTMLDivElement>, "value" | "defaultValue" | "onChange" | "onKeyDown"> & {
|
|
@@ -435,6 +449,8 @@ declare const Selection: react.ForwardRefExoticComponent<Omit<react.HTMLAttribut
|
|
|
435
449
|
disabled?: boolean;
|
|
436
450
|
name?: string;
|
|
437
451
|
onKeyDown?: react.KeyboardEventHandler<HTMLButtonElement>;
|
|
452
|
+
maxWidth?: number | string;
|
|
453
|
+
overflow?: SelectionOverflow;
|
|
438
454
|
} & react.RefAttributes<HTMLDivElement>>;
|
|
439
455
|
|
|
440
456
|
declare function formatNumber(value: number, decimals?: number, thousandSeparator?: string, decimalSeparator?: string): string;
|
|
@@ -510,11 +526,26 @@ type CurrencyInputProps = Omit<NumberInputProps, 'suffix' | 'endAdornment'> & {
|
|
|
510
526
|
declare function CurrencyInput({ suffix, currencies, currency, defaultCurrency, onCurrencyChange, className, disabled, ...props }: CurrencyInputProps): react.JSX.Element;
|
|
511
527
|
|
|
512
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
|
+
};
|
|
513
542
|
type DateTimeBaseProps = Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'> & FieldBaseProps & {
|
|
514
543
|
format?: string;
|
|
515
544
|
disabled?: boolean;
|
|
516
545
|
placeholder?: string;
|
|
517
546
|
locale?: string;
|
|
547
|
+
/** Overrides the text chosen from `locale` (Vietnamese for `vi*`, otherwise English). */
|
|
548
|
+
labels?: Partial<DateTimePickerLabels>;
|
|
518
549
|
};
|
|
519
550
|
type DateTimePickerSingleProps = DateTimeBaseProps & {
|
|
520
551
|
mode?: 'single';
|
|
@@ -1001,4 +1032,4 @@ declare function NotFoundLost(props: NotFoundSceneProps): react.JSX.Element;
|
|
|
1001
1032
|
/** A 404 page with a stable random design, or an explicitly selected variant. */
|
|
1002
1033
|
declare function NotFound({ variant, ...props }: NotFoundProps): react.JSX.Element;
|
|
1003
1034
|
|
|
1004
|
-
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 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
|
@@ -2127,6 +2127,9 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2127
2127
|
disabled = false,
|
|
2128
2128
|
name,
|
|
2129
2129
|
onKeyDown,
|
|
2130
|
+
maxWidth,
|
|
2131
|
+
overflow = "ellipsis",
|
|
2132
|
+
style,
|
|
2130
2133
|
"aria-label": ariaLabel,
|
|
2131
2134
|
"aria-describedby": ariaDescribedBy,
|
|
2132
2135
|
"aria-labelledby": ariaLabelledBy,
|
|
@@ -2137,6 +2140,7 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2137
2140
|
const listboxId = triggerId + "-listbox";
|
|
2138
2141
|
const labelId = generatedId + "-label";
|
|
2139
2142
|
const messageId2 = generatedId + "-message";
|
|
2143
|
+
const tooltipId = generatedId + "-tooltip";
|
|
2140
2144
|
const fieldError = getFieldError(error, errorMessage);
|
|
2141
2145
|
const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
|
|
2142
2146
|
const resolvedDescription = description ?? helperText;
|
|
@@ -2163,6 +2167,26 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2163
2167
|
const [activeIndex, setActiveIndex] = (0, import_react17.useState)(0);
|
|
2164
2168
|
const rootRef = (0, import_react17.useRef)(null);
|
|
2165
2169
|
const menuRef = (0, import_react17.useRef)(null);
|
|
2170
|
+
const valueRef = (0, import_react17.useRef)(null);
|
|
2171
|
+
const [truncated, setTruncated] = (0, import_react17.useState)(false);
|
|
2172
|
+
const [hovered, setHovered] = (0, import_react17.useState)(false);
|
|
2173
|
+
const [focused, setFocused] = (0, import_react17.useState)(false);
|
|
2174
|
+
const showsTags = tag && multiple && selectedOptions.length > 0;
|
|
2175
|
+
const canTruncate = overflow === "ellipsis" && !showsTags && selectedOptions.length > 0;
|
|
2176
|
+
const selectedKey = selectedOptions.map((option) => String(option.value)).join("|");
|
|
2177
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
2178
|
+
const node = valueRef.current;
|
|
2179
|
+
if (!canTruncate || !node) {
|
|
2180
|
+
setTruncated(false);
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
const measure = () => setTruncated(node.scrollWidth > node.clientWidth + 1);
|
|
2184
|
+
measure();
|
|
2185
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2186
|
+
const observer = new ResizeObserver(measure);
|
|
2187
|
+
observer.observe(node);
|
|
2188
|
+
return () => observer.disconnect();
|
|
2189
|
+
}, [canTruncate, selectedKey]);
|
|
2166
2190
|
const [menuPosition, setMenuPosition] = (0, import_react17.useState)(null);
|
|
2167
2191
|
(0, import_react17.useEffect)(() => {
|
|
2168
2192
|
const close = (event) => {
|
|
@@ -2227,6 +2251,12 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2227
2251
|
setQuery("");
|
|
2228
2252
|
};
|
|
2229
2253
|
const displayLabel = selectedOptions.length ? selectedOptions.map((option) => option.label) : null;
|
|
2254
|
+
const showTooltip = truncated && (hovered || focused) && !open;
|
|
2255
|
+
const renderLabels = () => displayLabel?.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
|
|
2256
|
+
item,
|
|
2257
|
+
index < displayLabel.length - 1 ? ", " : ""
|
|
2258
|
+
] }, index));
|
|
2259
|
+
const toPx = (length) => typeof length === "number" ? length + "px" : length;
|
|
2230
2260
|
const onTriggerKeyDown = (event) => {
|
|
2231
2261
|
onKeyDown?.(event);
|
|
2232
2262
|
if (disabled) return;
|
|
@@ -2258,12 +2288,14 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2258
2288
|
className: [
|
|
2259
2289
|
"fe-selection",
|
|
2260
2290
|
"fe-selection--" + size,
|
|
2291
|
+
"fe-selection--" + overflow,
|
|
2261
2292
|
open && "fe-selection--open",
|
|
2262
2293
|
clearable && selectedOptions.length > 0 && "fe-selection--clearable",
|
|
2263
2294
|
hasError && "fe-selection--error",
|
|
2264
2295
|
disabled && "fe-selection--disabled",
|
|
2265
2296
|
className
|
|
2266
2297
|
].filter(Boolean).join(" "),
|
|
2298
|
+
style: maxWidth === void 0 ? style : { ...style, maxWidth: toPx(maxWidth) },
|
|
2267
2299
|
...props,
|
|
2268
2300
|
children: [
|
|
2269
2301
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -2297,16 +2329,24 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2297
2329
|
"aria-invalid": hasError || void 0,
|
|
2298
2330
|
"aria-required": isRequired || void 0,
|
|
2299
2331
|
"aria-labelledby": labelledBy,
|
|
2300
|
-
"aria-describedby":
|
|
2332
|
+
"aria-describedby": getDescribedBy(
|
|
2333
|
+
describedBy,
|
|
2334
|
+
showTooltip ? tooltipId : void 0
|
|
2335
|
+
),
|
|
2301
2336
|
"aria-haspopup": "listbox",
|
|
2302
2337
|
"aria-expanded": open,
|
|
2303
2338
|
"aria-controls": listboxId,
|
|
2304
2339
|
onClick: () => setOpen((current) => !current),
|
|
2305
2340
|
onKeyDown: onTriggerKeyDown,
|
|
2341
|
+
onMouseEnter: () => setHovered(true),
|
|
2342
|
+
onMouseLeave: () => setHovered(false),
|
|
2343
|
+
onFocus: () => setFocused(true),
|
|
2344
|
+
onBlur: () => setFocused(false),
|
|
2306
2345
|
children: [
|
|
2307
2346
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2308
2347
|
"span",
|
|
2309
2348
|
{
|
|
2349
|
+
ref: valueRef,
|
|
2310
2350
|
className: [
|
|
2311
2351
|
"fe-selection__value",
|
|
2312
2352
|
!selectedOptions.length && "is-placeholder",
|
|
@@ -2322,10 +2362,7 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2322
2362
|
]
|
|
2323
2363
|
},
|
|
2324
2364
|
String(option.value)
|
|
2325
|
-
)) :
|
|
2326
|
-
item,
|
|
2327
|
-
index < displayLabel.length - 1 ? ", " : ""
|
|
2328
|
-
] }, index)) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
2365
|
+
)) : renderLabels() : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
2329
2366
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: placeholder }),
|
|
2330
2367
|
isRequired && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
|
|
2331
2368
|
] })
|
|
@@ -2344,6 +2381,7 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2344
2381
|
onClick: clear
|
|
2345
2382
|
}
|
|
2346
2383
|
),
|
|
2384
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { id: tooltipId, role: "tooltip", className: "fe-selection__tooltip", children: renderLabels() }),
|
|
2347
2385
|
open && menuPosition && (0, import_react_dom2.createPortal)(
|
|
2348
2386
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2349
2387
|
"div",
|
|
@@ -2395,7 +2433,7 @@ var Selection = (0, import_react17.forwardRef)(
|
|
|
2395
2433
|
onMouseMove: () => setActiveIndex(index),
|
|
2396
2434
|
onClick: () => choose(option),
|
|
2397
2435
|
children: [
|
|
2398
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: option.label }),
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-selection__option-label", children: option.label }),
|
|
2399
2437
|
isSelected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2400
2438
|
"span",
|
|
2401
2439
|
{
|
|
@@ -2781,6 +2819,30 @@ function CurrencyInput({
|
|
|
2781
2819
|
// packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
|
|
2782
2820
|
var import_react20 = require("react");
|
|
2783
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
|
+
};
|
|
2784
2846
|
var pad = (value) => String(value).padStart(2, "0");
|
|
2785
2847
|
function formatDate(date, format) {
|
|
2786
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()));
|
|
@@ -2810,12 +2872,17 @@ function DateTimePicker(props) {
|
|
|
2810
2872
|
disabled,
|
|
2811
2873
|
placeholder,
|
|
2812
2874
|
locale = "en-US",
|
|
2875
|
+
labels,
|
|
2813
2876
|
className,
|
|
2814
2877
|
mode = "single",
|
|
2815
2878
|
id,
|
|
2816
2879
|
"aria-describedby": ariaDescribedBy,
|
|
2817
2880
|
"aria-labelledby": ariaLabelledBy
|
|
2818
2881
|
} = props;
|
|
2882
|
+
const text = {
|
|
2883
|
+
...locale.toLowerCase().startsWith("vi") ? LABELS_VI : LABELS_EN,
|
|
2884
|
+
...labels
|
|
2885
|
+
};
|
|
2819
2886
|
const generatedId = (0, import_react20.useId)();
|
|
2820
2887
|
const triggerId = id ?? generatedId + "-trigger";
|
|
2821
2888
|
const labelId = generatedId + "-label";
|
|
@@ -2903,6 +2970,15 @@ function DateTimePicker(props) {
|
|
|
2903
2970
|
{ length: 42 },
|
|
2904
2971
|
(_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1)
|
|
2905
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
|
+
};
|
|
2906
2982
|
const selectedForTime = isRange ? editingEnd ? rangeValue[1] : rangeValue[0] : singleValue;
|
|
2907
2983
|
const setTime = (time) => {
|
|
2908
2984
|
if (!selectedForTime) return;
|
|
@@ -2943,7 +3019,7 @@ function DateTimePicker(props) {
|
|
|
2943
3019
|
"aria-labelledby": labelledBy,
|
|
2944
3020
|
"aria-describedby": describedBy,
|
|
2945
3021
|
"aria-expanded": open,
|
|
2946
|
-
onClick:
|
|
3022
|
+
onClick: toggleOpen,
|
|
2947
3023
|
children: [
|
|
2948
3024
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
|
|
2949
3025
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
@@ -2951,7 +3027,7 @@ function DateTimePicker(props) {
|
|
|
2951
3027
|
{
|
|
2952
3028
|
className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
|
|
2953
3029
|
children: [
|
|
2954
|
-
shownValue || placeholder || (isRange ?
|
|
3030
|
+
shownValue || placeholder || (isRange ? text.selectDateRange : text.selectDateTime),
|
|
2955
3031
|
isRequired && placeholder && !shownValue && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
|
|
2956
3032
|
]
|
|
2957
3033
|
}
|
|
@@ -2964,14 +3040,14 @@ function DateTimePicker(props) {
|
|
|
2964
3040
|
{
|
|
2965
3041
|
className: "fe-datetime-picker__popper",
|
|
2966
3042
|
role: "dialog",
|
|
2967
|
-
"aria-label":
|
|
3043
|
+
"aria-label": text.dialog,
|
|
2968
3044
|
children: [
|
|
2969
3045
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__month", children: [
|
|
2970
3046
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2971
3047
|
"button",
|
|
2972
3048
|
{
|
|
2973
3049
|
type: "button",
|
|
2974
|
-
"aria-label":
|
|
3050
|
+
"aria-label": text.previousMonth,
|
|
2975
3051
|
onClick: () => setMonth(
|
|
2976
3052
|
(current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
|
|
2977
3053
|
),
|
|
@@ -2986,7 +3062,7 @@ function DateTimePicker(props) {
|
|
|
2986
3062
|
"button",
|
|
2987
3063
|
{
|
|
2988
3064
|
type: "button",
|
|
2989
|
-
"aria-label":
|
|
3065
|
+
"aria-label": text.nextMonth,
|
|
2990
3066
|
onClick: () => setMonth(
|
|
2991
3067
|
(current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
|
|
2992
3068
|
),
|
|
@@ -2994,17 +3070,20 @@ function DateTimePicker(props) {
|
|
|
2994
3070
|
}
|
|
2995
3071
|
)
|
|
2996
3072
|
] }),
|
|
2997
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__weekdays", children:
|
|
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)) }),
|
|
2998
3074
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
|
|
2999
3075
|
const inMonth = day.getMonth() === month.getMonth();
|
|
3000
3076
|
const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
|
|
3001
3077
|
const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
|
|
3078
|
+
const isToday = sameDay(day, today);
|
|
3002
3079
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3003
3080
|
"button",
|
|
3004
3081
|
{
|
|
3005
3082
|
type: "button",
|
|
3083
|
+
"aria-current": isToday ? "date" : void 0,
|
|
3006
3084
|
className: [
|
|
3007
3085
|
!inMonth && "is-other-month",
|
|
3086
|
+
isToday && "is-today",
|
|
3008
3087
|
selected && "is-selected",
|
|
3009
3088
|
inRange && "is-in-range"
|
|
3010
3089
|
].filter(Boolean).join(" "),
|
|
@@ -3014,6 +3093,7 @@ function DateTimePicker(props) {
|
|
|
3014
3093
|
day.toISOString()
|
|
3015
3094
|
);
|
|
3016
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 }) }),
|
|
3017
3097
|
isRange && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
|
|
3018
3098
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3019
3099
|
"button",
|
|
@@ -3021,7 +3101,7 @@ function DateTimePicker(props) {
|
|
|
3021
3101
|
type: "button",
|
|
3022
3102
|
className: !editingEnd ? "is-active" : "",
|
|
3023
3103
|
onClick: () => setEditingEnd(false),
|
|
3024
|
-
children:
|
|
3104
|
+
children: text.start
|
|
3025
3105
|
}
|
|
3026
3106
|
),
|
|
3027
3107
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
@@ -3030,12 +3110,12 @@ function DateTimePicker(props) {
|
|
|
3030
3110
|
type: "button",
|
|
3031
3111
|
className: editingEnd ? "is-active" : "",
|
|
3032
3112
|
onClick: () => setEditingEnd(true),
|
|
3033
|
-
children:
|
|
3113
|
+
children: text.end
|
|
3034
3114
|
}
|
|
3035
3115
|
)
|
|
3036
3116
|
] }),
|
|
3037
3117
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "fe-datetime-picker__time", children: [
|
|
3038
|
-
|
|
3118
|
+
text.time,
|
|
3039
3119
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3040
3120
|
"input",
|
|
3041
3121
|
{
|
package/dist/index.mjs
CHANGED
|
@@ -1821,6 +1821,9 @@ var Selection = forwardRef9(
|
|
|
1821
1821
|
disabled = false,
|
|
1822
1822
|
name,
|
|
1823
1823
|
onKeyDown,
|
|
1824
|
+
maxWidth,
|
|
1825
|
+
overflow = "ellipsis",
|
|
1826
|
+
style,
|
|
1824
1827
|
"aria-label": ariaLabel,
|
|
1825
1828
|
"aria-describedby": ariaDescribedBy,
|
|
1826
1829
|
"aria-labelledby": ariaLabelledBy,
|
|
@@ -1831,6 +1834,7 @@ var Selection = forwardRef9(
|
|
|
1831
1834
|
const listboxId = triggerId + "-listbox";
|
|
1832
1835
|
const labelId = generatedId + "-label";
|
|
1833
1836
|
const messageId2 = generatedId + "-message";
|
|
1837
|
+
const tooltipId = generatedId + "-tooltip";
|
|
1834
1838
|
const fieldError = getFieldError(error, errorMessage);
|
|
1835
1839
|
const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
|
|
1836
1840
|
const resolvedDescription = description ?? helperText;
|
|
@@ -1857,6 +1861,26 @@ var Selection = forwardRef9(
|
|
|
1857
1861
|
const [activeIndex, setActiveIndex] = useState11(0);
|
|
1858
1862
|
const rootRef = useRef7(null);
|
|
1859
1863
|
const menuRef = useRef7(null);
|
|
1864
|
+
const valueRef = useRef7(null);
|
|
1865
|
+
const [truncated, setTruncated] = useState11(false);
|
|
1866
|
+
const [hovered, setHovered] = useState11(false);
|
|
1867
|
+
const [focused, setFocused] = useState11(false);
|
|
1868
|
+
const showsTags = tag && multiple && selectedOptions.length > 0;
|
|
1869
|
+
const canTruncate = overflow === "ellipsis" && !showsTags && selectedOptions.length > 0;
|
|
1870
|
+
const selectedKey = selectedOptions.map((option) => String(option.value)).join("|");
|
|
1871
|
+
useLayoutEffect3(() => {
|
|
1872
|
+
const node = valueRef.current;
|
|
1873
|
+
if (!canTruncate || !node) {
|
|
1874
|
+
setTruncated(false);
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
const measure = () => setTruncated(node.scrollWidth > node.clientWidth + 1);
|
|
1878
|
+
measure();
|
|
1879
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
1880
|
+
const observer = new ResizeObserver(measure);
|
|
1881
|
+
observer.observe(node);
|
|
1882
|
+
return () => observer.disconnect();
|
|
1883
|
+
}, [canTruncate, selectedKey]);
|
|
1860
1884
|
const [menuPosition, setMenuPosition] = useState11(null);
|
|
1861
1885
|
useEffect5(() => {
|
|
1862
1886
|
const close = (event) => {
|
|
@@ -1921,6 +1945,12 @@ var Selection = forwardRef9(
|
|
|
1921
1945
|
setQuery("");
|
|
1922
1946
|
};
|
|
1923
1947
|
const displayLabel = selectedOptions.length ? selectedOptions.map((option) => option.label) : null;
|
|
1948
|
+
const showTooltip = truncated && (hovered || focused) && !open;
|
|
1949
|
+
const renderLabels = () => displayLabel?.map((item, index) => /* @__PURE__ */ jsxs12("span", { children: [
|
|
1950
|
+
item,
|
|
1951
|
+
index < displayLabel.length - 1 ? ", " : ""
|
|
1952
|
+
] }, index));
|
|
1953
|
+
const toPx = (length) => typeof length === "number" ? length + "px" : length;
|
|
1924
1954
|
const onTriggerKeyDown = (event) => {
|
|
1925
1955
|
onKeyDown?.(event);
|
|
1926
1956
|
if (disabled) return;
|
|
@@ -1952,12 +1982,14 @@ var Selection = forwardRef9(
|
|
|
1952
1982
|
className: [
|
|
1953
1983
|
"fe-selection",
|
|
1954
1984
|
"fe-selection--" + size,
|
|
1985
|
+
"fe-selection--" + overflow,
|
|
1955
1986
|
open && "fe-selection--open",
|
|
1956
1987
|
clearable && selectedOptions.length > 0 && "fe-selection--clearable",
|
|
1957
1988
|
hasError && "fe-selection--error",
|
|
1958
1989
|
disabled && "fe-selection--disabled",
|
|
1959
1990
|
className
|
|
1960
1991
|
].filter(Boolean).join(" "),
|
|
1992
|
+
style: maxWidth === void 0 ? style : { ...style, maxWidth: toPx(maxWidth) },
|
|
1961
1993
|
...props,
|
|
1962
1994
|
children: [
|
|
1963
1995
|
/* @__PURE__ */ jsx15(
|
|
@@ -1991,16 +2023,24 @@ var Selection = forwardRef9(
|
|
|
1991
2023
|
"aria-invalid": hasError || void 0,
|
|
1992
2024
|
"aria-required": isRequired || void 0,
|
|
1993
2025
|
"aria-labelledby": labelledBy,
|
|
1994
|
-
"aria-describedby":
|
|
2026
|
+
"aria-describedby": getDescribedBy(
|
|
2027
|
+
describedBy,
|
|
2028
|
+
showTooltip ? tooltipId : void 0
|
|
2029
|
+
),
|
|
1995
2030
|
"aria-haspopup": "listbox",
|
|
1996
2031
|
"aria-expanded": open,
|
|
1997
2032
|
"aria-controls": listboxId,
|
|
1998
2033
|
onClick: () => setOpen((current) => !current),
|
|
1999
2034
|
onKeyDown: onTriggerKeyDown,
|
|
2035
|
+
onMouseEnter: () => setHovered(true),
|
|
2036
|
+
onMouseLeave: () => setHovered(false),
|
|
2037
|
+
onFocus: () => setFocused(true),
|
|
2038
|
+
onBlur: () => setFocused(false),
|
|
2000
2039
|
children: [
|
|
2001
2040
|
/* @__PURE__ */ jsx15(
|
|
2002
2041
|
"span",
|
|
2003
2042
|
{
|
|
2043
|
+
ref: valueRef,
|
|
2004
2044
|
className: [
|
|
2005
2045
|
"fe-selection__value",
|
|
2006
2046
|
!selectedOptions.length && "is-placeholder",
|
|
@@ -2016,10 +2056,7 @@ var Selection = forwardRef9(
|
|
|
2016
2056
|
]
|
|
2017
2057
|
},
|
|
2018
2058
|
String(option.value)
|
|
2019
|
-
)) :
|
|
2020
|
-
item,
|
|
2021
|
-
index < displayLabel.length - 1 ? ", " : ""
|
|
2022
|
-
] }, index)) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
2059
|
+
)) : renderLabels() : /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
2023
2060
|
/* @__PURE__ */ jsx15("span", { children: placeholder }),
|
|
2024
2061
|
isRequired && /* @__PURE__ */ jsx15("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
|
|
2025
2062
|
] })
|
|
@@ -2038,6 +2075,7 @@ var Selection = forwardRef9(
|
|
|
2038
2075
|
onClick: clear
|
|
2039
2076
|
}
|
|
2040
2077
|
),
|
|
2078
|
+
showTooltip && /* @__PURE__ */ jsx15("span", { id: tooltipId, role: "tooltip", className: "fe-selection__tooltip", children: renderLabels() }),
|
|
2041
2079
|
open && menuPosition && createPortal2(
|
|
2042
2080
|
/* @__PURE__ */ jsxs12(
|
|
2043
2081
|
"div",
|
|
@@ -2089,7 +2127,7 @@ var Selection = forwardRef9(
|
|
|
2089
2127
|
onMouseMove: () => setActiveIndex(index),
|
|
2090
2128
|
onClick: () => choose(option),
|
|
2091
2129
|
children: [
|
|
2092
|
-
/* @__PURE__ */ jsx15("span", { children: option.label }),
|
|
2130
|
+
/* @__PURE__ */ jsx15("span", { className: "fe-selection__option-label", children: option.label }),
|
|
2093
2131
|
isSelected && /* @__PURE__ */ jsx15(
|
|
2094
2132
|
"span",
|
|
2095
2133
|
{
|
|
@@ -2481,6 +2519,30 @@ function CurrencyInput({
|
|
|
2481
2519
|
// packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
|
|
2482
2520
|
import { useEffect as useEffect7, useId as useId9, useRef as useRef9, useState as useState14 } from "react";
|
|
2483
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
|
+
};
|
|
2484
2546
|
var pad = (value) => String(value).padStart(2, "0");
|
|
2485
2547
|
function formatDate(date, format) {
|
|
2486
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()));
|
|
@@ -2510,12 +2572,17 @@ function DateTimePicker(props) {
|
|
|
2510
2572
|
disabled,
|
|
2511
2573
|
placeholder,
|
|
2512
2574
|
locale = "en-US",
|
|
2575
|
+
labels,
|
|
2513
2576
|
className,
|
|
2514
2577
|
mode = "single",
|
|
2515
2578
|
id,
|
|
2516
2579
|
"aria-describedby": ariaDescribedBy,
|
|
2517
2580
|
"aria-labelledby": ariaLabelledBy
|
|
2518
2581
|
} = props;
|
|
2582
|
+
const text = {
|
|
2583
|
+
...locale.toLowerCase().startsWith("vi") ? LABELS_VI : LABELS_EN,
|
|
2584
|
+
...labels
|
|
2585
|
+
};
|
|
2519
2586
|
const generatedId = useId9();
|
|
2520
2587
|
const triggerId = id ?? generatedId + "-trigger";
|
|
2521
2588
|
const labelId = generatedId + "-label";
|
|
@@ -2603,6 +2670,15 @@ function DateTimePicker(props) {
|
|
|
2603
2670
|
{ length: 42 },
|
|
2604
2671
|
(_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1)
|
|
2605
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
|
+
};
|
|
2606
2682
|
const selectedForTime = isRange ? editingEnd ? rangeValue[1] : rangeValue[0] : singleValue;
|
|
2607
2683
|
const setTime = (time) => {
|
|
2608
2684
|
if (!selectedForTime) return;
|
|
@@ -2643,7 +2719,7 @@ function DateTimePicker(props) {
|
|
|
2643
2719
|
"aria-labelledby": labelledBy,
|
|
2644
2720
|
"aria-describedby": describedBy,
|
|
2645
2721
|
"aria-expanded": open,
|
|
2646
|
-
onClick:
|
|
2722
|
+
onClick: toggleOpen,
|
|
2647
2723
|
children: [
|
|
2648
2724
|
/* @__PURE__ */ jsx18("span", { "aria-hidden": "true", children: "\u25F7" }),
|
|
2649
2725
|
/* @__PURE__ */ jsxs14(
|
|
@@ -2651,7 +2727,7 @@ function DateTimePicker(props) {
|
|
|
2651
2727
|
{
|
|
2652
2728
|
className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
|
|
2653
2729
|
children: [
|
|
2654
|
-
shownValue || placeholder || (isRange ?
|
|
2730
|
+
shownValue || placeholder || (isRange ? text.selectDateRange : text.selectDateTime),
|
|
2655
2731
|
isRequired && placeholder && !shownValue && /* @__PURE__ */ jsx18("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
|
|
2656
2732
|
]
|
|
2657
2733
|
}
|
|
@@ -2664,14 +2740,14 @@ function DateTimePicker(props) {
|
|
|
2664
2740
|
{
|
|
2665
2741
|
className: "fe-datetime-picker__popper",
|
|
2666
2742
|
role: "dialog",
|
|
2667
|
-
"aria-label":
|
|
2743
|
+
"aria-label": text.dialog,
|
|
2668
2744
|
children: [
|
|
2669
2745
|
/* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__month", children: [
|
|
2670
2746
|
/* @__PURE__ */ jsx18(
|
|
2671
2747
|
"button",
|
|
2672
2748
|
{
|
|
2673
2749
|
type: "button",
|
|
2674
|
-
"aria-label":
|
|
2750
|
+
"aria-label": text.previousMonth,
|
|
2675
2751
|
onClick: () => setMonth(
|
|
2676
2752
|
(current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
|
|
2677
2753
|
),
|
|
@@ -2686,7 +2762,7 @@ function DateTimePicker(props) {
|
|
|
2686
2762
|
"button",
|
|
2687
2763
|
{
|
|
2688
2764
|
type: "button",
|
|
2689
|
-
"aria-label":
|
|
2765
|
+
"aria-label": text.nextMonth,
|
|
2690
2766
|
onClick: () => setMonth(
|
|
2691
2767
|
(current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
|
|
2692
2768
|
),
|
|
@@ -2694,17 +2770,20 @@ function DateTimePicker(props) {
|
|
|
2694
2770
|
}
|
|
2695
2771
|
)
|
|
2696
2772
|
] }),
|
|
2697
|
-
/* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__weekdays", children:
|
|
2773
|
+
/* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__weekdays", children: text.weekdays.map((day) => /* @__PURE__ */ jsx18("span", { children: day }, day)) }),
|
|
2698
2774
|
/* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
|
|
2699
2775
|
const inMonth = day.getMonth() === month.getMonth();
|
|
2700
2776
|
const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
|
|
2701
2777
|
const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
|
|
2778
|
+
const isToday = sameDay(day, today);
|
|
2702
2779
|
return /* @__PURE__ */ jsx18(
|
|
2703
2780
|
"button",
|
|
2704
2781
|
{
|
|
2705
2782
|
type: "button",
|
|
2783
|
+
"aria-current": isToday ? "date" : void 0,
|
|
2706
2784
|
className: [
|
|
2707
2785
|
!inMonth && "is-other-month",
|
|
2786
|
+
isToday && "is-today",
|
|
2708
2787
|
selected && "is-selected",
|
|
2709
2788
|
inRange && "is-in-range"
|
|
2710
2789
|
].filter(Boolean).join(" "),
|
|
@@ -2714,6 +2793,7 @@ function DateTimePicker(props) {
|
|
|
2714
2793
|
day.toISOString()
|
|
2715
2794
|
);
|
|
2716
2795
|
}) }),
|
|
2796
|
+
/* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__footer", children: /* @__PURE__ */ jsx18("button", { type: "button", onClick: selectToday, children: text.today }) }),
|
|
2717
2797
|
isRange && /* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__range-tabs", children: [
|
|
2718
2798
|
/* @__PURE__ */ jsx18(
|
|
2719
2799
|
"button",
|
|
@@ -2721,7 +2801,7 @@ function DateTimePicker(props) {
|
|
|
2721
2801
|
type: "button",
|
|
2722
2802
|
className: !editingEnd ? "is-active" : "",
|
|
2723
2803
|
onClick: () => setEditingEnd(false),
|
|
2724
|
-
children:
|
|
2804
|
+
children: text.start
|
|
2725
2805
|
}
|
|
2726
2806
|
),
|
|
2727
2807
|
/* @__PURE__ */ jsx18(
|
|
@@ -2730,12 +2810,12 @@ function DateTimePicker(props) {
|
|
|
2730
2810
|
type: "button",
|
|
2731
2811
|
className: editingEnd ? "is-active" : "",
|
|
2732
2812
|
onClick: () => setEditingEnd(true),
|
|
2733
|
-
children:
|
|
2813
|
+
children: text.end
|
|
2734
2814
|
}
|
|
2735
2815
|
)
|
|
2736
2816
|
] }),
|
|
2737
2817
|
/* @__PURE__ */ jsxs14("label", { className: "fe-datetime-picker__time", children: [
|
|
2738
|
-
|
|
2818
|
+
text.time,
|
|
2739
2819
|
/* @__PURE__ */ jsx18(
|
|
2740
2820
|
"input",
|
|
2741
2821
|
{
|
package/dist/styles.css
CHANGED
|
@@ -886,8 +886,9 @@ table[data-fe-table][data-resizing] {
|
|
|
886
886
|
display: flex;
|
|
887
887
|
align-items: center;
|
|
888
888
|
width: 100%;
|
|
889
|
+
min-width: 0;
|
|
889
890
|
min-height: 40px;
|
|
890
|
-
padding: 0 13px;
|
|
891
|
+
padding: 0 40px 0 13px;
|
|
891
892
|
border: 1px solid #d4d8e0;
|
|
892
893
|
border-radius: 12px;
|
|
893
894
|
outline: 0;
|
|
@@ -902,7 +903,11 @@ table[data-fe-table][data-resizing] {
|
|
|
902
903
|
background 0.15s;
|
|
903
904
|
}
|
|
904
905
|
.fe-selection--clearable .fe-selection__trigger {
|
|
905
|
-
padding-right:
|
|
906
|
+
padding-right: 72px;
|
|
907
|
+
}
|
|
908
|
+
.fe-selection--wrap .fe-selection__trigger {
|
|
909
|
+
padding-top: 8px;
|
|
910
|
+
padding-bottom: 8px;
|
|
906
911
|
}
|
|
907
912
|
.fe-selection--small .fe-selection__trigger {
|
|
908
913
|
min-height: 34px;
|
|
@@ -922,19 +927,24 @@ table[data-fe-table][data-resizing] {
|
|
|
922
927
|
box-shadow: 0 0 0 3px rgba(40, 120, 240, 0.12);
|
|
923
928
|
}
|
|
924
929
|
.fe-selection__value {
|
|
925
|
-
display:
|
|
930
|
+
display: block;
|
|
926
931
|
width: 100%;
|
|
927
932
|
min-width: 0;
|
|
928
933
|
flex: 1 1 auto;
|
|
929
|
-
align-items: center;
|
|
930
934
|
overflow: hidden;
|
|
931
935
|
text-overflow: ellipsis;
|
|
932
936
|
white-space: nowrap;
|
|
933
937
|
}
|
|
938
|
+
.fe-selection--wrap .fe-selection__value {
|
|
939
|
+
line-height: 1.4;
|
|
940
|
+
overflow-wrap: anywhere;
|
|
941
|
+
white-space: normal;
|
|
942
|
+
}
|
|
934
943
|
.fe-selection__value.is-placeholder {
|
|
935
944
|
color: #8b94a4;
|
|
936
945
|
}
|
|
937
946
|
.fe-selection__value.is-tags {
|
|
947
|
+
display: flex;
|
|
938
948
|
flex-wrap: wrap;
|
|
939
949
|
align-content: center;
|
|
940
950
|
gap: 5px;
|
|
@@ -1013,6 +1023,24 @@ table[data-fe-table][data-resizing] {
|
|
|
1013
1023
|
outline: 2px solid #2878f0;
|
|
1014
1024
|
outline-offset: 1px;
|
|
1015
1025
|
}
|
|
1026
|
+
.fe-selection__tooltip {
|
|
1027
|
+
position: absolute;
|
|
1028
|
+
z-index: 50;
|
|
1029
|
+
bottom: calc(100% + 8px);
|
|
1030
|
+
left: 0;
|
|
1031
|
+
width: max-content;
|
|
1032
|
+
max-width: min(320px, calc(100vw - 32px));
|
|
1033
|
+
padding: 7px 9px;
|
|
1034
|
+
border-radius: 7px;
|
|
1035
|
+
background: #20242c;
|
|
1036
|
+
color: #fff;
|
|
1037
|
+
font-size: 12px;
|
|
1038
|
+
font-weight: 500;
|
|
1039
|
+
line-height: 1.35;
|
|
1040
|
+
overflow-wrap: anywhere;
|
|
1041
|
+
box-shadow: 0 5px 18px rgba(0, 0, 0, 0.22);
|
|
1042
|
+
pointer-events: none;
|
|
1043
|
+
}
|
|
1016
1044
|
.fe-selection__chevron {
|
|
1017
1045
|
position: absolute;
|
|
1018
1046
|
top: 2px;
|
|
@@ -1073,6 +1101,7 @@ table[data-fe-table][data-resizing] {
|
|
|
1073
1101
|
display: flex;
|
|
1074
1102
|
align-items: center;
|
|
1075
1103
|
justify-content: space-between;
|
|
1104
|
+
gap: 8px;
|
|
1076
1105
|
width: 100%;
|
|
1077
1106
|
min-height: 37px;
|
|
1078
1107
|
padding: 8px 10px;
|
|
@@ -1098,7 +1127,12 @@ table[data-fe-table][data-resizing] {
|
|
|
1098
1127
|
opacity: 0.45;
|
|
1099
1128
|
cursor: not-allowed;
|
|
1100
1129
|
}
|
|
1130
|
+
.fe-selection__option-label {
|
|
1131
|
+
min-width: 0;
|
|
1132
|
+
overflow-wrap: anywhere;
|
|
1133
|
+
}
|
|
1101
1134
|
.fe-selection__check {
|
|
1135
|
+
flex: none;
|
|
1102
1136
|
font-weight: 800;
|
|
1103
1137
|
}
|
|
1104
1138
|
.fe-selection__empty {
|
|
@@ -1677,6 +1711,34 @@ table[data-fe-table][data-resizing] {
|
|
|
1677
1711
|
.fe-datetime-picker__days button.is-other-month {
|
|
1678
1712
|
color: #aab0bb;
|
|
1679
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
|
+
}
|
|
1680
1742
|
.fe-datetime-picker__range-tabs {
|
|
1681
1743
|
display: flex;
|
|
1682
1744
|
gap: 4px;
|
package/package.json
CHANGED