maquinaweb-ui 2.71.0 → 2.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { ComponentProps, ElementType } from "react";
2
- import * as react_jsx_runtime3 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime4 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/container-animation/container-animation.d.ts
5
5
  type ContainerAnimationProps<T extends ElementType = 'div'> = ComponentProps<'div'> & ComponentProps<T> & {
@@ -23,7 +23,7 @@ declare const ContainerAnimation: <T extends ElementType = "div">({
23
23
  distance,
24
24
  hideNotInView,
25
25
  ...props
26
- }: ContainerAnimationProps<T>) => react_jsx_runtime3.JSX.Element;
26
+ }: ContainerAnimationProps<T>) => react_jsx_runtime4.JSX.Element;
27
27
  //#endregion
28
28
  export { ContainerAnimation, ContainerAnimationProps };
29
29
  //# sourceMappingURL=container-animation.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
2
- import * as react_jsx_runtime1 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime5 from "react/jsx-runtime";
3
3
  import { Matcher } from "react-day-picker";
4
4
 
5
5
  //#region src/components/date-hour-field/DateHourField.d.ts
@@ -29,7 +29,7 @@ declare function DateHourField<TFieldValues extends FieldValues = FieldValues, T
29
29
  help,
30
30
  hourPlaceholder,
31
31
  valueType
32
- }: DateHourFieldProps<TFieldValues, TFieldName>): react_jsx_runtime1.JSX.Element;
32
+ }: DateHourFieldProps<TFieldValues, TFieldName>): react_jsx_runtime5.JSX.Element;
33
33
  //#endregion
34
34
  export { DateHourField, DateHourFieldProps };
35
35
  //# sourceMappingURL=DateHourField.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import { Mask, Options } from "../src/hooks/with-mask.js";
2
2
  import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
3
3
  import { Dispatch, SetStateAction } from "react";
4
- import * as react_jsx_runtime0 from "react/jsx-runtime";
4
+ import * as react_jsx_runtime6 from "react/jsx-runtime";
5
5
  import { PopoverProps } from "@radix-ui/react-popover";
6
6
 
7
7
  //#region src/components/input-suggest/input-suggest.d.ts
@@ -71,7 +71,7 @@ declare function InputSuggest<TFieldValues extends FieldValues = FieldValues, TF
71
71
  debounceTime,
72
72
  maxWait,
73
73
  ...props
74
- }: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps): react_jsx_runtime0.JSX.Element;
74
+ }: InputSuggestProps<TFieldValues, TFieldName> & PopoverProps): react_jsx_runtime6.JSX.Element;
75
75
  //#endregion
76
76
  export { InputSuggest, InputSuggestProps };
77
77
  //# sourceMappingURL=input-suggest.d.ts.map
@@ -8,6 +8,7 @@ import { useRef, useState } from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Check, Loader2, X } from "lucide-react";
10
10
  import { Slot } from "@radix-ui/react-slot";
11
+ import { flushSync } from "react-dom";
11
12
 
12
13
  //#region src/components/landing-text/client-landing-text.tsx
