@charcoal-ui/react 3.9.0 → 3.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.
Files changed (35) hide show
  1. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.d.ts.map +1 -1
  2. package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts +2 -1
  3. package/dist/components/DropdownSelector/MenuList/MenuListContext.d.ts.map +1 -1
  4. package/dist/components/DropdownSelector/MenuList/index.d.ts.map +1 -1
  5. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts +2 -1
  6. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.d.ts.map +1 -1
  7. package/dist/components/DropdownSelector/index.d.ts +4 -0
  8. package/dist/components/DropdownSelector/index.d.ts.map +1 -1
  9. package/dist/components/DropdownSelector/index.story.d.ts +12 -5
  10. package/dist/components/DropdownSelector/index.story.d.ts.map +1 -1
  11. package/dist/components/LoadingSpinner/LoadingSpinnerIcon.story.d.ts.map +1 -1
  12. package/dist/components/LoadingSpinner/index.story.d.ts.map +1 -1
  13. package/dist/components/Modal/index.story.d.ts +1 -0
  14. package/dist/components/Modal/index.story.d.ts.map +1 -1
  15. package/dist/components/Modal/useCustomModalOverlay.d.ts.map +1 -1
  16. package/dist/index.cjs.js +49 -25
  17. package/dist/index.cjs.js.map +1 -1
  18. package/dist/index.esm.js +60 -36
  19. package/dist/index.esm.js.map +1 -1
  20. package/package.json +9 -7
  21. package/src/components/DropdownSelector/ListItem/__snapshots__/index.story.storyshot +5 -3
  22. package/src/components/DropdownSelector/ListItem/index.tsx +5 -1
  23. package/src/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.tsx +29 -18
  24. package/src/components/DropdownSelector/MenuList/MenuListContext.ts +3 -2
  25. package/src/components/DropdownSelector/MenuList/__snapshots__/index.story.storyshot +15 -9
  26. package/src/components/DropdownSelector/MenuList/index.tsx +6 -4
  27. package/src/components/DropdownSelector/MenuList/internals/getValuesRecursive.tsx +11 -8
  28. package/src/components/DropdownSelector/__snapshots__/index.story.storyshot +2666 -396
  29. package/src/components/DropdownSelector/index.story.tsx +264 -103
  30. package/src/components/DropdownSelector/index.tsx +35 -7
  31. package/src/components/LoadingSpinner/LoadingSpinnerIcon.story.tsx +1 -0
  32. package/src/components/LoadingSpinner/index.story.tsx +1 -0
  33. package/src/components/Modal/__snapshots__/index.story.storyshot +990 -0
  34. package/src/components/Modal/index.story.tsx +23 -0
  35. package/src/components/Modal/useCustomModalOverlay.tsx +5 -0
package/dist/index.esm.js CHANGED
@@ -879,7 +879,7 @@ var ModalBackgroundContext = React8.createContext(null);
879
879
 
880
880
  // src/components/Modal/useCustomModalOverlay.tsx
881
881
  import * as React9 from "react";
