@wix/auto-patterns 1.21.0 → 1.22.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.
Files changed (38) hide show
  1. package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +109 -0
  2. package/dist/cjs/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -0
  3. package/dist/cjs/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js +5 -14
  4. package/dist/cjs/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js.map +1 -1
  5. package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +19 -68
  6. package/dist/cjs/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js.map +1 -1
  7. package/dist/cjs/hooks/useActionCell.js +10 -2
  8. package/dist/cjs/hooks/useActionCell.js.map +1 -1
  9. package/dist/cjs/providers/PatternsWizardOverridesContext.js.map +1 -1
  10. package/dist/cjs/types/CollectionPageConfig.js.map +1 -1
  11. package/dist/cjs/types/actions/actionCell.js.map +1 -1
  12. package/dist/docs/action_cell.md +13 -3
  13. package/dist/docs/app_config_structure.md +7 -1
  14. package/dist/docs/auto-patterns-guide.md +201 -13
  15. package/dist/docs/custom_overrides.md +181 -9
  16. package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js +72 -0
  17. package/dist/esm/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.js.map +1 -0
  18. package/dist/esm/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js +1 -3
  19. package/dist/esm/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.js.map +1 -1
  20. package/dist/esm/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js +17 -48
  21. package/dist/esm/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.js.map +1 -1
  22. package/dist/esm/hooks/useActionCell.js +10 -2
  23. package/dist/esm/hooks/useActionCell.js.map +1 -1
  24. package/dist/esm/providers/PatternsWizardOverridesContext.js.map +1 -1
  25. package/dist/esm/types/CollectionPageConfig.js.map +1 -1
  26. package/dist/esm/types/actions/actionCell.js.map +1 -1
  27. package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts +7 -0
  28. package/dist/types/components/AutoPatternsCollectionComponent/AutoPatternsCollectionComponent.d.ts.map +1 -0
  29. package/dist/types/components/AutoPatternsCollectionPage/AutoPatternsCollectionPage.d.ts.map +1 -1
  30. package/dist/types/components/AutoPatternsCollectionPageContent/AutoPatternsCollectionPageContent.d.ts.map +1 -1
  31. package/dist/types/hooks/useActionCell.d.ts.map +1 -1
  32. package/dist/types/providers/PatternsWizardOverridesContext.d.ts +1 -1
  33. package/dist/types/providers/PatternsWizardOverridesContext.d.ts.map +1 -1
  34. package/dist/types/types/CollectionPageConfig.d.ts +7 -1
  35. package/dist/types/types/CollectionPageConfig.d.ts.map +1 -1
  36. package/dist/types/types/actions/actionCell.d.ts +1 -0
  37. package/dist/types/types/actions/actionCell.d.ts.map +1 -1
  38. package/package.json +7 -7
@@ -147,8 +147,9 @@ export interface AppConfig {
147
147
  menu?: {}; // Same structure as primaryActions.menu
148
148
  };
149
149
  };
150
- components: [
150
+ components: [ // Array of component configurations that can be collection components or custom slot components
151
151
  {
152
+ type: 'collection'; // Component type for collection rendering (table/grid with full features)
152
153
  entityPageId?: string; // ID of the entity page to navigate to when clicking a row
153
154
  collection: {
154
155
  collectionId: string; // ID of the Wix Data collection
@@ -249,6 +250,7 @@ export interface AppConfig {
249
250
  };
250
251
  };
251
252
  };
253
+ alwaysVisible?: boolean; // Whether to always show the primary action (not just on hover)
252
254
  };
253
255
  secondaryActions?: {
254
256
  items: {}[]; // Array of action configurations, same structure as primaryAction.item, can include dividers
@@ -366,6 +368,10 @@ export interface AppConfig {
366
368
  };
367
369
  }
368
370
  ]; // End of layout array
371
+ } |
372
+ {
373
+ type: 'custom'; // Component type for custom slot components
374
+ id: string; // Unique identifier that maps to a custom React component provided through PatternsWizardOverridesProvider slots
369
375
  }
370
376
  ]; // End of components array
371
377
  };
@@ -1356,6 +1362,10 @@ The ActionCell has a two-level structure:
1356
1362
 
