@seedgrid/fe-components 0.2.9 → 2026.3.1

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 (155) hide show
  1. package/dist/buttons/SgFloatActionButton.d.ts.map +1 -1
  2. package/dist/buttons/SgFloatActionButton.js +168 -38
  3. package/dist/commons/SgAvatar.d.ts +66 -0
  4. package/dist/commons/SgAvatar.d.ts.map +1 -0
  5. package/dist/commons/SgAvatar.js +136 -0
  6. package/dist/commons/SgSkeleton.d.ts +16 -0
  7. package/dist/commons/SgSkeleton.d.ts.map +1 -0
  8. package/dist/commons/SgSkeleton.js +58 -0
  9. package/dist/commons/SgToaster.d.ts +9 -0
  10. package/dist/commons/SgToaster.d.ts.map +1 -1
  11. package/dist/commons/SgToaster.js +86 -17
  12. package/dist/digits/discard-digit/SgDiscardDigit.d.ts +39 -0
  13. package/dist/digits/discard-digit/SgDiscardDigit.d.ts.map +1 -0
  14. package/dist/digits/discard-digit/SgDiscardDigit.js +303 -0
  15. package/dist/digits/discard-digit/index.d.ts +3 -0
  16. package/dist/digits/discard-digit/index.d.ts.map +1 -0
  17. package/dist/digits/discard-digit/index.js +1 -0
  18. package/dist/digits/fade-digit/SgFadeDigit.d.ts +27 -0
  19. package/dist/digits/fade-digit/SgFadeDigit.d.ts.map +1 -0
  20. package/dist/digits/fade-digit/SgFadeDigit.js +85 -0
  21. package/dist/digits/fade-digit/index.d.ts +3 -0
  22. package/dist/digits/fade-digit/index.d.ts.map +1 -0
  23. package/dist/digits/fade-digit/index.js +1 -0
  24. package/dist/digits/flip-digit/SgFlipDigit.d.ts +27 -0
  25. package/dist/digits/flip-digit/SgFlipDigit.d.ts.map +1 -0
  26. package/dist/digits/flip-digit/SgFlipDigit.js +70 -0
  27. package/dist/digits/flip-digit/index.d.ts.map +1 -0
  28. package/dist/digits/matrix-digit/SgMatrixDigit.d.ts +32 -0
  29. package/dist/digits/matrix-digit/SgMatrixDigit.d.ts.map +1 -0
  30. package/dist/digits/matrix-digit/SgMatrixDigit.js +86 -0
  31. package/dist/digits/matrix-digit/index.d.ts +3 -0
  32. package/dist/digits/matrix-digit/index.d.ts.map +1 -0
  33. package/dist/digits/matrix-digit/index.js +1 -0
  34. package/dist/digits/neon-digit/SgNeonDigit.d.ts +37 -0
  35. package/dist/digits/neon-digit/SgNeonDigit.d.ts.map +1 -0
  36. package/dist/digits/neon-digit/SgNeonDigit.js +59 -0
  37. package/dist/digits/neon-digit/index.d.ts +3 -0
  38. package/dist/digits/neon-digit/index.d.ts.map +1 -0
  39. package/dist/digits/neon-digit/index.js +1 -0
  40. package/dist/digits/roller3d-digit/SgRoller3DDigit.d.ts +37 -0
  41. package/dist/digits/roller3d-digit/SgRoller3DDigit.d.ts.map +1 -0
  42. package/dist/digits/roller3d-digit/SgRoller3DDigit.js +47 -0
  43. package/dist/digits/roller3d-digit/index.d.ts +3 -0
  44. package/dist/digits/roller3d-digit/index.d.ts.map +1 -0
  45. package/dist/digits/roller3d-digit/index.js +1 -0
  46. package/dist/environment/SgEnvironmentProvider.d.ts +1 -0
  47. package/dist/environment/SgEnvironmentProvider.d.ts.map +1 -1
  48. package/dist/environment/SgEnvironmentProvider.js +51 -12
  49. package/dist/gadgets/clock/SgClock.d.ts +3 -1
  50. package/dist/gadgets/clock/SgClock.d.ts.map +1 -1
  51. package/dist/gadgets/clock/SgClock.js +111 -180
  52. package/dist/gadgets/clock/SgTimeProvider.d.ts +1 -0
  53. package/dist/gadgets/clock/SgTimeProvider.d.ts.map +1 -1
  54. package/dist/gadgets/clock/SgTimeProvider.js +11 -4
  55. package/dist/gadgets/gauge/SgLinearGauge.d.ts +59 -0
  56. package/dist/gadgets/gauge/SgLinearGauge.d.ts.map +1 -0
  57. package/dist/gadgets/gauge/SgLinearGauge.js +258 -0
  58. package/dist/gadgets/gauge/SgRadialGauge.d.ts +73 -0
  59. package/dist/gadgets/gauge/SgRadialGauge.d.ts.map +1 -0
  60. package/dist/gadgets/gauge/SgRadialGauge.js +311 -0
  61. package/dist/gadgets/gauge/index.d.ts +5 -0
  62. package/dist/gadgets/gauge/index.d.ts.map +1 -0
  63. package/dist/gadgets/gauge/index.js +2 -0
  64. package/dist/gadgets/qr-code/SgQRCode.d.ts +25 -0
  65. package/dist/gadgets/qr-code/SgQRCode.d.ts.map +1 -0
  66. package/dist/gadgets/qr-code/SgQRCode.js +75 -0
  67. package/dist/gadgets/qr-code/index.d.ts +3 -0
  68. package/dist/gadgets/qr-code/index.d.ts.map +1 -0
  69. package/dist/gadgets/qr-code/index.js +1 -0
  70. package/dist/gadgets/string-animator/SgStringAnimator.d.ts +91 -0
  71. package/dist/gadgets/string-animator/SgStringAnimator.d.ts.map +1 -0
  72. package/dist/gadgets/string-animator/SgStringAnimator.js +145 -0
  73. package/dist/gadgets/string-animator/index.d.ts +3 -0
  74. package/dist/gadgets/string-animator/index.d.ts.map +1 -0
  75. package/dist/gadgets/string-animator/index.js +1 -0
  76. package/dist/i18n/en-US.json +9 -1
  77. package/dist/i18n/es.json +55 -47
  78. package/dist/i18n/index.d.ts +32 -0
  79. package/dist/i18n/index.d.ts.map +1 -1
  80. package/dist/i18n/pt-BR.json +9 -1
  81. package/dist/i18n/pt-PT.json +9 -1
  82. package/dist/index.d.ts +53 -5
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +25 -1
  85. package/dist/inputs/SgAutocomplete.js +21 -5
  86. package/dist/inputs/SgCombobox.d.ts +26 -0
  87. package/dist/inputs/SgCombobox.d.ts.map +1 -0
  88. package/dist/inputs/SgCombobox.js +354 -0
  89. package/dist/inputs/SgInputOTP.d.ts.map +1 -1
  90. package/dist/inputs/SgInputOTP.js +9 -2
  91. package/dist/inputs/SgRadioGroup.d.ts +37 -0
  92. package/dist/inputs/SgRadioGroup.d.ts.map +1 -0
  93. package/dist/inputs/SgRadioGroup.js +139 -0
  94. package/dist/inputs/SgRating.d.ts +55 -0
  95. package/dist/inputs/SgRating.d.ts.map +1 -0
  96. package/dist/inputs/SgRating.js +135 -0
  97. package/dist/inputs/SgSlider.d.ts +20 -0
  98. package/dist/inputs/SgSlider.d.ts.map +1 -0
  99. package/dist/inputs/SgSlider.js +40 -0
  100. package/dist/inputs/SgStepperInput.d.ts +22 -0
  101. package/dist/inputs/SgStepperInput.d.ts.map +1 -0
  102. package/dist/inputs/SgStepperInput.js +51 -0
  103. package/dist/inputs/SgTextEditor.d.ts +1 -0
  104. package/dist/inputs/SgTextEditor.d.ts.map +1 -1
  105. package/dist/inputs/SgTextEditor.js +19 -3
  106. package/dist/inputs/SgToggleSwitch.d.ts +36 -0
  107. package/dist/inputs/SgToggleSwitch.d.ts.map +1 -0
  108. package/dist/inputs/SgToggleSwitch.js +174 -0
  109. package/dist/layout/SgAccordion.d.ts +39 -0
  110. package/dist/layout/SgAccordion.d.ts.map +1 -0
  111. package/dist/layout/SgAccordion.js +116 -0
  112. package/dist/layout/SgBreadcrumb.d.ts +33 -0
  113. package/dist/layout/SgBreadcrumb.d.ts.map +1 -0
  114. package/dist/layout/SgBreadcrumb.js +121 -0
  115. package/dist/layout/SgCarousel.d.ts +43 -0
  116. package/dist/layout/SgCarousel.d.ts.map +1 -0
  117. package/dist/layout/SgCarousel.js +166 -0
  118. package/dist/layout/SgDockLayout.d.ts +14 -0
  119. package/dist/layout/SgDockLayout.d.ts.map +1 -1
  120. package/dist/layout/SgDockLayout.js +145 -13
  121. package/dist/layout/SgDockScreen.d.ts +15 -0
  122. package/dist/layout/SgDockScreen.d.ts.map +1 -0
  123. package/dist/layout/SgDockScreen.js +13 -0
  124. package/dist/layout/SgDockZone.d.ts.map +1 -1
  125. package/dist/layout/SgDockZone.js +36 -2
  126. package/dist/layout/SgExpandablePanel.d.ts +50 -0
  127. package/dist/layout/SgExpandablePanel.d.ts.map +1 -0
  128. package/dist/layout/SgExpandablePanel.js +302 -0
  129. package/dist/layout/SgMainPanel.d.ts.map +1 -1
  130. package/dist/layout/SgMainPanel.js +36 -14
  131. package/dist/layout/SgMenu.d.ts +91 -0
  132. package/dist/layout/SgMenu.d.ts.map +1 -0
  133. package/dist/layout/SgMenu.js +939 -0
  134. package/dist/layout/SgPageControl.d.ts +49 -0
  135. package/dist/layout/SgPageControl.d.ts.map +1 -0
  136. package/dist/layout/SgPageControl.js +152 -0
  137. package/dist/layout/SgPanel.d.ts.map +1 -1
  138. package/dist/layout/SgPanel.js +10 -1
  139. package/dist/layout/SgScreen.d.ts +2 -0
  140. package/dist/layout/SgScreen.d.ts.map +1 -1
  141. package/dist/layout/SgScreen.js +4 -2
  142. package/dist/layout/SgToolBar.d.ts +9 -3
  143. package/dist/layout/SgToolBar.d.ts.map +1 -1
  144. package/dist/layout/SgToolBar.js +461 -55
  145. package/dist/menus/SgDockMenu.d.ts +62 -0
  146. package/dist/menus/SgDockMenu.d.ts.map +1 -0
  147. package/dist/menus/SgDockMenu.js +480 -0
  148. package/dist/others/SgPlayground.js +73 -73
  149. package/package.json +72 -57
  150. package/dist/gadgets/flip-digit/SgFlipDigit.d.ts +0 -23
  151. package/dist/gadgets/flip-digit/SgFlipDigit.d.ts.map +0 -1
  152. package/dist/gadgets/flip-digit/SgFlipDigit.js +0 -118
  153. package/dist/gadgets/flip-digit/index.d.ts.map +0 -1
  154. /package/dist/{gadgets → digits}/flip-digit/index.d.ts +0 -0
  155. /package/dist/{gadgets → digits}/flip-digit/index.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SgDockMenu.d.ts","sourceRoot":"","sources":["../../src/menus/SgDockMenu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,kBAAkB,GAC1B,UAAU,GAAG,aAAa,GAAG,aAAa,GAC1C,YAAY,GAAG,eAAe,GAC9B,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;AAElD,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE9D,MAAM,MAAM,cAAc,GAAG;IAC3B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,yCAAyC;IACzC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,MAAM,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACxC,mBAAmB;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAkFD,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,2CAghB1D"}
