@griddo/ax 10.1.38 → 10.1.40

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "10.1.38",
4
+ "version": "10.1.40",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -230,5 +230,5 @@
230
230
  "publishConfig": {
231
231
  "access": "public"
232
232
  },
233
- "gitHead": "886d482e966f0398730f532b49101a8cafb01fae"
233
+ "gitHead": "378c1f32dd2b9ba61146a24ab4eb76276c72656e"
234
234
  }
@@ -1,4 +1,4 @@
1
- import React, { memo, useEffect, useState } from "react";
1
+ import React, { memo, useEffect, useRef, useState } from "react";
2
2
  import { Icon, IconAction, Gallery, Modal, Image } from "@ax/components";
3
3
 
4
4
  import { formatBytes, getFormattedDateWithTimezone } from "@ax/helpers";
@@ -27,13 +27,22 @@ const ImageField = (props: IImageFieldProps) => {
27
27
  const isModalOpen = isLinkableImage && !hasImage;
28
28
  const { isOpen, toggleModal } = useModal(isModalOpen);
29
29
  const [previewSrc, setPreviewSrc] = useState<string>();
30
+ const [imageHeight, setImageHeight] = useState<number>();
31
+ const previewRef = useRef<HTMLDivElement>(null);
30
32
 
31
33
  const imageUrl = value ? (typeof value === "string" ? value : value.url) : "";
34
+ const imagePosition = value && typeof value === "object" ? value.position : "center";
32
35
 
33
36
  useEffect(() => {
34
37
  setPreviewSrc(imageUrl);
35
38
  }, [imageUrl]);
36
39
 
40
+ useEffect(() => {
41
+ if (previewRef.current) {
42
+ setImageHeight(previewRef.current.clientHeight);
43
+ }
44
+ }, [previewRef.current]);
45
+
37
46
  const handleDelete = () => {
38
47
  if (!disabled) {
39
48
  setPreviewSrc("");
@@ -65,7 +74,14 @@ const ImageField = (props: IImageFieldProps) => {
65
74
  }
66
75
  };
67
76
 
68
- const previewHeight = cropPreview ? { height: 190 } : {};
77
+ const handlePosition = (newPosition: string) => () => {
78
+ if (value && typeof value === "object") {
79
+ const newValue = { ...value, position: newPosition };
80
+ onChange(newValue);
81
+ }
82
+ };
83
+
84
+ const previewHeight = cropPreview || (imageHeight && imageHeight < 180) ? { height: 180 } : {};
69
85
  return (
70
86
  <>
71
87
  <S.FieldWrapper
@@ -91,8 +107,25 @@ const ImageField = (props: IImageFieldProps) => {
91
107
  </S.ImageData>
92
108
  </S.ImageDataWrapper>
93
109
  )}
94
- <S.Preview preview={!!previewSrc} data-testid="previewDiv">
110
+ <S.Preview preview={!!previewSrc} data-testid="previewDiv" ref={previewRef}>
95
111
  {previewSrc && <Image url={previewSrc} width={320} {...previewHeight} />}
112
+ <S.PositionWrapper>
113
+ <S.PositionTitle>
114
+ <Icon name="grid" size="16" />
115
+ <span>POSITION</span>
116
+ </S.PositionTitle>
117
+ <S.PositionGrid>
118
+ <S.Position onClick={handlePosition("left-top")} active={imagePosition === "left-top"} />
119
+ <S.Position onClick={handlePosition("top")} active={imagePosition === "top"} />
120
+ <S.Position onClick={handlePosition("right-top")} active={imagePosition === "right-top"} />
121
+ <S.Position onClick={handlePosition("left")} active={imagePosition === "left"} />
122
+ <S.Position onClick={handlePosition("center")} active={!imagePosition || imagePosition === "center"} />
123
+ <S.Position onClick={handlePosition("right")} active={imagePosition === "right"} />
124
+ <S.Position onClick={handlePosition("left-bottom")} active={imagePosition === "left-bottom"} />
125
+ <S.Position onClick={handlePosition("bottom")} active={imagePosition === "bottom"} />
126
+ <S.Position onClick={handlePosition("right-bottom")} active={imagePosition === "right-bottom"} />
127
+ </S.PositionGrid>
128
+ </S.PositionWrapper>
96
129
  <S.PreviewActions>
97
130
  <IconAction icon="change" onClick={handleChange} />
98
131
  <IconAction icon="delete" onClick={handleDelete} />
@@ -8,7 +8,7 @@ const FieldWrapper = styled.div<{ error?: boolean; preview: boolean; disabled?:
8
8
  align-items: center;
9
9
  flex-flow: column nowrap;
10
10
  min-height: ${(p) => `calc(${p.theme.spacing.l} * 2)`};
11
- max-width: ${(p) => (!p.fullWidth ? `calc(${p.theme.spacing.xl} * 5) ` : '100%')};
11
+ max-width: ${(p) => (!p.fullWidth ? `calc(${p.theme.spacing.xl} * 5) ` : "100%")};
12
12
  width: 100%;
13
13
  background-color: ${(p) => p.theme.colors.uiBackground02};
14
14
  border: ${(p) =>
@@ -55,19 +55,61 @@ const PreviewActions = styled.div`
55
55
  display: none;
56
56
  justify-content: flex-end;
57
57
  position: absolute;
58
- top: 100%;
59
- left: 0;
60
- right: 0;
58
+ bottom: ${(p) => p.theme.spacing.xs};
59
+ right: ${(p) => p.theme.spacing.xs};
61
60
  background-color: #ffffff;
62
- padding: ${(p) => p.theme.spacing.xs};
61
+ padding: ${(p) => `${p.theme.spacing.xxs} ${p.theme.spacing.xs}`};
63
62
  z-index: 3;
64
- height: 48px;
63
+ border-radius: 4px;
65
64
  transition: all 0.3s ease-out;
66
- & > button {
65
+ button:last-child {
67
66
  margin-left: ${(p) => p.theme.spacing.xs};
68
67
  }
69
68
  `;
70
69
 
70
+ const PositionTitle = styled.div`
71
+ display: flex;
72
+ ${(p) => p.theme.textStyle.uiButton};
73
+ color: ${(p) => p.theme.color.interactive01};
74
+ align-items: center;
75
+ span {
76
+ margin-left: 4px;
77
+ }
78
+ `;
79
+
80
+ const PositionGrid = styled.div`
81
+ display: none;
82
+ gap: ${(p) => p.theme.spacing.xxs};
83
+ grid-template-columns: repeat(3, 1fr);
84
+ margin-top: ${(p) => p.theme.spacing.xs};
85
+ `;
86
+
87
+ const Position = styled.div<{active?: boolean}>`
88
+ width: ${(p) => p.theme.spacing.m};
89
+ height: ${(p) => p.theme.spacing.m};
90
+ border-radius: ${(p) => p.theme.radii.xs};
91
+ background-color: ${(p) => p.active ? p.theme.color.interactive01 : p.theme.color.uiBackground03};
92
+ :hover {
93
+ background-color: ${(p) => p.active ? p.theme.color.interactive01 : p.theme.color.overlayPressedPrimary};
94
+ }
95
+ `;
96
+
97
+ const PositionWrapper = styled.div`
98
+ position: absolute;
99
+ display: none;
100
+ top: ${(p) => p.theme.spacing.xs};
101
+ right: ${(p) => p.theme.spacing.xs};
102
+ background-color: ${(p) => p.theme.color.uiBarBackground};
103
+ padding: ${(p) => p.theme.spacing.xs};
104
+ border-radius: ${(p) => p.theme.radii.s};
105
+ flex-direction: column;
106
+ :hover {
107
+ ${PositionGrid} {
108
+ display: grid;
109
+ }
110
+ }
111
+ `;
112
+
71
113
  const Preview = styled.div<{ preview: boolean }>`
72
114
  position: relative;
73
115
  min-height: ${(p) => `calc(${p.theme.spacing.l} * 2)`};
@@ -82,7 +124,9 @@ const Preview = styled.div<{ preview: boolean }>`
82
124
  cursor: pointer;
83
125
  ${PreviewActions} {
84
126
  display: flex;
85
- top: calc(100% - 48px);
127
+ }
128
+ ${PositionWrapper} {
129
+ display: flex;
86
130
  }
87
131
  }
88
132
  img {
@@ -108,4 +152,18 @@ const ImageData = styled.div`
108
152
  ${(p) => p.theme.textStyle.uiXS};
109
153
  `;
110
154
 
111
- export { FieldWrapper, Input, IconWrapper, Text, PreviewActions, Preview, ImageDataWrapper, FileName, ImageData };
155
+ export {
156
+ FieldWrapper,
157
+ Input,
158
+ IconWrapper,
159
+ Text,
160
+ PreviewActions,
161
+ Preview,
162
+ ImageDataWrapper,
163
+ FileName,
164
+ ImageData,
165
+ PositionWrapper,
166
+ PositionTitle,
167
+ PositionGrid,
168
+ Position,
169
+ };
@@ -63,11 +63,9 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
63
63
  availableSites,
64
64
  structuredData,
65
65
  structuredDataContent,
66
- fullUrl,
66
+ fullPath,
67
67
  } = globalPage;
68
68
 
69
- const slug = fullUrl ? fullUrl.replace(/^.*\/\/[^\/]+\/[\w-.]+/, "") : "";
70
-
71
69
  const activeColumns = Object.keys(columns).filter((col: string) => columns[col].show);
72
70
 
73
71
  const initValue = { title: "", slug: "" };
@@ -81,7 +79,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
81
79
  const theme: any = useTheme();
82
80
  const nameCellPadding = Number(theme.spacing.s.slice(0, -2));
83
81
  const title = useAdaptiveText(nameCellRef, globalPage.title, nameCellPadding);
84
- const path = useAdaptiveText(nameCellRef, slug, nameCellPadding);
82
+ const path = useAdaptiveText(nameCellRef, fullPath.page, nameCellPadding);
85
83
  const API_URL = process.env.REACT_APP_API_ENDPOINT;
86
84
 
87
85
  const publishedTooltip: Record<string, string> = {
@@ -371,7 +369,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
371
369
  <strong>{globalPage.title}</strong>
372
370
  <br />
373
371
  </>,
374
- <>{slug}</>,
372
+ <>{fullPath.page}</>,
375
373
  ]}
376
374
  left={0}
377
375
  top={1}
@@ -189,6 +189,7 @@ export interface IImage {
189
189
  orientation: string;
190
190
  site: string;
191
191
  file?: File;
192
+ position?: string;
192
193
  }
193
194
 
194
195
  export interface IUrlField {