1357
1363
  Both properties are optional, but at least one should be provided for the ActionCell to be useful.
1358
1364
 
1365
+ ### Primary Action Visibility Control
1366
+
1367
+ **New Feature**: Primary actions now support visibility control through the `alwaysVisible` property. By default, primary actions follow standard table interaction patterns (typically visible on hover), but you can configure them to be always visible for improved accessibility and user discovery.
1368
+
1359
1369
  ### Inline Secondary Actions
1360
1370
 
1361
1371
  **New Feature**: By default, all secondary actions are hidden in a popover menu that appears when the user hovers over or clicks the "more actions" button. However, you can now configure some secondary actions to display inline directly in the table row for improved accessibility and reduced clicks.
@@ -1560,17 +1570,21 @@ Follow this decision process when implementing ActionCell:
1560
1570
  - Most common operation (typically Edit) → Place in `primaryAction.item`
1561
1571
  - Less common operations → Place in `secondaryActions.items` array
1562
1572
 
1563
- 3. **Inline Secondary Actions Strategy**:
1573
+ 3. **Primary Action Visibility Strategy**:
1574
+ - **Standard Visibility** (`alwaysVisible: false` or omitted): Use for most cases where actions appear on interaction
1575
+ - **Always Visible** (`alwaysVisible: true`): Use for critical actions that need constant visibility or when user discovery is important
1576
+
1577
+ 4. **Inline Secondary Actions Strategy**:
1564
1578
  - **Action Prioritization**: Order `secondaryActions.items` by frequency of use (most used first)
1565
1579
  - **Inline Count**: Use `inlineCount: 1-3` for optimal UX (avoid cluttering)
1566
1580
  - **Visibility Control**:
1567
1581
  - Use `inlineAlwaysVisible: false` (default) for cleaner visual appearance
1568
1582
  - Use `inlineAlwaysVisible: true` only for critical actions requiring constant visibility
1569
1583
 
1570
- 4. **Update Action Mode**:
1584
+ 5. **Update Action Mode**:
1571
1585
  - Complex, full-entity edits → Use `mode: "page"` to navigate to entity page
1572
1586
 
1573
- 5. **Custom Implementation**:
1587
+ 6. **Custom Implementation**:
1574
1588
  - For `custom` actions, you must provide implementations in your code and register them with `PatternsWizardOverridesProvider`
1575
1589
 
1576
1590
  ### ActionCell Validation Checklist
@@ -1584,6 +1598,8 @@ AI agents should verify these requirements before generating ActionCell configur
1584
1598
  ✓ Delete action has a modal configuration
1585
1599
  ✓ Custom actions match implementations in overrides
1586
1600
  ✓ At least one of `primaryAction` or `secondaryActions` is provided
1601
+ ✓ `alwaysVisible` property on primary actions (if specified) is a boolean value
1602
+ ✓ Primary action visibility is properly considered for UX (use `alwaysVisible: true` for critical actions)
1587
1603
  ✓ `inlineCount` (if specified) is a non-negative number ≤ total secondary actions count
1588
1604
  ✓ `inlineAlwaysVisible` (if specified) is a boolean value
1589
1605
  ✓ Inline secondary actions configuration is applied only when secondary actions exist
@@ -2163,6 +2179,10 @@ your-page/
2163
2179
  │ ├── index.tsx // Exports useColumns hook
2164
2180
  │ ├── name.ts
2165
2181
  │ └── date.ts
2182
+ ├── slots/ // Custom slot components for collection pages
2183
+ │ ├── index.tsx // Exports useSlots hook
2184
+ │ ├── TopBannerComponent.tsx
2185
+ │ └── BottomStatsComponent.tsx
2166
2186
  ├── customComponents/ // Custom entity page components
2167
2187
  │ ├── index.tsx // Exports useComponents hook
2168
2188
  │ ├── CustomNameField.tsx
@@ -2170,16 +2190,12 @@ your-page/
2170
2190
  ├── modals/ // Custom modals
2171
2191
  │ ├── index.tsx // Exports useModals hook
2172
2192
  │ └── myCustomModal.tsx