13
14
  function labelFromKey(value) {
@@ -17,20 +18,26 @@ function labelFromKey(value) {
17
18
  function normalizeBaseUrl(baseUrl) {
18
19
  return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
19
20
  }
20
- function getCookieValue(name) {
21
- if (typeof document === "undefined") return;
22
- const key = `${encodeURIComponent(name)}=`;
23
- const cookies = document.cookie ? document.cookie.split("; ") : [];
24
- for (const cookie of cookies) {
25
- if (!cookie.startsWith(key)) continue;
26
- return decodeURIComponent(cookie.slice(key.length));
27
- }
21
+ function parseCookies(cookieHeader) {
22
+ return cookieHeader.split(";").map((part) => part.trim()).filter(Boolean).reduce((acc, part) => {
23
+ const separatorIndex = part.indexOf("=");
24
+ if (separatorIndex < 0) return acc;
25
+ const name = decodeURIComponent(part.slice(0, separatorIndex));
26
+ acc[name] = decodeURIComponent(part.slice(separatorIndex + 1));
27
+ return acc;
28
+ }, {});
29
+ }
30
+ function getTokenCookieValue() {
31
+ if (typeof document === "undefined" || !document.cookie) return;
32
+ const rawToken = parseCookies(document.cookie).token;
33
+ if (!rawToken) return;
34
+ return rawToken.trim().replace(/^"|"$/g, "").replace(/^Token\s+/i, "");
28
35
  }
29
36
  async function persistLandingContent(item, value) {
30
37
  const baseUrl = String(process.env.NEXT_PUBLIC_BASE_URL || "");
31
- const organization = process.env.NEXT_PUBLIC_ORGANIZATION_ID || "";
38
+ const organization = String(process.env.NEXT_PUBLIC_ORGANIZATION_ID || "").trim();
32
39
  if (!baseUrl) return;
33
- const token = getCookieValue("token");
40
+ const token = getTokenCookieValue();
34
41
  if (!token || !organization) throw new Error("Credenciais de edição indisponíveis para salvar conteúdo.");
35
42
  if (!(await fetch(`${normalizeBaseUrl(baseUrl)}/landing-page-contents/upsert/`, {
36
43
  method: "POST",
@@ -54,44 +61,69 @@ async function persistLandingContent(item, value) {
54
61
  })).ok) throw new Error("Nao foi possivel salvar o conteudo.");
55
62
  await refreshTag(`landing-page-content-${item.pageKey}`);
56
63
  }
64
+ function normalizeEditableText(value) {
65
+ return value.replace(/\u00a0/g, " ").replace(/\s+/g, " ").trim();
66
+ }
57
67
  function ClientLandingText({ item, editable = false, children }) {
58
68
  const [isEditing, setIsEditing] = useState(false);
59
69
  const [isSaving, setIsSaving] = useState(false);
60
70
  const [currentValue, setCurrentValue] = useState(item.value);
61
71
  const [draftValue, setDraftValue] = useState(item.value);
72
+ const containerRef = useRef(null);
62
73
  const ref = useRef(null);
74
+ const closeEditing = (value) => {
75
+ if (ref.current) ref.current.innerText = value;
76
+ setDraftValue(value);
77
+ setIsEditing(false);
78
+ };
63
79
  const handleEdit = (event) => {
64
- if (!editable || isSaving) return;
65
- event.preventDefault();
66
80
  event.stopPropagation();
67
- setDraftValue(ref.current?.innerText ?? currentValue);
68
- setIsEditing(true);
69
- requestAnimationFrame(() => {
70
- ref.current?.focus();
81
+ if (!editable || isSaving || isEditing) return;
82
+ const element = event.currentTarget;
83
+ ref.current = element;
84
+ const nextDraft = element.innerText || currentValue;
85
+ flushSync(() => {
86
+ setDraftValue(nextDraft);
87
+ setIsEditing(true);
71
88
  });
72
89
  };
73
- const handleCancel = () => {
74
- if (ref.current) ref.current.innerText = currentValue;
75
- setDraftValue(currentValue);
76
- setIsEditing(false);
90
+ const handleCancel = (event) => {
91
+ event.preventDefault();
92
+ event.stopPropagation();
93
+ closeEditing(currentValue);
77
94
  };
78
- const handleSave = async () => {
95
+ const handleSave = async (event) => {
96
+ event.preventDefault();
97
+ event.stopPropagation();
79
98
  try {
80
99
  setIsSaving(true);
81
100
  await persistLandingContent(item, draftValue);
82
101
  setCurrentValue(draftValue);
83
- if (ref.current) ref.current.innerText = draftValue;
84
- setIsEditing(false);
102
+ closeEditing(draftValue);
85
103
  } finally {
86
104
  setIsSaving(false);
87
105
  }
88
106
  };
89
107
  const handleInput = (event) => {
90
108
  if (!isEditing) return;
109
+ ref.current = event.currentTarget;
91
110
  setDraftValue(event.currentTarget.innerText);
92
111
  };
112
+ const handleBlur = (event) => {
113
+ if (!isEditing || isSaving) return;
114
+ const container = containerRef.current;
115
+ const nextFocused = event.relatedTarget;
116
+ if (container && nextFocused instanceof Node && container.contains(nextFocused)) return;
117
+ const liveValue = event.currentTarget.innerText;
118
+ if (normalizeEditableText(liveValue) !== normalizeEditableText(currentValue)) {
119
+ if (liveValue !== draftValue) setDraftValue(liveValue);
120
+ return;
121
+ }
122
+ closeEditing(currentValue);
123
+ };
93
124
  return /* @__PURE__ */ jsxs("div", {
94
125
  className: "relative",
126
+ ref: containerRef,
95
127
  children: [editable && isEditing && /* @__PURE__ */ jsxs("div", {
96
128
  className: "absolute right-0 z-10 h-fit -top-7 flex",
97
129
  children: [/* @__PURE__ */ jsx(Button, {
@@ -111,10 +143,11 @@ function ClientLandingText({ item, editable = false, children }) {
111
143
  children: isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "animate-spin size-3" }) : /* @__PURE__ */ jsx(Check, {})
112
144
  })]
113
145
  }), /* @__PURE__ */ jsx(Slot, {
114
- className: cn("relative", "after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1", editable && "hover:after:border hover:after:border-input", isEditing && "after:border after:border-input", isEditing && "outline-none cursor-text before:bg-red-500", !editable && "after:hidden"),
146
+ className: cn("relative", "after:pointer-events-none after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1", editable && "hover:after:border hover:after:border-input", isEditing && "after:border after:border-input", isEditing && "outline-none cursor-text before:bg-red-500", !editable && "after:hidden"),
115
147
  contentEditable: editable && isEditing,
116
- onClick: handleEdit,
148
+ onBlur: handleBlur,
117
149
  onInput: handleInput,
150
+ onPointerDownCapture: handleEdit,
118
151
  ref,
119
152
  suppressContentEditableWarning: true,
120
153
  children
@@ -1 +1 @@
1
- {"version":3,"file":"client-landing-text.js","names":[],"sources":["../../src/components/landing-text/client-landing-text.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState } from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { Button } from '../ui/button';\n\nimport { Check, Loader2, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { refreshTag } from '../actions';\nimport type { LandingTextItem } from './types';\n\ninterface ClientLandingTextProps {\n item: LandingTextItem;\n editable?: boolean;\n children: React.ReactNode;\n}\n\nfunction labelFromKey(value: string) {\n if (!value) {\n return '';\n }\n\n return value\n .split(/[-_\\.]/g)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction getCookieValue(name: string): string | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n const key = `${encodeURIComponent(name)}=`;\n const cookies = document.cookie ? document.cookie.split('; ') : [];\n\n for (const cookie of cookies) {\n if (!cookie.startsWith(key)) {\n continue;\n }\n\n return decodeURIComponent(cookie.slice(key.length));\n }\n\n return undefined;\n}\n\nasync function persistLandingContent(item: LandingTextItem, value: string) {\n const baseUrl = String(process.env.NEXT_PUBLIC_BASE_URL || '');\n const organization = process.env.NEXT_PUBLIC_ORGANIZATION_ID || '';\n\n if (!baseUrl) {\n return;\n }\n\n const token = getCookieValue('token');\n\n if (!token || !organization) {\n throw new Error(\n 'Credenciais de edição indisponíveis para salvar conteúdo.'\n );\n }\n\n const endpoint = '/landing-page-contents/upsert/';\n const response = await fetch(`${normalizeBaseUrl(baseUrl)}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Token ${token}`,\n 'X-Organization': organization,\n },\n body: JSON.stringify({\n page_key: item.pageKey,\n page_title: labelFromKey(item.pageKey),\n section_key: item.sectionKey,\n section_title: labelFromKey(item.sectionKey),\n content_key: item.contentKey,\n content_title: labelFromKey(item.contentKey),\n value,\n default_value: item.defaultValue,\n metadata: item.metadata,\n }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n throw new Error('Nao foi possivel salvar o conteudo.');\n }\n\n await refreshTag(`landing-page-content-${item.pageKey}`);\n}\n\nfunction ClientLandingText({\n item,\n editable = false,\n children,\n}: ClientLandingTextProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [currentValue, setCurrentValue] = useState(item.value);\n const [draftValue, setDraftValue] = useState(item.value);\n const ref = useRef<HTMLElement | null>(null);\n\n const handleEdit = (event: React.MouseEvent<HTMLElement>) => {\n if (!editable || isSaving) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const nextDraft = ref.current?.innerText ?? currentValue;\n setDraftValue(nextDraft);\n setIsEditing(true);\n\n requestAnimationFrame(() => {\n ref.current?.focus();\n });\n };\n\n const handleCancel = () => {\n if (ref.current) {\n ref.current.innerText = currentValue;\n }\n setDraftValue(currentValue);\n setIsEditing(false);\n };\n\n const handleSave = async () => {\n try {\n setIsSaving(true);\n await persistLandingContent(item, draftValue);\n setCurrentValue(draftValue);\n if (ref.current) {\n ref.current.innerText = draftValue;\n }\n setIsEditing(false);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleInput = (event: React.FormEvent<HTMLElement>) => {\n if (!isEditing) {\n return;\n }\n setDraftValue(event.currentTarget.innerText);\n };\n\n return (\n <div className=\"relative\">\n {editable && isEditing && (\n <div className=\"absolute right-0 z-10 h-fit -top-7 flex\">\n <Button\n className=\"size-6 rounded-none p-0 text-foreground!\"\n disabled={isSaving}\n onClick={handleCancel}\n size=\"icon\"\n type=\"button\"\n variant=\"outline\"\n >\n <X />\n </Button>\n <Button\n className=\"size-6 rounded-none p-0\"\n disabled={isSaving}\n onClick={handleSave}\n size=\"icon\"\n type=\"button\"\n >\n {isSaving ? <Loader2 className=\"animate-spin size-3\" /> : <Check />}\n </Button>\n </div>\n )}\n\n <Slot\n className={cn(\n 'relative',\n 'after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1',\n editable && 'hover:after:border hover:after:border-input',\n isEditing && 'after:border after:border-input',\n isEditing && 'outline-none cursor-text before:bg-red-500',\n !editable && 'after:hidden'\n )}\n contentEditable={editable && isEditing}\n onClick={handleEdit}\n onInput={handleInput}\n ref={ref}\n suppressContentEditableWarning\n >\n {children}\n </Slot>\n </div>\n );\n}\n\nexport { ClientLandingText };\n"],"mappings":";;;;;;;;;;;;AAmBA,SAAS,aAAa,OAAe;AACnC,KAAI,CAAC,MACH,QAAO;AAGT,QAAO,MACJ,MAAM,UAAU,CAChB,OAAO,QAAQ,CACf,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,IAAI;;AAGd,SAAS,iBAAiB,SAAyB;AACjD,QAAO,QAAQ,SAAS,IAAI,GAAG,QAAQ,MAAM,GAAG,GAAG,GAAG;;AAGxD,SAAS,eAAe,MAAkC;AACxD,KAAI,OAAO,aAAa,YACtB;CAGF,MAAM,MAAM,GAAG,mBAAmB,KAAK,CAAC;CACxC,MAAM,UAAU,SAAS,SAAS,SAAS,OAAO,MAAM,KAAK,GAAG,EAAE;AAElE,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,CAAC,OAAO,WAAW,IAAI,CACzB;AAGF,SAAO,mBAAmB,OAAO,MAAM,IAAI,OAAO,CAAC;;;AAMvD,eAAe,sBAAsB,MAAuB,OAAe;CACzE,MAAM,UAAU,OAAO,QAAQ,IAAI,wBAAwB,GAAG;CAC9D,MAAM,eAAe,QAAQ,IAAI,+BAA+B;AAEhE,KAAI,CAAC,QACH;CAGF,MAAM,QAAQ,eAAe,QAAQ;AAErC,KAAI,CAAC,SAAS,CAAC,aACb,OAAM,IAAI,MACR,4DACD;AAyBH,KAAI,EArBa,MAAM,MAAM,GAAG,iBAAiB,QAAQ,kCAAe;EACtE,QAAQ;EACR,SAAS;GACP,gBAAgB;GAChB,eAAe,SAAS;GACxB,kBAAkB;GACnB;EACD,MAAM,KAAK,UAAU;GACnB,UAAU,KAAK;GACf,YAAY,aAAa,KAAK,QAAQ;GACtC,aAAa,KAAK;GAClB,eAAe,aAAa,KAAK,WAAW;GAC5C,aAAa,KAAK;GAClB,eAAe,aAAa,KAAK,WAAW;GAC5C;GACA,eAAe,KAAK;GACpB,UAAU,KAAK;GAChB,CAAC;EACF,aAAa;EACd,CAAC,EAEY,GACZ,OAAM,IAAI,MAAM,sCAAsC;AAGxD,OAAM,WAAW,wBAAwB,KAAK,UAAU;;AAG1D,SAAS,kBAAkB,EACzB,MACA,WAAW,OACX,YACyB;CACzB,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAC/C,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK,MAAM;CAC5D,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK,MAAM;CACxD,MAAM,MAAM,OAA2B,KAAK;CAE5C,MAAM,cAAc,UAAyC;AAC3D,MAAI,CAAC,YAAY,SACf;AAGF,QAAM,gBAAgB;AACtB,QAAM,iBAAiB;AAGvB,gBADkB,IAAI,SAAS,aAAa,aACpB;AACxB,eAAa,KAAK;AAElB,8BAA4B;AAC1B,OAAI,SAAS,OAAO;IACpB;;CAGJ,MAAM,qBAAqB;AACzB,MAAI,IAAI,QACN,KAAI,QAAQ,YAAY;AAE1B,gBAAc,aAAa;AAC3B,eAAa,MAAM;;CAGrB,MAAM,aAAa,YAAY;AAC7B,MAAI;AACF,eAAY,KAAK;AACjB,SAAM,sBAAsB,MAAM,WAAW;AAC7C,mBAAgB,WAAW;AAC3B,OAAI,IAAI,QACN,KAAI,QAAQ,YAAY;AAE1B,gBAAa,MAAM;YACX;AACR,eAAY,MAAM;;;CAItB,MAAM,eAAe,UAAwC;AAC3D,MAAI,CAAC,UACH;AAEF,gBAAc,MAAM,cAAc,UAAU;;AAG9C,QACE,qBAAC;EAAI,WAAU;aACZ,YAAY,aACX,qBAAC;GAAI,WAAU;cACb,oBAAC;IACC,WAAU;IACV,UAAU;IACV,SAAS;IACT,MAAK;IACL,MAAK;IACL,SAAQ;cAER,oBAAC,MAAI;KACE,EACT,oBAAC;IACC,WAAU;IACV,UAAU;IACV,SAAS;IACT,MAAK;IACL,MAAK;cAEJ,WAAW,oBAAC,WAAQ,WAAU,wBAAwB,GAAG,oBAAC,UAAQ;KAC5D;IACL,EAGR,oBAAC;GACC,WAAW,GACT,YACA,8JACA,YAAY,+CACZ,aAAa,mCACb,aAAa,8CACb,CAAC,YAAY,eACd;GACD,iBAAiB,YAAY;GAC7B,SAAS;GACT,SAAS;GACJ;GACL;GAEC;IACI;GACH"}
1
+ {"version":3,"file":"client-landing-text.js","names":[],"sources":["../../src/components/landing-text/client-landing-text.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState } from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { Button } from '../ui/button';\n\nimport { Check, Loader2, X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { flushSync } from 'react-dom';\nimport { refreshTag } from '../actions';\nimport type { LandingTextItem } from './types';\n\ninterface ClientLandingTextProps {\n item: LandingTextItem;\n editable?: boolean;\n children: React.ReactNode;\n}\n\nfunction labelFromKey(value: string) {\n if (!value) {\n return '';\n }\n\n return value\n .split(/[-_\\.]/g)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction parseCookies(cookieHeader: string): Record<string, string> {\n return cookieHeader\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .reduce<Record<string, string>>((acc, part) => {\n const separatorIndex = part.indexOf('=');\n if (separatorIndex < 0) {\n return acc;\n }\n\n const name = decodeURIComponent(part.slice(0, separatorIndex));\n const value = decodeURIComponent(part.slice(separatorIndex + 1));\n acc[name] = value;\n return acc;\n }, {});\n}\n\nfunction getTokenCookieValue(): string | undefined {\n if (typeof document === 'undefined' || !document.cookie) {\n return undefined;\n }\n\n const rawToken = parseCookies(document.cookie).token;\n if (!rawToken) {\n return undefined;\n }\n\n const withoutQuotes = rawToken.trim().replace(/^\"|\"$/g, '');\n return withoutQuotes.replace(/^Token\\s+/i, '');\n}\n\nasync function persistLandingContent(item: LandingTextItem, value: string) {\n const baseUrl = String(process.env.NEXT_PUBLIC_BASE_URL || '');\n const organization = String(\n process.env.NEXT_PUBLIC_ORGANIZATION_ID || ''\n ).trim();\n\n if (!baseUrl) {\n return;\n }\n\n const token = getTokenCookieValue();\n\n if (!token || !organization) {\n throw new Error(\n 'Credenciais de edição indisponíveis para salvar conteúdo.'\n );\n }\n\n const endpoint = '/landing-page-contents/upsert/';\n const response = await fetch(`${normalizeBaseUrl(baseUrl)}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Token ${token}`,\n 'X-Organization': organization,\n },\n body: JSON.stringify({\n page_key: item.pageKey,\n page_title: labelFromKey(item.pageKey),\n section_key: item.sectionKey,\n section_title: labelFromKey(item.sectionKey),\n content_key: item.contentKey,\n content_title: labelFromKey(item.contentKey),\n value,\n default_value: item.defaultValue,\n metadata: item.metadata,\n }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n throw new Error('Nao foi possivel salvar o conteudo.');\n }\n\n await refreshTag(`landing-page-content-${item.pageKey}`);\n}\n\nfunction normalizeEditableText(value: string): string {\n return value\n .replace(/\\u00a0/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction ClientLandingText({\n item,\n editable = false,\n children,\n}: ClientLandingTextProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [currentValue, setCurrentValue] = useState(item.value);\n const [draftValue, setDraftValue] = useState(item.value);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const ref = useRef<HTMLElement | null>(null);\n\n const closeEditing = (value: string) => {\n if (ref.current) {\n ref.current.innerText = value;\n }\n setDraftValue(value);\n setIsEditing(false);\n };\n\n const handleEdit = (event: React.PointerEvent<HTMLElement>) => {\n event.stopPropagation();\n if (!editable || isSaving || isEditing) {\n return;\n }\n\n const element = event.currentTarget;\n ref.current = element;\n\n const nextDraft = element.innerText || currentValue;\n flushSync(() => {\n setDraftValue(nextDraft);\n setIsEditing(true);\n });\n };\n\n const handleCancel = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n closeEditing(currentValue);\n };\n\n const handleSave = async (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n try {\n setIsSaving(true);\n await persistLandingContent(item, draftValue);\n setCurrentValue(draftValue);\n closeEditing(draftValue);\n } finally {\n setIsSaving(false);\n }\n };\n\n const handleInput = (event: React.FormEvent<HTMLElement>) => {\n if (!isEditing) {\n return;\n }\n ref.current = event.currentTarget;\n setDraftValue(event.currentTarget.innerText);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n if (!isEditing || isSaving) {\n return;\n }\n\n const container = containerRef.current;\n const nextFocused = event.relatedTarget;\n\n if (\n container &&\n nextFocused instanceof Node &&\n container.contains(nextFocused)\n ) {\n return;\n }\n\n const liveValue = event.currentTarget.innerText;\n if (\n normalizeEditableText(liveValue) !== normalizeEditableText(currentValue)\n ) {\n if (liveValue !== draftValue) {\n setDraftValue(liveValue);\n }\n return;\n }\n\n closeEditing(currentValue);\n };\n\n return (\n <div className=\"relative\" ref={containerRef}>\n {editable && isEditing && (\n <div className=\"absolute right-0 z-10 h-fit -top-7 flex\">\n <Button\n className=\"size-6 rounded-none p-0 text-foreground!\"\n disabled={isSaving}\n onClick={handleCancel}\n size=\"icon\"\n type=\"button\"\n variant=\"outline\"\n >\n <X />\n </Button>\n <Button\n className=\"size-6 rounded-none p-0\"\n disabled={isSaving}\n onClick={handleSave}\n size=\"icon\"\n type=\"button\"\n >\n {isSaving ? <Loader2 className=\"animate-spin size-3\" /> : <Check />}\n </Button>\n </div>\n )}\n\n <Slot\n className={cn(\n 'relative',\n 'after:pointer-events-none after:z-10 after:w-full after:h-full after:absolute after:left-1/2 after:-translate-x-1/2 after:top-1/2 after:-translate-y-1/2 after:box-content after:p-1',\n editable && 'hover:after:border hover:after:border-input',\n isEditing && 'after:border after:border-input',\n isEditing && 'outline-none cursor-text before:bg-red-500',\n !editable && 'after:hidden'\n )}\n contentEditable={editable && isEditing}\n onBlur={handleBlur}\n onInput={handleInput}\n onPointerDownCapture={handleEdit}\n ref={ref}\n suppressContentEditableWarning\n >\n {children}\n </Slot>\n </div>\n );\n}\n\nexport { ClientLandingText };\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ServerLandingTextProps } from "./types.js";
2
2
  import { ElementType } from "react";
3
- import * as react_jsx_runtime6 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/components/landing-text/server-landing-text.d.ts
6
6
  declare function ServerLandingText<TAs extends ElementType = 'span'>({
@@ -9,7 +9,7 @@ declare function ServerLandingText<TAs extends ElementType = 'span'>({
9
9
  className,
10
10
  registration,
11
11
  ...props
12
- }: ServerLandingTextProps<TAs>): react_jsx_runtime6.JSX.Element;
12
+ }: ServerLandingTextProps<TAs>): react_jsx_runtime0.JSX.Element;
13
13
  //#endregion
14
14
  export { ServerLandingText };
15
15
  //# sourceMappingURL=server-landing-text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/components/landing-text/types.ts"],"sourcesContent":[],"mappings":";;;KAEY,cAAA;KACA,kBAAA;AADA,UAGK,4BAAA,CAHS;EACd,UAAA,EAAA,MAAA;EAEK,KAAA,EAAA,MAAA;EAMA,QAAA,CAAA,EAHJ,MAGI,CAAA,MAAA,EAAA,OAAA,CAA+B;AAKhD;AAKiB,UAVA,+BAAA,CAeJ;EAGI,UAAA,EAAA,MAAA;EASA,QAAA,EAzBL,4BAyB+B,EAAA;AAM3C;AAMiB,UAlCA,4BAAA,CAkCwB;EAMxB,OAAA,EAAA,MAAA;EAIZ,QAAA,EA1CO,+BA0CS,EAAA;;AAAuC,UAvC3C,yBAAA,CAuC2C;EACrD,QAAA,EAAA,MAAA;EAC2B,WAAA,EAAA,MAAA;EAAzB,WAAA,EAAA,MAAA;EAAqC,KAAA,EAAA,MAAA;EAA1C,QAAA,CAAA,EApCS,MAoCT,CAAA,MAAA,EAAA,OAAA,CAAA;;AAEQ,UAnCK,0BAAA,CAmCmB;EAAa,OAAA,EAAA,MAAA;EAE7C,UAAA,EAAA,MAAA;EACA,UAAA,EAAA,MAAA;EACQ,KAAA,EAAA,MAAA;EAHV,YAAA,EAAA,MAAA;EAAgB,QAAA,EA9BN,MA8BM,CAAA,MAAA,EAAA,OAAA,CAAA;AAQlB;AAA+C,UAnC9B,0BAAA,CAmC8B;EAE3C,OAAA,EAAA,MAAA;EACA,QAAA,EAAA,OAAA;EAEiB,QAAA,EArCT,MAqCS,CAAA,MAAA,EArCM,0BAqCN,CAAA;;AAJH,UA9BD,uBAAA,CA8BC;EAQN,OAAA,EAAA,MAAA;EAA6B,UAAA,EAAA,MAAA;EACd,UAAA,EAAA,MAAA;;AAAD,UAjCT,eAAA,SAAwB,uBAiCf,CAAA;;;YA9Bd;;UAGK,oBAAA;;;KAIZ,6BAA6B,0BAA0B;OACrD;IACH,KAAK,yBAAyB,YAAY;KAElC,qCAAqC,wBAC/C,iBACE,KACA;QACQ;;;KAKA,mCAAmC,wBAC7C,iBACE,KACA;;iBAEiB;;KAIT,6BAA6B,wBACvC,yBAAyB"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/components/landing-text/types.ts"],"sourcesContent":[],"mappings":";;;KAEY,cAAA;KACA,kBAAA;AADA,UAGK,4BAAA,CAHS;EACd,UAAA,EAAA,MAAA;EAEK,KAAA,EAAA,MAAA;EAMA,QAAA,CAAA,EAHJ,MAGI,CAAA,MAAA,EAAA,OAAA,CAA+B;AAKhD;AAKiB,UAVA,+BAAA,CAeJ;EAGI,UAAA,EAAA,MAAA;EASA,QAAA,EAzBL,4BAyB+B,EAGhB;AAG3B;AAMiB,UAlCA,4BAAA,CAkCwB;EAMxB,OAAA,EAAA,MAAA;EAIZ,QAAA,EA1CO,+BA0CS,EAAA;;AAAuC,UAvC3C,yBAAA,CAuC2C;EACrD,QAAA,EAAA,MAAA;EAC2B,WAAA,EAAA,MAAA;EAAzB,WAAA,EAAA,MAAA;EAAqC,KAAA,EAAA,MAAA;EAA1C,QAAA,CAAA,EApCS,MAoCT,CAAA,MAAA,EAAA,OAAA,CAAA;;AAEQ,UAnCK,0BAAA,CAmCmB;EAAa,OAAA,EAAA,MAAA;EAE7C,UAAA,EAAA,MAAA;EACA,UAAA,EAAA,MAAA;EACQ,KAAA,EAAA,MAAA;EAHV,YAAA,EAAA,MAAA;EAAgB,QAAA,EA9BN,MA8BM,CAAA,MAAA,EAAA,OAAA,CAAA;AAQlB;AAA+C,UAnC9B,0BAAA,CAmC8B;EAE3C,OAAA,EAAA,MAAA;EACA,QAAA,EAAA,OAAA;EAEiB,QAAA,EArCT,MAqCS,CAAA,MAAA,EArCM,0BAqCN,CAAA;;AAJH,UA9BD,uBAAA,CA8BC;EAQN,OAAA,EAAA,MAAA;EAA6B,UAAA,EAAA,MAAA;EACd,UAAA,EAAA,MAAA;;AAAD,UAjCT,eAAA,SAAwB,uBAiCf,CAAA;;;YA9Bd;;UAGK,oBAAA;;;KAIZ,6BAA6B,0BAA0B;OACrD;IACH,KAAK,yBAAyB,YAAY;KAElC,qCAAqC,wBAC/C,iBACE,KACA;QACQ;;;KAKA,mCAAmC,wBAC7C,iBACE,KACA;;iBAEiB;;KAIT,6BAA6B,wBACvC,yBAAyB"}
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime2 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/page-header/page-header.d.ts
4
4
  interface PageHeaderProps {
@@ -10,7 +10,7 @@ declare function PageHeader({
10
10
  title,
11
11
  help,
12
12
  description
13
- }: PageHeaderProps): react_jsx_runtime2.JSX.Element;
13
+ }: PageHeaderProps): react_jsx_runtime3.JSX.Element;
14
14
  //#endregion
15
15
  export { PageHeader, PageHeaderProps };
16
16
  //# sourceMappingURL=page-header.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { SelectorProps } from "../ui/selector.js";
2
2
  import { FieldPath, FieldPathValue, FieldValues, UseControllerProps } from "react-hook-form";
3
- import * as react_jsx_runtime4 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
4
4
  import { Options } from "nuqs";
5
5
 
6
6
  //#region src/components/remote-selector/remote-selector.d.ts
@@ -38,7 +38,7 @@ declare function RemoteSelectorField<T, TFieldValues extends FieldValues = Field
38
38
  ...props
39
39
  }: RemoteSelectorFieldProps<TFieldValues, TFieldName> & BaseRemoteSelectorProps<T> & {
40
40
  withPortal?: boolean;
41
- }): react_jsx_runtime4.JSX.Element;
41
+ }): react_jsx_runtime1.JSX.Element;
42
42
  interface RemoteSelectorQueryProps<T> extends BaseRemoteSelectorProps<T> {
43
43
  name: string;
44
44
  defaultValue?: string;
@@ -58,7 +58,7 @@ declare function RemoteSelectorQuery<T>({
58
58
  fieldLabel,
59
59
  type,
60
60
  ...props
61
- }: RemoteSelectorQueryProps<T>): react_jsx_runtime4.JSX.Element;
61
+ }: RemoteSelectorQueryProps<T>): react_jsx_runtime1.JSX.Element;
62
62
  //#endregion
63
63
  export { BaseRemoteSelectorProps, RemoteSelectorField, RemoteSelectorFieldProps, RemoteSelectorQuery, RemoteSelectorQueryProps, TUseData };
64
64
  //# sourceMappingURL=remote-selector.d.ts.map
package/package.json CHANGED
@@ -1,57 +1,57 @@
1
1
  {
2
2
  "name": "maquinaweb-ui",
3
- "version": "2.71.0",
3
+ "version": "2.72.0",
4
4
  "description": "A minimal React component library",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "exports": {
8
- "./toggle-field": {
9
- "import": "./dist/toggle-field.js",
10
- "types": "./dist/toggle-field.d.ts"
8
+ "./page-header": {
9
+ "import": "./dist/page-header.js",
10
+ "types": "./dist/page-header.d.ts"
11
11
  },
12
12
  "./kanban-dnd": {
13
13
  "import": "./dist/kanban-dnd.js",
14
14
  "types": "./dist/kanban-dnd.d.ts"
15
15
  },
16
+ "./landing-content": {
17
+ "import": "./dist/landing-content.js",
18
+ "types": "./dist/landing-content.d.ts"
19
+ },
20
+ "./date-field": {
21
+ "import": "./dist/date-field.js",
22
+ "types": "./dist/date-field.d.ts"
23
+ },
24
+ "./container-animation": {
25
+ "import": "./dist/container-animation.js",
26
+ "types": "./dist/container-animation.d.ts"
27
+ },
16
28
  "./date-hour-field": {
17
29
  "import": "./dist/date-hour-field.js",
18
30
  "types": "./dist/date-hour-field.d.ts"
19
31
  },
20
- "./split-text-poor": {
21
- "import": "./dist/split-text-poor.js",
22
- "types": "./dist/split-text-poor.d.ts"
32
+ "./remote-selector": {
33
+ "import": "./dist/remote-selector.js",
34
+ "types": "./dist/remote-selector.d.ts"
23
35
  },
24
- "./landing-content": {
25
- "import": "./dist/landing-content.js",
26
- "types": "./dist/landing-content.d.ts"
36
+ "./toggle-field": {
37
+ "import": "./dist/toggle-field.js",
38
+ "types": "./dist/toggle-field.d.ts"
27
39
  },
28
40
  "./landing-text": {
29
41
  "import": "./dist/landing-text.js",
30
42
  "types": "./dist/landing-text.d.ts"
31
43
  },
32
- "./page-header": {
33
- "import": "./dist/page-header.js",
34
- "types": "./dist/page-header.d.ts"
35
- },
36
44
  "./text-field": {
37
45
  "import": "./dist/text-field.js",
38
46
  "types": "./dist/text-field.d.ts"
39
47
  },
40
- "./remote-selector": {
41
- "import": "./dist/remote-selector.js",
42
- "types": "./dist/remote-selector.d.ts"
43
- },
44
48
  "./input-suggest": {
45
49
  "import": "./dist/input-suggest.js",
46
50
  "types": "./dist/input-suggest.d.ts"
47
51
  },
48
- "./date-field": {
49
- "import": "./dist/date-field.js",
50
- "types": "./dist/date-field.d.ts"
51
- },
52
- "./container-animation": {
53
- "import": "./dist/container-animation.js",
54
- "types": "./dist/container-animation.d.ts"
52
+ "./split-text-poor": {
53
+ "import": "./dist/split-text-poor.js",
54
+ "types": "./dist/split-text-poor.d.ts"
55
55
  },
56
56
  "./package.json": "./package.json"
57
57
  },