@cambly/syntax-core 5.8.0 → 5.9.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,
@@ -1015,22 +1207,22 @@ var SelectList = ({
1015
1207
  const id = useId();
1016
1208
  const { isFocusVisible: isFocusVisible2 } = useFocusVisible();
1017
1209
  const [isFocused, setIsFocused] = useState4(false);
1018
- return /* @__PURE__ */ jsxs4(
1210
+ return /* @__PURE__ */ jsxs5(
1019
1211
  "div",
1020
1212
  {
1021
- className: (0, import_classnames9.default)(SelectList_module_default.selectContainer, {
1213
+ className: (0, import_classnames10.default)(SelectList_module_default.selectContainer, {
1022
1214
  [SelectList_module_default.opacityOverlay]: disabled
1023
1215
  }),
1024
1216
  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(
1217
+ label && /* @__PURE__ */ jsx18("label", { htmlFor: id, className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx18(Typography_default, { size: 100, color: "gray700", children: label }) }),
1218
+ /* @__PURE__ */ jsxs5("div", { className: SelectList_module_default.selectWrapper, children: [
1219
+ /* @__PURE__ */ jsxs5(
1028
1220
  "select",
1029
1221
  {
1030
1222
  id,
1031
1223
  "data-testid": dataTestId,
1032
1224
  disabled,
1033
- className: (0, import_classnames9.default)(SelectList_module_default.selectBox, SelectList_module_default[size], {
1225
+ className: (0, import_classnames10.default)(SelectList_module_default.selectBox, SelectList_module_default[size], {
1034
1226
  [SelectList_module_default.unselected]: !selectedValue && !errorText,
1035
1227
  [SelectList_module_default.selected]: selectedValue && !errorText,
1036
1228
  [SelectList_module_default.selectError]: errorText,
@@ -1045,19 +1237,19 @@ var SelectList = ({
1045
1237
  onFocus: () => setIsFocused(true),
1046
1238
  onBlur: () => setIsFocused(false),
1047
1239
  children: [
1048
- placeholderText && /* @__PURE__ */ jsx15("option", { disabled: true, value: placeholderText, children: placeholderText }),
1240
+ placeholderText && /* @__PURE__ */ jsx18("option", { disabled: true, value: placeholderText, children: placeholderText }),
1049
1241
  children
1050
1242
  ]
1051
1243
  }
1052
1244
  ),
1053
- /* @__PURE__ */ jsx15("div", { className: SelectList_module_default.arrowIcon, children: /* @__PURE__ */ jsx15(
1245
+ /* @__PURE__ */ jsx18("div", { className: SelectList_module_default.arrowIcon, children: /* @__PURE__ */ jsx18(
1054
1246
  "svg",
1055
1247
  {
1056
1248
  focusable: "false",
1057
1249
  "aria-hidden": "true",
1058
1250
  viewBox: "0 0 24 24",
1059
1251
  width: iconSize3[size],
1060
- children: /* @__PURE__ */ jsx15(
1252
+ children: /* @__PURE__ */ jsx18(
1061
1253
  "path",
1062
1254
  {
1063
1255
  fill: errorText ? ColorBaseDestructive700 : ColorBaseGray800,
@@ -1067,7 +1259,7 @@ var SelectList = ({
1067
1259
  }
1068
1260
  ) })
1069
1261
  ] }),
1070
- (helperText || errorText) && /* @__PURE__ */ jsx15("div", { className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx15(
1262
+ (helperText || errorText) && /* @__PURE__ */ jsx18("div", { className: SelectList_module_default.outerTextContainer, children: /* @__PURE__ */ jsx18(
1071
1263
  Typography_default,
1072
1264
  {
1073
1265
  size: 100,
@@ -1093,6 +1285,7 @@ export {
1093
1285
  Heading_default as Heading,
1094
1286
  IconButton_default as IconButton,
1095
1287
  MiniActionCard_default as MiniActionCard,
1288
+ Modal,
1096
1289
  RadioButton_default as RadioButton,
1097
1290
  SelectList_default as SelectList,
1098
1291
  Typography_default as Typography