2173
- └── customDataSources/ // Custom data sources
2193
+ ├── customDataSources/ // Custom data sources
2174
2194
  │ ├── index.tsx // Exports useCustomDataSources hook
2175
2195
  │ └── myCustomDataSource.ts
2176
- ├── sections/ // Section renderers
2177
- │ ├── index.tsx
2178
- │ └── groupByType.ts
2179
- └── customComponents/ // Custom entity page components
2196
+ └── sections/ // Section renderers
2180
2197
  ├── index.tsx
2181
- ├── CustomNameField.tsx
2182
- └── InfoCard.tsx
2198
+ └── groupByType.ts
2183
2199
  ```
2184
2200
 
2185
2201
  ### Using Override Hooks in Your Page
@@ -2189,6 +2205,7 @@ In your page component, use the hook-based approach to access React context and
2189
2205
  ```tsx
2190
2206
  import { useActions } from '../components/actions';
2191
2207
  import { useColumns } from '../components/columns';
2208
+ import { useSlots } from '../components/slots';
2192
2209
  import { useSections } from '../components/sections';
2193
2210
  import { useComponents } from '../components/customComponents';
2194
2211
  import { useModals } from '../components/modals';
@@ -2197,13 +2214,14 @@ import { useCustomDataSources } from '../components/customDataSources';
2197
2214
  export default function YourPage() {
2198
2215
  const actions = useActions();
2199
2216
  const columns = useColumns();
2217
+ const slots = useSlots();
2200
2218
  const sections = useSections();
2201
2219
  const components = useComponents();
2202
2220
  const modals = useModals();
2203
2221
  const customDataSources = useCustomDataSources();
2204
2222
 
2205
2223
  return (
2206
- <PatternsWizardOverridesProvider value={{ actions, columns, sections, components, modals, customDataSources }}>
2224
+ <PatternsWizardOverridesProvider value={{ actions, columns, slots, sections, components, modals, customDataSources }}>
2207
2225
  <AutoPatternsApp configuration={config} />
2208
2226
  </PatternsWizardOverridesProvider>
2209
2227
  );
@@ -2212,12 +2230,13 @@ export default function YourPage() {
2212
2230
 
2213
2231
  ### Important: Updating Hook Index Files
2214
2232
 
2215
- **When adding any new implementation (action, modal, column, section or component), you MUST update the corresponding hook in the `index.tsx` file to include your new implementation.** The main page component uses these hooks, so they serve as the central export point for each type of override.
2233
+ **When adding any new implementation (action, modal, column, slot, section or component), you MUST update the corresponding hook in the `index.tsx` file to include your new implementation.** The main page component uses these hooks, so they serve as the central export point for each type of override.
2216
2234
 
2217
2235
  For example:
2218
2236
  - Adding a new action → Update `../components/actions/index.tsx` to include the new action in the `useActions` hook
2219
2237
  - Adding a new modal → Update `../components/modals/index.tsx` to include the new modal in the `useModals` hook
2220
2238
  - Adding a new column override → Update `../components/columns/index.tsx` to include the new column in the `useColumns` hook
2239
+ - Adding a new slot component → Update `../components/slots/index.tsx` to include the new slot in the `useSlots` hook
2221
2240
  - Adding a new section renderer → Update `../components/sections/index.tsx` to include the new section in the `useSections` hook
2222
2241
  - Adding a new custom component → Update `../components/customComponents/index.tsx` to include the new component in the `useComponents` hook
2223
2242
  - Adding a new custom data source → Update `../components/customDataSources/index.tsx` to include the new data source in the `useCustomDataSources` hook
@@ -2947,6 +2966,10 @@ interface Section {
2947
2966
  prefixIcon?: React.ReactElement;
2948
2967
  onClick: () => void;
2949
2968
  };
2969
+ badge?: {
2970
+ visible: boolean;
2971
+ skin?: 'light' | 'danger' | 'neutralLight';
2972
+ };
2950
2973
  }
2951
2974
  ```
2952
2975
 
@@ -2954,6 +2977,7 @@ The section renderer receives an item and returns:
2954
2977
  - **id**: A unique identifier for the section (items with the same id are grouped together)
2955
2978
  - **title**: The text displayed in the section header
2956
2979
  - **primaryAction** (optional): An action button displayed in the section header
2980
+ - **badge** (optional): A badge configuration displayed in the section header
2957
2981
 
2958
2982
  #### Example: Section Renderer Implementation
2959
2983
 
@@ -2979,6 +3003,10 @@ export function groupByType(item: any): Section {
2979
3003
  console.log(`Showing all ${petType}s`);
2980
3004
  },
2981
3005
  },
3006
+ badge: {
3007
+ visible: true,
3008
+ skin: 'light',
3009
+ },
2982
3010
  };
2983
3011
  }
2984
3012
  ```
@@ -3001,16 +3029,20 @@ export function groupByAgeAndVaccination(item: any): Section {
3001
3029
 
3002
3030
  let sectionId: string;
3003
3031
  let sectionTitle: string;
3032
+ let badgeSkin: 'light' | 'danger' | 'neutralLight' = 'light';
3004
3033
 
3005
3034
  if (age < 1) {
3006
3035
  sectionId = 'puppies';
3007
3036
  sectionTitle = 'Puppies (Under 1 year)';
3037
+ badgeSkin = 'neutralLight';
3008
3038
  } else if (age >= 1 && age <= 5) {
3009
3039
  sectionId = isVaccinated ? 'young-vaccinated' : 'young-unvaccinated';
3010
3040
  sectionTitle = `Young Adults (1-5 years) - ${isVaccinated ? 'Vaccinated' : 'Not Vaccinated'}`;
3041
+ badgeSkin = isVaccinated ? 'light' : 'danger';
3011
3042
  } else {
3012
3043
  sectionId = 'seniors';
3013
3044
  sectionTitle = 'Senior Pets (5+ years)';
3045
+ badgeSkin = 'light';
3014
3046
  }
3015
3047
 
3016
3048
  return {
@@ -3023,6 +3055,10 @@ export function groupByAgeAndVaccination(item: any): Section {
3023
3055
  // Show special care information for puppies
3024
3056
  },
3025
3057
  } : undefined,
3058
+ badge: {
3059
+ visible: true,
3060
+ skin: badgeSkin,
3061
+ },
3026
3062
  };
3027
3063
  }
