@gallop.software/canon 2.1.0 → 2.2.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.
@@ -9,6 +9,7 @@ declare const recommendedConfig: {
9
9
  'gallop/no-container-in-section': string;
10
10
  'gallop/prefer-component-props': string;
11
11
  'gallop/prefer-layout-components': string;
12
+ 'gallop/background-image-rounded': string;
12
13
  };
13
14
  };
14
15
  export default recommendedConfig;
@@ -10,7 +10,8 @@ const recommendedConfig = {
10
10
  'gallop/no-container-in-section': 'warn',
11
11
  'gallop/prefer-component-props': 'warn',
12
12
  'gallop/prefer-layout-components': 'warn',
13
+ 'gallop/background-image-rounded': 'warn',
13
14
  },
14
15
  };
15
16
  export default recommendedConfig;
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50L2NvbmZpZ3MvcmVjb21tZW5kZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7SUFDbkIsS0FBSyxFQUFFO1FBQ0wsMENBQTBDO1FBQzFDLHlCQUF5QixFQUFFLE1BQU07UUFDakMsZ0NBQWdDLEVBQUUsTUFBTTtRQUN4QywrQkFBK0IsRUFBRSxNQUFNO1FBQ3ZDLGlDQUFpQyxFQUFFLE1BQU07S0FDMUM7Q0FDRixDQUFBO0FBRUQsZUFBZSxpQkFBaUIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVjb21tZW5kZWQgY29uZmlndXJhdGlvblxuICogQSBzZW5zaWJsZSBkZWZhdWx0IGZvciBhbnkgR2FsbG9wLWJhc2VkIHRlbXBsYXRlXG4gKi9cbmNvbnN0IHJlY29tbWVuZGVkQ29uZmlnID0ge1xuICBwbHVnaW5zOiBbJ2dhbGxvcCddLFxuICBydWxlczoge1xuICAgIC8vIENvcmUgcnVsZXMgdGhhdCBhcHBseSB0byBtb3N0IHRlbXBsYXRlc1xuICAgICdnYWxsb3Avbm8tY2xpZW50LWJsb2Nrcyc6ICd3YXJuJyxcbiAgICAnZ2FsbG9wL25vLWNvbnRhaW5lci1pbi1zZWN0aW9uJzogJ3dhcm4nLFxuICAgICdnYWxsb3AvcHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6ICd3YXJuJyxcbiAgICAnZ2FsbG9wL3ByZWZlci1sYXlvdXQtY29tcG9uZW50cyc6ICd3YXJuJyxcbiAgfSxcbn1cblxuZXhwb3J0IGRlZmF1bHQgcmVjb21tZW5kZWRDb25maWdcbiJdfQ==
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50L2NvbmZpZ3MvcmVjb21tZW5kZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7SUFDbkIsS0FBSyxFQUFFO1FBQ0wsMENBQTBDO1FBQzFDLHlCQUF5QixFQUFFLE1BQU07UUFDakMsZ0NBQWdDLEVBQUUsTUFBTTtRQUN4QywrQkFBK0IsRUFBRSxNQUFNO1FBQ3ZDLGlDQUFpQyxFQUFFLE1BQU07UUFDekMsaUNBQWlDLEVBQUUsTUFBTTtLQUMxQztDQUNGLENBQUE7QUFFRCxlQUFlLGlCQUFpQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZWNvbW1lbmRlZCBjb25maWd1cmF0aW9uXG4gKiBBIHNlbnNpYmxlIGRlZmF1bHQgZm9yIGFueSBHYWxsb3AtYmFzZWQgdGVtcGxhdGVcbiAqL1xuY29uc3QgcmVjb21tZW5kZWRDb25maWcgPSB7XG4gIHBsdWdpbnM6IFsnZ2FsbG9wJ10sXG4gIHJ1bGVzOiB7XG4gICAgLy8gQ29yZSBydWxlcyB0aGF0IGFwcGx5IHRvIG1vc3QgdGVtcGxhdGVzXG4gICAgJ2dhbGxvcC9uby1jbGllbnQtYmxvY2tzJzogJ3dhcm4nLFxuICAgICdnYWxsb3Avbm8tY29udGFpbmVyLWluLXNlY3Rpb24nOiAnd2FybicsXG4gICAgJ2dhbGxvcC9wcmVmZXItY29tcG9uZW50LXByb3BzJzogJ3dhcm4nLFxuICAgICdnYWxsb3AvcHJlZmVyLWxheW91dC1jb21wb25lbnRzJzogJ3dhcm4nLFxuICAgICdnYWxsb3AvYmFja2dyb3VuZC1pbWFnZS1yb3VuZGVkJzogJ3dhcm4nLFxuICB9LFxufVxuXG5leHBvcnQgZGVmYXVsdCByZWNvbW1lbmRlZENvbmZpZ1xuIl19
@@ -9,6 +9,7 @@ declare const speedwellConfig: {
9
9
  'gallop/no-container-in-section': string;
10
10
  'gallop/prefer-component-props': string;
11
11
  'gallop/prefer-layout-components': string;
12
+ 'gallop/background-image-rounded': string;
12
13
  };
13
14
  };
14
15
  export default speedwellConfig;
@@ -13,7 +13,9 @@ const speedwellConfig = {
13
13
  'gallop/prefer-component-props': 'warn',
14
14
  // Use Grid/Columns instead of raw div with grid classes
15
15
  'gallop/prefer-layout-components': 'warn',
16
+ // Background images must have rounded="rounded-none"
17
+ 'gallop/background-image-rounded': 'warn',
16
18
  },
