@wallarm-org/design-system 0.28.0-rc-feature-WDS-96-update-data-input-component.5 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/components/DateInput/DateInput.js +2 -5
  2. package/dist/components/DateInput/DateInputInternal.js +4 -6
  3. package/dist/components/DateInput/types.d.ts +0 -3
  4. package/dist/components/DateRangeInput/DateRangeContext/DateRangeProvider.js +17 -9
  5. package/dist/components/DateRangeInput/DateRangeContext/types.d.ts +0 -2
  6. package/dist/components/DateRangeInput/DateRangeGroup.js +1 -1
  7. package/dist/components/DateRangeInput/DateRangeInputInternal.js +15 -33
  8. package/dist/components/DateRangeInput/DateRangeSegment.js +1 -6
  9. package/dist/components/DateRangeInput/DateRangeSegmentGroup.js +12 -4
  10. package/dist/components/DateRangeInput/DateRangeSeparator.d.ts +1 -2
  11. package/dist/components/DateRangeInput/DateRangeSeparator.js +5 -2
  12. package/dist/components/DateRangeInput/types.d.ts +0 -3
  13. package/dist/components/FilterInput/FilterInput.d.ts +14 -0
  14. package/dist/components/FilterInput/FilterInput.js +5 -1
  15. package/dist/components/FilterInput/index.d.ts +1 -1
  16. package/dist/components/FilterInput/index.js +2 -2
  17. package/dist/components/FilterInput/lib/applyFieldValueTransforms.d.ts +11 -0
  18. package/dist/components/FilterInput/lib/applyFieldValueTransforms.js +43 -0
  19. package/dist/components/FilterInput/lib/applyKnownFieldHelpers.d.ts +21 -0
  20. package/dist/components/FilterInput/lib/applyKnownFieldHelpers.js +29 -0
  21. package/dist/components/FilterInput/lib/index.d.ts +3 -1
  22. package/dist/components/FilterInput/lib/index.js +4 -2
  23. package/dist/components/FilterInput/lib/serializeExpression.d.ts +12 -2
  24. package/dist/components/FilterInput/lib/serializeExpression.js +5 -2
  25. package/dist/components/FilterInput/lib/statusCode/createStatusCodeSerializer.d.ts +16 -0
  26. package/dist/components/FilterInput/lib/statusCode/createStatusCodeSerializer.js +6 -0
  27. package/dist/components/FilterInput/lib/statusCode/createStatusCodeSuggestions.d.ts +5 -4
  28. package/dist/components/FilterInput/lib/statusCode/createStatusCodeSuggestions.js +5 -6
  29. package/dist/components/FilterInput/lib/statusCode/createStatusCodeValidator.d.ts +1 -8
  30. package/dist/components/FilterInput/lib/statusCode/createStatusCodeValidator.js +3 -3
  31. package/dist/components/FilterInput/lib/statusCode/index.d.ts +1 -1
  32. package/dist/components/FilterInput/lib/statusCode/index.js +2 -1
  33. package/dist/components/FilterInput/lib/statusCode/utils/canonicalize.d.ts +2 -2
  34. package/dist/components/FilterInput/lib/statusCode/utils/canonicalize.js +3 -3
  35. package/dist/components/FilterInput/lib/statusCode/utils/constants.d.ts +7 -3
  36. package/dist/components/FilterInput/lib/statusCode/utils/constants.js +3 -3
  37. package/dist/components/FilterInput/lib/statusCode/utils/index.d.ts +1 -3
  38. package/dist/components/FilterInput/lib/statusCode/utils/index.js +2 -3
  39. package/dist/components/FilterInput/types.d.ts +9 -0
  40. package/dist/components/InputGroup/InputGroup.d.ts +1 -6
  41. package/dist/components/InputGroup/InputGroup.js +3 -19
  42. package/dist/components/InputGroup/index.d.ts +1 -1
  43. package/dist/components/SimpleCharts/BarList/BarList.d.ts +16 -0
  44. package/dist/components/SimpleCharts/BarList/BarList.figma.d.ts +1 -0
  45. package/dist/components/SimpleCharts/BarList/BarList.figma.js +74 -0
  46. package/dist/components/SimpleCharts/BarList/BarList.js +38 -0
  47. package/dist/components/SimpleCharts/BarList/BarListBar.d.ts +14 -0
  48. package/dist/components/SimpleCharts/BarList/BarListBar.js +29 -0
  49. package/dist/components/SimpleCharts/BarList/BarListContext.d.ts +12 -0
  50. package/dist/components/SimpleCharts/BarList/BarListContext.js +4 -0
  51. package/dist/components/SimpleCharts/BarList/BarListItem.d.ts +12 -0
  52. package/dist/components/SimpleCharts/BarList/BarListItem.js +66 -0
  53. package/dist/components/SimpleCharts/BarList/BarListLabel.d.ts +5 -0
  54. package/dist/components/SimpleCharts/BarList/BarListLabel.js +16 -0
  55. package/dist/components/SimpleCharts/BarList/BarListPercent.d.ts +7 -0
  56. package/dist/components/SimpleCharts/BarList/BarListPercent.js +21 -0
  57. package/dist/components/SimpleCharts/BarList/BarListSkeleton.d.ts +8 -0
  58. package/dist/components/SimpleCharts/BarList/BarListSkeleton.js +36 -0
  59. package/dist/components/SimpleCharts/BarList/BarListValue.d.ts +5 -0
  60. package/dist/components/SimpleCharts/BarList/BarListValue.js +16 -0
  61. package/dist/components/SimpleCharts/BarList/classes.d.ts +25 -0
  62. package/dist/components/SimpleCharts/BarList/classes.js +44 -0
  63. package/dist/components/SimpleCharts/BarList/index.d.ts +7 -0
  64. package/dist/components/SimpleCharts/BarList/index.js +8 -0
  65. package/dist/components/SimpleCharts/Chart/Chart.d.ts +6 -0
  66. package/dist/components/SimpleCharts/Chart/Chart.figma.d.ts +1 -0
  67. package/dist/components/SimpleCharts/Chart/Chart.figma.js +41 -0
  68. package/dist/components/SimpleCharts/Chart/Chart.js +17 -0
  69. package/dist/components/SimpleCharts/Chart/ChartActions.d.ts +10 -0
  70. package/dist/components/SimpleCharts/Chart/ChartActions.js +18 -0
  71. package/dist/components/SimpleCharts/Chart/ChartEmpty.d.ts +5 -0
  72. package/dist/components/SimpleCharts/Chart/ChartEmpty.js +22 -0
  73. package/dist/components/SimpleCharts/Chart/ChartHeader.d.ts +5 -0
  74. package/dist/components/SimpleCharts/Chart/ChartHeader.js +16 -0
  75. package/dist/components/SimpleCharts/Chart/ChartTitle.d.ts +5 -0
  76. package/dist/components/SimpleCharts/Chart/ChartTitle.js +22 -0
  77. package/dist/components/SimpleCharts/Chart/classes.d.ts +6 -0
  78. package/dist/components/SimpleCharts/Chart/classes.js +16 -0
  79. package/dist/components/SimpleCharts/Chart/index.d.ts +5 -0
  80. package/dist/components/SimpleCharts/Chart/index.js +6 -0
  81. package/dist/components/SimpleCharts/index.d.ts +2 -0
  82. package/dist/components/SimpleCharts/index.js +3 -0
  83. package/dist/components/SimpleCharts/types.d.ts +9 -0
  84. package/dist/components/TemporalCore/TemporalClear.js +0 -1
  85. package/dist/components/TemporalCore/TemporalSegment.js +2 -7
  86. package/dist/components/TemporalCore/TimeDropdown.js +1 -1
  87. package/dist/components/TemporalCore/index.d.ts +0 -1
  88. package/dist/components/TemporalCore/index.js +1 -2
  89. package/dist/components/TemporalCore/utils.d.ts +0 -8
  90. package/dist/components/TemporalCore/utils.js +1 -6
  91. package/dist/components/TimeInput/TimeInput.js +3 -7
  92. package/dist/metadata/components.json +3569 -282
  93. package/package.json +1 -1
  94. package/dist/components/FilterInput/lib/statusCode/utils/maskRoots.d.ts +0 -4
  95. package/dist/components/FilterInput/lib/statusCode/utils/maskRoots.js +0 -3
  96. package/dist/components/FilterInput/lib/statusCode/utils/types.d.ts +0 -8
  97. package/dist/components/FilterInput/stories/mockStatusCodes.d.ts +0 -6
  98. package/dist/components/FilterInput/stories/mockStatusCodes.js +0 -20
  99. /package/dist/components/{FilterInput/lib/statusCode/utils → SimpleCharts}/types.js +0 -0