3028
3064
  ```
@@ -3051,4 +3087,156 @@ import * as actions from './components/actions';
3051
3087
 
3052
3088
  By implementing sections, you can significantly improve the user experience when dealing with large datasets by providing logical groupings that make information easier to find and understand.
3053
3089
 
3090
+ ## Slots
3091
+
3092
+ Slots allow you to inject custom React components into collection pages at specific points in the component hierarchy. Unlike other overrides that modify existing functionality, slots enable you to add entirely custom UI elements anywhere within the collection page components array.
3093
+
3094
+ Slots are useful for:
3095
+ - Adding custom banners or announcements above or below the table/grid
3096
+ - Inserting analytics widgets or dashboards
3097
+ - Adding custom promotional content
3098
+ - Implementing page-specific functionality that doesn't fit into standard patterns
3099
+
3100
+ ### Configuration Structure
3101
+
3102
+ Slots are configured in the collection page configuration using the `CustomComponentConfig` structure:
3103
+
3104
+ ```json
3105
+ {
3106
+ "type": "custom",
3107
+ "id": "myCustomSlot"
3108
+ }
3109
+ ```
3110
+
3111
+ **Key Properties:**
3112
+ - `type`: Must be set to `"custom"` to identify this as a slot component
3113
+ - `id`: A unique identifier that maps to your slot component implementation
3114
+
3115
+ ### Component Positioning
3116
+
3117
+ Slot components can be positioned anywhere within the `components` array of a collection page. They will be rendered in the exact order specified in the configuration:
3118
+
3119
+ ```json
3120
+ {
3121
+ "type": "collectionPage",
3122
+ "collectionPage": {
3123
+ "components": [
3124
+ {
3125
+ "type": "custom",
3126
+ "id": "topBanner"
3127
+ },
3128
+ {
3129
+ "type": "collection",
3130
+ "collection": {
3131
+ "collectionId": "MyCollection"
3132
+ },
3133
+ "layout": [...]
3134
+ },
3135
+ {
3136
+ "type": "custom",
3137
+ "id": "bottomStats"
3138
+ }
3139
+ ]
3140
+ }
3141
+ }
3142
+ ```
3143
+
3144
+ This configuration will render:
3145
+ 1. The custom `topBanner` component at the top
3146
+ 2. The main collection component (table/grid) in the middle
3147
+ 3. The custom `bottomStats` component at the bottom
3148
+
3149
+ ### Implementation Structure
3150
+
3151
+ #### Creating Slot Components
3152
+
3153
+ Slot components are standard React functional components that take no props:
3154
+
3155
+ ```tsx
3156
+ import React from 'react';
3157
+ import { Box, Card, Text, Button } from '@wix/design-system';
3158
+
3159
+ export const TopBannerComponent: React.FC = () => {
3160
+ return (
3161
+ <Card>
3162
+ <Card.Content>
3163
+ <Box direction="vertical" gap={2}>
3164
+ <Text size="large" weight="bold">Welcome to Pet Management</Text>
3165
+ <Text>Manage all your pets from this central dashboard.</Text>
3166
+ <Button size="small">Get Started</Button>
3167
+ </Box>
3168
+ </Card.Content>
3169
+ </Card>
3170
+ );
3171
+ };
3172
+
3173
+ export const BottomStatsComponent: React.FC = () => {
3174
+ return (
3175
+ <Card>
3176
+ <Card.Content>
3177
+ <Box direction="horizontal" gap={4}>
3178
+ <Box direction="vertical" gap={1}>
3179
+ <Text size="large" weight="bold">47</Text>
3180
+ <Text size="small">Total Pets</Text>
3181
+ </Box>
3182
+ <Box direction="vertical" gap={1}>
3183
+ <Text size="large" weight="bold">12</Text>
3184
+ <Text size="small">Available for Adoption</Text>
3185
+ </Box>
3186
+ </Box>
3187
+ </Card.Content>
3188
+ </Card>
3189
+ );
3190
+ };
3191
+ ```
3192
+
3193
+ #### Creating the Slots Hook
3194
+
3195
+ In `components/slots/index.tsx`:
3196
+
3197
+ ```tsx
3198
+ import { TopBannerComponent } from './TopBannerComponent';
3199
+ import { BottomStatsComponent } from './BottomStatsComponent';
3200
+
3201
+ export const useSlots = () => {
3202
+ // You can access React context and other hooks here
3203
+ return {
3204
+ topBanner: TopBannerComponent,
3205
+ bottomStats: BottomStatsComponent
3206
+ };
3207
+ };
3208
+ ```
3209
+
3210
+ **Important:** Every time you create a new slot component, you must import it and add it to the `useSlots` hook return object. The key in the return object must match the `id` specified in your JSON configuration.
3211
+
3212
+ #### Registering Slots in Your Page
3213
+
3214
+ In your main page component:
3215
+
3216
+ ```tsx
3217
+ import { useSlots } from '../components/slots';
3218
+
3219
+ export default function YourPage() {
3220
+ const slots = useSlots();
3221
+
3222
+ return (
3223
+ <PatternsWizardOverridesProvider value={{ slots }}>
3224
+ <AutoPatternsApp configuration={config} />
3225
+ </PatternsWizardOverridesProvider>
3226
+ );
3227
+ }
3228
+ ```
3229
+
3230
+ ### Important Guidelines for Slots
3231
+
3232
+ 1. **Component Signature**: Slot components must be React functional components with no props: `React.FC`
3233
+ 2. **Rendering Order**: Components render in the exact order specified in the `components` array
3234
+ 3. **Performance**: Slot components re-render with the page, so optimize for performance if needed
3235
+ 4. **Styling**: Follow the design system patterns and responsive design principles
3236
+
3237
+
3238
+ **Important:** Every time you create a new slot component, you must import it and add it to the `useSlots` hook return object in the `./components/slots/index.tsx` file. The key must match the `id` specified in your JSON configuration.
3239
+
3240
+ Slots provide a powerful way to enhance collection pages with custom functionality while maintaining the structure and features of the AutoPatterns system.
3241
+
3054
3242
  ---
@@ -28,6 +28,10 @@ your-page/
28
28
  │ ├── index.tsx // Exports useColumns hook
29
29
  │ ├── name.ts
30
30
  │ └── date.ts
31
+ ├── slots/ // Custom slot components for collection pages
32
+ │ ├── index.tsx // Exports useSlots hook
33
+ │ ├── TopBannerComponent.tsx
34
+ │ └── BottomStatsComponent.tsx
31
35
  ├── customComponents/ // Custom entity page components
32
36
  │ ├── index.tsx // Exports useComponents hook
33
37
  │ ├── CustomNameField.tsx
@@ -35,16 +39,12 @@ your-page/
35
39
  ├── modals/ // Custom modals
36
40
  │ ├── index.tsx // Exports useModals hook
37
41
  │ └── myCustomModal.tsx
38
- └── customDataSources/ // Custom data sources
42
+ ├── customDataSources/ // Custom data sources
39
43
  │ ├── index.tsx // Exports useCustomDataSources hook
40
44
  │ └── myCustomDataSource.ts
41
- ├── sections/ // Section renderers
42
- │ ├── index.tsx
43
- │ └── groupByType.ts
44
- └── customComponents/ // Custom entity page components
45
+ └── sections/ // Section renderers
45
46
  ├── index.tsx
46
- ├── CustomNameField.tsx
47
- └── InfoCard.tsx
47
+ └── groupByType.ts
48
48
  ```
