@mond-design-system/react 4.12.0 → 5.1.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.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createContext, createElement, useContext, Children, useId, useRef, useEffect, useState, useMemo, useCallback } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { createPortal } from 'react-dom';
4
+ import { autoUpdate, computePosition, offset, flip, size, shift } from '@floating-ui/dom';
4
5
 
5
6
  // src/internal/cx.ts
6
7
  function cx(...parts) {
@@ -78,15 +79,15 @@ function Heading({
78
79
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Spinner/Spinner.module.css?mds-scoped
79
80
  var Spinner_module_default = { "spinner": "mds-Spinner__spinner"};
80
81
  function Spinner({
81
- size = 20,
82
+ size: size2 = 20,
82
83
  label,
83
84
  className,
84
85
  style,
85
86
  ...rest
86
87
  }) {
87
88
  const vars = {
88
- "--spinner-size": `${size}px`,
89
- "--spinner-border": `${Math.max(2, Math.round(size / 10))}px`
89
+ "--spinner-size": `${size2}px`,
90
+ "--spinner-border": `${Math.max(2, Math.round(size2 / 10))}px`
90
91
  };
91
92
  return /* @__PURE__ */ jsx(
92
93
  "span",
@@ -108,7 +109,7 @@ function IconProvider({ render, children }) {
108
109
  }
109
110
  var SIZE_PX = { sm: 16, md: 20, lg: 24 };
110
111
  var warned = /* @__PURE__ */ new Set();
111
- function Icon({ name, size, label, className, ...rest }) {
112
+ function Icon({ name, size: size2, label, className, ...rest }) {
112
113
  const render = useContext(IconContext);
113
114
  if (render === null && !warned.has(name)) {
114
115
  warned.add(name);
@@ -119,10 +120,10 @@ function Icon({ name, size, label, className, ...rest }) {
119
120
  return /* @__PURE__ */ jsx(
120
121
  "span",
121
122
  {
122
- className: cx(Icon_module_default.icon, Icon_module_default[`size-${size ?? "slot"}`], className),
123
+ className: cx(Icon_module_default.icon, Icon_module_default[`size-${size2 ?? "slot"}`], className),
123
124
  ...label ? { role: "img", "aria-label": label } : { "aria-hidden": true },
124
125
  ...rest,
125
- children: render?.(name, { size: size === void 0 ? void 0 : SIZE_PX[size] })
126
+ children: render?.(name, { size: size2 === void 0 ? void 0 : SIZE_PX[size2] })
126
127
  }
127
128
  );
128
129
  }
@@ -132,7 +133,7 @@ var Button_module_default = { "button": "mds-Button__button", "size-sm": "mds-Bu
132
133
  var ICON_PX = { sm: 16, md: 20, lg: 24 };
133
134
  function Button({
134
135
  variant = "primary",
135
- size = "md",
136
+ size: size2 = "md",
136
137
  shape,
137
138
  onMedia = false,
138
139
  iconLeft,
@@ -159,7 +160,7 @@ function Button({
159
160
  className: cx(
160
161
  Button_module_default.button,
161
162
  Button_module_default[`variant-${variant}`],
162
- Button_module_default[`size-${size}`],
163
+ Button_module_default[`size-${size2}`],
163
164
  fullWidth && Button_module_default.fullWidth,
164
165
  iconOnly && Button_module_default["icon-only"],
165
166
  shape !== void 0 && Button_module_default[`shape-${shape}`],
@@ -170,7 +171,7 @@ function Button({
170
171
  ...own,
171
172
  ...rest,
172
173
  children: [
173
- loading ? /* @__PURE__ */ jsx("span", { className: Button_module_default.slot, children: /* @__PURE__ */ jsx(Spinner, { size: ICON_PX[size], label: "", "aria-hidden": "true" }) }) : iconLeft ? /* @__PURE__ */ jsx("span", { className: Button_module_default.slot, children: iconLeft }) : null,
174
+ loading ? /* @__PURE__ */ jsx("span", { className: Button_module_default.slot, children: /* @__PURE__ */ jsx(Spinner, { size: ICON_PX[size2], label: "", "aria-hidden": "true" }) }) : iconLeft ? /* @__PURE__ */ jsx("span", { className: Button_module_default.slot, children: iconLeft }) : null,
174
175
  body,
175
176
  !loading && iconRight ? /* @__PURE__ */ jsx("span", { className: Button_module_default.slot, children: iconRight }) : null
176
177
  ]
@@ -182,7 +183,7 @@ function Button({
182
183
  var Link_module_default = { "link": "mds-Link__link", "variant-inline": "mds-Link__variant-inline", "variant-standalone": "mds-Link__variant-standalone", "variant-plain": "mds-Link__variant-plain", "size-xs": "mds-Link__size-xs", "size-sm": "mds-Link__size-sm", "size-base": "mds-Link__size-base", "size-lg": "mds-Link__size-lg", "size-xl": "mds-Link__size-xl" };
183
184
  function Link({
184
185
  variant = "inline",
185
- size,
186
+ size: size2,
186
187
  external = false,
187
188
  as,
188
189
  ...rest
@@ -197,7 +198,7 @@ function Link({
197
198
  className: cx(
198
199
  Link_module_default.link,
199
200
  Link_module_default[`variant-${variant}`],
200
- size && Link_module_default[`size-${size}`],
201
+ size2 && Link_module_default[`size-${size2}`],
201
202
  className
202
203
  ),
203
204
  ...externalProps,
@@ -218,7 +219,7 @@ function initials(name) {
218
219
  function Avatar({
219
220
  name,
220
221
  src,
221
- size = "md",
222
+ size: size2 = "md",
222
223
  tone,
223
224
  decorative = false,
224
225
  className,
@@ -229,7 +230,7 @@ function Avatar({
229
230
  {
230
231
  className: cx(
231
232
  Avatar_module_default.avatar,
232
- Avatar_module_default[`size-${size}`],
233
+ Avatar_module_default[`size-${size2}`],
233
234
  tone !== void 0 && Avatar_module_default[`tone-${tone}`],
234
235
  className
235
236
  ),
@@ -253,7 +254,7 @@ var AvatarGroup_module_default = { "group": "mds-AvatarGroup__group", "item": "m
253
254
  function AvatarGroup({
254
255
  children,
255
256
  max = 4,
256
- size = "md",
257
+ size: size2 = "md",
257
258
  overflowLabel,
258
259
  className,
259
260
  ...rest
@@ -266,7 +267,7 @@ function AvatarGroup({
266
267
  hidden > 0 && /* @__PURE__ */ jsxs(
267
268
  "span",
268
269
  {
269
- className: cx(AvatarGroup_module_default.item, AvatarGroup_module_default.overflow, AvatarGroup_module_default[`size-${size}`]),
270
+ className: cx(AvatarGroup_module_default.item, AvatarGroup_module_default.overflow, AvatarGroup_module_default[`size-${size2}`]),
270
271
  "aria-label": overflowLabel(hidden),
271
272
  children: [
272
273
  "+",
@@ -517,7 +518,7 @@ function Field({ label, children, hint, error, required = false, className }) {
517
518
 
518
519
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Select/Select.module.css?mds-scoped
519
520
  var Select_module_default = { "wrap": "mds-Select__wrap", "select": "mds-Select__select", "size-sm": "mds-Select__size-sm", "size-md": "mds-Select__size-md", "size-lg": "mds-Select__size-lg", "chevron": "mds-Select__chevron" };
520
- function Select({ size = "md", className, children, ...rest }) {
521
+ function Select({ size: size2 = "md", className, children, ...rest }) {
521
522
  const field = useFieldContext();
522
523
  return /* @__PURE__ */ jsxs("span", { className: Select_module_default.wrap, children: [
523
524
  /* @__PURE__ */ jsx(
@@ -526,7 +527,7 @@ function Select({ size = "md", className, children, ...rest }) {
526
527
  id: rest.id ?? field?.id,
527
528
  "aria-describedby": rest["aria-describedby"] ?? field?.describedBy,
528
529
  "aria-invalid": rest["aria-invalid"] ?? (field?.invalid || void 0),
529
- className: cx(Select_module_default.select, Select_module_default[`size-${size}`], className),
530
+ className: cx(Select_module_default.select, Select_module_default[`size-${size2}`], className),
530
531
  ...rest,
531
532
  children
532
533
  }
@@ -540,7 +541,7 @@ var OverlayHistoryContext = createContext(null);
540
541
  var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
541
542
  function useOverlay(options) {
542
543
  const ref = useRef(null);
543
- const { open, onClose } = options;
544
+ const { open, onClose, lockScroll = true } = options;
544
545
  const close = useRef(onClose);
545
546
  useEffect(() => {
546
547
  close.current = onClose;
@@ -581,13 +582,13 @@ function useOverlay(options) {
581
582
  };
582
583
  document.addEventListener("keydown", onKeyDown);
583
584
  const bodyOverflow = document.body.style.overflow;
584
- document.body.style.overflow = "hidden";
585
+ if (lockScroll) document.body.style.overflow = "hidden";
585
586
  return () => {
586
587
  document.removeEventListener("keydown", onKeyDown);
587
- document.body.style.overflow = bodyOverflow;
588
+ if (lockScroll) document.body.style.overflow = bodyOverflow;
588
589
  previous?.focus();
589
590
  };
590
- }, [open]);
591
+ }, [open, lockScroll]);
591
592
  return ref;
592
593
  }
593
594
  function usePresence(open, durationMs) {
@@ -1092,38 +1093,68 @@ function ProgressBar({
1092
1093
  );
1093
1094
  }
1094
1095
 
1096
+ // src/internal/forkRef.ts
1097
+ function forkRef(own, given) {
1098
+ return (node) => {
1099
+ own.current = node;
1100
+ if (typeof given === "function") given(node);
1101
+ else if (given != null) given.current = node;
1102
+ };
1103
+ }
1104
+
1095
1105
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Input/Input.module.css?mds-scoped
1096
- var Input_module_default = { "input": "mds-Input__input", "size-sm": "mds-Input__size-sm", "size-md": "mds-Input__size-md", "size-lg": "mds-Input__size-lg", "iconWrap": "mds-Input__iconWrap", "icon": "mds-Input__icon", "iconLeft": "mds-Input__iconLeft", "iconRight": "mds-Input__iconRight", "with-icon-left": "mds-Input__with-icon-left", "with-icon-right": "mds-Input__with-icon-right" };
1106
+ var Input_module_default = { "input": "mds-Input__input", "own-clear": "mds-Input__own-clear", "size-sm": "mds-Input__size-sm", "size-md": "mds-Input__size-md", "size-lg": "mds-Input__size-lg", "iconWrap": "mds-Input__iconWrap", "icon": "mds-Input__icon", "slot-sm": "mds-Input__slot-sm", "slot-md": "mds-Input__slot-md", "slot-lg": "mds-Input__slot-lg", "iconLeft": "mds-Input__iconLeft", "iconRight": "mds-Input__iconRight", "with-icon-left": "mds-Input__with-icon-left", "with-icon-right": "mds-Input__with-icon-right", "clear": "mds-Input__clear mds-hit-area__hitArea", "clearGlyph": "mds-Input__clearGlyph" };
1097
1107
  function Input({
1098
- size = "md",
1108
+ size: size2 = "md",
1099
1109
  invalid,
1100
1110
  iconLeft,
1101
1111
  iconRight,
1112
+ onClear,
1113
+ clearLabel,
1102
1114
  className,
1115
+ ref,
1103
1116
  ...rest
1104
1117
  }) {
1105
1118
  const field = useFieldContext();
1119
+ const own = useRef(null);
1120
+ const [typedInto, setTypedInto] = useState(() => String(rest.defaultValue ?? "") !== "");
1121
+ const hasText = rest.value !== void 0 ? String(rest.value) !== "" : typedInto;
1122
+ const showClear = onClear != null && hasText;
1123
+ const handleChange = (event) => {
1124
+ if (onClear != null) setTypedInto(event.target.value !== "");
1125
+ rest.onChange?.(event);
1126
+ };
1127
+ const clear = () => {
1128
+ if (rest.value === void 0 && own.current != null) own.current.value = "";
1129
+ setTypedInto(false);
1130
+ own.current?.focus();
1131
+ onClear?.();
1132
+ };
1106
1133
  const input = /* @__PURE__ */ jsx(
1107
1134
  "input",
1108
1135
  {
1136
+ ref: forkRef(own, ref),
1109
1137
  id: rest.id ?? field?.id,
1110
1138
  "aria-describedby": rest["aria-describedby"] ?? field?.describedBy,
1111
1139
  "aria-invalid": rest["aria-invalid"] ?? ((invalid ?? field?.invalid) || void 0),
1112
1140
  className: cx(
1113
1141
  Input_module_default.input,
1114
- Input_module_default[`size-${size}`],
1142
+ Input_module_default[`size-${size2}`],
1115
1143
  iconLeft != null && Input_module_default["with-icon-left"],
1116
- iconRight != null && Input_module_default["with-icon-right"],
1144
+ (iconRight != null || showClear) && Input_module_default["with-icon-right"],
1145
+ onClear != null && Input_module_default["own-clear"],
1117
1146
  className
1118
1147
  ),
1119
- ...rest
1148
+ ...rest,
1149
+ onChange: handleChange
1120
1150
  }
1121
1151
  );
1122
- if (iconLeft == null && iconRight == null) return input;
1123
- return /* @__PURE__ */ jsxs("span", { className: Input_module_default.iconWrap, children: [
1152
+ if (iconLeft == null && iconRight == null && onClear == null) return input;
1153
+ return /* @__PURE__ */ jsxs("span", { className: cx(Input_module_default.iconWrap, Input_module_default[`slot-${size2}`]), children: [
1124
1154
  input,
1125
1155
  iconLeft != null && /* @__PURE__ */ jsx("span", { className: cx(Input_module_default.icon, Input_module_default.iconLeft), "aria-hidden": "true", children: iconLeft }),
1126
- iconRight != null && /* @__PURE__ */ jsx("span", { className: cx(Input_module_default.icon, Input_module_default.iconRight), "aria-hidden": "true", children: iconRight })
1156
+ iconRight != null && /* @__PURE__ */ jsx("span", { className: cx(Input_module_default.icon, Input_module_default.iconRight), "aria-hidden": "true", children: iconRight }),
1157
+ showClear && /* @__PURE__ */ jsx("button", { type: "button", "aria-label": clearLabel, className: Input_module_default.clear, onClick: clear, children: /* @__PURE__ */ jsx(CloseGlyph, { className: Input_module_default.clearGlyph }) })
1127
1158
  ] });
1128
1159
  }
1129
1160
 
@@ -1195,15 +1226,6 @@ function Textarea({ rows = 3, showCount = false, className, ...rest }) {
1195
1226
  ] });
1196
1227
  }
1197
1228
 
1198
- // src/internal/forkRef.ts
1199
- function forkRef(own, given) {
1200
- return (node) => {
1201
- own.current = node;
1202
- if (typeof given === "function") given(node);
1203
- else if (given != null) given.current = node;
1204
- };
1205
- }
1206
-
1207
1229
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Checkbox/Checkbox.module.css?mds-scoped
1208
1230
  var Checkbox_module_default = { "root": "mds-Checkbox__root", "box": "mds-Checkbox__box mds-hit-area__hitArea", "bare": "mds-Checkbox__bare", "label": "mds-Checkbox__label" };
1209
1231
  function Checkbox({
@@ -1278,7 +1300,7 @@ function SegmentedControl({
1278
1300
  onChange,
1279
1301
  disabled = false,
1280
1302
  fullWidth = false,
1281
- size = "md",
1303
+ size: size2 = "md",
1282
1304
  bare = false,
1283
1305
  repick = false,
1284
1306
  className
@@ -1291,7 +1313,7 @@ function SegmentedControl({
1291
1313
  "aria-label": label,
1292
1314
  className: cx(
1293
1315
  SegmentedControl_module_default.group,
1294
- SegmentedControl_module_default[`size-${size}`],
1316
+ SegmentedControl_module_default[`size-${size2}`],
1295
1317
  fullWidth && SegmentedControl_module_default.fullWidth,
1296
1318
  bare && SegmentedControl_module_default.bare,
1297
1319
  className
@@ -1316,51 +1338,6 @@ function SegmentedControl({
1316
1338
  );
1317
1339
  }
1318
1340
 
1319
- // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/SearchField/SearchField.module.css?mds-scoped
1320
- var SearchField_module_default = { "wrap": "mds-SearchField__wrap", "glass": "mds-SearchField__glass", "input": "mds-SearchField__input", "clear": "mds-SearchField__clear mds-hit-area__hitArea", "clearGlyph": "mds-SearchField__clearGlyph" };
1321
- function SearchField({
1322
- label,
1323
- clearLabel,
1324
- value,
1325
- onChange,
1326
- className,
1327
- ...rest
1328
- }) {
1329
- return /* @__PURE__ */ jsxs("span", { className: cx(SearchField_module_default.wrap, className), children: [
1330
- /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", className: SearchField_module_default.glass, children: /* @__PURE__ */ jsx(
1331
- "path",
1332
- {
1333
- d: "M7 12a5 5 0 1 1 0-10 5 5 0 0 1 0 10Zm7 2-3.5-3.5",
1334
- fill: "none",
1335
- stroke: "currentColor",
1336
- strokeWidth: "1.5",
1337
- strokeLinecap: "round"
1338
- }
1339
- ) }),
1340
- /* @__PURE__ */ jsx(
1341
- "input",
1342
- {
1343
- type: "search",
1344
- "aria-label": label,
1345
- value,
1346
- onChange: (event) => onChange(event.target.value),
1347
- className: SearchField_module_default.input,
1348
- ...rest
1349
- }
1350
- ),
1351
- value !== "" && /* @__PURE__ */ jsx(
1352
- "button",
1353
- {
1354
- type: "button",
1355
- "aria-label": clearLabel,
1356
- className: SearchField_module_default.clear,
1357
- onClick: () => onChange(""),
1358
- children: /* @__PURE__ */ jsx(CloseGlyph, { className: SearchField_module_default.clearGlyph })
1359
- }
1360
- )
1361
- ] });
1362
- }
1363
-
1364
1341
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Scroller/Scroller.module.css?mds-scoped
1365
1342
  var Scroller_module_default = { "scroller": "mds-Scroller__scroller", "header": "mds-Scroller__header", "trailing": "mds-Scroller__trailing", "track": "mds-Scroller__track", "arrows": "mds-Scroller__arrows" };
1366
1343
  var STEP = 0.8;
@@ -1907,6 +1884,304 @@ function ModalBody({ children }) {
1907
1884
  function ModalFooter({ children }) {
1908
1885
  return /* @__PURE__ */ jsx("div", { className: Modal_module_default.footer, children });
1909
1886
  }
1887
+ var VIEWPORT_PAD = 8;
1888
+ var MIN_HEIGHT = 120;
1889
+ function useAnchoredPosition({
1890
+ open,
1891
+ anchorRef,
1892
+ floatingRef,
1893
+ placement,
1894
+ gap
1895
+ }) {
1896
+ useEffect(() => {
1897
+ const anchor = anchorRef.current;
1898
+ const floating = floatingRef.current;
1899
+ if (!open || anchor === null || floating === null) return;
1900
+ const update = () => {
1901
+ void computePosition(anchor, floating, {
1902
+ placement,
1903
+ strategy: "fixed",
1904
+ middleware: [
1905
+ offset(gap),
1906
+ // Order is load-bearing: choose the side first, then cap the height
1907
+ // to what that side has, then slide along the cross axis. Sizing
1908
+ // before flipping caps against the side being abandoned.
1909
+ flip({ padding: VIEWPORT_PAD }),
1910
+ size({
1911
+ padding: VIEWPORT_PAD,
1912
+ apply({ availableHeight, elements }) {
1913
+ elements.floating.style.maxHeight = `${Math.max(availableHeight, MIN_HEIGHT)}px`;
1914
+ }
1915
+ }),
1916
+ shift({ padding: VIEWPORT_PAD })
1917
+ ]
1918
+ }).then(({ x, y, placement: resolved }) => {
1919
+ floating.style.left = `${x}px`;
1920
+ floating.style.top = `${y}px`;
1921
+ floating.dataset.placement = resolved;
1922
+ });
1923
+ };
1924
+ return autoUpdate(anchor, floating, update);
1925
+ }, [open, anchorRef, floatingRef, placement, gap]);
1926
+ }
1927
+ function useDismissOnOutside(open, onDismiss, inside) {
1928
+ const latest = useRef({ onDismiss, inside });
1929
+ useEffect(() => {
1930
+ latest.current = { onDismiss, inside };
1931
+ });
1932
+ useEffect(() => {
1933
+ if (!open) return;
1934
+ const onPointerDown = (event) => {
1935
+ const target = event.target;
1936
+ if (!(target instanceof Node)) return;
1937
+ const { onDismiss: dismiss, inside: refs } = latest.current;
1938
+ if (refs.some((ref) => ref.current?.contains(target))) return;
1939
+ dismiss();
1940
+ };
1941
+ document.addEventListener("pointerdown", onPointerDown);
1942
+ return () => document.removeEventListener("pointerdown", onPointerDown);
1943
+ }, [open]);
1944
+ }
1945
+
1946
+ // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Popover/Popover.module.css?mds-scoped
1947
+ var Popover_module_default = { "panel": "mds-Popover__panel", "header": "mds-Popover__header", "headerTitle": "mds-Popover__headerTitle", "close": "mds-Popover__close", "closeGlyph": "mds-Popover__closeGlyph", "body": "mds-Popover__body", "footer": "mds-Popover__footer" };
1948
+ var POPOVER_EXIT_MS = 120;
1949
+ var GAP = 8;
1950
+ function Popover({
1951
+ open,
1952
+ onClose,
1953
+ anchorRef,
1954
+ label,
1955
+ placement = "bottom-start",
1956
+ className,
1957
+ children
1958
+ }) {
1959
+ const { mounted, visible } = usePresence(open, POPOVER_EXIT_MS);
1960
+ const panelRef = useOverlay({ open, onClose, lockScroll: false });
1961
+ useAnchoredPosition({ open: mounted, anchorRef, floatingRef: panelRef, placement, gap: GAP });
1962
+ useDismissOnOutside(open, onClose, [panelRef, anchorRef]);
1963
+ if (!mounted) return null;
1964
+ return createPortal(
1965
+ /* @__PURE__ */ jsx(
1966
+ "div",
1967
+ {
1968
+ ref: panelRef,
1969
+ role: "dialog",
1970
+ "aria-label": label,
1971
+ tabIndex: -1,
1972
+ className: cx(Popover_module_default.panel, className),
1973
+ "data-open": visible || void 0,
1974
+ children
1975
+ }
1976
+ ),
1977
+ document.body
1978
+ );
1979
+ }
1980
+ function PopoverHeader({ children, onClose, closeLabel }) {
1981
+ return /* @__PURE__ */ jsxs("div", { className: Popover_module_default.header, children: [
1982
+ /* @__PURE__ */ jsx("h2", { className: Popover_module_default.headerTitle, children }),
1983
+ onClose !== void 0 && /* @__PURE__ */ jsx("button", { type: "button", "aria-label": closeLabel, className: Popover_module_default.close, onClick: onClose, children: /* @__PURE__ */ jsx(CloseGlyph, { className: Popover_module_default.closeGlyph }) })
1984
+ ] });
1985
+ }
1986
+ function PopoverBody({ children }) {
1987
+ return /* @__PURE__ */ jsx("div", { className: Popover_module_default.body, children });
1988
+ }
1989
+ function PopoverFooter({ children }) {
1990
+ return /* @__PURE__ */ jsx("div", { className: Popover_module_default.footer, children });
1991
+ }
1992
+ function useRovingGroup(ref, { selector, orientation = "horizontal" }) {
1993
+ return useCallback(
1994
+ (event) => {
1995
+ const horizontal = orientation !== "vertical";
1996
+ const vertical = orientation !== "horizontal";
1997
+ const forward = horizontal && event.key === "ArrowRight" || vertical && event.key === "ArrowDown";
1998
+ const backward = horizontal && event.key === "ArrowLeft" || vertical && event.key === "ArrowUp";
1999
+ const home = event.key === "Home";
2000
+ const end = event.key === "End";
2001
+ if (!forward && !backward && !home && !end) return;
2002
+ const container = ref.current;
2003
+ if (container === null) return;
2004
+ const items = [...container.querySelectorAll(selector)].filter(
2005
+ (item) => !item.hasAttribute("disabled")
2006
+ );
2007
+ const current = items.indexOf(document.activeElement);
2008
+ if (items.length === 0 || current === -1) return;
2009
+ event.preventDefault();
2010
+ const next = home ? 0 : end ? items.length - 1 : (current + (forward ? 1 : -1) + items.length) % items.length;
2011
+ items[next]?.focus();
2012
+ },
2013
+ [ref, selector, orientation]
2014
+ );
2015
+ }
2016
+
2017
+ // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Menu/Menu.module.css?mds-scoped
2018
+ var Menu_module_default = { "panel": "mds-Menu__panel", "item": "mds-Menu__item", "tone-danger": "mds-Menu__tone-danger" };
2019
+ var MENU_EXIT_MS = 120;
2020
+ var GAP2 = 8;
2021
+ var ITEM_SELECTOR = '[role="menuitem"]';
2022
+ var MenuContext = createContext(null);
2023
+ function Menu({ label, trigger, placement = "bottom-end", className, children }) {
2024
+ const [open, setOpen] = useState(false);
2025
+ const { mounted, visible } = usePresence(open, MENU_EXIT_MS);
2026
+ const triggerRef = useRef(null);
2027
+ const panelRef = useRef(null);
2028
+ const close = () => {
2029
+ setOpen(false);
2030
+ triggerRef.current?.focus();
2031
+ };
2032
+ const dismiss = () => setOpen(false);
2033
+ useAnchoredPosition({ open: mounted, anchorRef: triggerRef, floatingRef: panelRef, placement, gap: GAP2 });
2034
+ useDismissOnOutside(open, dismiss, [panelRef, triggerRef]);
2035
+ const onArrowKeys = useRovingGroup(panelRef, {
2036
+ selector: ITEM_SELECTOR,
2037
+ orientation: "vertical"
2038
+ });
2039
+ useEffect(() => {
2040
+ if (!open) return;
2041
+ const first = panelRef.current?.querySelector(
2042
+ `${ITEM_SELECTOR}:not([disabled])`
2043
+ );
2044
+ first?.focus();
2045
+ }, [open]);
2046
+ const openWithKeyboard = (event) => {
2047
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
2048
+ event.preventDefault();
2049
+ setOpen(true);
2050
+ };
2051
+ const { type: Trigger, props: triggerProps } = trigger;
2052
+ return /* @__PURE__ */ jsxs(MenuContext.Provider, { value: { close }, children: [
2053
+ /* @__PURE__ */ jsx(
2054
+ Trigger,
2055
+ {
2056
+ ...triggerProps,
2057
+ ref: forkRef(triggerRef, triggerProps.ref),
2058
+ "aria-haspopup": "menu",
2059
+ "aria-expanded": open,
2060
+ onClick: (event) => {
2061
+ triggerProps.onClick?.(event);
2062
+ setOpen((v) => !v);
2063
+ },
2064
+ onKeyDown: (event) => {
2065
+ triggerProps.onKeyDown?.(event);
2066
+ openWithKeyboard(event);
2067
+ }
2068
+ }
2069
+ ),
2070
+ mounted && createPortal(
2071
+ /* @__PURE__ */ jsx(
2072
+ "div",
2073
+ {
2074
+ ref: panelRef,
2075
+ role: "menu",
2076
+ "aria-label": label,
2077
+ className: cx(Menu_module_default.panel, className),
2078
+ "data-open": visible || void 0,
2079
+ onKeyDown: (event) => {
2080
+ if (event.key === "Escape") {
2081
+ event.stopPropagation();
2082
+ close();
2083
+ return;
2084
+ }
2085
+ if (event.key === "Tab") {
2086
+ event.preventDefault();
2087
+ close();
2088
+ return;
2089
+ }
2090
+ onArrowKeys(event);
2091
+ },
2092
+ children
2093
+ }
2094
+ ),
2095
+ document.body
2096
+ )
2097
+ ] });
2098
+ }
2099
+ function MenuItem({ onSelect, disabled = false, tone = "default", children }) {
2100
+ const menu = useContext(MenuContext);
2101
+ return /* @__PURE__ */ jsx(
2102
+ "button",
2103
+ {
2104
+ type: "button",
2105
+ role: "menuitem",
2106
+ tabIndex: -1,
2107
+ disabled,
2108
+ className: cx(Menu_module_default.item, Menu_module_default[`tone-${tone}`]),
2109
+ onClick: () => {
2110
+ onSelect();
2111
+ menu?.close();
2112
+ },
2113
+ children
2114
+ }
2115
+ );
2116
+ }
2117
+
2118
+ // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/Tooltip/Tooltip.module.css?mds-scoped
2119
+ var Tooltip_module_default = { "surface": "mds-Tooltip__surface" };
2120
+ var GAP3 = 8;
2121
+ var DEFAULT_DELAY_MS = 400;
2122
+ function Tooltip({
2123
+ content,
2124
+ placement = "top",
2125
+ delayMs = DEFAULT_DELAY_MS,
2126
+ children
2127
+ }) {
2128
+ const id = useId();
2129
+ const [open, setOpen] = useState(false);
2130
+ const anchorRef = useRef(null);
2131
+ const surfaceRef = useRef(null);
2132
+ const timer = useRef(void 0);
2133
+ const show = () => {
2134
+ clearTimeout(timer.current);
2135
+ setOpen(true);
2136
+ };
2137
+ const hide = () => {
2138
+ clearTimeout(timer.current);
2139
+ setOpen(false);
2140
+ };
2141
+ useEffect(() => clearTimeout(timer.current), []);
2142
+ useAnchoredPosition({ open, anchorRef, floatingRef: surfaceRef, placement, gap: GAP3 });
2143
+ useEffect(() => {
2144
+ if (!open) return;
2145
+ const onKeyDown = (event) => {
2146
+ if (event.key === "Escape") hide();
2147
+ };
2148
+ document.addEventListener("keydown", onKeyDown);
2149
+ return () => document.removeEventListener("keydown", onKeyDown);
2150
+ }, [open]);
2151
+ const { type: Trigger, props: triggerProps } = children;
2152
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2153
+ /* @__PURE__ */ jsx(
2154
+ Trigger,
2155
+ {
2156
+ ...triggerProps,
2157
+ ref: forkRef(anchorRef, triggerProps.ref),
2158
+ "aria-describedby": open ? id : triggerProps["aria-describedby"],
2159
+ onPointerEnter: (event) => {
2160
+ triggerProps.onPointerEnter?.(event);
2161
+ if (event.pointerType === "touch") return;
2162
+ clearTimeout(timer.current);
2163
+ timer.current = setTimeout(show, delayMs);
2164
+ },
2165
+ onPointerLeave: (event) => {
2166
+ triggerProps.onPointerLeave?.(event);
2167
+ hide();
2168
+ },
2169
+ onFocus: (event) => {
2170
+ triggerProps.onFocus?.(event);
2171
+ show();
2172
+ },
2173
+ onBlur: (event) => {
2174
+ triggerProps.onBlur?.(event);
2175
+ hide();
2176
+ }
2177
+ }
2178
+ ),
2179
+ open && createPortal(
2180
+ /* @__PURE__ */ jsx("div", { ref: surfaceRef, id, role: "tooltip", className: Tooltip_module_default.surface, children: content }),
2181
+ document.body
2182
+ )
2183
+ ] });
2184
+ }
1910
2185
 
1911
2186
  // mds-cssmod:/home/runner/work/mond-design-system/mond-design-system/packages/react/src/components/ConfirmDialog/ConfirmDialog.module.css?mds-scoped
1912
2187
  var ConfirmDialog_module_default = { "description": "mds-ConfirmDialog__description", "error": "mds-ConfirmDialog__error" };
@@ -2452,7 +2727,7 @@ var distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
2452
2727
  function Lightbox({ open, onClose, src, alt = "", caption, labels }) {
2453
2728
  const [surface, setSurface] = useState(null);
2454
2729
  const [scale, setScale] = useState(MIN_SCALE);
2455
- const [offset, setOffset] = useState(ORIGIN);
2730
+ const [offset2, setOffset] = useState(ORIGIN);
2456
2731
  const points = useRef(/* @__PURE__ */ new Map());
2457
2732
  const from = useRef({ spread: 0, scale: MIN_SCALE, x: 0, y: 0, offset: ORIGIN });
2458
2733
  const [shown, setShown] = useState({ src, open });
@@ -2502,7 +2777,7 @@ function Lightbox({ open, onClose, src, alt = "", caption, labels }) {
2502
2777
  from.current = { ...from.current, spread: distance(first, second), scale };
2503
2778
  return;
2504
2779
  }
2505
- if (first) from.current = { ...from.current, x: first.x, y: first.y, offset };
2780
+ if (first) from.current = { ...from.current, x: first.x, y: first.y, offset: offset2 };
2506
2781
  }
2507
2782
  function onPointerMove(event) {
2508
2783
  if (!points.current.has(event.pointerId)) return;
@@ -2529,12 +2804,12 @@ function Lightbox({ open, onClose, src, alt = "", caption, labels }) {
2529
2804
  function onPointerUp(event) {
2530
2805
  points.current.delete(event.pointerId);
2531
2806
  const [rest] = [...points.current.values()];
2532
- if (rest) from.current = { ...from.current, x: rest.x, y: rest.y, offset };
2807
+ if (rest) from.current = { ...from.current, x: rest.x, y: rest.y, offset: offset2 };
2533
2808
  }
2534
2809
  const vars = {
2535
2810
  "--zoom": String(round(scale)),
2536
- "--pan-x": `${round(offset.x)}px`,
2537
- "--pan-y": `${round(offset.y)}px`
2811
+ "--pan-x": `${round(offset2.x)}px`,
2812
+ "--pan-y": `${round(offset2.y)}px`
2538
2813
  };
2539
2814
  return /* @__PURE__ */ jsxs(
2540
2815
  Overlay,
@@ -2805,31 +3080,7 @@ function Breadcrumb({
2805
3080
  ] }, `${item.label}-${index}`);
2806
3081
  }) }) });
2807
3082
  }
2808
- function useRovingGroup(ref, { selector, orientation = "horizontal" }) {
2809
- return useCallback(
2810
- (event) => {
2811
- const horizontal = orientation !== "vertical";
2812
- const vertical = orientation !== "horizontal";
2813
- const forward = horizontal && event.key === "ArrowRight" || vertical && event.key === "ArrowDown";
2814
- const backward = horizontal && event.key === "ArrowLeft" || vertical && event.key === "ArrowUp";
2815
- const home = event.key === "Home";
2816
- const end = event.key === "End";
2817
- if (!forward && !backward && !home && !end) return;
2818
- const container = ref.current;
2819
- if (container === null) return;
2820
- const items = [...container.querySelectorAll(selector)].filter(
2821
- (item) => !item.hasAttribute("disabled")
2822
- );
2823
- const current = items.indexOf(document.activeElement);
2824
- if (items.length === 0 || current === -1) return;
2825
- event.preventDefault();
2826
- const next = home ? 0 : end ? items.length - 1 : (current + (forward ? 1 : -1) + items.length) % items.length;
2827
- items[next]?.focus();
2828
- },
2829
- [ref, selector, orientation]
2830
- );
2831
- }
2832
3083
 
2833
- export { AppBar, Avatar, AvatarGroup, Badge, Breadcrumb, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, Chip, ChipBar, ChipGroup, ConfirmDialog, Container, CountButton, DataTable, DateTimePicker, Divider, EmptyState, Field, FileDrop, Heading, Icon, IconProvider, ImageCarousel, Inline, Input, Lightbox, Link, ListGroup, ListItem, MediaPlaceholder, Modal, ModalBody, ModalFooter, ModalHeader, OverlayHistoryContext, PasswordInput, ProgressBar, Radio, Screen, ScreenContent, Scroller, SearchField, SegmentedControl, Select, Sheet, SheetBody, SheetFooter, SheetHeader, SideNav, SideNavGroup, SideNavItem, Skeleton, Spinner, Stack, Switch, Tab, TabBar, TabBarAction, TabBarItem, TabList, TabPanel, Tabs, Tag, Text, Textarea, ToastProvider, UploadProgress, VideoPlayer, VisuallyHidden, cx, useFieldContext, useOverlay, usePresence, useRovingGroup, useToast };
3084
+ export { AppBar, Avatar, AvatarGroup, Badge, Breadcrumb, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, Chip, ChipBar, ChipGroup, ConfirmDialog, Container, CountButton, DataTable, DateTimePicker, Divider, EmptyState, Field, FileDrop, Heading, Icon, IconProvider, ImageCarousel, Inline, Input, Lightbox, Link, ListGroup, ListItem, MediaPlaceholder, Menu, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, OverlayHistoryContext, PasswordInput, Popover, PopoverBody, PopoverFooter, PopoverHeader, ProgressBar, Radio, Screen, ScreenContent, Scroller, SegmentedControl, Select, Sheet, SheetBody, SheetFooter, SheetHeader, SideNav, SideNavGroup, SideNavItem, Skeleton, Spinner, Stack, Switch, Tab, TabBar, TabBarAction, TabBarItem, TabList, TabPanel, Tabs, Tag, Text, Textarea, ToastProvider, Tooltip, UploadProgress, VideoPlayer, VisuallyHidden, cx, useFieldContext, useOverlay, usePresence, useRovingGroup, useToast };
2834
3085
  //# sourceMappingURL=index.js.map
2835
3086
  //# sourceMappingURL=index.js.map