17
19
  };
18
20
  export default speedwellConfig;
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWR3ZWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9jb25maWdzL3NwZWVkd2VsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLGVBQWUsR0FBRztJQUN0QixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7SUFDbkIsS0FBSyxFQUFFO1FBQ0wsMEVBQTBFO1FBQzFFLHlCQUF5QixFQUFFLE1BQU07UUFFakMsdUNBQXVDO1FBQ3ZDLGdDQUFnQyxFQUFFLE1BQU07UUFFeEMsNERBQTREO1FBQzVELCtCQUErQixFQUFFLE1BQU07UUFFdkMsd0RBQXdEO1FBQ3hELGlDQUFpQyxFQUFFLE1BQU07S0FDMUM7Q0FDRixDQUFBO0FBRUQsZUFBZSxlQUFlLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWVkd2VsbCB0ZW1wbGF0ZSBjb25maWd1cmF0aW9uXG4gKiBFbmFibGVzIGFsbCBHYWxsb3AgcnVsZXMgcmVsZXZhbnQgdG8gdGhlIFNwZWVkd2VsbCBhcmNoaXRlY3R1cmVcbiAqL1xuY29uc3Qgc3BlZWR3ZWxsQ29uZmlnID0ge1xuICBwbHVnaW5zOiBbJ2dhbGxvcCddLFxuICBydWxlczoge1xuICAgIC8vIEJsb2NrcyBzaG91bGQgYmUgc2VydmVyIGNvbXBvbmVudHMgLSBleHRyYWN0IGNsaWVudCBsb2dpYyB0byBjb21wb25lbnRzXG4gICAgJ2dhbGxvcC9uby1jbGllbnQtYmxvY2tzJzogJ3dhcm4nLFxuXG4gICAgLy8gU2VjdGlvbiBhbHJlYWR5IHByb3ZpZGVzIGNvbnRhaW5tZW50XG4gICAgJ2dhbGxvcC9uby1jb250YWluZXItaW4tc2VjdGlvbic6ICd3YXJuJyxcblxuICAgIC8vIFVzZSBjb21wb25lbnQgcHJvcHMgaW5zdGVhZCBvZiBjbGFzc05hbWUgZm9yIHN0eWxlIHZhbHVlc1xuICAgICdnYWxsb3AvcHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6ICd3YXJuJyxcblxuICAgIC8vIFVzZSBHcmlkL0NvbHVtbnMgaW5zdGVhZCBvZiByYXcgZGl2IHdpdGggZ3JpZCBjbGFzc2VzXG4gICAgJ2dhbGxvcC9wcmVmZXItbGF5b3V0LWNvbXBvbmVudHMnOiAnd2FybicsXG4gIH0sXG59XG5cbmV4cG9ydCBkZWZhdWx0IHNwZWVkd2VsbENvbmZpZ1xuIl19
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWR3ZWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9jb25maWdzL3NwZWVkd2VsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLGVBQWUsR0FBRztJQUN0QixPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7SUFDbkIsS0FBSyxFQUFFO1FBQ0wsMEVBQTBFO1FBQzFFLHlCQUF5QixFQUFFLE1BQU07UUFFakMsdUNBQXVDO1FBQ3ZDLGdDQUFnQyxFQUFFLE1BQU07UUFFeEMsNERBQTREO1FBQzVELCtCQUErQixFQUFFLE1BQU07UUFFdkMsd0RBQXdEO1FBQ3hELGlDQUFpQyxFQUFFLE1BQU07UUFFekMscURBQXFEO1FBQ3JELGlDQUFpQyxFQUFFLE1BQU07S0FDMUM7Q0FDRixDQUFBO0FBRUQsZUFBZSxlQUFlLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWVkd2VsbCB0ZW1wbGF0ZSBjb25maWd1cmF0aW9uXG4gKiBFbmFibGVzIGFsbCBHYWxsb3AgcnVsZXMgcmVsZXZhbnQgdG8gdGhlIFNwZWVkd2VsbCBhcmNoaXRlY3R1cmVcbiAqL1xuY29uc3Qgc3BlZWR3ZWxsQ29uZmlnID0ge1xuICBwbHVnaW5zOiBbJ2dhbGxvcCddLFxuICBydWxlczoge1xuICAgIC8vIEJsb2NrcyBzaG91bGQgYmUgc2VydmVyIGNvbXBvbmVudHMgLSBleHRyYWN0IGNsaWVudCBsb2dpYyB0byBjb21wb25lbnRzXG4gICAgJ2dhbGxvcC9uby1jbGllbnQtYmxvY2tzJzogJ3dhcm4nLFxuXG4gICAgLy8gU2VjdGlvbiBhbHJlYWR5IHByb3ZpZGVzIGNvbnRhaW5tZW50XG4gICAgJ2dhbGxvcC9uby1jb250YWluZXItaW4tc2VjdGlvbic6ICd3YXJuJyxcblxuICAgIC8vIFVzZSBjb21wb25lbnQgcHJvcHMgaW5zdGVhZCBvZiBjbGFzc05hbWUgZm9yIHN0eWxlIHZhbHVlc1xuICAgICdnYWxsb3AvcHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6ICd3YXJuJyxcblxuICAgIC8vIFVzZSBHcmlkL0NvbHVtbnMgaW5zdGVhZCBvZiByYXcgZGl2IHdpdGggZ3JpZCBjbGFzc2VzXG4gICAgJ2dhbGxvcC9wcmVmZXItbGF5b3V0LWNvbXBvbmVudHMnOiAnd2FybicsXG5cbiAgICAvLyBCYWNrZ3JvdW5kIGltYWdlcyBtdXN0IGhhdmUgcm91bmRlZD1cInJvdW5kZWQtbm9uZVwiXG4gICAgJ2dhbGxvcC9iYWNrZ3JvdW5kLWltYWdlLXJvdW5kZWQnOiAnd2FybicsXG4gIH0sXG59XG5cbmV4cG9ydCBkZWZhdWx0IHNwZWVkd2VsbENvbmZpZ1xuIl19
@@ -15,6 +15,7 @@ declare const plugin: {
15
15
  };