49
49
 
50
50
  ### Using Override Hooks in Your Page
@@ -54,6 +54,7 @@ In your page component, use the hook-based approach to access React context and
54
54
  ```tsx
55
55
  import { useActions } from '../components/actions';
56
56
  import { useColumns } from '../components/columns';
57
+ import { useSlots } from '../components/slots';
57
58
  import { useSections } from '../components/sections';
58
59
  import { useComponents } from '../components/customComponents';
59
60
  import { useModals } from '../components/modals';
@@ -62,13 +63,14 @@ import { useCustomDataSources } from '../components/customDataSources';
62
63
  export default function YourPage() {
63
64
  const actions = useActions();
64
65
  const columns = useColumns();
66
+ const slots = useSlots();
65
67
  const sections = useSections();
66
68
  const components = useComponents();
67
69
  const modals = useModals();
68
70
  const customDataSources = useCustomDataSources();
69
71
 
70
72
  return (
71
- <PatternsWizardOverridesProvider value={{ actions, columns, sections, components, modals, customDataSources }}>
73
+ <PatternsWizardOverridesProvider value={{ actions, columns, slots, sections, components, modals, customDataSources }}>
72
74
  <AutoPatternsApp configuration={config} />
73
75
  </PatternsWizardOverridesProvider>
74
76
  );
@@ -77,12 +79,13 @@ export default function YourPage() {
77
79
 
78
80
  ### Important: Updating Hook Index Files
79
81
 
80
- **When adding any new implementation (action, modal, column, section or component), you MUST update the corresponding hook in the `index.tsx` file to include your new implementation.** The main page component uses these hooks, so they serve as the central export point for each type of override.
82
+ **When adding any new implementation (action, modal, column, slot, section or component), you MUST update the corresponding hook in the `index.tsx` file to include your new implementation.** The main page component uses these hooks, so they serve as the central export point for each type of override.
81
83
 
82
84
  For example:
83
85
  - Adding a new action → Update `../components/actions/index.tsx` to include the new action in the `useActions` hook
84
86
  - Adding a new modal → Update `../components/modals/index.tsx` to include the new modal in the `useModals` hook
85
87
  - Adding a new column override → Update `../components/columns/index.tsx` to include the new column in the `useColumns` hook
88
+ - Adding a new slot component → Update `../components/slots/index.tsx` to include the new slot in the `useSlots` hook
86
89
  - Adding a new section renderer → Update `../components/sections/index.tsx` to include the new section in the `useSections` hook
87
90
  - Adding a new custom component → Update `../components/customComponents/index.tsx` to include the new component in the `useComponents` hook
88
91
  - Adding a new custom data source → Update `../components/customDataSources/index.tsx` to include the new data source in the `useCustomDataSources` hook
@@ -812,6 +815,10 @@ interface Section {
812
815
  prefixIcon?: React.ReactElement;
813
816
  onClick: () => void;
814
817
  };
818
+ badge?: {
819
+ visible: boolean;
820
+ skin?: 'light' | 'danger' | 'neutralLight';
821
+ };
815
822
  }
816
823
  ```
