boss-css 0.0.18 → 0.0.20

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.
@@ -23,7 +23,7 @@ const plugin = {
23
23
  [require_prefer_unitless_values.default.name]: require_prefer_unitless_values.default
24
24
  }
25
25
  };
26
- const plugins = [plugin.meta.name];
26
+ const plugins = { [plugin.meta.name]: plugin };
27
27
  const globalOptions = { languageOptions: { globals: { $$: "readonly" } } };
28
28
  const createConfig = (name, getRules) => ({
29
29
  [`${name}-error`]: {
@@ -23,7 +23,7 @@ const plugin = {
23
23
  [prefer_unitless_values_default.name]: prefer_unitless_values_default
24
24
  }
25
25
  };
26
- const plugins = [plugin.meta.name];
26
+ const plugins = { [plugin.meta.name]: plugin };
27
27
  const globalOptions = { languageOptions: { globals: { $$: "readonly" } } };
28
28
  const createConfig = (name, getRules) => ({
29
29
  [`${name}-error`]: {
@@ -1,10 +1,10 @@
1
- const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
1
+ const require_merge_index = require('../../merge/index.cjs');
2
2
  const require_ast = require('../utils/ast.cjs');
3
3
  const require_defaults = require('../utils/defaults.cjs');
4
4
  const require_format = require('../utils/format.cjs');
5
5
  const require_boss_classes = require('../utils/boss-classes.cjs');
6
6
  const require_order = require('../utils/order.cjs');
7
- let boss_css_merge = require("boss-css/merge");
7
+ const require_context = require('../utils/context.cjs');
8
8
 
9
9
  //#region src/eslint-plugin/rules/format-classnames.js
10
10
  const RULE_NAME = "format-classnames";
@@ -30,13 +30,14 @@ const formatClassList = (merge, literal, options) => {
30
30
  return next;
31
31
  };
32
32
  const create = (context) => {
33
- const sourceCode = context.getSourceCode();
33
+ const sourceCode = require_context.getSourceCode(context);
34
34
  const options = {
35
35
  ...defaultOptions,
36
36
  ...context.options[0] || {}
37
37
  };
38
38
  const patterns = createPatterns(options);
39
- const merge = (0, boss_css_merge.createBossMerge)(options.merge || {});
39
+ const merge = require_merge_index.createBossMerge(options.merge || {});
40
+ if (!sourceCode) return {};
40
41
  const reportLiteral = (literal) => {
41
42
  if (!literal || !literal.canFix) return;
42
43
  const next = formatClassList(merge, literal, options);
@@ -1,9 +1,10 @@
1
+ import { createBossMerge } from "../../merge/index.mjs";
1
2
  import { collectClassLiteralsFromExpression, compilePatterns, getCalleeName, getJSXAttributeName, getLiteralInfo, matchesPattern } from "../utils/ast.mjs";
2
3
  import { DEFAULT_ATTRIBUTE_PATTERNS, DEFAULT_CALLEE_PATTERNS, DEFAULT_TAG_PATTERNS, DEFAULT_VARIABLE_PATTERNS } from "../utils/defaults.mjs";
3
4
  import { buildLiteralReplacement } from "../utils/format.mjs";
4
5
  import { splitClassList } from "../utils/boss-classes.mjs";
5
6
  import { sortTokens } from "../utils/order.mjs";
6
- import { createBossMerge } from "boss-css/merge";
7
+ import { getSourceCode } from "../utils/context.mjs";
7
8
 
8
9
  //#region src/eslint-plugin/rules/format-classnames.js
9
10
  const RULE_NAME = "format-classnames";
@@ -29,13 +30,14 @@ const formatClassList = (merge, literal, options) => {
29
30
  return next;
30
31
  };
31
32
  const create = (context) => {
32
- const sourceCode = context.getSourceCode();
33
+ const sourceCode = getSourceCode(context);
33
34
  const options = {
34
35
  ...defaultOptions,
35
36
  ...context.options[0] || {}
36
37
  };
37
38
  const patterns = createPatterns(options);
38
39
  const merge = createBossMerge(options.merge || {});
40
+ if (!sourceCode) return {};
39
41
  const reportLiteral = (literal) => {
40
42
  if (!literal || !literal.canFix) return;
41
43
  const next = formatClassList(merge, literal, options);
@@ -1,6 +1,7 @@
1
1
  const require_ast = require('../utils/ast.cjs');
2
2
  const require_defaults = require('../utils/defaults.cjs');
3
3
  const require_boss_classes = require('../utils/boss-classes.cjs');
4
+ const require_context = require('../utils/context.cjs');
4
5
 
5
6
  //#region src/eslint-plugin/rules/no-unknown-classes.js
6
7
  const RULE_NAME = "no-unknown-classes";
@@ -21,12 +22,13 @@ const createPatterns = (options) => ({
21
22
  tags: require_ast.compilePatterns(options.tags)
22
23
  });
23
24
  const create = (context) => {
24
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = require_context.getSourceCode(context);
25
26
  const options = {
26
27
  ...defaultOptions,
27
28
  ...context.options[0] || {}
28
29
  };
29
30
  const patterns = createPatterns(options);
31
+ if (!sourceCode) return {};
30
32
  const reportInvalid = (literal) => {
31
33
  if (!literal || !literal.value) return;
32
34
  const invalid = require_boss_classes.findInvalidTokens(literal.value, options);
@@ -1,6 +1,7 @@
1
1
  import { collectClassLiteralsFromExpression, compilePatterns, getCalleeName, getJSXAttributeName, getLiteralInfo, matchesPattern } from "../utils/ast.mjs";
2
2
  import { DEFAULT_ATTRIBUTE_PATTERNS, DEFAULT_CALLEE_PATTERNS, DEFAULT_TAG_PATTERNS, DEFAULT_VARIABLE_PATTERNS } from "../utils/defaults.mjs";
3
3
  import { findInvalidTokens } from "../utils/boss-classes.mjs";
4
+ import { getSourceCode } from "../utils/context.mjs";
4
5
 
5
6
  //#region src/eslint-plugin/rules/no-unknown-classes.js
6
7
  const RULE_NAME = "no-unknown-classes";
@@ -21,12 +22,13 @@ const createPatterns = (options) => ({
21
22
  tags: compilePatterns(options.tags)
22
23
  });
23
24
  const create = (context) => {
24
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = getSourceCode(context);
25
26
  const options = {
26
27
  ...defaultOptions,
27
28
  ...context.options[0] || {}
28
29
  };
29
30
  const patterns = createPatterns(options);
31
+ if (!sourceCode) return {};
30
32
  const reportInvalid = (literal) => {
31
33
  if (!literal || !literal.value) return;
32
34
  const invalid = findInvalidTokens(literal.value, options);
@@ -2,6 +2,7 @@ const require_ast = require('../utils/ast.cjs');
2
2
  const require_defaults = require('../utils/defaults.cjs');
3
3
  const require_api = require('../utils/api.cjs');
4
4
  const require_boss_classes = require('../utils/boss-classes.cjs');
5
+ const require_context = require('../utils/context.cjs');
5
6
 
6
7
  //#region src/eslint-plugin/rules/prefer-token-values.js
7
8
  const RULE_NAME = "prefer-token-values";
@@ -94,7 +95,7 @@ const resolveTokenValue = (groupValues, tokenPath) => {
94
95
  return current;
95
96
  };
96
97
  const create = (context) => {
97
- const sourceCode = context.getSourceCode();
98
+ const sourceCode = require_context.getSourceCode(context);
98
99
  const options = {
99
100
  ...defaultOptions,
100
101
  ...context.options[0] || {}
@@ -105,6 +106,7 @@ const create = (context) => {
105
106
  const { api } = require_api.getApi();
106
107
  const tokenGroups = api?.tokens && typeof api.tokens === "object" ? api.tokens : null;
107
108
  if (!api || !tokenGroups) return {};
109
+ if (!sourceCode) return {};
108
110
  const reportTokenUsage = (node, propName, tokenKey) => {
109
111
  context.report({
110
112
  node,
@@ -2,6 +2,7 @@ import { getJSXAttributeName, getJSXRootName, getLiteralInfo } from "../utils/as
2
2
  import { DEFAULT_COMPONENTS } from "../utils/defaults.mjs";
3
3
  import { getApi } from "../utils/api.mjs";
4
4
  import { getContextSet, isCssPropName } from "../utils/boss-classes.mjs";
5
+ import { getSourceCode } from "../utils/context.mjs";
5
6
 
6
7
  //#region src/eslint-plugin/rules/prefer-token-values.js
7
8
  const RULE_NAME = "prefer-token-values";
@@ -94,7 +95,7 @@ const resolveTokenValue = (groupValues, tokenPath) => {
94
95
  return current;
95
96
  };
96
97
  const create = (context) => {
97
- const sourceCode = context.getSourceCode();
98
+ const sourceCode = getSourceCode(context);
98
99
  const options = {
99
100
  ...defaultOptions,
100
101
  ...context.options[0] || {}
@@ -105,6 +106,7 @@ const create = (context) => {
105
106
  const { api } = getApi();
106
107
  const tokenGroups = api?.tokens && typeof api.tokens === "object" ? api.tokens : null;
107
108
  if (!api || !tokenGroups) return {};
109
+ if (!sourceCode) return {};
108
110
  const reportTokenUsage = (node, propName, tokenKey) => {
109
111
  context.report({
110
112
  node,
@@ -3,6 +3,7 @@ const require_defaults = require('../utils/defaults.cjs');
3
3
  const require_format = require('../utils/format.cjs');
4
4
  const require_api = require('../utils/api.cjs');
5
5
  const require_boss_classes = require('../utils/boss-classes.cjs');
6
+ const require_context = require('../utils/context.cjs');
6
7
 
7
8
  //#region src/eslint-plugin/rules/prefer-unitless-values.js
8
9
  const RULE_NAME = "prefer-unitless-values";
@@ -118,7 +119,7 @@ const analyzeClassList = (classList, unit, extraProps) => {
118
119
  };
119
120
  };
120
121
  const create = (context) => {
121
- const sourceCode = context.getSourceCode();
122
+ const sourceCode = require_context.getSourceCode(context);
122
123
  const options = {
123
124
  ...defaultOptions,
124
125
  ...context.options[0] || {}
@@ -128,6 +129,7 @@ const create = (context) => {
128
129
  const { api } = require_api.getApi();
129
130
  const unit = normalizeUnit(options.unit) || normalizeUnit(api?.unit) || "px";
130
131
  if (!unit) return {};
132
+ if (!sourceCode) return {};
131
133
  const reportLiteral = (literal) => {
132
134
  if (!literal || !literal.value) return;
133
135
  const { issues, nextClassList } = analyzeClassList(literal.value, unit, extraProps);
@@ -3,6 +3,7 @@ import { DEFAULT_ATTRIBUTE_PATTERNS, DEFAULT_CALLEE_PATTERNS, DEFAULT_TAG_PATTER
3
3
  import { buildLiteralReplacement } from "../utils/format.mjs";
4
4
  import { getApi } from "../utils/api.mjs";
5
5
  import { isCssPropName, parseGroupedSelector, splitClassList, splitFragments } from "../utils/boss-classes.mjs";
6
+ import { getSourceCode } from "../utils/context.mjs";
6
7
 
7
8
  //#region src/eslint-plugin/rules/prefer-unitless-values.js
8
9
  const RULE_NAME = "prefer-unitless-values";
@@ -118,7 +119,7 @@ const analyzeClassList = (classList, unit, extraProps) => {
118
119
  };
119
120
  };
120
121
  const create = (context) => {
121
- const sourceCode = context.getSourceCode();
122
+ const sourceCode = getSourceCode(context);
122
123
  const options = {
123
124
  ...defaultOptions,
124
125
  ...context.options[0] || {}
@@ -128,6 +129,7 @@ const create = (context) => {
128
129
  const { api } = getApi();
129
130
  const unit = normalizeUnit(options.unit) || normalizeUnit(api?.unit) || "px";
130
131
  if (!unit) return {};
132
+ if (!sourceCode) return {};
131
133
  const reportLiteral = (literal) => {
132
134
  if (!literal || !literal.value) return;
133
135
  const { issues, nextClassList } = analyzeClassList(literal.value, unit, extraProps);
@@ -1,6 +1,7 @@
1
1
  const require_ast = require('../utils/ast.cjs');
2
2
  const require_defaults = require('../utils/defaults.cjs');
3
3
  const require_boss_classes = require('../utils/boss-classes.cjs');
4
+ const require_context = require('../utils/context.cjs');
4
5
 
5
6
  //#region src/eslint-plugin/rules/props-only.js
6
7
  const RULE_NAME = "props-only";
@@ -21,12 +22,13 @@ const createPatterns = (options) => ({
21
22
  tags: require_ast.compilePatterns(options.tags)
22
23
  });
23
24
  const create = (context) => {
24
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = require_context.getSourceCode(context);
25
26
  const options = {
26
27
  ...defaultOptions,
27
28
  ...context.options[0] || {}
28
29
  };
29
30
  const patterns = createPatterns(options);
31
+ if (!sourceCode) return {};
30
32
  const reportLiteral = (literal) => {
31
33
  if (!literal || !literal.value) return;
32
34
  if (!require_boss_classes.containsBossToken(literal.value, options)) return;
@@ -1,6 +1,7 @@
1
1
  import { collectClassLiteralsFromExpression, compilePatterns, getCalleeName, getJSXAttributeName, getLiteralInfo, matchesPattern } from "../utils/ast.mjs";
2
2
  import { DEFAULT_ATTRIBUTE_PATTERNS, DEFAULT_CALLEE_PATTERNS, DEFAULT_TAG_PATTERNS, DEFAULT_VARIABLE_PATTERNS } from "../utils/defaults.mjs";
3
3
  import { containsBossToken } from "../utils/boss-classes.mjs";
4
+ import { getSourceCode } from "../utils/context.mjs";
4
5
 
5
6
  //#region src/eslint-plugin/rules/props-only.js
6
7
  const RULE_NAME = "props-only";
@@ -21,12 +22,13 @@ const createPatterns = (options) => ({
21
22
  tags: compilePatterns(options.tags)
22
23
  });
23
24
  const create = (context) => {
24
- const sourceCode = context.getSourceCode();
25
+ const sourceCode = getSourceCode(context);
25
26
  const options = {
26
27
  ...defaultOptions,
27
28
  ...context.options[0] || {}
28
29
  };
29
30
  const patterns = createPatterns(options);
31
+ if (!sourceCode) return {};
30
32
  const reportLiteral = (literal) => {
31
33
  if (!literal || !literal.value) return;
32
34
  if (!containsBossToken(literal.value, options)) return;
@@ -5,8 +5,10 @@ const require_defaults = require('../utils/defaults.cjs');
5
5
  const RULE_NAME = "redundant-cx";
6
6
  const defaultOptions = {
7
7
  components: require_defaults.DEFAULT_COMPONENTS,
8
- callees: ["^cx$", "^\\$\\$\\.cx$"]
8
+ callees: null
9
9
  };
10
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ const getDefaultCalleePatterns = (components) => components.map((component) => `^${escapeRegExp(component)}\\.cx$`);
10
12
  const getCallExpression = (node) => {
11
13
  if (!node) return null;
12
14
  if (node.type === "ChainExpression") return getCallExpression(node.expression);
@@ -20,7 +22,7 @@ const create = (context) => {
20
22
  ...context.options[0] || {}
21
23
  };
22
24
  const componentSet = new Set(options.components);
23
- const calleePatterns = require_ast.compilePatterns(options.callees);
25
+ const calleePatterns = require_ast.compilePatterns(Array.isArray(options.callees) ? options.callees : getDefaultCalleePatterns(options.components));
24
26
  return { JSXOpeningElement(node) {
25
27
  const rootName = require_ast.getJSXRootName(node.name);
26
28
  if (!rootName || !componentSet.has(rootName)) return;
@@ -5,8 +5,10 @@ import { DEFAULT_COMPONENTS } from "../utils/defaults.mjs";
5
5
  const RULE_NAME = "redundant-cx";
6
6
  const defaultOptions = {
7
7
  components: DEFAULT_COMPONENTS,
8
- callees: ["^cx$", "^\\$\\$\\.cx$"]
8
+ callees: null
9
9
  };
10
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
+ const getDefaultCalleePatterns = (components) => components.map((component) => `^${escapeRegExp(component)}\\.cx$`);
10
12
  const getCallExpression = (node) => {
11
13
  if (!node) return null;
12
14
  if (node.type === "ChainExpression") return getCallExpression(node.expression);
@@ -20,7 +22,7 @@ const create = (context) => {
20
22
  ...context.options[0] || {}
21
23
  };
22
24
  const componentSet = new Set(options.components);
23
- const calleePatterns = compilePatterns(options.callees);
25
+ const calleePatterns = compilePatterns(Array.isArray(options.callees) ? options.callees : getDefaultCalleePatterns(options.components));
24
26
  return { JSXOpeningElement(node) {
25
27
  const rootName = getJSXRootName(node.name);
26
28
  if (!rootName || !componentSet.has(rootName)) return;
@@ -0,0 +1,9 @@
1
+
2
+ //#region src/eslint-plugin/utils/context.js
3
+ const getSourceCode = (context) => {
4
+ if (typeof context?.getSourceCode === "function") return context.getSourceCode();
5
+ return context?.sourceCode ?? null;
6
+ };
7
+
8
+ //#endregion
9
+ exports.getSourceCode = getSourceCode;
@@ -0,0 +1,8 @@
1
+ //#region src/eslint-plugin/utils/context.js
2
+ const getSourceCode = (context) => {
3
+ if (typeof context?.getSourceCode === "function") return context.getSourceCode();
4
+ return context?.sourceCode ?? null;
5
+ };
6
+
7
+ //#endregion
8
+ export { getSourceCode };
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let ts_deepmerge = require("ts-deepmerge");
2
3
  let _boss_css_is_css_prop = require("@boss-css/is-css-prop");
3
4
  _boss_css_is_css_prop = require_rolldown_runtime.__toESM(_boss_css_is_css_prop);
4
- let ts_deepmerge = require("ts-deepmerge");
5
5
 
6
6
  //#region src/merge/index.ts
7
7
  const cssPropCache = /* @__PURE__ */ new Map();
@@ -1,5 +1,5 @@
1
- import isCSSProp from "@boss-css/is-css-prop";
2
1
  import { merge as merge$1 } from "ts-deepmerge";
2
+ import isCSSProp from "@boss-css/is-css-prop";
3
3
 
4
4
  //#region src/merge/index.ts
5
5
  const cssPropCache = /* @__PURE__ */ new Map();
@@ -25,28 +25,62 @@ const onParse = async (api, input) => {
25
25
  });
26
26
  }
27
27
  };
28
- const templateRegexp = /`([\S\s]+?)`/g;
29
- const quoteRegexps = [
30
- /"(.+?)"/g,
31
- /'(.+?)'/g,
32
- templateRegexp
33
- ];
34
28
  const extractCode = (content) => {
35
29
  const results = [];
36
- for (const regexp of quoteRegexps) {
37
- const matches = content.matchAll(regexp);
38
- const isTemplate = regexp === templateRegexp;
39
- for (const match of matches) {
40
- const [, code] = match;
41
- if (isTemplate && code.includes("${")) {
30
+ [
31
+ "\"",
32
+ "'",
33
+ "`"
34
+ ].forEach((quote) => {
35
+ scanQuotedSegments(content, quote, ({ value, hasTemplateExpression }) => {
36
+ if (quote === "`" && hasTemplateExpression) {
42
37
  console.warn("[boss-css] classname parser skipped template literals with expressions. Classnames must be static.");
43
- console.warn(code);
38
+ console.warn(value);
39
+ return;
40
+ }
41
+ results.push(value);
42
+ });
43
+ });
44
+ return { codes: results };
45
+ };
46
+ const scanQuotedSegments = (input, quote, onSegment) => {
47
+ let index = 0;
48
+ const length = input.length;
49
+ while (index < length) {
50
+ if (input[index] !== quote) {
51
+ index += 1;
52
+ continue;
53
+ }
54
+ index += 1;
55
+ let value = "";
56
+ let escaped = false;
57
+ let hasTemplateExpression = false;
58
+ while (index < length) {
59
+ const current = input[index];
60
+ if (escaped) {
61
+ value += current;
62
+ escaped = false;
63
+ index += 1;
64
+ continue;
65
+ }
66
+ if (current === "\\") {
67
+ value += current;
68
+ escaped = true;
69
+ index += 1;
44
70
  continue;
45
71
  }
46
- results.push(code);
72
+ if (quote === "`" && current === "$" && input[index + 1] === "{") hasTemplateExpression = true;
73
+ if (current === quote) break;
74
+ value += current;
75
+ index += 1;
47
76
  }
77
+ if (index >= length) break;
78
+ onSegment({
79
+ value,
80
+ hasTemplateExpression
81
+ });
82
+ index += 1;
48
83
  }
49
- return { codes: results };
50
84
  };
51
85
  const extractPropTree = async (string, api) => {
52
86
  const tree = {};
@@ -25,28 +25,62 @@ const onParse = async (api, input) => {
25
25
  });
26
26
  }
27
27
  };
28
- const templateRegexp = /`([\S\s]+?)`/g;
29
- const quoteRegexps = [
30
- /"(.+?)"/g,
31
- /'(.+?)'/g,
32
- templateRegexp
33
- ];
34
28
  const extractCode = (content) => {
35
29
  const results = [];
36
- for (const regexp of quoteRegexps) {
37
- const matches = content.matchAll(regexp);
38
- const isTemplate = regexp === templateRegexp;
39
- for (const match of matches) {
40
- const [, code] = match;
41
- if (isTemplate && code.includes("${")) {
30
+ [
31
+ "\"",
32
+ "'",
33
+ "`"
34
+ ].forEach((quote) => {
35
+ scanQuotedSegments(content, quote, ({ value, hasTemplateExpression }) => {
36
+ if (quote === "`" && hasTemplateExpression) {
42
37
  console.warn("[boss-css] classname parser skipped template literals with expressions. Classnames must be static.");
43
- console.warn(code);
38
+ console.warn(value);
39
+ return;
40
+ }
41
+ results.push(value);
42
+ });
43
+ });
44
+ return { codes: results };
45
+ };
46
+ const scanQuotedSegments = (input, quote, onSegment) => {
47
+ let index = 0;
48
+ const length = input.length;
49
+ while (index < length) {
50
+ if (input[index] !== quote) {
51
+ index += 1;
52
+ continue;
53
+ }
54
+ index += 1;
55
+ let value = "";
56
+ let escaped = false;
57
+ let hasTemplateExpression = false;
58
+ while (index < length) {
59
+ const current = input[index];
60
+ if (escaped) {
61
+ value += current;
62
+ escaped = false;
63
+ index += 1;
64
+ continue;
65
+ }
66
+ if (current === "\\") {
67
+ value += current;
68
+ escaped = true;
69
+ index += 1;
44
70
  continue;
45
71
  }
46
- results.push(code);
72
+ if (quote === "`" && current === "$" && input[index + 1] === "{") hasTemplateExpression = true;
73
+ if (current === quote) break;
74
+ value += current;
75
+ index += 1;
47
76
  }
77
+ if (index >= length) break;
78
+ onSegment({
79
+ value,
80
+ hasTemplateExpression
81
+ });
82
+ index += 1;
48
83
  }
49
- return { codes: results };
50
84
  };
51
85
  const extractPropTree = async (string, api) => {
52
86
  const tree = {};
@@ -141,7 +141,15 @@ type BossComponentProps<C> = C extends keyof BossIntrinsicElements
141
141
  type AsProp<C extends BossElementType> = {
142
142
  as?: C
143
143
  }
144
- type PolymorphicComponentProp<C extends BossElementType, Props = {}> = Props & BossComponentProps<C> & AsProp<C>
144
+ type BossMergedProps<Props, ComponentProps> = Omit<Props, keyof ComponentProps> &
145
+ Omit<ComponentProps, keyof Props> & {
146
+ [K in Extract<keyof ComponentProps, keyof Props>]?: ComponentProps[K] | Props[K]
147
+ }
148
+ type PolymorphicComponentProp<C extends BossElementType, Props = {}> = BossMergedProps<
149
+ Props,
150
+ BossComponentProps<C>
151
+ > &
152
+ AsProp<C>
145
153
  type PolymorphicComponentPropWithRef<C extends BossElementType, Props = {}> = PolymorphicComponentProp<C, Props> & {
146
154
  ref?: unknown
147
155
  }
@@ -140,7 +140,15 @@ type BossComponentProps<C> = C extends keyof BossIntrinsicElements
140
140
  type AsProp<C extends BossElementType> = {
141
141
  as?: C
142
142
  }
143
- type PolymorphicComponentProp<C extends BossElementType, Props = {}> = Props & BossComponentProps<C> & AsProp<C>
143
+ type BossMergedProps<Props, ComponentProps> = Omit<Props, keyof ComponentProps> &
144
+ Omit<ComponentProps, keyof Props> & {
145
+ [K in Extract<keyof ComponentProps, keyof Props>]?: ComponentProps[K] | Props[K]
146
+ }
147
+ type PolymorphicComponentProp<C extends BossElementType, Props = {}> = BossMergedProps<
148
+ Props,
149
+ BossComponentProps<C>
150
+ > &
151
+ AsProp<C>
144
152
  type PolymorphicComponentPropWithRef<C extends BossElementType, Props = {}> = PolymorphicComponentProp<C, Props> & {
145
153
  ref?: unknown
146
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boss-css",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "Polymorphic, usage-driven CSS-in-JS.",
5
5
  "bin": {
6
6
  "boss": "./dist/cli/index.cjs",
@@ -275,6 +275,7 @@
275
275
  "@types/jsdom": "^27.0.0",
276
276
  "@types/node": "^25.0.9",
277
277
  "@types/react": "^19.2.8",
278
+ "eslint": "^10.0.2",
278
279
  "postcss": "^8.5.6",
279
280
  "preact": "^10.28.2",
280
281
  "prettier": "^3.8.0",