16
16
  'prefer-typography-components': import("eslint").Rule.RuleModule;
17
17
  'prefer-layout-components': import("eslint").Rule.RuleModule;
18
+ 'background-image-rounded': import("eslint").Rule.RuleModule;
18
19
  };
19
20
  configs: {
20
21
  speedwell: {
@@ -24,6 +25,7 @@ declare const plugin: {
24
25
  'gallop/no-container-in-section': string;
25
26
  'gallop/prefer-component-props': string;
26
27
  'gallop/prefer-layout-components': string;
28
+ 'gallop/background-image-rounded': string;
27
29
  };
28
30
  };
29
31
  recommended: {
@@ -33,6 +35,7 @@ declare const plugin: {
33
35
  'gallop/no-container-in-section': string;
34
36
  'gallop/prefer-component-props': string;
35
37
  'gallop/prefer-layout-components': string;
38
+ 'gallop/background-image-rounded': string;
36
39
  };
37
40
  };
38
41
  };
@@ -3,6 +3,7 @@ import noContainerInSection from './rules/no-container-in-section.js';
3
3
  import preferComponentProps from './rules/prefer-component-props.js';
4
4
  import preferTypographyComponents from './rules/prefer-typography-components.js';
5
5
  import preferLayoutComponents from './rules/prefer-layout-components.js';
6
+ import backgroundImageRounded from './rules/background-image-rounded.js';
6
7
  import speedwellConfig from './configs/speedwell.js';
7
8
  import recommendedConfig from './configs/recommended.js';