817
824
 
@@ -819,6 +826,7 @@ The section renderer receives an item and returns:
819
826
  - **id**: A unique identifier for the section (items with the same id are grouped together)
820
827
  - **title**: The text displayed in the section header
821
828
  - **primaryAction** (optional): An action button displayed in the section header
829
+ - **badge** (optional): A badge configuration displayed in the section header
822
830
 
823
831
  #### Example: Section Renderer Implementation
824
832
 
@@ -844,6 +852,10 @@ export function groupByType(item: any): Section {
844
852
  console.log(`Showing all ${petType}s`);
845
853
  },
846
854
  },
855
+ badge: {
856
+ visible: true,
857
+ skin: 'light',
858
+ },
847
859
  };
848
860
  }
849
861
  ```
@@ -866,16 +878,20 @@ export function groupByAgeAndVaccination(item: any): Section {
866
878
 
867
879
  let sectionId: string;
868
880
  let sectionTitle: string;
881
+ let badgeSkin: 'light' | 'danger' | 'neutralLight' = 'light';
869
882
 
870
883
  if (age < 1) {
871
884
  sectionId = 'puppies';
872
885
  sectionTitle = 'Puppies (Under 1 year)';
886
+ badgeSkin = 'neutralLight';
873
887
  } else if (age >= 1 && age <= 5) {
874
888
  sectionId = isVaccinated ? 'young-vaccinated' : 'young-unvaccinated';
875
889
  sectionTitle = `Young Adults (1-5 years) - ${isVaccinated ? 'Vaccinated' : 'Not Vaccinated'}`;
890
+ badgeSkin = isVaccinated ? 'light' : 'danger';
876
891
  } else {
877
892
  sectionId = 'seniors';
878
893
  sectionTitle = 'Senior Pets (5+ years)';
894
+ badgeSkin = 'light';
879
895
  }
880
896
 
881
897
  return {
@@ -888,6 +904,10 @@ export function groupByAgeAndVaccination(item: any): Section {
888
904
  // Show special care information for puppies
889
905
  },
890
906
  } : undefined,
907
+ badge: {
908
+ visible: true,
909
+ skin: badgeSkin,
910
+ },
891
911
  };
892
912
  }
893
913
  ```
