slice-machine-ui 1.26.1-beta.1 → 1.26.1-beta.10

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 (94) hide show
  1. package/components/AppLayout/index.tsx +2 -2
  2. package/components/Forms/RenameVariationModal/RenameVariationModal.module.css +5 -0
  3. package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +1 -1
  4. package/components/Navigation/index.module.css +3 -0
  5. package/components/Navigation/index.tsx +1 -1
  6. package/lib/builders/SliceBuilder/FieldZones/index.tsx +93 -28
  7. package/lib/builders/SliceBuilder/index.tsx +5 -1
  8. package/lib/builders/common/Zone/components/EmptyState/index.tsx +1 -1
  9. package/out/404.html +1 -1
  10. package/out/_next/static/chunks/318-77a29f41c3a027e3.js +1 -0
  11. package/out/_next/static/chunks/382-aacd61be9adba45a.js +1 -0
  12. package/out/_next/static/chunks/{727-2c302be2def92786.js → 727-d0d6a29f0793bde2.js} +1 -1
  13. package/out/_next/static/chunks/pages/{_app-756c037ed6c707e9.js → _app-f7ec0d037993439e.js} +1 -1
  14. package/out/_next/static/chunks/pages/{changelog-5c9ac93faf0df06b.js → changelog-055db8139a22a592.js} +1 -1
  15. package/out/_next/static/chunks/pages/changes-f43ad4ab5e00f9b9.js +1 -0
  16. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-d1a4a07e6b600fa6.js → [customTypeId]-89ccb93ce7409ad0.js} +1 -1
  17. package/out/_next/static/chunks/pages/{labs-6f5925cd6cdcee9e.js → labs-73a12d2fe0233fb9.js} +1 -1
  18. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-a724ff12ef322020.js → [pageTypeId]-dbf86fe3a94dc892.js} +1 -1
  19. package/out/_next/static/chunks/pages/{settings-f0620e5b727cda03.js → settings-417f1d5c1e558c88.js} +1 -1
  20. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-a8933b0ef10806cd.js +1 -0
  21. package/out/_next/static/chunks/pages/slices-3c9b08adf578b020.js +1 -0
  22. package/out/_next/static/css/{838fd8bb5a7c32b0.css → 0e0d6c4ec6bf7373.css} +1 -1
  23. package/out/_next/static/css/{b22c0750c14cc089.css → 27f2b9b9c9f65885.css} +1 -1
  24. package/out/_next/static/css/{72465cc1225f28a2.css → 6e65ff596e3b465e.css} +1 -1
  25. package/out/_next/static/css/{21654235130d0806.css → fa4e416634515cbb.css} +1 -1
  26. package/out/_next/static/{dLmvq3LL0BsWu15laiKoK → w56F6n1XbyP8jyJHeri22}/_buildManifest.js +1 -1
  27. package/out/changelog.html +1 -1
  28. package/out/changes.html +1 -1
  29. package/out/custom-types/[customTypeId].html +1 -1
  30. package/out/custom-types.html +1 -1
  31. package/out/index.html +1 -1
  32. package/out/labs.html +1 -1
  33. package/out/page-types/[pageTypeId].html +1 -1
  34. package/out/settings.html +1 -1
  35. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  36. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  37. package/out/slices.html +1 -1
  38. package/package.json +5 -3
  39. package/pages/changes.tsx +4 -1
  40. package/pages/slices.tsx +4 -1
  41. package/src/components/Breadcrumb/Breadcrumb.module.css +11 -0
  42. package/src/components/Breadcrumb/Breadcrumb.module.css.d.ts +6 -0
  43. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +34 -0
  44. package/src/components/Breadcrumb/Breadcrumb.tsx +43 -25
  45. package/src/components/Breadcrumb/index.ts +1 -1
  46. package/src/components/CodeBlock/CodeBlock.module.css +46 -0
  47. package/src/components/CodeBlock/CodeBlock.module.css.d.ts +10 -0
  48. package/src/components/CodeBlock/CodeBlock.tsx +1 -1
  49. package/src/components/ContentTabs/ContentTabs.module.css +60 -0
  50. package/src/components/ContentTabs/ContentTabs.module.css.d.ts +12 -0
  51. package/src/components/ContentTabs/ContentTabs.tsx +1 -1
  52. package/src/components/Count/Count.module.css +19 -0
  53. package/src/components/Count/Count.module.css.d.ts +6 -0
  54. package/src/components/{Counter/Counter.stories.tsx → Count/Count.stories.tsx} +3 -3
  55. package/src/components/{Counter/Counter.tsx → Count/Count.tsx} +2 -2
  56. package/src/components/Count/index.ts +1 -0
  57. package/src/components/HoverCard/HoverCard.module.css +79 -0
  58. package/src/components/HoverCard/HoverCard.module.css.d.ts +13 -0
  59. package/src/components/HoverCard/HoverCard.tsx +1 -1
  60. package/src/components/TextLink/TextLink.module.css +58 -0
  61. package/src/components/TextLink/TextLink.module.css.d.ts +11 -0
  62. package/src/components/TextLink/TextLink.tsx +4 -4
  63. package/src/domain/__tests__/slice.test.ts +41 -0
  64. package/src/domain/slice.ts +25 -0
  65. package/src/features/customTypes/__tests__/CustomTypeBuilderPage.test.tsx +5 -6
  66. package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +9 -4
  67. package/src/features/customTypes/customTypesTable/CustomTypesTablePage.tsx +11 -12
  68. package/src/features/inAppGuide/InAppGuideDialog.tsx +2 -2
  69. package/src/features/labs/labsList/LabsPage.tsx +4 -1
  70. package/src/features/settings/SettingsPage.tsx +4 -1
  71. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewSliceDialog.tsx +1 -1
  72. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +1 -1
  73. package/src/features/slices/convertLegacySlice/ConvertLegacySliceButton.module.css +14 -0
  74. package/src/features/slices/convertLegacySlice/ConvertLegacySliceButton.module.css.d.ts +6 -0
  75. package/src/features/slices/convertLegacySlice/ConvertLegacySliceMergeWithIdenticalDialog.tsx +2 -5
  76. package/src/features/slices/sliceBuilder/useGroupsInSlicesExperiment.ts +8 -0
  77. package/test/__setup__.ts +3 -0
  78. package/components/Forms/RenameVariationModal/RenameVariationModal.css.ts +0 -7
  79. package/components/Navigation/index.css.ts +0 -5
  80. package/out/_next/static/chunks/318-d6f1200138628ec3.js +0 -1
  81. package/out/_next/static/chunks/904-c9221a5cb09524e8.js +0 -1
  82. package/out/_next/static/chunks/pages/changes-3e4989e09fd412a8.js +0 -1
  83. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-8d7043e6638d65cd.js +0 -1
  84. package/out/_next/static/chunks/pages/slices-77cff50b1df13579.js +0 -1
  85. package/src/components/Breadcrumb/Breadcrumb.css.ts +0 -5
  86. package/src/components/Breadcrumb/Breadcrumb.stories.ts +0 -32
  87. package/src/components/CodeBlock/CodeBlock.css.ts +0 -37
  88. package/src/components/ContentTabs/ContentTabs.css.ts +0 -49
  89. package/src/components/Counter/Counter.css.ts +0 -26
  90. package/src/components/Counter/index.ts +0 -1
  91. package/src/components/HoverCard/HoverCard.css.ts +0 -105
  92. package/src/components/TextLink/TextLink.css.ts +0 -65
  93. package/src/features/slices/convertLegacySlice/ConvertLegacySliceButton.css.ts +0 -15
  94. /package/out/_next/static/{dLmvq3LL0BsWu15laiKoK → w56F6n1XbyP8jyJHeri22}/_ssgManifest.js +0 -0