@@ -0,0 +1,480 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { t, useComponentsI18n } from "../i18n";
5
+ import { useHasSgEnvironmentProvider, useSgPersistence } from "../environment/SgEnvironmentProvider";
6
+ /* ── 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
+ const ELEV_CLS = {
25
+ none: "",
26
+ sm: "shadow-sm",
27
+ md: "shadow-md shadow-black/15",
28
+ lg: "shadow-lg shadow-black/20",
29
+ };
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
+ function clamp(value, min, max) {
37
+ return Math.min(Math.max(value, min), max);
38
+ }
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
+ /* ── orientation helper ── */
62
+ function getOrientation(position) {
63
+ if (position === "center-top" || position === "center-bottom")
64
+ return "horizontal";
65
+ if (position === "left-center" || position === "right-center")
66
+ return "vertical";
67
+ // For corners, default to horizontal
68
+ return "horizontal";
69
+ }
70
+ /* ── component ── */
71
+ export function SgDockMenu(props) {
72
+ const i18n = useComponentsI18n();
73
+ const hasEnvironmentProvider = useHasSgEnvironmentProvider();
74
+ const { load: loadPersistedState, save: savePersistedState, clear: clearPersistedState } = useSgPersistence();
75
+ const { id, items, position = "center-bottom", enableDragDrop = false, dragId, offset, className = "", itemClassName = "", zIndex = 50, itemSize = 48, gap = 16, backgroundColor = "rgba(255, 255, 255, 0.95)", showLabels = true, magnify = true, magnifyScale = 1.5, borderRadius = 16, elevation = "lg", style, } = props;
76
+ const [dragPos, setDragPos] = React.useState(null);
77
+ const dragPosRef = React.useRef(null);
78
+ const hasStoredPosRef = React.useRef(false);
79
+ const [isDragging, setIsDragging] = React.useState(false);
80
+ const [menuOpen, setMenuOpen] = React.useState(false);
81
+ const [hoveredIndex, setHoveredIndex] = React.useState(null);
82
+ const dragStart = React.useRef(null);
83
+ const dragMoved = React.useRef(false);
84
+ const containerRef = React.useRef(null);
85
+ const orientation = getOrientation(position);
86
+ const liftDirection = getLiftDirection(position, orientation);
87
+ const crossPadding = Math.max(8, Math.round(gap * 0.6));
88
+ const edgePadding = Math.max(Math.round(gap * 2.2), Math.round(itemSize * 0.45));
89
+ const isAbsolutePosition = style?.position === "absolute";
90
+ const storageKey = dragId
91
+ ? `sg-dockmenu-pos:${dragId}:${isAbsolutePosition ? "parent" : "viewport"}`
92
+ : null;
93
+ const loadStoredPosition = React.useCallback(async () => {
94
+ if (!storageKey)
95
+ return null;
96
+ if (hasEnvironmentProvider) {
97
+ try {
98
+ const loaded = await loadPersistedState(storageKey);
99
+ if (loaded === null || loaded === undefined)
100
+ return null;
101
+ const parsed = parseStoredDragPosition(loaded);
102
+ if (!parsed) {
103
+ await clearPersistedState(storageKey);
104
+ return null;
105
+ }
106
+ return parsed;
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ }
112
+ try {
113
+ const raw = localStorage.getItem(storageKey);
114
+ if (!raw)
115
+ return null;
116
+ const parsed = parseStoredDragPosition(raw);
117
+ if (!parsed) {
118
+ localStorage.removeItem(storageKey);
119
+ return null;
120
+ }
121
+ return parsed;
122
+ }
123
+ catch {
124
+ return null;
125
+ }
126
+ }, [clearPersistedState, hasEnvironmentProvider, loadPersistedState, storageKey]);
127
+ const saveStoredPosition = React.useCallback(async (nextPos) => {
128
+ if (!storageKey)
129
+ return;
130
+ if (hasEnvironmentProvider) {
131
+ try {
132
+ await savePersistedState(storageKey, nextPos);
133
+ }
134
+ catch {
135
+ // ignore
136
+ }
137
+ return;
138
+ }
139
+ try {
140
+ localStorage.setItem(storageKey, JSON.stringify(nextPos));
141
+ }
142
+ catch {
143
+ // ignore
144
+ }
145
+ }, [hasEnvironmentProvider, savePersistedState, storageKey]);
146
+ const clearStoredPosition = React.useCallback(async () => {
147
+ if (!storageKey)
148
+ return;
149
+ if (hasEnvironmentProvider) {
150
+ try {
151
+ await clearPersistedState(storageKey);
152
+ }
153
+ catch {
154
+ // ignore
155
+ }
156
+ return;
157
+ }
158
+ try {
159
+ localStorage.removeItem(storageKey);
160
+ }
161
+ catch {
162
+ // ignore
163
+ }
164
+ }, [clearPersistedState, hasEnvironmentProvider, storageKey]);
165
+ const getDragBounds = React.useCallback(() => {
166
+ if (!containerRef.current)
167
+ return null;
168
+ const element = containerRef.current;
169
+ const elementRect = element.getBoundingClientRect();
170
+ if (isAbsolutePosition) {
171
+ const parent = element.offsetParent;
172
+ if (!parent)
173
+ return null;
174
+ const parentRect = parent.getBoundingClientRect();
175
+ return {
176
+ originX: parentRect.left,
177
+ originY: parentRect.top,
178
+ minX: 0,
179
+ minY: 0,
180
+ maxX: Math.max(0, parent.clientWidth - elementRect.width),
181
+ maxY: Math.max(0, parent.clientHeight - elementRect.height)
182
+ };
183
+ }
184
+ return {
185
+ originX: 0,
186
+ originY: 0,
187
+ minX: 0,
188
+ minY: 0,
189
+ maxX: Math.max(0, window.innerWidth - elementRect.width),
190
+ maxY: Math.max(0, window.innerHeight - elementRect.height)
191
+ };
192
+ }, [isAbsolutePosition]);
193
+ // Load stored position
194
+ React.useEffect(() => {
195
+ if (!enableDragDrop || !storageKey)
196
+ return;
197
+ if (!containerRef.current)
198
+ return;
199
+ let alive = true;
200
+ (async () => {
201
+ const parsed = await loadStoredPosition();
202
+ if (!alive || !parsed)
203
+ return;
204
+ const bounds = getDragBounds();
205
+ if (!bounds)
206
+ return;
207
+ const clamped = {
208
+ x: clamp(parsed.x, bounds.minX, bounds.maxX),
209
+ y: clamp(parsed.y, bounds.minY, bounds.maxY)
210
+ };
211
+ dragPosRef.current = clamped;
212
+ setDragPos(clamped);
213
+ hasStoredPosRef.current = true;
214
+ })();
215
+ return () => {
216
+ alive = false;
217
+ };
218
+ }, [enableDragDrop, getDragBounds, loadStoredPosition, storageKey]);
219
+ React.useEffect(() => {
220
+ if (!enableDragDrop || !isDragging)
221
+ return;
222
+ const previous = document.body.style.cursor;
223
+ document.body.style.cursor = "grabbing";
224
+ return () => {
225
+ document.body.style.cursor = previous;
226
+ };
227
+ }, [enableDragDrop, isDragging]);
228
+ const handlePointerDown = React.useCallback((event) => {
229
+ if (event.button !== 0)
230
+ return;
231
+ if (!enableDragDrop)
232
+ return;
233
+ if (!containerRef.current)
234
+ return;
235
+ const bounds = getDragBounds();
236
+ if (!bounds)
237
+ return;
238
+ // Don't start drag if clicking on an item
239
+ const target = event.target;
240
+ if (target.closest('[data-dock-item]'))
241
+ return;
242
+ event.preventDefault();
243
+ const rect = containerRef.current.getBoundingClientRect();
244
+ dragStart.current = {
245
+ x: event.clientX,
246
+ y: event.clientY,
247
+ left: rect.left - bounds.originX,
248
+ top: rect.top - bounds.originY
249
+ };
250
+ dragMoved.current = false;
251
+ setIsDragging(true);
252
+ const handleMove = (moveEvent) => {
253
+ if (!dragStart.current)
254
+ return;
255
+ const dx = moveEvent.clientX - dragStart.current.x;
256
+ const dy = moveEvent.clientY - dragStart.current.y;
257
+ if (Math.abs(dx) > 3 || Math.abs(dy) > 3) {
258
+ dragMoved.current = true;
259
+ }
260
+ const nextPos = {
261
+ x: clamp(dragStart.current.left + dx, bounds.minX, bounds.maxX),
262
+ y: clamp(dragStart.current.top + dy, bounds.minY, bounds.maxY)
263
+ };
264
+ dragPosRef.current = nextPos;
265
+ setDragPos(nextPos);
266
+ hasStoredPosRef.current = true;
267
+ };
268
+ const handleUp = () => {
269
+ setIsDragging(false);
270
+ dragStart.current = null;
271
+ if (enableDragDrop && storageKey && dragPosRef.current) {
272
+ void saveStoredPosition(dragPosRef.current);
273
+ }
274
+ window.removeEventListener("pointermove", handleMove);
275
+ window.removeEventListener("pointerup", handleUp);
276
+ window.removeEventListener("pointercancel", handleUp);
277
+ };
278
+ window.addEventListener("pointermove", handleMove);
279
+ window.addEventListener("pointerup", handleUp);
280
+ window.addEventListener("pointercancel", handleUp);
281
+ }, [enableDragDrop, getDragBounds, saveStoredPosition, storageKey]);
282
+ const handleContextMenu = React.useCallback((event) => {
283
+ if (!enableDragDrop || !dragId)
284
+ return;
285
+ if (!hasStoredPosRef.current)
286
+ return;
287
+ event.preventDefault();
288
+ setMenuOpen(true);
289
+ }, [enableDragDrop, dragId]);
290
+ const handleResetPosition = React.useCallback(() => {
291
+ if (!storageKey)
292
+ return;
293
+ void clearStoredPosition();
294
+ dragPosRef.current = null;
295
+ setDragPos(null);
296
+ setMenuOpen(false);
297
+ hasStoredPosRef.current = false;
298
+ dragMoved.current = false;
299
+ }, [clearStoredPosition, storageKey]);
300
+ const handleItemClick = React.useCallback((item) => {
301
+ if (item.disabled)
302
+ return;
303
+ if (dragMoved.current) {
304
+ dragMoved.current = false;
305
+ return;
306
+ }
307
+ item.onClick?.();
308
+ }, []);
309
+ // Container position
310
+ const posStyle = {
311
+ position: "fixed",
312
+ ...POS_CSS[position],
313
+ zIndex
314
+ };
315
+ if (enableDragDrop && dragPos) {
316
+ posStyle.left = dragPos.x;
317
+ posStyle.top = dragPos.y;
318
+ delete posStyle.right;
319
+ delete posStyle.bottom;
320
+ }
321
+ if (offset?.x) {
322
+ if (posStyle.right !== undefined)
323
+ posStyle.right = (typeof posStyle.right === "number" ? posStyle.right : 0) - offset.x;
324
+ else if (posStyle.left !== undefined)
325
+ posStyle.left = (typeof posStyle.left === "number" ? posStyle.left : 0) + offset.x;
326
+ }
327
+ if (offset?.y) {
328
+ if (posStyle.bottom !== undefined)
329
+ posStyle.bottom = (typeof posStyle.bottom === "number" ? posStyle.bottom : 0) - offset.y;
330
+ else if (posStyle.top !== undefined)
331
+ posStyle.top = (typeof posStyle.top === "number" ? posStyle.top : 0) + offset.y;
332
+ }
333
+ const txParts = [];
334
+ const ctx = !(enableDragDrop && dragPos) ? CENTER_TX[position] : undefined;
335
+ if (ctx)
336
+ txParts.push(ctx);
337
+ return (_jsxs(_Fragment, { children: [_jsx("div", { ref: containerRef, id: id, className: `sg-dock ${className} ${ELEV_CLS[elevation]}`, style: {
338
+ ...posStyle,
339
+ ...style,
340
+ transform: txParts.join(" "),
341
+ cursor: enableDragDrop ? (isDragging ? "grabbing" : "grab") : "default",
342
+ }, onPointerDown: handlePointerDown, onContextMenu: handleContextMenu, children: _jsx("div", { className: "sg-dock-container", style: {
343
+ display: "flex",
344
+ flexDirection: orientation === "horizontal" ? "row" : "column",
345
+ alignItems: "center",
346
+ gap: `${gap}px`,
347
+ ...(orientation === "horizontal"
348
+ ? {
349
+ paddingTop: crossPadding,
350
+ paddingBottom: crossPadding,
351
+ paddingLeft: edgePadding,
352
+ paddingRight: edgePadding
353
+ }
354
+ : {
355
+ paddingTop: edgePadding,
356
+ paddingBottom: edgePadding,
357
+ paddingLeft: crossPadding,
358
+ paddingRight: crossPadding
359
+ }),
360
+ backgroundColor,
361
+ borderRadius: `${borderRadius}px`,
362
+ backdropFilter: "blur(10px)",
363
+ transition: "all 0.3s ease",
364
+ }, children: items.map((item, index) => {
365
+ const isHovered = hoveredIndex === index;
366
+ const hasMagnifyCurve = magnify && hoveredIndex !== null;
367
+ const distance = hasMagnifyCurve ? Math.abs(index - hoveredIndex) : Number.POSITIVE_INFINITY;
368
+ const influence = hasMagnifyCurve ? Math.max(0, 1 - distance / 3) : 0;
369
+ const curve = influence * influence;
370
+ const scale = 1 + (magnifyScale - 1) * curve;
371
+ const liftPx = curve * Math.min(itemSize * 0.4, 18);
372
+ const spreadBase = Math.max(0, itemSize * (magnifyScale - 1) * 0.68 + gap * 0.12);
373
+ const spreadCurve = hasMagnifyCurve && distance > 0
374
+ ? Math.max(0, 1 - (distance - 1) * 0.1)
375
+ : 0;
376
+ const spreadSign = hasMagnifyCurve && hoveredIndex !== null ? Math.sign(index - hoveredIndex) : 0;
377
+ const spreadPx = spreadSign === 0 ? 0 : spreadSign * spreadBase * spreadCurve;
378
+ const translateX = (orientation === "vertical" ? liftDirection * liftPx : 0) +
379
+ (orientation === "horizontal" ? spreadPx : 0);
380
+ const translateY = (orientation === "horizontal" ? liftDirection * liftPx : 0) +
381
+ (orientation === "vertical" ? spreadPx : 0);
382
+ const transformOrigin = orientation === "horizontal"
383
+ ? liftDirection < 0
384
+ ? "50% 100%"
385
+ : "50% 0%"
386
+ : liftDirection > 0
387
+ ? "0% 50%"
388
+ : "100% 50%";
389
+ return (_jsxs("div", { "data-dock-item": true, className: `sg-dock-item ${itemClassName} ${item.className ?? ""}`, style: {
390
+ position: "relative",
391
+ width: itemSize,
392
+ height: itemSize,
393
+ transform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,
394
+ transformOrigin,
395
+ transition: "transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)",
396
+ willChange: "transform",
397
+ cursor: item.disabled ? "not-allowed" : "pointer",
398
+ opacity: item.disabled ? 0.5 : 1,
399
+ zIndex: isHovered ? 3 : curve > 0 ? 2 : 1,
400
+ }, onMouseEnter: () => setHoveredIndex(index), onMouseLeave: () => setHoveredIndex(null), onClick: () => handleItemClick(item), children: [_jsx("div", { className: "sg-dock-item-icon", style: {
401
+ width: "100%",
402
+ height: "100%",
403
+ display: "flex",
404
+ alignItems: "center",
405
+ justifyContent: "center",
406
+ borderRadius: `${borderRadius * 0.5}px`,
407
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
408
+ transition: "background-color 0.2s ease",
409
+ }, onMouseEnter: (e) => {
410
+ e.currentTarget.style.backgroundColor = "rgba(0, 0, 0, 0.1)";
411
+ }, onMouseLeave: (e) => {
412
+ e.currentTarget.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
413
+ }, children: item.icon }), item.badge && (_jsx("div", { className: "sg-dock-item-badge", style: {
414
+ position: "absolute",
415
+ top: -4,
416
+ right: -4,
417
+ backgroundColor: "hsl(var(--destructive))",
418
+ color: "white",
419
+ borderRadius: "50%",
420
+ minWidth: 20,
421
+ height: 20,
422
+ display: "flex",
423
+ alignItems: "center",
424
+ justifyContent: "center",
425
+ fontSize: 11,
426
+ fontWeight: 600,
427
+ padding: "0 4px",
428
+ boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
429
+ }, children: item.badge })), showLabels && isHovered && (_jsx("div", { className: "sg-dock-item-label", style: {
430
+ position: "absolute",
431
+ ...(orientation === "horizontal"
432
+ ? { bottom: "100%", left: "50%", transform: "translateX(-50%)", marginBottom: 8 }
433
+ : position.startsWith("left")
434
+ ? { left: "100%", top: "50%", transform: "translateY(-50%)", marginLeft: 8 }
435
+ : { right: "100%", top: "50%", transform: "translateY(-50%)", marginRight: 8 }),
436
+ backgroundColor: "rgba(0, 0, 0, 0.8)",
437
+ color: "white",
438
+ padding: "4px 8px",
439
+ borderRadius: 6,
440
+ fontSize: 12,
441
+ fontWeight: 500,
442
+ whiteSpace: "nowrap",
443
+ pointerEvents: "none",
444
+ zIndex: 1000,
445
+ }, children: item.label }))] }, item.id));
446
+ }) }) }), menuOpen && (_jsx("div", { style: {
447
+ position: "fixed",
448
+ top: 0,
449
+ left: 0,
450
+ right: 0,
451
+ bottom: 0,
452
+ zIndex: zIndex + 1,
453
+ }, onClick: () => setMenuOpen(false), children: _jsxs("div", { style: {
454
+ position: "absolute",
455
+ top: "50%",
456
+ left: "50%",
457
+ transform: "translate(-50%, -50%)",
458
+ backgroundColor: "white",
459
+ borderRadius: 12,
460
+ padding: 24,
461
+ boxShadow: "0 8px 32px rgba(0,0,0,0.2)",
462
+ maxWidth: 400,
463
+ }, onClick: (e) => e.stopPropagation(), children: [_jsx("h3", { style: { margin: 0, marginBottom: 12, fontSize: 18, fontWeight: 600 }, children: t(i18n, "components.dock.resetPosition") }), _jsx("p", { style: { margin: 0, marginBottom: 16, fontSize: 14, color: "hsl(var(--muted-foreground))" }, children: t(i18n, "components.dock.resetConfirm") }), _jsxs("div", { style: { display: "flex", gap: 8, justifyContent: "flex-end" }, children: [_jsx("button", { onClick: () => setMenuOpen(false), style: {
464
+ padding: "8px 16px",
465
+ borderRadius: 6,
466
+ border: "1px solid hsl(var(--border))",
467
+ backgroundColor: "transparent",
468
+ cursor: "pointer",
469
+ fontSize: 14,
470
+ }, children: t(i18n, "components.actions.cancel") }), _jsx("button", { onClick: handleResetPosition, style: {
471
+ padding: "8px 16px",
472
+ borderRadius: 6,
473
+ border: "none",
474
+ backgroundColor: "hsl(var(--primary))",
475
+ color: "white",
476
+ cursor: "pointer",
477
+ fontSize: 14,
478
+ fontWeight: 500,
479
+ }, children: t(i18n, "components.actions.confirm") })] })] }) }))] }));
480
+ }
@@ -7,7 +7,7 @@ import { SgCard } from "../layout/SgCard";
7
7
  function cn(...parts) {
8
8
  return parts.filter(Boolean).join(" ");
9
9
  }
10
- const DEFAULT_SEEDGRID_DEPENDENCY = "0.2.6";
10
+ const DEFAULT_SEEDGRID_DEPENDENCY = "0.2.9";
11
11
  const DEFAULT_SEEDGRID_PEER_DEPENDENCIES = {
12
12
  "@codesandbox/sandpack-react": "^2.20.0",
13
13
  "react-hook-form": "^7.0.0",
@@ -64,44 +64,44 @@ const SANDPACK_CORE_THEME_VARS = [
64
64
  "--border",
65
65
  "--ring"
66
66
  ];
67
- const SANDPACK_BASE_STYLES_CSS = `* {
68
- box-sizing: border-box;
69
- }
70
-
71
- html, body, #root {
72
- margin: 0;
73
- min-height: 100%;
74
- }
75
-
76
- #root {
77
- padding: var(--sg-preview-padding, 0px);
78
- }
79
-
80
- body {
81
- font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
82
- background: rgb(var(--sg-bg, 255 255 255));
83
- color: rgb(var(--sg-text, 11 11 12));
84
- }
85
-
86
- /* Classes with arbitrary values used by SeedGrid components */
87
- .bg-\\[var\\(--sg-btn-bg\\)\\] { background-color: var(--sg-btn-bg); }
88
- .text-\\[var\\(--sg-btn-fg\\)\\] { color: var(--sg-btn-fg); }
89
- .border-\\[var\\(--sg-btn-border\\)\\] { border-color: var(--sg-btn-border); }
90
- .hover\\:bg-\\[var\\(--sg-btn-hover-bg\\)\\]:hover { background-color: var(--sg-btn-hover-bg); }
91
- .hover\\:text-\\[var\\(--sg-btn-hover-fg\\)\\]:hover { color: var(--sg-btn-hover-fg); }
92
- .hover\\:border-\\[var\\(--sg-btn-hover-border\\)\\]:hover { border-color: var(--sg-btn-hover-border); }
93
- .active\\:bg-\\[var\\(--sg-btn-active-bg\\)\\]:active { background-color: var(--sg-btn-active-bg); }
94
- .focus-visible\\:ring-\\[var\\(--sg-btn-ring\\)\\]:focus-visible { box-shadow: 0 0 0 4px var(--sg-btn-ring); }
95
- .hover\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.12\\)\\]:hover { background-color: rgb(var(--sg-btn-tint) / 0.12); }
96
- .active\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.18\\)\\]:active { background-color: rgb(var(--sg-btn-tint) / 0.18); }
97
- .hover\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.10\\)\\]:hover { background-color: rgb(var(--sg-btn-tint) / 0.10); }
98
- .active\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.16\\)\\]:active { background-color: rgb(var(--sg-btn-tint) / 0.16); }
99
- .transition-\\[background-color\\,color\\,border-color\\,box-shadow\\,transform\\] {
100
- transition-property: background-color, color, border-color, box-shadow, transform;
101
- }
102
- .active\\:translate-y-\\[0\\.5px\\]:active { transform: translateY(0.5px); }
103
- .size-4 { width: 1rem; height: 1rem; }
104
- .size-5 { width: 1.25rem; height: 1.25rem; }
67
+ const SANDPACK_BASE_STYLES_CSS = `* {
68
+ box-sizing: border-box;
69
+ }
70
+
71
+ html, body, #root {
72
+ margin: 0;
73
+ min-height: 100%;
74
+ }
75
+
76
+ #root {
77
+ padding: var(--sg-preview-padding, 0px);
78
+ }
79
+
80
+ body {
81
+ font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
82
+ background: rgb(var(--sg-bg, 255 255 255));
83
+ color: rgb(var(--sg-text, 11 11 12));
84
+ }
85
+
86
+ /* Classes with arbitrary values used by SeedGrid components */
87
+ .bg-\\[var\\(--sg-btn-bg\\)\\] { background-color: var(--sg-btn-bg); }
88
+ .text-\\[var\\(--sg-btn-fg\\)\\] { color: var(--sg-btn-fg); }
89
+ .border-\\[var\\(--sg-btn-border\\)\\] { border-color: var(--sg-btn-border); }
90
+ .hover\\:bg-\\[var\\(--sg-btn-hover-bg\\)\\]:hover { background-color: var(--sg-btn-hover-bg); }
91
+ .hover\\:text-\\[var\\(--sg-btn-hover-fg\\)\\]:hover { color: var(--sg-btn-hover-fg); }
92
+ .hover\\:border-\\[var\\(--sg-btn-hover-border\\)\\]:hover { border-color: var(--sg-btn-hover-border); }
93
+ .active\\:bg-\\[var\\(--sg-btn-active-bg\\)\\]:active { background-color: var(--sg-btn-active-bg); }
94
+ .focus-visible\\:ring-\\[var\\(--sg-btn-ring\\)\\]:focus-visible { box-shadow: 0 0 0 4px var(--sg-btn-ring); }
95
+ .hover\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.12\\)\\]:hover { background-color: rgb(var(--sg-btn-tint) / 0.12); }
96
+ .active\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.18\\)\\]:active { background-color: rgb(var(--sg-btn-tint) / 0.18); }
97
+ .hover\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.10\\)\\]:hover { background-color: rgb(var(--sg-btn-tint) / 0.10); }
98
+ .active\\:bg-\\[rgb\\(var\\(--sg-btn-tint\\)\\/0\\.16\\)\\]:active { background-color: rgb(var(--sg-btn-tint) / 0.16); }
99
+ .transition-\\[background-color\\,color\\,border-color\\,box-shadow\\,transform\\] {
100
+ transition-property: background-color, color, border-color, box-shadow, transform;
101
+ }
102
+ .active\\:translate-y-\\[0\\.5px\\]:active { transform: translateY(0.5px); }
103
+ .size-4 { width: 1rem; height: 1rem; }
104
+ .size-5 { width: 1.25rem; height: 1.25rem; }
105
105
  `;
106
106
  function parseRgbParts(raw) {
107
107
  const value = raw.trim();
@@ -217,10 +217,10 @@ function buildSandpackStylesCss(themeVars, previewPadding) {
217
217
  .sort(([a], [b]) => a.localeCompare(b))
218
218
  .map(([varName, value]) => ` ${varName}: ${value};`)
219
219
  .join("\n");
220
- return `:root {
221
- ${rootVars}
222
- }
223
-
220
+ return `:root {
221
+ ${rootVars}
222
+ }
223
+
224
224
  ${SANDPACK_BASE_STYLES_CSS}`;
