@seedgrid/fe-components 2026.8.6 → 2026.8.7

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 (61) hide show
  1. package/dist/ai/seedgrid-components.manifest.json +330 -148
  2. package/dist/commons/SgSkeleton.meta.js +3 -3
  3. package/dist/commons/SgToastHost.meta.js +1 -1
  4. package/dist/commons/SgToaster.meta.js +1 -1
  5. package/dist/commons/SgWhistleHost.meta.d.ts.map +1 -1
  6. package/dist/commons/SgWhistleHost.meta.js +1 -0
  7. package/dist/commons/SgWhistler.d.ts +10 -0
  8. package/dist/commons/SgWhistler.d.ts.map +1 -1
  9. package/dist/commons/SgWhistler.js +8 -4
  10. package/dist/commons/SgWhistler.meta.d.ts.map +1 -1
  11. package/dist/commons/SgWhistler.meta.js +1 -0
  12. package/dist/commons/dismissSgToast.meta.js +3 -3
  13. package/dist/commons/dismissSgWhistle.meta.js +3 -3
  14. package/dist/commons/subscribeSgToasts.meta.js +3 -3
  15. package/dist/commons/subscribeSgWhistles.meta.js +3 -3
  16. package/dist/commons/toast.meta.d.ts.map +1 -1
  17. package/dist/commons/toast.meta.js +32 -11
  18. package/dist/commons/whistle.meta.d.ts.map +1 -1
  19. package/dist/commons/whistle.meta.js +27 -9
  20. package/dist/digits/fade-digit/SgFadeDigit.meta.js +1 -1
  21. package/dist/digits/matrix-digit/SgMatrixDigit.meta.js +1 -1
  22. package/dist/digits/roller3d-digit/SgRoller3DDigit.meta.js +1 -1
  23. package/dist/digits/segment-digit/SgSegmentDigit.meta.js +1 -1
  24. package/dist/digits/seven-segment-digit/SgSevenSegmentDigit.meta.js +1 -1
  25. package/dist/environment/useSgEnvironment.meta.js +6 -6
  26. package/dist/environment/useSgNamespaceProvider.meta.js +2 -2
  27. package/dist/environment/useSgPersistence.meta.js +6 -6
  28. package/dist/environment/useSgPersistentState.meta.d.ts.map +1 -1
  29. package/dist/environment/useSgPersistentState.meta.js +15 -9
  30. package/dist/gadgets/calendar/SgCalendar.meta.js +1 -1
  31. package/dist/gadgets/clock/themes/useSgClockThemeResolver.meta.d.ts.map +1 -1
  32. package/dist/gadgets/clock/themes/useSgClockThemeResolver.meta.js +24 -17
  33. package/dist/gadgets/clock/useSgTime.meta.js +3 -3
  34. package/dist/gadgets/qr-code/SgQRCode.meta.js +1 -1
  35. package/dist/gadgets/string-animator/SgStringAnimator.meta.js +1 -1
  36. package/dist/i18n/en-US.d.ts.map +1 -1
  37. package/dist/i18n/en-US.js +1 -0
  38. package/dist/i18n/es.d.ts.map +1 -1
  39. package/dist/i18n/es.js +1 -0
  40. package/dist/i18n/fr.d.ts.map +1 -1
  41. package/dist/i18n/fr.js +1 -0
  42. package/dist/i18n/pt-BR.d.ts.map +1 -1
  43. package/dist/i18n/pt-BR.js +1 -0
  44. package/dist/i18n/pt-PT.d.ts.map +1 -1
  45. package/dist/i18n/pt-PT.js +1 -0
  46. package/dist/i18n/useComponentsI18n.meta.js +6 -6
  47. package/dist/layout/SgCarousel.meta.js +1 -1
  48. package/dist/layout/SgExpandablePanel.meta.d.ts.map +1 -1
  49. package/dist/layout/SgExpandablePanel.meta.js +5 -1
  50. package/dist/layout/SgGrid.meta.js +3 -3
  51. package/dist/layout/SgMenu.meta.d.ts.map +1 -1
  52. package/dist/layout/SgMenu.meta.js +39 -3
  53. package/dist/layout/SgStack.meta.js +3 -3
  54. package/dist/sandbox.cjs +34 -34
  55. package/dist/wizard/SgWizard.d.ts +12 -0
  56. package/dist/wizard/SgWizard.d.ts.map +1 -1
  57. package/dist/wizard/SgWizard.js +11 -2
  58. package/dist/wizard/SgWizard.meta.d.ts.map +1 -1
  59. package/dist/wizard/SgWizard.meta.js +11 -1
  60. package/dist/wizard/SgWizardPage.meta.js +1 -1
  61. package/package.json +3 -3
