@rio-cloud/rio-uikit 2.5.0-beta.1 → 2.5.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 (124) hide show
  1. package/CountedInput.d.ts +2 -0
  2. package/CountedInput.js +5 -0
  3. package/CountedInput.js.map +1 -0
  4. package/TabbedPanel.d.ts +2 -0
  5. package/TabbedPanel.js +5 -0
  6. package/TabbedPanel.js.map +1 -0
  7. package/components/applicationHeader/NavItems.js +58 -46
  8. package/components/applicationHeader/NavItems.js.map +1 -1
  9. package/components/applicationLayout/ApplicationLayoutBody.d.ts +1 -1
  10. package/components/applicationLayout/ApplicationLayoutBody.js +29 -29
  11. package/components/applicationLayout/ApplicationLayoutBody.js.map +1 -1
  12. package/components/applicationLayout/ApplicationLayoutHeader.js +22 -7
  13. package/components/applicationLayout/ApplicationLayoutHeader.js.map +1 -1
  14. package/components/assetTree/useTreeHeight.js.map +1 -1
  15. package/components/button/Button.d.ts +17 -3
  16. package/components/button/Button.js +54 -52
  17. package/components/button/Button.js.map +1 -1
  18. package/components/clearableInput/ClearableInput.d.ts +4 -0
  19. package/components/clearableInput/ClearableInput.js.map +1 -1
  20. package/components/countedInput/CountedInput.d.ts +91 -0
  21. package/components/countedInput/CountedInput.js +65 -0
  22. package/components/countedInput/CountedInput.js.map +1 -0
  23. package/components/datepicker/DatePicker.d.ts +1 -1
  24. package/components/datepicker/DatePicker.js +1 -1
  25. package/components/datepicker/DatePicker.js.map +1 -1
  26. package/components/datepicker/DayPicker.js +3 -2
  27. package/components/datepicker/DayPicker.js.map +1 -1
  28. package/components/datepicker/DayPickerInput.d.ts +1 -1
  29. package/components/datepicker/DayPickerInput.js.map +1 -1
  30. package/components/datepicker/dayPickerTypes.d.ts +3 -2
  31. package/components/datepicker/dayPickerTypes.js.map +1 -1
  32. package/components/datepicker/dayPickerUtils.d.ts +1 -1
  33. package/components/datepicker/dayPickerUtils.js +45 -22
  34. package/components/datepicker/dayPickerUtils.js.map +1 -1
  35. package/components/datepicker/useDayPickerInputState.d.ts +1 -1
  36. package/components/dialog/ConfirmationDialog.d.ts +17 -0
  37. package/components/dialog/ConfirmationDialog.js +43 -19
  38. package/components/dialog/ConfirmationDialog.js.map +1 -1
  39. package/components/dialog/DialogHeader.js +20 -19
  40. package/components/dialog/DialogHeader.js.map +1 -1
  41. package/components/dropdown/ButtonDropdown.d.ts +5 -0
  42. package/components/dropdown/ButtonDropdown.js +63 -61
  43. package/components/dropdown/ButtonDropdown.js.map +1 -1
  44. package/components/dropdown/DropdownToggleButton.d.ts +2 -0
  45. package/components/dropdown/DropdownToggleButton.js +39 -35
  46. package/components/dropdown/DropdownToggleButton.js.map +1 -1
  47. package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js +103 -105
  48. package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js.map +1 -1
  49. package/components/map/utils/eventHandling.js.map +1 -1
  50. package/components/map/utils/mapTypes.d.ts +7 -0
  51. package/components/map/utils/mapTypes.js.map +1 -1
  52. package/components/map/utils/rendering.js +5 -5
  53. package/components/numberControl/NumberControl.js.map +1 -1
  54. package/components/page/Page.d.ts +2 -0
  55. package/components/page/Page.js.map +1 -1
  56. package/components/rioglyph/Rioglyph.d.ts +8 -2
  57. package/components/rioglyph/Rioglyph.js.map +1 -1
  58. package/components/rioglyph/RioglyphIconType.d.ts +1 -1
  59. package/components/selects/BaseSelectDropdown.d.ts +8 -0
  60. package/components/selects/BaseSelectDropdown.js +76 -60
  61. package/components/selects/BaseSelectDropdown.js.map +1 -1
  62. package/components/selects/Multiselect.d.ts +5 -0
  63. package/components/selects/Multiselect.js +60 -58
  64. package/components/selects/Multiselect.js.map +1 -1
  65. package/components/selects/Select.d.ts +5 -0
  66. package/components/selects/Select.js +60 -58
  67. package/components/selects/Select.js.map +1 -1
  68. package/components/sidebars/Sidebar.js +40 -40
  69. package/components/sidebars/Sidebar.js.map +1 -1
  70. package/components/sidebars/SidebarCloseButton.d.ts +3 -1
  71. package/components/sidebars/SidebarCloseButton.js +19 -5
  72. package/components/sidebars/SidebarCloseButton.js.map +1 -1
  73. package/components/states/CustomState.d.ts +7 -1
  74. package/components/states/CustomState.js.map +1 -1
  75. package/components/states/StateButton.d.ts +11 -1
  76. package/components/states/StateButton.js +46 -10
  77. package/components/states/StateButton.js.map +1 -1
  78. package/components/statsWidget/StatsWidgetNumber.d.ts +16 -1
  79. package/components/statsWidget/StatsWidgetNumber.js +29 -12
  80. package/components/statsWidget/StatsWidgetNumber.js.map +1 -1
  81. package/components/tabbedPanel/TabbedPanel.d.ts +99 -0
  82. package/components/tabbedPanel/TabbedPanel.js +119 -0
  83. package/components/tabbedPanel/TabbedPanel.js.map +1 -0
  84. package/components/table/Table.types.d.ts +9 -1
  85. package/components/table/TableColumn.js +20 -19
  86. package/components/table/TableColumn.js.map +1 -1
  87. package/components/table/TableHeaderColumn.d.ts +4 -0
  88. package/components/table/TableHeaderColumn.js +50 -53
  89. package/components/table/TableHeaderColumn.js.map +1 -1
  90. package/components/table/TableToolbar.d.ts +4 -0
  91. package/components/table/TableToolbar.js.map +1 -1
  92. package/components/table/TableToolbarColumn.d.ts +3 -0
  93. package/components/table/TableToolbarColumn.js.map +1 -1
  94. package/components/table/render/header/TableBatchDropdown.js +8 -7
  95. package/components/table/render/header/TableBatchDropdown.js.map +1 -1
  96. package/components/table/render/header/TableColumnFilter.js +9 -9
  97. package/components/table/render/header/TableColumnFilter.js.map +1 -1
  98. package/components/table/render/header/resolveHeaderCellStyle.d.ts +87 -55
  99. package/components/timepicker/TimePicker.d.ts +6 -0
  100. package/components/timepicker/TimePicker.js +57 -56
  101. package/components/timepicker/TimePicker.js.map +1 -1
  102. package/hooks/useClickOutside.js +3 -3
  103. package/hooks/useClipboard.js.map +1 -1
  104. package/hooks/useScrollPosition.js.map +1 -1
  105. package/package.json +2 -4
  106. package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js +23 -22
  107. package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js.map +1 -1
  108. package/utils/analytics/getTrackingLabelFromNode.d.ts +2 -0
  109. package/utils/analytics/getTrackingLabelFromNode.js +24 -0
  110. package/utils/analytics/getTrackingLabelFromNode.js.map +1 -0
  111. package/utils/analytics/googleAnalyticsUtils.js +21 -28
  112. package/utils/analytics/googleAnalyticsUtils.js.map +1 -1
  113. package/utils/getNodeTextContent.d.ts +2 -0
  114. package/utils/getNodeTextContent.js +22 -0
  115. package/utils/getNodeTextContent.js.map +1 -0
  116. package/utils/init/initCSS.js +5 -5
  117. package/utils/init/initCSS.js.map +1 -1
  118. package/utils/init/initConfig.js +4 -7
  119. package/utils/init/initConfig.js.map +1 -1
  120. package/utils/init/initDocumentBootstrapping.js +14 -14
  121. package/utils/init/initDocumentBootstrapping.js.map +1 -1
  122. package/version.d.ts +1 -1
  123. package/version.js +2 -2
  124. package/version.js.map +1 -1
@@ -1,11 +1,11 @@
1
1
  import { jsxs as E, jsx as k } from "react/jsx-runtime";
