@seedgrid/fe-components 2026.3.19 → 2026.3.26

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 (172) hide show
  1. package/dist/buttons/SgFloatActionButton.d.ts.map +1 -1
  2. package/dist/buttons/SgFloatActionButton.js +5 -26
  3. package/dist/buttons/SgSplitButton.d.ts.map +1 -1
  4. package/dist/buttons/SgSplitButton.js +3 -1
  5. package/dist/buttons/fab-helpers.d.ts +6 -0
  6. package/dist/buttons/fab-helpers.d.ts.map +1 -0
  7. package/dist/buttons/fab-helpers.js +29 -0
  8. package/dist/commons/SgAvatar.d.ts.map +1 -1
  9. package/dist/commons/SgAvatar.js +6 -3
  10. package/dist/commons/SgBadge.d.ts.map +1 -1
  11. package/dist/commons/SgBadge.js +5 -2
  12. package/dist/commons/SgToast.d.ts.map +1 -1
  13. package/dist/commons/SgToast.js +3 -1
  14. package/dist/commons/SgToaster.d.ts.map +1 -1
  15. package/dist/commons/SgToaster.js +3 -1
  16. package/dist/environment/SgEnvironmentProvider.d.ts.map +1 -1
  17. package/dist/environment/SgEnvironmentProvider.js +10 -15
  18. package/dist/environment/persistent-state.d.ts +22 -0
  19. package/dist/environment/persistent-state.d.ts.map +1 -0
  20. package/dist/environment/persistent-state.js +33 -0
  21. package/dist/gadgets/calendar/SgCalendar.d.ts.map +1 -1
  22. package/dist/gadgets/calendar/SgCalendar.js +5 -23
  23. package/dist/gadgets/clock/SgClock.d.ts.map +1 -1
  24. package/dist/gadgets/clock/SgClock.js +12 -10
  25. package/dist/gadgets/clock/themes/SgClockThemePicker.d.ts +2 -1
  26. package/dist/gadgets/clock/themes/SgClockThemePicker.d.ts.map +1 -1
  27. package/dist/gadgets/clock/themes/SgClockThemePicker.js +23 -28
  28. package/dist/gadgets/clock/themes/search.d.ts +9 -0
  29. package/dist/gadgets/clock/themes/search.d.ts.map +1 -0
  30. package/dist/gadgets/clock/themes/search.js +15 -0
  31. package/dist/gadgets/gauge/SgLinearGauge.d.ts.map +1 -1
  32. package/dist/gadgets/gauge/SgLinearGauge.js +39 -28
  33. package/dist/gadgets/gauge/SgRadialGauge.d.ts.map +1 -1
  34. package/dist/gadgets/gauge/SgRadialGauge.js +44 -37
  35. package/dist/gadgets/gauge/math.d.ts +90 -0
  36. package/dist/gadgets/gauge/math.d.ts.map +1 -0
  37. package/dist/gadgets/gauge/math.js +81 -0
  38. package/dist/gadgets/qr-code/SgQRCode.d.ts.map +1 -1
  39. package/dist/gadgets/qr-code/SgQRCode.js +3 -1
  40. package/dist/i18n/en-US.d.ts.map +1 -1
  41. package/dist/i18n/en-US.js +97 -1
  42. package/dist/i18n/es.d.ts.map +1 -1
  43. package/dist/i18n/es.js +153 -57
  44. package/dist/i18n/fr.d.ts +3 -0
  45. package/dist/i18n/fr.d.ts.map +1 -0
  46. package/dist/i18n/fr.js +206 -0
  47. package/dist/i18n/index.d.ts +5 -1
  48. package/dist/i18n/index.d.ts.map +1 -1
  49. package/dist/i18n/index.js +50 -14
  50. package/dist/i18n/pt-BR.d.ts.map +1 -1
  51. package/dist/i18n/pt-BR.js +97 -1
  52. package/dist/i18n/pt-PT.d.ts.map +1 -1
  53. package/dist/i18n/pt-PT.js +97 -1
  54. package/dist/index.d.ts +12 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +10 -2
  57. package/dist/inputs/SgAutocomplete.d.ts +1 -1
  58. package/dist/inputs/SgAutocomplete.d.ts.map +1 -1
  59. package/dist/inputs/SgAutocomplete.js +7 -4
  60. package/dist/inputs/SgCheckboxGroup.d.ts +2 -6
  61. package/dist/inputs/SgCheckboxGroup.d.ts.map +1 -1
  62. package/dist/inputs/SgCheckboxGroup.js +6 -6
  63. package/dist/inputs/SgCombobox.d.ts.map +1 -1
  64. package/dist/inputs/SgCombobox.js +11 -2
  65. package/dist/inputs/SgInputBirthDate.d.ts.map +1 -1
  66. package/dist/inputs/SgInputBirthDate.js +6 -1
  67. package/dist/inputs/SgInputCNPJ.d.ts +3 -1
  68. package/dist/inputs/SgInputCNPJ.d.ts.map +1 -1
  69. package/dist/inputs/SgInputCNPJ.js +4 -3
  70. package/dist/inputs/SgInputCPF.d.ts +3 -1
  71. package/dist/inputs/SgInputCPF.d.ts.map +1 -1
  72. package/dist/inputs/SgInputCPF.js +8 -3
  73. package/dist/inputs/SgInputCPFCNPJ.d.ts +3 -1
  74. package/dist/inputs/SgInputCPFCNPJ.d.ts.map +1 -1
  75. package/dist/inputs/SgInputCPFCNPJ.js +8 -3
  76. package/dist/inputs/SgInputCurrency.d.ts +3 -7
  77. package/dist/inputs/SgInputCurrency.d.ts.map +1 -1
  78. package/dist/inputs/SgInputCurrency.js +5 -2
  79. package/dist/inputs/SgInputDate.d.ts.map +1 -1
  80. package/dist/inputs/SgInputDate.js +6 -1
  81. package/dist/inputs/SgInputEmail.d.ts.map +1 -1
  82. package/dist/inputs/SgInputEmail.js +1 -1
  83. package/dist/inputs/SgInputNumber.d.ts +3 -7
  84. package/dist/inputs/SgInputNumber.d.ts.map +1 -1
  85. package/dist/inputs/SgInputNumber.js +5 -2
  86. package/dist/inputs/SgInputOTP.d.ts +5 -12
  87. package/dist/inputs/SgInputOTP.d.ts.map +1 -1
  88. package/dist/inputs/SgInputOTP.js +7 -4
  89. package/dist/inputs/SgInputPassword.d.ts.map +1 -1
  90. package/dist/inputs/SgInputPassword.js +1 -1
  91. package/dist/inputs/SgInputPhone.d.ts +3 -1
  92. package/dist/inputs/SgInputPhone.d.ts.map +1 -1
  93. package/dist/inputs/SgInputPhone.js +2 -1
  94. package/dist/inputs/SgInputPostalCode.d.ts.map +1 -1
  95. package/dist/inputs/SgInputPostalCode.js +2 -1
  96. package/dist/inputs/SgInputSelect.d.ts +4 -2
  97. package/dist/inputs/SgInputSelect.d.ts.map +1 -1
  98. package/dist/inputs/SgInputSelect.js +38 -3
  99. package/dist/inputs/SgInputText.d.ts +3 -7
  100. package/dist/inputs/SgInputText.d.ts.map +1 -1
  101. package/dist/inputs/SgInputText.js +5 -2
  102. package/dist/inputs/SgInputTextArea.d.ts +4 -2
  103. package/dist/inputs/SgInputTextArea.d.ts.map +1 -1
  104. package/dist/inputs/SgInputTextArea.js +37 -2
  105. package/dist/inputs/SgOrderList.d.ts +3 -1
  106. package/dist/inputs/SgOrderList.d.ts.map +1 -1
  107. package/dist/inputs/SgOrderList.js +19 -3
  108. package/dist/inputs/SgPickList.d.ts +3 -1
  109. package/dist/inputs/SgPickList.d.ts.map +1 -1
  110. package/dist/inputs/SgPickList.js +20 -4
  111. package/dist/inputs/SgRadioGroup.d.ts +2 -6
  112. package/dist/inputs/SgRadioGroup.d.ts.map +1 -1
  113. package/dist/inputs/SgRadioGroup.js +6 -6
  114. package/dist/inputs/SgRating.d.ts +2 -10
  115. package/dist/inputs/SgRating.d.ts.map +1 -1
  116. package/dist/inputs/SgRating.js +6 -3
  117. package/dist/inputs/SgSlider.d.ts +8 -2
  118. package/dist/inputs/SgSlider.d.ts.map +1 -1
  119. package/dist/inputs/SgSlider.js +62 -10
  120. package/dist/inputs/SgStepperInput.d.ts +8 -2
  121. package/dist/inputs/SgStepperInput.d.ts.map +1 -1
  122. package/dist/inputs/SgStepperInput.js +62 -8
  123. package/dist/inputs/SgTextEditor.d.ts +3 -1
  124. package/dist/inputs/SgTextEditor.d.ts.map +1 -1
  125. package/dist/inputs/SgTextEditor.js +24 -11
  126. package/dist/inputs/SgToggleSwitch.d.ts +3 -7
  127. package/dist/inputs/SgToggleSwitch.d.ts.map +1 -1
  128. package/dist/inputs/SgToggleSwitch.js +6 -3
  129. package/dist/layout/SgBreadcrumb.d.ts.map +1 -1
  130. package/dist/layout/SgBreadcrumb.js +7 -3
  131. package/dist/layout/SgCard.d.ts.map +1 -1
  132. package/dist/layout/SgCard.js +3 -1
  133. package/dist/layout/SgCarousel.d.ts.map +1 -1
  134. package/dist/layout/SgCarousel.js +3 -1
  135. package/dist/layout/SgExpandablePanel.d.ts.map +1 -1
  136. package/dist/layout/SgExpandablePanel.js +3 -1
  137. package/dist/layout/SgMenu.d.ts.map +1 -1
  138. package/dist/layout/SgMenu.js +173 -297
  139. package/dist/layout/SgPageControl.d.ts.map +1 -1
  140. package/dist/layout/SgPageControl.js +7 -3
  141. package/dist/layout/SgToolBar.d.ts.map +1 -1
  142. package/dist/layout/SgToolBar.js +19 -55
  143. package/dist/layout/SgTreeView.d.ts.map +1 -1
  144. package/dist/layout/SgTreeView.js +7 -3
  145. package/dist/layout/drag-position.d.ts +7 -0
  146. package/dist/layout/drag-position.d.ts.map +1 -0
  147. package/dist/layout/drag-position.js +30 -0
  148. package/dist/layout/menu-logic.d.ts +187 -0
  149. package/dist/layout/menu-logic.d.ts.map +1 -0
  150. package/dist/layout/menu-logic.js +349 -0
  151. package/dist/layout/toolbar-logic.d.ts +26 -0
  152. package/dist/layout/toolbar-logic.d.ts.map +1 -0
  153. package/dist/layout/toolbar-logic.js +38 -0
  154. package/dist/menus/SgDockMenu.d.ts.map +1 -1
  155. package/dist/menus/SgDockMenu.js +44 -120
  156. package/dist/menus/dock-menu-logic.d.ts +50 -0
  157. package/dist/menus/dock-menu-logic.d.ts.map +1 -0
  158. package/dist/menus/dock-menu-logic.js +113 -0
  159. package/dist/overlay/SgDialog.d.ts.map +1 -1
  160. package/dist/overlay/SgDialog.js +4 -2
  161. package/dist/overlay/SgPopup.d.ts.map +1 -1
  162. package/dist/overlay/SgPopup.js +4 -1
  163. package/dist/rhf.d.ts +8 -3
  164. package/dist/rhf.d.ts.map +1 -1
  165. package/dist/rhf.js +18 -1
  166. package/dist/sandbox.cjs +60 -60
  167. package/dist/wizard/SgWizard.d.ts.map +1 -1
  168. package/dist/wizard/SgWizard.js +20 -32
  169. package/dist/wizard/logic.d.ts +9 -0
  170. package/dist/wizard/logic.d.ts.map +1 -0
  171. package/dist/wizard/logic.js +20 -0
  172. package/package.json +78 -76
