@wix/editor-react-components 1.2344.0 → 1.2346.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 (43) hide show
  1. package/dist/site/components/AudioPlayer/component.js +3 -4
  2. package/dist/site/components/Breadcrumbs/component.js +1 -1
  3. package/dist/site/components/Button/component.js +1 -1
  4. package/dist/site/components/Checkbox/css.css +4 -4
  5. package/dist/site/components/CheckboxGroup/css.css +4 -4
  6. package/dist/site/components/CollapsibleText/component.js +1 -1
  7. package/dist/site/components/DatePicker/DatePicker.types.d.ts +6 -1
  8. package/dist/site/components/DatePicker/component.js +61 -11
  9. package/dist/site/components/DatePicker/components/DatePickerLabel.d.ts +2 -1
  10. package/dist/site/components/DatePicker/constants.d.ts +8 -0
  11. package/dist/site/components/DatePicker/css.css +13 -0
  12. package/dist/site/components/DatePicker/hooks/useDatePickerValue.d.ts +1 -1
  13. package/dist/site/components/DatePicker/manifest.js +12 -1
  14. package/dist/site/components/Lottie/component.js +1 -1
  15. package/dist/site/components/Menu/component.js +1 -1
  16. package/dist/site/components/Slideshow/component.js +1 -1
  17. package/dist/site/components/TextInput/TextInput.types.d.ts +3 -1
  18. package/dist/site/components/TextInput/component.js +86 -19
  19. package/dist/site/components/TextInput/constants.d.ts +13 -0
  20. package/dist/site/components/TextInput/css.css +47 -4
  21. package/dist/site/components/TextInput/manifest.js +8 -1
  22. package/dist/site/components/TimePicker/TimePicker.types.d.ts +7 -1
  23. package/dist/site/components/TimePicker/component.js +61 -11
  24. package/dist/site/components/TimePicker/constants.d.ts +7 -0
  25. package/dist/site/components/TimePicker/css.css +13 -0
  26. package/dist/site/components/TimePicker/hooks/useTimePickerValue.d.ts +1 -1
  27. package/dist/site/components/TimePicker/manifest.js +8 -1
  28. package/dist/site/components/chunks/Button.js +347 -1057
  29. package/dist/site/components/chunks/{Tooltip.js → DateField.js} +52 -1018
  30. package/dist/site/components/chunks/Group.js +970 -46
  31. package/dist/site/components/chunks/NumberFormatter.js +140 -0
  32. package/dist/site/components/chunks/VisuallyHidden.js +1 -1
  33. package/dist/site/components/chunks/constants2.js +9 -2
  34. package/dist/site/components/chunks/constants3.js +10 -1
  35. package/dist/site/components/chunks/constants33.js +10 -2
  36. package/dist/site/components/chunks/filterDOMProps.js +139 -18
  37. package/dist/site/components/chunks/manifest2.js +73 -0
  38. package/dist/site/components/chunks/useLocalizedStringFormatter.js +1 -1
  39. package/dist/site/components/chunks/useValidatedField.js +1411 -0
  40. package/package.json +5 -5
  41. package/dist/site/components/chunks/Button2.js +0 -365
  42. package/dist/site/components/chunks/I18nProvider.js +0 -125
  43. package/dist/site/components/chunks/Input.js +0 -341
@@ -5,13 +5,15 @@ import { c as clsx } from "../chunks/clsx.js";
5
5
  import { E as EnvironmentDefinition } from "../chunks/index2.js";
6
6
  import { b as getAccessibilityAttributes, H as HAS_CUSTOM_FOCUS_CLASSNAME } from "../chunks/a11y.js";
7
7
  import { a as getDataAttributes } from "../chunks/dataUtils.js";