@@ -21,6 +21,18 @@ export type SgWizardProps = {
21
21
  onBeforeNext?: (index: number) => boolean | Promise<boolean>;
22
22
  onBeforeFinish?: (index: number) => boolean | Promise<boolean>;
23
23
  validateStep?: (index: number) => boolean | Promise<boolean>;
24
+ /**
25
+ * Desabilita o avanco de forma declarativa: o botao "Proximo" fica desabilitado (opaco, com
26
+ * cursor de bloqueio) e o stepper para de oferecer as etapas seguintes.
27
+ *
28
+ * Complementa `onBeforeNext`/`validateStep`, que so' agem NO CLIQUE. Quando o consumidor ja
29
+ * sabe que a etapa nao pode avancar — tipicamente o resultado de uma checagem assincrona que
30
+ * ja' terminou, como "este CNPJ ja' tem cadastro" — o botao continuava com aparencia de
31
+ * clicavel e o clique nao fazia nada, sem explicar por que.
32
+ *
33
+ * Nao afeta o botao de conclusao da ultima etapa: para esse caso existe `onBeforeFinish`.
34
+ */
35
+ nextDisabled?: boolean;
24
36
  initialStep?: number;
25
37
  labels?: Partial<SgWizardLabels>;
26
38
  stepper?: SgWizardStepper;
@@ -1 +1 @@
1
- {"version":3,"file":"SgWizard.d.ts","sourceRoot":"","sources":["../../src/wizard/SgWizard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAEpD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAqGF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,2CA2J5C"}
1
+ {"version":3,"file":"SgWizard.d.ts","sourceRoot":"","sources":["../../src/wizard/SgWizard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAEpD;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAqGF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,2CAkK5C"}
@@ -30,6 +30,7 @@ export function SgWizard(props) {
30
30
  const pages = React.Children.toArray(props.children).filter((child) => React.isValidElement(child) && child.type === SgWizardPage);
31
31
  const stepper = props.stepper ?? "none";
32
32
  const stepNavigation = props.stepNavigation ?? "previous-and-next";
33
+ const nextDisabled = props.nextDisabled ?? false;
33
34
  const [step, setStep] = React.useState(() => clampWizardStep(props.initialStep, pages.length));
34
35
  const [isFinishing, setIsFinishing] = React.useState(false);
35
36
  const [isValidating, setIsValidating] = React.useState(false);
@@ -61,6 +62,10 @@ export function SgWizard(props) {
61
62
  const goNext = async () => {
62
63
  if (isLast)
63
64
  return;
65
+ // Guarda aqui, e nao so' no `disabled` do botao: o avanco pelo stepper cai neste mesmo
66
+ // caminho, entao um unico ponto cobre as duas formas de ir para frente.
67
+ if (nextDisabled)
68
+ return;
64
69
  if (isValidating)
65
70
  return;
66
71
  setIsValidating(true);
@@ -80,13 +85,17 @@ export function SgWizard(props) {
80
85
  }
81
86
  };
82
87
  const canNavigateStep = React.useCallback((targetStep) => {
88
+ // Com o avanco bloqueado, o stepper nao pode continuar oferecendo as etapas seguintes como
89
+ // clicaveis — seria um atalho com aparencia de habilitado que nao leva a lugar nenhum.
90
+ if (nextDisabled && targetStep > step)
91
+ return false;
83
92
  return canNavigateToWizardStep({
84
93
  currentStep: step,
85
94
  targetStep,
86
95
  pageCount: pages.length,
87
96
  stepNavigation
88
97
  });
89
- }, [pages.length, step, stepNavigation]);
98
+ }, [pages.length, step, stepNavigation, nextDisabled]);
90
99
  const goPrevious = () => {
91
100
  if (isFirst)
92
101
  return;
@@ -128,5 +137,5 @@ export function SgWizard(props) {
128
137
  setIsFinishing(false);
129
138
  }
130
139
  };
131
- return (_jsxs("div", { className: props.className, style: props.style, children: [stepper !== "none" ? (_jsx(StepperBar, { pages: pages, currentStep: step, mode: stepper, i18n: i18n, canNavigateStep: canNavigateStep, onNavigateStep: handleStepNavigation })) : null, _jsx("div", { ref: pageRef, children: pages[step] }), _jsxs("div", { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [_jsx("div", { children: !isFirst ? (_jsx("button", { type: "button", onClick: goPrevious, className: "inline-flex h-10 items-center justify-center rounded-full border border-border px-5 text-sm font-semibold text-foreground/80 transition hover:bg-muted/60", children: labels.previous })) : null }), _jsx("div", { className: "flex items-center gap-3", children: !isLast ? (_jsx("button", { type: "button", onClick: goNext, disabled: isValidating, className: "inline-flex h-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] px-5 text-sm font-semibold text-white shadow-lg shadow-[hsl(var(--primary)/0.35)] transition hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-60", children: labels.next })) : (_jsx("button", { type: "button", onClick: handleFinish, disabled: isFinishing || isValidating, className: "inline-flex h-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] px-5 text-sm font-semibold text-white shadow-lg shadow-[hsl(var(--primary)/0.35)] transition hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-60", children: labels.finish })) })] })] }));
140
+ return (_jsxs("div", { className: props.className, style: props.style, children: [stepper !== "none" ? (_jsx(StepperBar, { pages: pages, currentStep: step, mode: stepper, i18n: i18n, canNavigateStep: canNavigateStep, onNavigateStep: handleStepNavigation })) : null, _jsx("div", { ref: pageRef, children: pages[step] }), _jsxs("div", { className: "mt-6 flex flex-wrap items-center justify-between gap-3", children: [_jsx("div", { children: !isFirst ? (_jsx("button", { type: "button", onClick: goPrevious, className: "inline-flex h-10 items-center justify-center rounded-full border border-border px-5 text-sm font-semibold text-foreground/80 transition hover:bg-muted/60", children: labels.previous })) : null }), _jsx("div", { className: "flex items-center gap-3", children: !isLast ? (_jsx("button", { type: "button", onClick: goNext, disabled: isValidating || nextDisabled, className: "inline-flex h-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] px-5 text-sm font-semibold text-white shadow-lg shadow-[hsl(var(--primary)/0.35)] transition hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-60", children: labels.next })) : (_jsx("button", { type: "button", onClick: handleFinish, disabled: isFinishing || isValidating, className: "inline-flex h-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] px-5 text-sm font-semibold text-white shadow-lg shadow-[hsl(var(--primary)/0.35)] transition hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-60", children: labels.finish })) })] })] }));
132
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SgWizard.meta.d.ts","sourceRoot":"","sources":["../../src/wizard/SgWizard.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,QA8BpB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,WAmBrB,CAAC"}
1
+ {"version":3,"file":"SgWizard.meta.d.ts","sourceRoot":"","sources":["../../src/wizard/SgWizard.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,QAwCpB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,WAmBrB,CAAC"}
@@ -17,12 +17,22 @@ export const sgMeta = {
17
17
  { name: "stepper", type: '"numbered" | "icons" | "none"', default: "none", description: "Modo visual do stepper.", semanticRole: "appearance", bindable: true },
18
18
  { name: "stepNavigation", type: '"none" | "previous" | "previous-and-next"', default: "previous-and-next", description: "Define quais etapas podem ser acessadas clicando no stepper.", semanticRole: "behavior", bindable: true },
19
19
  { name: "validateStep", type: "(stepIndex: number) => boolean | Promise<boolean>", description: "Valida a etapa atual antes de avancar.", semanticRole: "validation", bindable: false },
20
+ { name: "onBeforeNext", type: "(index: number) => boolean | Promise<boolean>", description: "Roda ao clicar em Proximo; devolver false (ou uma Promise<false>) impede o avanco. Enquanto e aguardado, o botao fica desabilitado.", semanticRole: "validation", bindable: false },
21
+ { name: "onBeforeFinish", type: "(index: number) => boolean | Promise<boolean>", description: "Roda ao clicar em concluir; devolver false impede a finalizacao.", semanticRole: "validation", bindable: false },
22
+ { name: "nextDisabled", type: "boolean", default: false, description: "Desabilita o avanco de forma declarativa: o botao Proximo fica desabilitado e o stepper para de oferecer as etapas seguintes. Use quando o bloqueio JA e conhecido (ex.: uma checagem assincrona ja resolveu que a etapa nao pode avancar) — onBeforeNext/validateStep so agem no clique e deixam o botao com aparencia de clicavel. Nao afeta o botao da ultima etapa; para isso use onBeforeFinish.", semanticRole: "behavior", bindable: true },
20
23
  { name: "onStepChange", type: "(index: number) => void", description: "Callback disparado ao trocar de etapa.", semanticRole: "event", bindable: false },
21
24
  { name: "onFinish", type: "() => void | Promise<void>", required: true, description: "Acao executada ao concluir o wizard.", semanticRole: "event", bindable: false }
22
25
  ],
23
26
  states: ["default", "validating", "finishing", "completed"],
24
27
  examples: [
25
- { id: "auto-validation", title: "Auto validation", file: "apps/showcase/src/app/components/sg-wizard/samples/auto-validation.tsx.sample", kind: "sample" },
28
+ { id: "validacao-automatica", title: "Validacao automatica", file: "apps/showcase/src/app/components/sg-wizard/samples/validacao-automatica.tsx.sample", kind: "sample" },
29
+ { id: "validatestep", title: "validateStep", file: "apps/showcase/src/app/components/sg-wizard/samples/validatestep.tsx.sample", kind: "sample" },
30
+ { id: "onbeforenext-async", title: "onBeforeNext assincrono", file: "apps/showcase/src/app/components/sg-wizard/samples/onbeforenext-async.tsx.sample", kind: "sample" },
31
+ { id: "nextdisabled", title: "Avanco bloqueado (nextDisabled)", file: "apps/showcase/src/app/components/sg-wizard/samples/nextdisabled.tsx.sample", kind: "sample" },
32
+ { id: "stepnavigation", title: "stepNavigation", file: "apps/showcase/src/app/components/sg-wizard/samples/stepnavigation.tsx.sample", kind: "sample" },
33
+ { id: "stepper-numerado", title: "Stepper numerado", file: "apps/showcase/src/app/components/sg-wizard/samples/stepper-numerado.tsx.sample", kind: "sample" },
34
+ { id: "stepper-com-icones", title: "Stepper com icones", file: "apps/showcase/src/app/components/sg-wizard/samples/stepper-com-icones.tsx.sample", kind: "sample" },
35
+ { id: "labels-customizados", title: "Labels customizados", file: "apps/showcase/src/app/components/sg-wizard/samples/labels-customizados.tsx.sample", kind: "sample" },
26
36
  { id: "playground", title: "Playground", file: "apps/showcase/src/app/components/sg-wizard/sg-wizard.tsx.playground", kind: "playground" }
27
37
  ],
28
38
  showcase: { route: "/components/sg-wizard", hasPlayground: true, hasPropsTable: true },
@@ -18,7 +18,7 @@ export const sgMeta = {
18
18
  { name: "className", type: "string", description: "Classes adicionais da etapa.", semanticRole: "appearance", bindable: true }
19
19
  ],
20
20
  states: ["default", "active", "completed"],
21
- examples: [{ id: "auto-validation", title: "Auto validation", file: "apps/showcase/src/app/components/sg-wizard/samples/auto-validation.tsx.sample", kind: "sample" }],
21
+ examples: [{ id: "validacao-automatica", title: "Validacao automatica", file: "apps/showcase/src/app/components/sg-wizard/samples/validacao-automatica.tsx.sample", kind: "sample" }],
22
22
  showcase: { route: "/components/sg-wizard", hasPlayground: true, hasPropsTable: true },
23
23
  sdui: { rendererType: "navigation.wizard-page", acceptsDataBinding: true, defaultProps: {} }
24
24
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seedgrid/fe-components",
3
- "version": "2026.8.6",
3
+ "version": "2026.8.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -69,7 +69,7 @@
69
69
  "tailwindcss-animate": "^1.0.7",
70
70
  "postcss": "^8.4.45",
71
71
  "autoprefixer": "^10.4.20",
72
- "@seedgrid/fe-theme": "2026.8.6"
72
+ "@seedgrid/fe-theme": "2026.8.7"
73
73
  },
74
74
  "dependencies": {
75
75
  "@pqina/flip": "^1.8.4",
@@ -77,7 +77,7 @@
77
77
  },
78
78
  "scripts": {
79
79
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
80
- "build": "pnpm run clean && node scripts/build-style.mjs && tsc -p tsconfig.json && node scripts/extract-props.mjs && node scripts/build-ai-manifest.mjs && pnpm run build:sandbox",
80
+ "build": "pnpm run clean && node scripts/build-style.mjs && tsc -p tsconfig.json && node scripts/extract-props.mjs && node scripts/build-ai-manifest.mjs && node scripts/validate-example-refs.mjs && pnpm run build:sandbox",
81
81
  "build:sandbox": "tsup --config tsup.sandbox.config.ts",
82
82
  "dev": "node scripts/build-style.mjs && tsc -p tsconfig.json --watch --preserveWatchOutput",
83
83
  "typecheck": "tsc -p tsconfig.json --noEmit",