@@ -1,12 +1,12 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
 
3
- import { Counter } from "./Counter";
3
+ import { Count } from "./Count";
4
4
 
5
5
  type Story = StoryObj<typeof meta>;
6
6
 
7
7
  const meta = {
8
- component: Counter,
9
- } satisfies Meta<typeof Counter>;
8
+ component: Count,
9
+ } satisfies Meta<typeof Count>;
10
10
 
11
11
  export default meta;
12
12
 
@@ -2,9 +2,9 @@ import { FC, PropsWithChildren } from "react";
2
2
 
3
3
  import { FlowerBackgroundIcon } from "@src/icons/FlowerBackgroundIcon";
4
4
 
5
- import * as styles from "./Counter.css";
5
+ import styles from "./Count.module.css";
6
6
 
7
- export const Counter: FC<PropsWithChildren> = (props) => {
7
+ export const Count: FC<PropsWithChildren> = (props) => {
8
8
  const { children } = props;
9
9
 
10
10
  return (
@@ -0,0 +1 @@
1
+ export { Count } from "./Count";
@@ -0,0 +1,79 @@
1
+ .block {
2
+ all: unset;
3
+ box-sizing: border-box;
4
+ font-family: var(--font-family-body);
5
+ }
6
+
7
+ .blockWithDisplayRevert {
8
+ composes: block;
9
+ display: revert;
10
+ }
11
+
12
+ .root {
13
+ composes: blockWithDisplayRevert;
14
+ width: 288px;
15
+ }
16
+
17
+ .title {
18
+ composes: block;
19
+ align-items: center;
20
+ border-bottom-style: solid;
21
+ border-color: var(--grey6);
22
+ border-width: 1px;
23
+ color: var(--grey12);
24
+ display: flex;
25
+ justify-content: space-between;
26
+ margin-bottom: 16px;
27
+ padding-bottom: 4px;
28
+ padding-left: 16px;
29
+ padding-right: 6px;
30
+ padding-top: 4px;
31
+ font-size: 12px;
32
+ font-weight: 500;
33
+ line-height: 16px;
34
+ }
35
+
36
+ .titleCloseIcon {
37
+ composes: block;
38
+ color: var(--grey11);
39
+ display: flex;
40
+ padding: 4px;
41
+
42
+ &:hover {
43
+ cursor: pointer;
44
+ }
45
+ }
46
+
47
+ .mediaContainer {
48
+ composes: block;
49
+ display: flex;
50
+ margin-bottom: 8px;
51
+ padding-inline: 16px;
52
+ }
53
+
54
+ .media {
55
+ composes: blockWithDisplayRevert;
56
+ border-color: var(--grey6);
57
+ border-radius: 6px;
58
+ border-style: solid;
59
+ border-width: 1px;
60
+ overflow: hidden;
61
+ width: 100%;
62
+ height: 146px;
63
+ }
64
+
65
+ .description {
66
+ composes: blockWithDisplayRevert;
67
+ color: var(--grey11);
68
+ margin-bottom: 16px;
69
+ padding-inline: 16px;
70
+ font-size: 12px;
71
+ font-weight: 400;
72
+ line-height: 20px;
73
+ }
74
+
75
+ .closeButtonContainer {
76
+ composes: blockWithDisplayRevert;
77
+ padding-bottom: 16px;
78
+ padding-inline: 16px;
79
+ }
@@ -0,0 +1,13 @@
1
+ declare const styles: {
2
+ readonly "block": string;
3
+ readonly "blockWithDisplayRevert": string;
4
+ readonly "closeButtonContainer": string;
5
+ readonly "description": string;
6
+ readonly "media": string;
7
+ readonly "mediaContainer": string;
8
+ readonly "root": string;
9
+ readonly "title": string;
10
+ readonly "titleCloseIcon": string;
11
+ };
12
+ export = styles;
13
+
@@ -17,7 +17,7 @@ import { useDelayedAction } from "@src/hooks/useDelayedAction";
17
17
  import { CloseIcon } from "@src/icons/CloseIcon";
18
18
 
19
19
  import { BaseHoverCard, type BaseHoverCardProps } from "../BaseHoverCard";
20
- import * as styles from "./HoverCard.css";
20
+ import styles from "./HoverCard.module.css";
21
21
 
22
22
  type HoverCardProps = PropsWithChildren<{
23
23
  align?: BaseHoverCardProps["align"];
@@ -0,0 +1,58 @@
1
+ .root {
2
+ all: unset;
3
+ cursor: pointer;
4
+ display: flex;
5
+ align-items: center;
6
+
7
+ &:focus-visible {
8
+ outline: none;
9
+ text-decoration-line: underline;
10
+ }
11
+ }
12
+
13
+ .color-primary {
14
+ color: var(--purple9);
15
+
16
+ &:hover {
17
+ color: var(--purple8);
18
+ }
19
+
20
+ &:active {
21
+ color: var(--purple9);
22
+ }
23
+ }
24
+
25
+ .color-secondary {
26
+ color: var(--indigo11);
27
+
28
+ &:hover {
29
+ color: var(--indigo10);
30
+ }
31
+
32
+ &:active {
33
+ color: var(--indigo11);
34
+ }
35
+ }
36
+
37
+ .endIcon {
38
+ padding-left: 4px;
39
+ }
40
+
41
+ .icon-normal {
42
+ font-size: 1.2rem;
43
+ width: 18px;
44
+ height: 18px;
45
+ }
46
+
47
+ .icon-smallBold {
48
+ font-size: 1rem;
49
+ width: 16px;
50
+ height: 16px;
51
+ }
52
+
53
+ .icon-inherit {
54
+ font-family: inherit;
55
+ font-size: inherit;
56
+ width: inherit;
57
+ height: inherit;
58
+ }
@@ -0,0 +1,11 @@
1
+ declare const styles: {
2
+ readonly "color-primary": string;
3
+ readonly "color-secondary": string;
4
+ readonly "endIcon": string;
5
+ readonly "icon-inherit": string;
6
+ readonly "icon-normal": string;
7
+ readonly "icon-smallBold": string;
8
+ readonly "root": string;
9
+ };
10
+ export = styles;
11
+
@@ -2,7 +2,7 @@ import { Text } from "@prismicio/editor-ui";
2
2
  import { clsx } from "clsx";
3
3
  import { type FC, type ReactNode, cloneElement, isValidElement } from "react";
4
4
 
5
- import * as styles from "./TextLink.css";
5
+ import styles from "./TextLink.module.css";
6
6
 
7
7
  type IconProps = Readonly<{
8
8
  className?: string;
@@ -10,7 +10,7 @@ type IconProps = Readonly<{
10
10
 
11
11
  interface TextLinkProps {
12
12
  children: string;
13
- color?: keyof typeof styles.colorVariant;
13
+ color?: "primary" | "secondary";
14
14
  endIcon?: ReactNode;
15
15
  href: string;
16
16
  textVariant?: "normal" | "smallBold" | "inherit";
@@ -32,7 +32,7 @@ export const TextLink: FC<TextLinkProps> = (props) => {
32
32
  target="_blank"
33
33
  rel="noreferrer"
34
34
  {...otherProps}
35
- className={clsx(styles.root, styles.colorVariant[color])}
35
+ className={clsx(styles.root, styles[`color-${color}`])}
36
36
  >
37
37
  <Text component="span" color="inherit" variant={textVariant}>
38
38
  {children}
@@ -42,7 +42,7 @@ export const TextLink: FC<TextLinkProps> = (props) => {
42
42
  className: clsx(
43
43
  endIcon.props.className,
44
44
  styles.endIcon,
45
- styles.iconVariant[textVariant],
45
+ styles[`icon-${textVariant}`],
46
46
  ),
47
47
  })
48
48
  : null}
@@ -0,0 +1,41 @@
1
+ import { it, describe, expect } from "vitest";
2
+ import { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
3
+
4
+ import { Slices } from "@lib/models/common/Slice";
5
+ import { ComponentUI } from "@lib/models/common/ComponentUI";
6
+
7
+ import { deleteRepeatableZone } from "../slice";
8
+
9
+ describe("deleteRepeatableZone", () => {
10
+ it("removes the `items` property from a specific variation within a slice", (ctx) => {
11
+ const variation = ctx.createMock.model.sharedSliceVariation({
12
+ itemsFields: { foo: ctx.createMock.model.boolean() },
13
+ });
14
+ const model = ctx.createMock.model.sharedSlice({ variations: [variation] });
15
+ const slice = buildMockSliceComponentUI(model);
16
+
17
+ const res = deleteRepeatableZone({ slice, variationId: variation.id });
18
+ expect(res.model.variations[0].items).toBeUndefined();
19
+ });
20
+
21
+ it("does nothing if the variation does not exist", (ctx) => {
22
+ const model = ctx.createMock.model.sharedSlice();
23
+ const slice = buildMockSliceComponentUI(model);
24
+
25
+ const res = deleteRepeatableZone({ slice, variationId: "non-existent" });
26
+ expect(res).toStrictEqual(slice);
27
+ });
28
+ });
29
+
30
+ function buildMockSliceComponentUI(model: SharedSlice): ComponentUI {
31
+ return {
32
+ model: Slices.toSM(model),
33
+ extension: "extension",
34
+ fileName: "fileName",
35
+ from: "from",
36
+ href: "href",
37
+ mocks: [],
38
+ pathToSlice: "pathToSlice",
39
+ screenshots: {},
40
+ };
41
+ }
@@ -48,6 +48,11 @@ type ReorderFieldArgs = {
48
48
  destinationIndex: number;
49
49
  };
50
50
 
51
+ type DeleteRepeatableZoneArgs = {
52
+ slice: ComponentUI;
53
+ variationId: string;
54
+ };
55
+
51
56
  const DEFAULT_VARIATION_ID = "default";
52
57
 
53
58
  export function countMissingScreenshots(slice: ComponentUI): number {
@@ -281,3 +286,23 @@ export function rename(slice: ComponentUI, newSliceName: string): ComponentUI {
281
286
  },
282
287
  };
283
288
  }
289
+
290
+ export function deleteRepeatableZone(args: DeleteRepeatableZoneArgs) {
291
+ const { slice, variationId } = args;
292
+
293
+ return {
294
+ ...slice,
295
+ model: {
296
+ ...slice.model,
297
+ variations: slice.model.variations.map((v) => {
298
+ if (v.id === variationId) {
299
+ const newVariation = { ...v };
300
+ delete newVariation.items;
301
+
302
+ return newVariation;
303
+ }
304
+ return v;
305
+ }),
306
+ },
307
+ };
308
+ }
@@ -89,10 +89,9 @@ describe.each(formats)(
89
89
  // Submit the form
90
90
  await user.click(screen.getByRole("button", { name: "Rename" }));
91
91
 
92
- const folder =
93
- customType.format === "page" ? "Page types" : "Custom types";
92
+ const breadcrumb = screen.getByLabelText("Breadcrumb");
94
93
  expect(
95
- screen.getByTestId(`breadcrumb-${folder}-${renamedCustomType}`),
94
+ await within(breadcrumb).findByText(renamedCustomType),
96
95
  ).toBeVisible();
97
96
  });
98
97
  },
@@ -178,10 +177,10 @@ async function renderCustomTypesBuilderPage({
178
177
  const renderResults = render(<CustomTypesBuilderPage />, customTypeMockStore);
179
178
 
180
179
  const folder = customType.format === "page" ? "Page types" : "Custom types";
181
- const breadcrumb = await screen.findByTestId(
182
- `breadcrumb-${folder}-${customType.label as string}`,
180
+ const breadcrumb = await screen.findByLabelText("Breadcrumb");
181
+ expect(breadcrumb).toHaveTextContent(
182
+ `${folder}/${customType.label as string}`,
183
183
  );
184
- expect(breadcrumb).toBeVisible();
185
184
 
186
185
  return renderResults;
187
186
  }
@@ -26,6 +26,7 @@ import { CUSTOM_TYPES_MESSAGES } from "../customTypesMessages";
26
26
  import { EditDropdown } from "../EditDropdown";
27
27
  import { PageSnippetDialog } from "./PageSnippetDialog";
28
28
  import { CustomTypeProvider } from "./CustomTypeProvider";
29
+ import { BreadcrumbItem } from "@src/components/Breadcrumb";
29
30
 
30
31
  export const CustomTypesBuilderPage: FC = () => {
31
32
  const router = useRouter();
@@ -87,10 +88,14 @@ const CustomTypesBuilderPageWithProvider: React.FC<
87
88
  <>
88
89
  <AppLayoutHeader>
89
90
  <AppLayoutBackButton url={config.tablePagePathname} />
90
- <AppLayoutBreadcrumb
91
- folder={messages.name({ start: true, plural: true })}
92
- page={customType.label ?? customType.id}
93
- />
91
+ <AppLayoutBreadcrumb>
92
+ <BreadcrumbItem>
93
+ {messages.name({ start: true, plural: true })}
94
+ </BreadcrumbItem>
95
+ <BreadcrumbItem active>
96
+ {customType.label ?? customType.id}
97
+ </BreadcrumbItem>
98
+ </AppLayoutBreadcrumb>
94
99
  <AppLayoutActions>
95
100
  <AutoSaveStatusIndicator status={actionQueueStatus} />
96
101
  {customType.format === "page" ? (
@@ -20,6 +20,7 @@ import { ErrorBoundary } from "@src/ErrorBoundary";
20
20
  import type { CustomTypeFormat } from "@slicemachine/manager";
21
21
 
22
22
  import { CustomTypesTable } from "./CustomTypesTable";
23
+ import { BreadcrumbItem } from "@src/components/Breadcrumb";
23
24
 
24
25
  type CustomTypesTablePageProps = {
25
26
  format: CustomTypeFormat;
@@ -61,12 +62,11 @@ export const CustomTypesTablePage: FC<CustomTypesTablePageProps> = ({
61
62
  fallback={
62
63
  <AppLayout>
63
64
  <AppLayoutHeader>
64
- <AppLayoutBreadcrumb
65
- folder={customTypesMessages.name({
66
- start: true,
67
- plural: true,
68
- })}
69
- />
65
+ <AppLayoutBreadcrumb>
66
+ <BreadcrumbItem>
67
+ {customTypesMessages.name({ start: true, plural: true })}
68
+ </BreadcrumbItem>
69
+ </AppLayoutBreadcrumb>
70
70
  <AppLayoutActions>
71
71
  <Button disabled startIcon="add">
72
72
  Create
@@ -81,12 +81,11 @@ export const CustomTypesTablePage: FC<CustomTypesTablePageProps> = ({
81
81
  >
82
82
  <AppLayout>
83
83
  <AppLayoutHeader>
84
- <AppLayoutBreadcrumb
85
- folder={customTypesMessages.name({
86
- start: true,
87
- plural: true,
88
- })}
89
- />
84
+ <AppLayoutBreadcrumb>
85
+ <BreadcrumbItem>
86
+ {customTypesMessages.name({ start: true, plural: true })}
87
+ </BreadcrumbItem>
88
+ </AppLayoutBreadcrumb>
90
89
  <AppLayoutActions>
91
90
  <Button
92
91
  data-testid="create-ct"
@@ -11,7 +11,7 @@ import {
11
11
  Video,
12
12
  } from "@prismicio/editor-ui";
13
13
 
14
- import { Counter } from "@src/components/Counter";
14
+ import { Count } from "@src/components/Count";
15
15
  import { HelpIcon } from "@src/icons/HelpIcon";
16
16
  import { useIsEmptyProject } from "@src/hooks/useIsEmptyProject";
17
17
 
@@ -67,7 +67,7 @@ export const InAppGuideDialog: FC = () => {
67
67
  <Box key={index} flexDirection="column">
68
68
  <Box flexDirection="column" padding={16} gap={8}>
69
69
  <Box alignItems="center" gap={8}>
70
- <Counter>{index + 1}</Counter>
70
+ <Count>{index + 1}</Count>
71
71
  <Text component="h3" variant="bold">
72
72
  {content.title}
73
73
  </Text>
@@ -11,6 +11,7 @@ import {
11
11
  import { ErrorBoundary } from "@src/ErrorBoundary";
12
12
 
13
13
  import { LabsList } from "./LabsList";
14
+ import { BreadcrumbItem } from "@src/components/Breadcrumb";
14
15
 
15
16
  export const LabsPage: FC = () => {
16
17
  return (
@@ -58,7 +59,9 @@ const LabsPageLayout: FC<LabsPageLayoutProps> = ({
58
59
  <AppLayout>
59
60
  {withHeader ? (
60
61
  <AppLayoutHeader>
61
- <AppLayoutBreadcrumb folder="Labs" />
62
+ <AppLayoutBreadcrumb>
63
+ <BreadcrumbItem>Labs</BreadcrumbItem>
64
+ </AppLayoutBreadcrumb>
62
65
  </AppLayoutHeader>
63
66
  ) : null}
64
67
  <AppLayoutContent>{children}</AppLayoutContent>
@@ -11,6 +11,7 @@ import {
11
11
  } from "@components/AppLayout";
12
12
  import { ConnectGitRepository } from "@src/features/settings/git/ConnectGitRepository";
13
13
  import { useGitIntegrationExperiment } from "@src/features/settings/git/useGitIntegrationExperiment";
14
+ import { BreadcrumbItem } from "@src/components/Breadcrumb";
14
15
 
15
16
  export const SettingsPage: FC = () => {
16
17
  const gitIntegrationExperiment = useGitIntegrationExperiment();
@@ -34,7 +35,9 @@ export const SettingsPage: FC = () => {
34
35
  </Head>
35
36
  <AppLayout>
36
37
  <AppLayoutHeader>
37
- <AppLayoutBreadcrumb folder="Settings" />
38
+ <AppLayoutBreadcrumb>
39
+ <BreadcrumbItem>Settings</BreadcrumbItem>
40
+ </AppLayoutBreadcrumb>
38
41
  </AppLayoutHeader>
39
42
  <AppLayoutContent>
40
43
  <Box flexDirection="column" maxWidth={600}>
@@ -19,7 +19,7 @@ import { getRemoteSlices } from "@src/modules/slices";
19
19
  import { pascalize } from "@lib/utils/str";
20
20
  import { validateSliceModalValues as validateAsNewSliceValues } from "@components/Forms/formsValidator";
21
21
 
22
- import * as styles from "./ConvertLegacySliceButton.css";
22
+ import styles from "./ConvertLegacySliceButton.module.css";
23
23
  import { DialogProps } from "./types";
24
24
 
25
25
  export const ConvertLegacySliceAsNewSliceDialog: FC<DialogProps> = ({
@@ -16,7 +16,7 @@ import {
16
16
 
17
17
  import { LibraryUI } from "@models/common/LibraryUI";
18
18
 
19
- import * as styles from "./ConvertLegacySliceButton.css";
19
+ import styles from "./ConvertLegacySliceButton.module.css";
20
20
  import { DialogProps } from "./types";
21
21
 
22
22
  type FormValues = {
@@ -0,0 +1,14 @@
1
+ .scrollArea {
2
+ width: 448px;
3
+ height: 100%;
4
+ display: flex;
5
+ gap: 8px;
6
+ padding-inline: 16px;
7
+ padding-block: 16px;
8
+ }
9
+
10
+ .label {
11
+ display: inline-flex;
12
+ align-items: center;
13
+ gap: 4px;
14
+ }
@@ -0,0 +1,6 @@
1
+ declare const styles: {
2
+ readonly "label": string;
3
+ readonly "scrollArea": string;
4
+ };
5
+ export = styles;
6
+
@@ -12,7 +12,7 @@ import {
12
12
  SelectItem,
13
13
  } from "@prismicio/editor-ui";
14
14
 
15
- import * as styles from "./ConvertLegacySliceButton.css";
15
+ import styles from "./ConvertLegacySliceButton.module.css";
16
16
  import { DialogProps } from "./types";
17
17
 
18
18
  export const ConvertLegacySliceMergeWithIdenticalDialog: FC<DialogProps> = ({
@@ -48,10 +48,7 @@ export const ConvertLegacySliceMergeWithIdenticalDialog: FC<DialogProps> = ({
48
48
  return (
49
49
  <form id="convert-legacy-slice-merge-with-identical-dialog">
50
50
  <Box display="flex" flexDirection="column">
51
- <ScrollArea
52
- className={styles.scrollArea}
53
- style={{ width: 448 }}
54
- >
51
+ <ScrollArea className={styles.scrollArea}>
55
52
  <Text variant="normal" color="grey11">
56
53
  If you have multiple identical slices, you can merge them.
57
54
  All of your content will be remapped to the target slice.
@@ -0,0 +1,8 @@
1
+ import { useExperimentVariant } from "@src/hooks/useExperimentVariant";
2
+
3
+ type UseGitIntegrationExperimentReturnType = { eligible: boolean };
4
+
5
+ export function useGroupsInSlicesExperiment(): UseGitIntegrationExperimentReturnType {
6
+ const variant = useExperimentVariant("slicemachine-groups-in-slices");
7
+ return { eligible: variant?.value === "on" };
8
+ }
package/test/__setup__.ts CHANGED
@@ -3,6 +3,7 @@ import fetch, { Blob, File, Headers, Request, Response } from "node-fetch";
3
3
  import { FormData } from "formdata-polyfill/esm.min";
4
4
  import { setupServer, SetupServer } from "msw/node";
5
5
  import { cleanup } from "@testing-library/react";
6
+ import { createMockFactory, MockFactory } from "@prismicio/mock";
6
7
  import * as fs from "node:fs/promises";
7
8
  import * as path from "node:path";
8
9
  import * as os from "node:os";
@@ -17,6 +18,7 @@ import { createTestProject } from "./__testutils__/createTestProject";
17
18
  declare module "vitest" {
18
19
  export interface TestContext {
19
20
  msw: SetupServer;
21
+ createMock: MockFactory;
20
22
  }
21
23
  }
22
24
 
@@ -28,6 +30,7 @@ beforeAll(() => {
28
30
 
29
31
  beforeEach(async (ctx) => {
30
32
  ctx.msw = mswServer;
33
+ ctx.createMock = createMockFactory({ seed: ctx.task.id });
31
34
 
32
35
  const adapter = createTestPlugin();
33
36
  const cwd = await createTestProject({ adapter });
@@ -1,7 +0,0 @@
1
- import { sprinkles } from "@prismicio/editor-ui";
2
-
3
- export const label = sprinkles({
4
- display: "inline-flex",
5
- alignItems: "center",
6
- gap: 4,
7
- });
@@ -1,5 +0,0 @@
1
- import { sprinkles } from "@prismicio/editor-ui";
2
-
3
- export const environmentDivider = sprinkles({
4
- marginBlock: 16,
5
- });