8
- import { s as selectors } from "../chunks/constants3.js";
8
+ import { R as RequiredIndicator } from "../chunks/RequiredIndicator.js";
9
+ import { d as $fd2148440a13ec26$export$fc1a364ae1f3ff10, e as $191c9b6d48a0a4e2$export$294aa081a6c6f55d, f as $860f7da480e22816$export$b8473d3665f3a75a, g as $d3e0e05bdfcf66bd$export$c24727297075ec6a, h as $3985021b0ad6602f$export$37fb8590cf2c088c, i as $514c0188e459b4c0$export$9afb8bc826b033ea, j as $ee014567cb39d3f0$export$ff05c3ac10437e03, u as useValidatedField, $ as $4e3b923658d69c60$export$8c610744efcf8a1d, a as $4e3b923658d69c60$export$28c660c63b792dea, k as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../chunks/useValidatedField.js";
10
+ import { s as selectors, T as TestIds, V as VALUE_MISSING_MESSAGE } from "../chunks/constants3.js";
9
11
  import { useService } from "@wix/services-manager-react";
10
12
  import { T as TranslationsDefinition } from "../chunks/index5.js";
11
- import { a as $fd2148440a13ec26$export$fc1a364ae1f3ff10, b as $191c9b6d48a0a4e2$export$294aa081a6c6f55d, c as $860f7da480e22816$export$b8473d3665f3a75a, d as $d3e0e05bdfcf66bd$export$c24727297075ec6a, e as $3985021b0ad6602f$export$37fb8590cf2c088c, f as $514c0188e459b4c0$export$9afb8bc826b033ea, g as $ee014567cb39d3f0$export$ff05c3ac10437e03, h as $3985021b0ad6602f$export$f5b8910cec6cf069 } from "../chunks/Input.js";
12
- import { b as $3e6197669829fe11$export$40bfa8c7b0832715, c as $d1116acdf220c2da$export$4c014de7c8940b4c, d as $3274bf1495747a7b$export$5add1d006293d136, e as $bbaa08b3cd72f041$export$9d1611c77c2fe928, f as $23f2114a1b82827e$export$e58f029f0fbfdb29, g as $01b77f81d0f07f68$export$75b6ee27786ba447, h as $a049562f99e7db0e$export$f9c6924e160136d1, a as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../chunks/Group.js";
13
- import { $ as $8e9d2fae0ecb9001$export$457c3d6518dd4c6f, a as $f39a9eba43920ace$export$86427a43e3e48ebb, b as $64fa3d84918910a7$export$29f1550f4b0d4415, c as $64fa3d84918910a7$export$fabf2dc03a41866e, d as $64fa3d84918910a7$export$9d4c57ee4c6ffdd8, e as $64fa3d84918910a7$export$ef03459518577ad4, f as $64fa3d84918910a7$export$4d86445c2cf5e3, g as $65484d02dcb7eb3e$export$457c3d6518dd4c6f, h as $64fa3d84918910a7$export$2881499e37b75b9a } from "../chunks/filterDOMProps.js";
13
+ import { c as $3e6197669829fe11$export$40bfa8c7b0832715, d as $d1116acdf220c2da$export$4c014de7c8940b4c, e as $3274bf1495747a7b$export$5add1d006293d136, f as $bbaa08b3cd72f041$export$9d1611c77c2fe928, g as $23f2114a1b82827e$export$e58f029f0fbfdb29, h as $01b77f81d0f07f68$export$75b6ee27786ba447, i as $a049562f99e7db0e$export$f9c6924e160136d1, a as $01b77f81d0f07f68$export$b04be29aa201d4f5, b as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../chunks/Group.js";
14
+ import { a as $8e9d2fae0ecb9001$export$457c3d6518dd4c6f, b as $f39a9eba43920ace$export$86427a43e3e48ebb, c as $64fa3d84918910a7$export$29f1550f4b0d4415, d as $64fa3d84918910a7$export$fabf2dc03a41866e, e as $64fa3d84918910a7$export$9d4c57ee4c6ffdd8, f as $64fa3d84918910a7$export$ef03459518577ad4, g as $64fa3d84918910a7$export$4d86445c2cf5e3, h as $65484d02dcb7eb3e$export$457c3d6518dd4c6f, i as $64fa3d84918910a7$export$2881499e37b75b9a } from "../chunks/filterDOMProps.js";
14
15
  import { S as SdkStateDefinition } from "../chunks/index6.js";
16
+ import { I as InfoCircleSmall_default } from "../chunks/InfoCircleSmall.js";
15
17
  const $8e6cc465cc68f603$export$698f465ec27e93df = /* @__PURE__ */ createContext(null);
16
18
  function $054f71d2330da2e3$export$712718f7aec83d5(props, ref) {
17
19
  let { inputElementType = "input", isDisabled = false, isRequired = false, isReadOnly = false, type = "text", validationBehavior = "aria" } = props;
@@ -474,8 +476,12 @@ const hideNumberSpinner = "hideNumberSpinner__nYhia";
474
476
  const hasPrefix = "hasPrefix__RXMKp";
475
477
  const validationIndication = "validationIndication__GE20D";
476
478
  const label = "label__mbGIM";
479
+ const labelRow = "labelRow__tN4T-";
480
+ const tooltipButton = "tooltipButton__7D4vU";
481
+ const infoIcon = "infoIcon__Ksarp";
482
+ const tooltip = "tooltip__JnxIe";
477
483
  const hasLabel = "hasLabel__AGhlP";
478
- const requiredIndication = "requiredIndication__H3yrQ";
484
+ const requiredIndicator = "requiredIndicator__RyrLe";
479
485
  const style = {
480
486
  root,
481
487
  inputWrapper,
@@ -485,8 +491,12 @@ const style = {
485
491
  hasPrefix,
486
492
  validationIndication,
487
493
  label,
494
+ labelRow,
495
+ tooltipButton,
496
+ infoIcon,
497
+ tooltip,
488
498
  hasLabel,
489
- requiredIndication
499
+ requiredIndicator
490
500
  };
491
501
  const TranslationKeys = {
492
502
  NAMESPACE: "Text_Input",
@@ -569,7 +579,7 @@ const useSdkState = (componentId, key, defaultValue) => {
569
579
  const noop = () => {
570
580
  };
571
581
  const TextInput = (props, ref) => {
572
- var _a, _b;
582
+ var _a;
573
583
  const {
574
584
  name,
575
585
  id,
@@ -577,6 +587,7 @@ const TextInput = (props, ref) => {
577
587
  dataTestId,
578
588
  inputType = "text",
579
589
  label: label2,
590
+ tooltip: tooltip2,
580
591
  placeholder,
581
592
  readOnly,
582
593
  required,
@@ -594,7 +605,7 @@ const TextInput = (props, ref) => {
594
605
  autoFocus,
595
606
  prefix: prefix2,
596
607
  phoneFormat = "",
597
- errorMessageType = "tooltip",
608
+ errorMessageType = "inline",
598
609
  validateValue = noop,
599
610
  onBlur = noop,
600
611
  onFocus = noop,
@@ -615,7 +626,11 @@ const TextInput = (props, ref) => {
615
626
  const { translate } = useService(
616
627
  TranslationsDefinition
617
628
  );
618
- const [sdkValue, setSdkValue] = useSdkState(props.wix.wixPath, "value", "");
629
+ const [sdkValue, setSdkValue] = useSdkState(
630
+ props.wix.wixPath,
631
+ "value",
632
+ props.defaultValue ?? ""
633
+ );
619
634
  const [sdkValidityIndication, setSdkValidityIndication] = useSdkState(
620
635
  props.wix.wixPath,
621
636
  "shouldShowValidityIndication",
@@ -661,11 +676,11 @@ const TextInput = (props, ref) => {
661
676
  (_a2 = inputRef.current) == null ? void 0 : _a2.blur();
662
677
  },
663
678
  setCustomValidity: (message) => {
664
- var _a2, _b2;
679
+ var _a2, _b;
665
680
  if (message.type === "message") {
666
681
  (_a2 = inputRef.current) == null ? void 0 : _a2.setCustomValidity(message.message);
667
682
  } else {
668
- (_b2 = inputRef.current) == null ? void 0 : _b2.setCustomValidity(
683
+ (_b = inputRef.current) == null ? void 0 : _b.setCustomValidity(
669
684
  translateHtmlValidationMessage(message, {
670
685
  translations: props.translations,
671
686
  phoneFormat: props.phoneFormat
@@ -741,6 +756,31 @@ const TextInput = (props, ref) => {
741
756
  onChangeFn(((_a2 = inputRef.current) == null ? void 0 : _a2.value) ?? "");
742
757
  onHydrationComplete({ type: "onHydrationComplete" });
743
758
  }, []);
759
+ const useValidationContract = isExperimentOpen(
760
+ "specs.thunderbolt.textInputBreakingChange"
761
+ );
762
+ const nativeValidationMessage = ((_a = inputRef.current) == null ? void 0 : _a.validationMessage) ?? "";
763
+ const valueMissing = required && !value;
764
+ const intrinsic = valueMissing ? { valid: false, validationMessage: VALUE_MISSING_MESSAGE } : {
765
+ valid: !nativeValidationMessage,
766
+ validationMessage: nativeValidationMessage
767
+ };
768
+ const validityGate = props.showValidityIndication !== void 0 ? props.showValidityIndication : shouldShowValidityIndication;
769
+ const {
770
+ validity,
771
+ showValidityIndication: showIndication,
772
+ handleBlur: validateOnBlur
773
+ } = useValidatedField({
774
+ value,
775
+ intrinsic,
776
+ fieldValidity: useValidationContract ? props.fieldValidity : void 0,
777
+ showValidityIndication: validityGate,
778
+ onValidate: useValidationContract ? props.onValidate : void 0,
779
+ onValidityChange: useValidationContract ? props.onValidityChange : void 0
780
+ });
781
+ const showErrorIndication = useValidationContract ? showIndication : shouldShowValidityIndication;
782
+ const isInvalid = useValidationContract ? showIndication && !validity.valid : !!nativeValidationMessage && shouldShowValidityIndication;
783
+ const errorMessageToShow = useValidationContract ? validity.validationMessage : nativeValidationMessage;
744
784
  const _onBlur = (event) => {
745
785
  onBlur(event);
746
786
  if (valueChanged.current) {
@@ -752,6 +792,7 @@ const TextInput = (props, ref) => {
752
792
  valueChanged.current = false;
753
793
  setValidityIndication(true);
754
794
  setSdkValidityIndication(true);
795
+ validateOnBlur();
755
796
  };
756
797
  const _onClick = (event) => {
757
798
  if (!isDisabled) {
@@ -775,8 +816,7 @@ const TextInput = (props, ref) => {
775
816
  };
776
817
  const containerClasses = clsx(style.root, selectors.root, className, {
777
818
  [style.hasLabel]: !!label2,
778
- [style.requiredIndication]: required,
779
- [style.validationIndication]: !!shouldShowValidityIndication
819
+ [style.validationIndication]: showErrorIndication
780
820
  });
781
821
  const getMaxLength = () => {
782
822
  let updatedMaxLength = maxLength === null ? void 0 : maxLength;
@@ -790,7 +830,6 @@ const TextInput = (props, ref) => {
790
830
  ariaAttributes: { "aria-label": ariaLabel, ...restAriaAttributes }
791
831
  } = getAccessibilityAttributes({ ariaAttributes });
792
832
  const hasFocus = () => !!inputRef.current && inputRef.current === document.activeElement;
793
- const hasInvalidErrorMessage = !!((_a = inputRef.current) == null ? void 0 : _a.validationMessage) && shouldShowValidityIndication;
794
833
  const inputClasses = clsx(style.input, HAS_CUSTOM_FOCUS_CLASSNAME, {
795
834
  [style.hideNumberSpinner]: numberSpinnerHidden,
796
835
  [style.hasPrefix]: !!prefix2
@@ -813,7 +852,9 @@ const TextInput = (props, ref) => {
813
852
  name,
814
853
  type: inputType,
815
854
  placeholder,
816
- pattern,
855
+ // An empty pattern must NOT set the attribute — `pattern=""` matches only the
856
+ // empty string, so it would reject every non-empty value.
857
+ pattern: pattern || void 0,
817
858
  maxLength: getMaxLength(),
818
859
  minLength: getMinLength(),
819
860
  autoComplete: autoComplete ? autocompleteToken || "on" : autoComplete_ || "off",
@@ -825,7 +866,7 @@ const TextInput = (props, ref) => {
825
866
  onFocus,
826
867
  onKeyDown: onKeyPress,
827
868
  onBlur: _onBlur,
828
- "aria-invalid": hasInvalidErrorMessage,
869
+ "aria-invalid": isInvalid,
829
870
  ...ariaLabel && { "aria-label": ariaLabel },
830
871
  ...!required && { "aria-required": false },
831
872
  ...restAriaAttributes
@@ -844,7 +885,33 @@ const TextInput = (props, ref) => {
844
885
  onMouseLeave: _onMouseLeave,
845
886
  lang: language,
846
887
  children: /* @__PURE__ */ jsxs($bcdf0525bf22703d$export$2c73285ae9390cec, { ...textFieldProps, children: [
847
- label2 && /* @__PURE__ */ jsx($01b77f81d0f07f68$export$b04be29aa201d4f5, { className: labelClasses, htmlFor: `input_${id}`, children: label2 }),
888
+ (label2 || tooltip2) && /* @__PURE__ */ jsxs("div", { className: style.labelRow, children: [
889
+ label2 && /* @__PURE__ */ jsxs($01b77f81d0f07f68$export$b04be29aa201d4f5, { className: labelClasses, htmlFor: `input_${id}`, children: [
890
+ label2,
891
+ required && /* @__PURE__ */ jsx(
892
+ RequiredIndicator,
893
+ {
894
+ className: clsx(
895
+ style.requiredIndicator,
896
+ selectors.requiredIndicator
897
+ ),
898
+ "data-testid": TestIds.requiredIndicator
899
+ }
900
+ )
901
+ ] }),
902
+ tooltip2 && /* @__PURE__ */ jsxs($4e3b923658d69c60$export$8c610744efcf8a1d, { delay: 0, children: [
903
+ /* @__PURE__ */ jsx(
904
+ $d2b4bc8c273e7be6$export$353f5b6fc5456de1,
905
+ {
906
+ className: style.tooltipButton,
907
+ "data-testid": TestIds.tooltipButton,
908
+ "aria-label": tooltip2,
909
+ children: /* @__PURE__ */ jsx(InfoCircleSmall_default, { "aria-hidden": true, className: style.infoIcon })
910
+ }
911
+ ),
912
+ /* @__PURE__ */ jsx($4e3b923658d69c60$export$28c660c63b792dea, { className: style.tooltip, offset: 6, children: tooltip2 })
913
+ ] })
914
+ ] }),
848
915
  /* @__PURE__ */ jsxs("div", { className: style.inputWrapper, children: [
849
916
  prefix2 && /* @__PURE__ */ jsx("div", { className: style.prefix, "data-testid": "prefix", children: prefix2 }),
850
917
  /* @__PURE__ */ jsx($3985021b0ad6602f$export$f5b8910cec6cf069, { ...inputProps })
@@ -853,8 +920,8 @@ const TextInput = (props, ref) => {
853
920
  InlineErrorMessage,
854
921
  {
855
922
  errorMessageType,
856
- errorMessage: (_b = inputRef.current) == null ? void 0 : _b.validationMessage,
857
- shouldShowValidityIndication,
923
+ errorMessage: errorMessageToShow,
924
+ shouldShowValidityIndication: showErrorIndication,
858
925
  translations,
859
926
  componentViewMode: (getPreviewMode == null ? void 0 : getPreviewMode()) ? "preview" : "editor"
860
927
  }
@@ -1,6 +1,18 @@
1
1
  export declare const selectors: {
2
2
  readonly root: "textInput";
3
+ readonly requiredIndicator: "textInput__required-indicator";
3
4
  };
5
+ export declare const TestIds: {
6
+ readonly requiredIndicator: "text-input-required-indicator";
7
+ readonly tooltipButton: "text-input-tooltip-button";
8
+ };
9
+ /**
10
+ * Intrinsic `required` failure message (pre-resolved; i18n is a shared TODO,
11
+ * matching the other validation-contract inputs). `required` is surfaced as
12
+ * `aria-required` (not the native `required` attribute), so the browser never
13
+ * reports `valueMissing` — the empty-required check is computed in JS instead.
14
+ */
15
+ export declare const VALUE_MISSING_MESSAGE = "This field is required";
4
16
  export declare const DesignStates: {
5
17
  readonly root: {
6
18
  readonly hover: {
@@ -41,6 +53,7 @@ export declare const DisplayNames: {
41
53
  };
42
54
  data: {
43
55
  value: string;
56
+ defaultValue: string;
44
57
  isDisabled: string;
45
58
  name: string;
46
59
  minLength: string;
@@ -168,24 +168,67 @@
168
168
  .root__zQlRz .label__mbGIM {
169
169
  display: none;
170
170
  }
171
+ .root__zQlRz .labelRow__tN4T- {
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 6px;
175
+ margin-bottom: var(--labelMarginBottom);
176
+ }
177
+ .root__zQlRz .tooltipButton__7D4vU {
178
+ flex: none;
179
+ box-sizing: border-box;
180
+ display: inline-flex;
181
+ align-items: center;
182
+ justify-content: center;
183
+ width: 16px;
184
+ height: 16px;
185
+ margin: 0;
186
+ padding: 0;
187
+ border: none;
188
+ background: transparent;
189
+ color: var(--labelTextColor);
190
+ cursor: pointer;
191
+ opacity: 0.65;
192
+ }
193
+ .root__zQlRz .tooltipButton__7D4vU[data-hovered], .root__zQlRz .tooltipButton__7D4vU[data-focus-visible] {
194
+ opacity: 1;
195
+ }
196
+ .root__zQlRz .infoIcon__Ksarp {
197
+ width: 16px;
198
+ height: 16px;
199
+ }
200
+ .root__zQlRz .tooltip__JnxIe {
201
+ max-width: 220px;
202
+ padding: 6px 10px;
203
+ color: #ffffff;
204
+ background: #2b2b2b;
205
+ border-radius: 6px;
206
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
207
+ font: var(--labelFont);
208
+ }
171
209
  .root__zQlRz.hasLabel__AGhlP .label__mbGIM {
172
210
  word-break: break-word;
173
211
  display: inline-block;
174
212
  line-height: 1;
175
- margin-bottom: var(--labelMarginBottom);
176
213
  padding-inline-start: var(--labelPaddingInlineStart);
177
214
  padding-inline-end: var(--labelPaddingInlineEnd);
178
215
  text-align: var(--labelAlign, inherit);
179
216
  color: var(--labelTextColor);
180
217
  font: var(--labelFont);
181
218
  }
182
- .root__zQlRz.hasLabel__AGhlP.requiredIndication__H3yrQ .label__mbGIM::after {
183
- display: inline;
184
- content: " *";
219
+ .root__zQlRz.hasLabel__AGhlP .label__mbGIM .requiredIndicator__RyrLe {
185
220
  color: var(--requiredTextColor);
186
221
  }
187
222
  .root__zQlRz.validationIndication__GE20D .input__fyTfx:invalid {
188
223
  background-color: var(--errorBackground, #ffffff);
189
224
  border-color: var(--errorBorderColor, #e3e3e3);
190
225
  border-width: var(--errorBorderWidth, 1px);
226
+ }
227
+ .requiredIndicator__j5mIH {
228
+ display: inline-block;
229
+ width: 0.6em;
230
+ height: 0.6em;
231
+ margin-inline-start: 0.2em;
232
+ vertical-align: super;
233
+ color: inherit;
191
234
  }
@@ -3,6 +3,7 @@ import { D as DesignStates, a as DisplayNames, s as selectors } from "../chunks/
3
3
  import { w as withSpec, g as getSelector } from "../chunks/manifest.js";
4
4
  import { I as IS_SUPPORT_DESIGN_STATE_SPEC } from "../chunks/specs.js";
5
5
  import { m as manifestFocusable, b as manifestInputable, a as manifestChangeable } from "../chunks/manifestSdkMixins.js";
6
+ import { m as manifestValidation } from "../chunks/manifest2.js";
6
7
  const manifest = {
7
8
  id: "b8f7e3d2-4a5c-4e8f-9b2d-1c3e5f7a9b4d",
8
9
  type: "wixEditorElements.TextInput",
@@ -371,6 +372,10 @@ const manifest = {
371
372
  displayName: DisplayNames.data.value,
372
373
  dataType: DATA.DATA_TYPE.text
373
374
  },
375
+ defaultValue: {
376
+ displayName: DisplayNames.data.defaultValue,
377
+ dataType: DATA.DATA_TYPE.text
378
+ },
374
379
  isDisabled: {
375
380
  displayName: DisplayNames.data.isDisabled,
376
381
  dataType: DATA.DATA_TYPE.booleanValue,
@@ -501,6 +506,7 @@ const manifest = {
501
506
  errorMessageType: {
502
507
  displayName: DisplayNames.data.errorMessageType,
503
508
  dataType: DATA.DATA_TYPE.textEnum,
509
+ defaultValue: "inline",
504
510
  [DATA.DATA_TYPE.textEnum]: {
505
511
  options: [
506
512
  { value: "inline", displayName: DisplayNames.options.inline },
@@ -533,7 +539,8 @@ const manifest = {
533
539
  },
534
540
  ...manifestChangeable(),
535
541
  ...manifestInputable(),
536
- ...manifestFocusable()
542
+ ...manifestFocusable(),
543
+ ...manifestValidation({ valueDataType: DATA.DATA_TYPE.text })
537
544
  },
538
545
  interactions: {
539
546
  triggers: [
@@ -1,5 +1,6 @@
1
1
  import { A11y, Direction } from '@wix/editor-react-types';
2
2
  import { SdkFunctionChangeableProps, SdkFunctionFocusableProps } from '../../../utils/functions/sdkFunctionCallbackProps';
3
+ import { FieldValidationProps } from '../../../utils/validation/types';
3
4
  import { TranslationKeys } from './constants';
4
5
  /** A viewer-facing translatable string key. */
5
6
  export type TranslationKey = keyof typeof TranslationKeys;
@@ -7,7 +8,7 @@ export type TranslationKey = keyof typeof TranslationKeys;
7
8
  export type TimePickerGranularity = 'hour' | 'minute' | 'second';
8
9
  /** `auto` defers to the locale; `12`/`24` force the hour cycle. */
9
10
  export type TimePickerHourCycle = 'auto' | '12' | '24';
10
- export type TimePickerProps = Omit<SdkFunctionChangeableProps, 'onChange'> & SdkFunctionFocusableProps & {
11
+ export type TimePickerProps = Omit<SdkFunctionChangeableProps, 'onChange'> & SdkFunctionFocusableProps & FieldValidationProps<string> & {
11
12
  /** Fires with the selected ISO time string (`HH:MM[:SS]`), or `''` when cleared. */
12
13
  onChange?: (value: string) => void;
13
14
  /** DOM `id` on the root `.timePicker` wrapper. */
@@ -25,6 +26,11 @@ export type TimePickerProps = Omit<SdkFunctionChangeableProps, 'onChange'> & Sdk
25
26
  * means no time is selected.
26
27
  */
27
28
  value: string;
29
+ /**
30
+ * Uncontrolled initial selected time (ISO string, e.g. '14:30'). Used
31
+ * only when `value` is not provided (component owns its state).
32
+ */
33
+ defaultValue?: string;
28
34
  /** Optional text label rendered above the field. */
29
35
  label: string;
30
36
  /** Site-facing helper text rendered under the field. */
@@ -1,18 +1,18 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useState, useMemo } from "react";
3
3
  import { c as clsx } from "../chunks/clsx.js";
4
- import { $ as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../chunks/Button.js";
5
- import { $ as $58246871e4652552$export$c9698ec7f05a07e1, a as $40825cdb76e74f70$export$7edc06cf1783b30f, b as $40825cdb76e74f70$export$336ab7fa954c4b5f, c as $40825cdb76e74f70$export$5eaee2322dd727eb, d as $4e3b923658d69c60$export$8c610744efcf8a1d, e as $4e3b923658d69c60$export$28c660c63b792dea } from "../chunks/Tooltip.js";
6
- import { $ as $a049562f99e7db0e$export$eb2fcfdbd7ba97d4, a as $01b77f81d0f07f68$export$b04be29aa201d4f5 } from "../chunks/Group.js";
7
- import { $ as $514c0188e459b4c0$export$5f1af8db9871e1d6 } from "../chunks/Input.js";
8
- import { $ as $2eb8e6d23f3d0cb0$export$a54013f0d02a8f82 } from "../chunks/I18nProvider.js";
4
+ import { $ as $a049562f99e7db0e$export$eb2fcfdbd7ba97d4, a as $01b77f81d0f07f68$export$b04be29aa201d4f5, b as $d2b4bc8c273e7be6$export$353f5b6fc5456de1 } from "../chunks/Group.js";
5
+ import { $ as $58246871e4652552$export$c9698ec7f05a07e1, a as $40825cdb76e74f70$export$7edc06cf1783b30f, b as $40825cdb76e74f70$export$336ab7fa954c4b5f, c as $40825cdb76e74f70$export$5eaee2322dd727eb } from "../chunks/DateField.js";
6
+ import { u as useValidatedField, $ as $4e3b923658d69c60$export$8c610744efcf8a1d, a as $4e3b923658d69c60$export$28c660c63b792dea, b as $514c0188e459b4c0$export$5f1af8db9871e1d6, c as $ee014567cb39d3f0$export$f551688fc98f2e09 } from "../chunks/useValidatedField.js";
7
+ import { $ as $2eb8e6d23f3d0cb0$export$a54013f0d02a8f82 } from "../chunks/filterDOMProps.js";
9
8
  import { useService } from "@wix/services-manager-react";
10
9
  import { E as EnvironmentDefinition } from "../chunks/index2.js";
11
10
  import { T as TranslationsDefinition } from "../chunks/index5.js";
12
11
  import { a as getDataAttributes } from "../chunks/dataUtils.js";
13
12
  import { d as directionStyles } from "../chunks/direction.module.js";
14
13
  import { p as presetWrapperStyles } from "../chunks/presetWrapper.module.js";
15
- import { E as EMPTY_VALUE, T as TestIds, s as selectors, a as TRANSLATIONS_NAMESPACE, d as defaultValues, H as HourCycleValues, D as DefaultTranslations, b as TranslationKeys } from "../chunks/constants2.js";
14
+ import { E as EMPTY_VALUE, T as TestIds, s as selectors, a as TRANSLATIONS_NAMESPACE, d as defaultValues, V as VALUE_MISSING_MESSAGE, H as HourCycleValues, D as DefaultTranslations, b as TranslationKeys } from "../chunks/constants2.js";
15
+ import { R as RequiredIndicator } from "../chunks/RequiredIndicator.js";
16
16
  import { D as DismissSmall_default } from "../chunks/DismissSmall.js";
17
17
  import { I as InfoCircleSmall_default } from "../chunks/InfoCircleSmall.js";
18
18
  const getTranslation = (translate, key, translationKeys, defaultTranslations) => {
@@ -29,6 +29,7 @@ const tooltip = "tooltip__FTZhM";
29
29
  const group = "group__6HZy7";
30
30
  const field = "field__mnQwh";
31
31
  const description = "description__ePprf";
32
+ const errorMessage = "errorMessage__zxbOJ";
32
33
  const segment = "segment__OtazP";
33
34
  const clearButton = "clearButton__Bto7s";
34
35
  const clearIcon = "clearIcon__x11eI";
@@ -42,6 +43,7 @@ const styles = {
42
43
  group,
43
44
  field,
44
45
  description,
46
+ errorMessage,
45
47
  segment,
46
48
  clearButton,
47
49
  clearIcon
@@ -85,7 +87,10 @@ const useTimePickerValue = (params) => {
85
87
  return {
86
88
  timeValue,
87
89
  handleChange,
88
- hasValue: Boolean(valueStr)
90
+ // Key off the live parsed value, not the raw prop — a standalone picker
91
+ // updates `timeValue` internally while `props.value` may stay stale, so a
92
+ // prop-based check would keep the clear control / required error out of sync.
93
+ hasValue: Boolean(timeValue)
89
94
  };
90
95
  };
91
96
  const useTimeConstraints = (params) => {
@@ -133,6 +138,10 @@ function TimePicker(props) {
133
138
  onChange = noop,
134
139
  onFocus = noop,
135
140
  onBlur = noop,
141
+ fieldValidity,
142
+ showValidityIndication,
143
+ onValidate,
144
+ onValidityChange,
136
145
  wix
137
146
  } = props;
138
147
  const label2 = readString(props.label);
@@ -140,11 +149,31 @@ function TimePicker(props) {
140
149
  const tooltip2 = readString(props.tooltip);
141
150
  const isDisabled = readBool(props.isDisabled, false);
142
151
  const isRequired = readBool(props.required, defaultValues.required);
152
+ const isControlled = props.value !== void 0;
153
+ const sourceValue = isControlled ? props.value : props.defaultValue;
143
154
  const { timeValue, handleChange, hasValue } = useTimePickerValue({
144
- value: props.value,
155
+ value: sourceValue,
145
156
  onChange,
146
157
  granularity
147
158
  });
159
+ const intrinsic = isRequired && !hasValue ? { valid: false, validationMessage: VALUE_MISSING_MESSAGE } : { valid: true, validationMessage: "" };
160
+ const {
161
+ validity,
162
+ showValidityIndication: showIndication,
163
+ handleBlur: validateOnBlur
164
+ } = useValidatedField({
165
+ value: readString(props.value),
166
+ intrinsic,
167
+ fieldValidity,
168
+ showValidityIndication,
169
+ onValidate,
170
+ onValidityChange
171
+ });
172
+ const isInvalid = showIndication && !validity.valid;
173
+ const handleBlur = (event) => {
174
+ onBlur(event);
175
+ validateOnBlur();
176
+ };
148
177
  const { minValue, maxValue } = useTimeConstraints({
149
178
  minTime: props.minTime,
150
179
  maxTime: props.maxTime
@@ -200,12 +229,22 @@ function TimePicker(props) {
200
229
  isDisabled,
201
230
  isReadOnly: readOnly,
202
231
  isRequired,
232
+ isInvalid,
203
233
  "aria-label": ariaLabel,
204
234
  onFocus,
205
- onBlur,
235
+ onBlur: handleBlur,
206
236
  children: [
207
237
  label2 || tooltip2 ? /* @__PURE__ */ jsxs("div", { className: styles.labelRow, children: [
208
- label2 ? /* @__PURE__ */ jsx($01b77f81d0f07f68$export$b04be29aa201d4f5, { className: clsx(styles.label, selectors.label), children: label2 }) : null,
238
+ label2 ? /* @__PURE__ */ jsxs($01b77f81d0f07f68$export$b04be29aa201d4f5, { className: clsx(styles.label, selectors.label), children: [
239
+ label2,
240
+ isRequired && /* @__PURE__ */ jsx(
241
+ RequiredIndicator,
242
+ {
243
+ className: selectors.requiredIndicator,
244
+ "data-testid": TestIds.requiredIndicator
245
+ }
246
+ )
247
+ ] }) : null,
209
248
  tooltip2 ? /* @__PURE__ */ jsxs($4e3b923658d69c60$export$8c610744efcf8a1d, { delay: 0, children: [
210
249
  /* @__PURE__ */ jsx(
211
250
  $d2b4bc8c273e7be6$export$353f5b6fc5456de1,
@@ -228,7 +267,18 @@ function TimePicker(props) {
228
267
  ] }) : null
229
268
  ] }) : null,
230
269
  /* @__PURE__ */ jsx(TimePickerField, { clearButton: clearButton2 }),
231
- description2 ? /* @__PURE__ */ jsx($514c0188e459b4c0$export$5f1af8db9871e1d6, { slot: "description", className: styles.description, children: description2 }) : null
270
+ description2 ? /* @__PURE__ */ jsx($514c0188e459b4c0$export$5f1af8db9871e1d6, { slot: "description", className: styles.description, children: description2 }) : null,
271
+ isInvalid && validity.validationMessage ? /* @__PURE__ */ jsx(
272
+ $ee014567cb39d3f0$export$f551688fc98f2e09,
273
+ {
274
+ className: clsx(
275
+ styles.errorMessage,
276
+ selectors.errorMessage
277
+ ),
278
+ "data-testid": TestIds.errorMessage,
279
+ children: validity.validationMessage
280
+ }
281
+ ) : null
232
282
  ]
233
283
  }
234
284
  ) })
@@ -3,6 +3,7 @@ export declare const DisplayNames: {
3
3
  elementDisplayName: string;
4
4
  data: {
5
5
  value: string;
6
+ defaultValue: string;
6
7
  granularity: {
7
8
  displayName: string;
8
9
  options: {
@@ -105,9 +106,15 @@ export declare const TestIds: {
105
106
  readonly field: "timepicker-field";
106
107
  readonly clearButton: "timepicker-clear-button";
107
108
  readonly tooltipButton: "timepicker-tooltip-button";
109
+ readonly errorMessage: "timepicker-error-message";
110
+ readonly requiredIndicator: "timepicker-required-indicator";
108
111
  };
109
112
  export declare const selectors: {
110
113
  readonly root: "timePicker";
111
114
  readonly label: "timePicker__label";
115
+ readonly requiredIndicator: "timePicker__required-indicator";
112
116
  readonly group: "timePicker__group";
117
+ readonly errorMessage: "timePicker__error-message";
113
118
  };
119
+ /** Intrinsic `required` failure message (pre-resolved; i18n is a shared TODO). */
120
+ export declare const VALUE_MISSING_MESSAGE = "This field is required";
@@ -144,6 +144,11 @@
144
144
  font-size: 12px;
145
145
  opacity: 0.7;
146
146
  }
147
+ .errorMessage__zxbOJ {
148
+ margin-top: 4px;
149
+ font-size: 12px;
150
+ color: var(--errorColor, var(--wst-error-color, #e21c21));
151
+ }
147
152
  .segment__OtazP {
148
153
  padding: 0 2px;
149
154
  border-radius: 3px;
@@ -191,4 +196,12 @@
191
196
  }
192
197
  .presetWrapper__J1yzj {
193
198
  display: contents;
199
+ }
200
+ .requiredIndicator__j5mIH {
201
+ display: inline-block;
202
+ width: 0.6em;
203
+ height: 0.6em;
204
+ margin-inline-start: 0.2em;
205
+ vertical-align: super;
206
+ color: inherit;
194
207
  }
@@ -1,7 +1,7 @@
1
1
  import { TimeValue } from 'react-aria-components';
2
2
  import { TimePickerGranularity, TimePickerProps } from '../TimePicker.types';
3
3
  export declare const useTimePickerValue: (params: {
4
- value: TimePickerProps["value"];
4
+ value: TimePickerProps["value"] | undefined;
5
5
  onChange: NonNullable<TimePickerProps["onChange"]>;
6
6
  granularity: TimePickerGranularity;
7
7
  }) => {
@@ -3,6 +3,7 @@ import { c as DisplayNames, d as defaultValues, e as DesignStates, s as selector
3
3
  import { w as withSpec, g as getSelector } from "../chunks/manifest.js";
4
4
  import { I as IS_SUPPORT_DESIGN_STATE_SPEC } from "../chunks/specs.js";
5
5
  import { m as manifestFocusable, a as manifestChangeable } from "../chunks/manifestSdkMixins.js";
6
+ import { m as manifestValidation } from "../chunks/manifest2.js";
6
7
  const cssProperties = {
7
8
  font: {},
8
9
  color: {},
@@ -101,6 +102,10 @@ const manifest = {
101
102
  dataType: DATA.DATA_TYPE.localTime,
102
103
  displayName: DisplayNames.root.data.value
103
104
  },
105
+ defaultValue: {
106
+ dataType: DATA.DATA_TYPE.localTime,
107
+ displayName: DisplayNames.root.data.defaultValue
108
+ },
104
109
  granularity: {
105
110
  dataType: DATA.DATA_TYPE.textEnum,
106
111
  displayName: DisplayNames.root.data.granularity.displayName,
@@ -201,7 +206,9 @@ const manifest = {
201
206
  dataType: DATA.DATA_TYPE.direction
202
207
  },
203
208
  ...manifestChangeable(),
204
- ...manifestFocusable()
209
+ ...manifestFocusable(),
210
+ // The bound value is an ISO time string, so `onValidate` carries text.
211
+ ...manifestValidation({ valueDataType: DATA.DATA_TYPE.text })
205
212
  },
206
213
  displayFilters: {
207
214
  data: {