8
9
  const plugin = {
@@ -16,6 +17,7 @@ const plugin = {
16
17
  'prefer-component-props': preferComponentProps,
17
18
  'prefer-typography-components': preferTypographyComponents,
18
19
  'prefer-layout-components': preferLayoutComponents,
20
+ 'background-image-rounded': backgroundImageRounded,
19
21
  },
20
22
  configs: {
21
23
  speedwell: speedwellConfig,
@@ -23,4 +25,4 @@ const plugin = {
23
25
  },
24
26
  };
25
27
  export default plugin;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXNsaW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sY0FBYyxNQUFNLDZCQUE2QixDQUFBO0FBQ3hELE9BQU8sb0JBQW9CLE1BQU0sb0NBQW9DLENBQUE7QUFDckUsT0FBTyxvQkFBb0IsTUFBTSxtQ0FBbUMsQ0FBQTtBQUNwRSxPQUFPLDBCQUEwQixNQUFNLHlDQUF5QyxDQUFBO0FBQ2hGLE9BQU8sc0JBQXNCLE1BQU0scUNBQXFDLENBQUE7QUFDeEUsT0FBTyxlQUFlLE1BQU0sd0JBQXdCLENBQUE7QUFDcEQsT0FBTyxpQkFBaUIsTUFBTSwwQkFBMEIsQ0FBQTtBQUV4RCxNQUFNLE1BQU0sR0FBRztJQUNiLElBQUksRUFBRTtRQUNKLElBQUksRUFBRSxzQkFBc0I7UUFDNUIsT0FBTyxFQUFFLE9BQU87S0FDakI7SUFDRCxLQUFLLEVBQUU7UUFDTCxrQkFBa0IsRUFBRSxjQUFjO1FBQ2xDLHlCQUF5QixFQUFFLG9CQUFvQjtRQUMvQyx3QkFBd0IsRUFBRSxvQkFBb0I7UUFDOUMsOEJBQThCLEVBQUUsMEJBQTBCO1FBQzFELDBCQUEwQixFQUFFLHNCQUFzQjtLQUNuRDtJQUNELE9BQU8sRUFBRTtRQUNQLFNBQVMsRUFBRSxlQUFlO1FBQzFCLFdBQVcsRUFBRSxpQkFBaUI7S0FDL0I7Q0FDRixDQUFBO0FBRUQsZUFBZSxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbm9DbGllbnRCbG9ja3MgZnJvbSAnLi9ydWxlcy9uby1jbGllbnQtYmxvY2tzLmpzJ1xuaW1wb3J0IG5vQ29udGFpbmVySW5TZWN0aW9uIGZyb20gJy4vcnVsZXMvbm8tY29udGFpbmVyLWluLXNlY3Rpb24uanMnXG5pbXBvcnQgcHJlZmVyQ29tcG9uZW50UHJvcHMgZnJvbSAnLi9ydWxlcy9wcmVmZXItY29tcG9uZW50LXByb3BzLmpzJ1xuaW1wb3J0IHByZWZlclR5cG9ncmFwaHlDb21wb25lbnRzIGZyb20gJy4vcnVsZXMvcHJlZmVyLXR5cG9ncmFwaHktY29tcG9uZW50cy5qcydcbmltcG9ydCBwcmVmZXJMYXlvdXRDb21wb25lbnRzIGZyb20gJy4vcnVsZXMvcHJlZmVyLWxheW91dC1jb21wb25lbnRzLmpzJ1xuaW1wb3J0IHNwZWVkd2VsbENvbmZpZyBmcm9tICcuL2NvbmZpZ3Mvc3BlZWR3ZWxsLmpzJ1xuaW1wb3J0IHJlY29tbWVuZGVkQ29uZmlnIGZyb20gJy4vY29uZmlncy9yZWNvbW1lbmRlZC5qcydcblxuY29uc3QgcGx1Z2luID0ge1xuICBtZXRhOiB7XG4gICAgbmFtZTogJ2VzbGludC1wbHVnaW4tZ2FsbG9wJyxcbiAgICB2ZXJzaW9uOiAnMS4wLjEnLFxuICB9LFxuICBydWxlczoge1xuICAgICduby1jbGllbnQtYmxvY2tzJzogbm9DbGllbnRCbG9ja3MsXG4gICAgJ25vLWNvbnRhaW5lci1pbi1zZWN0aW9uJzogbm9Db250YWluZXJJblNlY3Rpb24sXG4gICAgJ3ByZWZlci1jb21wb25lbnQtcHJvcHMnOiBwcmVmZXJDb21wb25lbnRQcm9wcyxcbiAgICAncHJlZmVyLXR5cG9ncmFwaHktY29tcG9uZW50cyc6IHByZWZlclR5cG9ncmFwaHlDb21wb25lbnRzLFxuICAgICdwcmVmZXItbGF5b3V0LWNvbXBvbmVudHMnOiBwcmVmZXJMYXlvdXRDb21wb25lbnRzLFxuICB9LFxuICBjb25maWdzOiB7XG4gICAgc3BlZWR3ZWxsOiBzcGVlZHdlbGxDb25maWcsXG4gICAgcmVjb21tZW5kZWQ6IHJlY29tbWVuZGVkQ29uZmlnLFxuICB9LFxufVxuXG5leHBvcnQgZGVmYXVsdCBwbHVnaW5cbiJdfQ==
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXNsaW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sY0FBYyxNQUFNLDZCQUE2QixDQUFBO0FBQ3hELE9BQU8sb0JBQW9CLE1BQU0sb0NBQW9DLENBQUE7QUFDckUsT0FBTyxvQkFBb0IsTUFBTSxtQ0FBbUMsQ0FBQTtBQUNwRSxPQUFPLDBCQUEwQixNQUFNLHlDQUF5QyxDQUFBO0FBQ2hGLE9BQU8sc0JBQXNCLE1BQU0scUNBQXFDLENBQUE7QUFDeEUsT0FBTyxzQkFBc0IsTUFBTSxxQ0FBcUMsQ0FBQTtBQUN4RSxPQUFPLGVBQWUsTUFBTSx3QkFBd0IsQ0FBQTtBQUNwRCxPQUFPLGlCQUFpQixNQUFNLDBCQUEwQixDQUFBO0FBRXhELE1BQU0sTUFBTSxHQUFHO0lBQ2IsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFLHNCQUFzQjtRQUM1QixPQUFPLEVBQUUsT0FBTztLQUNqQjtJQUNELEtBQUssRUFBRTtRQUNMLGtCQUFrQixFQUFFLGNBQWM7UUFDbEMseUJBQXlCLEVBQUUsb0JBQW9CO1FBQy9DLHdCQUF3QixFQUFFLG9CQUFvQjtRQUM5Qyw4QkFBOEIsRUFBRSwwQkFBMEI7UUFDMUQsMEJBQTBCLEVBQUUsc0JBQXNCO1FBQ2xELDBCQUEwQixFQUFFLHNCQUFzQjtLQUNuRDtJQUNELE9BQU8sRUFBRTtRQUNQLFNBQVMsRUFBRSxlQUFlO1FBQzFCLFdBQVcsRUFBRSxpQkFBaUI7S0FDL0I7Q0FDRixDQUFBO0FBRUQsZUFBZSxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbm9DbGllbnRCbG9ja3MgZnJvbSAnLi9ydWxlcy9uby1jbGllbnQtYmxvY2tzLmpzJ1xuaW1wb3J0IG5vQ29udGFpbmVySW5TZWN0aW9uIGZyb20gJy4vcnVsZXMvbm8tY29udGFpbmVyLWluLXNlY3Rpb24uanMnXG5pbXBvcnQgcHJlZmVyQ29tcG9uZW50UHJvcHMgZnJvbSAnLi9ydWxlcy9wcmVmZXItY29tcG9uZW50LXByb3BzLmpzJ1xuaW1wb3J0IHByZWZlclR5cG9ncmFwaHlDb21wb25lbnRzIGZyb20gJy4vcnVsZXMvcHJlZmVyLXR5cG9ncmFwaHktY29tcG9uZW50cy5qcydcbmltcG9ydCBwcmVmZXJMYXlvdXRDb21wb25lbnRzIGZyb20gJy4vcnVsZXMvcHJlZmVyLWxheW91dC1jb21wb25lbnRzLmpzJ1xuaW1wb3J0IGJhY2tncm91bmRJbWFnZVJvdW5kZWQgZnJvbSAnLi9ydWxlcy9iYWNrZ3JvdW5kLWltYWdlLXJvdW5kZWQuanMnXG5pbXBvcnQgc3BlZWR3ZWxsQ29uZmlnIGZyb20gJy4vY29uZmlncy9zcGVlZHdlbGwuanMnXG5pbXBvcnQgcmVjb21tZW5kZWRDb25maWcgZnJvbSAnLi9jb25maWdzL3JlY29tbWVuZGVkLmpzJ1xuXG5jb25zdCBwbHVnaW4gPSB7XG4gIG1ldGE6IHtcbiAgICBuYW1lOiAnZXNsaW50LXBsdWdpbi1nYWxsb3AnLFxuICAgIHZlcnNpb246ICcxLjAuMScsXG4gIH0sXG4gIHJ1bGVzOiB7XG4gICAgJ25vLWNsaWVudC1ibG9ja3MnOiBub0NsaWVudEJsb2NrcyxcbiAgICAnbm8tY29udGFpbmVyLWluLXNlY3Rpb24nOiBub0NvbnRhaW5lckluU2VjdGlvbixcbiAgICAncHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6IHByZWZlckNvbXBvbmVudFByb3BzLFxuICAgICdwcmVmZXItdHlwb2dyYXBoeS1jb21wb25lbnRzJzogcHJlZmVyVHlwb2dyYXBoeUNvbXBvbmVudHMsXG4gICAgJ3ByZWZlci1sYXlvdXQtY29tcG9uZW50cyc6IHByZWZlckxheW91dENvbXBvbmVudHMsXG4gICAgJ2JhY2tncm91bmQtaW1hZ2Utcm91bmRlZCc6IGJhY2tncm91bmRJbWFnZVJvdW5kZWQsXG4gIH0sXG4gIGNvbmZpZ3M6IHtcbiAgICBzcGVlZHdlbGw6IHNwZWVkd2VsbENvbmZpZyxcbiAgICByZWNvbW1lbmRlZDogcmVjb21tZW5kZWRDb25maWcsXG4gIH0sXG59XG5cbmV4cG9ydCBkZWZhdWx0IHBsdWdpblxuIl19
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ declare const rule: Rule.RuleModule;
3
+ export default rule;
@@ -0,0 +1,122 @@
1
+ import { getCanonUrl, getCanonPattern } from '../utils/canon.js';
2
+ const RULE_NAME = 'background-image-rounded';
3
+ const pattern = getCanonPattern(RULE_NAME);
4
+ const rule = {
5
+ meta: {
6
+ type: 'suggestion',
7
+ docs: {
8
+ description: pattern?.summary || 'Background images must have rounded="rounded-none"',
9
+ recommended: true,
10
+ url: getCanonUrl(RULE_NAME),
11
+ },
12
+ messages: {
13
+ requireRoundedNone: `[Canon ${pattern?.id || '019'}] Background Image components (with absolute inset-0) must have rounded="rounded-none" to prevent corner clipping.`,
14
+ },
15
+ schema: [],
16
+ },
17
+ create(context) {
18
+ const filename = context.filename || context.getFilename();
19
+ // Only apply to block files
20
+ if (!filename.includes('/blocks/')) {
21
+ return {};
22
+ }
23
+ return {
24
+ JSXOpeningElement(node) {
25
+ const elementName = node.name?.name;
26
+ // Only check Image components
27
+ if (elementName !== 'Image') {
28
+ return;
29
+ }
30
+ // Check if className contains 'absolute' and 'inset-0'
31
+ const classNameAttr = node.attributes?.find((attr) => attr.type === 'JSXAttribute' &&
32
+ attr.name?.name === 'className');
33
+ if (!classNameAttr) {
34
+ return;
35
+ }
36
+ const classValue = getClassNameValue(classNameAttr);
37
+ if (!classValue) {
38
+ return;
39
+ }
40
+ // Check if this is a background image pattern
41
+ if (!isBackgroundImage(classValue)) {
42
+ return;
43
+ }
44
+ // Check if rounded="rounded-none" is set
45
+ const roundedAttr = node.attributes?.find((attr) => attr.type === 'JSXAttribute' &&
46
+ attr.name?.name === 'rounded');
47
+ if (!roundedAttr) {
48
+ context.report({
49
+ node,
50
+ messageId: 'requireRoundedNone',
51
+ });
52
+ return;
53
+ }
54
+ // Check the value of rounded prop
55
+ const roundedValue = getRoundedValue(roundedAttr);
56
+ if (roundedValue !== 'rounded-none') {
57
+ context.report({
58
+ node,
59
+ messageId: 'requireRoundedNone',
60
+ });
61
+ }
62
+ },
63
+ };
64
+ },
65
+ };
66
+ /**
67
+ * Extract className value from attribute
68
+ */
69
+ function getClassNameValue(attr) {
70
+ // Handle string literal
71
+ if (attr.value?.type === 'Literal' && typeof attr.value.value === 'string') {
72
+ return attr.value.value;
73
+ }
74
+ // Handle JSX expression container with template literal
75
+ if (attr.value?.type === 'JSXExpressionContainer') {
76
+ const expr = attr.value.expression;
77
+ if (expr.type === 'TemplateLiteral') {
78
+ // Combine all quasis
79
+ return expr.quasis?.map((q) => q.value?.raw || '').join(' ') || null;
80
+ }
81
+ // Handle clsx or other function calls - extract string arguments
82
+ if (expr.type === 'CallExpression') {
83
+ const strings = [];
84
+ for (const arg of expr.arguments || []) {
85
+ if (arg.type === 'Literal' && typeof arg.value === 'string') {
86
+ strings.push(arg.value);
87
+ }
88
+ if (arg.type === 'TemplateLiteral') {
89
+ strings.push(arg.quasis?.map((q) => q.value?.raw || '').join(' ') || '');
90
+ }
91
+ }
92
+ return strings.join(' ');
93
+ }
94
+ }
95
+ return null;
96
+ }
97
+ /**
98
+ * Check if className indicates a background image pattern
99
+ */
100
+ function isBackgroundImage(classValue) {
101
+ const classes = classValue.split(/\s+/);
102
+ const hasAbsolute = classes.includes('absolute');
103
+ const hasInset0 = classes.includes('inset-0');
104
+ return hasAbsolute && hasInset0;
105
+ }
106
+ /**
107
+ * Extract rounded prop value
108
+ */
109
+ function getRoundedValue(attr) {
110
+ if (attr.value?.type === 'Literal' && typeof attr.value.value === 'string') {
111
+ return attr.value.value;
112
+ }
113
+ if (attr.value?.type === 'JSXExpressionContainer') {
114
+ const expr = attr.value.expression;
115
+ if (expr.type === 'Literal' && typeof expr.value === 'string') {
116
+ return expr.value;
117
+ }
118
+ }
119
+ return null;
120
+ }
121
+ export default rule;
122
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1pbWFnZS1yb3VuZGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9ydWxlcy9iYWNrZ3JvdW5kLWltYWdlLXJvdW5kZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUVoRSxNQUFNLFNBQVMsR0FBRywwQkFBMEIsQ0FBQTtBQUM1QyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUE7QUFFMUMsTUFBTSxJQUFJLEdBQW9CO0lBQzVCLElBQUksRUFBRTtRQUNKLElBQUksRUFBRSxZQUFZO1FBQ2xCLElBQUksRUFBRTtZQUNKLFdBQVcsRUFBRSxPQUFPLEVBQUUsT0FBTyxJQUFJLG9EQUFvRDtZQUNyRixXQUFXLEVBQUUsSUFBSTtZQUNqQixHQUFHLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQztTQUM1QjtRQUNELFFBQVEsRUFBRTtZQUNSLGtCQUFrQixFQUFFLFVBQVUsT0FBTyxFQUFFLEVBQUUsSUFBSSxLQUFLLG9IQUFvSDtTQUN2SztRQUNELE1BQU0sRUFBRSxFQUFFO0tBQ1g7SUFFRCxNQUFNLENBQUMsT0FBTztRQUNaLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBRTFELDRCQUE0QjtRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sRUFBRSxDQUFBO1FBQ1gsQ0FBQztRQUVELE9BQU87WUFDTCxpQkFBaUIsQ0FBQyxJQUFTO2dCQUN6QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQTtnQkFFbkMsOEJBQThCO2dCQUM5QixJQUFJLFdBQVcsS0FBSyxPQUFPLEVBQUUsQ0FBQztvQkFDNUIsT0FBTTtn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QVMsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFBO1FBQ25CLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQsZUFBZSxJQUFJLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJ1bGUgfSBmcm9tICdlc2xpbnQnXG5pbXBvcnQgeyBnZXRDYW5vblVybCwgZ2V0Q2Fub25QYXR0ZXJuIH0gZnJvbSAnLi4vdXRpbHMvY2Fub24uanMnXG5cbmNvbnN0IFJVTEVfTkFNRSA9ICdiYWNrZ3JvdW5kLWltYWdlLXJvdW5kZWQnXG5jb25zdCBwYXR0ZXJuID0gZ2V0Q2Fub25QYXR0ZXJuKFJVTEVfTkFNRSlcblxuY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBwYXR0ZXJuPy5zdW1tYXJ5IHx8ICdCYWNrZ3JvdW5kIGltYWdlcyBtdXN0IGhhdmUgcm91bmRlZD1cInJvdW5kZWQtbm9uZVwiJyxcbiAgICAgIHJlY29tbWVuZGVkOiB0cnVlLFxuICAgICAgdXJsOiBnZXRDYW5vblVybChSVUxFX05BTUUpLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIHJlcXVpcmVSb3VuZGVkTm9uZTogYFtDYW5vbiAke3BhdHRlcm4/LmlkIHx8ICcwMTknfV0gQmFja2dyb3VuZCBJbWFnZSBjb21wb25lbnRzICh3aXRoIGFic29sdXRlIGluc2V0LTApIG11c3QgaGF2ZSByb3VuZGVkPVwicm91bmRlZC1ub25lXCIgdG8gcHJldmVudCBjb3JuZXIgY2xpcHBpbmcuYCxcbiAgICB9LFxuICAgIHNjaGVtYTogW10sXG4gIH0sXG5cbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGNvbnRleHQuZmlsZW5hbWUgfHwgY29udGV4dC5nZXRGaWxlbmFtZSgpXG5cbiAgICAvLyBPbmx5IGFwcGx5IHRvIGJsb2NrIGZpbGVzXG4gICAgaWYgKCFmaWxlbmFtZS5pbmNsdWRlcygnL2Jsb2Nrcy8nKSkge1xuICAgICAgcmV0dXJuIHt9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIEpTWE9wZW5pbmdFbGVtZW50KG5vZGU6IGFueSkge1xuICAgICAgICBjb25zdCBlbGVtZW50TmFtZSA9IG5vZGUubmFtZT8ubmFtZVxuXG4gICAgICAgIC8vIE9ubHkgY2hlY2sgSW1hZ2UgY29tcG9uZW50c1xuICAgICAgICBpZiAoZWxlbWVudE5hbWUgIT09ICdJbWFnZScpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIGNsYXNzTmFtZSBjb250YWlucyAnYWJzb2x1dGUnIGFuZCAnaW5zZXQtMCdcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lQXR0ciA9IG5vZGUuYXR0cmlidXRlcz8uZmluZChcbiAgICAgICAgICAoYXR0cjogYW55KSA9PlxuICAgICAgICAgICAgYXR0ci50eXBlID09PSAnSlNYQXR0cmlidXRlJyAmJlxuICAgICAgICAgICAgYXR0ci5uYW1lPy5uYW1lID09PSAnY2xhc3NOYW1lJ1xuICAgICAgICApXG5cbiAgICAgICAgaWYgKCFjbGFzc05hbWVBdHRyKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbGFzc1ZhbHVlID0gZ2V0Q2xhc3NOYW1lVmFsdWUoY2xhc3NOYW1lQXR0cilcbiAgICAgICAgaWYgKCFjbGFzc1ZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgYmFja2dyb3VuZCBpbWFnZSBwYXR0ZXJuXG4gICAgICAgIGlmICghaXNCYWNrZ3JvdW5kSW1hZ2UoY2xhc3NWYWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIHJvdW5kZWQ9XCJyb3VuZGVkLW5vbmVcIiBpcyBzZXRcbiAgICAgICAgY29uc3Qgcm91bmRlZEF0dHIgPSBub2RlLmF0dHJpYnV0ZXM/LmZpbmQoXG4gICAgICAgICAgKGF0dHI6IGFueSkgPT5cbiAgICAgICAgICAgIGF0dHIudHlwZSA9PT0gJ0pTWEF0dHJpYnV0ZScgJiZcbiAgICAgICAgICAgIGF0dHIubmFtZT8ubmFtZSA9PT0gJ3JvdW5kZWQnXG4gICAgICAgIClcblxuICAgICAgICBpZiAoIXJvdW5kZWRBdHRyKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgIG1lc3NhZ2VJZDogJ3JlcXVpcmVSb3VuZGVkTm9uZScsXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIHRoZSB2YWx1ZSBvZiByb3VuZGVkIHByb3BcbiAgICAgICAgY29uc3Qgcm91bmRlZFZhbHVlID0gZ2V0Um91bmRlZFZhbHVlKHJvdW5kZWRBdHRyKVxuICAgICAgICBpZiAocm91bmRlZFZhbHVlICE9PSAncm91bmRlZC1ub25lJykge1xuICAgICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICBtZXNzYWdlSWQ6ICdyZXF1aXJlUm91bmRlZE5vbmUnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfVxuICB9LFxufVxuXG4vKipcbiAqIEV4dHJhY3QgY2xhc3NOYW1lIHZhbHVlIGZyb20gYXR0cmlidXRlXG4gKi9cbmZ1bmN0aW9uIGdldENsYXNzTmFtZVZhbHVlKGF0dHI6IGFueSk6IHN0cmluZyB8IG51bGwge1xuICAvLyBIYW5kbGUgc3RyaW5nIGxpdGVyYWxcbiAgaWYgKGF0dHIudmFsdWU/LnR5cGUgPT09ICdMaXRlcmFsJyAmJiB0eXBlb2YgYXR0ci52YWx1ZS52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gYXR0ci52YWx1ZS52YWx1ZVxuICB9XG5cbiAgLy8gSGFuZGxlIEpTWCBleHByZXNzaW9uIGNvbnRhaW5lciB3aXRoIHRlbXBsYXRlIGxpdGVyYWxcbiAgaWYgKGF0dHIudmFsdWU/LnR5cGUgPT09ICdKU1hFeHByZXNzaW9uQ29udGFpbmVyJykge1xuICAgIGNvbnN0IGV4cHIgPSBhdHRyLnZhbHVlLmV4cHJlc3Npb25cblxuICAgIGlmIChleHByLnR5cGUgPT09ICdUZW1wbGF0ZUxpdGVyYWwnKSB7XG4gICAgICAvLyBDb21iaW5lIGFsbCBxdWFzaXNcbiAgICAgIHJldHVybiBleHByLnF1YXNpcz8ubWFwKChxOiBhbnkpID0+IHEudmFsdWU/LnJhdyB8fCAnJykuam9pbignICcpIHx8IG51bGxcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgY2xzeCBvciBvdGhlciBmdW5jdGlvbiBjYWxscyAtIGV4dHJhY3Qgc3RyaW5nIGFyZ3VtZW50c1xuICAgIGlmIChleHByLnR5cGUgPT09ICdDYWxsRXhwcmVzc2lvbicpIHtcbiAgICAgIGNvbnN0IHN0cmluZ3M6IHN0cmluZ1tdID0gW11cbiAgICAgIGZvciAoY29uc3QgYXJnIG9mIGV4cHIuYXJndW1lbnRzIHx8IFtdKSB7XG4gICAgICAgIGlmIChhcmcudHlwZSA9PT0gJ0xpdGVyYWwnICYmIHR5cGVvZiBhcmcudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgc3RyaW5ncy5wdXNoKGFyZy52YWx1ZSlcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXJnLnR5cGUgPT09ICdUZW1wbGF0ZUxpdGVyYWwnKSB7XG4gICAgICAgICAgc3RyaW5ncy5wdXNoKGFyZy5xdWFzaXM/Lm1hcCgocTogYW55KSA9PiBxLnZhbHVlPy5yYXcgfHwgJycpLmpvaW4oJyAnKSB8fCAnJylcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cmluZ3Muam9pbignICcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBjbGFzc05hbWUgaW5kaWNhdGVzIGEgYmFja2dyb3VuZCBpbWFnZSBwYXR0ZXJuXG4gKi9cbmZ1bmN0aW9uIGlzQmFja2dyb3VuZEltYWdlKGNsYXNzVmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBjbGFzc2VzID0gY2xhc3NWYWx1ZS5zcGxpdCgvXFxzKy8pXG4gIGNvbnN0IGhhc0Fic29sdXRlID0gY2xhc3Nlcy5pbmNsdWRlcygnYWJzb2x1dGUnKVxuICBjb25zdCBoYXNJbnNldDAgPSBjbGFzc2VzLmluY2x1ZGVzKCdpbnNldC0wJylcbiAgXG4gIHJldHVybiBoYXNBYnNvbHV0ZSAmJiBoYXNJbnNldDBcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHJvdW5kZWQgcHJvcCB2YWx1ZVxuICovXG5mdW5jdGlvbiBnZXRSb3VuZGVkVmFsdWUoYXR0cjogYW55KTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmIChhdHRyLnZhbHVlPy50eXBlID09PSAnTGl0ZXJhbCcgJiYgdHlwZW9mIGF0dHIudmFsdWUudmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGF0dHIudmFsdWUudmFsdWVcbiAgfVxuXG4gIGlmIChhdHRyLnZhbHVlPy50eXBlID09PSAnSlNYRXhwcmVzc2lvbkNvbnRhaW5lcicpIHtcbiAgICBjb25zdCBleHByID0gYXR0ci52YWx1ZS5leHByZXNzaW9uXG4gICAgaWYgKGV4cHIudHlwZSA9PT0gJ0xpdGVyYWwnICYmIHR5cGVvZiBleHByLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGV4cHIudmFsdWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuXG5leHBvcnQgZGVmYXVsdCBydWxlXG4iXX0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gallop.software/canon",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "description": "Gallop Canon - Architecture patterns, ESLint plugin, and CLI for template governance",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,52 @@
1
+ # 019: Background Image Rounded
2
+
3
+ **Category:** Components
4
+ **Status:** Stable
5
+ **Enforcement:** ESLint (`gallop/background-image-rounded`)
6
+
7
+ ## Summary
8
+
9
+ When using the `Image` component as a background image (with `absolute inset-0` positioning), always set `rounded="rounded-none"`.
10
+
11
+ ## Rationale
12
+
13
+ The Image component defaults to `rounded-lg` for rounded corners. When used as a full-bleed background image, these rounded corners:
14
+
15
+ - **Cause visual artifacts** - corners get clipped unexpectedly
16
+ - **Conflict with container rounding** - the parent container should control edge styling
17
+ - **Create inconsistent edges** - background images should fill their container completely
18
+
19
+ ## Bad
20
+
21
+ ```tsx
22
+ {/* Background image without rounded prop - uses default rounded-lg */}
23
+ <Image
24
+ src="/images/hero-bg.jpg"
25
+ alt="Background"
26
+ className="absolute inset-0 w-full h-full object-cover"
27
+ />
28
+ ```
29
+
30
+ ## Good
31
+
32
+ ```tsx
33
+ {/* Background image with explicit rounded-none */}
34
+ <Image
35
+ src="/images/hero-bg.jpg"
36
+ alt="Background"
37
+ className="absolute inset-0 w-full h-full object-cover"
38
+ rounded="rounded-none"
39
+ />
40
+ ```
41
+
42
+ ## Detection
43
+
44
+ The rule identifies background images by checking for:
45
+ - `Image` component usage
46
+ - `className` containing both `absolute` and `inset-0`
47
+
48
+ When detected, the rule requires `rounded="rounded-none"` to be explicitly set.
49
+
50
+ ## Exceptions
51
+
52
+ This rule only applies to files in `/blocks/`. Component files that implement background image patterns internally are not flagged.
package/schema.json CHANGED
@@ -220,6 +220,16 @@
220
220
  "enforcement": "eslint",
221
221
  "rule": "gallop/prefer-layout-components",
222
222
  "summary": "Use Grid/Columns, not raw div with grid"
223
+ },
224
+ {
225
+ "id": "019",
226
+ "title": "Background Image Rounded",
227
+ "file": "patterns/019-background-image-rounded.md",
228
+ "category": "components",
229
+ "status": "stable",
230
+ "enforcement": "eslint",
231
+ "rule": "gallop/background-image-rounded",
232
+ "summary": "Background images must have rounded=\"rounded-none\""
223
233
  }
224
234
  ],
225
235
  "guarantees": [
@@ -249,7 +259,7 @@
249
259
  "name": "Design System Compliance",
250
260
  "since": "1.0.0",
251
261
  "status": "stable",
252
- "patterns": ["003", "004", "009", "010", "011", "018"]
262
+ "patterns": ["003", "004", "009", "010", "011", "018", "019"]
253
263
  }
254
264
  ]
255
265
  }