@@ -2,62 +2,19 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { t, useComponentsI18n } from "../i18n";
5
+ import { buildDockMenuStorageKey, parseStoredPanelDragPosition } from "../layout/drag-position";
6
+ import { buildDockMenuContainerStyle, buildDockMenuContextMenuState, buildDockMenuItemMotion, buildDockMenuLabelStyle, buildDockMenuLayout } from "./dock-menu-logic";
5
7
  import { useHasSgEnvironmentProvider, useSgPersistence } from "../environment/SgEnvironmentProvider";
6
8
  /* ── constants ── */
7
- const EDGE = 24;
8
- const POS_CSS = {
9
- "left-top": { top: EDGE, left: EDGE },
10
- "left-center": { left: EDGE, top: "50%" },
11
- "left-bottom": { bottom: EDGE, left: EDGE },
12
- "center-top": { top: EDGE, left: "50%" },
13
- "center-bottom": { bottom: EDGE, left: "50%" },
14
- "right-top": { top: EDGE, right: EDGE },
15
- "right-center": { right: EDGE, top: "50%" },
16
- "right-bottom": { bottom: EDGE, right: EDGE },
17
- };
18
- const CENTER_TX = {
19
- "left-center": "translateY(-50%)",
20
- "right-center": "translateY(-50%)",
21
- "center-top": "translateX(-50%)",
22
- "center-bottom": "translateX(-50%)",
23
- };
24
9
  const ELEV_CLS = {
25
10
  none: "",
26
11
  sm: "shadow-sm",
27
12
  md: "shadow-md shadow-black/15",
28
13
  lg: "shadow-lg shadow-black/20",
29
14
  };