2
- import { forwardRef as Y, useState as L, useRef as $ } from "react";
3
- import { noop as w } from "es-toolkit/function";
4
- import B from "../../utils/classNames.js";
5
- import { createButtonRipple as S } from "../../utils/buttonEffect.js";
6
- import F from "../../hooks/useMergeRefs.js";
7
- import { getAutoTrackingAttributes as G } from "../../utils/analytics/autoTracking.js";
8
- const z = {
2
+ import { forwardRef as $, useState as S, useRef as w } from "react";
3
+ import { noop as B } from "es-toolkit/function";
4
+ import F from "../../utils/classNames.js";
5
+ import { createButtonRipple as L } from "../../utils/buttonEffect.js";
6
+ import G from "../../hooks/useMergeRefs.js";
7
+ import { getAutoTrackingAttributes as z } from "../../utils/analytics/autoTracking.js";
8
+ const W = {
9
9
  DEFAULT: "default",
10
10
  UNSTYLED: "unstyled",
11
11
  PRIMARY: "primary",
@@ -16,72 +16,74 @@ const z = {
16
16
  SUCCESS: "success",
17
17
  MUTED: "muted",
18
18
  MUTED_FILLED: "muted-filled"
19
- }, i = {
19
+ }, s = {
20
20
  VARIANT_LINK: "link",
21
21
  VARIANT_LINK_INLINE: "link-inline",
22
22
  VARIANT_OUTLINE: "outline",
23
23
  VARIANT_ACTION: "action"
24
- }, W = {
24
+ }, X = {
25
25
  XS: "xs",
26
26
  SM: "sm",
27
27
  MD: "md",
28
28
  LG: "lg"
29
- }, u = Y((_, C) => {
29
+ }, u = $((_, h) => {
30
30
  const {
31
31
  as: a = "button",
32
- active: n = !1,
33
- disabled: e = !1,
32
+ active: e = !1,
33
+ disabled: n = !1,
34
34
  asToggle: f = !1,
35
- onClick: l = w,
36
- bsStyle: y = "default",
35
+ onClick: l = B,
36
+ bsStyle: C = "default",
37
37
  bsSize: b,
38
- variant: s,
39
- iconOnly: O = !1,
38
+ variant: i,
39
+ iconOnly: v = !1,
40
40
  iconName: o,
41
- iconRight: h = !1,
42
- multiline: D = !1,
43
- block: M = !1,
41
+ iconRight: y = !1,
42
+ multiline: O = !1,
43
+ block: D = !1,
44
+ hoverScale: M = !1,
44
45
  className: V = "",
45
46
  noRippleEffect: N = !1,
46
- autoTrackingKey: v,
47
- type: U = "button",
47
+ autoTrackingKey: U,
48
+ type: x = "button",
48
49
  tabIndex: A = 0,
49
50
  children: m,
50
51
  ...r
51
- } = _, I = G({
52
- autoTrackingKey: v,
52
+ } = _, I = z({
53
+ autoTrackingKey: U,
53
54
  props: r,
54
55
  source: "button"
55
- }), [g, d] = L(n), T = $(null), p = F(T, C), [x, P] = L(n);
56
- n !== x && (d(n), P(n));
57
- const j = (t) => {
58
- if (N || S(t.nativeEvent, t.currentTarget), f) {
56
+ }), [g, d] = S(e), T = w(null), p = G(T, h), [P, j] = S(e);
57
+ e !== P && (d(e), j(e));
58
+ const K = (t) => {
59
+ if (N || L(t.nativeEvent, t.currentTarget), f) {
59
60
  const c = !g;
60
61
  d(c), c && T.current?.blur(), l(c);
61
62
  } else
62
63
  l(t);
63
- }, K = (t) => {
64
- if (e) {
64
+ }, Y = (t) => {
65
+ if (n) {
65
66
  t.preventDefault();
66
67
  return;
67
68
  }
68
- N || S(t.nativeEvent, t.currentTarget), l(t);
69
- }, R = B(
69
+ N || L(t.nativeEvent, t.currentTarget), l(t);
70
+ }, R = F(
70
71
  "btn",
71
- `btn-${y}`,
72
- s === i.VARIANT_LINK && "btn-link",
73
- s === i.VARIANT_LINK_INLINE && "btn-link btn-link-inline",
74
- s === i.VARIANT_OUTLINE && "btn-outline",
75
- s === i.VARIANT_ACTION && "btn-action",
72
+ `btn-${C}`,
73
+ i === s.VARIANT_LINK && "btn-link",
74
+ i === s.VARIANT_LINK_INLINE && "btn-link btn-link-inline",
75
+ i === s.VARIANT_OUTLINE && "btn-outline",
76
+ i === s.VARIANT_ACTION && "btn-action",
76
77
  b && `btn-${b}`,
77
78
  f && "btn-toggle",
78
79
  g && "active",
79
- O && "btn-icon-only",
80
- h && "btn-icon-right",
81
- D && "btn-multiline",
82
- M && "btn-block",
80
+ v && "btn-icon-only",
81
+ y && "btn-icon-right",
82
+ O && "btn-multiline",
83
+ D && "btn-block",
84
+ M && "hover-scale",
83
85
  a === "a" && "gap-0",
84
- a === "a" && e && "disabled",
86
+ a === "a" && n && "disabled",
85
87
  "btn-component",
86
88
  V
87
89
  );
@@ -92,9 +94,9 @@ const z = {
92
94
  ...r,
93
95
  ...I,
94
96
  className: R,
95
- onClick: K,
96
- "aria-disabled": e || void 0,
97
- tabIndex: e ? -1 : A,
97
+ onClick: Y,
98
+ "aria-disabled": n || void 0,
99
+ tabIndex: n ? -1 : A,
98
100
  children: [
99
101
  o && /* @__PURE__ */ k("span", { className: `rioglyph ${o}` }),
100
102
  m
@@ -104,12 +106,12 @@ const z = {
104
106
  "button",
105
107
  {
106
108
  ref: p,
107
- type: U,
109
+ type: x,
108
110
  ...r,
109
111
  ...I,
110
112
  className: R,
111
- onClick: j,
112
- disabled: e,
113
+ onClick: K,
114
+ disabled: n,
113
115
  tabIndex: A,
114
116
  children: [
115
117
  o && /* @__PURE__ */ k("span", { className: `rioglyph ${o}` }),
@@ -118,13 +120,13 @@ const z = {
118
120
  }
119
121
  );
120
122
  });
121
- Object.assign(u, z);
122
- Object.assign(u, i);
123
123
  Object.assign(u, W);
124
+ Object.assign(u, s);
125
+ Object.assign(u, X);
124
126
  export {
125
- W as SIZES_MAP,
126
- z as STYLES_MAP,
127
- i as VARIANTS_MAP,
127
+ X as SIZES_MAP,
128
+ W as STYLES_MAP,
129
+ s as VARIANTS_MAP,
128
130
  u as default
129
131
  };
130
132
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import React, {\n forwardRef,\n type ForwardRefExoticComponent,\n type HTMLProps,\n type PropsWithChildren,\n type RefAttributes,\n useRef,\n useState,\n} from 'react';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport { createButtonRipple } from '../../utils/buttonEffect';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport type { ObjectValues } from '../../utils/ObjectValues';\nimport { getAutoTrackingAttributes } from '../../utils/analytics/autoTracking';\n\nexport const STYLES_MAP = {\n DEFAULT: 'default',\n UNSTYLED: 'unstyled',\n PRIMARY: 'primary',\n SECONDARY: 'secondary',\n INFO: 'info',\n WARNING: 'warning',\n DANGER: 'danger',\n SUCCESS: 'success',\n MUTED: 'muted',\n MUTED_FILLED: 'muted-filled',\n} as const;\n\n// export for convenient usage on client side\nexport type BUTTON_STYLE = ObjectValues<typeof STYLES_MAP>;\n\nexport const VARIANTS_MAP = {\n VARIANT_LINK: 'link',\n VARIANT_LINK_INLINE: 'link-inline',\n VARIANT_OUTLINE: 'outline',\n VARIANT_ACTION: 'action',\n} as const;\n\nexport type BUTTON_VARIANT = ObjectValues<typeof VARIANTS_MAP>;\n\nexport const SIZES_MAP = {\n XS: 'xs',\n SM: 'sm',\n MD: 'md',\n LG: 'lg',\n} as const;\n\nexport type BUTTON_SIZE = ObjectValues<typeof SIZES_MAP>;\n\n/*\n * ATTENTION: We're typing the onClick handler based on the value of `asToggle`.\n *\n * It does not fully work here inside of this file, though. Therefore, we have to apply some explicit casts below.\n * In code _using_ the Button component, however, the parameter type of the onClick handler must either be a boolean or\n * a React.MouseEvent, respectively.\n */\n\ntype RegularButton = {\n /**\n * Use the button as a toggle button. The toggle state can be controlled via the `active` prop.\n *\n * @default false\n */\n asToggle?: false;\n\n /**\n * Callback function triggered when clicking the button.\n *\n * @param event The MouseEvent that triggered the click.\n */\n onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n};\n\ntype ToggleButton = {\n /**\n * Use the button as a toggle button. The toggle state can be controlled via the `active` prop.\n *\n * @default false\n */\n asToggle: true;\n\n /**\n * Callback function triggered when clicking the button.\n *\n * @param value The new value of the toggle button.\n */\n onClick?: (value: boolean) => void;\n};\n\ntype BaseButtonProps = {\n /**\n * Whether the button should be disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Set the button toggled. Should be used in combination with \"asToggle\" prop.\n *\n * @default false\n */\n active?: boolean;\n\n /**\n * Use when the content of the button is an icon only to adapt the button spacing accordingly.\n *\n * @default false\n */\n iconOnly?: boolean;\n\n /**\n * Adds right side spacing for an icon. This should be used when having navigation buttons\n * that use an icon on the right side.\n *\n * @default false\n */\n iconRight?: boolean;\n\n /**\n * Optional rio-glyph icon name that comes in handy for icon only buttons for not adding\n * a span tag for the icon which reduces boilerplate code.\n */\n iconName?: string;\n\n /**\n * Defines whether the button text break into multiple lines when the button space exceeds.\n *\n * Multiline buttons should be used as exception only.\n *\n * @default false\n */\n multiline?: boolean;\n\n /**\n * Defines whether the button takes up the full width of the parent element.\n *\n * @default false\n */\n block?: boolean;\n\n /**\n * Sets the button style.\n * @default 'default'\n */\n bsStyle?: BUTTON_STYLE;\n\n /**\n * Sets the button size.\n */\n bsSize?: BUTTON_SIZE;\n\n /**\n * Sets the button variant.\n */\n variant?: BUTTON_VARIANT;\n\n /**\n * Whether the \"ripple\" effect should be suppressed on this button.\n */\n noRippleEffect?: boolean;\n\n /**\n * Optional key used to generate automatic GA tracking attributes when no explicit\n * tracking attributes are provided.\n *\n * Resulting label format: `button::<autoTrackingKey>`.\n */\n autoTrackingKey?: string;\n\n /**\n * Number of the index used for keyboard support.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Additional classes to be set on the button element.\n */\n className?: string;\n};\n\ntype NativeButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'as' | 'type' | 'onClick' | 'ref'> &\n BaseButtonProps & {\n /**\n * Defines this component as a native button element.\n *\n * @default 'button'\n */\n as?: 'button';\n\n /**\n * Defines the type of the button. This may be used for form submit buttons.\n *\n * @default 'button'\n */\n type?: 'button' | 'submit';\n } & (RegularButton | ToggleButton);\n\ntype LinkButtonProps = Omit<HTMLProps<HTMLAnchorElement>, 'as' | 'type' | 'onClick' | 'ref'> &\n BaseButtonProps & {\n /**\n * Defines this component as a link element.\n */\n as: 'a';\n\n /**\n * Native button type is not supported when using `as=\"a\"`.\n */\n type?: never;\n\n /**\n * Defines the destination URL for the link button.\n */\n href: string;\n\n /**\n * Toggle behavior is not supported when using `as=\"a\"`.\n *\n * @default false\n */\n asToggle?: false;\n\n /**\n * Callback function triggered when clicking the link.\n *\n * @param event The MouseEvent that triggered the click.\n */\n onClick?: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;\n };\n\nexport type ButtonProps = NativeButtonProps | LinkButtonProps;\n\ntype Props = PropsWithChildren<ButtonProps>;\n\n// Define statics to be used as \"Button.PRIMARY\"\ntype ButtonType = ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>> & {\n DEFAULT: 'default';\n UNSTYLED: 'unstyled';\n PRIMARY: 'primary';\n SECONDARY: 'secondary';\n INFO: 'info';\n WARNING: 'warning';\n DANGER: 'danger';\n SUCCESS: 'success';\n MUTED: 'muted';\n MUTED_FILLED: 'muted-filled';\n\n VARIANT_LINK: 'link';\n VARIANT_LINK_INLINE: 'link-inline';\n VARIANT_OUTLINE: 'outline';\n VARIANT_ACTION: 'action';\n\n XS: 'xs';\n SM: 'sm';\n MD: 'md';\n LG: 'lg';\n};\n\nconst Button = forwardRef<HTMLButtonElement, Props>((props, ref) => {\n const {\n as = 'button',\n active = false,\n disabled = false,\n asToggle = false,\n onClick = noop,\n bsStyle = 'default',\n bsSize,\n variant,\n iconOnly = false,\n iconName,\n iconRight = false,\n multiline = false,\n block = false,\n className = '',\n noRippleEffect = false,\n autoTrackingKey,\n type = 'button',\n tabIndex = 0,\n children,\n ...remainingProps\n } = props;\n\n const autoTrackingAttributes = getAutoTrackingAttributes({\n autoTrackingKey,\n props: remainingProps as Record<string, unknown>,\n source: 'button',\n });\n\n const [isToggled, setIsToggled] = useState(active);\n\n const btnRef = useRef<HTMLButtonElement>(null);\n\n const buttonRef = useMergeRefs(btnRef, ref);\n\n // Update internal toggle state when used as controlled component and outside toggle state changes\n // Note, using the usePrevious hook resulted in an endless loop, hence the useState here\n const [previousActive, setPreviousActive] = useState(active);\n if (active !== previousActive) {\n setIsToggled(active);\n setPreviousActive(active);\n }\n\n const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (!noRippleEffect) {\n createButtonRipple(event.nativeEvent, event.currentTarget);\n }\n\n if (asToggle) {\n // Intercept click handler only for toggle button to update internal state and blur after click\n const newIsToggled = !isToggled;\n setIsToggled(newIsToggled);\n\n if (newIsToggled) {\n btnRef.current?.blur();\n }\n\n (onClick as (x: boolean) => void)(newIsToggled);\n } else {\n (onClick as (x: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void)(event);\n }\n };\n\n const handleLinkClick = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n if (!noRippleEffect) {\n createButtonRipple(event.nativeEvent, event.currentTarget);\n }\n\n (onClick as (x: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void)(event);\n };\n\n const buttonClassNames = classNames(\n 'btn',\n `btn-${bsStyle}`,\n variant === VARIANTS_MAP.VARIANT_LINK && 'btn-link',\n variant === VARIANTS_MAP.VARIANT_LINK_INLINE && 'btn-link btn-link-inline',\n variant === VARIANTS_MAP.VARIANT_OUTLINE && 'btn-outline',\n variant === VARIANTS_MAP.VARIANT_ACTION && 'btn-action',\n bsSize && `btn-${bsSize}`,\n asToggle && 'btn-toggle',\n isToggled && 'active',\n iconOnly && 'btn-icon-only',\n iconRight && 'btn-icon-right',\n multiline && 'btn-multiline',\n block && 'btn-block',\n as === 'a' && 'gap-0',\n as === 'a' && disabled && 'disabled',\n 'btn-component',\n className\n );\n\n if (as === 'a') {\n return (\n <a\n ref={buttonRef as React.Ref<HTMLAnchorElement>}\n {...(remainingProps as Omit<HTMLProps<HTMLAnchorElement>, 'as' | 'type' | 'onClick' | 'ref'>)}\n {...autoTrackingAttributes}\n className={buttonClassNames}\n onClick={handleLinkClick}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : tabIndex}\n >\n {iconName && <span className={`rioglyph ${iconName}`} />}\n {children}\n </a>\n );\n }\n\n return (\n <button\n ref={buttonRef}\n type={type}\n {...(remainingProps as Omit<HTMLProps<HTMLButtonElement>, 'as' | 'type' | 'onClick' | 'ref'>)}\n {...autoTrackingAttributes}\n className={buttonClassNames}\n onClick={handleButtonClick}\n disabled={disabled}\n tabIndex={tabIndex}\n >\n {iconName && <span className={`rioglyph ${iconName}`} />}\n {children}\n </button>\n );\n}) as ButtonType;\n\nObject.assign(Button, STYLES_MAP);\nObject.assign(Button, VARIANTS_MAP);\nObject.assign(Button, SIZES_MAP);\n\nexport default Button;\n"],"names":["STYLES_MAP","VARIANTS_MAP","SIZES_MAP","Button","forwardRef","props","ref","as","active","disabled","asToggle","onClick","noop","bsStyle","bsSize","variant","iconOnly","iconName","iconRight","multiline","block","className","noRippleEffect","autoTrackingKey","type","tabIndex","children","remainingProps","autoTrackingAttributes","getAutoTrackingAttributes","isToggled","setIsToggled","useState","btnRef","useRef","buttonRef","useMergeRefs","previousActive","setPreviousActive","handleButtonClick","event","createButtonRipple","newIsToggled","handleLinkClick","buttonClassNames","classNames","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Button.js","sources":["../../../src/components/button/Button.tsx"],"sourcesContent":["import React, {\n forwardRef,\n type ForwardRefExoticComponent,\n type HTMLProps,\n type PropsWithChildren,\n type RefAttributes,\n useRef,\n useState,\n} from 'react';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport { createButtonRipple } from '../../utils/buttonEffect';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport type { ObjectValues } from '../../utils/ObjectValues';\nimport { getAutoTrackingAttributes } from '../../utils/analytics/autoTracking';\n\nexport const STYLES_MAP = {\n DEFAULT: 'default',\n UNSTYLED: 'unstyled',\n PRIMARY: 'primary',\n SECONDARY: 'secondary',\n INFO: 'info',\n WARNING: 'warning',\n DANGER: 'danger',\n SUCCESS: 'success',\n MUTED: 'muted',\n MUTED_FILLED: 'muted-filled',\n} as const;\n\n// export for convenient usage on client side\nexport type BUTTON_STYLE = ObjectValues<typeof STYLES_MAP>;\n\nexport const VARIANTS_MAP = {\n VARIANT_LINK: 'link',\n VARIANT_LINK_INLINE: 'link-inline',\n VARIANT_OUTLINE: 'outline',\n VARIANT_ACTION: 'action',\n} as const;\n\nexport type BUTTON_VARIANT = ObjectValues<typeof VARIANTS_MAP>;\n\nexport const SIZES_MAP = {\n XS: 'xs',\n SM: 'sm',\n MD: 'md',\n LG: 'lg',\n} as const;\n\nexport type BUTTON_SIZE = ObjectValues<typeof SIZES_MAP>;\n\n/*\n * ATTENTION: We're typing the onClick handler based on the value of `asToggle`.\n *\n * It does not fully work here inside of this file, though. Therefore, we have to apply some explicit casts below.\n * In code _using_ the Button component, however, the parameter type of the onClick handler must either be a boolean or\n * a React.MouseEvent, respectively.\n */\n\ntype RegularButton = {\n /**\n * Use the button as a toggle button. The toggle state can be controlled via the `active` prop.\n *\n * @default false\n */\n asToggle?: false;\n\n /**\n * Callback function triggered when clicking the button.\n *\n * @param event The MouseEvent that triggered the click.\n */\n onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n};\n\ntype ToggleButton = {\n /**\n * Use the button as a toggle button. The toggle state can be controlled via the `active` prop.\n *\n * @default false\n */\n asToggle: true;\n\n /**\n * Callback function triggered when clicking the button.\n *\n * @param value The new value of the toggle button.\n */\n onClick?: (value: boolean) => void;\n};\n\ntype BaseButtonProps = {\n /**\n * Whether the button should be disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Set the button toggled. Should be used in combination with \"asToggle\" prop.\n *\n * @default false\n */\n active?: boolean;\n\n /**\n * Use when the content of the button is an icon only to adapt the button spacing accordingly.\n *\n * @default false\n */\n iconOnly?: boolean;\n\n /**\n * Adds right side spacing for an icon. This should be used when having navigation buttons\n * that use an icon on the right side.\n *\n * @default false\n */\n iconRight?: boolean;\n\n /**\n * Optional RIOglyph icon class name that comes in handy for icon-only buttons without adding\n * a separate icon span.\n *\n * Use only exact existing `rioglyph-*` classes from the generated UIKIT icon contract,\n * for example `rioglyph-download`. Do not compose or guess semantic icon names; an unknown\n * icon class renders as a filled rectangle.\n */\n iconName?: string;\n\n /**\n * Defines whether the button text break into multiple lines when the button space exceeds.\n *\n * Multiline buttons should be used as exception only.\n *\n * @default false\n */\n multiline?: boolean;\n\n /**\n * Defines whether the button takes up the full width of the parent element.\n *\n * @default false\n */\n block?: boolean;\n\n /**\n * Enables a subtle scale animation when the button is hovered.\n *\n * @default false\n */\n hoverScale?: boolean;\n\n /**\n * Sets the button style.\n * @default 'default'\n */\n bsStyle?: BUTTON_STYLE;\n\n /**\n * Sets the button size.\n */\n bsSize?: BUTTON_SIZE;\n\n /**\n * Sets the button variant.\n */\n variant?: BUTTON_VARIANT;\n\n /**\n * Whether the \"ripple\" effect should be suppressed on this button.\n */\n noRippleEffect?: boolean;\n\n /**\n * Optional key used to generate automatic GA tracking attributes when no explicit\n * tracking attributes are provided.\n *\n * Resulting label format: `button::<autoTrackingKey>`.\n */\n autoTrackingKey?: string;\n\n /**\n * Number of the index used for keyboard support.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Additional classes to be set on the button element.\n */\n className?: string;\n};\n\ntype NativeButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'as' | 'type' | 'onClick' | 'ref'> &\n BaseButtonProps & {\n /**\n * Defines this component as a native button element.\n *\n * @default 'button'\n */\n as?: 'button';\n\n /**\n * Defines the native button type.\n *\n * The Button component renders a native `<button>` with `type=\"button\"` by default.\n * Only set `type=\"submit\"` when the button should submit a form. Do not add\n * `type=\"button\"` defensively unless local code style requires explicit defaults.\n *\n * @default 'button'\n */\n type?: 'button' | 'submit';\n } & (RegularButton | ToggleButton);\n\ntype LinkButtonProps = Omit<HTMLProps<HTMLAnchorElement>, 'as' | 'type' | 'onClick' | 'ref'> &\n BaseButtonProps & {\n /**\n * Defines this component as a link element.\n */\n as: 'a';\n\n /**\n * Native button type is not supported when using `as=\"a\"`.\n */\n type?: never;\n\n /**\n * Defines the destination URL for the link button.\n */\n href: string;\n\n /**\n * Toggle behavior is not supported when using `as=\"a\"`.\n *\n * @default false\n */\n asToggle?: false;\n\n /**\n * Callback function triggered when clicking the link.\n *\n * @param event The MouseEvent that triggered the click.\n */\n onClick?: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;\n };\n\nexport type ButtonProps = NativeButtonProps | LinkButtonProps;\n\ntype Props = PropsWithChildren<ButtonProps>;\n\n// Define statics to be used as \"Button.PRIMARY\"\ntype ButtonType = ForwardRefExoticComponent<Props & RefAttributes<HTMLButtonElement>> & {\n DEFAULT: 'default';\n UNSTYLED: 'unstyled';\n PRIMARY: 'primary';\n SECONDARY: 'secondary';\n INFO: 'info';\n WARNING: 'warning';\n DANGER: 'danger';\n SUCCESS: 'success';\n MUTED: 'muted';\n MUTED_FILLED: 'muted-filled';\n\n VARIANT_LINK: 'link';\n VARIANT_LINK_INLINE: 'link-inline';\n VARIANT_OUTLINE: 'outline';\n VARIANT_ACTION: 'action';\n\n XS: 'xs';\n SM: 'sm';\n MD: 'md';\n LG: 'lg';\n};\n\nconst Button = forwardRef<HTMLButtonElement, Props>((props, ref) => {\n const {\n as = 'button',\n active = false,\n disabled = false,\n asToggle = false,\n onClick = noop,\n bsStyle = 'default',\n bsSize,\n variant,\n iconOnly = false,\n iconName,\n iconRight = false,\n multiline = false,\n block = false,\n hoverScale = false,\n className = '',\n noRippleEffect = false,\n autoTrackingKey,\n type = 'button',\n tabIndex = 0,\n children,\n ...remainingProps\n } = props;\n\n const autoTrackingAttributes = getAutoTrackingAttributes({\n autoTrackingKey,\n props: remainingProps as Record<string, unknown>,\n source: 'button',\n });\n\n const [isToggled, setIsToggled] = useState(active);\n\n const btnRef = useRef<HTMLButtonElement>(null);\n\n const buttonRef = useMergeRefs(btnRef, ref);\n\n // Update internal toggle state when used as controlled component and outside toggle state changes\n // Note, using the usePrevious hook resulted in an endless loop, hence the useState here\n const [previousActive, setPreviousActive] = useState(active);\n if (active !== previousActive) {\n setIsToggled(active);\n setPreviousActive(active);\n }\n\n const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (!noRippleEffect) {\n createButtonRipple(event.nativeEvent, event.currentTarget);\n }\n\n if (asToggle) {\n // Intercept click handler only for toggle button to update internal state and blur after click\n const newIsToggled = !isToggled;\n setIsToggled(newIsToggled);\n\n if (newIsToggled) {\n btnRef.current?.blur();\n }\n\n (onClick as (x: boolean) => void)(newIsToggled);\n } else {\n (onClick as (x: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void)(event);\n }\n };\n\n const handleLinkClick = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n if (!noRippleEffect) {\n createButtonRipple(event.nativeEvent, event.currentTarget);\n }\n\n (onClick as (x: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void)(event);\n };\n\n const buttonClassNames = classNames(\n 'btn',\n `btn-${bsStyle}`,\n variant === VARIANTS_MAP.VARIANT_LINK && 'btn-link',\n variant === VARIANTS_MAP.VARIANT_LINK_INLINE && 'btn-link btn-link-inline',\n variant === VARIANTS_MAP.VARIANT_OUTLINE && 'btn-outline',\n variant === VARIANTS_MAP.VARIANT_ACTION && 'btn-action',\n bsSize && `btn-${bsSize}`,\n asToggle && 'btn-toggle',\n isToggled && 'active',\n iconOnly && 'btn-icon-only',\n iconRight && 'btn-icon-right',\n multiline && 'btn-multiline',\n block && 'btn-block',\n hoverScale && 'hover-scale',\n as === 'a' && 'gap-0',\n as === 'a' && disabled && 'disabled',\n 'btn-component',\n className\n );\n\n if (as === 'a') {\n return (\n <a\n ref={buttonRef as React.Ref<HTMLAnchorElement>}\n {...(remainingProps as Omit<HTMLProps<HTMLAnchorElement>, 'as' | 'type' | 'onClick' | 'ref'>)}\n {...autoTrackingAttributes}\n className={buttonClassNames}\n onClick={handleLinkClick}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : tabIndex}\n >\n {iconName && <span className={`rioglyph ${iconName}`} />}\n {children}\n </a>\n );\n }\n\n return (\n <button\n ref={buttonRef}\n type={type}\n {...(remainingProps as Omit<HTMLProps<HTMLButtonElement>, 'as' | 'type' | 'onClick' | 'ref'>)}\n {...autoTrackingAttributes}\n className={buttonClassNames}\n onClick={handleButtonClick}\n disabled={disabled}\n tabIndex={tabIndex}\n >\n {iconName && <span className={`rioglyph ${iconName}`} />}\n {children}\n </button>\n );\n}) as ButtonType;\n\nObject.assign(Button, STYLES_MAP);\nObject.assign(Button, VARIANTS_MAP);\nObject.assign(Button, SIZES_MAP);\n\nexport default Button;\n"],"names":["STYLES_MAP","VARIANTS_MAP","SIZES_MAP","Button","forwardRef","props","ref","as","active","disabled","asToggle","onClick","noop","bsStyle","bsSize","variant","iconOnly","iconName","iconRight","multiline","block","hoverScale","className","noRippleEffect","autoTrackingKey","type","tabIndex","children","remainingProps","autoTrackingAttributes","getAutoTrackingAttributes","isToggled","setIsToggled","useState","btnRef","useRef","buttonRef","useMergeRefs","previousActive","setPreviousActive","handleButtonClick","event","createButtonRipple","newIsToggled","handleLinkClick","buttonClassNames","classNames","jsxs","jsx"],"mappings":"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"}
@@ -163,6 +163,10 @@ export type ClearableInputProps = {
163
163
  * Parses the masked string representation back to a typed date value.
164
164
  */
165
165
  parse?: (value: string, masked: unknown) => Date | null;
166
+ /**
167
+ * Custom IMask blocks for pattern masks.
168
+ */
169
+ blocks?: Record<string, unknown>;
166
170
  /**
167
171
  * Enables IMask autofix behavior for date and number masks.
168
172
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ClearableInput.js","sources":["../../../src/components/clearableInput/ClearableInput.tsx"],"sourcesContent":["/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */\nimport React, { useState, forwardRef, type ForwardedRef, useRef } from 'react';\nimport { isEmpty, omit } from 'es-toolkit/compat';\nimport { isFunction, isNil } from 'es-toolkit/predicate';\nimport { noop } from 'es-toolkit/function';\nimport { IMaskInput } from 'react-imask';\n\nimport classNames from '../../utils/classNames';\nimport usePrevious from '../../hooks/usePrevious';\nimport useMergeRefs from '../../hooks/useMergeRefs';\n\nexport const DEFAULT_TYPE = 'text';\nexport const SUPPORTED_TYPES = ['text', 'password', 'email'];\n\nexport type MaskVisibility = 'always' | 'onFocus' | 'never';\nexport type MaskDefinition = {\n mask: string;\n definitions?: Record<string, string | RegExp>;\n startsWith?: string;\n [key: string]: any;\n};\n\nexport type ClearableInputProps = {\n /**\n * Gives the input element the id.\n */\n id?: string;\n\n /**\n * Gives the input element a name.\n */\n name?: string;\n\n /**\n * The translated text that shall be shown when the input is empty.\n */\n placeholder?: string | React.ReactNode;\n\n /**\n * Defines the type of the input itself.\n *\n * There are three types supported:\n * `text`, `email`, `password`.\n *\n * @default 'text'\n */\n type?: 'text' | 'password' | 'email';\n\n /**\n * Initial value of the ClearableInput. Pass this prop if you want to use this\n * component as an uncontrolled component.\n */\n defaultValue?: string;\n\n /**\n * Value of the ClearableInput. Pass this prop if you want to use this\n * component as a controlled component.\n */\n value?: string;\n\n /**\n * Defines the maximum amount of characters that can be entered.\n */\n maxLength?: number;\n\n /**\n * Defines the tab index to be added to the input element.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Defined whether or not the input has the error styling.\n *\n * @default false\n */\n hasError?: boolean;\n\n /**\n * The callback ref for the underlying input. Alternatively, use can use a forward ref.\n */\n inputRef?: React.RefObject<HTMLInputElement>;\n\n /**\n * Sets autocomplete value for autosuggest forms.\n */\n autoComplete?: string;\n\n /**\n * Callback function for when the value changes. Receives new value as an argument.\n * @param newValue\n * @param event\n * @returns\n */\n onChange?: (\n newValue: string,\n event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLSpanElement>\n ) => void;\n\n /**\n * Callback function which gets triggered when the input looses the focus.\n * @param event\n * @returns\n */\n onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;\n\n /**\n * Callback function which gets triggered when the input gains the focus.\n * @param event\n * @returns\n */\n onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;\n\n /**\n * Callback function for when the value is cleared via the clear button.\n * @param event\n * @returns\n */\n onClear?: (event: React.MouseEvent<HTMLSpanElement>) => void;\n\n /**\n * Callback function for every key pressed including `Enter` key.\n * @param event\n * @returns\n */\n onKeyPress?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n\n /**\n * Callback triggered when clicked into the input to react on it like when using an auto suggest dropdown\n * @param event\n * @returns\n */\n onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;\n\n /**\n * The mask prop will allow to use the component with an input mask.\n * It defines the pattern that should be followed.\n *\n * For more details on masking, checkout the third party documentation for the\n * input mask here: {@link https://imask.js.org/guide.html}\n *\n * Simple masks can be defined as strings.\n *\n * The following characters will define mask format:\n *\n * - \"0\" = allowed input: \"0-9\" (digit)\n * - \"a\" = allowed input: \"a-z, A-Z\" (letter)\n * - \"*\" = allowed input: any character\n * - \"#\" = allowed input: \"0-9, a-z, A-Z\" (digit or letter)\n *\n * Other chars which is not in custom definitions supposed to be fixed:\n *\n * - [] - make input optional\n * - {} - include fixed part in unmasked value\n * - ` - prevent symbols shift back\n *\n * If definition character should be treated as fixed it should be escaped by \\\\ (E.g. \\\\0).\n *\n * Additionally you can provide custom definitions.\n *\n * @example\n * '-- ### ### ###' or '+49 00 000 00'\n */\n mask?: string | (string | RegExp)[] | RegExp | DateConstructor | number | Function | MaskDefinition[];\n\n /**\n * Placeholder to cover unfilled parts of the mask.\n *\n * @default '_'\n */\n maskPlaceholder?: string | null;\n\n /**\n * Enable characters overwriting\n *\n * @default true\n */\n maskOverwrite?: boolean | 'shift' | undefined;\n\n /**\n * Chooses the mask for dynamic masking depending on input value.\n * Note, this function may not be an empty function, otherwise the mask selection won't work\n */\n maskDispatch?: (appended: string, dynamicMasked: any) => any;\n\n /**\n * Pattern used by IMask date masks.\n *\n * @example\n * 'Y-m-d'\n */\n pattern?: string;\n\n /**\n * Formats a typed date value to the masked string representation.\n */\n format?: (value: Date | null, masked: unknown) => string;\n\n /**\n * Parses the masked string representation back to a typed date value.\n */\n parse?: (value: string, masked: unknown) => Date | null;\n\n /**\n * Enables IMask autofix behavior for date and number masks.\n */\n autofix?: boolean | 'pad';\n\n /**\n * Controls when the mask pattern is visible.\n *\n * - 'always': Mask is always visible\n * - 'onFocus': Mask is hidden but shown when input is focused\n * - 'never': Mask is never shown\n *\n * @default 'always'\n */\n maskVisibility?: MaskVisibility;\n\n /**\n * Custom definitions to have more control over your mask. The defined character will be replaced in your mask.\n *\n * @example\n * mask='AAA AAA.AA'\n * maskDefinitions={{ A: /[A-Z0-9]/ }}\n */\n maskDefinitions?: Record<string, string | RegExp>;\n\n /**\n * Minimum value to be entered. This prop is extended to accept a Date\n * when used with an input mask.\n */\n min?: string | number | undefined | Date;\n\n /**\n * Maximum value to be entered. This prop is extended to accept a Date\n * when used with an input mask.\n */\n max?: string | number | undefined | Date;\n\n /**\n * Disabled the input component.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Makes the input read-only.\n */\n readOnly?: boolean;\n\n /**\n * Controls whether the clear button is rendered.\n * This might be useful to reuse this component for other use-cases.\n *\n * @default true\n */\n showClearButton?: boolean;\n\n /**\n * Additional classes to be set on the input element.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n\n /**\n * Render-prop to customize the rendered input.\n *\n * The function gets the `inputProps` passed and is responsible for rendering the custom `<input>` component.\n *\n * Receives the computed `input` props so you can render your own field. See: {@link https://reactjs.org/docs/render-props.html}\n */\n children?: (props: React.InputHTMLAttributes<HTMLInputElement>) => React.ReactNode;\n};\n\nconst hasValue = (value: unknown) => !isEmpty(`${value}`);\n\nconst ClearableInput = forwardRef((props: ClearableInputProps, ref: ForwardedRef<HTMLInputElement>) => {\n const {\n type = DEFAULT_TYPE,\n defaultValue,\n value,\n showClearButton = true,\n maxLength,\n tabIndex = 0,\n hasError = false,\n inputRef,\n autoComplete,\n onChange = noop,\n onBlur = noop,\n onFocus = noop,\n onClear = noop,\n onKeyPress = noop,\n onClick = noop,\n mask,\n maskPlaceholder = '_',\n maskVisibility = 'always',\n maskOverwrite = true,\n maskDefinitions,\n maskDispatch,\n inputClassName = '',\n disabled = false,\n readOnly = false,\n className = '',\n children,\n ...remainingProps\n } = props;\n\n const initialValue = value || defaultValue || '';\n\n const [inputValue, setInputValue] = useState(initialValue);\n const [showClear, setShowClear] = useState(hasValue(initialValue));\n const [isFocused, setIsFocused] = useState(false);\n\n const isControlled = !isNil(value);\n\n const internalMaskRef = useRef<HTMLInputElement>(null);\n const mergedInternalMaskRef = useMergeRefs(internalMaskRef, inputRef, ref);\n\n const hasMask = !!mask;\n\n // Calculate if mask should be visible (lazy=false means visible, lazy=true means hidden)\n const shouldShowMask = () => {\n switch (maskVisibility) {\n case 'always':\n return true;\n case 'onFocus':\n return isFocused;\n case 'never':\n return false;\n default:\n return isFocused;\n }\n };\n\n // Handles new input value and saves it in the local state.\n // The value stored in the state is used for rendering.\n const changeInternalValue = (newValue = '') => {\n // this is there to prevent that onChange and UNSAFE_componentWillReceiveProps set state at the same time\n if (inputValue === newValue) {\n return;\n }\n\n setInputValue(newValue);\n setShowClear(hasValue(newValue));\n };\n\n // important for when used as a controlled component and value changes from the outside.\n const previousValue = usePrevious(value);\n if (previousValue !== value) {\n changeInternalValue(value);\n }\n\n // only gets triggered on user interaction.\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value;\n\n if (isControlled) {\n onChange(newValue, event);\n } else {\n changeInternalValue(newValue);\n onChange(newValue, event);\n }\n };\n\n const handleAccept = (newValue: string, maskRef: any, _event?: InputEvent) => {\n if (!internalMaskRef.current) {\n return;\n }\n\n // Simulate a ChangeEvent for backwards compatibility since react-imask does not return a change event itself\n const syntheticEvent = {\n target: internalMaskRef.current,\n currentTarget: internalMaskRef.current,\n // Standard synthetic event props\n bubbles: true,\n cancelable: true,\n defaultPrevented: false,\n isTrusted: true,\n preventDefault: () => {},\n stopPropagation: () => {},\n persist: () => {},\n nativeEvent: {} as any,\n type: 'change',\n timeStamp: Date.now(),\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n\n // Set unmasked value manually if needed\n // (you can use data-attributes or attach it directly)\n (syntheticEvent.target as any).unmaskedValue = maskRef.unmaskedValue;\n\n if (isControlled) {\n onChange(newValue, syntheticEvent);\n } else {\n changeInternalValue(newValue);\n onChange(newValue, syntheticEvent);\n }\n };\n\n const handleInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(true);\n onFocus(event);\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(false);\n onBlur(event);\n };\n\n // Will be triggered on every key press but also when pressing 'Enter' for example\n const handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyPress(event);\n };\n\n const clearInputValue = (event: React.MouseEvent<HTMLSpanElement>) => {\n changeInternalValue('');\n onChange('', event);\n\n if (onClear) {\n onClear(event);\n }\n };\n\n const classes = classNames(\n 'ClearableInput',\n 'input-group',\n hasError && 'has-error',\n disabled && 'pointer-events-none',\n className && className\n );\n\n const inputClassNames = classNames(\n 'form-control',\n inputClassName,\n showClear && showClearButton && 'withClearButton',\n hasMask && 'withInputMask',\n disabled && 'disabled'\n );\n\n const clearButtonClassNames = classNames('clearButton', (!showClear || !showClearButton) && 'hide');\n\n const convertedType = type?.toLowerCase();\n const inputType = SUPPORTED_TYPES.indexOf(convertedType) !== -1 ? convertedType : DEFAULT_TYPE;\n\n const inputProps = {\n ...omit(remainingProps, ['value', 'defaultValue', 'onClear']),\n className: inputClassNames,\n autoComplete,\n type: inputType,\n value: inputValue,\n onKeyPress: handleKeyPress,\n onBlur: handleInputBlur,\n onFocus: handleInputFocus,\n onChange: hasMask ? undefined : handleChange, // In case of masked input, the onAccept callback is used\n onClick,\n disabled,\n readOnly,\n maxLength: hasMask ? undefined : maxLength,\n tabIndex,\n } as any;\n\n // The dispatch function may not be an empty function. Specify it when\n // using dynamic masking and need more control over which mask gets selected\n const maskDispatchObj: any = {};\n if (maskDispatch) {\n maskDispatchObj.dispatch = maskDispatch;\n }\n\n const input = hasMask ? (\n <IMaskInput\n {...inputProps}\n inputRef={mergedInternalMaskRef}\n mask={mask}\n definitions={maskDefinitions}\n {...maskDispatchObj}\n placeholderChar={maskPlaceholder}\n onAccept={handleAccept}\n lazy={!shouldShowMask()}\n overwrite={maskOverwrite}\n />\n ) : (\n <input {...inputProps} ref={inputRef || ref} />\n );\n\n return (\n <div className={classes}>\n {children && isFunction(children) ? children(inputProps) : input}\n <span className={clearButtonClassNames} onClick={clearInputValue}>\n <span className='clearButtonIcon rioglyph rioglyph-remove-sign' />\n </span>\n </div>\n );\n});\n\nexport default ClearableInput;\n"],"names":["DEFAULT_TYPE","SUPPORTED_TYPES","hasValue","value","isEmpty","ClearableInput","forwardRef","props","ref","type","defaultValue","showClearButton","maxLength","tabIndex","hasError","inputRef","autoComplete","onChange","noop","onBlur","onFocus","onClear","onKeyPress","onClick","mask","maskPlaceholder","maskVisibility","maskOverwrite","maskDefinitions","maskDispatch","inputClassName","disabled","readOnly","className","children","remainingProps","initialValue","inputValue","setInputValue","useState","showClear","setShowClear","isFocused","setIsFocused","isControlled","isNil","internalMaskRef","useRef","mergedInternalMaskRef","useMergeRefs","hasMask","shouldShowMask","changeInternalValue","newValue","usePrevious","handleChange","event","handleAccept","maskRef","_event","syntheticEvent","handleInputFocus","handleInputBlur","handleKeyPress","clearInputValue","classes","classNames","inputClassNames","clearButtonClassNames","convertedType","inputType","inputProps","omit","maskDispatchObj","input","jsx","IMaskInput","jsxs","isFunction"],"mappings":"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"}
1
+ {"version":3,"file":"ClearableInput.js","sources":["../../../src/components/clearableInput/ClearableInput.tsx"],"sourcesContent":["/** biome-ignore-all lint/complexity/noBannedTypes: <explanation> */\nimport React, { useState, forwardRef, type ForwardedRef, useRef } from 'react';\nimport { isEmpty, omit } from 'es-toolkit/compat';\nimport { isFunction, isNil } from 'es-toolkit/predicate';\nimport { noop } from 'es-toolkit/function';\nimport { IMaskInput } from 'react-imask';\n\nimport classNames from '../../utils/classNames';\nimport usePrevious from '../../hooks/usePrevious';\nimport useMergeRefs from '../../hooks/useMergeRefs';\n\nexport const DEFAULT_TYPE = 'text';\nexport const SUPPORTED_TYPES = ['text', 'password', 'email'];\n\nexport type MaskVisibility = 'always' | 'onFocus' | 'never';\nexport type MaskDefinition = {\n mask: string;\n definitions?: Record<string, string | RegExp>;\n startsWith?: string;\n [key: string]: any;\n};\n\nexport type ClearableInputProps = {\n /**\n * Gives the input element the id.\n */\n id?: string;\n\n /**\n * Gives the input element a name.\n */\n name?: string;\n\n /**\n * The translated text that shall be shown when the input is empty.\n */\n placeholder?: string | React.ReactNode;\n\n /**\n * Defines the type of the input itself.\n *\n * There are three types supported:\n * `text`, `email`, `password`.\n *\n * @default 'text'\n */\n type?: 'text' | 'password' | 'email';\n\n /**\n * Initial value of the ClearableInput. Pass this prop if you want to use this\n * component as an uncontrolled component.\n */\n defaultValue?: string;\n\n /**\n * Value of the ClearableInput. Pass this prop if you want to use this\n * component as a controlled component.\n */\n value?: string;\n\n /**\n * Defines the maximum amount of characters that can be entered.\n */\n maxLength?: number;\n\n /**\n * Defines the tab index to be added to the input element.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Defined whether or not the input has the error styling.\n *\n * @default false\n */\n hasError?: boolean;\n\n /**\n * The callback ref for the underlying input. Alternatively, use can use a forward ref.\n */\n inputRef?: React.RefObject<HTMLInputElement>;\n\n /**\n * Sets autocomplete value for autosuggest forms.\n */\n autoComplete?: string;\n\n /**\n * Callback function for when the value changes. Receives new value as an argument.\n * @param newValue\n * @param event\n * @returns\n */\n onChange?: (\n newValue: string,\n event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLSpanElement>\n ) => void;\n\n /**\n * Callback function which gets triggered when the input looses the focus.\n * @param event\n * @returns\n */\n onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;\n\n /**\n * Callback function which gets triggered when the input gains the focus.\n * @param event\n * @returns\n */\n onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;\n\n /**\n * Callback function for when the value is cleared via the clear button.\n * @param event\n * @returns\n */\n onClear?: (event: React.MouseEvent<HTMLSpanElement>) => void;\n\n /**\n * Callback function for every key pressed including `Enter` key.\n * @param event\n * @returns\n */\n onKeyPress?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n\n /**\n * Callback triggered when clicked into the input to react on it like when using an auto suggest dropdown\n * @param event\n * @returns\n */\n onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;\n\n /**\n * The mask prop will allow to use the component with an input mask.\n * It defines the pattern that should be followed.\n *\n * For more details on masking, checkout the third party documentation for the\n * input mask here: {@link https://imask.js.org/guide.html}\n *\n * Simple masks can be defined as strings.\n *\n * The following characters will define mask format:\n *\n * - \"0\" = allowed input: \"0-9\" (digit)\n * - \"a\" = allowed input: \"a-z, A-Z\" (letter)\n * - \"*\" = allowed input: any character\n * - \"#\" = allowed input: \"0-9, a-z, A-Z\" (digit or letter)\n *\n * Other chars which is not in custom definitions supposed to be fixed:\n *\n * - [] - make input optional\n * - {} - include fixed part in unmasked value\n * - ` - prevent symbols shift back\n *\n * If definition character should be treated as fixed it should be escaped by \\\\ (E.g. \\\\0).\n *\n * Additionally you can provide custom definitions.\n *\n * @example\n * '-- ### ### ###' or '+49 00 000 00'\n */\n mask?: string | (string | RegExp)[] | RegExp | DateConstructor | number | Function | MaskDefinition[];\n\n /**\n * Placeholder to cover unfilled parts of the mask.\n *\n * @default '_'\n */\n maskPlaceholder?: string | null;\n\n /**\n * Enable characters overwriting\n *\n * @default true\n */\n maskOverwrite?: boolean | 'shift' | undefined;\n\n /**\n * Chooses the mask for dynamic masking depending on input value.\n * Note, this function may not be an empty function, otherwise the mask selection won't work\n */\n maskDispatch?: (appended: string, dynamicMasked: any) => any;\n\n /**\n * Pattern used by IMask date masks.\n *\n * @example\n * 'Y-m-d'\n */\n pattern?: string;\n\n /**\n * Formats a typed date value to the masked string representation.\n */\n format?: (value: Date | null, masked: unknown) => string;\n\n /**\n * Parses the masked string representation back to a typed date value.\n */\n parse?: (value: string, masked: unknown) => Date | null;\n\n /**\n * Custom IMask blocks for pattern masks.\n */\n blocks?: Record<string, unknown>;\n\n /**\n * Enables IMask autofix behavior for date and number masks.\n */\n autofix?: boolean | 'pad';\n\n /**\n * Controls when the mask pattern is visible.\n *\n * - 'always': Mask is always visible\n * - 'onFocus': Mask is hidden but shown when input is focused\n * - 'never': Mask is never shown\n *\n * @default 'always'\n */\n maskVisibility?: MaskVisibility;\n\n /**\n * Custom definitions to have more control over your mask. The defined character will be replaced in your mask.\n *\n * @example\n * mask='AAA AAA.AA'\n * maskDefinitions={{ A: /[A-Z0-9]/ }}\n */\n maskDefinitions?: Record<string, string | RegExp>;\n\n /**\n * Minimum value to be entered. This prop is extended to accept a Date\n * when used with an input mask.\n */\n min?: string | number | undefined | Date;\n\n /**\n * Maximum value to be entered. This prop is extended to accept a Date\n * when used with an input mask.\n */\n max?: string | number | undefined | Date;\n\n /**\n * Disabled the input component.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Makes the input read-only.\n */\n readOnly?: boolean;\n\n /**\n * Controls whether the clear button is rendered.\n * This might be useful to reuse this component for other use-cases.\n *\n * @default true\n */\n showClearButton?: boolean;\n\n /**\n * Additional classes to be set on the input element.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n\n /**\n * Render-prop to customize the rendered input.\n *\n * The function gets the `inputProps` passed and is responsible for rendering the custom `<input>` component.\n *\n * Receives the computed `input` props so you can render your own field. See: {@link https://reactjs.org/docs/render-props.html}\n */\n children?: (props: React.InputHTMLAttributes<HTMLInputElement>) => React.ReactNode;\n};\n\nconst hasValue = (value: unknown) => !isEmpty(`${value}`);\n\nconst ClearableInput = forwardRef((props: ClearableInputProps, ref: ForwardedRef<HTMLInputElement>) => {\n const {\n type = DEFAULT_TYPE,\n defaultValue,\n value,\n showClearButton = true,\n maxLength,\n tabIndex = 0,\n hasError = false,\n inputRef,\n autoComplete,\n onChange = noop,\n onBlur = noop,\n onFocus = noop,\n onClear = noop,\n onKeyPress = noop,\n onClick = noop,\n mask,\n maskPlaceholder = '_',\n maskVisibility = 'always',\n maskOverwrite = true,\n maskDefinitions,\n maskDispatch,\n inputClassName = '',\n disabled = false,\n readOnly = false,\n className = '',\n children,\n ...remainingProps\n } = props;\n\n const initialValue = value || defaultValue || '';\n\n const [inputValue, setInputValue] = useState(initialValue);\n const [showClear, setShowClear] = useState(hasValue(initialValue));\n const [isFocused, setIsFocused] = useState(false);\n\n const isControlled = !isNil(value);\n\n const internalMaskRef = useRef<HTMLInputElement>(null);\n const mergedInternalMaskRef = useMergeRefs(internalMaskRef, inputRef, ref);\n\n const hasMask = !!mask;\n\n // Calculate if mask should be visible (lazy=false means visible, lazy=true means hidden)\n const shouldShowMask = () => {\n switch (maskVisibility) {\n case 'always':\n return true;\n case 'onFocus':\n return isFocused;\n case 'never':\n return false;\n default:\n return isFocused;\n }\n };\n\n // Handles new input value and saves it in the local state.\n // The value stored in the state is used for rendering.\n const changeInternalValue = (newValue = '') => {\n // this is there to prevent that onChange and UNSAFE_componentWillReceiveProps set state at the same time\n if (inputValue === newValue) {\n return;\n }\n\n setInputValue(newValue);\n setShowClear(hasValue(newValue));\n };\n\n // important for when used as a controlled component and value changes from the outside.\n const previousValue = usePrevious(value);\n if (previousValue !== value) {\n changeInternalValue(value);\n }\n\n // only gets triggered on user interaction.\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = event.target.value;\n\n if (isControlled) {\n onChange(newValue, event);\n } else {\n changeInternalValue(newValue);\n onChange(newValue, event);\n }\n };\n\n const handleAccept = (newValue: string, maskRef: any, _event?: InputEvent) => {\n if (!internalMaskRef.current) {\n return;\n }\n\n // Simulate a ChangeEvent for backwards compatibility since react-imask does not return a change event itself\n const syntheticEvent = {\n target: internalMaskRef.current,\n currentTarget: internalMaskRef.current,\n // Standard synthetic event props\n bubbles: true,\n cancelable: true,\n defaultPrevented: false,\n isTrusted: true,\n preventDefault: () => {},\n stopPropagation: () => {},\n persist: () => {},\n nativeEvent: {} as any,\n type: 'change',\n timeStamp: Date.now(),\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n\n // Set unmasked value manually if needed\n // (you can use data-attributes or attach it directly)\n (syntheticEvent.target as any).unmaskedValue = maskRef.unmaskedValue;\n\n if (isControlled) {\n onChange(newValue, syntheticEvent);\n } else {\n changeInternalValue(newValue);\n onChange(newValue, syntheticEvent);\n }\n };\n\n const handleInputFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(true);\n onFocus(event);\n };\n\n const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(false);\n onBlur(event);\n };\n\n // Will be triggered on every key press but also when pressing 'Enter' for example\n const handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyPress(event);\n };\n\n const clearInputValue = (event: React.MouseEvent<HTMLSpanElement>) => {\n changeInternalValue('');\n onChange('', event);\n\n if (onClear) {\n onClear(event);\n }\n };\n\n const classes = classNames(\n 'ClearableInput',\n 'input-group',\n hasError && 'has-error',\n disabled && 'pointer-events-none',\n className && className\n );\n\n const inputClassNames = classNames(\n 'form-control',\n inputClassName,\n showClear && showClearButton && 'withClearButton',\n hasMask && 'withInputMask',\n disabled && 'disabled'\n );\n\n const clearButtonClassNames = classNames('clearButton', (!showClear || !showClearButton) && 'hide');\n\n const convertedType = type?.toLowerCase();\n const inputType = SUPPORTED_TYPES.indexOf(convertedType) !== -1 ? convertedType : DEFAULT_TYPE;\n\n const inputProps = {\n ...omit(remainingProps, ['value', 'defaultValue', 'onClear']),\n className: inputClassNames,\n autoComplete,\n type: inputType,\n value: inputValue,\n onKeyPress: handleKeyPress,\n onBlur: handleInputBlur,\n onFocus: handleInputFocus,\n onChange: hasMask ? undefined : handleChange, // In case of masked input, the onAccept callback is used\n onClick,\n disabled,\n readOnly,\n maxLength: hasMask ? undefined : maxLength,\n tabIndex,\n } as any;\n\n // The dispatch function may not be an empty function. Specify it when\n // using dynamic masking and need more control over which mask gets selected\n const maskDispatchObj: any = {};\n if (maskDispatch) {\n maskDispatchObj.dispatch = maskDispatch;\n }\n\n const input = hasMask ? (\n <IMaskInput\n {...inputProps}\n inputRef={mergedInternalMaskRef}\n mask={mask}\n definitions={maskDefinitions}\n {...maskDispatchObj}\n placeholderChar={maskPlaceholder}\n onAccept={handleAccept}\n lazy={!shouldShowMask()}\n overwrite={maskOverwrite}\n />\n ) : (\n <input {...inputProps} ref={inputRef || ref} />\n );\n\n return (\n <div className={classes}>\n {children && isFunction(children) ? children(inputProps) : input}\n <span className={clearButtonClassNames} onClick={clearInputValue}>\n <span className='clearButtonIcon rioglyph rioglyph-remove-sign' />\n </span>\n </div>\n );\n});\n\nexport default ClearableInput;\n"],"names":["DEFAULT_TYPE","SUPPORTED_TYPES","hasValue","value","isEmpty","ClearableInput","forwardRef","props","ref","type","defaultValue","showClearButton","maxLength","tabIndex","hasError","inputRef","autoComplete","onChange","noop","onBlur","onFocus","onClear","onKeyPress","onClick","mask","maskPlaceholder","maskVisibility","maskOverwrite","maskDefinitions","maskDispatch","inputClassName","disabled","readOnly","className","children","remainingProps","initialValue","inputValue","setInputValue","useState","showClear","setShowClear","isFocused","setIsFocused","isControlled","isNil","internalMaskRef","useRef","mergedInternalMaskRef","useMergeRefs","hasMask","shouldShowMask","changeInternalValue","newValue","usePrevious","handleChange","event","handleAccept","maskRef","_event","syntheticEvent","handleInputFocus","handleInputBlur","handleKeyPress","clearInputValue","classes","classNames","inputClassNames","clearButtonClassNames","convertedType","inputType","inputProps","omit","maskDispatchObj","input","jsx","IMaskInput","jsxs","isFunction"],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { default as React } from 'react';
2
+ import { ClearableInputProps } from '../clearableInput/ClearableInput';
3
+ export type CountedInputProps = Omit<ClearableInputProps, 'children' | 'max' | 'min' | 'onChange' | 'showClearButton'> & {
4
+ /**
5
+ * Defines the minimum amount of characters required for a valid value.
6
+ * If set, the counter counts up to this value because this is the threshold for success.
7
+ * If no `maxLength` is set, this value is also used as the maximum amount of characters that can be entered.
8
+ * Set at least one of `minLength` or `maxLength`.
9
+ *
10
+ * @default 0
11
+ */
12
+ minLength?: number;
13
+ /**
14
+ * Defines the maximum amount of characters that can be entered.
15
+ * If no `minLength` is set, the counter counts up to this value.
16
+ * Set at least one of `minLength` or `maxLength`.
17
+ */
18
+ maxLength?: number;
19
+ /**
20
+ * Controls whether the clear button is rendered.
21
+ *
22
+ * @default false
23
+ */
24
+ clearable?: boolean;
25
+ /**
26
+ * Controls whether success or warning feedback styling is rendered. If omitted, feedback is shown after user
27
+ * interaction or when the input has a value.
28
+ */
29
+ showValidationState?: boolean;
30
+ /**
31
+ * Controls whether an initially empty input is validated before user interaction.
32
+ *
33
+ * @default false
34
+ */
35
+ validateInitialEmpty?: boolean;
36
+ /**
37
+ * Defines the invalid feedback style used while the character criteria are not met.
38
+ *
39
+ * @default 'warning'
40
+ */
41
+ validationState?: 'warning' | 'error';
42
+ /**
43
+ * Callback function for when the value changes. Receives the new value and validity as arguments.
44
+ */
45
+ onChange?: (newValue: string, isValid: boolean, event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLSpanElement>) => void;
46
+ };
47
+ declare const CountedInput: React.ForwardRefExoticComponent<Omit<ClearableInputProps, "max" | "min" | "children" | "onChange" | "showClearButton"> & {
48
+ /**
49
+ * Defines the minimum amount of characters required for a valid value.
50
+ * If set, the counter counts up to this value because this is the threshold for success.
51
+ * If no `maxLength` is set, this value is also used as the maximum amount of characters that can be entered.
52
+ * Set at least one of `minLength` or `maxLength`.
53
+ *
54
+ * @default 0
55
+ */
56
+ minLength?: number;
57
+ /**
58
+ * Defines the maximum amount of characters that can be entered.
59
+ * If no `minLength` is set, the counter counts up to this value.
60
+ * Set at least one of `minLength` or `maxLength`.
61
+ */
62
+ maxLength?: number;
63
+ /**
64
+ * Controls whether the clear button is rendered.
65
+ *
66
+ * @default false
67
+ */
68
+ clearable?: boolean;
69
+ /**
70
+ * Controls whether success or warning feedback styling is rendered. If omitted, feedback is shown after user
71
+ * interaction or when the input has a value.
72
+ */
73
+ showValidationState?: boolean;
74
+ /**
75
+ * Controls whether an initially empty input is validated before user interaction.
76
+ *
77
+ * @default false
78
+ */
79
+ validateInitialEmpty?: boolean;
80
+ /**
81
+ * Defines the invalid feedback style used while the character criteria are not met.
82
+ *
83
+ * @default 'warning'
84
+ */
85
+ validationState?: "warning" | "error";
86
+ /**
87
+ * Callback function for when the value changes. Receives the new value and validity as arguments.
88
+ */
89
+ onChange?: (newValue: string, isValid: boolean, event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLSpanElement>) => void;
90
+ } & React.RefAttributes<HTMLInputElement>>;
91
+ export default CountedInput;
@@ -0,0 +1,65 @@
1
+ import { jsx as r, jsxs as x } from "react/jsx-runtime";
2
+ import { forwardRef as K, useState as I } from "react";
3
+ import { isNil as O } from "es-toolkit/predicate";
4
+ import { noop as N } from "es-toolkit/function";
5
+ import c from "../../utils/classNames.js";
6
+ import Q from "../clearableInput/ClearableInput.js";
7
+ const v = (l, i, u) => {
8
+ const t = l.length;
9
+ return t >= i && t <= u;
10
+ }, tt = K((l, i) => {
11
+ const {
12
+ defaultValue: u,
13
+ value: t,
14
+ minLength: h = 0,
15
+ maxLength: V,
16
+ clearable: S = !1,
17
+ showValidationState: w,
18
+ validateInitialEmpty: L = !1,
19
+ validationState: m = "warning",
20
+ className: b = "",
21
+ onChange: B = N,
22
+ onBlur: T = N,
23
+ ...y
24
+ } = l, n = V ?? h ?? 0, s = h ?? 0, M = t || u || "", [j, k] = I(M), [$, p] = I(!1), g = !O(t), o = g ? t || "" : j, d = v(o, s, n), a = w ?? (L || o.length > 0 || $), E = m === "error" ? "has-error" : "has-warning", P = m === "error" ? "text-color-danger" : "text-color-warning", f = a && d, C = s > 0 ? s : n, R = `${Math.min(o.length, C)}/${C}`, q = (e, H) => {
25
+ const J = v(e, s, n);
26
+ p(!0), g || k(e), B(e, J, H);
27
+ }, z = (e) => {
28
+ p(!0), T(e);
29
+ }, A = c(
30
+ "form-group",
31
+ "CountedInput",
32
+ a && "has-feedback",
33
+ a && (d ? "has-success" : E),
34
+ b
35
+ ), D = c(
36
+ "input-group-addon",
37
+ "CountedInputCounter text-bold",
38
+ a && (d ? "text-color-success" : P)
39
+ ), F = c("CountedInputCounterValue text-italic", f && "is-hidden"), G = c(
40
+ "CountedInputSuccessIcon rioglyph rioglyph-ok text-color-success",
41
+ f && "is-visible"
42
+ );
43
+ return /* @__PURE__ */ r("div", { className: A, children: /* @__PURE__ */ x("div", { className: "input-group", children: [
44
+ /* @__PURE__ */ r(
45
+ Q,
46
+ {
47
+ ...y,
48
+ ref: i,
49
+ value: o,
50
+ maxLength: n,
51
+ showClearButton: S,
52
+ onChange: q,
53
+ onBlur: z
54
+ }
55
+ ),
56
+ /* @__PURE__ */ x("span", { className: D, children: [
57
+ /* @__PURE__ */ r("span", { className: F, children: R }),
58
+ /* @__PURE__ */ r("span", { className: G, "aria-hidden": !0 })
59
+ ] })
60
+ ] }) });
61
+ });
62
+ export {
63
+ tt as default
64
+ };
65
+ //# sourceMappingURL=CountedInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CountedInput.js","sources":["../../../src/components/countedInput/CountedInput.tsx"],"sourcesContent":["import React, { forwardRef, useState, type ForwardedRef } from 'react';\nimport { isNil } from 'es-toolkit/predicate';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\nimport ClearableInput, { type ClearableInputProps } from '../clearableInput/ClearableInput';\n\nexport type CountedInputProps = Omit<\n ClearableInputProps,\n 'children' | 'max' | 'min' | 'onChange' | 'showClearButton'\n> & {\n /**\n * Defines the minimum amount of characters required for a valid value.\n * If set, the counter counts up to this value because this is the threshold for success.\n * If no `maxLength` is set, this value is also used as the maximum amount of characters that can be entered.\n * Set at least one of `minLength` or `maxLength`.\n *\n * @default 0\n */\n minLength?: number;\n\n /**\n * Defines the maximum amount of characters that can be entered.\n * If no `minLength` is set, the counter counts up to this value.\n * Set at least one of `minLength` or `maxLength`.\n */\n maxLength?: number;\n\n /**\n * Controls whether the clear button is rendered.\n *\n * @default false\n */\n clearable?: boolean;\n\n /**\n * Controls whether success or warning feedback styling is rendered. If omitted, feedback is shown after user\n * interaction or when the input has a value.\n */\n showValidationState?: boolean;\n\n /**\n * Controls whether an initially empty input is validated before user interaction.\n *\n * @default false\n */\n validateInitialEmpty?: boolean;\n\n /**\n * Defines the invalid feedback style used while the character criteria are not met.\n *\n * @default 'warning'\n */\n validationState?: 'warning' | 'error';\n\n /**\n * Callback function for when the value changes. Receives the new value and validity as arguments.\n */\n onChange?: (\n newValue: string,\n isValid: boolean,\n event: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLSpanElement>\n ) => void;\n};\n\nconst getIsValid = (value: string, minLength: number, maxLength: number) => {\n const length = value.length;\n return length >= minLength && length <= maxLength;\n};\n\nconst CountedInput = forwardRef((props: CountedInputProps, ref: ForwardedRef<HTMLInputElement>) => {\n const {\n defaultValue,\n value,\n minLength = 0,\n maxLength,\n clearable = false,\n showValidationState,\n validateInitialEmpty = false,\n validationState = 'warning',\n className = '',\n onChange = noop,\n onBlur = noop,\n ...remainingProps\n } = props;\n\n const effectiveMaxLength = maxLength ?? minLength ?? 0;\n const effectiveMinLength = minLength ?? 0;\n const initialValue = value || defaultValue || '';\n\n const [inputValue, setInputValue] = useState(initialValue);\n const [isTouched, setTouched] = useState(false);\n\n const isControlled = !isNil(value);\n const currentValue = isControlled ? value || '' : inputValue;\n\n const isValid = getIsValid(currentValue, effectiveMinLength, effectiveMaxLength);\n\n const shouldShowValidationState =\n showValidationState ?? (validateInitialEmpty || currentValue.length > 0 || isTouched);\n\n const invalidClassName = validationState === 'error' ? 'has-error' : 'has-warning';\n const invalidTextColor = validationState === 'error' ? 'text-color-danger' : 'text-color-warning';\n\n const showSuccessIcon = shouldShowValidationState && isValid;\n const counterTargetLength = effectiveMinLength > 0 ? effectiveMinLength : effectiveMaxLength;\n const counter = `${Math.min(currentValue.length, counterTargetLength)}/${counterTargetLength}`;\n\n const handleChange: ClearableInputProps['onChange'] = (newValue, event) => {\n const nextIsValid = getIsValid(newValue, effectiveMinLength, effectiveMaxLength);\n\n setTouched(true);\n\n if (!isControlled) {\n setInputValue(newValue);\n }\n\n onChange(newValue, nextIsValid, event);\n };\n\n const handleBlur: ClearableInputProps['onBlur'] = event => {\n setTouched(true);\n onBlur(event);\n };\n\n const classes = classNames(\n 'form-group',\n 'CountedInput',\n shouldShowValidationState && 'has-feedback',\n shouldShowValidationState && (isValid ? 'has-success' : invalidClassName),\n className\n );\n\n const counterClassNames = classNames(\n 'input-group-addon',\n 'CountedInputCounter text-bold',\n shouldShowValidationState && (isValid ? 'text-color-success' : invalidTextColor)\n );\n\n const counterValueClassNames = classNames('CountedInputCounterValue text-italic', showSuccessIcon && 'is-hidden');\n const successIconClassNames = classNames(\n 'CountedInputSuccessIcon rioglyph rioglyph-ok text-color-success',\n showSuccessIcon && 'is-visible'\n );\n\n return (\n <div className={classes}>\n <div className='input-group'>\n <ClearableInput\n {...remainingProps}\n ref={ref}\n value={currentValue}\n maxLength={effectiveMaxLength}\n showClearButton={clearable}\n onChange={handleChange}\n onBlur={handleBlur}\n />\n <span className={counterClassNames}>\n <span className={counterValueClassNames}>{counter}</span>\n <span className={successIconClassNames} aria-hidden />\n </span>\n </div>\n </div>\n );\n});\n\nexport default CountedInput;\n"],"names":["getIsValid","value","minLength","maxLength","length","CountedInput","forwardRef","props","ref","defaultValue","clearable","showValidationState","validateInitialEmpty","validationState","className","onChange","noop","onBlur","remainingProps","effectiveMaxLength","effectiveMinLength","initialValue","inputValue","setInputValue","useState","isTouched","setTouched","isControlled","isNil","currentValue","isValid","shouldShowValidationState","invalidClassName","invalidTextColor","showSuccessIcon","counterTargetLength","counter","handleChange","newValue","event","nextIsValid","handleBlur","classes","classNames","counterClassNames","counterValueClassNames","successIconClassNames","jsxs","jsx","ClearableInput"],"mappings":";;;;;;AAiEA,MAAMA,IAAa,CAACC,GAAeC,GAAmBC,MAAsB;AACxE,QAAMC,IAASH,EAAM;AACrB,SAAOG,KAAUF,KAAaE,KAAUD;AAC5C,GAEME,KAAeC,EAAW,CAACC,GAA0BC,MAAwC;AAC/F,QAAM;AAAA,IACF,cAAAC;AAAA,IACA,OAAAR;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,WAAAC;AAAA,IACA,WAAAO,IAAY;AAAA,IACZ,qBAAAC;AAAA,IACA,sBAAAC,IAAuB;AAAA,IACvB,iBAAAC,IAAkB;AAAA,IAClB,WAAAC,IAAY;AAAA,IACZ,UAAAC,IAAWC;AAAA,IACX,QAAAC,IAASD;AAAA,IACT,GAAGE;AAAA,EAAA,IACHX,GAEEY,IAAqBhB,KAAaD,KAAa,GAC/CkB,IAAqBlB,KAAa,GAClCmB,IAAepB,KAASQ,KAAgB,IAExC,CAACa,GAAYC,CAAa,IAAIC,EAASH,CAAY,GACnD,CAACI,GAAWC,CAAU,IAAIF,EAAS,EAAK,GAExCG,IAAe,CAACC,EAAM3B,CAAK,GAC3B4B,IAAeF,IAAe1B,KAAS,KAAKqB,GAE5CQ,IAAU9B,EAAW6B,GAAcT,GAAoBD,CAAkB,GAEzEY,IACFpB,MAAwBC,KAAwBiB,EAAa,SAAS,KAAKJ,IAEzEO,IAAmBnB,MAAoB,UAAU,cAAc,eAC/DoB,IAAmBpB,MAAoB,UAAU,sBAAsB,sBAEvEqB,IAAkBH,KAA6BD,GAC/CK,IAAsBf,IAAqB,IAAIA,IAAqBD,GACpEiB,IAAU,GAAG,KAAK,IAAIP,EAAa,QAAQM,CAAmB,CAAC,IAAIA,CAAmB,IAEtFE,IAAgD,CAACC,GAAUC,MAAU;AACvE,UAAMC,IAAcxC,EAAWsC,GAAUlB,GAAoBD,CAAkB;AAE/E,IAAAO,EAAW,EAAI,GAEVC,KACDJ,EAAce,CAAQ,GAG1BvB,EAASuB,GAAUE,GAAaD,CAAK;AAAA,EACzC,GAEME,IAA4C,CAAAF,MAAS;AACvD,IAAAb,EAAW,EAAI,GACfT,EAAOsB,CAAK;AAAA,EAChB,GAEMG,IAAUC;AAAA,IACZ;AAAA,IACA;AAAA,IACAZ,KAA6B;AAAA,IAC7BA,MAA8BD,IAAU,gBAAgBE;AAAA,IACxDlB;AAAA,EAAA,GAGE8B,IAAoBD;AAAA,IACtB;AAAA,IACA;AAAA,IACAZ,MAA8BD,IAAU,uBAAuBG;AAAA,EAAA,GAG7DY,IAAyBF,EAAW,wCAAwCT,KAAmB,WAAW,GAC1GY,IAAwBH;AAAA,IAC1B;AAAA,IACAT,KAAmB;AAAA,EAAA;AAGvB,2BACK,OAAA,EAAI,WAAWQ,GACZ,UAAA,gBAAAK,EAAC,OAAA,EAAI,WAAU,eACX,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACI,GAAG/B;AAAA,QACJ,KAAAV;AAAA,QACA,OAAOqB;AAAA,QACP,WAAWV;AAAA,QACX,iBAAiBT;AAAA,QACjB,UAAU2B;AAAA,QACV,QAAQI;AAAA,MAAA;AAAA,IAAA;AAAA,IAEZ,gBAAAM,EAAC,QAAA,EAAK,WAAWH,GACb,UAAA;AAAA,MAAA,gBAAAI,EAAC,QAAA,EAAK,WAAWH,GAAyB,UAAAT,GAAQ;AAAA,MAClD,gBAAAY,EAAC,QAAA,EAAK,WAAWF,GAAuB,eAAW,GAAA,CAAC;AAAA,IAAA,EAAA,CACxD;AAAA,EAAA,EAAA,CACJ,EAAA,CACJ;AAER,CAAC;"}
@@ -1,6 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Moment } from 'moment';
3
- import { default as DatetimeImport, DatetimepickerProps } from 'react-datetime';
3
+ import { default as DatetimeImport, DatetimepickerProps } from '@rio-cloud/react-datetime';
4
4
  export type DatePickerProps = Omit<DatetimepickerProps, 'onChange' | 'initialValue'> & {
5
5
  /**
6
6
  * An id used for the internal input element.
@@ -1,6 +1,6 @@
1
1
  import { jsx as C } from "react/jsx-runtime";
2
2
  import { forwardRef as L, useState as N } from "react";
3
- import o from "react-datetime";
3
+ import o from "@rio-cloud/react-datetime";
4
4
  import { noop as O } from "es-toolkit/function";
5
5
  import _ from "../../utils/classNames.js";
6
6
  const A = o?.default ? o.default : o, k = "en-GB", x = 0, U = L((s, y) => {
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","sources":["../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState, forwardRef } from 'react';\nimport type { Moment } from 'moment';\nimport DatetimeImport, { type DatetimepickerProps } from 'react-datetime';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\n\n// Fix: Handle ESM/CJS interop by unwrapping default if necessary\n// @ts-expect-error\nconst Datetime = DatetimeImport?.default ? DatetimeImport.default : DatetimeImport;\n\nconst DEFAULT_LOCALE = 'en-GB';\nconst DEFAULT_MIN_WIDTH = 0;\n\nexport type DatePickerProps = Omit<DatetimepickerProps, 'onChange' | 'initialValue'> & {\n /**\n * An id used for the internal input element.\n */\n id?: string;\n\n /**\n * The moment locale to be used for the date picker.\n * Make sure to import the respective moment locale files.\n *\n * @default 'en-GB'\n * @example import 'moment/dist/locale/de';\n */\n locale?: string;\n\n /**\n * Once the day has been selected, the date picker will be closed automatically.\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * Default value of the DatePicker (date or moment).\n */\n initialValue?: Date | Moment;\n\n /**\n * Value of the DatePicker (date or moment). Use this only if you want to use\n * this component as a controlled component\n */\n value?: Date | string | Moment;\n\n /*\n * Defines the format for the date. It accepts any moment.js date format.\n * If true the date will be displayed using the defaults for the current locale.\n * If false the date picker is disabled and the component can be used as time picker.\n */\n dateFormat?: boolean | string;\n\n /*\n * Defines the format for the time. It accepts any moment.js time format.\n * If true the time will be displayed using the defaults for the current locale.\n * If false the time picker is disabled and the component can be used as date picker.\n */\n timeFormat?: boolean | string;\n\n /*\n * Defines additional attributes for the input element of the component.\n */\n inputProps?: React.HTMLProps<HTMLInputElement>;\n\n /**\n * Defines whether the dropdown opens upwards or not.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Opens the picker right aligned.\n *\n * @default false\n */\n\n alignRight?: boolean;\n\n /**\n * Defines whether the clearableInput button is shown.\n *\n * @default false\n */\n clearableInput?: boolean;\n\n /**\n * Optional min-width value (without px). Since the DatePicker has a max-width of 100%\n * you can also set a high minWidth number to use 100% with of the parent element.\n * A value of \"0\" means no extra width is set and it becomes 100% width of the parent.\n *\n * @default 0\n */\n minWidth?: number;\n\n /**\n * Callback function when the value changes. Receives the new date (moment)\n * and a boolean (whether date is valid or not) as arguments.\n *\n * @param value\n * @param isValid\n * @returns\n */\n onChange?: (value: Moment | string, isValid: boolean) => void;\n\n /**\n * Defines whether the input shows an error when the date is invalid or cleared.\n *\n * @default true\n */\n mandatory?: boolean;\n\n /**\n * Overwrites the internal date validation function in case you need to customize it.\n *\n * @param date\n * @returns\n */\n dateValidation?: (date: Moment | string) => boolean;\n\n /**\n * Additional classes to be set on the DatePicker element.\n */\n className?: string;\n};\n\nconst DatePicker = forwardRef((props: DatePickerProps, _ref) => {\n const {\n id,\n dropup = false,\n alignRight = false,\n locale = DEFAULT_LOCALE,\n minWidth = DEFAULT_MIN_WIDTH,\n onChange = noop,\n mandatory = true,\n dateValidation,\n clearableInput = false,\n closeOnSelect = true,\n inputProps,\n className,\n ...remainingProp\n } = props;\n\n const [hasError, setHasError] = useState(false);\n\n const validateDate = (dateToValidate: Moment | string) => {\n // If the entered date complies with the defined dateFormat, the Datetime component\n // returns a moment object, otherwise the return value is a string.\n // Note, using a isValid() function from moment or the Date object itself will result in\n // different outcome in various browsers.\n // For instance `new Date('1')` or `moment('1')` are valid dates in Chrome where it defaults\n // to \"01/01/2001\" whereas in Firefox it is an invalid date.\n // The solution is to compare the entered value to the date format which is done by React Datetime.\n const isDateObject = typeof dateToValidate === 'object';\n\n return dateValidation ? dateValidation(dateToValidate) : isDateObject;\n };\n\n const handleChange = (date: Moment | string) => {\n const isValid = mandatory ? validateDate(date) : true;\n setHasError(!isValid);\n onChange(date, isValid);\n };\n\n const classes = classNames(\n 'DatePicker',\n 'form-group',\n hasError && 'has-error',\n dropup && 'dropup',\n alignRight && 'align-right',\n className && className\n );\n\n // This way we can expose the \"id\" as top level prop and not as part of the inputProps which\n // makes the use of the id much more convenient\n const enhancedInputProps = { id, ...inputProps };\n\n return (\n <Datetime\n // TODO: add support for setting ref to the input. Maybe add a \"inputRef\" prop to react-datetime\n // ref={ref}\n {...remainingProp}\n locale={locale}\n clearableInput={clearableInput}\n closeOnSelect={closeOnSelect}\n onChange={handleChange}\n minWidth={minWidth}\n inputProps={enhancedInputProps}\n className={classes}\n />\n );\n});\n\nexport default DatePicker;\n"],"names":["Datetime","DatetimeImport","DEFAULT_LOCALE","DEFAULT_MIN_WIDTH","DatePicker","forwardRef","props","_ref","id","dropup","alignRight","locale","minWidth","onChange","noop","mandatory","dateValidation","clearableInput","closeOnSelect","inputProps","className","remainingProp","hasError","setHasError","useState","validateDate","dateToValidate","handleChange","date","isValid","classes","classNames","enhancedInputProps","jsx"],"mappings":";;;;;AAUA,MAAMA,IAAWC,GAAgB,UAAUA,EAAe,UAAUA,GAE9DC,IAAiB,SACjBC,IAAoB,GAoHpBC,IAAaC,EAAW,CAACC,GAAwBC,MAAS;AAC5D,QAAM;AAAA,IACF,IAAAC;AAAA,IACA,QAAAC,IAAS;AAAA,IACT,YAAAC,IAAa;AAAA,IACb,QAAAC,IAAST;AAAA,IACT,UAAAU,IAAWT;AAAA,IACX,UAAAU,IAAWC;AAAA,IACX,WAAAC,IAAY;AAAA,IACZ,gBAAAC;AAAA,IACA,gBAAAC,IAAiB;AAAA,IACjB,eAAAC,IAAgB;AAAA,IAChB,YAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHf,GAEE,CAACgB,GAAUC,CAAW,IAAIC,EAAS,EAAK,GAExCC,IAAe,CAACC,MAUXV,IAAiBA,EAAeU,CAAc,IAFhC,OAAOA,KAAmB,UAK7CC,IAAe,CAACC,MAA0B;AAC5C,UAAMC,IAAUd,IAAYU,EAAaG,CAAI,IAAI;AACjD,IAAAL,EAAY,CAACM,CAAO,GACpBhB,EAASe,GAAMC,CAAO;AAAA,EAC1B,GAEMC,IAAUC;AAAA,IACZ;AAAA,IACA;AAAA,IACAT,KAAY;AAAA,IACZb,KAAU;AAAA,IACVC,KAAc;AAAA,IACdU,KAAaA;AAAA,EAAA,GAKXY,IAAqB,EAAE,IAAAxB,GAAI,GAAGW,EAAA;AAEpC,SACI,gBAAAc;AAAA,IAACjC;AAAA,IAAA;AAAA,MAGI,GAAGqB;AAAA,MACJ,QAAAV;AAAA,MACA,gBAAAM;AAAA,MACA,eAAAC;AAAA,MACA,UAAUS;AAAA,MACV,UAAAf;AAAA,MACA,YAAYoB;AAAA,MACZ,WAAWF;AAAA,IAAA;AAAA,EAAA;AAGvB,CAAC;"}
1
+ {"version":3,"file":"DatePicker.js","sources":["../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState, forwardRef } from 'react';\nimport type { Moment } from 'moment';\nimport DatetimeImport, { type DatetimepickerProps } from '@rio-cloud/react-datetime';\nimport { noop } from 'es-toolkit/function';\n\nimport classNames from '../../utils/classNames';\n\n// Fix: Handle ESM/CJS interop by unwrapping default if necessary\n// @ts-expect-error\nconst Datetime = DatetimeImport?.default ? DatetimeImport.default : DatetimeImport;\n\nconst DEFAULT_LOCALE = 'en-GB';\nconst DEFAULT_MIN_WIDTH = 0;\n\nexport type DatePickerProps = Omit<DatetimepickerProps, 'onChange' | 'initialValue'> & {\n /**\n * An id used for the internal input element.\n */\n id?: string;\n\n /**\n * The moment locale to be used for the date picker.\n * Make sure to import the respective moment locale files.\n *\n * @default 'en-GB'\n * @example import 'moment/dist/locale/de';\n */\n locale?: string;\n\n /**\n * Once the day has been selected, the date picker will be closed automatically.\n *\n * @default true\n */\n closeOnSelect?: boolean;\n\n /**\n * Default value of the DatePicker (date or moment).\n */\n initialValue?: Date | Moment;\n\n /**\n * Value of the DatePicker (date or moment). Use this only if you want to use\n * this component as a controlled component\n */\n value?: Date | string | Moment;\n\n /*\n * Defines the format for the date. It accepts any moment.js date format.\n * If true the date will be displayed using the defaults for the current locale.\n * If false the date picker is disabled and the component can be used as time picker.\n */\n dateFormat?: boolean | string;\n\n /*\n * Defines the format for the time. It accepts any moment.js time format.\n * If true the time will be displayed using the defaults for the current locale.\n * If false the time picker is disabled and the component can be used as date picker.\n */\n timeFormat?: boolean | string;\n\n /*\n * Defines additional attributes for the input element of the component.\n */\n inputProps?: React.HTMLProps<HTMLInputElement>;\n\n /**\n * Defines whether the dropdown opens upwards or not.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Opens the picker right aligned.\n *\n * @default false\n */\n\n alignRight?: boolean;\n\n /**\n * Defines whether the clearableInput button is shown.\n *\n * @default false\n */\n clearableInput?: boolean;\n\n /**\n * Optional min-width value (without px). Since the DatePicker has a max-width of 100%\n * you can also set a high minWidth number to use 100% with of the parent element.\n * A value of \"0\" means no extra width is set and it becomes 100% width of the parent.\n *\n * @default 0\n */\n minWidth?: number;\n\n /**\n * Callback function when the value changes. Receives the new date (moment)\n * and a boolean (whether date is valid or not) as arguments.\n *\n * @param value\n * @param isValid\n * @returns\n */\n onChange?: (value: Moment | string, isValid: boolean) => void;\n\n /**\n * Defines whether the input shows an error when the date is invalid or cleared.\n *\n * @default true\n */\n mandatory?: boolean;\n\n /**\n * Overwrites the internal date validation function in case you need to customize it.\n *\n * @param date\n * @returns\n */\n dateValidation?: (date: Moment | string) => boolean;\n\n /**\n * Additional classes to be set on the DatePicker element.\n */\n className?: string;\n};\n\nconst DatePicker = forwardRef((props: DatePickerProps, _ref) => {\n const {\n id,\n dropup = false,\n alignRight = false,\n locale = DEFAULT_LOCALE,\n minWidth = DEFAULT_MIN_WIDTH,\n onChange = noop,\n mandatory = true,\n dateValidation,\n clearableInput = false,\n closeOnSelect = true,\n inputProps,\n className,\n ...remainingProp\n } = props;\n\n const [hasError, setHasError] = useState(false);\n\n const validateDate = (dateToValidate: Moment | string) => {\n // If the entered date complies with the defined dateFormat, the Datetime component\n // returns a moment object, otherwise the return value is a string.\n // Note, using a isValid() function from moment or the Date object itself will result in\n // different outcome in various browsers.\n // For instance `new Date('1')` or `moment('1')` are valid dates in Chrome where it defaults\n // to \"01/01/2001\" whereas in Firefox it is an invalid date.\n // The solution is to compare the entered value to the date format which is done by React Datetime.\n const isDateObject = typeof dateToValidate === 'object';\n\n return dateValidation ? dateValidation(dateToValidate) : isDateObject;\n };\n\n const handleChange = (date: Moment | string) => {\n const isValid = mandatory ? validateDate(date) : true;\n setHasError(!isValid);\n onChange(date, isValid);\n };\n\n const classes = classNames(\n 'DatePicker',\n 'form-group',\n hasError && 'has-error',\n dropup && 'dropup',\n alignRight && 'align-right',\n className && className\n );\n\n // This way we can expose the \"id\" as top level prop and not as part of the inputProps which\n // makes the use of the id much more convenient\n const enhancedInputProps = { id, ...inputProps };\n\n return (\n <Datetime\n // TODO: add support for setting ref to the input. Maybe add a \"inputRef\" prop to react-datetime\n // ref={ref}\n {...remainingProp}\n locale={locale}\n clearableInput={clearableInput}\n closeOnSelect={closeOnSelect}\n onChange={handleChange}\n minWidth={minWidth}\n inputProps={enhancedInputProps}\n className={classes}\n />\n );\n});\n\nexport default DatePicker;\n"],"names":["Datetime","DatetimeImport","DEFAULT_LOCALE","DEFAULT_MIN_WIDTH","DatePicker","forwardRef","props","_ref","id","dropup","alignRight","locale","minWidth","onChange","noop","mandatory","dateValidation","clearableInput","closeOnSelect","inputProps","className","remainingProp","hasError","setHasError","useState","validateDate","dateToValidate","handleChange","date","isValid","classes","classNames","enhancedInputProps","jsx"],"mappings":";;;;;AAUA,MAAMA,IAAWC,GAAgB,UAAUA,EAAe,UAAUA,GAE9DC,IAAiB,SACjBC,IAAoB,GAoHpBC,IAAaC,EAAW,CAACC,GAAwBC,MAAS;AAC5D,QAAM;AAAA,IACF,IAAAC;AAAA,IACA,QAAAC,IAAS;AAAA,IACT,YAAAC,IAAa;AAAA,IACb,QAAAC,IAAST;AAAA,IACT,UAAAU,IAAWT;AAAA,IACX,UAAAU,IAAWC;AAAA,IACX,WAAAC,IAAY;AAAA,IACZ,gBAAAC;AAAA,IACA,gBAAAC,IAAiB;AAAA,IACjB,eAAAC,IAAgB;AAAA,IAChB,YAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHf,GAEE,CAACgB,GAAUC,CAAW,IAAIC,EAAS,EAAK,GAExCC,IAAe,CAACC,MAUXV,IAAiBA,EAAeU,CAAc,IAFhC,OAAOA,KAAmB,UAK7CC,IAAe,CAACC,MAA0B;AAC5C,UAAMC,IAAUd,IAAYU,EAAaG,CAAI,IAAI;AACjD,IAAAL,EAAY,CAACM,CAAO,GACpBhB,EAASe,GAAMC,CAAO;AAAA,EAC1B,GAEMC,IAAUC;AAAA,IACZ;AAAA,IACA;AAAA,IACAT,KAAY;AAAA,IACZb,KAAU;AAAA,IACVC,KAAc;AAAA,IACdU,KAAaA;AAAA,EAAA,GAKXY,IAAqB,EAAE,IAAAxB,GAAI,GAAGW,EAAA;AAEpC,SACI,gBAAAc;AAAA,IAACjC;AAAA,IAAA;AAAA,MAGI,GAAGqB;AAAA,MACJ,QAAAV;AAAA,MACA,gBAAAM;AAAA,MACA,eAAAC;AAAA,MACA,UAAUS;AAAA,MACV,UAAAf;AAAA,MACA,YAAYoB;AAAA,MACZ,WAAWF;AAAA,IAAA;AAAA,EAAA;AAGvB,CAAC;"}