@griddo/ax 11.10.12 → 11.10.13-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/api/config.tsx +5 -0
- package/src/components/Fields/ArrayFieldGroup/index.tsx +45 -42
- package/src/components/Fields/CheckField/index.tsx +4 -5
- package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +17 -17
- package/src/components/Fields/UniqueCheck/index.tsx +21 -16
- package/src/components/Fields/UniqueCheck/style.tsx +17 -0
- package/src/components/FileGallery/GalleryPanel/DetailPanel/index.tsx +6 -3
- package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +5 -3
- package/src/components/Tooltip/index.tsx +35 -20
- package/src/schemas/pages/GlobalPage.tsx +17 -0
- package/src/schemas/pages/Page.tsx +17 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "11.10.
|
|
4
|
+
"version": "11.10.13-rc.1",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Diego M. Béjar <diego.bejar@secuoyas.com>",
|
|
@@ -217,5 +217,5 @@
|
|
|
217
217
|
"publishConfig": {
|
|
218
218
|
"access": "public"
|
|
219
219
|
},
|
|
220
|
-
"gitHead": "
|
|
220
|
+
"gitHead": "f5bb7e21bd1d985da6ebb2ddb0b21494861c935f"
|
|
221
221
|
}
|
package/src/api/config.tsx
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import packageJson from "../../package.json";
|
|
2
|
+
|
|
1
3
|
const BASE_PATH = process.env.GRIDDO_API_URL || process.env.REACT_APP_API_ENDPOINT;
|
|
2
4
|
|
|
3
5
|
const headers = {
|
|
4
6
|
"Content-type": "application/json; charset=UTF-8",
|
|
5
7
|
accept: "application/json",
|
|
8
|
+
"x-application-id": "griddo-ax",
|
|
9
|
+
"x-client-version": packageJson.version,
|
|
10
|
+
"x-client-name": "AX",
|
|
6
11
|
};
|
|
7
12
|
|
|
8
13
|
export const template = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
2
|
import { v4 as uuidv4 } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { Button, FieldsDivider } from "@ax/components";
|
|
5
|
-
import { ISite } from "@ax/types";
|
|
5
|
+
import type { ISite } from "@ax/types";
|
|
6
6
|
import { getDefaultSchema } from "@ax/helpers";
|
|
7
7
|
import ArrayFieldItem from "./ArrayFieldItem";
|
|
8
8
|
import ArrayFieldInline from "./ArrayFieldInline";
|
|
@@ -28,20 +28,24 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
|
|
|
28
28
|
const [items, setItems] = useState<any[]>([]);
|
|
29
29
|
const [isOpen, setIsOpen] = useState<number | null>(null);
|
|
30
30
|
|
|
31
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: false positive
|
|
31
32
|
useEffect(() => {
|
|
32
33
|
const initialValue = value ? Object.values(value) : [];
|
|
33
|
-
const initialValueMapped = initialValue.map((val
|
|
34
|
+
const initialValueMapped = initialValue.map((val) => {
|
|
34
35
|
return val.id ? val : { id: uuidv4(), ...val };
|
|
35
36
|
});
|
|
36
37
|
setItems(initialValueMapped);
|
|
37
38
|
}, [editorID]);
|
|
38
39
|
|
|
39
40
|
const handleClick = () => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
let newComponent = { id: uuidv4() };
|
|
42
|
+
if(selectedContent){
|
|
43
|
+
const defaultValues = getDefaultSchema(selectedContent.component);
|
|
44
|
+
newComponent =
|
|
45
|
+
!!defaultValues[objKey] && defaultValues[objKey].length
|
|
46
|
+
? { ...defaultValues[objKey][0], id: uuidv4() }
|
|
47
|
+
: newComponent;
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
const newItems = [...items, newComponent];
|
|
47
51
|
setItems(newItems);
|
|
@@ -72,40 +76,39 @@ const ArrayFieldGroup = (props: IProps): JSX.Element => {
|
|
|
72
76
|
<div>
|
|
73
77
|
<DividerComponent />
|
|
74
78
|
<div>
|
|
75
|
-
{items
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})}
|
|
79
|
+
{items?.map((item, index) => {
|
|
80
|
+
const handleFieldChange = (newValue: Record<string, unknown>) => handleChange(newValue, index);
|
|
81
|
+
return arrayType === "inline" ? (
|
|
82
|
+
<ArrayFieldInline
|
|
83
|
+
key={item.id}
|
|
84
|
+
fields={innerFields}
|
|
85
|
+
item={item}
|
|
86
|
+
index={index}
|
|
87
|
+
onChange={handleFieldChange}
|
|
88
|
+
handleDelete={handleDelete}
|
|
89
|
+
site={site}
|
|
90
|
+
disabled={disabled}
|
|
91
|
+
parentKey={objKey}
|
|
92
|
+
actions={actions}
|
|
93
|
+
/>
|
|
94
|
+
) : (
|
|
95
|
+
<ArrayFieldItem
|
|
96
|
+
key={item.id}
|
|
97
|
+
name={name}
|
|
98
|
+
fields={innerFields}
|
|
99
|
+
item={item}
|
|
100
|
+
index={index}
|
|
101
|
+
onChange={handleFieldChange}
|
|
102
|
+
handleDelete={handleDelete}
|
|
103
|
+
isOpen={isOpen}
|
|
104
|
+
setIsOpen={setIsOpen}
|
|
105
|
+
site={site}
|
|
106
|
+
disabled={disabled}
|
|
107
|
+
parentKey={objKey}
|
|
108
|
+
actions={actions}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
})}
|
|
109
112
|
</div>
|
|
110
113
|
<S.ButtonWrapper>
|
|
111
114
|
<Button type="button" onClick={handleClick} buttonStyle="line" disabled={disabled}>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { ICheck } from "@ax/types";
|
|
3
1
|
import Icon from "@ax/components/Icon";
|
|
2
|
+
import type { ICheck } from "@ax/types";
|
|
4
3
|
|
|
5
4
|
import * as S from "./style";
|
|
6
5
|
|
|
@@ -23,12 +22,12 @@ const CheckField = (props: ICheckFieldProps): JSX.Element => {
|
|
|
23
22
|
|
|
24
23
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
25
24
|
const isChecked = e.target.checked;
|
|
26
|
-
onChange
|
|
25
|
+
onChange?.({ value, isChecked });
|
|
27
26
|
};
|
|
28
27
|
|
|
29
|
-
const handleMouseOver = () => setHoverCheck
|
|
28
|
+
const handleMouseOver = () => setHoverCheck?.(true);
|
|
30
29
|
|
|
31
|
-
const handleMouseLeave = () => setHoverCheck
|
|
30
|
+
const handleMouseLeave = () => setHoverCheck?.(false);
|
|
32
31
|
|
|
33
32
|
return (
|
|
34
33
|
<S.Wrapper className={className}>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
|
|
4
|
-
import { IDataSource, ILanguage, IRootState, ISchemaField, ISite, IStructuredData } from "@ax/types";
|
|
4
|
+
import type { IDataSource, ILanguage, IRootState, ISchemaField, ISite, IStructuredData } from "@ax/types";
|
|
5
5
|
import {
|
|
6
6
|
Button,
|
|
7
7
|
FloatingMenu,
|
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
UniqueCheck,
|
|
15
15
|
} from "@ax/components";
|
|
16
16
|
|
|
17
|
-
import { IReferenceState, IRefField, ISource
|
|
17
|
+
import type { IReferenceState, IRefField, ISource } from "../Context";
|
|
18
|
+
import { useReference } from "../Context";
|
|
18
19
|
import AutoItem from "./AutoItem";
|
|
19
20
|
|
|
20
21
|
import * as S from "./style";
|
|
@@ -36,9 +37,9 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
36
37
|
};
|
|
37
38
|
const [configState, setConfigState] = useState<IConfigState>(initConfig);
|
|
38
39
|
const initToggle = {
|
|
39
|
-
isSiteActive: state.site && state.site !== "global"
|
|
40
|
-
isLangActive: state.lang
|
|
41
|
-
isGlobalActive: state.site && state.site === "global"
|
|
40
|
+
isSiteActive: !!(state.site && state.site !== "global" ),
|
|
41
|
+
isLangActive: !!state.lang,
|
|
42
|
+
isGlobalActive: !!(state.site && state.site === "global" ),
|
|
42
43
|
errorSite: false,
|
|
43
44
|
errorLang: false,
|
|
44
45
|
errorMsg: "",
|
|
@@ -130,8 +131,8 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
130
131
|
title: "",
|
|
131
132
|
value: state.quantity,
|
|
132
133
|
onChange: (quantity: number) => setState((state: IReferenceState) => ({ ...state, quantity })),
|
|
133
|
-
maxValue: validators
|
|
134
|
-
minValue: validators
|
|
134
|
+
maxValue: validators?.maxValue ? validators.maxValue : undefined,
|
|
135
|
+
minValue: validators?.minValue ? validators.minValue : undefined,
|
|
135
136
|
};
|
|
136
137
|
|
|
137
138
|
const checkErrors = (): boolean => {
|
|
@@ -258,7 +259,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
258
259
|
};
|
|
259
260
|
|
|
260
261
|
const handleLangChange = (value: string) => {
|
|
261
|
-
const lang = value.length ? parseInt(value) : undefined;
|
|
262
|
+
const lang = value.length ? parseInt(value, 10) : undefined;
|
|
262
263
|
setState((state: IReferenceState) => ({ ...state, lang }));
|
|
263
264
|
if (value) {
|
|
264
265
|
setToggleState({ ...toggleState, isLangActive: true, errorLang: false, errorMsg: "" });
|
|
@@ -295,7 +296,8 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
295
296
|
state.sources.map((singleSource: ISource) => {
|
|
296
297
|
const source = state.sourceTitles.find((el: IDataSource) => el.id === singleSource.structuredData);
|
|
297
298
|
const { filters = [], filterOperator, globalOperator } = singleSource;
|
|
298
|
-
|
|
299
|
+
if(!source) return null;
|
|
300
|
+
return (
|
|
299
301
|
<AutoItem
|
|
300
302
|
key={singleSource.structuredData}
|
|
301
303
|
source={source}
|
|
@@ -309,9 +311,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
309
311
|
globalOperator={globalOperator}
|
|
310
312
|
siteID={state.site || site?.id}
|
|
311
313
|
/>
|
|
312
|
-
)
|
|
313
|
-
<></>
|
|
314
|
-
);
|
|
314
|
+
)
|
|
315
315
|
})}
|
|
316
316
|
</S.SourcesWrapper>
|
|
317
317
|
<S.RadioWrapper>
|
|
@@ -383,9 +383,9 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
383
383
|
</S.SubConfigContent>
|
|
384
384
|
</S.ConfigWrapper>
|
|
385
385
|
</>
|
|
386
|
-
) :
|
|
387
|
-
|
|
388
|
-
|
|
386
|
+
) :
|
|
387
|
+
null
|
|
388
|
+
}
|
|
389
389
|
|
|
390
390
|
<S.OptionLabel
|
|
391
391
|
onClick={() => toggleConfig("isDataOpen")}
|
|
@@ -483,7 +483,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
|
|
|
483
483
|
<UniqueCheck
|
|
484
484
|
name="preferenceLanguageCheck"
|
|
485
485
|
options={[
|
|
486
|
-
{
|
|
486
|
+
{ title: `${currentLang} content shown first` },
|
|
487
487
|
]}
|
|
488
488
|
value={state.preferenceLanguage}
|
|
489
489
|
onChange={handlePreferenceLanguageChange}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { CheckField } from "@ax/components";
|
|
3
2
|
|
|
3
|
+
import * as S from "./style";
|
|
4
|
+
|
|
4
5
|
const UniqueCheck = (props: IProps) => {
|
|
5
|
-
const { name, value, options, onChange, disabled, inversed = false, className } = props;
|
|
6
|
+
const { name, value, options, onChange, disabled, inversed = false, className, description } = props;
|
|
6
7
|
const uniqueOption = options[0];
|
|
7
8
|
|
|
8
9
|
const handleChange = (changeEvt: ICheckEvent) => {
|
|
@@ -10,17 +11,22 @@ const UniqueCheck = (props: IProps) => {
|
|
|
10
11
|
onChange(isChecked);
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const classes = description ? "with-subtitle" : "";
|
|
15
|
+
|
|
13
16
|
return (
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
<S.Wrapper className={classes}>
|
|
18
|
+
<CheckField
|
|
19
|
+
name={name}
|
|
20
|
+
checked={!!value}
|
|
21
|
+
title={uniqueOption.title}
|
|
22
|
+
value={value}
|
|
23
|
+
onChange={handleChange}
|
|
24
|
+
disabled={disabled}
|
|
25
|
+
inversed={inversed}
|
|
26
|
+
className={className}
|
|
27
|
+
/>
|
|
28
|
+
<S.Subtitle>{description}</S.Subtitle>
|
|
29
|
+
</S.Wrapper>
|
|
24
30
|
);
|
|
25
31
|
};
|
|
26
32
|
|
|
@@ -31,17 +37,16 @@ interface ICheckEvent {
|
|
|
31
37
|
|
|
32
38
|
interface IProps {
|
|
33
39
|
name: string;
|
|
34
|
-
value:
|
|
40
|
+
value: string | number;
|
|
35
41
|
options: ICheck[];
|
|
36
|
-
onChange:
|
|
42
|
+
onChange(isChecked: boolean): void;
|
|
37
43
|
disabled?: boolean;
|
|
38
44
|
inversed?: boolean;
|
|
39
45
|
className?: string;
|
|
46
|
+
description?: string;
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
interface ICheck {
|
|
43
|
-
name: string;
|
|
44
|
-
value: any;
|
|
45
50
|
title: string;
|
|
46
51
|
}
|
|
47
52
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Wrapper = styled.div`
|
|
4
|
+
&.with-subtitle label {
|
|
5
|
+
${(p) => p.theme.textStyle.uiL};
|
|
6
|
+
font-weight: 600;
|
|
7
|
+
}
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
const Subtitle = styled.div`
|
|
11
|
+
${(p) => p.theme.textStyle.uiS};
|
|
12
|
+
font-weight: 400;
|
|
13
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
14
|
+
padding-left: ${(p) => p.theme.spacing.m};
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
export { Wrapper, Subtitle };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { memo, useEffect, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { Button, FieldsBehavior, IconAction } from "@ax/components";
|
|
5
|
-
import { formatBytes, getFileIcon, getFormattedDateWithTimezone } from "@ax/helpers";
|
|
6
5
|
import { fileDriveActions } from "@ax/containers/FileDrive";
|
|
6
|
+
import { formatBytes, getFileIcon, getFormattedDateWithTimezone } from "@ax/helpers";
|
|
7
|
+
import type { IFile, IRootState } from "@ax/types";
|
|
7
8
|
|
|
8
9
|
import * as S from "./style";
|
|
9
10
|
|
|
@@ -14,6 +15,7 @@ const GalleryDetailPanel = (props: IProps) => {
|
|
|
14
15
|
const initState: IFormState = { title: title || "", alt: alt || "", tags: tags || [] };
|
|
15
16
|
const [form, setForm] = useState(initState);
|
|
16
17
|
|
|
18
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
17
19
|
useEffect(() => {
|
|
18
20
|
setForm(initState);
|
|
19
21
|
}, [selectedFile]);
|
|
@@ -105,6 +107,7 @@ const GalleryDetailPanel = (props: IProps) => {
|
|
|
105
107
|
fieldType="TagsField"
|
|
106
108
|
onChange={handleTags}
|
|
107
109
|
disabled={!isAllowedToEdit}
|
|
110
|
+
helptext="Type a tag and press enter to create it"
|
|
108
111
|
/>
|
|
109
112
|
</S.FormWrapper>
|
|
110
113
|
</S.PanelForm>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { memo, useEffect, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { Button, FieldsBehavior, IconAction } from "@ax/components";
|
|
5
|
-
import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
|
|
6
5
|
import { galleryActions } from "@ax/containers/Gallery";
|
|
6
|
+
import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
|
|
7
|
+
import type { IGetFolderParams, IImage, IRootState } from "@ax/types";
|
|
7
8
|
|
|
8
9
|
import * as S from "./style";
|
|
9
10
|
|
|
@@ -114,6 +115,7 @@ const GalleryDetailPanel = (props: IProps) => {
|
|
|
114
115
|
fieldType="TagsField"
|
|
115
116
|
onChange={handleTags}
|
|
116
117
|
disabled={!isAllowedToEdit}
|
|
118
|
+
helptext="Type a tag and press enter to create it"
|
|
117
119
|
/>
|
|
118
120
|
</S.FormWrapper>
|
|
119
121
|
</S.PanelForm>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
2
4
|
import { useHandleClickOutside } from "@ax/hooks";
|
|
3
5
|
|
|
4
6
|
import * as S from "./style";
|
|
5
7
|
|
|
6
|
-
const Tooltip = (props: ITooltipProps)
|
|
8
|
+
const Tooltip = (props: ITooltipProps) => {
|
|
7
9
|
const { content, children, hideOnClick = true, bottom, left, expanded, top } = props;
|
|
8
10
|
|
|
9
11
|
const initialState: IState = {
|
|
@@ -15,26 +17,31 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
|
|
|
15
17
|
const [state, setState] = useState(initialState);
|
|
16
18
|
const { active, childrenWidth, clicked, fixOutOfBounds } = state;
|
|
17
19
|
|
|
18
|
-
const changeState = (value:
|
|
20
|
+
const changeState = useCallback((value: Partial<IState>) => {
|
|
19
21
|
setState((state) => ({ ...state, ...value }));
|
|
20
|
-
};
|
|
22
|
+
}, []);
|
|
21
23
|
|
|
22
24
|
const childrenRef = useRef<HTMLDivElement>(null);
|
|
23
25
|
const tipRef = useRef<HTMLDivElement>(null);
|
|
24
|
-
|
|
25
|
-
let timeout: any;
|
|
26
|
+
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
26
27
|
|
|
27
28
|
const showTip = () => {
|
|
28
29
|
if (!clicked) {
|
|
29
|
-
|
|
30
|
+
if (timeoutRef.current) {
|
|
31
|
+
clearTimeout(timeoutRef.current);
|
|
32
|
+
}
|
|
33
|
+
timeoutRef.current = setTimeout(() => {
|
|
30
34
|
changeState({ active: true });
|
|
31
35
|
}, 1000);
|
|
32
36
|
}
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
const hideTip = () => {
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
if (timeoutRef.current) {
|
|
41
|
+
clearTimeout(timeoutRef.current);
|
|
42
|
+
timeoutRef.current = null;
|
|
43
|
+
}
|
|
44
|
+
changeState({ active: false, fixOutOfBounds: 0 });
|
|
38
45
|
};
|
|
39
46
|
|
|
40
47
|
const handleClick = () => {
|
|
@@ -44,8 +51,8 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
|
|
|
44
51
|
}
|
|
45
52
|
};
|
|
46
53
|
|
|
47
|
-
const handleClickOutside = (e:
|
|
48
|
-
if (childrenRef.current
|
|
54
|
+
const handleClickOutside = (e: MouseEvent | TouchEvent) => {
|
|
55
|
+
if (childrenRef.current?.contains(e.target as Node)) {
|
|
49
56
|
return;
|
|
50
57
|
}
|
|
51
58
|
changeState({ clicked: false });
|
|
@@ -53,16 +60,22 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
|
|
|
53
60
|
|
|
54
61
|
useHandleClickOutside(clicked, handleClickOutside);
|
|
55
62
|
|
|
56
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
|
|
57
63
|
useEffect(() => {
|
|
58
|
-
|
|
64
|
+
return () => {
|
|
65
|
+
if (timeoutRef.current) {
|
|
66
|
+
clearTimeout(timeoutRef.current);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (childrenRef.current?.children[0]) {
|
|
59
73
|
const childrenWidth = childrenRef.current.children[0].clientWidth;
|
|
60
74
|
changeState({ childrenWidth });
|
|
61
75
|
}
|
|
62
|
-
}, [
|
|
76
|
+
}, [changeState]);
|
|
63
77
|
|
|
64
|
-
|
|
65
|
-
useEffect(() => {
|
|
78
|
+
useLayoutEffect(() => {
|
|
66
79
|
if (active && tipRef.current) {
|
|
67
80
|
const clientRect = tipRef.current.getBoundingClientRect();
|
|
68
81
|
|
|
@@ -72,11 +85,13 @@ const Tooltip = (props: ITooltipProps): JSX.Element => {
|
|
|
72
85
|
changeState({ fixOutOfBounds: left });
|
|
73
86
|
} else if (right > windowSize) {
|
|
74
87
|
changeState({ fixOutOfBounds: right - windowSize });
|
|
88
|
+
} else {
|
|
89
|
+
changeState({ fixOutOfBounds: 0 });
|
|
75
90
|
}
|
|
76
91
|
}
|
|
77
|
-
}, [
|
|
92
|
+
}, [active, changeState]);
|
|
78
93
|
|
|
79
|
-
if (!content) return children
|
|
94
|
+
if (!content) return <>{children}</>;
|
|
80
95
|
|
|
81
96
|
return (
|
|
82
97
|
<S.Tooltip
|
|
@@ -112,8 +127,8 @@ interface IState {
|
|
|
112
127
|
}
|
|
113
128
|
|
|
114
129
|
export interface ITooltipProps {
|
|
115
|
-
content?: string | boolean | JSX.Element
|
|
116
|
-
children:
|
|
130
|
+
content?: string | boolean | JSX.Element | JSX.Element[];
|
|
131
|
+
children: ReactNode;
|
|
117
132
|
hideOnClick?: boolean;
|
|
118
133
|
bottom?: boolean;
|
|
119
134
|
left?: number;
|
|
@@ -151,6 +151,22 @@ export default {
|
|
|
151
151
|
},
|
|
152
152
|
],
|
|
153
153
|
},
|
|
154
|
+
{
|
|
155
|
+
title: "GEO (LLMS)",
|
|
156
|
+
type: "FieldGroup",
|
|
157
|
+
key: "geo",
|
|
158
|
+
collapsed: true,
|
|
159
|
+
fields: [
|
|
160
|
+
{
|
|
161
|
+
type: "UniqueCheck",
|
|
162
|
+
key: "isLlmsEnabled",
|
|
163
|
+
options: [
|
|
164
|
+
{ "title": "Include this page in LLMs.txt" }
|
|
165
|
+
],
|
|
166
|
+
description: "If enabled, this page will be listed in LLMs.txt for language models."
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
154
170
|
{
|
|
155
171
|
title: "Analytics Data Layer",
|
|
156
172
|
type: "FieldGroup",
|
|
@@ -206,5 +222,6 @@ export default {
|
|
|
206
222
|
socialTitle: "",
|
|
207
223
|
socialDescription: "",
|
|
208
224
|
socialImage: {},
|
|
225
|
+
isLlmsEnabled: true,
|
|
209
226
|
},
|
|
210
227
|
};
|
|
@@ -217,6 +217,22 @@ export default {
|
|
|
217
217
|
},
|
|
218
218
|
],
|
|
219
219
|
},
|
|
220
|
+
{
|
|
221
|
+
title: "GEO (LLMS)",
|
|
222
|
+
type: "FieldGroup",
|
|
223
|
+
key: "geo",
|
|
224
|
+
collapsed: true,
|
|
225
|
+
fields: [
|
|
226
|
+
{
|
|
227
|
+
type: "UniqueCheck",
|
|
228
|
+
key: "isLlmsEnabled",
|
|
229
|
+
options: [
|
|
230
|
+
{ "title": "Include this page in LLMs.txt" }
|
|
231
|
+
],
|
|
232
|
+
description: "If enabled, this page will be listed in LLMs.txt for language models."
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
},
|
|
220
236
|
{
|
|
221
237
|
title: "Analytics Data Layer",
|
|
222
238
|
type: "FieldGroup",
|
|
@@ -280,5 +296,6 @@ export default {
|
|
|
280
296
|
customizeThemes: false,
|
|
281
297
|
headerTheme: null,
|
|
282
298
|
footerTheme: null,
|
|
299
|
+
isLlmsEnabled: true,
|
|
283
300
|
},
|
|
284
301
|
};
|