@seedgrid/fe-components 0.2.7 → 0.2.9

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.
@@ -318,46 +318,46 @@ function DigitalClock({ timezone, locale = "pt-BR", format = "24h", showSeconds
318
318
  const glossBottom = "after:absolute after:inset-0 after:bg-gradient-to-t after:from-black/30 after:to-transparent after:content-['']";
319
319
  const Colon = () => (_jsxs("div", { className: "flex flex-col items-center justify-center", style: { height: h }, children: [_jsx("div", { className: "h-2 w-2 rounded-full bg-white/80" }), _jsx("div", { className: "mt-2 h-2 w-2 rounded-full bg-white/80" })] }));
320
320
  const PeriodCell = ({ value }) => (_jsx("div", { className: cn(panel, glossTop, glossBottom, "flex items-center justify-center"), style: { width: Math.round(w * 1.35), height: h }, children: _jsx("span", { className: "font-semibold text-white/90", style: { fontSize: Math.round(sizePx * 1.05), lineHeight: 1 }, children: value }) }));
321
- return (_jsxs("div", { className: cn("flex items-center gap-2", className), "aria-label": "Digital clock", children: [_jsx("style", { children: `
322
- .flip-top {
323
- background: #1a1a1a;
324
- border-radius: 8px 8px 0 0;
325
- animation: sgFlipTop 0.6s cubic-bezier(0.4, 0.0, 0.2, 1) both;
326
- backface-visibility: hidden;
327
- transform-style: preserve-3d;
328
- will-change: transform;
329
- box-shadow: 0 2px 8px rgba(0,0,0,0.3), inset 0 -2px 4px rgba(0,0,0,0.2);
330
- }
331
- .flip-bottom {
332
- background: #1a1a1a;
333
- border-radius: 0 0 8px 8px;
334
- animation: sgFlipBottom 0.6s cubic-bezier(0.4, 0.0, 0.2, 1) both;
335
- animation-delay: 0.6s;
336
- backface-visibility: hidden;
337
- transform-style: preserve-3d;
338
- will-change: transform;
339
- box-shadow: 0 -2px 8px rgba(0,0,0,0.3), inset 0 2px 4px rgba(0,0,0,0.2);
340
- }
341
- @keyframes sgFlipTop {
342
- 0% {
343
- transform: rotateX(0deg);
344
- z-index: 30;
345
- }
346
- 100% {
347
- transform: rotateX(-180deg);
348
- z-index: 5;
349
- }
350
- }
351
- @keyframes sgFlipBottom {
352
- 0% {
353
- transform: rotateX(180deg);
354
- z-index: 5;
355
- }
356
- 100% {
357
- transform: rotateX(0deg);
358
- z-index: 30;
359
- }
360
- }
321
+ return (_jsxs("div", { className: cn("flex items-center gap-2", className), "aria-label": "Digital clock", children: [_jsx("style", { children: `
322
+ .flip-top {
323
+ background: #1a1a1a;
324
+ border-radius: 8px 8px 0 0;
325
+ animation: sgFlipTop 0.6s cubic-bezier(0.4, 0.0, 0.2, 1) both;
326
+ backface-visibility: hidden;
327
+ transform-style: preserve-3d;
328
+ will-change: transform;
329
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3), inset 0 -2px 4px rgba(0,0,0,0.2);
330
+ }
331
+ .flip-bottom {
332
+ background: #1a1a1a;
333
+ border-radius: 0 0 8px 8px;
334
+ animation: sgFlipBottom 0.6s cubic-bezier(0.4, 0.0, 0.2, 1) both;
335
+ animation-delay: 0.6s;
336
+ backface-visibility: hidden;
337
+ transform-style: preserve-3d;
338
+ will-change: transform;
339
+ box-shadow: 0 -2px 8px rgba(0,0,0,0.3), inset 0 2px 4px rgba(0,0,0,0.2);
340
+ }
341
+ @keyframes sgFlipTop {
342
+ 0% {
343
+ transform: rotateX(0deg);
344
+ z-index: 30;
345
+ }
346
+ 100% {
347
+ transform: rotateX(-180deg);
348
+ z-index: 5;
349
+ }
350
+ }
351
+ @keyframes sgFlipBottom {
352
+ 0% {
353
+ transform: rotateX(180deg);
354
+ z-index: 5;
355
+ }
356
+ 100% {
357
+ transform: rotateX(0deg);
358
+ z-index: 30;
359
+ }
360
+ }
361
361
  ` }), _jsx(FlipDigitCard, { ch: hh.charAt(0), w: w, h: h, digitFont: digitFont }), _jsx(FlipDigitCard, { ch: hh.charAt(1), w: w, h: h, digitFont: digitFont }), _jsx(Colon, {}), _jsx(FlipDigitCard, { ch: mm.charAt(0), w: w, h: h, digitFont: digitFont }), _jsx(FlipDigitCard, { ch: mm.charAt(1), w: w, h: h, digitFont: digitFont }), showSeconds ? (_jsxs(_Fragment, { children: [_jsx(Colon, {}), _jsx(FlipDigitCard, { ch: ss.charAt(0), w: w, h: h, digitFont: digitFont }), _jsx(FlipDigitCard, { ch: ss.charAt(1), w: w, h: h, digitFont: digitFont })] })) : null, format === "12h" && dayPeriod ? _jsx(PeriodCell, { value: dayPeriod.toUpperCase() }) : null] }));
362
362
  }
363
363
  if (digitalStyle === "roller3d") {
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export { SgInputPhone } from "./inputs/SgInputPhone";
20
20
  export type { SgInputPhoneProps } from "./inputs/SgInputPhone";
21
21
  export { SgInputEmail } from "./inputs/SgInputEmail";
22
22
  export { SgInputPassword } from "./inputs/SgInputPassword";
23
+ export { SgInputOTP } from "./inputs/SgInputOTP";
24
+ export type { SgInputOTPProps, SgInputOTPRef } from "./inputs/SgInputOTP";
23
25
  export { SgInputDate } from "./inputs/SgInputDate";
24
26
  export { SgInputBirthDate } from "./inputs/SgInputBirthDate";
25
27
  export { SgAutocomplete } from "./inputs/SgAutocomplete";
@@ -61,6 +63,8 @@ export { SgStack } from "./layout/SgStack";
61
63
  export type { SgStackProps } from "./layout/SgStack";
62
64
  export { SgCard } from "./layout/SgCard";
63
65
  export type { SgCardProps, SgCardVariant, SgCardSize } from "./layout/SgCard";
66
+ export { default as SgPlayground } from "./others/SgPlayground";
67
+ export type { SgPlaygroundProps } from "./others/SgPlayground";
64
68
  export { SgToolBar, SgToolbarIconButton } from "./layout/SgToolBar";
65
69
  export type { SgToolBarProps, SgToolBarOrientation, SgToolBarSeverity, SgToolBarSize, SgToolbarIconButtonProps } from "./layout/SgToolBar";
66
70
  export { SgDockLayout } from "./layout/SgDockLayout";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { SgInputPostalCode } from "./inputs/SgInputPostalCode";
10
10
  export { SgInputPhone } from "./inputs/SgInputPhone";
11
11
  export { SgInputEmail } from "./inputs/SgInputEmail";
12
12
  export { SgInputPassword } from "./inputs/SgInputPassword";
13
+ export { SgInputOTP } from "./inputs/SgInputOTP";
13
14
  export { SgInputDate } from "./inputs/SgInputDate";
14
15
  export { SgInputBirthDate } from "./inputs/SgInputBirthDate";
15
16
  export { SgAutocomplete } from "./inputs/SgAutocomplete";
@@ -32,6 +33,7 @@ export { SgPanel } from "./layout/SgPanel";
32
33
  export { SgGrid } from "./layout/SgGrid";
33
34
  export { SgStack } from "./layout/SgStack";
34
35
  export { SgCard } from "./layout/SgCard";
36
+ export { default as SgPlayground } from "./others/SgPlayground";
35
37
  export { SgToolBar, SgToolbarIconButton } from "./layout/SgToolBar";
36
38
  export { SgDockLayout } from "./layout/SgDockLayout";
37
39
  export { SgDockZone } from "./layout/SgDockZone";
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import type { FieldValues, RegisterOptions, UseFormRegister } from "react-hook-form";
3
+ import type { RhfFieldProps } from "../rhf";
4
+ export type SgInputOTPRef = {
5
+ focus: (slotIndex?: number) => void;
6
+ clear: () => void;
7
+ getRawValue: () => string;
8
+ getMaskedValue: () => string;
9
+ };
10
+ export type SgInputOTPProps = {
11
+ id: string;
12
+ label?: string;
13
+ hintText?: string;
14
+ mask?: string;
15
+ value?: string;
16
+ defaultValue?: string;
17
+ error?: string;
18
+ className?: string;
19
+ groupClassName?: string;
20
+ slotClassName?: string;
21
+ separatorClassName?: string;
22
+ inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue"> & {
23
+ ref?: React.Ref<HTMLInputElement>;
24
+ };
25
+ width?: number | string;
26
+ enabled?: boolean;
27
+ readOnly?: boolean;
28
+ required?: boolean;
29
+ requiredMessage?: string;
30
+ validation?: (rawValue: string, maskedValue: string) => string | null;
31
+ validateOnBlur?: boolean;
32
+ onValidation?: (message: string | null) => void;
33
+ onChange?: (maskedValue: string) => void;
34
+ onRawChange?: (rawValue: string) => void;
35
+ onComplete?: (value: string) => void;
36
+ onEnter?: () => void;
37
+ onExit?: () => void;
38
+ onClear?: () => void;
39
+ register?: UseFormRegister<FieldValues>;
40
+ rules?: RegisterOptions<FieldValues>;
41
+ } & RhfFieldProps;
42
+ export declare const SgInputOTP: React.ForwardRefExoticComponent<{
43
+ id: string;
44
+ label?: string;
45
+ hintText?: string;
46
+ mask?: string;
47
+ value?: string;
48
+ defaultValue?: string;
49
+ error?: string;
50
+ className?: string;
51
+ groupClassName?: string;
52
+ slotClassName?: string;
53
+ separatorClassName?: string;
54
+ inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue"> & {
55
+ ref?: React.Ref<HTMLInputElement>;
56
+ };
57
+ width?: number | string;
58
+ enabled?: boolean;
59
+ readOnly?: boolean;
60
+ required?: boolean;
61
+ requiredMessage?: string;
62
+ validation?: (rawValue: string, maskedValue: string) => string | null;
63
+ validateOnBlur?: boolean;
64
+ onValidation?: (message: string | null) => void;
65
+ onChange?: (maskedValue: string) => void;
66
+ onRawChange?: (rawValue: string) => void;
67
+ onComplete?: (value: string) => void;
68
+ onEnter?: () => void;
69
+ onExit?: () => void;
70
+ onClear?: () => void;
71
+ register?: UseFormRegister<FieldValues>;
72
+ rules?: RegisterOptions<FieldValues>;
73
+ } & RhfFieldProps & React.RefAttributes<SgInputOTPRef>>;
74
+ //# sourceMappingURL=SgInputOTP.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SgInputOTP.d.ts","sourceRoot":"","sources":["../../src/inputs/SgInputOTP.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAGV,WAAW,EACX,eAAe,EACf,eAAe,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAsB5C,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,MAAM,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,IAAI,CACf,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,OAAO,GAAG,cAAc,CACzB,GAAG;QACF,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;KACnC,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACtE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;CACtC,GAAG,aAAa,CAAC;AAyqBlB,eAAO,MAAM,UAAU;QA1sBjB,MAAM;YACF,MAAM;eACH,MAAM;WACV,MAAM;YACL,MAAM;mBACC,MAAM;YACb,MAAM;gBACF,MAAM;qBACD,MAAM;oBACP,MAAM;yBACD,MAAM;iBACd,IAAI,CACf,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,OAAO,GAAG,cAAc,CACzB,GAAG;QACF,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;KACnC;YACO,MAAM,GAAG,MAAM;cACb,OAAO;eACN,OAAO;eACP,OAAO;sBACA,MAAM;iBACX,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;qBACpD,OAAO;mBACT,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;eACpC,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI;kBAC1B,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI;iBAC3B,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;cAC1B,MAAM,IAAI;aACX,MAAM,IAAI;cACT,MAAM,IAAI;eACT,eAAe,CAAC,WAAW,CAAC;YAC/B,eAAe,CAAC,WAAW,CAAC;uDAkuBpC,CAAC"}
@@ -0,0 +1,492 @@
1
+ "use client";
2
+ import { createElement as _createElement } from "react";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import React from "react";
5
+ import { Controller } from "react-hook-form";
6
+ import { t, useComponentsI18n } from "../i18n";
7
+ const DEFAULT_MASK = "999999";
8
+ const DIGIT_RE = /^[0-9]$/;
9
+ const ALPHANUMERIC_RE = /^[A-Za-z0-9]$/;
10
+ function normalizeExternalValue(value) {
11
+ if (value == null)
12
+ return "";
13
+ if (typeof value === "string")
14
+ return value;
15
+ if (typeof value === "number")
16
+ return String(value);
17
+ return String(value);
18
+ }
19
+ function toCssSize(value) {
20
+ if (value === undefined)
21
+ return "fit-content";
22
+ return typeof value === "number" ? `${value}px` : value;
23
+ }
24
+ function mergeRefs(...refs) {
25
+ return (node) => {
26
+ for (const ref of refs) {
27
+ if (!ref)
28
+ continue;
29
+ if (typeof ref === "function") {
30
+ ref(node);
31
+ continue;
32
+ }
33
+ if (typeof ref === "object" && "current" in ref) {
34
+ ref.current = node;
35
+ }
36
+ }
37
+ };
38
+ }
39
+ function buildMask(source) {
40
+ const tokens = [];
41
+ const slots = [];
42
+ let nextSlotIndex = 0;
43
+ for (const char of source) {
44
+ if (char === "#" || char === "9") {
45
+ const slot = {
46
+ type: "slot",
47
+ slotIndex: nextSlotIndex,
48
+ slotKind: char === "#" ? "alphanumeric" : "digit"
49
+ };
50
+ tokens.push(slot);
51
+ slots.push(slot);
52
+ nextSlotIndex += 1;
53
+ }
54
+ else {
55
+ tokens.push({ type: "separator", value: char });
56
+ }
57
+ }
58
+ return { tokens, slots };
59
+ }
60
+ function parseMask(mask) {
61
+ const source = mask && mask.length > 0 ? mask : DEFAULT_MASK;
62
+ const parsed = buildMask(source);
63
+ if (parsed.slots.length > 0)
64
+ return parsed;
65
+ return buildMask(DEFAULT_MASK);
66
+ }
67
+ function buildEmptySlotValues(slots) {
68
+ return Array.from({ length: slots.length }, () => "");
69
+ }
70
+ function isAcceptedChar(slot, char) {
71
+ if (char.length !== 1)
72
+ return false;
73
+ if (slot.slotKind === "digit")
74
+ return DIGIT_RE.test(char);
75
+ return ALPHANUMERIC_RE.test(char);
76
+ }
77
+ function textToSlotValues(text, slots) {
78
+ const next = buildEmptySlotValues(slots);
79
+ let nextSlotIndex = 0;
80
+ for (const char of text) {
81
+ if (nextSlotIndex >= slots.length)
82
+ break;
83
+ const slot = slots[nextSlotIndex];
84
+ if (!slot)
85
+ break;
86
+ if (!isAcceptedChar(slot, char))
87
+ continue;
88
+ next[nextSlotIndex] = char;
89
+ nextSlotIndex += 1;
90
+ }
91
+ return next;
92
+ }
93
+ function slotValuesToRaw(slotValues) {
94
+ return slotValues.join("");
95
+ }
96
+ function hasRemainingSlotBeforeLastFilled(tokens, tokenIndex, lastFilledSlotIndex) {
97
+ for (let index = tokenIndex + 1; index < tokens.length; index += 1) {
98
+ const token = tokens[index];
99
+ if (!token || token.type !== "slot")
100
+ continue;
101
+ return token.slotIndex <= lastFilledSlotIndex;
102
+ }
103
+ return false;
104
+ }
105
+ function slotValuesToMasked(tokens, slotValues) {
106
+ let lastFilledSlotIndex = -1;
107
+ for (let index = slotValues.length - 1; index >= 0; index -= 1) {
108
+ const value = slotValues[index];
109
+ if (!value)
110
+ continue;
111
+ lastFilledSlotIndex = index;
112
+ break;
113
+ }
114
+ if (lastFilledSlotIndex < 0)
115
+ return "";
116
+ let masked = "";
117
+ let hasWrittenAnySlot = false;
118
+ for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) {
119
+ const token = tokens[tokenIndex];
120
+ if (!token)
121
+ continue;
122
+ if (token.type === "separator") {
123
+ if (!hasWrittenAnySlot)
124
+ continue;
125
+ if (!hasRemainingSlotBeforeLastFilled(tokens, tokenIndex, lastFilledSlotIndex))
126
+ continue;
127
+ masked += token.value;
128
+ continue;
129
+ }
130
+ if (token.slotIndex > lastFilledSlotIndex)
131
+ break;
132
+ const value = slotValues[token.slotIndex] ?? "";
133
+ if (!value)
134
+ continue;
135
+ masked += value;
136
+ hasWrittenAnySlot = true;
137
+ }
138
+ return masked;
139
+ }
140
+ function areSlotValuesEqual(left, right) {
141
+ if (left.length !== right.length)
142
+ return false;
143
+ for (let index = 0; index < left.length; index += 1) {
144
+ if ((left[index] ?? "") !== (right[index] ?? ""))
145
+ return false;
146
+ }
147
+ return true;
148
+ }
149
+ function clampIndex(index, slotCount) {
150
+ if (slotCount <= 0)
151
+ return 0;
152
+ if (index < 0)
153
+ return 0;
154
+ if (index > slotCount - 1)
155
+ return slotCount - 1;
156
+ return index;
157
+ }
158
+ const SgInputOTPBase = React.forwardRef(function SgInputOTPBase(props, ref) {
159
+ const i18n = useComponentsI18n();
160
+ const { id, label, hintText, mask, value, defaultValue, error, className, groupClassName, slotClassName, separatorClassName, inputProps, width, enabled = true, readOnly = false, required = false, requiredMessage, validation, validateOnBlur = true, onValidation, onChange, onRawChange, onComplete, onEnter, onExit, onClear, name, onFieldChange, onFieldBlur, hiddenFieldRef } = props;
161
+ const parsedMask = React.useMemo(() => parseMask(mask), [mask]);
162
+ const tokens = parsedMask.tokens;
163
+ const slots = parsedMask.slots;
164
+ const slotCount = slots.length;
165
+ const makeSlotValues = React.useCallback((text) => textToSlotValues(text, slots), [slots]);
166
+ const [slotValues, setSlotValues] = React.useState(() => {
167
+ const seeded = normalizeExternalValue(value ?? defaultValue ?? "");
168
+ return makeSlotValues(seeded);
169
+ });
170
+ const slotValuesRef = React.useRef(slotValues);
171
+ const slotRefs = React.useRef([]);
172
+ const hiddenInputRef = React.useRef(null);
173
+ const hasInteractedRef = React.useRef(false);
174
+ const focusWithinRef = React.useRef(false);
175
+ const [internalError, setInternalError] = React.useState(null);
176
+ const { ref: inputRef, className: inputClassName, onChange: onSlotInputChange, onPaste: onSlotInputPaste, onKeyDown: onSlotInputKeyDown, onFocus: onSlotInputFocus, onBlur: onSlotInputBlur, autoComplete: slotAutoComplete, inputMode: slotInputMode, pattern: slotPattern, disabled: inputDisabled, readOnly: inputReadOnly, autoFocus: slotAutoFocus, ...restSlotInputProps } = inputProps ?? {};
177
+ React.useEffect(() => {
178
+ slotValuesRef.current = slotValues;
179
+ }, [slotValues]);
180
+ React.useEffect(() => {
181
+ if (slotRefs.current.length <= slotCount)
182
+ return;
183
+ slotRefs.current = slotRefs.current.slice(0, slotCount);
184
+ }, [slotCount]);
185
+ React.useEffect(() => {
186
+ if (value === undefined)
187
+ return;
188
+ const next = makeSlotValues(normalizeExternalValue(value));
189
+ setSlotValues((prev) => (areSlotValuesEqual(prev, next) ? prev : next));
190
+ }, [makeSlotValues, value]);
191
+ React.useEffect(() => {
192
+ if (value !== undefined)
193
+ return;
194
+ setSlotValues((prev) => {
195
+ const next = makeSlotValues(slotValuesToRaw(prev));
196
+ return areSlotValuesEqual(prev, next) ? prev : next;
197
+ });
198
+ }, [makeSlotValues, value]);
199
+ const focusSlot = React.useCallback((requestedIndex) => {
200
+ const nextIndex = clampIndex(requestedIndex, slotCount);
201
+ const node = slotRefs.current[nextIndex];
202
+ if (!node)
203
+ return;
204
+ node.focus();
205
+ node.select();
206
+ }, [slotCount]);
207
+ const runValidation = React.useCallback((rawValue, maskedValue) => {
208
+ if (!rawValue && required) {
209
+ const message = requiredMessage ?? t(i18n, "components.inputs.required");
210
+ setInternalError(message);
211
+ onValidation?.(message);
212
+ return message;
213
+ }
214
+ if (validation) {
215
+ const message = validation(rawValue, maskedValue);
216
+ setInternalError(message);
217
+ onValidation?.(message ?? null);
218
+ return message ?? null;
219
+ }
220
+ setInternalError(null);
221
+ onValidation?.(null);
222
+ return null;
223
+ }, [i18n, onValidation, required, requiredMessage, validation]);
224
+ const commitSlotValues = React.useCallback((nextSlotValues, options) => {
225
+ const previousRawValue = slotValuesToRaw(slotValuesRef.current);
226
+ const nextRawValue = slotValuesToRaw(nextSlotValues);
227
+ const nextMaskedValue = slotValuesToMasked(tokens, nextSlotValues);
228
+ hasInteractedRef.current = true;
229
+ slotValuesRef.current = nextSlotValues;
230
+ setSlotValues(nextSlotValues);
231
+ if (hiddenInputRef.current) {
232
+ hiddenInputRef.current.value = nextRawValue;
233
+ }
234
+ onChange?.(nextMaskedValue);
235
+ onRawChange?.(nextRawValue);
236
+ onFieldChange?.(nextRawValue);
237
+ const shouldValidateNow = options?.triggerValidation ?? !validateOnBlur;
238
+ if (shouldValidateNow) {
239
+ runValidation(nextRawValue, nextMaskedValue);
240
+ }
241
+ const isComplete = nextSlotValues.length > 0 && nextSlotValues.every((part) => part.length === 1);
242
+ if (isComplete) {
243
+ onComplete?.(nextMaskedValue);
244
+ }
245
+ if (previousRawValue.length > 0 && nextRawValue.length === 0) {
246
+ onClear?.();
247
+ }
248
+ if (options?.focusIndex === undefined)
249
+ return;
250
+ const nextFocusIndex = clampIndex(options.focusIndex, slotCount);
251
+ if (typeof window !== "undefined") {
252
+ window.requestAnimationFrame(() => focusSlot(nextFocusIndex));
253
+ return;
254
+ }
255
+ focusSlot(nextFocusIndex);
256
+ }, [
257
+ focusSlot,
258
+ onChange,
259
+ onClear,
260
+ onComplete,
261
+ onFieldChange,
262
+ onRawChange,
263
+ runValidation,
264
+ slotCount,
265
+ tokens,
266
+ validateOnBlur
267
+ ]);
268
+ const applyTextFrom = React.useCallback((startSlotIndex, text, replaceTail) => {
269
+ if (!text)
270
+ return;
271
+ const next = [...slotValuesRef.current];
272
+ const boundedStart = clampIndex(startSlotIndex, slotCount);
273
+ if (replaceTail) {
274
+ for (let index = boundedStart; index < next.length; index += 1) {
275
+ next[index] = "";
276
+ }
277
+ }
278
+ let pointer = boundedStart;
279
+ for (const char of text) {
280
+ if (pointer >= slots.length)
281
+ break;
282
+ const slot = slots[pointer];
283
+ if (!slot)
284
+ break;
285
+ if (!isAcceptedChar(slot, char))
286
+ continue;
287
+ next[pointer] = char;
288
+ pointer += 1;
289
+ }
290
+ const focusIndex = clampIndex(pointer, slotCount);
291
+ commitSlotValues(next, { focusIndex });
292
+ }, [commitSlotValues, slotCount, slots]);
293
+ React.useImperativeHandle(ref, () => ({
294
+ focus: (slotIndex = 0) => {
295
+ focusSlot(slotIndex);
296
+ },
297
+ clear: () => {
298
+ commitSlotValues(buildEmptySlotValues(slots), {
299
+ focusIndex: 0,
300
+ triggerValidation: !validateOnBlur
301
+ });
302
+ },
303
+ getRawValue: () => slotValuesToRaw(slotValuesRef.current),
304
+ getMaskedValue: () => slotValuesToMasked(tokens, slotValuesRef.current)
305
+ }), [commitSlotValues, focusSlot, slots, tokens, validateOnBlur]);
306
+ const handleGroupFocusCapture = React.useCallback(() => {
307
+ if (focusWithinRef.current)
308
+ return;
309
+ focusWithinRef.current = true;
310
+ onEnter?.();
311
+ }, [onEnter]);
312
+ const handleGroupBlurCapture = React.useCallback((event) => {
313
+ const nextTarget = event.relatedTarget;
314
+ if (nextTarget && event.currentTarget.contains(nextTarget))
315
+ return;
316
+ focusWithinRef.current = false;
317
+ const nextRawValue = slotValuesToRaw(slotValuesRef.current);
318
+ const nextMaskedValue = slotValuesToMasked(tokens, slotValuesRef.current);
319
+ if (validateOnBlur || hasInteractedRef.current) {
320
+ runValidation(nextRawValue, nextMaskedValue);
321
+ }
322
+ onExit?.();
323
+ onFieldBlur?.(nextRawValue);
324
+ }, [onExit, onFieldBlur, runValidation, tokens, validateOnBlur]);
325
+ const handleSlotChange = React.useCallback((slotIndex, event) => {
326
+ onSlotInputChange?.(event);
327
+ if (event.defaultPrevented)
328
+ return;
329
+ const slot = slots[slotIndex];
330
+ if (!slot)
331
+ return;
332
+ const typed = event.currentTarget.value ?? "";
333
+ if (!typed) {
334
+ const next = [...slotValuesRef.current];
335
+ next[slotIndex] = "";
336
+ commitSlotValues(next, { focusIndex: slotIndex });
337
+ return;
338
+ }
339
+ if (typed.length > 1) {
340
+ applyTextFrom(slotIndex, typed, true);
341
+ return;
342
+ }
343
+ const nextChar = typed.slice(-1);
344
+ if (!isAcceptedChar(slot, nextChar)) {
345
+ event.currentTarget.value = slotValuesRef.current[slotIndex] ?? "";
346
+ return;
347
+ }
348
+ const next = [...slotValuesRef.current];
349
+ next[slotIndex] = nextChar;
350
+ commitSlotValues(next, { focusIndex: slotIndex + 1 });
351
+ }, [applyTextFrom, commitSlotValues, onSlotInputChange, slots]);
352
+ const handleSlotPaste = React.useCallback((slotIndex, event) => {
353
+ onSlotInputPaste?.(event);
354
+ if (event.defaultPrevented)
355
+ return;
356
+ event.preventDefault();
357
+ const pasted = event.clipboardData.getData("text") ?? "";
358
+ if (!pasted)
359
+ return;
360
+ applyTextFrom(slotIndex, pasted, true);
361
+ }, [applyTextFrom, onSlotInputPaste]);
362
+ const handleSlotKeyDown = React.useCallback((slotIndex, event) => {
363
+ onSlotInputKeyDown?.(event);
364
+ if (event.defaultPrevented)
365
+ return;
366
+ const slot = slots[slotIndex];
367
+ if (!slot)
368
+ return;
369
+ if (event.key === "ArrowLeft") {
370
+ event.preventDefault();
371
+ focusSlot(slotIndex - 1);
372
+ return;
373
+ }
374
+ if (event.key === "ArrowRight") {
375
+ event.preventDefault();
376
+ focusSlot(slotIndex + 1);
377
+ return;
378
+ }
379
+ if (event.key === "Backspace") {
380
+ event.preventDefault();
381
+ const next = [...slotValuesRef.current];
382
+ const currentValue = next[slotIndex] ?? "";
383
+ if (currentValue) {
384
+ next[slotIndex] = "";
385
+ commitSlotValues(next, { focusIndex: slotIndex });
386
+ return;
387
+ }
388
+ if (slotIndex === 0)
389
+ return;
390
+ next[slotIndex - 1] = "";
391
+ commitSlotValues(next, { focusIndex: slotIndex - 1 });
392
+ return;
393
+ }
394
+ if (event.key === "Delete") {
395
+ event.preventDefault();
396
+ const next = [...slotValuesRef.current];
397
+ next[slotIndex] = "";
398
+ commitSlotValues(next, { focusIndex: slotIndex });
399
+ return;
400
+ }
401
+ if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
402
+ if (!isAcceptedChar(slot, event.key)) {
403
+ event.preventDefault();
404
+ }
405
+ }
406
+ }, [commitSlotValues, focusSlot, onSlotInputKeyDown, slots]);
407
+ const hasError = Boolean(error ?? internalError);
408
+ const resolvedError = error ?? internalError ?? undefined;
409
+ const isDisabled = enabled === false || Boolean(inputDisabled);
410
+ const isReadOnly = readOnly || Boolean(inputReadOnly);
411
+ const mergedSlotClass = [
412
+ "h-12 w-11 rounded-md border bg-white px-0 text-center text-base font-medium shadow-sm outline-none transition-all",
413
+ hasError
414
+ ? "border-[hsl(var(--destructive))] focus:border-[hsl(var(--destructive))] focus:ring-2 focus:ring-[hsl(var(--destructive)/0.25)]"
415
+ : "border-border focus:border-[hsl(var(--primary))] focus:ring-2 focus:ring-[hsl(var(--primary)/0.25)]",
416
+ "disabled:cursor-not-allowed disabled:bg-muted/40 disabled:text-foreground/40",
417
+ "read-only:cursor-default read-only:bg-muted/30",
418
+ inputClassName ?? "",
419
+ slotClassName ?? ""
420
+ ]
421
+ .filter(Boolean)
422
+ .join(" ");
423
+ const setHiddenInputRef = React.useMemo(() => mergeRefs(hiddenFieldRef, hiddenInputRef), [hiddenFieldRef]);
424
+ const setSlotRef = React.useCallback((slotIndex, node) => {
425
+ slotRefs.current[slotIndex] = node;
426
+ if (slotIndex !== 0)
427
+ return;
428
+ if (!inputRef)
429
+ return;
430
+ if (typeof inputRef === "function") {
431
+ inputRef(node);
432
+ return;
433
+ }
434
+ if (typeof inputRef === "object" && "current" in inputRef) {
435
+ inputRef.current = node;
436
+ }
437
+ }, [inputRef]);
438
+ const labelText = label ?? "";
439
+ const firstSlotId = `${id}-slot-0`;
440
+ return (_jsxs("div", { className: className, style: { width: toCssSize(width) }, children: [labelText ? (_jsxs("label", { htmlFor: firstSlotId, className: "mb-2 block text-sm font-medium text-foreground/80", children: [labelText, required ? (_jsx("span", { className: "ml-1 text-[hsl(var(--destructive))]", "aria-hidden": "true", children: "*" })) : null] })) : null, _jsx("div", { className: groupClassName ?? "inline-flex items-center gap-2", onFocusCapture: handleGroupFocusCapture, onBlurCapture: handleGroupBlurCapture, role: "group", "aria-label": labelText || id, "aria-invalid": hasError || undefined, children: tokens.map((token, tokenIndex) => {
441
+ if (token.type === "separator") {
442
+ return (_jsx("span", { className: separatorClassName ??
443
+ "select-none px-1 text-lg font-semibold leading-none text-foreground/60", "aria-hidden": "true", children: token.value }, `${id}-separator-${tokenIndex}`));
444
+ }
445
+ const slotIndex = token.slotIndex;
446
+ const slotValue = slotValues[slotIndex] ?? "";
447
+ const computedInputMode = token.slotKind === "digit" ? "numeric" : slotInputMode ?? "text";
448
+ const computedPattern = token.slotKind === "digit"
449
+ ? "[0-9]*"
450
+ : slotPattern ?? "[A-Za-z0-9]*";
451
+ return (_createElement("input", { ...restSlotInputProps, key: `${id}-slot-${slotIndex}`, id: `${id}-slot-${slotIndex}`, type: "text", value: slotValue, maxLength: 1, autoComplete: slotIndex === 0 ? slotAutoComplete ?? "one-time-code" : "off", autoFocus: slotIndex === 0 ? slotAutoFocus : false, inputMode: computedInputMode, pattern: computedPattern, className: mergedSlotClass, disabled: isDisabled, readOnly: isReadOnly, "aria-label": labelText ? `${labelText} ${slotIndex + 1}` : `OTP ${slotIndex + 1}`, ref: (node) => setSlotRef(slotIndex, node), onFocus: (event) => {
452
+ event.currentTarget.select();
453
+ onSlotInputFocus?.(event);
454
+ }, onBlur: (event) => {
455
+ onSlotInputBlur?.(event);
456
+ }, onChange: (event) => handleSlotChange(slotIndex, event), onPaste: (event) => handleSlotPaste(slotIndex, event), onKeyDown: (event) => handleSlotKeyDown(slotIndex, event) }));
457
+ }) }), hintText ? _jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: hintText }) : null, resolvedError ? _jsx("p", { "data-sg-error": true, className: "mt-1 text-xs text-red-600", children: resolvedError }) : null, _jsx("input", { id: `${id}-value`, type: "hidden", name: name, value: slotValuesToRaw(slotValues), ref: setHiddenInputRef, readOnly: true, "aria-hidden": "true" })] }));
458
+ });
459
+ function createSyntheticChangeEvent(name, value) {
460
+ const target = { name, value };
461
+ return {
462
+ target,
463
+ currentTarget: target
464
+ };
465
+ }
466
+ function createSyntheticBlurEvent(name, value) {
467
+ const target = { name, value };
468
+ return {
469
+ target,
470
+ currentTarget: target,
471
+ relatedTarget: null
472
+ };
473
+ }
474
+ export const SgInputOTP = React.forwardRef(function SgInputOTP(props, ref) {
475
+ const { control, name, register, rules, ...rest } = props;
476
+ if (name && register) {
477
+ const registration = register(name, rules);
478
+ return (_jsx(SgInputOTPBase, { ...rest, ref: ref, name: name, hiddenFieldRef: registration.ref, onFieldChange: (rawValue) => {
479
+ registration.onChange(createSyntheticChangeEvent(name, rawValue));
480
+ }, onFieldBlur: (rawValue) => {
481
+ registration.onBlur(createSyntheticBlurEvent(name, rawValue));
482
+ } }));
483
+ }
484
+ if (control && name) {
485
+ return (_jsx(Controller, { name: name, control: control, render: ({ field, fieldState }) => (_jsx(SgInputOTPBase, { ...rest, ref: ref, name: name, value: normalizeExternalValue(field.value), error: rest.error ?? fieldState.error?.message, hiddenFieldRef: field.ref, onFieldChange: (rawValue) => {
486
+ field.onChange(rawValue);
487
+ }, onFieldBlur: () => {
488
+ field.onBlur();
489
+ } })) }));
490
+ }
491
+ return _jsx(SgInputOTPBase, { ...rest, ref: ref, name: name });
492
+ });
@@ -0,0 +1,24 @@
1
+ export type SgPlaygroundProps = {
2
+ code: string;
3
+ interactive?: boolean;
4
+ codeContract?: "renderBody" | "appFile";
5
+ title?: string;
6
+ description?: string;
7
+ height?: number | string;
8
+ expandedHeight?: number | string;
9
+ expandable?: boolean;
10
+ resizable?: boolean;
11
+ resizeAxis?: "vertical" | "horizontal" | "both";
12
+ previewPadding?: number | string;
13
+ className?: string;
14
+ dependencies?: Record<string, string>;
15
+ defaultImports?: string;
16
+ previewWrapperClassName?: string;
17
+ seedgridDependency?: string;
18
+ withCard?: boolean;
19
+ collapsible?: boolean;
20
+ defaultOpen?: boolean;
21
+ cardId?: string;
22
+ };
23
+ export default function SgPlayground(props: Readonly<SgPlaygroundProps>): import("react/jsx-runtime").JSX.Element;
24
+ //# sourceMappingURL=SgPlayground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SgPlayground.d.ts","sourceRoot":"","sources":["../../src/others/SgPlayground.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAqVF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,iBAAiB,CAAC,2CAoMtE"}
@@ -0,0 +1,389 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { SandpackCodeEditor, SandpackPreview, SandpackProvider, useSandpack } from "@codesandbox/sandpack-react";
5
+ import { SgButton } from "../buttons/SgButton";
6
+ import { SgCard } from "../layout/SgCard";
7
+ function cn(...parts) {
8
+ return parts.filter(Boolean).join(" ");
9
+ }
10
+ const DEFAULT_SEEDGRID_DEPENDENCY = "0.2.6";
11
+ const DEFAULT_SEEDGRID_PEER_DEPENDENCIES = {
12
+ "@codesandbox/sandpack-react": "^2.20.0",
13
+ "react-hook-form": "^7.0.0",
14
+ "lucide-react": "^0.468.0",
15
+ "@tiptap/react": "^2.9.1",
16
+ "@tiptap/starter-kit": "^2.9.1",
17
+ "@tiptap/extension-underline": "^2.9.1",
18
+ "@tiptap/extension-link": "^2.9.1",
19
+ "@tiptap/extension-image": "^2.9.1",
20
+ "@tiptap/extension-text-align": "^2.9.1",
21
+ "@tiptap/extension-text-style": "^2.9.1",
22
+ "@tiptap/extension-color": "^2.9.1",
23
+ "@tiptap/extension-highlight": "^2.9.1",
24
+ "@tiptap/extension-subscript": "^2.9.1",
25
+ "@tiptap/extension-superscript": "^2.9.1",
26
+ "@tiptap/extension-font-family": "^2.9.1"
27
+ };
28
+ const SANDPACK_EXTERNAL_RESOURCES = [
29
+ // Prebuilt utility CSS so classes from @seedgrid/fe-components can render inside Sandpack
30
+ "https://unpkg.com/tailwindcss@2.2.19/dist/tailwind.min.css"
31
+ ];
32
+ const SANDPACK_FALLBACK_THEME_VARS = {
33
+ "--background": "0 0% 100%",
34
+ "--foreground": "222.2 84% 4.9%",
35
+ "--primary": "142 76% 36%",
36
+ "--primary-foreground": "0 0% 100%",
37
+ "--secondary": "210 40% 96.1%",
38
+ "--secondary-foreground": "222.2 47.4% 11.2%",
39
+ "--accent": "152 57% 40%",
40
+ "--accent-foreground": "0 0% 100%",
41
+ "--destructive": "0 84.2% 60.2%",
42
+ "--destructive-foreground": "0 0% 100%",
43
+ "--border": "214.3 31.8% 91.4%",
44
+ "--ring": "var(--primary)",
45
+ "--sg-primary-600": "22 163 74",
46
+ "--sg-secondary-600": "82 82 91",
47
+ "--sg-tertiary-600": "20 184 166",
48
+ "--sg-error-600": "220 38 38",
49
+ "--sg-warning-600": "217 119 6",
50
+ "--sg-info-600": "2 132 199",
51
+ "--sg-success-600": "22 163 74"
52
+ };
53
+ const SANDPACK_CORE_THEME_VARS = [
54
+ "--background",
55
+ "--foreground",
56
+ "--primary",
57
+ "--primary-foreground",
58
+ "--secondary",
59
+ "--secondary-foreground",
60
+ "--accent",
61
+ "--accent-foreground",
62
+ "--destructive",
63
+ "--destructive-foreground",
64
+ "--border",
65
+ "--ring"
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; }
105
+ `;
106
+ function parseRgbParts(raw) {
107
+ const value = raw.trim();
108
+ if (!value)
109
+ return null;
110
+ const normalized = value
111
+ .replace(/^rgb\(/i, "")
112
+ .replace(/\)$/g, "")
113
+ .replace(/\//g, " ")
114
+ .replace(/,/g, " ")
115
+ .trim();
116
+ const pieces = normalized
117
+ .split(/\s+/)
118
+ .map((part) => Number(part))
119
+ .filter((num) => Number.isFinite(num));
120
+ if (pieces.length < 3)
121
+ return null;
122
+ const r = pieces[0];
123
+ const g = pieces[1];
124
+ const b = pieces[2];
125
+ const clamp = (n) => Math.max(0, Math.min(255, Math.round(n)));
126
+ return [clamp(r), clamp(g), clamp(b)];
127
+ }
128
+ function rgbToHslTriplet(r, g, b) {
129
+ const rr = r / 255;
130
+ const gg = g / 255;
131
+ const bb = b / 255;
132
+ const max = Math.max(rr, gg, bb);
133
+ const min = Math.min(rr, gg, bb);
134
+ const delta = max - min;
135
+ let h = 0;
136
+ let s = 0;
137
+ const l = (max + min) / 2;
138
+ if (delta !== 0) {
139
+ s = delta / (1 - Math.abs(2 * l - 1));
140
+ switch (max) {
141
+ case rr:
142
+ h = ((gg - bb) / delta + (gg < bb ? 6 : 0)) / 6;
143
+ break;
144
+ case gg:
145
+ h = ((bb - rr) / delta + 2) / 6;
146
+ break;
147
+ default:
148
+ h = ((rr - gg) / delta + 4) / 6;
149
+ break;
150
+ }
151
+ }
152
+ const hue = Math.round(h * 360);
153
+ const sat = Math.round(s * 100);
154
+ const lig = Math.round(l * 100);
155
+ return `${hue} ${sat}% ${lig}%`;
156
+ }
157
+ function toHslFromRgbVar(value) {
158
+ if (!value)
159
+ return null;
160
+ const parts = parseRgbParts(value);
161
+ if (!parts)
162
+ return null;
163
+ return rgbToHslTriplet(parts[0], parts[1], parts[2]);
164
+ }
165
+ function mapSgVarsToCoreVars(themeVars) {
166
+ const mapped = {};
167
+ const assignFromSg = (coreVar, sgVar) => {
168
+ const hsl = toHslFromRgbVar(themeVars[sgVar]);
169
+ if (hsl)
170
+ mapped[coreVar] = hsl;
171
+ };
172
+ assignFromSg("--background", "--sg-bg");
173
+ assignFromSg("--foreground", "--sg-text");
174
+ assignFromSg("--primary", "--sg-primary-600");
175
+ assignFromSg("--primary-foreground", "--sg-on-primary");
176
+ assignFromSg("--secondary", "--sg-secondary-600");
177
+ assignFromSg("--secondary-foreground", "--sg-on-secondary");
178
+ assignFromSg("--accent", "--sg-tertiary-600");
179
+ assignFromSg("--accent-foreground", "--sg-on-tertiary");
180
+ assignFromSg("--destructive", "--sg-error-600");
181
+ assignFromSg("--destructive-foreground", "--sg-on-error");
182
+ assignFromSg("--border", "--sg-border");
183
+ assignFromSg("--ring", "--sg-primary-400");
184
+ return mapped;
185
+ }
186
+ function readThemeVarsFromHost() {
187
+ if (typeof window === "undefined")
188
+ return {};
189
+ const computed = window.getComputedStyle(document.documentElement);
190
+ const themeVars = {};
191
+ for (const varName of SANDPACK_CORE_THEME_VARS) {
192
+ const value = computed.getPropertyValue(varName).trim();
193
+ if (value)
194
+ themeVars[varName] = value;
195
+ }
196
+ for (let index = 0; index < computed.length; index += 1) {
197
+ const varName = computed.item(index)?.trim();
198
+ if (!varName || !varName.startsWith("--sg-"))
199
+ continue;
200
+ const value = computed.getPropertyValue(varName).trim();
201
+ if (value)
202
+ themeVars[varName] = value;
203
+ }
204
+ Object.assign(themeVars, mapSgVarsToCoreVars(themeVars));
205
+ return themeVars;
206
+ }
207
+ function normalizeCssSize(value) {
208
+ return typeof value === "number" ? `${value}px` : value;
209
+ }
210
+ function buildSandpackStylesCss(themeVars, previewPadding) {
211
+ const mergedVars = {
212
+ ...SANDPACK_FALLBACK_THEME_VARS,
213
+ ...themeVars,
214
+ "--sg-preview-padding": previewPadding
215
+ };
216
+ const rootVars = Object.entries(mergedVars)
217
+ .sort(([a], [b]) => a.localeCompare(b))
218
+ .map(([varName, value]) => ` ${varName}: ${value};`)
219
+ .join("\n");
220
+ return `:root {
221
+ ${rootVars}
222
+ }
223
+
224
+ ${SANDPACK_BASE_STYLES_CSS}`;
225
+ }
226
+ function ReadonlyBlock({ code }) {
227
+ return (_jsx("pre", { className: "overflow-auto rounded-lg border border-border bg-muted/30 p-4 text-xs leading-relaxed", children: _jsx("code", { children: code }) }));
228
+ }
229
+ function buildAppTsxFromRenderBody(renderBody, defaultImports, wrapperClassName) {
230
+ const body = renderBody
231
+ .replace(/\t/g, " ")
232
+ .split("\n")
233
+ .map((line) => (line ? ` ${line}` : ""))
234
+ .join("\n");
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
+ }
246
+ `;
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
+ }
260
+ `;
261
+ }
262
+ async function copyText(text) {
263
+ if (!text)
264
+ return false;
265
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
266
+ await navigator.clipboard.writeText(text);
267
+ return true;
268
+ }
269
+ if (typeof document === "undefined")
270
+ return false;
271
+ const textarea = document.createElement("textarea");
272
+ textarea.value = text;
273
+ textarea.setAttribute("readonly", "");
274
+ textarea.style.position = "fixed";
275
+ textarea.style.opacity = "0";
276
+ document.body.appendChild(textarea);
277
+ textarea.select();
278
+ const ok = document.execCommand("copy");
279
+ document.body.removeChild(textarea);
280
+ return ok;
281
+ }
282
+ function CopyButton() {
283
+ const { sandpack } = useSandpack();
284
+ const [copyState, setCopyState] = React.useState("idle");
285
+ const handleCopy = React.useCallback(async () => {
286
+ try {
287
+ const activeFilePath = sandpack.activeFile;
288
+ const activeCode = sandpack.files[activeFilePath]?.code ?? "";
289
+ const copied = await copyText(activeCode);
290
+ setCopyState(copied ? "success" : "error");
291
+ }
292
+ catch {
293
+ setCopyState("error");
294
+ }
295
+ }, [sandpack.activeFile, sandpack.files]);
296
+ React.useEffect(() => {
297
+ if (copyState === "idle")
298
+ return;
299
+ const timerId = window.setTimeout(() => setCopyState("idle"), 1400);
300
+ return () => window.clearTimeout(timerId);
301
+ }, [copyState]);
302
+ return (_jsx(SgButton, { appearance: "outline", size: "sm", onClick: handleCopy, children: copyState === "success" ? "Copiado" : copyState === "error" ? "Erro" : "Copiar" }));
303
+ }
304
+ function RunButton() {
305
+ const { sandpack } = useSandpack();
306
+ return (_jsx(SgButton, { severity: "primary", size: "sm", onClick: () => sandpack.runSandpack(), children: "Run" }));
307
+ }
308
+ export default function SgPlayground(props) {
309
+ const { code, interactive = false, codeContract = "renderBody", title, description, height = 360, expandedHeight = "70vh", expandable = true, resizable = true, resizeAxis = "vertical", previewPadding, className, dependencies, defaultImports, previewWrapperClassName = "h-[420px] rounded-xl border border-border bg-muted/30 p-3", seedgridDependency, withCard = true, collapsible = true, defaultOpen = true, cardId } = props;
310
+ const effectivePreviewPadding = normalizeCssSize(previewPadding ?? (codeContract === "appFile" ? 12 : 0));
311
+ const [sandpackStylesCss, setSandpackStylesCss] = React.useState(() => buildSandpackStylesCss(readThemeVarsFromHost(), effectivePreviewPadding));
312
+ const [isExpanded, setIsExpanded] = React.useState(false);
313
+ React.useEffect(() => {
314
+ if (typeof window === "undefined")
315
+ return;
316
+ const root = document.documentElement;
317
+ const refreshStyles = () => {
318
+ const liveThemeVars = readThemeVarsFromHost();
319
+ setSandpackStylesCss(buildSandpackStylesCss(liveThemeVars, effectivePreviewPadding));
320
+ };
321
+ let frameId = null;
322
+ const scheduleRefresh = () => {
323
+ if (frameId !== null)
324
+ return;
325
+ frameId = window.requestAnimationFrame(() => {
326
+ frameId = null;
327
+ refreshStyles();
328
+ });
329
+ };
330
+ const observer = new MutationObserver(scheduleRefresh);
331
+ observer.observe(root, {
332
+ attributes: true,
333
+ attributeFilter: ["style", "class", "data-theme"]
334
+ });
335
+ refreshStyles();
336
+ return () => {
337
+ observer.disconnect();
338
+ if (frameId !== null) {
339
+ window.cancelAnimationFrame(frameId);
340
+ }
341
+ };
342
+ }, [effectivePreviewPadding]);
343
+ const seedgridDefaultImports = defaultImports ?? `import {
344
+ SgScreen,
345
+ SgMainPanel,
346
+ SgPanel,
347
+ SgGrid,
348
+ SgStack,
349
+ SgButton,
350
+ SgAutocomplete
351
+ } from "@seedgrid/fe-components";`;
352
+ const appTsx = codeContract === "appFile"
353
+ ? code
354
+ : buildAppTsxFromRenderBody(code, seedgridDefaultImports, previewWrapperClassName);
355
+ const resolvedSeedgridDependency = seedgridDependency ??
356
+ process.env.NEXT_PUBLIC_SANDPACK_SEEDGRID_DEPENDENCY ??
357
+ DEFAULT_SEEDGRID_DEPENDENCY;
358
+ const files = {
359
+ "/App.tsx": { code: appTsx, active: true },
360
+ "/styles.css": { code: sandpackStylesCss || buildSandpackStylesCss({}, effectivePreviewPadding) }
361
+ };
362
+ const deps = {
363
+ react: "^19.0.0",
364
+ "react-dom": "^19.0.0",
365
+ ...DEFAULT_SEEDGRID_PEER_DEPENDENCIES,
366
+ "@seedgrid/fe-components": resolvedSeedgridDependency,
367
+ ...(dependencies ?? {})
368
+ };
369
+ const currentHeight = isExpanded ? expandedHeight : height;
370
+ const resizeClass = !resizable
371
+ ? undefined
372
+ : resizeAxis === "vertical"
373
+ ? "resize-y"
374
+ : resizeAxis === "horizontal"
375
+ ? "resize-x"
376
+ : "resize";
377
+ const content = interactive ? (_jsx("div", { className: cn(withCard ? "" : "rounded-lg border border-border", withCard ? undefined : className), children: _jsxs(SandpackProvider, { template: "react-ts", files: files, customSetup: { dependencies: deps }, options: {
378
+ autorun: false,
379
+ activeFile: "/App.tsx",
380
+ visibleFiles: ["/App.tsx"],
381
+ externalResources: SANDPACK_EXTERNAL_RESOURCES
382
+ }, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [withCard ? null : _jsx("span", { className: "text-sm font-medium", children: title ?? "Example" }), _jsx("span", { className: "text-xs text-muted-foreground", children: codeContract === "renderBody" ? "editable snippet" : "editable App.tsx" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [expandable ? (_jsx(SgButton, { appearance: "outline", size: "sm", onClick: () => setIsExpanded((prev) => !prev), children: isExpanded ? "Reduzir" : "Expandir" })) : null, _jsx(RunButton, {})] })] }), _jsxs("div", { className: cn("grid overflow-auto min-h-[260px] min-w-[480px]", resizeClass), style: {
383
+ gridTemplateColumns: "1fr 1fr",
384
+ height: currentHeight
385
+ }, children: [_jsxs("div", { className: "min-w-0 border-r border-border", children: [_jsx(SandpackCodeEditor, { showLineNumbers: true, wrapContent: true, showTabs: false, showRunButton: false, style: { height: "100%" } }), _jsx("div", { className: "flex justify-end border-t border-border px-3 py-2", children: _jsx(CopyButton, {}) })] }), _jsx("div", { className: "min-w-0", children: _jsx(SandpackPreview, { style: { height: "100%" }, showOpenInCodeSandbox: false, showRefreshButton: false, showRestartButton: false }) })] })] }) })) : (_jsxs("div", { className: cn(withCard ? undefined : "space-y-2", withCard ? undefined : className), children: [withCard ? null : title ? _jsx("div", { className: "text-sm font-medium", children: title }) : null, _jsx(ReadonlyBlock, { code: code })] }));
386
+ if (!withCard)
387
+ return content;
388
+ return (_jsx(SgCard, { id: cardId, title: title ?? "Codigo", description: description, collapsible: collapsible, defaultOpen: defaultOpen, className: cn("rounded-lg", className), bodyClassName: "p-0", children: content }));
389
+ }
package/package.json CHANGED
@@ -1,54 +1,57 @@
1
- {
2
- "name": "@seedgrid/fe-components",
3
- "version": "0.2.7",
4
- "type": "module",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./dist/index.d.ts",
10
- "default": "./dist/index.js"
11
- }
12
- },
13
- "files": [
14
- "dist"
15
- ],
16
- "scripts": {
17
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
18
- "build": "pnpm run clean && tsc -p tsconfig.json",
19
- "typecheck": "tsc -p tsconfig.json --noEmit"
20
- },
21
- "peerDependencies": {
22
- "react": "^18.2.0 || ^19.0.0",
23
- "react-hook-form": "^7.0.0",
24
- "lucide-react": "^0.468.0",
25
- "@tiptap/react": "^2.9.1",
26
- "@tiptap/starter-kit": "^2.9.1",
27
- "@tiptap/extension-underline": "^2.9.1",
28
- "@tiptap/extension-link": "^2.9.1",
29
- "@tiptap/extension-image": "^2.9.1",
30
- "@tiptap/extension-text-align": "^2.9.1",
31
- "@tiptap/extension-text-style": "^2.9.1",
32
- "@tiptap/extension-color": "^2.9.1",
33
- "@tiptap/extension-highlight": "^2.9.1",
34
- "@tiptap/extension-subscript": "^2.9.1",
35
- "@tiptap/extension-superscript": "^2.9.1",
36
- "@tiptap/extension-font-family": "^2.9.1"
37
- },
38
- "devDependencies": {
39
- "react-hook-form": "^7.0.0",
40
- "lucide-react": "^0.468.0",
41
- "@tiptap/react": "^2.9.1",
42
- "@tiptap/starter-kit": "^2.9.1",
43
- "@tiptap/extension-underline": "^2.9.1",
44
- "@tiptap/extension-link": "^2.9.1",
45
- "@tiptap/extension-image": "^2.9.1",
46
- "@tiptap/extension-text-align": "^2.9.1",
47
- "@tiptap/extension-text-style": "^2.9.1",
48
- "@tiptap/extension-color": "^2.9.1",
49
- "@tiptap/extension-highlight": "^2.9.1",
50
- "@tiptap/extension-subscript": "^2.9.1",
51
- "@tiptap/extension-superscript": "^2.9.1",
52
- "@tiptap/extension-font-family": "^2.9.1"
53
- }
54
- }
1
+ {
2
+ "name": "@seedgrid/fe-components",
3
+ "version": "0.2.9",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
18
+ "build": "pnpm run clean && tsc -p tsconfig.json",
19
+ "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput",
20
+ "typecheck": "tsc -p tsconfig.json --noEmit"
21
+ },
22
+ "peerDependencies": {
23
+ "react": "^18.2.0 || ^19.0.0",
24
+ "react-hook-form": "^7.0.0",
25
+ "@codesandbox/sandpack-react": "^2.20.0",
26
+ "lucide-react": "^0.468.0",
27
+ "@tiptap/react": "^2.9.1",
28
+ "@tiptap/starter-kit": "^2.9.1",
29
+ "@tiptap/extension-underline": "^2.9.1",
30
+ "@tiptap/extension-link": "^2.9.1",
31
+ "@tiptap/extension-image": "^2.9.1",
32
+ "@tiptap/extension-text-align": "^2.9.1",
33
+ "@tiptap/extension-text-style": "^2.9.1",
34
+ "@tiptap/extension-color": "^2.9.1",
35
+ "@tiptap/extension-highlight": "^2.9.1",
36
+ "@tiptap/extension-subscript": "^2.9.1",
37
+ "@tiptap/extension-superscript": "^2.9.1",
38
+ "@tiptap/extension-font-family": "^2.9.1"
39
+ },
40
+ "devDependencies": {
41
+ "react-hook-form": "^7.0.0",
42
+ "@codesandbox/sandpack-react": "^2.20.0",
43
+ "lucide-react": "^0.468.0",
44
+ "@tiptap/react": "^2.9.1",
45
+ "@tiptap/starter-kit": "^2.9.1",
46
+ "@tiptap/extension-underline": "^2.9.1",
47
+ "@tiptap/extension-link": "^2.9.1",
48
+ "@tiptap/extension-image": "^2.9.1",
49
+ "@tiptap/extension-text-align": "^2.9.1",
50
+ "@tiptap/extension-text-style": "^2.9.1",
51
+ "@tiptap/extension-color": "^2.9.1",
52
+ "@tiptap/extension-highlight": "^2.9.1",
53
+ "@tiptap/extension-subscript": "^2.9.1",
54
+ "@tiptap/extension-superscript": "^2.9.1",
55
+ "@tiptap/extension-font-family": "^2.9.1"
56
+ }
57
+ }