30
- function getLiftDirection(position, orientation) {
31
- if (orientation === "horizontal") {
32
- return position.includes("bottom") ? -1 : 1;
33
- }
34
- return position.startsWith("left") ? 1 : -1;
35
- }
36
15
  function clamp(value, min, max) {
37
16
  return Math.min(Math.max(value, min), max);
38
17
  }
39
- function parseStoredDragPosition(raw) {
40
- const value = typeof raw === "string" ? (() => {
41
- try {
42
- return JSON.parse(raw);
43
- }
44
- catch {
45
- return null;
46
- }
47
- })() : raw;
48
- if (!value ||
49
- typeof value !== "object" ||
50
- typeof value.x !== "number" ||
51
- typeof value.y !== "number" ||
52
- !Number.isFinite(value.x) ||
53
- !Number.isFinite(value.y)) {
54
- return null;
55
- }
56
- return {
57
- x: value.x,
58
- y: value.y
59
- };
60
- }
61
18
  /* ── orientation helper ── */
62
19
  function getOrientation(position) {
63
20
  if (position === "center-top" || position === "center-bottom")
@@ -82,14 +39,11 @@ export function SgDockMenu(props) {
82
39
  const dragStart = React.useRef(null);
83
40
  const dragMoved = React.useRef(false);
84
41
  const containerRef = React.useRef(null);
85
- const orientation = getOrientation(position);
86
- const liftDirection = getLiftDirection(position, orientation);
42
+ const { orientation, liftDirection } = buildDockMenuLayout(position);
87
43
  const crossPadding = Math.max(8, Math.round(gap * 0.6));
88
44
  const edgePadding = Math.max(Math.round(gap * 2.2), Math.round(itemSize * 0.45));
89
45
  const isAbsolutePosition = style?.position === "absolute";
90
- const storageKey = dragId
91
- ? `sg-dockmenu-pos:${dragId}:${isAbsolutePosition ? "parent" : "viewport"}`
92
- : null;
46
+ const storageKey = buildDockMenuStorageKey(dragId, isAbsolutePosition);
93
47
  const itemSurfaceColor = "rgb(var(--sg-muted-surface, 241 245 249) / 0.92)";
94
48
  const itemSurfaceHoverColor = "rgb(var(--sg-primary-500, 34 197 94) / 0.18)";
95
49
  const itemIconColor = "rgb(var(--sg-text, 15 23 42))";
@@ -103,7 +57,7 @@ export function SgDockMenu(props) {
103
57
  const loaded = await loadPersistedState(storageKey);
104
58
  if (loaded === null || loaded === undefined)
105
59
  return null;
106
- const parsed = parseStoredDragPosition(loaded);
60
+ const parsed = parseStoredPanelDragPosition(loaded);
107
61
  if (!parsed) {
108
62
  await clearPersistedState(storageKey);
109
63
  return null;
@@ -118,7 +72,7 @@ export function SgDockMenu(props) {
118
72
  const raw = localStorage.getItem(storageKey);
119
73
  if (!raw)
120
74
  return null;
121
- const parsed = parseStoredDragPosition(raw);
75
+ const parsed = parseStoredPanelDragPosition(raw);
122
76
  if (!parsed) {
123
77
  localStorage.removeItem(storageKey);
124
78
  return null;
@@ -285,15 +239,23 @@ export function SgDockMenu(props) {
285
239
  window.addEventListener("pointercancel", handleUp);
286
240
  }, [enableDragDrop, getDragBounds, saveStoredPosition, storageKey]);
287
241
  const handleContextMenu = React.useCallback((event) => {
288
- if (!enableDragDrop || !dragId)
289
- return;
290
- if (!hasStoredPosRef.current)
242
+ const contextState = buildDockMenuContextMenuState({
243
+ enableDragDrop,
244
+ dragId,
245
+ hasStoredPosition: hasStoredPosRef.current
246
+ });
247
+ if (!contextState.canOpenContextMenu)
291
248
  return;
292
249
  event.preventDefault();
293
250
  setMenuOpen(true);
294
251
  }, [enableDragDrop, dragId]);
295
252
  const handleResetPosition = React.useCallback(() => {
296
- if (!storageKey)
253
+ const contextState = buildDockMenuContextMenuState({
254
+ enableDragDrop,
255
+ dragId,
256
+ hasStoredPosition: hasStoredPosRef.current
257
+ });
258
+ if (!contextState.canResetPosition || !storageKey)
297
259
  return;
298
260
  void clearStoredPosition();
299
261
  dragPosRef.current = null;
@@ -301,7 +263,7 @@ export function SgDockMenu(props) {
301
263
  setMenuOpen(false);
302
264
  hasStoredPosRef.current = false;
303
265
  dragMoved.current = false;
304
- }, [clearStoredPosition, storageKey]);
266
+ }, [clearStoredPosition, dragId, enableDragDrop, storageKey]);
305
267
  const handleItemClick = React.useCallback((item) => {
306
268
  if (item.disabled)
307
269
  return;
@@ -311,38 +273,17 @@ export function SgDockMenu(props) {
311
273
  }
312
274
  item.onClick?.();
313
275
  }, []);
314
- // Container position
315
- const posStyle = {
316
- position: "fixed",
317
- ...POS_CSS[position],
318
- zIndex
319
- };
320
- if (enableDragDrop && dragPos) {
321
- posStyle.left = dragPos.x;
322
- posStyle.top = dragPos.y;
323
- delete posStyle.right;
324
- delete posStyle.bottom;
325
- }
326
- if (offset?.x) {
327
- if (posStyle.right !== undefined)
328
- posStyle.right = (typeof posStyle.right === "number" ? posStyle.right : 0) - offset.x;
329
- else if (posStyle.left !== undefined)
330
- posStyle.left = (typeof posStyle.left === "number" ? posStyle.left : 0) + offset.x;
331
- }
332
- if (offset?.y) {
333
- if (posStyle.bottom !== undefined)
334
- posStyle.bottom = (typeof posStyle.bottom === "number" ? posStyle.bottom : 0) - offset.y;
335
- else if (posStyle.top !== undefined)
336
- posStyle.top = (typeof posStyle.top === "number" ? posStyle.top : 0) + offset.y;
337
- }
338
- const txParts = [];
339
- const ctx = !(enableDragDrop && dragPos) ? CENTER_TX[position] : undefined;
340
- if (ctx)
341
- txParts.push(ctx);
276
+ const containerStyleState = buildDockMenuContainerStyle({
277
+ position,
278
+ zIndex,
279
+ enableDragDrop,
280
+ dragPos,
281
+ offset
282
+ });
342
283
  return (_jsxs(_Fragment, { children: [_jsx("div", { ref: containerRef, id: id, className: `sg-dock ${className} ${ELEV_CLS[elevation]}`, style: {
343
- ...posStyle,
284
+ ...containerStyleState.style,
344
285
  ...style,
345
- transform: txParts.join(" "),
286
+ transform: containerStyleState.transform,
346
287
  cursor: enableDragDrop ? (isDragging ? "grabbing" : "grab") : "default",
347
288
  ...(enableDragDrop ? { touchAction: "none" } : {}),
348
289
  }, onPointerDown: handlePointerDown, onContextMenu: handleContextMenu, children: _jsx("div", { className: "sg-dock-container", style: {
@@ -370,41 +311,28 @@ export function SgDockMenu(props) {
370
311
  transition: "all 0.3s ease",
371
312
  }, children: items.map((item, index) => {
372
313
  const isHovered = hoveredIndex === index;
373
- const hasMagnifyCurve = magnify && hoveredIndex !== null;
374
- const distance = hasMagnifyCurve ? Math.abs(index - hoveredIndex) : Number.POSITIVE_INFINITY;
375
- const influence = hasMagnifyCurve ? Math.max(0, 1 - distance / 3) : 0;
376
- const curve = influence * influence;
377
- const scale = 1 + (magnifyScale - 1) * curve;
378
- const liftPx = curve * Math.min(itemSize * 0.4, 18);
379
- const spreadBase = Math.max(0, itemSize * (magnifyScale - 1) * 0.68 + gap * 0.12);
380
- const spreadCurve = hasMagnifyCurve && distance > 0
381
- ? Math.max(0, 1 - (distance - 1) * 0.1)
382
- : 0;
383
- const spreadSign = hasMagnifyCurve && hoveredIndex !== null ? Math.sign(index - hoveredIndex) : 0;
384
- const spreadPx = spreadSign === 0 ? 0 : spreadSign * spreadBase * spreadCurve;
385
- const translateX = (orientation === "vertical" ? liftDirection * liftPx : 0) +
386
- (orientation === "horizontal" ? spreadPx : 0);
387
- const translateY = (orientation === "horizontal" ? liftDirection * liftPx : 0) +
388
- (orientation === "vertical" ? spreadPx : 0);
389
- const transformOrigin = orientation === "horizontal"
390
- ? liftDirection < 0
391
- ? "50% 100%"
392
- : "50% 0%"
393
- : liftDirection > 0
394
- ? "0% 50%"
395
- : "100% 50%";
314
+ const motion = buildDockMenuItemMotion({
315
+ index,
316
+ hoveredIndex,
317
+ magnify,
318
+ magnifyScale,
319
+ itemSize,
320
+ gap,
321
+ orientation,
322
+ liftDirection
323
+ });
396
324
  return (_jsxs("div", { "data-dock-item": true, className: `sg-dock-item ${itemClassName} ${item.className ?? ""}`, style: {
397
325
  position: "relative",
398
326
  width: itemSize,
399
327
  height: itemSize,
400
- transform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
401
- transformOrigin,
328
+ transform: `translate3d(${motion.translateX}px, ${motion.translateY}px, 0) scale(${motion.scale})`,
329
+ transformOrigin: motion.transformOrigin,
402
330
  transition: "transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)",
403
331
  willChange: "transform",
404
332
  cursor: item.disabled ? "not-allowed" : "pointer",
405
333
  opacity: item.disabled ? 0.5 : 1,
406
- zIndex: isHovered ? 3 : curve > 0 ? 2 : 1,
407
- }, onMouseEnter: () => setHoveredIndex(index), onMouseLeave: () => setHoveredIndex(null), onClick: () => handleItemClick(item), children: [_jsx("div", { className: "sg-dock-item-icon", style: {
334
+ zIndex: motion.zIndex,
335
+ }, onMouseEnter: () => setHoveredIndex(index), onMouseLeave: () => setHoveredIndex(null), children: [_jsx("button", { type: "button", className: "sg-dock-item-icon focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35", style: {
408
336
  width: "100%",
409
337
  height: "100%",
410
338
  display: "flex",
@@ -418,7 +346,7 @@ export function SgDockMenu(props) {
418
346
  e.currentTarget.style.backgroundColor = itemSurfaceHoverColor;
419
347
  }, onMouseLeave: (e) => {
420
348
  e.currentTarget.style.backgroundColor = itemSurfaceColor;
421
- }, children: item.icon }), item.badge && (_jsx("div", { className: "sg-dock-item-badge", style: {
349
+ }, onClick: () => handleItemClick(item), "aria-label": item.label, title: item.label, disabled: item.disabled, children: item.icon }), item.badge && (_jsx("div", { className: "sg-dock-item-badge", style: {
422
350
  position: "absolute",
423
351
  top: -4,
424
352
  right: -4,
@@ -436,11 +364,7 @@ export function SgDockMenu(props) {
436
364
  boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
437
365
  }, children: item.badge })), showLabels && isHovered && (_jsx("div", { className: "sg-dock-item-label", style: {
438
366
  position: "absolute",
439
- ...(orientation === "horizontal"
440
- ? { bottom: "100%", left: "50%", transform: "translateX(-50%)", marginBottom: 8 }
441
- : position.startsWith("left")
442
- ? { left: "100%", top: "50%", transform: "translateY(-50%)", marginLeft: 8 }
443
- : { right: "100%", top: "50%", transform: "translateY(-50%)", marginRight: 8 }),
367
+ ...buildDockMenuLabelStyle(orientation, position),
444
368
  backgroundColor: tooltipBgColor,
445
369
  color: tooltipTextColor,
446
370
  padding: "4px 8px",
@@ -0,0 +1,50 @@
1
+ import type * as React from "react";
2
+ import type { SgDockMenuOrientation, SgDockMenuPosition } from "./SgDockMenu";
3
+ export declare function resolveDockMenuOrientation(position: SgDockMenuPosition): SgDockMenuOrientation;
4
+ export declare function resolveDockMenuLiftDirection(position: SgDockMenuPosition, orientation: SgDockMenuOrientation): number;
5
+ export declare function buildDockMenuLayout(position: SgDockMenuPosition): {
6
+ orientation: SgDockMenuOrientation;
7
+ liftDirection: number;
8
+ };
9
+ export declare function buildDockMenuItemMotion(args: {
10
+ index: number;
11
+ hoveredIndex: number | null;
12
+ magnify: boolean;
13
+ magnifyScale: number;
14
+ itemSize: number;
15
+ gap: number;
16
+ orientation: SgDockMenuOrientation;
17
+ liftDirection: number;
18
+ }): {
19
+ scale: number;
20
+ translateX: number;
21
+ translateY: number;
22
+ transformOrigin: string;
23
+ zIndex: number;
24
+ };
25
+ export declare function buildDockMenuLabelStyle(orientation: SgDockMenuOrientation, position: SgDockMenuPosition): React.CSSProperties;
26
+ export declare function buildDockMenuContainerStyle(args: {
27
+ position: SgDockMenuPosition;
28
+ zIndex: number;
29
+ enableDragDrop: boolean;
30
+ dragPos: {
31
+ x: number;
32
+ y: number;
33
+ } | null;
34
+ offset?: {
35
+ x?: number;
36
+ y?: number;
37
+ };
38
+ }): {
39
+ style: React.CSSProperties;
40
+ transform: string;
41
+ };
42
+ export declare function buildDockMenuContextMenuState(args: {
43
+ enableDragDrop: boolean;
44
+ dragId?: string;
45
+ hasStoredPosition: boolean;
46
+ }): {
47
+ canOpenContextMenu: boolean;
48
+ canResetPosition: boolean;
49
+ };
50
+ //# sourceMappingURL=dock-menu-logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dock-menu-logic.d.ts","sourceRoot":"","sources":["../../src/menus/dock-menu-logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE9E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,kBAAkB,GAAG,qBAAqB,CAI9F;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,kBAAkB,EAC5B,WAAW,EAAE,qBAAqB,GACjC,MAAM,CAKR;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,GAAG;IACjE,WAAW,EAAE,qBAAqB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAMA;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,qBAAqB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG;IACF,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CAsCA;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,qBAAqB,EAClC,QAAQ,EAAE,kBAAkB,GAC3B,KAAK,CAAC,aAAa,CAUrB;AAsBD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA0BpD;AAGD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG;IACF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAMA"}
@@ -0,0 +1,113 @@
1
+ export function resolveDockMenuOrientation(position) {
2
+ if (position === "center-top" || position === "center-bottom")
3
+ return "horizontal";
4
+ if (position === "left-center" || position === "right-center")
5
+ return "vertical";
6
+ return "horizontal";
7
+ }
8
+ export function resolveDockMenuLiftDirection(position, orientation) {
9
+ if (orientation === "horizontal") {
10
+ return position.includes("bottom") ? -1 : 1;
11
+ }
12
+ return position.startsWith("left") ? 1 : -1;
13
+ }
14
+ export function buildDockMenuLayout(position) {
15
+ const orientation = resolveDockMenuOrientation(position);
16
+ return {
17
+ orientation,
18
+ liftDirection: resolveDockMenuLiftDirection(position, orientation)
19
+ };
20
+ }
21
+ export function buildDockMenuItemMotion(args) {
22
+ const { index, hoveredIndex, magnify, magnifyScale, itemSize, gap, orientation, liftDirection } = args;
23
+ const isHovered = hoveredIndex === index;
24
+ const hasMagnifyCurve = magnify && hoveredIndex !== null;
25
+ const distance = hasMagnifyCurve ? Math.abs(index - hoveredIndex) : Number.POSITIVE_INFINITY;
26
+ const influence = hasMagnifyCurve ? Math.max(0, 1 - distance / 3) : 0;
27
+ const curve = influence * influence;
28
+ const scale = 1 + (magnifyScale - 1) * curve;
29
+ const liftPx = curve * Math.min(itemSize * 0.4, 18);
30
+ const spreadBase = Math.max(0, itemSize * (magnifyScale - 1) * 0.68 + gap * 0.12);
31
+ const spreadCurve = hasMagnifyCurve && distance > 0 ? Math.max(0, 1 - (distance - 1) * 0.1) : 0;
32
+ const spreadSign = hasMagnifyCurve && hoveredIndex !== null ? Math.sign(index - hoveredIndex) : 0;
33
+ const spreadPx = spreadSign === 0 ? 0 : spreadSign * spreadBase * spreadCurve;
34
+ const translateX = (orientation === "vertical" ? liftDirection * liftPx : 0) +
35
+ (orientation === "horizontal" ? spreadPx : 0);
36
+ const translateY = (orientation === "horizontal" ? liftDirection * liftPx : 0) +
37
+ (orientation === "vertical" ? spreadPx : 0);
38
+ const transformOrigin = orientation === "horizontal"
39
+ ? liftDirection < 0
40
+ ? "50% 100%"
41
+ : "50% 0%"
42
+ : liftDirection > 0
43
+ ? "0% 50%"
44
+ : "100% 50%";
45
+ return {
46
+ scale,
47
+ translateX,
48
+ translateY,
49
+ transformOrigin,
50
+ zIndex: isHovered ? 3 : curve > 0 ? 2 : 1
51
+ };
52
+ }
53
+ export function buildDockMenuLabelStyle(orientation, position) {
54
+ if (orientation === "horizontal") {
55
+ return { bottom: "100%", left: "50%", transform: "translateX(-50%)", marginBottom: 8 };
56
+ }
57
+ if (position.startsWith("left")) {
58
+ return { left: "100%", top: "50%", transform: "translateY(-50%)", marginLeft: 8 };
59
+ }
60
+ return { right: "100%", top: "50%", transform: "translateY(-50%)", marginRight: 8 };
61
+ }
62
+ const DOCK_EDGE = 24;
63
+ const DOCK_POS_CSS = {
64
+ "left-top": { top: DOCK_EDGE, left: DOCK_EDGE },
65
+ "left-center": { left: DOCK_EDGE, top: "50%" },
66
+ "left-bottom": { bottom: DOCK_EDGE, left: DOCK_EDGE },
67
+ "center-top": { top: DOCK_EDGE, left: "50%" },
68
+ "center-bottom": { bottom: DOCK_EDGE, left: "50%" },
69
+ "right-top": { top: DOCK_EDGE, right: DOCK_EDGE },
70
+ "right-center": { right: DOCK_EDGE, top: "50%" },
71
+ "right-bottom": { bottom: DOCK_EDGE, right: DOCK_EDGE }
72
+ };
73
+ const DOCK_CENTER_TX = {
74
+ "left-center": "translateY(-50%)",
75
+ "right-center": "translateY(-50%)",
76
+ "center-top": "translateX(-50%)",
77
+ "center-bottom": "translateX(-50%)"
78
+ };
79
+ export function buildDockMenuContainerStyle(args) {
80
+ const { position, zIndex, enableDragDrop, dragPos, offset } = args;
81
+ const style = {
82
+ position: "fixed",
83
+ ...DOCK_POS_CSS[position],
84
+ zIndex
85
+ };
86
+ if (enableDragDrop && dragPos) {
87
+ style.left = dragPos.x;
88
+ style.top = dragPos.y;
89
+ delete style.right;
90
+ delete style.bottom;
91
+ }
92
+ if (offset?.x) {
93
+ if (style.right !== undefined)
94
+ style.right = (typeof style.right === "number" ? style.right : 0) - offset.x;
95
+ else if (style.left !== undefined)
96
+ style.left = (typeof style.left === "number" ? style.left : 0) + offset.x;
97
+ }
98
+ if (offset?.y) {
99
+ if (style.bottom !== undefined)
100
+ style.bottom = (typeof style.bottom === "number" ? style.bottom : 0) - offset.y;
101
+ else if (style.top !== undefined)
102
+ style.top = (typeof style.top === "number" ? style.top : 0) + offset.y;
103
+ }
104
+ const transform = !(enableDragDrop && dragPos) ? (DOCK_CENTER_TX[position] ?? "") : "";
105
+ return { style, transform };
106
+ }
107
+ export function buildDockMenuContextMenuState(args) {
108
+ const canOpenContextMenu = Boolean(args.enableDragDrop && args.dragId && args.hasStoredPosition);
109
+ return {
110
+ canOpenContextMenu,
111
+ canResetPosition: canOpenContextMenu
112
+ };
113
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"SgDialog.d.ts","sourceRoot":"","sources":["../../src/overlay/SgDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,WAAW,GACX,SAAS,GACT,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,OAAO,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC3E,gCAAgC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAsRF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,4BA4QtD;yBA5Qe,QAAQ"}
1
+ {"version":3,"file":"SgDialog.d.ts","sourceRoot":"","sources":["../../src/overlay/SgDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,WAAW,GACX,SAAS,GACT,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,OAAO,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC3E,gCAAgC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAsRF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,4BA6QtD;yBA7Qe,QAAQ"}
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { createPortal } from "react-dom";
5
+ import { t, useComponentsI18n } from "../i18n";
5
6
  function cn(...parts) {
6
7
  return parts.filter(Boolean).join(" ");
7
8
  }
@@ -263,6 +264,7 @@ function resolveCustomSurfacePalette(backgroundColor) {
263
264
  };
264
265
  }
265
266
  export function SgDialog(props) {
267
+ const i18n = useComponentsI18n();
266
268
  const { open: openProp, onOpenChange, defaultOpen = false, title, subtitle, leading, trailing, children, footer, size = "md", severity = "plain", animation = "zoom", transitionMs = 160, autoCloseMs, className, style, customColor, elevation, shadow, showTopAccent = true, overlayClassName, contentClassName, headerClassName, bodyClassName, footerClassName, closeable = true, onClose, closeOnOverlayClick = true, closeOnEsc = true, lockBodyScroll = true, initialFocusRef, restoreFocus = true, ariaLabel } = props;
267
269
  const isControlled = openProp !== undefined;
268
270
  const [openUncontrolled, setOpenUncontrolled] = React.useState(defaultOpen);
@@ -374,7 +376,7 @@ export function SgDialog(props) {
374
376
  return null;
375
377
  if (!present)
376
378
  return null;
377
- const a11yLabel = ariaLabel ?? (typeof title === "string" ? title : undefined) ?? "Dialog";
379
+ const a11yLabel = ariaLabel ?? (typeof title === "string" ? title : undefined) ?? t(i18n, "components.dialog.ariaLabel");
378
380
  const overlayBase = "fixed inset-0 bg-black/60 backdrop-blur-[1px] transition-opacity";
379
381
  const overlayState = entered ? "opacity-100" : "opacity-0";
380
382
  const contentBase = "w-full rounded-2xl bg-background text-foreground shadow-2xl border border-border " +
@@ -396,7 +398,7 @@ export function SgDialog(props) {
396
398
  ...(customPalette ? { color: customPalette.foreground, borderColor: customPalette.border } : {}),
397
399
  ...(resolvedShadow !== undefined ? { boxShadow: resolvedShadow } : {})
398
400
  };
399
- return createPortal(_jsxs("div", { className: cn("fixed inset-0 z-[1000]", className), style: style, role: "dialog", "aria-modal": "true", "aria-label": a11yLabel, children: [_jsx("div", { ref: overlayRef, onMouseDown: onOverlayMouseDown, className: cn(overlayBase, overlayState, overlayClassName), style: transitionStyle }), _jsx("div", { className: "fixed inset-0 flex items-center justify-center p-4", children: _jsxs("div", { ref: contentRef, className: cn(contentBase, sizeClass(size), contentStateClass(animation, entered), showTopAccent ? severityClass(severity) : false, contentClassName), style: contentStyle, children: [(title || subtitle || closeable || leading || trailing) && (_jsxs("div", { className: cn("px-5 py-4 border-b border-[var(--sg-dialog-divider)] flex items-start gap-3", headerClassName), children: [leading ? _jsx("div", { className: "shrink-0 pt-0.5", children: leading }) : null, _jsxs("div", { className: "min-w-0 flex-1", children: [title ? _jsx("div", { className: "text-base font-semibold leading-6", children: title }) : null, subtitle ? _jsx("div", { className: "mt-1 text-sm text-[var(--sg-dialog-muted-foreground)]", children: subtitle }) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [trailing ? _jsx("div", { className: "shrink-0", children: trailing }) : null, closeable ? (_jsx("button", { type: "button", onClick: close, className: cn("inline-flex items-center justify-center h-9 w-9 rounded-lg", "hover:bg-[var(--sg-dialog-hover-bg)] active:bg-[var(--sg-dialog-active-bg)]", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring,var(--primary)))]"), "aria-label": "Close", children: _jsx(CloseIcon, {}) })) : null] })] })), _jsx("div", { className: cn("px-5 py-4 overflow-auto", bodyClassName), children: children }), footer ? (_jsx("div", { className: cn("px-5 py-4 border-t border-[var(--sg-dialog-divider)] flex items-center justify-end gap-2", footerClassName), children: footer })) : null] }) })] }), document.body);
401
+ return createPortal(_jsxs("div", { className: cn("fixed inset-0 z-[1000]", className), style: style, role: "dialog", "aria-modal": "true", "aria-label": a11yLabel, children: [_jsx("div", { ref: overlayRef, onMouseDown: onOverlayMouseDown, className: cn(overlayBase, overlayState, overlayClassName), style: transitionStyle }), _jsx("div", { className: "fixed inset-0 flex items-center justify-center p-4", children: _jsxs("div", { ref: contentRef, className: cn(contentBase, sizeClass(size), contentStateClass(animation, entered), showTopAccent ? severityClass(severity) : false, contentClassName), style: contentStyle, children: [(title || subtitle || closeable || leading || trailing) && (_jsxs("div", { className: cn("px-5 py-4 border-b border-[var(--sg-dialog-divider)] flex items-start gap-3", headerClassName), children: [leading ? _jsx("div", { className: "shrink-0 pt-0.5", children: leading }) : null, _jsxs("div", { className: "min-w-0 flex-1", children: [title ? _jsx("div", { className: "text-base font-semibold leading-6", children: title }) : null, subtitle ? _jsx("div", { className: "mt-1 text-sm text-[var(--sg-dialog-muted-foreground)]", children: subtitle }) : null] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [trailing ? _jsx("div", { className: "shrink-0", children: trailing }) : null, closeable ? (_jsx("button", { type: "button", onClick: close, className: cn("inline-flex items-center justify-center h-9 w-9 rounded-lg", "hover:bg-[var(--sg-dialog-hover-bg)] active:bg-[var(--sg-dialog-active-bg)]", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring,var(--primary)))]"), "aria-label": t(i18n, "components.dialog.close"), children: _jsx(CloseIcon, {}) })) : null] })] })), _jsx("div", { className: cn("px-5 py-4 overflow-auto", bodyClassName), children: children }), footer ? (_jsx("div", { className: cn("px-5 py-4 border-t border-[var(--sg-dialog-divider)] flex items-center justify-end gap-2", footerClassName), children: footer })) : null] }) })] }), document.body);
400
402
  }
401
403
  function CloseIcon() {
402
404
  return (_jsx("svg", { viewBox: "0 0 24 24", className: "size-5", "aria-hidden": "true", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"SgPopup.d.ts","sourceRoot":"","sources":["../../src/overlay/SgPopup.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAmB/B,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC5E,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,SAAS,GACT,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAExC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAwHF,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,4BAwLpD;yBAxLe,OAAO"}
1
+ {"version":3,"file":"SgPopup.d.ts","sourceRoot":"","sources":["../../src/overlay/SgPopup.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoB/B,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC5E,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,SAAS,GACT,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAExC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAwHF,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,4BA4LpD;yBA5Le,OAAO"}
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { createPortal } from "react-dom";
5
+ import { t, useComponentsI18n } from "../i18n";
5
6
  function cn(...parts) {
6
7
  return parts.filter(Boolean).join(" ");
7
8
  }
@@ -107,6 +108,7 @@ function computePosition(opts) {
107
108
  return { top, left };
108
109
  }
109
110
  export function SgPopup(props) {
111
+ const i18n = useComponentsI18n();
110
112
  const { title, subtitle, open, onOpenChange, defaultOpen = false, onOpen, onClose, anchorRef, placement = "auto", preferPlacement = "right", align = "start", offset = 8, padding = 8, closeOnOutsideClick = true, closeOnEscape = true, className, style, zIndex = 60, minWidth = 180, actions, children } = props;
111
113
  const isControlled = typeof open === "boolean";
112
114
  const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
@@ -198,13 +200,14 @@ export function SgPopup(props) {
198
200
  const close = React.useCallback(() => setOpen(false), [setOpen]);
199
201
  if (!isOpen)
200
202
  return null;
203
+ const resolvedAriaLabel = title ?? t(i18n, "components.popup.ariaLabel");
201
204
  const body = (_jsxs("div", { ref: panelRef, className: cn("fixed overflow-hidden rounded-md border border-border bg-background shadow-lg", "min-w-[180px]", className), style: {
202
205
  zIndex,
203
206
  top: pos?.top ?? -9999,
204
207
  left: pos?.left ?? -9999,
205
208
  minWidth,
206
209
  ...style
207
- }, role: "dialog", "aria-modal": "false", children: [title ? (_jsx("div", { className: "bg-primary px-3 py-2 text-xs font-medium text-primary-foreground", children: title })) : null, subtitle ? (_jsx("div", { className: "border-b border-border bg-background px-3 py-2 text-xs text-muted-foreground", children: subtitle })) : null, children ? _jsx("div", { className: "p-2", children: children }) : null, actions && actions.length > 0 ? (_jsx("div", { className: cn(children ? "border-t border-border" : "", "p-1"), children: actions.map((a, idx) => {
210
+ }, role: "dialog", "aria-modal": "false", "aria-label": resolvedAriaLabel, children: [title ? (_jsx("div", { className: "bg-primary px-3 py-2 text-xs font-medium text-primary-foreground", children: title })) : null, subtitle ? (_jsx("div", { className: "border-b border-border bg-background px-3 py-2 text-xs text-muted-foreground", children: subtitle })) : null, children ? _jsx("div", { className: "p-2", children: children }) : null, actions && actions.length > 0 ? (_jsx("div", { className: cn(children ? "border-t border-border" : "", "p-1"), children: actions.map((a, idx) => {
208
211
  const hasSeverity = a.severity !== undefined;
209
212
  const sev = a.severity ?? "plain";
210
213
  return (_jsx("button", { type: "button", disabled: a.disabled, title: a.hint, className: cn("w-full select-none rounded px-3 py-2 text-left text-sm", "transition-[filter,background-color] duration-150", "disabled:opacity-50 disabled:cursor-not-allowed", idx > 0 ? "border-t border-border" : "", hasSeverity ? ACTION_CLS[sev] : ACTION_DEFAULT_CLS), onClick: () => {
package/dist/rhf.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import type { Control } from "react-hook-form";
2
- export type RhfFieldProps = {
1
+ import type { Control, FieldValues, RegisterOptions, UseFormRegister } from "react-hook-form";
2
+ export type RhfFieldProps<TFieldValues extends FieldValues = FieldValues> = {
3
3
  name?: string;
4
- control?: Control<any>;
4
+ control?: Control<TFieldValues>;
5
+ register?: UseFormRegister<TFieldValues>;
6
+ rules?: RegisterOptions<TFieldValues>;
7
+ error?: string;
5
8
  };
9
+ export declare function resolveFieldError(...errors: Array<string | null | undefined>): string | undefined;
10
+ export declare function mergeRequiredRule<TFieldValues extends FieldValues = FieldValues>(rules: RegisterOptions<TFieldValues> | undefined, required: boolean | undefined, message: string): RegisterOptions<TFieldValues> | undefined;
6
11
  //# sourceMappingURL=rhf.d.ts.map
package/dist/rhf.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rhf.d.ts","sourceRoot":"","sources":["../src/rhf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;CACxB,CAAC"}
1
+ {"version":3,"file":"rhf.d.ts","sourceRoot":"","sources":["../src/rhf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,eAAe,EACf,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,aAAa,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,IAAI;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAOjG;AAED,wBAAgB,iBAAiB,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9E,KAAK,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,SAAS,EAChD,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,OAAO,EAAE,MAAM,GACd,eAAe,CAAC,YAAY,CAAC,GAAG,SAAS,CAO3C"}
package/dist/rhf.js CHANGED
@@ -1 +1,18 @@
1
- export {};
1
+ export function resolveFieldError(...errors) {
2
+ for (const error of errors) {
3
+ if (typeof error === "string" && error.trim()) {
4
+ return error;
5
+ }
6
+ }
7
+ return undefined;
8
+ }
9
+ export function mergeRequiredRule(rules, required, message) {
10
+ if (!required)
11
+ return rules;
12
+ if (!rules)
13
+ return { required: message };
14
+ if (rules.required === undefined || rules.required === false) {
15
+ return { ...rules, required: message };
16
+ }
17
+ return rules;
18
+ }