@cambly/syntax-core 5.8.0 → 5.10.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.
package/dist/index.mjs CHANGED
@@ -575,11 +575,11 @@ var ButtonGroup = ({
575
575
  size = "md",
576
576
  children
577
577
  }) => {
578
- const classnames2 = (0, import_classnames5.default)(ButtonGroup_module_default.buttonGroup, gap[size], {
578
+ const classnames3 = (0, import_classnames5.default)(ButtonGroup_module_default.buttonGroup, gap[size], {
579
579
  [ButtonGroup_module_default.horizontal]: orientation === "horizontal",
580
580
  [ButtonGroup_module_default.vertical]: orientation === "vertical"
581
581
  });
582
- return /* @__PURE__ */ jsx6("div", { className: classnames2, children });
582
+ return /* @__PURE__ */ jsx6("div", { className: classnames3, children });
583
583
  };
584
584
  var ButtonGroup_default = ButtonGroup;
585
585
 
@@ -590,7 +590,7 @@ var Card = ({
590
590
  size = "sm",
591
591
  "data-testid": dataTestId
592
592
  }) => {
593
- const sizeWidth = {
593
+ const sizeWidth2 = {
594
594
  sm: 352,
595
595
  lg: 744
596
596
  };
@@ -600,7 +600,7 @@ var Card = ({
600
600
  rounding: "xl",
601
601
  padding: 7,
602
602
  smPadding: 9,
603
- maxWidth: sizeWidth[size],
603
+ maxWidth: sizeWidth2[size],
604
604
  width: "100%",
605
605
  backgroundColor: "white",
606
606
  "data-testid": dataTestId,
@@ -743,7 +743,7 @@ function setupGlobalFocusEvents() {
743
743
  return;
744
744
  }
745
745
  const { focus } = HTMLElement.prototype;
746
- HTMLElement.prototype.focus = function focusElement(...args) {
746
+ HTMLElement.prototype.focus = function focusElement2(...args) {
747
747
  hasEventBeforeFocus = true;
748
748
  focus.apply(this, args);
749
749
  };
@@ -878,15 +878,207 @@ var MiniActionCard = ({
878
878
  }) => /* @__PURE__ */ jsx12("div", { className: MiniActionCard_module_default.miniActionCard, children });
879
879
  var MiniActionCard_default = MiniActionCard;
880
880
 
881
- // src/RadioButton/RadioButton.tsx
881
+ // src/Modal/Modal.tsx
882
882
  var import_classnames8 = __toESM(require_classnames());
883
+
884
+ // src/Modal/FocusTrap.tsx
885
+ import { useEffect as useEffect2, useRef } from "react";
886
+ import { jsx as jsx13 } from "react/jsx-runtime";
887
+ function queryFocusableAll(el) {
888
+ const selector = [
889
+ "a[href]",
890
+ "area[href]",
891
+ "input:not([disabled])",
892
+ "select:not([disabled])",
893
+ "textarea:not([disabled])",
894
+ "button:not([disabled])",
895
+ "iframe",
896
+ "object",
897
+ "embed",
898
+ '[tabindex="-1"]',
899
+ '[tabindex="0"]',
900
+ "[contenteditable]",
901
+ "audio[controls]",
902
+ "video[controls]",
903
+ "summary"
904
+ ].join(",");
905
+ return el.querySelectorAll(selector);
906
+ }
907
+ var focusElement = (el) => {
908
+ if (typeof el.focus === "function") {
909
+ el.focus();
910
+ }
911
+ };
912
+ function FocusTrap({
913
+ children
914
+ }) {
915
+ const elRef = useRef(null);
916
+ const previouslyFocusedElRef = useRef(null);
917
+ useEffect2(() => {
918
+ const { current: element } = elRef;
919
+ const focusFirstChild = () => {
920
+ const withinIframe = window !== window.parent;
921
+ if (element && !withinIframe) {
922
+ focusElement(queryFocusableAll(element)[0]);
923
+ }
924
+ };
925
+ const handleFocus = (event) => {
926
+ if (!element || event.target instanceof Node && element.contains(event.target)) {
927
+ return;
928
+ }
929
+ if (event.target instanceof Element && event.target.closest('[data-testid="syntax-focus-trap"]') !== null) {
930
+ return;
931
+ }
932
+ event.stopPropagation();
933
+ event.preventDefault();
934
+ focusFirstChild();
935
+ };
936
+ previouslyFocusedElRef.current = document.activeElement;
937
+ focusFirstChild();
938
+ document.addEventListener("focus", handleFocus, true);
939
+ return function cleanup() {
940
+ const { current: previouslyFocusedEl } = previouslyFocusedElRef;
941
+ document.removeEventListener("focus", handleFocus, true);
942
+ if (previouslyFocusedEl) {
943
+ focusElement(previouslyFocusedEl);
944
+ }
945
+ };
946
+ }, [elRef, previouslyFocusedElRef]);
947
+ return /* @__PURE__ */ jsx13("div", { "data-testid": "syntax-focus-trap", ref: elRef, children });
948
+ }
949
+
950
+ // src/Modal/StopScroll.tsx
951
+ import { useEffect as useEffect3 } from "react";
952
+ function StopScroll(props) {
953
+ useEffect3(() => {
954
+ const originalStyle = window.getComputedStyle(document.body).overflow;
955
+ document.body.style.overflow = "hidden";
956
+ return () => {
957
+ document.body.style.overflow = originalStyle;
958
+ };
959
+ }, []);
960
+ return props.children;
961
+ }
962
+
963
+ // src/Modal/Layer.tsx
964
+ import { createPortal } from "react-dom";
965
+ import { jsx as jsx14 } from "react/jsx-runtime";
966
+ function Layer({
967
+ children,
968
+ zIndex = 1
969
+ }) {
970
+ return createPortal(
971
+ /* @__PURE__ */ jsx14(
972
+ Box_default,
973
+ {
974
+ "data-testid": "syntax-layer",
975
+ position: "fixed",
976
+ dangerouslySetInlineStyle: {
977
+ __style: { zIndex, inset: 0 }
978
+ },
979
+ children
980
+ }
981
+ ),
982
+ document.body
983
+ );
984
+ }
985
+
986
+ // css-module:./Modal.module.css#css-module
987
+ var Modal_module_default = { "backdrop": "_backdrop_30t3h_1", "closeButton": "_closeButton_30t3h_12", "closeButtonWithImage": "_closeButtonWithImage_30t3h_32" };
988
+
989
+ // src/Modal/Modal.tsx
990
+ import { jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
991
+ function XIcon({ color = "#000" }) {
992
+ return /* @__PURE__ */ jsx15("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", fill: color, children: /* @__PURE__ */ jsx15(
993
+ "path",
994
+ {
995
+ fill: "inherit",
996
+ d: "M11.25.758a.83.83 0 0 0-1.175 0L6 4.825 1.925.75A.83.83 0 1 0 .75 1.925L4.825 6 .75 10.075a.83.83 0 1 0 1.175 1.175L6 7.175l4.075 4.075a.83.83 0 1 0 1.175-1.175L7.175 6l4.075-4.075a.835.835 0 0 0 0-1.167Z"
997
+ }
998
+ ) });
999
+ }
1000
+ var sizeWidth = {
1001
+ sm: 400,
1002
+ lg: 600
1003
+ };
1004
+ function Modal({
1005
+ header,
1006
+ children,
1007
+ image,
1008
+ onDismiss,
1009
+ footer,
1010
+ accessibilityCloseLabel = "close modal",
1011
+ size = "sm",
1012
+ zIndex = 1,
1013
+ "data-testid": dataTestId
1014
+ }) {
1015
+ return /* @__PURE__ */ jsx15(Layer, { zIndex, children: /* @__PURE__ */ jsx15(StopScroll, { children: /* @__PURE__ */ jsx15(FocusTrap, { children: /* @__PURE__ */ jsx15(
1016
+ "div",
1017
+ {
1018
+ className: Modal_module_default.backdrop,
1019
+ role: "presentation",
1020
+ onClick: (e) => e.target === e.currentTarget && onDismiss(),
1021
+ onKeyDown: (e) => e.key === "Escape" && onDismiss(),
1022
+ children: /* @__PURE__ */ jsxs3(
1023
+ Box_default,
1024
+ {
1025
+ "data-testid": dataTestId,
1026
+ backgroundColor: "white",
1027
+ rounding: "xl",
1028
+ display: "flex",
1029
+ direction: "column",
1030
+ minWidth: 240,
1031
+ maxWidth: sizeWidth[size],
1032
+ width: "100%",
1033
+ dangerouslySetInlineStyle: { __style: { overflow: "hidden" } },
1034
+ children: [
1035
+ /* @__PURE__ */ jsx15(Box_default, { position: "relative", children: /* @__PURE__ */ jsx15(
1036
+ "button",
1037
+ {
1038
+ "aria-label": accessibilityCloseLabel,
1039
+ type: "button",
1040
+ className: (0, import_classnames8.default)(Modal_module_default.closeButton, {
1041
+ [Modal_module_default.closeButtonWithImage]: !!image
1042
+ }),
1043
+ onClick: onDismiss,
1044
+ children: /* @__PURE__ */ jsx15(XIcon, { color: image ? "#fff" : "#000" })
1045
+ }
1046
+ ) }),
1047
+ image && /* @__PURE__ */ jsx15(Box_default, { maxHeight: 200, children: image }),
1048
+ /* @__PURE__ */ jsxs3(Box_default, { display: "flex", gap: 3, direction: "column", padding: 9, children: [
1049
+ /* @__PURE__ */ jsx15(Heading_default, { as: "h1", size: 500, children: header }),
1050
+ /* @__PURE__ */ jsx15(Box_default, { marginBottom: 4, children }),
1051
+ footer && /* @__PURE__ */ jsx15(
1052
+ Box_default,
1053
+ {
1054
+ display: "flex",
1055
+ direction: "column",
1056
+ gap: 3,
1057
+ smDirection: "row",
1058
+ smJustifyContent: "end",
1059
+ lgDirection: "row",
1060
+ lgJustifyContent: "end",
1061
+ children: footer
1062
+ }
1063
+ )
1064
+ ] })
1065
+ ]
1066
+ }
1067
+ )
1068
+ }
1069
+ ) }) }) });
1070
+ }
1071
+ Modal.displayName = "Modal";
1072
+
1073
+ // src/RadioButton/RadioButton.tsx
1074
+ var import_classnames9 = __toESM(require_classnames());
883
1075
  import { useState as useState3 } from "react";
884
1076
 
885
1077
  // css-module:./RadioButton.module.css#css-module
886
1078
  var RadioButton_module_default = { "radioBaseContainer": "_radioBaseContainer_1yyn9_1", "disabled": "_disabled_1yyn9_9", "cursorDisabled": "_cursorDisabled_1yyn9_13", "cursorEnabled": "_cursorEnabled_1yyn9_17", "smBase": "_smBase_1yyn9_21", "mdBase": "_mdBase_1yyn9_25", "radioStyleOverride": "_radioStyleOverride_1yyn9_29", "smOverride": "_smOverride_1yyn9_34", "mdOverride": "_mdOverride_1yyn9_39", "background": "_background_1yyn9_44", "sm": "_sm_1yyn9_21", "md": "_md_1yyn9_25", "neutralBorder": "_neutralBorder_1yyn9_61", "smCheckedBorder": "_smCheckedBorder_1yyn9_65", "mdCheckedBorder": "_mdCheckedBorder_1yyn9_69", "errorBorderColor": "_errorBorderColor_1yyn9_73", "borderColor": "_borderColor_1yyn9_77" };
887
1079
 
888
1080
  // src/RadioButton/RadioButton.tsx
889
- import { jsx as jsx13, jsxs as jsxs3 } from "react/jsx-runtime";
1081
+ import { jsx as jsx16, jsxs as jsxs4 } from "react/jsx-runtime";
890
1082
  var RadioButton = ({
891
1083
  checked = false,
892
1084
  "data-testid": dataTestId,
@@ -901,15 +1093,15 @@ var RadioButton = ({
901
1093
  }) => {
902
1094
  const [isFocused, setIsFocused] = useState3(false);
903
1095
  const { isFocusVisible: isFocusVisible2 } = useFocusVisible();
904
- const sharedStyles = (0, import_classnames8.default)(RadioButton_module_default.background, RadioButton_module_default[size], {
1096
+ const sharedStyles = (0, import_classnames9.default)(RadioButton_module_default.background, RadioButton_module_default[size], {
905
1097
  [RadioButton_module_default.errorBorderColor]: error,
906
1098
  [RadioButton_module_default.borderColor]: !error,
907
1099
  [Focus_module_default.accessibilityOutlineFocus]: isFocused && isFocusVisible2
908
1100
  });
909
- return /* @__PURE__ */ jsxs3(
1101
+ return /* @__PURE__ */ jsxs4(
910
1102
  "label",
911
1103
  {
912
- className: (0, import_classnames8.default)(
1104
+ className: (0, import_classnames9.default)(
913
1105
  RadioButton_module_default.radioBaseContainer,
914
1106
  RadioButton_module_default[`cursor${disabled ? "Disabled" : "Enabled"}`],
915
1107
  {
@@ -919,23 +1111,23 @@ var RadioButton = ({
919
1111
  }
920
1112
  ),
921
1113
  children: [
922
- checked ? /* @__PURE__ */ jsx13(
1114
+ checked ? /* @__PURE__ */ jsx16(
923
1115
  "div",
924
1116
  {
925
- className: (0, import_classnames8.default)(sharedStyles, {
1117
+ className: (0, import_classnames9.default)(sharedStyles, {
926
1118
  [RadioButton_module_default.mdCheckedBorder]: size === "md",
927
1119
  [RadioButton_module_default.smCheckedBorder]: size === "sm"
928
1120
  })
929
1121
  }
930
- ) : /* @__PURE__ */ jsx13("div", { className: (0, import_classnames8.default)(sharedStyles, RadioButton_module_default.neutralBorder) }),
931
- /* @__PURE__ */ jsx13(
1122
+ ) : /* @__PURE__ */ jsx16("div", { className: (0, import_classnames9.default)(sharedStyles, RadioButton_module_default.neutralBorder) }),
1123
+ /* @__PURE__ */ jsx16(
932
1124
  "input",
933
1125
  {
934
1126
  "data-testid": dataTestId,
935
1127
  type: "radio",
936
1128
  id,
937
1129
  name,
938
- className: (0, import_classnames8.default)(
1130
+ className: (0, import_classnames9.default)(
939
1131
  RadioButton_module_default.radioStyleOverride,
940
1132
  RadioButton_module_default[`cursor${disabled ? "Disabled" : "Enabled"}`],
941
1133
  {
@@ -955,7 +1147,7 @@ var RadioButton = ({
955
1147
  }
956
1148
  }
957
1149
  ),
958
- label && /* @__PURE__ */ jsx13(
1150
+ label && /* @__PURE__ */ jsx16(
959
1151
  Typography_default,
960
1152
  {
961
1153
  size: size === "md" ? 200 : 100,
@@ -970,7 +1162,7 @@ var RadioButton = ({
970
1162
  var RadioButton_default = RadioButton;
971
1163
 
972
1164
  // src/SelectList/SelectList.tsx
973
- var import_classnames9 = __toESM(require_classnames());
1165
+ var import_classnames10 = __toESM(require_classnames());
974
1166
  import {
975
1167
  useId,
976
1168
  useState as useState4
@@ -984,17 +1176,17 @@ var ColorBaseGray800 = "#353535";
984
1176
  var SelectList_module_default = { "selectContainer": "_selectContainer_1u9cw_1", "opacityOverlay": "_opacityOverlay_1u9cw_7", "outerTextContainer": "_outerTextContainer_1u9cw_11", "selectWrapper": "_selectWrapper_1u9cw_16", "selectBox": "_selectBox_1u9cw_21", "selectMouseFocusStyling": "_selectMouseFocusStyling_1u9cw_35", "unselected": "_unselected_1u9cw_40", "selected": "_selected_1u9cw_44", "arrowIcon": "_arrowIcon_1u9cw_48", "sm": "_sm_1u9cw_62", "md": "_md_1u9cw_67", "lg": "_lg_1u9cw_72", "selectError": "_selectError_1u9cw_77" };
985
1177
 
986
1178
  // src/SelectList/SelectOption.tsx
987
- import { jsx as jsx14 } from "react/jsx-runtime";
1179
+ import { jsx as jsx17 } from "react/jsx-runtime";
988
1180
  var SelectOption = ({
989
1181
  "data-testid": dataTestId,
990
1182
  value,
991
1183
  label,
992
1184
  disabled = false
993
- }) => /* @__PURE__ */ jsx14("option", { "data-testid": dataTestId, value, disabled, children: label });
1185
+ }) => /* @__PURE__ */ jsx17("option", { "data-testid": dataTestId, value, disabled, children: label });
994
1186
  var SelectOption_default = SelectOption;
995
1187
 
996
1188
  // src/SelectList/SelectList.tsx
997
- import { jsx as jsx15, jsxs as jsxs4 } from "react/jsx-runtime";
1189
+ import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
998
1190
  var iconSize3 = {
999
1191
  sm: 20,
1000
1192
  md: 24,
@@ -1008,6 +1200,7 @@ var SelectList = ({
1008
1200
  helperText,
1009
1201
  label,
1010
1202
  onChange,
1203
+ onClick,
1011
1204
  placeholderText,
1012
1205
  selectedValue = "",
1013
1206
  size = "md"
@@ -1015,22 +1208,22 @@ var SelectList = ({
1015
1208
  const id = useId();
1016
1209
  const { isFocusVisible: isFocusVisible2 } = useFocusVisible();
1017
1210
  const [isFocused, setIsFocused] = useState4(false);
1018
- return /* @__PURE__ */ jsxs4(
1211
+ return /* @__PURE__ */ jsxs5(
1019
1212
  "div",
1020
1213
  {
1021
- className: (0, import_classnames9.default)(SelectList_module_default.selectContainer, {
1214
+ className: (0, import_classnames10.default)(SelectList_module_default.selectContainer, {
1022
1215
  [SelectList_module_default.opacityOverlay]: disabled
1023
1216
  }),
1024
1217
  children: [
1025
- label && /* @__PURE__ */ jsx15("label", { htmlFor: id, className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx15(Typography_default, { size: 100, color: "gray700", children: label }) }),
1026
- /* @__PURE__ */ jsxs4("div", { className: SelectList_module_default.selectWrapper, children: [
1027
- /* @__PURE__ */ jsxs4(
1218
+ label && /* @__PURE__ */ jsx18("label", { htmlFor: id, className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx18(Typography_default, { size: 100, color: "gray700", children: label }) }),
1219
+ /* @__PURE__ */ jsxs5("div", { className: SelectList_module_default.selectWrapper, children: [
1220
+ /* @__PURE__ */ jsxs5(
1028
1221
  "select",
1029
1222
  {
1030
1223
  id,
1031
1224
  "data-testid": dataTestId,
1032
1225
  disabled,
1033
- className: (0, import_classnames9.default)(SelectList_module_default.selectBox, SelectList_module_default[size], {
1226
+ className: (0, import_classnames10.default)(SelectList_module_default.selectBox, SelectList_module_default[size], {
1034
1227
  [SelectList_module_default.unselected]: !selectedValue && !errorText,
1035
1228
  [SelectList_module_default.selected]: selectedValue && !errorText,
1036
1229
  [SelectList_module_default.selectError]: errorText,
@@ -1040,24 +1233,24 @@ var SelectList = ({
1040
1233
  // for focus mouse
1041
1234
  }),
1042
1235
  onChange,
1043
- onClick: (e) => e.stopPropagation(),
1236
+ onClick,
1044
1237
  value: placeholderText && !selectedValue ? placeholderText : selectedValue,
1045
1238
  onFocus: () => setIsFocused(true),
1046
1239
  onBlur: () => setIsFocused(false),
1047
1240
  children: [
1048
- placeholderText && /* @__PURE__ */ jsx15("option", { disabled: true, value: placeholderText, children: placeholderText }),
1241
+ placeholderText && /* @__PURE__ */ jsx18("option", { disabled: true, value: placeholderText, children: placeholderText }),
1049
1242
  children
1050
1243
  ]
1051
1244
  }
1052
1245
  ),
1053
- /* @__PURE__ */ jsx15("div", { className: SelectList_module_default.arrowIcon, children: /* @__PURE__ */ jsx15(
1246
+ /* @__PURE__ */ jsx18("div", { className: SelectList_module_default.arrowIcon, children: /* @__PURE__ */ jsx18(
1054
1247
  "svg",
1055
1248
  {
1056
1249
  focusable: "false",
1057
1250
  "aria-hidden": "true",
1058
1251
  viewBox: "0 0 24 24",
1059
1252
  width: iconSize3[size],
1060
- children: /* @__PURE__ */ jsx15(
1253
+ children: /* @__PURE__ */ jsx18(
1061
1254
  "path",
1062
1255
  {
1063
1256
  fill: errorText ? ColorBaseDestructive700 : ColorBaseGray800,
@@ -1067,7 +1260,7 @@ var SelectList = ({
1067
1260
  }
1068
1261
  ) })
1069
1262
  ] }),
1070
- (helperText || errorText) && /* @__PURE__ */ jsx15("div", { className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx15(
1263
+ (helperText || errorText) && /* @__PURE__ */ jsx18("div", { className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx18(
1071
1264
  Typography_default,
1072
1265
  {
1073
1266
  size: 100,
@@ -1093,6 +1286,7 @@ export {
1093
1286
  Heading_default as Heading,
1094
1287
  IconButton_default as IconButton,
1095
1288
  MiniActionCard_default as MiniActionCard,
1289
+ Modal,
1096
1290
  RadioButton_default as RadioButton,
1097
1291
  SelectList_default as SelectList,
1098
1292
  Typography_default as Typography