@@ -5,11 +5,9 @@ import { useDateField } from "@react-aria/datepicker";
5
5
  import { useLocale } from "@react-aria/i18n";
6
6
  import { useDateFieldState } from "@react-stately/datepicker";
7
7
  import { cn } from "../../utils/cn.js";
8
- import { getDefaultTemporalPlaceholder, useTemporalField } from "../TemporalCore/index.js";
8
+ import { useTemporalField } from "../TemporalCore/index.js";
9
9
  import { DateInputInternal } from "./DateInputInternal.js";
10
- const DateInput = /*#__PURE__*/ forwardRef(({ icon, value: controlledValue, defaultValue, onChange, error = false, disabled = false, granularity = 'day', placeholder = getDefaultTemporalPlaceholder({
11
- granularity
12
- }), showTimeDropdown, timeStep, hourCycle, size, className, ...props }, forwardedRef)=>{
10
+ const DateInput = /*#__PURE__*/ forwardRef(({ icon, value: controlledValue, defaultValue, onChange, error = false, disabled = false, granularity = 'day', placeholder, showTimeDropdown, timeStep, hourCycle, className, ...props }, forwardedRef)=>{
13
11
  const { locale } = useLocale();
14
12
  const ref = useRef(null);
15
13
  const finalRef = forwardedRef || ref;
@@ -48,7 +46,6 @@ const DateInput = /*#__PURE__*/ forwardRef(({ icon, value: controlledValue, defa
48
46
  showTimeDropdown: showTimeDropdown,
49
47
  timeStep: timeStep,
50
48
  hourCycle: hourCycle,
51
- size: size,
52
49
  className: cn('w-full')
53
50
  })
54
51
  });
@@ -4,7 +4,7 @@ import { CalendarDateTime, getLocalTimeZone, now } from "@internationalized/date
4
4
  import { cn } from "../../utils/cn.js";
5
5
  import { InputGroup, InputGroupAddon } from "../InputGroup/index.js";
6
6
  import { TemporalClear, TemporalPlaceholder, TemporalSegmentGroup, TimeDropdown, useTimeDropdownKeyCapture } from "../TemporalCore/index.js";
7
- const DateInputInternal = /*#__PURE__*/ forwardRef(({ state, icon: IconComponent, error, disabled, placeholder, showTimeDropdown, timeStep = 30, hourCycle, size = 'default', ...props }, ref)=>{
7
+ const DateInputInternal = /*#__PURE__*/ forwardRef(({ state, icon: IconComponent, error, disabled, placeholder, showTimeDropdown, timeStep = 30, hourCycle, ...props }, ref)=>{
8
8
  const dropdownRef = useRef(null);
9
9
  const [isFocused, setIsFocused] = useState(false);
10
10
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
@@ -53,24 +53,22 @@ const DateInputInternal = /*#__PURE__*/ forwardRef(({ state, icon: IconComponent
53
53
  });
54
54
  const currentTimeValue = state.value && hasTimeSegments ? state.value : null;
55
55
  return /*#__PURE__*/ jsxs(InputGroup, {
56
- size: size,
57
56
  children: [
58
57
  IconComponent && /*#__PURE__*/ jsx(InputGroupAddon, {
59
58
  children: /*#__PURE__*/ jsx(IconComponent, {})
60
59
  }),
61
60
  /*#__PURE__*/ jsxs("div", {
62
- className: cn('relative flex-1 h-full', !IconComponent && 'pl-12'),
61
+ className: cn('relative flex-1', !IconComponent && 'pl-12'),
63
62
  onKeyDownCapture: handleKeyDownCapture,
64
63
  children: [
65
64
  showPlaceholder && /*#__PURE__*/ jsx(TemporalPlaceholder, {
66
- text: placeholder,
67
- className: cn(!IconComponent && 'pl-12')
65
+ text: placeholder
68
66
  }),
69
67
  /*#__PURE__*/ jsx(TemporalSegmentGroup, {
70
68
  ...props,
71
69
  ref: ref,
72
70
  "data-slot": "input",
73
- className: cn('h-full', showPlaceholder && 'opacity-0'),
71
+ className: cn('h-36', showPlaceholder && 'opacity-0'),
74
72
  "aria-invalid": error || void 0,
75
73
  "aria-disabled": disabled || void 0,
76
74
  state: state,
@@ -1,6 +1,5 @@
1
1
  import type { FC } from 'react';
2
2
  import type { SvgIconProps } from '../../icons';
3
- import type { InputGroupSize } from '../InputGroup';
4
3
  export interface DateInputBaseProps {
5
4
  /** Optional icon component to display at the start of the input */
6
5
  icon?: FC<SvgIconProps>;
@@ -16,8 +15,6 @@ export interface DateInputBaseProps {
16
15
  timeStep?: number;
17
16
  /** Hour cycle for time display: 12-hour (AM/PM) or 24-hour format */
18
17
  hourCycle?: 12 | 24;
19
- /** Visual size of the input. Default: 'default' (36px) */
20
- size?: InputGroupSize;
21
18
  /**
22
19
  * className prop
23
20
  */
@@ -1,13 +1,11 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { forwardRef, useRef } from "react";
2
+ import { forwardRef, useCallback, useRef } from "react";
3
+ import { CalendarDate } from "@internationalized/date";
3
4
  import { useDateRangePicker } from "@react-aria/datepicker";
4
5
  import { useDateRangePickerState } from "@react-stately/datepicker";
5
- import { getDefaultTemporalPlaceholder, useTemporalField } from "../../TemporalCore/index.js";
6
+ import { useTemporalField } from "../../TemporalCore/index.js";
6
7
  import { DateRangeContext } from "./context.js";
7
- const DateRangeProvider = /*#__PURE__*/ forwardRef(({ children, value: controlledValue, defaultValue, onChange, error = false, disabled = false, readOnly = false, granularity = 'day', hourCycle, placeholder = getDefaultTemporalPlaceholder({
8
- granularity,
9
- isRange: true
10
- }), showTimeDropdown, timeStep, icon, size }, forwardedRef)=>{
8
+ const DateRangeProvider = /*#__PURE__*/ forwardRef(({ children, value: controlledValue, defaultValue, onChange, error = false, disabled = false, readOnly = false, granularity = 'day', hourCycle, placeholder, showTimeDropdown, timeStep, icon }, forwardedRef)=>{
11
9
  const ref = useRef(null);
12
10
  const finalRef = forwardedRef || ref;
13
11
  const startRef = useRef(null);
@@ -17,9 +15,20 @@ const DateRangeProvider = /*#__PURE__*/ forwardRef(({ children, value: controlle
17
15
  defaultValue,
18
16
  onChange
19
17
  });
18
+ const handleChangeWithValidation = useCallback((newValue)=>{
19
+ if (void 0 === newValue) return void handleChange(null);
20
+ if (newValue?.start && newValue?.end) {
21
+ const startDate = new CalendarDate(newValue.start.year, newValue.start.month, newValue.start.day);
22
+ const endDate = new CalendarDate(newValue.end.year, newValue.end.month, newValue.end.day);
23
+ if (endDate.compare(startDate) < 0) return;
24
+ }
25
+ handleChange(newValue);
26
+ }, [
27
+ handleChange
28
+ ]);
20
29
  const state = useDateRangePickerState({
21
30
  value,
22
- onChange: (newValue)=>handleChange(newValue ?? null),
31
+ onChange: handleChangeWithValidation,
23
32
  isDisabled: disabled,
24
33
  isReadOnly: readOnly,
25
34
  granularity,
@@ -51,8 +60,7 @@ const DateRangeProvider = /*#__PURE__*/ forwardRef(({ children, value: controlle
51
60
  showTimeDropdown,
52
61
  timeStep,
53
62
  hourCycle,
54
- icon,
55
- size
63
+ icon
56
64
  },
57
65
  children: children
58
66
  });
@@ -4,7 +4,6 @@ import type { DateRangePickerState } from '@react-stately/datepicker';
4
4
  import type { AriaDatePickerProps } from '@react-types/datepicker';
5
5
  import type { GroupDOMAttributes } from '@react-types/shared';
6
6
  import type { SvgIconProps } from '../../../icons';
7
- import type { InputGroupSize } from '../../InputGroup';
8
7
  export interface DateRangeContextValue {
9
8
  groupProps: GroupDOMAttributes;
10
9
  startFieldProps: AriaDatePickerProps<DateValue>;
@@ -22,5 +21,4 @@ export interface DateRangeContextValue {
22
21
  timeStep?: number;
23
22
  hourCycle?: 12 | 24;
24
23
  icon?: FC<SvgIconProps>;
25
- size?: InputGroupSize;
26
24
  }
@@ -2,7 +2,7 @@ import { jsx } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
3
  import { cn } from "../../utils/cn.js";
4
4
  import { useDateRangeContext } from "./DateRangeContext/index.js";
5
- const dateRangeGroupVariants = cva(cn('relative group/temporal flex-1 h-full flex items-center gap-4', 'focus-within:outline-none', 'data-disabled:opacity-50 data-disabled:cursor-not-allowed'));
5
+ const dateRangeGroupVariants = cva(cn('group/temporal flex-1 h-full flex items-center gap-4', 'focus-within:outline-none', 'data-disabled:opacity-50 data-disabled:cursor-not-allowed'));
6
6
  const DateRangeGroup = ({ children })=>{
7
7
  const context = useDateRangeContext();
8
8
  const { groupProps = {}, finalRef, disabled, error } = context ?? {};
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useState } from "react";
3
3
  import { cn } from "../../utils/cn.js";
4
4
  import { InputGroup, InputGroupAddon } from "../InputGroup/index.js";
5
- import { TemporalClear, TemporalPlaceholder } from "../TemporalCore/index.js";
5
+ import { TemporalClear } from "../TemporalCore/index.js";
6
6
  import { useDateRangeContext } from "./DateRangeContext/index.js";
7
7
  import { DateRangeGroup } from "./DateRangeGroup.js";
8
8
  import { DateRangeSegmentGroup } from "./DateRangeSegmentGroup.js";
@@ -11,7 +11,6 @@ const DateRangeInputInternal = ({ icon: IconComponent })=>{
11
11
  const context = useDateRangeContext();
12
12
  const [startHasValue, setStartHasValue] = useState(false);
13
13
  const [endHasValue, setEndHasValue] = useState(false);
14
- const [isFocused, setIsFocused] = useState(false);
15
14
  const [clearKey, setClearKey] = useState(0);
16
15
  const hasAnyValue = startHasValue || endHasValue;
17
16
  const handleClear = useCallback(()=>{
@@ -21,47 +20,30 @@ const DateRangeInputInternal = ({ icon: IconComponent })=>{
21
20
  }, [
22
21
  context
23
22
  ]);
24
- const handleFocusCapture = ()=>setIsFocused(true);
25
- const handleBlurCapture = (event)=>{
26
- if (!event.currentTarget.contains(event.relatedTarget)) setIsFocused(false);
27
- };
28
23
  if (!context) return null;
29
- const { startFieldProps, startRef, endFieldProps, endRef, disabled, placeholder, size } = context;
30
- const showPlaceholder = Boolean(placeholder && !hasAnyValue && !isFocused);
24
+ const { startFieldProps, startRef, endFieldProps, endRef, disabled } = context;
31
25
  return /*#__PURE__*/ jsx("div", {
32
26
  className: cn('**:data-[slot=input]:first:pr-0 **:data-[slot=input]:last:pl-0 min-w-284'),
33
- onFocusCapture: handleFocusCapture,
34
- onBlurCapture: handleBlurCapture,
35
27
  children: /*#__PURE__*/ jsxs(InputGroup, {
36
- size: size,
37
28
  children: [
38
29
  IconComponent && /*#__PURE__*/ jsx(InputGroupAddon, {
39
30
  children: /*#__PURE__*/ jsx(IconComponent, {})
40
31
  }),
41
32
  /*#__PURE__*/ jsxs(DateRangeGroup, {
42
33
  children: [
43
- showPlaceholder && placeholder && /*#__PURE__*/ jsx(TemporalPlaceholder, {
44
- text: placeholder,
45
- className: cn(!IconComponent && 'pl-12')
46
- }),
47
- /*#__PURE__*/ jsxs("div", {
48
- className: cn('contents', showPlaceholder && '[&>*]:opacity-0'),
49
- children: [
50
- /*#__PURE__*/ jsx(DateRangeSegmentGroup, {
51
- ...startFieldProps,
52
- ref: startRef,
53
- type: "start",
54
- onHasPartialValueChange: setStartHasValue
55
- }, `start-${clearKey}`),
56
- /*#__PURE__*/ jsx(DateRangeSeparator, {}),
57
- /*#__PURE__*/ jsx(DateRangeSegmentGroup, {
58
- ...endFieldProps,
59
- ref: endRef,
60
- type: "end",
61
- onHasPartialValueChange: setEndHasValue
62
- }, `end-${clearKey}`)
63
- ]
64
- })
34
+ /*#__PURE__*/ jsx(DateRangeSegmentGroup, {
35
+ ...startFieldProps,
36
+ ref: startRef,
37
+ type: "start",
38
+ onHasPartialValueChange: setStartHasValue
39
+ }, `start-${clearKey}`),
40
+ /*#__PURE__*/ jsx(DateRangeSeparator, {}),
41
+ /*#__PURE__*/ jsx(DateRangeSegmentGroup, {
42
+ ...endFieldProps,
43
+ ref: endRef,
44
+ type: "end",
45
+ onHasPartialValueChange: setEndHasValue
46
+ }, `end-${clearKey}`)
65
47
  ]
66
48
  }),
67
49
  /*#__PURE__*/ jsx(InputGroupAddon, {
@@ -1,10 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { InputGroup, InputGroupAddon } from "../InputGroup/index.js";
3
- import { useDateRangeContext } from "./DateRangeContext/index.js";
4
- const DateRangeSegment = ({ children, icon: IconComponent })=>{
5
- const context = useDateRangeContext();
6
- return /*#__PURE__*/ jsxs(InputGroup, {
7
- size: context?.size,
3
+ const DateRangeSegment = ({ children, icon: IconComponent })=>/*#__PURE__*/ jsxs(InputGroup, {
8
4
  children: [
9
5
  IconComponent && /*#__PURE__*/ jsx(InputGroupAddon, {
10
6
  children: /*#__PURE__*/ jsx(IconComponent, {})
@@ -12,5 +8,4 @@ const DateRangeSegment = ({ children, icon: IconComponent })=>{
12
8
  children
13
9
  ]
14
10
  });
15
- };
16
11
  export { DateRangeSegment };
@@ -5,13 +5,14 @@ import { useDateField } from "@react-aria/datepicker";
5
5
  import { useLocale } from "@react-aria/i18n";
6
6
  import { useDateFieldState } from "@react-stately/datepicker";
7
7
  import { cn } from "../../utils/cn.js";
8
- import { TemporalSegmentGroup, TimeDropdown, useTimeDropdownKeyCapture } from "../TemporalCore/index.js";
8
+ import { TemporalPlaceholder, TemporalSegmentGroup, TimeDropdown, useTimeDropdownKeyCapture } from "../TemporalCore/index.js";
9
9
  import { useDateRangeContext } from "./DateRangeContext/index.js";
10
10
  const DateRangeSegmentGroup = /*#__PURE__*/ forwardRef(({ type, onHasPartialValueChange, ...props }, ref)=>{
11
11
  const context = useDateRangeContext();
12
- const { disabled = false, error = false, readOnly = false, showTimeDropdown, timeStep = 30, hourCycle, icon } = context ?? {};
12
+ const { disabled = false, error = false, readOnly = false, placeholder, showTimeDropdown, timeStep = 30, hourCycle, icon } = context ?? {};
13
13
  const { locale } = useLocale();
14
14
  const dropdownRef = useRef(null);
15
+ const [isFocused, setIsFocused] = useState(false);
15
16
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
16
17
  const blurTimeoutRef = useRef(null);
17
18
  const fieldState = useDateFieldState({
@@ -23,6 +24,7 @@ const DateRangeSegmentGroup = /*#__PURE__*/ forwardRef(({ type, onHasPartialValu
23
24
  });
24
25
  const { fieldProps } = useDateField(props, fieldState, ref);
25
26
  const hasPartialValue = fieldState.segments.some((seg)=>seg.isEditable && !seg.isPlaceholder);
27
+ const showPlaceholder = placeholder && !hasPartialValue && !isFocused;
26
28
  useEffect(()=>{
27
29
  onHasPartialValueChange?.(hasPartialValue);
28
30
  }, [
@@ -32,6 +34,7 @@ const DateRangeSegmentGroup = /*#__PURE__*/ forwardRef(({ type, onHasPartialValu
32
34
  const hasTimeSegments = fieldState.segments.some((seg)=>'hour' === seg.type || 'minute' === seg.type);
33
35
  const hasDateSegments = fieldState.segments.some((seg)=>'year' === seg.type || 'month' === seg.type || 'day' === seg.type);
34
36
  const handleFocus = ()=>{
37
+ setIsFocused(true);
35
38
  if (blurTimeoutRef.current) {
36
39
  clearTimeout(blurTimeoutRef.current);
37
40
  blurTimeoutRef.current = null;
@@ -41,6 +44,7 @@ const DateRangeSegmentGroup = /*#__PURE__*/ forwardRef(({ type, onHasPartialValu
41
44
  if (showTimeDropdown && hasTimeSegments && !isDropdownOpen) setIsDropdownOpen(true);
42
45
  };
43
46
  const handleBlur = ()=>{
47
+ setIsFocused(false);
44
48
  blurTimeoutRef.current = window.setTimeout(()=>{
45
49
  setIsDropdownOpen(false);
46
50
  }, 200);
@@ -80,15 +84,19 @@ const DateRangeSegmentGroup = /*#__PURE__*/ forwardRef(({ type, onHasPartialValu
80
84
  const currentTimeValue = fieldState.value && hasTimeSegments ? fieldState.value : null;
81
85
  const hasIcon = Boolean(icon);
82
86
  return /*#__PURE__*/ jsxs("div", {
83
- className: cn('relative h-full', !hasIcon && 'start' === type && 'pl-12'),
87
+ className: cn('relative flex-1', !hasIcon && 'pl-12'),
84
88
  onKeyDownCapture: handleKeyDownCapture,
85
89
  onClick: handleClick,
86
90
  children: [
91
+ showPlaceholder && /*#__PURE__*/ jsx(TemporalPlaceholder, {
92
+ text: placeholder,
93
+ className: "overflow-hidden text-ellipsis"
94
+ }),
87
95
  /*#__PURE__*/ jsx(TemporalSegmentGroup, {
88
96
  ...fieldProps,
89
97
  ref: ref,
90
98
  "data-slot": "input",
91
- className: cn('h-full'),
99
+ className: cn('h-36', showPlaceholder && 'opacity-0'),
92
100
  "aria-disabled": disabled || void 0,
93
101
  "aria-invalid": error || void 0,
94
102
  "data-field-type": type,
@@ -1,7 +1,6 @@
1
1
  import type { FC } from 'react';
2
2
  /**
3
- * Visual separator between start and end date fields in a date range input.
4
- * Renders a Unicode right arrow as plain text.
3
+ * Visual separator (arrow icon) between start and end date fields in a date range input.
5
4
  * Used within DateRangeProvider for custom compositions.
6
5
  *
7
6
  * @example
@@ -1,9 +1,12 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
+ import { ArrowRight } from "../../icons/index.js";
2
3
  import { cn } from "../../utils/cn.js";
3
4
  const DateRangeSeparator = ()=>/*#__PURE__*/ jsx("span", {
4
- className: cn('text-sm text-text-secondary select-none'),
5
+ className: cn('text-icon-secondary select-none'),
5
6
  "aria-hidden": "true",
6
- children: "→"
7
+ children: /*#__PURE__*/ jsx(ArrowRight, {
8
+ size: "md"
9
+ })
7
10
  });
8
11
  DateRangeSeparator.displayName = 'DateRangeSeparator';
9
12
  export { DateRangeSeparator };
@@ -2,7 +2,6 @@ import type { FC } from 'react';
2
2
  import type { DateValue } from '@react-aria/datepicker';
3
3
  import type { RangeValue } from '@react-types/shared';
4
4
  import type { SvgIconProps } from '../../icons';
5
- import type { InputGroupSize } from '../InputGroup';
6
5
  export interface DateRangeBaseProps {
7
6
  /** Optional icon component to display at the start of the input */
8
7
  icon?: FC<SvgIconProps>;
@@ -18,8 +17,6 @@ export interface DateRangeBaseProps {
18
17
  showTimeDropdown?: boolean;
19
18
  /** Time interval in minutes for dropdown options. Default: 30 */
20
19
  timeStep?: number;
21
- /** Visual size of the input. Default: 'default' (36px) */
22
- size?: InputGroupSize;
23
20
  }
24
21
  export interface DateRangeInputProps extends DateRangeBaseProps {
25
22
  /** Controlled value - range with start and end dates */
@@ -1,6 +1,20 @@
1
1
  import type { FC, HTMLAttributes } from 'react';
2
2
  import type { ExprNode, FieldMetadata } from './types';
3
3
  export interface FilterInputProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onChange'> {
4
+ /**
5
+ * Filter-field configurations driving the autocomplete. Most fields are
6
+ * passed through as-is, but a few names are **reserved** and auto-wired
7
+ * with design-system helpers (`acceptChar` / `normalize` / `getSuggestions`
8
+ * / `validate`). Current reserved names:
9
+ *
10
+ * - `status_code` — HTTP status code field (mask suggestions, format
11
+ * validation, digit-or-X input filter, partial-input normalization).
12
+ *
13
+ * Consumer-supplied callbacks always override the auto-wiring, so you can
14
+ * opt out per-field. For the same helpers on a field with a different
15
+ * `name`, import the factories (`createStatusCodeSuggestions`, …) and
16
+ * attach them manually.
17
+ */
4
18
  fields?: FieldMetadata[];
5
19
  value?: ExprNode | null;
6
20
  onChange?: (expression: ExprNode | null) => void;
@@ -6,7 +6,8 @@ import { FilterInputErrors, parseFilterInputErrors } from "./FilterInputErrors/i
6
6
  import { FilterInputField } from "./FilterInputField/index.js";
7
7
  import { FilterInputMenu } from "./FilterInputMenu/FilterInputMenu.js";
8
8
  import { useFilterInputAutocomplete, useFilterInputExpression, useFilterInputSelection } from "./hooks/index.js";
9
- const FilterInput = ({ fields = [], value, onChange, placeholder = 'Type to filter...', error = false, showKeyboardHint = false, className, ...props })=>{
9
+ import { applyKnownFieldHelpers } from "./lib/applyKnownFieldHelpers.js";
10
+ const FilterInput = ({ fields: rawFields = [], value, onChange, placeholder = 'Type to filter...', error = false, showKeyboardHint = false, className, ...props })=>{
10
11
  const inputRef = useRef(null);
11
12
  const containerRef = useRef(null);
12
13
  const buildingChipRef = useRef(null);
@@ -15,6 +16,9 @@ const FilterInput = ({ fields = [], value, onChange, placeholder = 'Type to filt
15
16
  if (el) chipRegistryRef.current.set(id, el);
16
17
  else chipRegistryRef.current.delete(id);
17
18
  }, []);
19
+ const fields = useMemo(()=>applyKnownFieldHelpers(rawFields), [
20
+ rawFields
21
+ ]);
18
22
  const { conditions, connectors, chips, upsertCondition, removeCondition, removeConditionAtIndex, clearAll, setConnectorValue } = useFilterInputExpression({
19
23
  fields,
20
24
  value,
@@ -1,5 +1,5 @@
1
1
  export { FilterInput, type FilterInputProps } from './FilterInput';
2
2
  export { FilterInputChip, type FilterInputChipProps } from './FilterInputField';
3
3
  export { FilterInputFieldMenu, type FilterInputFieldMenuProps, FilterInputOperatorMenu, type FilterInputOperatorMenuProps, FilterInputValueMenu, type FilterInputValueMenuProps, type ValueOption, } from './FilterInputMenu';
4
- export { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator, type FilterParseError, isFilterParseError, parseExpression, type StatusCodeSuggestionsOptions, serializeExpression, } from './lib';
4
+ export { applyFieldValueTransforms, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, type FilterParseError, isFilterParseError, parseExpression, serializeExpression, } from './lib';
5
5
  export type { Condition, ExprNode, FieldMetadata, FieldType, FieldValueOption, FilterInputChipData, FilterInputChipVariant, FilterOperator, Group, } from './types';
@@ -1,5 +1,5 @@
1
1
  import { FilterInput } from "./FilterInput.js";
2
2
  import { FilterInputChip } from "./FilterInputField/index.js";
3
3
  import { FilterInputFieldMenu, FilterInputOperatorMenu, FilterInputValueMenu } from "./FilterInputMenu/index.js";
4
- import { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator, isFilterParseError, parseExpression, serializeExpression } from "./lib/index.js";
5
- export { FilterInput, FilterInputChip, FilterInputFieldMenu, FilterInputOperatorMenu, FilterInputValueMenu, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator, isFilterParseError, parseExpression, serializeExpression };
4
+ import { applyFieldValueTransforms, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, isFilterParseError, parseExpression, serializeExpression } from "./lib/index.js";
5
+ export { FilterInput, FilterInputChip, FilterInputFieldMenu, FilterInputOperatorMenu, FilterInputValueMenu, applyFieldValueTransforms, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, isFilterParseError, parseExpression, serializeExpression };
@@ -0,0 +1,11 @@
1
+ import type { ExprNode, FieldMetadata } from '../types';
2
+ /**
3
+ * Walk an expression tree and apply each field's `serializeValue` hook to the
4
+ * matching condition's value. Typical use: consumer has the UI-facing
5
+ * `ExprNode` (e.g. status code chip with `"2XX"`) and wants the backend
6
+ * payload to carry the transformed form (`"2"`).
7
+ *
8
+ * Returns the original node (by reference) when nothing changed, so
9
+ * downstream memoization stays stable.
10
+ */
11
+ export declare const applyFieldValueTransforms: (expr: ExprNode | null, fields: FieldMetadata[]) => ExprNode | null;
@@ -0,0 +1,43 @@
1
+ const transformConditionValue = (condition, fieldsByName)=>{
2
+ const field = fieldsByName.get(condition.field);
3
+ const transform = field?.serializeValue;
4
+ if (!transform) return condition;
5
+ const { value } = condition;
6
+ if (null == value) return condition;
7
+ if (Array.isArray(value)) {
8
+ const next = value.map((v)=>transform(v));
9
+ if (next.every((v, i)=>v === value[i])) return condition;
10
+ return {
11
+ ...condition,
12
+ value: next
13
+ };
14
+ }
15
+ const next = transform(value);
16
+ if (next === value) return condition;
17
+ return {
18
+ ...condition,
19
+ value: next
20
+ };
21
+ };
22
+ const transformGroup = (group, fieldsByName)=>{
23
+ const children = group.children.map((child)=>transformNode(child, fieldsByName));
24
+ if (children.every((c, i)=>c === group.children[i])) return group;
25
+ return {
26
+ ...group,
27
+ children
28
+ };
29
+ };
30
+ const transformNode = (node, fieldsByName)=>{
31
+ if ('condition' === node.type) return transformConditionValue(node, fieldsByName);
32
+ return transformGroup(node, fieldsByName);
33
+ };
34
+ const applyFieldValueTransforms = (expr, fields)=>{
35
+ if (!expr) return expr;
36
+ if (!fields.some((f)=>f.serializeValue)) return expr;
37
+ const fieldsByName = new Map(fields.map((f)=>[
38
+ f.name,
39
+ f
40
+ ]));
41
+ return transformNode(expr, fieldsByName);
42
+ };
43
+ export { applyFieldValueTransforms };
@@ -0,0 +1,21 @@
1
+ import type { FieldMetadata } from '../types';
2
+ /**
3
+ * Decorate `fields` in place with design-system helpers for known field names.
4
+ * `FilterInput` calls this on the `fields` prop before rendering.
5
+ *
6
+ * Reserved names and what they auto-attach (unless the consumer already
7
+ * provided a value for that slot):
8
+ *
9
+ * | `name` | Attaches |
10
+ * | ------------- | ------------------------------------------------------------------------------------------ |
11
+ * | `status_code` | HTTP status code: `acceptChar`, `normalize`, `getSuggestions`, `validate`, `serializeValue` |
12
+ *
13
+ * Consumer-supplied callbacks always win over the auto-wired ones. If the
14
+ * backend uses a different name (e.g. `http_status_code`), the helpers are
15
+ * NOT applied — the consumer must either rename the field to match or wire
16
+ * the factories (`createStatusCode*`) manually.
17
+ *
18
+ * The returned array has **reference-stable identity** when no field matches,
19
+ * so downstream `useMemo` that depends on it does not invalidate unnecessarily.
20
+ */
21
+ export declare const applyKnownFieldHelpers: (fields: FieldMetadata[]) => FieldMetadata[];
@@ -0,0 +1,29 @@
1
+ import { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator } from "./statusCode/index.js";
2
+ const KNOWN_FIELD_HELPERS = {
3
+ status_code: ()=>({
4
+ acceptChar: createStatusCodeInputFilter(),
5
+ normalize: createStatusCodeNormalizer(),
6
+ getSuggestions: createStatusCodeSuggestions(),
7
+ validate: createStatusCodeValidator(),
8
+ serializeValue: createStatusCodeSerializer()
9
+ })
10
+ };
11
+ const applyKnownFieldHelpers = (fields)=>{
12
+ let changed = false;
13
+ const out = fields.map((field)=>{
14
+ const factory = KNOWN_FIELD_HELPERS[field.name];
15
+ if (!factory) return field;
16
+ const helpers = factory();
17
+ changed = true;
18
+ return {
19
+ ...field,
20
+ acceptChar: field.acceptChar ?? helpers.acceptChar,
21
+ normalize: field.normalize ?? helpers.normalize,
22
+ getSuggestions: field.getSuggestions ?? helpers.getSuggestions,
23
+ validate: field.validate ?? helpers.validate,
24
+ serializeValue: field.serializeValue ?? helpers.serializeValue
25
+ };
26
+ });
27
+ return changed ? out : fields;
28
+ };
29
+ export { applyKnownFieldHelpers };
@@ -1,6 +1,8 @@
1
1
  export type { DatePreset } from '../FilterInputMenu/FilterInputDateValueMenu/constants';
2
2
  export { DATE_PRESETS, formatDateForChip, getDateDisplayLabel, isDatePreset, } from '../FilterInputMenu/FilterInputDateValueMenu/constants';
3
3
  export { applyAcceptChar } from './applyAcceptChar';
4
+ export { applyFieldValueTransforms } from './applyFieldValueTransforms';
5
+ export { applyKnownFieldHelpers } from './applyKnownFieldHelpers';
4
6
  export { chipIdToConditionIndex, findChipSplitIndex } from './conditions';
5
7
  export { CONNECTOR_ID_PATTERN, NO_VALUE_OPERATORS, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, OPERATORS_BY_TYPE, QUERY_BAR_SELECTOR, VARIANT_LABELS, } from './constants';
6
8
  export { buildContainerAnchoredRect, isMenuRelated } from './dom';
@@ -10,4 +12,4 @@ export { getCurrentValueTokenText, getValueFilterText } from './menuFilterText';
10
12
  export { getOperatorFromLabel, getOperatorLabel, isBetweenOperator, isMultiSelectOperator, isNoValueOperator, } from './operators';
11
13
  export { type FilterParseError, isFilterParseError, parseExpression } from './parseExpression';
12
14
  export { serializeExpression } from './serializeExpression';
13
- export { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator, type StatusCodeSuggestionsOptions, } from './statusCode';
15
+ export { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, } from './statusCode';
@@ -1,5 +1,7 @@
1
1
  import { DATE_PRESETS, formatDateForChip, getDateDisplayLabel, isDatePreset } from "../FilterInputMenu/FilterInputDateValueMenu/constants.js";
2
2
  import { applyAcceptChar } from "./applyAcceptChar.js";
3
+ import { applyFieldValueTransforms } from "./applyFieldValueTransforms.js";
4
+ import { applyKnownFieldHelpers } from "./applyKnownFieldHelpers.js";
3
5
  import { chipIdToConditionIndex, findChipSplitIndex } from "./conditions.js";
4
6
  import { CONNECTOR_ID_PATTERN, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, VARIANT_LABELS } from "./constants.js";
5
7
  import { buildContainerAnchoredRect, isMenuRelated } from "./dom.js";
@@ -9,5 +11,5 @@ import { getCurrentValueTokenText, getValueFilterText } from "./menuFilterText.j
9
11
  import { getOperatorFromLabel, getOperatorLabel, isBetweenOperator, isMultiSelectOperator, isNoValueOperator } from "./operators.js";
10
12
  import { isFilterParseError, parseExpression } from "./parseExpression/index.js";
11
13
  import { serializeExpression } from "./serializeExpression.js";
12
- import { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator } from "./statusCode/index.js";
13
- export { CONNECTOR_ID_PATTERN, DATE_PRESETS, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, VARIANT_LABELS, applyAcceptChar, buildContainerAnchoredRect, chipIdToConditionIndex, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSuggestions, createStatusCodeValidator, filterAndSort, findChipSplitIndex, formatDateForChip, getCurrentValueTokenText, getDateDisplayLabel, getFieldValues, getOperatorFromLabel, getOperatorLabel, getValueFilterText, hasFieldValues, hasStaticAllowlist, isBetweenOperator, isDatePreset, isFilterParseError, isMenuRelated, isMultiSelectOperator, isNoValueOperator, parseExpression, serializeExpression };
14
+ import { createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator } from "./statusCode/index.js";
15
+ export { CONNECTOR_ID_PATTERN, DATE_PRESETS, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OPERATOR_LABELS_BY_TYPE, OPERATOR_SYMBOLS, QUERY_BAR_SELECTOR, VARIANT_LABELS, applyAcceptChar, applyFieldValueTransforms, applyKnownFieldHelpers, buildContainerAnchoredRect, chipIdToConditionIndex, createStatusCodeInputFilter, createStatusCodeNormalizer, createStatusCodeSerializer, createStatusCodeSuggestions, createStatusCodeValidator, filterAndSort, findChipSplitIndex, formatDateForChip, getCurrentValueTokenText, getDateDisplayLabel, getFieldValues, getOperatorFromLabel, getOperatorLabel, getValueFilterText, hasFieldValues, hasStaticAllowlist, isBetweenOperator, isDatePreset, isFilterParseError, isMenuRelated, isMultiSelectOperator, isNoValueOperator, parseExpression, serializeExpression };
@@ -1,6 +1,16 @@
1
- import type { ExprNode } from '../types';
1
+ import type { ExprNode, FieldMetadata } from '../types';
2
2
  /**
3
3
  * Serialize an expression tree to a canonical text string.
4
4
  * Top-level conditions are sorted alphabetically by field name.
5
+ *
6
+ * **Pass `fields` when the output targets the backend.** Per-field
7
+ * `serializeValue` hooks run first, so values like the status-code mask
8
+ * `"2XX"` become `"2"` in the emitted string. Omitting `fields` keeps the
9
+ * UI-facing values verbatim — useful for clipboard round-trip, debug
10
+ * display, or any case where the output feeds `parseExpression` back. If
11
+ * you forget `fields` on the path to the backend, the placeholder `X`s
12
+ * ride through silently — name the backend call-site helper explicitly
13
+ * (e.g. `const query = serializeExpression(expr, fields)`) to make the
14
+ * intent obvious at callsite.
5
15
  */
6
- export declare const serializeExpression: (expr: ExprNode | null) => string;
16
+ export declare const serializeExpression: (expr: ExprNode | null, fields?: FieldMetadata[]) => string;
@@ -1,3 +1,4 @@
1
+ import { applyFieldValueTransforms } from "./applyFieldValueTransforms.js";
1
2
  const quoteValue = (v)=>`"${v}"`;
2
3
  const serializeValue = (condition)=>{
3
4
  if ('is_null' === condition.operator || 'is_not_null' === condition.operator) return '';
@@ -27,8 +28,10 @@ const serializeNode = (node, isTopLevel)=>{
27
28
  if ('condition' === node.type) return serializeCondition(node);
28
29
  return serializeGroup(node, isTopLevel);
29
30
  };
30
- const serializeExpression = (expr)=>{
31
+ const serializeExpression = (expr, fields)=>{
31
32
  if (!expr) return '';
32
- return serializeNode(expr, true);
33
+ const normalized = fields ? applyFieldValueTransforms(expr, fields) : expr;
34
+ if (!normalized) return '';
35
+ return serializeNode(normalized, true);
33
36
  };
34
37
  export { serializeExpression };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Build the `serializeValue` callback for the HTTP status code field. Strips
3
+ * trailing mask placeholders (`X` / `x`) from the UI value so the backend
4
+ * receives the shorter class form:
5
+ *
6
+ * "2XX" → "2"
7
+ * "22X" → "22"
8
+ * "222" → "222"
9
+ * "4XX" → "4"
10
+ * "40X" → "40"
11
+ *
12
+ * Anything that isn't a status-code-shaped string (e.g. a number, boolean,
13
+ * or freeform text) is returned unchanged so invalid committed values still
14
+ * surface in the backend payload for the parser to reject.
15
+ */
16
+ export declare const createStatusCodeSerializer: () => ((value: string | number | boolean) => string | number | boolean);
@@ -0,0 +1,6 @@
1
+ const createStatusCodeSerializer = ()=>(value)=>{
2
+ if ('string' != typeof value) return value;
3
+ if (!/^\d[\dX]{0,2}$/i.test(value)) return value;
4
+ return value.replace(/X+$/i, '');
5
+ };
6
+ export { createStatusCodeSerializer };