@@ -915,3 +935,155 @@ import * as actions from './components/actions';
915
935
 
916
936
 
917
937
  By implementing sections, you can significantly improve the user experience when dealing with large datasets by providing logical groupings that make information easier to find and understand.
938
+
939
+ ## Slots
940
+
941
+ Slots allow you to inject custom React components into collection pages at specific points in the component hierarchy. Unlike other overrides that modify existing functionality, slots enable you to add entirely custom UI elements anywhere within the collection page components array.
942
+
943
+ Slots are useful for:
944
+ - Adding custom banners or announcements above or below the table/grid
945
+ - Inserting analytics widgets or dashboards
946
+ - Adding custom promotional content
947
+ - Implementing page-specific functionality that doesn't fit into standard patterns
948
+
949
+ ### Configuration Structure
950
+
951
+ Slots are configured in the collection page configuration using the `CustomComponentConfig` structure:
952
+
953
+ ```json
954
+ {
955
+ "type": "custom",
956
+ "id": "myCustomSlot"
957
+ }
958
+ ```
959
+
960
+ **Key Properties:**
961
+ - `type`: Must be set to `"custom"` to identify this as a slot component
962
+ - `id`: A unique identifier that maps to your slot component implementation
963
+
964
+ ### Component Positioning
965
+
966
+ Slot components can be positioned anywhere within the `components` array of a collection page. They will be rendered in the exact order specified in the configuration:
967
+
968
+ ```json
969
+ {
970
+ "type": "collectionPage",
971
+ "collectionPage": {
972
+ "components": [
973
+ {
974
+ "type": "custom",
975
+ "id": "topBanner"
976
+ },
977
+ {
978
+ "type": "collection",
979
+ "collection": {
980
+ "collectionId": "MyCollection"
981
+ },
982
+ "layout": [...]
983
+ },
984
+ {
985
+ "type": "custom",
986
+ "id": "bottomStats"
987
+ }
988
+ ]
989
+ }
990
+ }
991
+ ```
992
+
993
+ This configuration will render:
994
+ 1. The custom `topBanner` component at the top
995
+ 2. The main collection component (table/grid) in the middle
996
+ 3. The custom `bottomStats` component at the bottom
997
+
998
+ ### Implementation Structure
999
+
1000
+ #### Creating Slot Components
1001
+
1002
+ Slot components are standard React functional components that take no props:
1003
+
1004
+ ```tsx
1005
+ import React from 'react';
1006
+ import { Box, Card, Text, Button } from '@wix/design-system';
1007
+
1008
+ export const TopBannerComponent: React.FC = () => {
1009
+ return (
1010
+ <Card>
1011
+ <Card.Content>
1012
+ <Box direction="vertical" gap={2}>
1013
+ <Text size="large" weight="bold">Welcome to Pet Management</Text>
1014
+ <Text>Manage all your pets from this central dashboard.</Text>
1015
+ <Button size="small">Get Started</Button>
1016
+ </Box>
1017
+ </Card.Content>
1018
+ </Card>
1019
+ );
1020
+ };
1021
+
1022
+ export const BottomStatsComponent: React.FC = () => {
1023
+ return (
1024
+ <Card>
1025
+ <Card.Content>
1026
+ <Box direction="horizontal" gap={4}>
1027
+ <Box direction="vertical" gap={1}>
1028
+ <Text size="large" weight="bold">47</Text>
1029
+ <Text size="small">Total Pets</Text>
1030
+ </Box>
1031
+ <Box direction="vertical" gap={1}>
1032
+ <Text size="large" weight="bold">12</Text>
1033
+ <Text size="small">Available for Adoption</Text>
1034
+ </Box>
1035
+ </Box>
1036
+ </Card.Content>
1037
+ </Card>
1038
+ );
1039
+ };
1040
+ ```
1041
+
1042
+ #### Creating the Slots Hook
1043
+
1044
+ In `components/slots/index.tsx`:
1045
+
1046
+ ```tsx
1047
+ import { TopBannerComponent } from './TopBannerComponent';
1048
+ import { BottomStatsComponent } from './BottomStatsComponent';
1049
+
1050
+ export const useSlots = () => {
1051
+ // You can access React context and other hooks here
1052
+ return {
1053
+ topBanner: TopBannerComponent,
1054
+ bottomStats: BottomStatsComponent
1055
+ };
1056
+ };
1057
+ ```
1058
+
1059
+ **Important:** Every time you create a new slot component, you must import it and add it to the `useSlots` hook return object. The key in the return object must match the `id` specified in your JSON configuration.
1060
+
1061
+ #### Registering Slots in Your Page
1062
+
1063
+ In your main page component:
1064
+
1065
+ ```tsx
1066
+ import { useSlots } from '../components/slots';
1067
+
1068
+ export default function YourPage() {
1069
+ const slots = useSlots();
1070
+
1071
+ return (
1072
+ <PatternsWizardOverridesProvider value={{ slots }}>
1073
+ <AutoPatternsApp configuration={config} />
1074
+ </PatternsWizardOverridesProvider>
1075
+ );
1076
+ }
1077
+ ```
1078
+
1079
+ ### Important Guidelines for Slots
1080
+
1081
+ 1. **Component Signature**: Slot components must be React functional components with no props: `React.FC`
1082
+ 2. **Rendering Order**: Components render in the exact order specified in the `components` array
1083
+ 3. **Performance**: Slot components re-render with the page, so optimize for performance if needed
1084
+ 4. **Styling**: Follow the design system patterns and responsive design principles
1085
+
1086
+
1087
+ **Important:** Every time you create a new slot component, you must import it and add it to the `useSlots` hook return object in the `./components/slots/index.tsx` file. The key must match the `id` specified in your JSON configuration.
1088
+
1089
+ Slots provide a powerful way to enhance collection pages with custom functionality while maintaining the structure and features of the AutoPatterns system.