882
- import { ariaHideOutside, useOverlay, useOverlayFocusContain } from "@react-aria/overlays";
882
+ import { ariaHideOutside, useOverlay, useOverlayFocusContain, usePreventScroll } from "@react-aria/overlays";
883
883
  function useCharcoalModalOverlay(props, state, ref) {
884
884
  const {
885
885
  overlayProps,
@@ -890,6 +890,9 @@ function useCharcoalModalOverlay(props, state, ref) {
890
890
  onClose: state.onClose,
891
891
  shouldCloseOnInteractOutside: () => false
892
892
  }, ref);
893
+ usePreventScroll({
894
+ isDisabled: !state.isOpen
895
+ });
893
896
  useOverlayFocusContain();
894
897
  React9.useEffect(() => {
895
898
  if (state.isOpen && ref.current) {
@@ -1086,7 +1089,7 @@ var LoadingSpinnerIcon = forwardRef14(function LoadingSpinnerIcon2({
1086
1089
  });
1087
1090
 
1088
1091
  // src/components/DropdownSelector/index.tsx
1089
- import { useState as useState3, useRef as useRef9 } from "react";
1092
+ import { useState as useState3, useRef as useRef9, useMemo as useMemo3 } from "react";
1090
1093
  import styled16, { css as css9 } from "styled-components";
1091
1094
  import { disabledSelector as disabledSelector2 } from "@charcoal-ui/utils";
1092
1095
 
@@ -1100,7 +1103,7 @@ import styled14 from "styled-components";
1100
1103
 
1101
1104
  // src/components/DropdownSelector/Popover/usePreventScroll.tsx
1102
1105
  import { useEffect as useEffect6 } from "react";
1103
- function usePreventScroll(element, isOpen) {
1106
+ function usePreventScroll2(element, isOpen) {
1104
1107
  useEffect6(() => {
1105
1108
  if (isOpen && element) {
1106
1109
  const defaultPaddingRight = element.style.paddingRight;
@@ -1136,7 +1139,7 @@ function Popover(props) {
1136
1139
  toggle: _empty
1137
1140
  });
1138
1141
  const modalBackground = useContext6(ModalBackgroundContext);
1139
- usePreventScroll(modalBackground, props.isOpen);
1142
+ usePreventScroll2(modalBackground, props.isOpen);
1140
1143
  if (!props.isOpen)
1141
1144
  return null;
1142
1145
  return /* @__PURE__ */ jsxs9(Overlay2, { portalContainer: document.body, children: [
@@ -1205,7 +1208,7 @@ function findPreviewRecursive(children, value) {
1205
1208
  }
1206
1209
 
1207
1210
  // src/components/DropdownSelector/MenuList/index.tsx
1208
- import { useRef as useRef8 } from "react";
1211
+ import { useMemo as useMemo2, useRef as useRef8 } from "react";
1209
1212
  import styled15 from "styled-components";
1210
1213
 
1211
1214
  // src/components/DropdownSelector/MenuList/MenuListContext.ts
@@ -1213,40 +1216,43 @@ import { createContext as createContext6 } from "react";
1213
1216
  var MenuListContext = createContext6({
1214
1217
  root: void 0,
1215
1218
  value: "",
1216
- values: [],
1219
+ propsArray: [],
1217
1220
  setValue: (_v) => {
1218
1221
  }
1219
1222
  });
1220
1223
 
1221
1224
  // src/components/DropdownSelector/MenuList/internals/getValuesRecursive.tsx
1222
1225
  import * as React12 from "react";
1223
- function getValuesRecursive(children, values = []) {
1226
+ function getValuesRecursive(children) {
1224
1227
  const childArray = React12.Children.toArray(children);
1228
+ const propsArray = [];
1225
1229
  for (let i = 0; i < childArray.length; i++) {
1226
1230
  const child = childArray[i];
1227
1231
  if (React12.isValidElement(child)) {
1228
1232
  const props = child.props;
1229
1233
  if ("value" in props && typeof props.value === "string") {
1230
- const childValue = props.value;
1231
- values.push(childValue);
1234
+ propsArray.push({
1235
+ disabled: props.disabled,
1236
+ value: props.value
1237
+ });
1232
1238
  }
1233
1239
  if ("children" in props && props.children) {
1234
- getValuesRecursive(props.children, values);
1240
+ propsArray.push(...getValuesRecursive(props.children));
1235
1241
  }
1236
1242
  }
1237
1243
  }
1244
+ return propsArray;
1238
1245
  }
1239
1246
 
1240
1247
  // src/components/DropdownSelector/MenuList/index.tsx
1241
1248
  import { jsx as jsx19 } from "react/jsx-runtime";
1242
1249
  function MenuList(props) {
1243
1250
  const root = useRef8(null);
1244
- const values = [];
1245
- getValuesRecursive(props.children, values);
1251
+ const propsArray = useMemo2(() => getValuesRecursive(props.children), [props.children]);
1246
1252
  return /* @__PURE__ */ jsx19(StyledUl, { ref: root, children: /* @__PURE__ */ jsx19(MenuListContext.Provider, { value: {
1247
1253
  value: props.value ?? "",
1248
1254
  root,
1249
- values,
1255
+ propsArray,
1250
1256
  setValue: (v) => {
1251
1257
  props.onChange?.(v);
1252
1258
  }
@@ -1258,20 +1264,29 @@ var StyledUl = styled15.ul.withConfig({
1258
1264
 
1259
1265
  // src/components/DropdownSelector/index.tsx
1260
1266
  import { focusVisibleFocusRingCss as focusVisibleFocusRingCss6 } from "@charcoal-ui/styled";
1267
+ import { useVisuallyHidden as useVisuallyHidden3 } from "@react-aria/visually-hidden";
1261
1268
  import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
1262
1269
  var defaultRequiredText = "*\u5FC5\u9808";
1263
1270
  function DropdownSelector(props) {
1264
1271
  const triggerRef = useRef9(null);
1265
1272
  const [isOpen, setIsOpen] = useState3(false);
1266
1273
  const preview = findPreviewRecursive(props.children, props.value);
1274
+ const isPlaceholder = useMemo3(() => props.placeholder !== void 0 && preview === void 0, [preview, props.placeholder]);
1275
+ const propsArray = getValuesRecursive(props.children);
1276
+ const {
1277
+ visuallyHiddenProps
1278
+ } = useVisuallyHidden3();
1267
1279
  return /* @__PURE__ */ jsxs10(DropdownSelectorRoot, { "aria-disabled": props.disabled, children: [
1268
1280
  props.showLabel === true && /* @__PURE__ */ jsx20(DropdownFieldLabel, { label: props.label, required: props.required, requiredText: props.requiredText ?? defaultRequiredText, subLabel: props.subLabel }),
1281
+ /* @__PURE__ */ jsx20("div", { ...visuallyHiddenProps, "aria-hidden": "true", children: /* @__PURE__ */ jsx20("select", { name: props.name, value: props.value, tabIndex: -1, children: propsArray.map((itemProps) => {
1282
+ return /* @__PURE__ */ jsx20("option", { value: itemProps.value, disabled: itemProps.disabled, children: itemProps.value }, itemProps.value);
1283
+ }) }) }),
1269
1284
  /* @__PURE__ */ jsxs10(DropdownButton, { invalid: props.invalid, disabled: props.disabled, onClick: () => {
1270
1285
  if (props.disabled === true)
1271
1286
  return;
1272
1287
  setIsOpen(true);
1273
1288
  }, ref: triggerRef, type: "button", $active: isOpen, children: [
1274
- /* @__PURE__ */ jsx20(DropdownButtonText, { children: props.placeholder !== void 0 && preview === void 0 ? props.placeholder : preview }),
1289
+ /* @__PURE__ */ jsx20(DropdownButtonText, { $isText3: isPlaceholder, children: isPlaceholder ? props.placeholder : preview }),
1275
1290
  /* @__PURE__ */ jsx20(DropdownButtonIcon, { name: "16/Menu" })
1276
1291
  ] }),
1277
1292
  isOpen && /* @__PURE__ */ jsx20(DropdownPopover, { isOpen, onClose: () => setIsOpen(false), triggerRef, value: props.value, children: /* @__PURE__ */ jsx20(MenuList, { value: props.value, onChange: (v) => {
@@ -1296,7 +1311,7 @@ var DropdownButton = styled16.button.withConfig({
1296
1311
  }) => invalid === true && css9(["&:not(:disabled):not([aria-disabled]),&[aria-disabled='false']{box-shadow:0 0 0 4px rgba(255,43,0,0.32);}"]));
1297
1312
  var DropdownButtonText = styled16.span.withConfig({
1298
1313
  componentId: "ccl__sc-1vnxmc8-3"
1299
- })(["text-align:left;font-size:14px;line-height:22px;display:flow-root;color:var(--charcoal-text2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"]);
1314
+ })(["text-align:left;font-size:14px;line-height:22px;display:flow-root;color:var(--charcoal-", ");overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"], (p) => p.$isText3 ? "text3" : "text2");
1300
1315
  var DropdownButtonIcon = styled16(Icon_default).withConfig({
1301
1316
  componentId: "ccl__sc-1vnxmc8-4"
1302
1317
  })(["color:var(--charcoal-text2);"]);
@@ -1324,7 +1339,7 @@ var StyledLi = styled17.li.withConfig({
1324
1339
  })(["list-style:none;"]);
1325
1340
  var ItemDiv = styled17.div.withConfig({
1326
1341
  componentId: "ccl__sc-p1vs75-1"
1327
- })(["display:flex;align-items:center;min-height:40px;cursor:pointer;outline:none;padding-right:16px;padding-left:16px;&:disabled,&[aria-disabled]:not([aria-disabled='false']){opacity:0.32;cursor:default;}:hover,:focus,:focus-within{background-color:var(--charcoal-surface3);}"]);
1342
+ })(["display:flex;align-items:center;min-height:40px;cursor:pointer;outline:none;padding-right:16px;padding-left:16px;transition:background-color 0.2s;&:disabled,&[aria-disabled]:not([aria-disabled='false']){opacity:0.32;cursor:default;}:hover,:focus,:focus-within{&:not(disabled):not([aria-disabled='true']){background-color:var(--charcoal-surface3);}}"]);
1328
1343
 
1329
1344
  // src/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.tsx
1330
1345
  import { useCallback as useCallback6, useContext as useContext7 } from "react";
@@ -1363,7 +1378,7 @@ function useMenuItemHandleKeyDown(value) {
1363
1378
  const {
1364
1379
  setValue,
1365
1380
  root,
1366
- values
1381
+ propsArray
1367
1382
  } = useContext7(MenuListContext);
1368
1383
  const setContextValue = useCallback6(() => {
1369
1384
  if (value !== void 0)
@@ -1373,24 +1388,33 @@ function useMenuItemHandleKeyDown(value) {
1373
1388
  if (e.key === "Enter") {
1374
1389
  setContextValue();
1375
1390
  } else if (e.key === "ArrowUp" || e.key === "ArrowDown") {
1391
+ const isForward = e.key === "ArrowDown";
1376
1392
  e.preventDefault();
1377
- if (!values || value === void 0)
1393
+ if (!propsArray || value === void 0)
1378
1394
  return;
1379
- const index = values.indexOf(value);
1395
+ const values = propsArray.map((props) => props.value).filter((v) => v);
1396
+ let index = values.indexOf(value);
1380
1397
  if (index === -1)
1381
1398
  return;
1382
- const focusValue = e.key === "ArrowUp" ? index - 1 < 0 ? values[values.length - 1] : values[index - 1] : index + 1 >= values.length ? values[0] : values[index + 1];
1383
- const next = root?.current?.querySelector(`[data-key='${focusValue}']`);
1384
- if (next instanceof HTMLElement) {
1385
- next.focus({
1386
- preventScroll: true
1387
- });
1388
- if (root?.current?.parentElement) {
1389
- handleFocusByKeyBoard(next, root.current.parentElement);
1399
+ for (let n = 0; n < values.length; n++) {
1400
+ const focusValue = isForward ? index + 1 >= values.length ? values[0] : values[index + 1] : index - 1 < 0 ? values[values.length - 1] : values[index - 1];
1401
+ const next = root?.current?.querySelector(`[data-key='${focusValue}']`);
1402
+ if (next instanceof HTMLElement) {
1403
+ if (next.ariaDisabled === "true") {
1404
+ index += isForward ? 1 : -1;
1405
+ continue;
1406
+ }
1407
+ next.focus({
1408
+ preventScroll: true
1409
+ });
1410
+ if (root?.current?.parentElement) {
1411
+ handleFocusByKeyBoard(next, root.current.parentElement);
1412
+ }
1413
+ break;
1390
1414
  }
1391
1415
  }
1392
1416
  }
1393
- }, [setContextValue, value, root, values]);
1417
+ }, [setContextValue, propsArray, value, root]);
1394
1418
  return [handleKeyDown, setContextValue];
1395
1419
  }
1396
1420
 
@@ -1452,7 +1476,7 @@ var StyledLi2 = styled19.li.withConfig({
1452
1476
  })(["display:block;"]);
1453
1477
 
1454
1478
  // src/components/SegmentedControl/index.tsx
1455
- import { forwardRef as forwardRef15, memo as memo6, useMemo as useMemo2, useRef as useRef10 } from "react";
1479
+ import { forwardRef as forwardRef15, memo as memo6, useMemo as useMemo4, useRef as useRef10 } from "react";
1456
1480
 
1457
1481
  // ../../node_modules/@react-stately/form/dist/import.mjs
1458
1482
  import { createContext as $jcIOw$createContext, useMemo as $jcIOw$useMemo, useContext as $jcIOw$useContext, useState as $jcIOw$useState, useRef as $jcIOw$useRef, useEffect as $jcIOw$useEffect } from "react";
@@ -1702,7 +1726,7 @@ var useRadioContext = () => {
1702
1726
  // src/components/SegmentedControl/index.tsx
1703
1727
  import { jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
1704
1728
  var SegmentedControl = forwardRef15(function SegmentedControlInner(props, ref) {
1705
- const ariaRadioGroupProps = useMemo2(() => ({
1729
+ const ariaRadioGroupProps = useMemo4(() => ({
1706
1730
  ...props,
1707
1731
  isDisabled: props.disabled,
1708
1732
  isReadOnly: props.readonly,
@@ -1713,7 +1737,7 @@ var SegmentedControl = forwardRef15(function SegmentedControlInner(props, ref) {
1713
1737
  const {
1714
1738
  radioGroupProps
1715
1739
  } = useRadioGroup(ariaRadioGroupProps, state);
1716
- const segmentedControlItems = useMemo2(() => {
1740
+ const segmentedControlItems = useMemo4(() => {
1717
1741
  return props.data.map((d) => typeof d === "string" ? {
1718
1742
  value: d,
1719
1743
  label: d
@@ -1725,7 +1749,7 @@ var SegmentedControl_default = memo6(SegmentedControl);
1725
1749
  var Segmented = (props) => {
1726
1750
  const state = useRadioContext();
1727
1751
  const ref = useRef10(null);
1728
- const ariaRadioProps = useMemo2(() => ({
1752
+ const ariaRadioProps = useMemo4(() => ({
1729
1753
  value: props.value,
1730
1754
  isDisabled: props.disabled,
1731
1755
  children: props.children
@@ -1759,7 +1783,7 @@ var SegmentedLabelInner = styled20.div.withConfig({
1759
1783
  })(["font-size:14px;line-height:22px;display:flow-root;&::before{display:block;width:0;height:0;content:'';margin-top:-4px;}&::after{display:block;width:0;height:0;content:'';margin-bottom:-4px;}"]);
1760
1784
 
1761
1785
  // src/components/Checkbox/index.tsx
1762
- import { forwardRef as forwardRef16, memo as memo7, useMemo as useMemo3 } from "react";
1786
+ import { forwardRef as forwardRef16, memo as memo7, useMemo as useMemo5 } from "react";
1763
1787
  import styled21, { css as css11 } from "styled-components";
1764
1788
  import { useCheckbox } from "@react-aria/checkbox";
1765
1789
  import { useObjectRef as useObjectRef3 } from "@react-aria/utils";
@@ -1770,7 +1794,7 @@ var Checkbox = forwardRef16(function CheckboxInner({
1770
1794
  invalid = false,
1771
1795
  ...props
1772
1796
  }, ref) {
1773
- const ariaCheckboxProps = useMemo3(() => ({
1797
+ const ariaCheckboxProps = useMemo5(() => ({
1774
1798
  ...props,
1775
1799
  isInValid: invalid,
1776
1800
  isSelected: props.checked,
@@ -1814,7 +1838,7 @@ var InputLabel = styled21.div.withConfig({
1814
1838
  })(["color:var(--charcoal-text2);font-size:14px;line-height:20px;"]);
1815
1839
 
1816
1840
  // src/components/TagItem/index.tsx
1817
- import { forwardRef as forwardRef17, memo as memo8, useMemo as useMemo4 } from "react";
1841
+ import { forwardRef as forwardRef17, memo as memo8, useMemo as useMemo6 } from "react";
1818
1842
  import { useObjectRef as useObjectRef4 } from "@react-aria/utils";
1819
1843
  import styled22, { css as css12 } from "styled-components";
1820
1844
  import { px as px2 } from "@charcoal-ui/utils";
@@ -1837,7 +1861,7 @@ var TagItem = forwardRef17(function TagItemInner({
1837
1861
  ...props
1838
1862
  }, _ref) {
1839
1863
  const ref = useObjectRef4(_ref);
1840
- const ariaButtonProps = useMemo4(() => ({
1864
+ const ariaButtonProps = useMemo6(() => ({
1841
1865
  elementType: "a",
1842
1866
  isDisabled: disabled,
1843
1867
  ...props