225
225
  }
226
226
  function ReadonlyBlock({ code }) {
@@ -233,30 +233,30 @@ function buildAppTsxFromRenderBody(renderBody, defaultImports, wrapperClassName)
233
233
  .map((line) => (line ? ` ${line}` : ""))
234
234
  .join("\n");
235
235
  if (!wrapperClassName) {
236
- return `import * as React from "react";
237
- ${defaultImports}
238
-
239
- export default function App() {
240
- return (
241
- <>
242
- ${body}
243
- </>
244
- );
245
- }
236
+ return `import * as React from "react";
237
+ ${defaultImports}
238
+
239
+ export default function App() {
240
+ return (
241
+ <>
242
+ ${body}
243
+ </>
244
+ );
245
+ }
246
246
  `;
247
247
  }
248
- return `import * as React from "react";
249
- ${defaultImports}
250
-
251
- export default function App() {
252
- return (
253
- <div className="${wrapperClassName}">
254
- <>
255
- ${body}
256
- </>
257
- </div>
258
- );
259
- }
248
+ return `import * as React from "react";
249
+ ${defaultImports}
250
+
251
+ export default function App() {
252
+ return (
253
+ <div className="${wrapperClassName}">
254
+ <>
255
+ ${body}
256
+ </>
257
+ </div>
258
+ );
259
+ }
260
260
  `;
261
261
  }
262
262
  async function copyText(text) {
@@ -340,14 +340,14 @@ export default function SgPlayground(props) {
340
340
  }
341
341
  };
342
342
  }, [effectivePreviewPadding]);
343
- const seedgridDefaultImports = defaultImports ?? `import {
344
- SgScreen,
345
- SgMainPanel,
346
- SgPanel,
347
- SgGrid,
348
- SgStack,
349
- SgButton,
350
- SgAutocomplete
343
+ const seedgridDefaultImports = defaultImports ?? `import {
344
+ SgScreen,
345
+ SgMainPanel,
346
+ SgPanel,
347
+ SgGrid,
348
+ SgStack,
349
+ SgButton,
350
+ SgAutocomplete
351
351
  } from "@seedgrid/fe-components";`;
352
352
  const appTsx = codeContract === "appFile"
353
353
  ? code