@se-studio/project-build 1.0.51 → 1.0.53

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 (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/management/check-target.d.ts +2 -0
  3. package/dist/management/check-target.d.ts.map +1 -0
  4. package/dist/management/check-target.js +40 -0
  5. package/dist/management/check-target.js.map +1 -0
  6. package/dist/management/count-brightline.d.ts +2 -0
  7. package/dist/management/count-brightline.d.ts.map +1 -0
  8. package/dist/management/count-brightline.js +37 -0
  9. package/dist/management/count-brightline.js.map +1 -0
  10. package/dist/management/cross-check-migration.d.ts +2 -0
  11. package/dist/management/cross-check-migration.d.ts.map +1 -0
  12. package/dist/management/cross-check-migration.js +212 -0
  13. package/dist/management/cross-check-migration.js.map +1 -0
  14. package/dist/management/discovery-brightlife.d.ts +2 -0
  15. package/dist/management/discovery-brightlife.d.ts.map +1 -0
  16. package/dist/management/discovery-brightlife.js +78 -0
  17. package/dist/management/discovery-brightlife.js.map +1 -0
  18. package/dist/management/discovery-brightline.d.ts +2 -0
  19. package/dist/management/discovery-brightline.d.ts.map +1 -0
  20. package/dist/management/discovery-brightline.js +68 -0
  21. package/dist/management/discovery-brightline.js.map +1 -0
  22. package/dist/management/inspect-target.d.ts +2 -0
  23. package/dist/management/inspect-target.d.ts.map +1 -0
  24. package/dist/management/inspect-target.js +48 -0
  25. package/dist/management/inspect-target.js.map +1 -0
  26. package/dist/management/migrate-brightlife.d.ts +2 -0
  27. package/dist/management/migrate-brightlife.d.ts.map +1 -0
  28. package/dist/management/migrate-brightlife.js +475 -0
  29. package/dist/management/migrate-brightlife.js.map +1 -0
  30. package/dist/management/migrate-brightline.d.ts +2 -0
  31. package/dist/management/migrate-brightline.d.ts.map +1 -0
  32. package/dist/management/migrate-brightline.js +1085 -0
  33. package/dist/management/migrate-brightline.js.map +1 -0
  34. package/dist/management/sync-skills.d.ts +2 -0
  35. package/dist/management/sync-skills.d.ts.map +1 -0
  36. package/dist/management/sync-skills.js +46 -0
  37. package/dist/management/sync-skills.js.map +1 -0
  38. package/dist/seskills.d.ts +9 -0
  39. package/dist/seskills.d.ts.map +1 -0
  40. package/dist/seskills.js +25 -0
  41. package/dist/seskills.js.map +1 -0
  42. package/package.json +7 -6
  43. package/skills/se-marketing-sites/create-collection/SKILL.md +283 -0
  44. package/skills/se-marketing-sites/create-component/SKILL.md +245 -0
  45. package/skills/se-marketing-sites/create-page/SKILL.md +134 -0
  46. package/skills/se-marketing-sites/handling-media/SKILL.md +118 -0
  47. package/skills/se-marketing-sites/register-cms-features/SKILL.md +95 -0
  48. package/skills/se-marketing-sites/styling-system/SKILL.md +118 -0
@@ -0,0 +1,245 @@
1
+ ---
2
+ name: create-cms-component
3
+ description: Guide for creating new CMS-driven components in the SE Core Product monorepo. Use this skill when asked to create a new component, ensuring adherence to the 4-layer architecture.
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.1.0"
8
+ ---
9
+
10
+ # Creating CMS Components
11
+
12
+ This guide explains how to build new CMS-driven components following the established architecture patterns in this codebase.
13
+
14
+ ## Architecture Overview
15
+
16
+ All components follow a **four-layer architecture** and must remain **Server Components** by default.
17
+
18
+ 1. **Layer 1: Core Component (Pure Presentation)**
19
+ * Named export: `Core[ComponentName]`
20
+ * CMS-agnostic rendering logic
21
+ * Accepts `positionClassName` prop
22
+ * **MUST be a Server Component** (no `'use client'`)
23
+ * If interactivity is needed, import a Client Component here.
24
+
25
+ 2. **Layer 2: Wrapper Component (Section Integration)**
26
+ * Named export: `[ComponentName]`
27
+ * Wraps Core with `<Section>`
28
+ * Handles spacing & background
29
+
30
+ 3. **Layer 3: Renderer (CMS Integration)**
31
+ * Default export: `[ComponentName]` (short name)
32
+ * Implements `ComponentRenderer`
33
+ * Wraps with `UnusedChecker` for CMS validation
34
+
35
+ 4. **Layer 4: Registration (Showcase & CMS)**
36
+ * Named export: `[ComponentName]Registration`
37
+ * Uses `defineComponent` helper
38
+ * Provides metadata & mock data
39
+
40
+ ## Client Component Strategy
41
+
42
+ **Rule: Isolate Client Logic.**
43
+
44
+ Never make the entire component a Client Component just for a small interactive part.
45
+
46
+ * **BAD**: Adding `'use client'` to `MyComponent.tsx` (Layers 1-3).
47
+ * **GOOD**: Creating `MyComponentClient.tsx` (or `*Animator.tsx`) with `'use client'` and importing it into `CoreMyComponent`.
48
+
49
+ ### Why?
50
+ * **Performance**: Keeps the majority of the HTML generation on the server.
51
+ * **SEO**: Ensures content is fully rendered for crawlers.
52
+ * **Bundle Size**: Only sends necessary JS to the browser.
53
+
54
+ ### Pattern: The Client Wrapper
55
+
56
+ If you need state (e.g., filters, toggles) or effects (e.g., animations), create a wrapper:
57
+
58
+ 1. Create `MyComponentClient.tsx` (or `MyComponentAnimator.tsx`).
59
+ 2. Add `'use client'` at the top.
60
+ 3. Accept `children` or raw data props.
61
+ 4. Import and use it in `CoreMyComponent`.
62
+
63
+ ## Quick Start Template
64
+
65
+ Use this template for new components. Replace `MyNewComponent` with your component name.
66
+
67
+ ```typescript
68
+ import type { IContentContext } from '@se-studio/core-data-types';
69
+ import {
70
+ type CmsRendererConfig,
71
+ type ComponentRenderer,
72
+ convertText,
73
+ cn,
74
+ defineComponent,
75
+ RtfOrString,
76
+ UnusedChecker,
77
+ } from '@se-studio/core-ui';
78
+ import { SectionLinks } from '@/elements/SectionLinks';
79
+ import { Section } from '@/framework/Section';
80
+ import type { IComponent, IContent } from '@/lib/cms';
81
+ import { getPreviewFieldIdProps } from '@/lib/cms';
82
+ import { getSizingInformation } from '@/lib/SizingInformation';
83
+ // If interactivity is needed:
84
+ // import MyNewComponentClient from './MyNewComponentClient';
85
+
86
+ // 1. Define which CMS fields this component uses
87
+ const FIELD_KEYS = [
88
+ 'id',
89
+ 'index',
90
+ 'heading',
91
+ 'body',
92
+ 'links',
93
+ 'anchor',
94
+ 'cmsLabel',
95
+ ] as const;
96
+
97
+ type Fields = Pick<IComponent, (typeof FIELD_KEYS)[number]>;
98
+
99
+ const USED_FIELDS = new Set([...FIELD_KEYS, 'componentType']);
100
+
101
+ // 2. Layer 1: Core Component (Pure presentation, Server Component)
102
+ export const CoreMyNewComponent: React.FC<
103
+ Fields & {
104
+ contentContext?: IContentContext;
105
+ rendererConfig?: CmsRendererConfig;
106
+ embedded?: boolean;
107
+ positionClassName?: string;
108
+ }
109
+ > = ({
110
+ id,
111
+ index,
112
+ heading,
113
+ body,
114
+ links,
115
+ cmsLabel,
116
+ contentContext,
117
+ rendererConfig,
118
+ positionClassName,
119
+ }) => {
120
+ const { Element, sizingInformation } = getSizingInformation(index);
121
+
122
+ return (
123
+ <div className={cn('space-y-6', positionClassName)}>
124
+ {heading && (
125
+ <Element
126
+ {...getPreviewFieldIdProps(id, 'heading')}
127
+ className={cn(sizingInformation.h1)}
128
+ >
129
+ {convertText(heading)}
130
+ </Element>
131
+ )}
132
+ {body && (
133
+ <RtfOrString
134
+ {...getPreviewFieldIdProps(id, 'body')}
135
+ content={body}
136
+ className={cn('rtf-standard')}
137
+ rendererConfig={rendererConfig}
138
+ contentContext={contentContext}
139
+ />
140
+ )}
141
+ {/* Example of isolated client logic usage: */}
142
+ {/* <MyNewComponentClient>
143
+ <InteractivePart />
144
+ </MyNewComponentClient>
145
+ */}
146
+ {links && (
147
+ <SectionLinks
148
+ links={links}
149
+ trackingLocation={cmsLabel}
150
+ analyticsContext={contentContext?.analyticsContext}
151
+ />
152
+ )}
153
+ </div>
154
+ );
155
+ };
156
+
157
+ // 3. Layer 2: Wrapper Component (Section integration)
158
+ const MyNewComponent: React.FC<
159
+ Fields &
160
+ Pick<IComponent, 'componentType'> & {
161
+ contentContext: IContentContext;
162
+ information: IContent;
163
+ rendererConfig: CmsRendererConfig;
164
+ }
165
+ > = ({ information, componentType, ...rest }) => {
166
+ return (
167
+ <Section componentName={componentType} information={information}>
168
+ <CoreMyNewComponent
169
+ {...rest}
170
+ positionClassName="col-span-full laptop:col-start-2 laptop:col-span-10"
171
+ />
172
+ </Section>
173
+ );
174
+ };
175
+
176
+ // 4. Layer 3: Renderer Export (CMS integration)
177
+ const MyNew: ComponentRenderer<IComponent> = ({
178
+ information,
179
+ contentContext,
180
+ rendererConfig,
181
+ }) => {
182
+ const { componentType, ...rest } = information;
183
+
184
+ return (
185
+ <UnusedChecker componentName={componentType} allFields={rest} usedFields={USED_FIELDS}>
186
+ <MyNewComponent
187
+ rendererConfig={rendererConfig}
188
+ contentContext={contentContext}
189
+ information={information}
190
+ componentType={componentType}
191
+ {...rest}
192
+ />
193
+ </UnusedChecker>
194
+ );
195
+ };
196
+
197
+ export default MyNew;
198
+
199
+ // 5. Layer 4: Registration
200
+ export const MyNewRegistration = defineComponent({
201
+ name: 'My New Component', // Must match CMS componentType
202
+ renderer: MyNew,
203
+ usedFields: USED_FIELDS,
204
+ mock: {
205
+ heading: 'Sample Heading',
206
+ body: 'This is sample body text for the showcase.',
207
+ },
208
+ });
209
+ ```
210
+
211
+ ## Implementation Checklist
212
+
213
+ 1. **Create file**: `src/project/components/MyNewComponent.tsx`
214
+ 2. **Define Fields**:
215
+ * Set `FIELD_KEYS` with all used fields.
216
+ * Create `Fields` type.
217
+ * Create `USED_FIELDS` set (don't forget `'componentType'`).
218
+ * Include standard fields: `id`, `index`, `anchor`, `cmsLabel`.
219
+ 3. **Build Core Component**:
220
+ * **ENSURE SERVER COMPONENT**: Do not use `'use client'`.
221
+ * Export named `Core[Name]`.
222
+ * Accept `positionClassName`.
223
+ * Use `getSizingInformation(index)` for semantic headings.
224
+ * Check field existence (`field &&`).
225
+ * Use `convertText()` for strings.
226
+ * Use `<RtfOrString>` for rich text.
227
+ * Apply `getPreviewFieldIdProps()` for CMS preview.
228
+ 4. **Handle Interactivity (If Needed)**:
229
+ * Create separate `[Name]Client.tsx` or `[Name]Animator.tsx`.
230
+ * Add `'use client'` to that file only.
231
+ * Import and use in Core component.
232
+ 5. **Build Wrapper Component**:
233
+ * Wrap Core with `<Section>`.
234
+ * Pass `componentName={componentType}` and `information`.
235
+ * Set layout (e.g., `positionClassName="col-span-full"`).
236
+ 6. **Build Renderer**:
237
+ * Default export (short name).
238
+ * Wrap with `<UnusedChecker>`.
239
+ 7. **Define Registration**:
240
+ * Export named `[Name]Registration`.
241
+ * Use `defineComponent`.
242
+ * **CRITICAL**: `name` must match CMS `componentType` exactly.
243
+ * Provide mock data for showcase.
244
+ 8. **Register Component**:
245
+ * Add to `componentRegistrations` array in `src/lib/cms.ts`.
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: create-page-route
3
+ description: Guide for creating new Next.js App Router pages and dynamic routes in the SE Core Product framework.
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Creating Pages and Routes
11
+
12
+ This guide explains how to create new pages and handle routing in the SE Core Product Next.js framework. The system uses Next.js App Router with Contentful-driven dynamic routing.
13
+
14
+ ## Page Architecture
15
+
16
+ ### 1. Dynamic Catch-All Route (`[...slugs]`)
17
+
18
+ Most CMS pages are handled by a single catch-all route at `app/(pages)/[...slugs]/page.tsx`. This component:
19
+ 1. Receives the URL slug.
20
+ 2. Fetches the page data from Contentful.
21
+ 3. Renders the `<CmsContent>` component.
22
+
23
+ ### 2. Static Params Generation
24
+
25
+ To enable Static Site Generation (SSG), the page exports `generateStaticParams`:
26
+
27
+ ```typescript
28
+ import { getAllPageLinks } from '@/lib/cms';
29
+
30
+ export async function generateStaticParams() {
31
+ const links = await getAllPageLinks();
32
+ return links
33
+ .filter(link => link.slug !== 'index')
34
+ .map(link => ({
35
+ slugs: link.href?.split('/').filter(Boolean)
36
+ }));
37
+ }
38
+ ```
39
+
40
+ ## Creating a New Specialized Route
41
+
42
+ Sometimes you need a route that behaves differently from standard CMS pages (e.g., a search page, a dashboard, or a specialized landing page).
43
+
44
+ ### Step 1: Create the Route Directory
45
+
46
+ Create a new directory in `src/app` matching your desired URL structure.
47
+
48
+ * Example: `src/app/search/page.tsx` -> `/search`
49
+ * Example: `src/app/team/[slug]/page.tsx` -> `/team/john-doe`
50
+
51
+ ### Step 2: Implement the Page Component
52
+
53
+ ```typescript
54
+ import type { Metadata } from 'next';
55
+ import { notFound } from 'next/navigation';
56
+ import { CmsContent } from '@se-studio/core-ui';
57
+ import { contentfulPageRest, getContentfulConfig } from '@/lib/cms';
58
+ import { projectRendererConfig } from '@/lib/cms';
59
+
60
+ interface PageProps {
61
+ params: { slug: string };
62
+ searchParams: { [key: string]: string | string[] | undefined };
63
+ }
64
+
65
+ export default async function Page({ params, searchParams }: PageProps) {
66
+ const { slug } = params;
67
+ const isPreview = searchParams.preview === 'true';
68
+
69
+ // 1. Fetch content
70
+ const response = await contentfulPageRest(
71
+ getContentfulConfig(isPreview),
72
+ slug,
73
+ { preview: isPreview }
74
+ );
75
+
76
+ if (!response.data) {
77
+ notFound();
78
+ }
79
+
80
+ // 2. Render content with CmsContent
81
+ // This automatically handles the recursive rendering of components
82
+ return (
83
+ <main>
84
+ <CmsContent
85
+ content={response.data}
86
+ config={projectRendererConfig}
87
+ contentContext={{
88
+ // Pass any required context
89
+ analyticsContext: { ... }
90
+ }}
91
+ />
92
+ </main>
93
+ );
94
+ }
95
+ ```
96
+
97
+ ### Step 3: Add Metadata
98
+
99
+ Always export metadata for SEO:
100
+
101
+ ```typescript
102
+ export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
103
+ const response = await contentfulPageRest(/* ... */);
104
+ const page = response.data;
105
+
106
+ if (!page) return {};
107
+
108
+ return {
109
+ title: page.seoTitle || page.title,
110
+ description: page.seoDescription,
111
+ // ... maps to Next.js metadata format
112
+ };
113
+ }
114
+ ```
115
+
116
+ ## Custom Layouts
117
+
118
+ If your new route needs a different layout (e.g., no header/footer), create a `layout.tsx` in your route directory.
119
+
120
+ ```typescript
121
+ export default function CustomLayout({ children }: { children: React.ReactNode }) {
122
+ return (
123
+ <div className="custom-layout">
124
+ {children}
125
+ </div>
126
+ );
127
+ }
128
+ ```
129
+
130
+ ## Troubleshooting
131
+
132
+ * **404 on new route**: Ensure you've re-run the dev server or build if you added a new dynamic route segment.
133
+ * **Static params missing**: Check if your new content is published in Contentful and reachable via `getAllPageLinks` (or your custom fetcher).
134
+ * **Preview mode not working**: Ensure you are passing `preview: true` to the fetcher functions when `searchParams.preview` is set.
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: handling-media
3
+ description: Guide for using images, videos, and animations in marketing sites using the ResponsiveVisual and VisualComponent systems.
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Handling Media
11
+
12
+ This project uses a unified media system to handle images, videos, and animations efficiently.
13
+
14
+ ## Core Components
15
+
16
+ ### 1. `ResponsiveVisual` (or `VisualComponent`)
17
+
18
+ This is the main component for rendering media from Contentful. It handles:
19
+ * Responsive image sources (desktop/mobile).
20
+ * Format optimization (WebP/AVIF).
21
+ * Video auto-play/looping.
22
+ * Lottie animations.
23
+ * Lazy loading & Priority hints.
24
+
25
+ ```typescript
26
+ import VisualComponent from '@/framework/VisualComponent';
27
+ // or
28
+ import { Visual } from '@se-studio/core-ui';
29
+ ```
30
+
31
+ ## Usage Pattern
32
+
33
+ ### Basic Usage
34
+
35
+ ```typescript
36
+ <VisualComponent
37
+ visual={field.visual}
38
+ className="w-full h-auto"
39
+ />
40
+ ```
41
+
42
+ ### Responsive Sizing (`visualSizes`)
43
+
44
+ You **MUST** provide `visualSizes` to ensure the browser loads the correct image size. This uses the `sizes` attribute.
45
+
46
+ ```typescript
47
+ import { calculateVisualSizes } from '@se-studio/core-ui';
48
+
49
+ // Example: Full width on mobile, 50% width on laptop
50
+ const sizes = calculateVisualSizes(1, { laptop: 0.5 });
51
+
52
+ <VisualComponent
53
+ visual={visual}
54
+ visualSizes={sizes}
55
+ />
56
+ ```
57
+
58
+ * `1`: 100vw (Mobile default)
59
+ * `laptop: 0.5`: 50vw (Laptop breakpoint)
60
+
61
+ ### LCP Optimization (`calculateImagePriority`)
62
+
63
+ For the Hero component (or whatever is at the top of the page), you must prioritize the image load to improve LCP (Largest Contentful Paint).
64
+
65
+ Use `calculateImagePriority(index)` where `index` is the component's position on the page.
66
+
67
+ ```typescript
68
+ import { calculateImagePriority } from '@se-studio/core-ui';
69
+
70
+ <VisualComponent
71
+ visual={visual}
72
+ {...calculateImagePriority(index)}
73
+ />
74
+ ```
75
+
76
+ If `index` is `0`, this sets `priority={true}` (or `fetchPriority="high"`). If `index > 0`, it defaults to lazy loading.
77
+
78
+ ### Analytics Tracking
79
+
80
+ Pass `componentLabel` (usually `cmsLabel`) and `analyticsContext` to enable click tracking on media elements (if they are linked).
81
+
82
+ ```typescript
83
+ <VisualComponent
84
+ visual={visual}
85
+ componentLabel={cmsLabel}
86
+ analyticsContext={contentContext.analyticsContext}
87
+ />
88
+ ```
89
+
90
+ ## Media Types
91
+
92
+ The `IResponsiveVisual` type (from `@se-studio/core-data-types`) supports:
93
+
94
+ 1. **Image**: Standard Contentful image asset.
95
+ 2. **Video**: Hosted video file (mp4/webm). The component handles `<video>` tag rendering with autoplay/loop/muted attributes suitable for background videos.
96
+ 3. **Animation**: Lottie JSON file. Renders using a Lottie player.
97
+
98
+ The component automatically detects the type and renders the appropriate element.
99
+
100
+ ## Mobile Specific Visuals
101
+
102
+ Contentful models often support a separate `mobileVisual` field. The `VisualComponent` handles switching between them using `<picture>` tags or CSS media queries internally.
103
+
104
+ You typically pass the combined object or handle it via props if the component exposes both:
105
+
106
+ ```typescript
107
+ // If your component merges them into one responsive object before rendering:
108
+ <VisualComponent visual={combinedVisual} />
109
+ ```
110
+
111
+ Or if using raw fields:
112
+
113
+ ```typescript
114
+ <VisualComponent
115
+ visual={visual}
116
+ mobileVisual={mobileVisual}
117
+ />
118
+ ```
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: register-cms-features
3
+ description: Guide for registering new components, collections, and external integrations in the CMS configuration (src/lib/cms.ts).
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Registering CMS Features
11
+
12
+ The file `src/lib/cms.ts` is the central registry for the application. It connects Contentful content types to their React implementations.
13
+
14
+ ## How Registration Works
15
+
16
+ The system uses "Registration Objects" created via `defineComponent` or `defineCollection`. These objects contain:
17
+ 1. **Name**: Matches the Contentful content type ID (or a mapped name).
18
+ 2. **Renderer**: The React component to render.
19
+ 3. **Used Fields**: Which fields from the content model are used.
20
+ 4. **Mock Data**: Sample data for the styleguide/showcase.
21
+
22
+ ## Registering a New Component
23
+
24
+ 1. **Import the Registration**:
25
+ At the top of `src/lib/cms.ts`, import your component's registration export.
26
+
27
+ ```typescript
28
+ import { MyNewComponentRegistration } from '@/project/components/MyNewComponent';
29
+ ```
30
+
31
+ 2. **Add to `componentRegistrations`**:
32
+ Find the `componentRegistrations` array and add your component.
33
+
34
+ ```typescript
35
+ const componentRegistrations = [
36
+ HeroRegistration,
37
+ // ...
38
+ MyNewComponentRegistration, // Add this
39
+ ];
40
+ ```
41
+
42
+ *Order does not matter for functionality, but logical grouping is helpful.*
43
+
44
+ ## Registering a New Collection
45
+
46
+ 1. **Import the Registration**:
47
+
48
+ ```typescript
49
+ import { MyCollectionRegistration } from '@/project/collections/MyCollection';
50
+ ```
51
+
52
+ 2. **Add to `collectionRegistrations`**:
53
+
54
+ ```typescript
55
+ const collectionRegistrations = [
56
+ CardGridRegistration,
57
+ // ...
58
+ MyCollectionRegistration, // Add this
59
+ ];
60
+ ```
61
+
62
+ ## Adding External Components
63
+
64
+ External components (like 3rd party forms or iframes) use a separate registry.
65
+
66
+ 1. **Import**:
67
+ ```typescript
68
+ import { MyExternalWidgetRegistration } from '@/project/externalComponents/MyExternalWidget';
69
+ ```
70
+
71
+ 2. **Add to `externalComponentRegistrations`**:
72
+ ```typescript
73
+ const externalComponentRegistrations = [
74
+ ExternalIFrameRegistration,
75
+ MyExternalWidgetRegistration,
76
+ ];
77
+ ```
78
+
79
+ ## Extending Type Definitions
80
+
81
+ If you introduce new Color names, Button variants, or other enumerations, update the type definitions in `src/lib/cms.ts`:
82
+
83
+ ```typescript
84
+ export type CmsColourName = NonNullable<TypeComponentFields['backgroundColour']>['values'];
85
+ // Add or modify if types are not automatically generated from Contentful
86
+ ```
87
+
88
+ **Note**: Most types are generated automatically into `@/generated/types` by the `type-gen` script. You typically don't need to manually edit types unless you are defining project-specific overrides.
89
+
90
+ ## The Showcase
91
+
92
+ Registering a component automatically adds it to the CMS Showcase (usually available at `/cms-showcase` in development). This allows you to view the component in isolation using its mock data.
93
+
94
+ * Ensure your `mock` object in the registration is complete and realistic.
95
+ * The showcase helps verify that `usedFields` and `UnusedChecker` are working correctly.