@kbach/react 0.6.10 → 0.6.12

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 @@ import {
23
23
  transformToWebProps,
24
24
  useConditionalWidth,
25
25
  useGlobalDarkMode
26
- } from "./chunk-CJRRPENF.mjs";
26
+ } from "./chunk-WYOKBFSK.mjs";
27
27
 
28
28
  // src/jsx-runtime.tsx
29
29
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -1793,6 +1793,16 @@ var RESOLVERS = {
1793
1793
  };
1794
1794
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1795
1795
  },
1796
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1797
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1798
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1799
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1800
+ content: ({ value, isArbitrary }) => {
1801
+ if (!getEffectiveIsWeb()) return null;
1802
+ if (isArbitrary) return { content: value };
1803
+ const presets = { none: "none" };
1804
+ return value in presets ? { content: presets[value] } : null;
1805
+ },
1796
1806
  // ── Outline extended (web-only) ───────────────────────────────────────────
1797
1807
  outline: ({ value, isArbitrary }, { colors }) => {
1798
1808
  if (!getEffectiveIsWeb()) return null;
@@ -3694,19 +3704,24 @@ var InteractiveWrapper = forwardRef(
3694
3704
  ...checked !== void 0 ? { checked } : {},
3695
3705
  style: finalStyle,
3696
3706
  ...!isNative && className ? { className } : {},
3697
- // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
3698
- // and onPressIn/onPressOut are ALSO forwarded — but only when Component is an actual
3699
- // component (react-native-web components accept both prop names), never when it's a
3700
- // literal HTML tag string ('div', 'a', …). React DOM warns "Unknown event handler
3701
- // property" for onPressIn/onPressOut on a host element even when the value is
3702
- // undefined — the check is on the prop KEY being present at all, not its value — so
3703
- // the key must be omitted entirely for string components, not just set to undefined.
3707
+ // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch) —
3708
+ // onPressIn/onPressOut are RN-only prop names and are never forwarded here, even when
3709
+ // Component isn't a literal HTML tag string. A non-string Component on web is just as
3710
+ // likely to be an ordinary web component (React Router's <Link>, Next.js's <Link>, any
3711
+ // custom wrapper) as an actual react-native-web primitive — "not a string" alone was never
3712
+ // a reliable signal that onPressIn/onPressOut are wanted, and forwarding them
3713
+ // unconditionally made React DOM warn "Unknown event handler property" the moment any web
3714
+ // component got an interactive modifier (hover:, active:, …), which is the common case,
3715
+ // not the exception. (A real react-native-web primitive would additionally have this pair
3716
+ // of props silently vanish after hydration anyway, once the browser-only web-substitution
3717
+ // in jsx-runtime.tsx swaps it for a plain host tag — so keeping them pre-hydration would
3718
+ // only have traded one prop-mismatch warning for another.) Genuinely native code paths
3719
+ // still get them via the isNative branch below.
3704
3720
  ...!isNative ? {
3705
3721
  onPointerDown: handlePointerDown,
3706
3722
  onPointerUp: handlePointerUp,
3707
3723
  onPointerLeave: handlePointerLeave,
3708
- onPointerCancel: handlePointerCancel,
3709
- ...typeof Component !== "string" ? { onPressIn, onPressOut } : {}
3724
+ onPointerCancel: handlePointerCancel
3710
3725
  } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3711
3726
  onMouseEnter: handleMouseEnter,
3712
3727
  onMouseLeave: handleMouseLeave,
package/dist/index.js CHANGED
@@ -1954,6 +1954,16 @@ var RESOLVERS = {
1954
1954
  };
1955
1955
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1956
1956
  },
1957
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1958
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1959
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1960
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1961
+ content: ({ value, isArbitrary }) => {
1962
+ if (!getEffectiveIsWeb()) return null;
1963
+ if (isArbitrary) return { content: value };
1964
+ const presets = { none: "none" };
1965
+ return value in presets ? { content: presets[value] } : null;
1966
+ },
1957
1967
  // ── Outline extended (web-only) ───────────────────────────────────────────
1958
1968
  outline: ({ value, isArbitrary }, { colors }) => {
1959
1969
  if (!getEffectiveIsWeb()) return null;
@@ -3988,25 +3998,28 @@ function styled(Component, baseClasses = "") {
3988
3998
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
3989
3999
  // Only attach state-tracking handlers when interactive modifiers are present.
3990
4000
  // Always forward user-provided handlers to avoid silently swallowing them.
3991
- // onPressIn/onPressOut are forwarded on web too (not just native) since
3992
- // react-native-web components rely on receiving them directly — but only
3993
- // when effectiveComponent is an actual component, never a literal HTML tag
3994
- // string ('div', 'a', …). React DOM warns "Unknown event handler property"
3995
- // for onPressIn/onPressOut on a host element even when the value is
3996
- // undefined — the check is on the prop KEY being present at all, not its
3997
- // value — so the key must be omitted entirely for string components.
3998
- ...isWeb ? hasInteractive ? {
4001
+ // Gated on isNative, not isWeb: isWeb is false during SSR too (no `window` there),
4002
+ // and onPressIn/onPressOut must stay excluded there as well — SSR is exactly where
4003
+ // getWebTag() above is skipped (it's isWeb-gated), so effectiveComponent may still be
4004
+ // a non-string RN-style reference server-side, and this used to forward onPressIn/
4005
+ // onPressOut to it unconditionally in that case (isWeb ? ... : ...'s false branch
4006
+ // covered both native AND SSR). onPressIn/onPressOut are RN-only prop names — a
4007
+ // non-string effectiveComponent on the web/SSR side is just as likely to be an
4008
+ // ordinary web component (React Router's <Link>, Next.js's <Link>, any custom
4009
+ // wrapper) as an actual react-native-web primitive, and "not a string" alone isn't a
4010
+ // reliable signal either way. Forwarding them made React DOM warn "Unknown event
4011
+ // handler property" the moment any such component got an interactive modifier
4012
+ // (hover:, active:, …), which is the common case, not the exception.
4013
+ ...!isNative ? hasInteractive ? {
3999
4014
  onPointerDown: handlePointerDown,
4000
4015
  onPointerUp: handlePointerUp,
4001
4016
  onPointerLeave: handlePointerLeave,
4002
- onPointerCancel: handlePointerCancel,
4003
- ...typeof effectiveComponent !== "string" ? { onPressIn, onPressOut } : {}
4017
+ onPointerCancel: handlePointerCancel
4004
4018
  } : {
4005
4019
  onPointerDown,
4006
4020
  onPointerUp,
4007
4021
  onPointerLeave,
4008
- onPointerCancel,
4009
- ...typeof effectiveComponent !== "string" ? { onPressIn, onPressOut } : {}
4022
+ onPointerCancel
4010
4023
  } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
4011
4024
  onMouseEnter: hasInteractive ? handleMouseEnter : onMouseEnter,
4012
4025
  onMouseLeave: hasInteractive ? handleMouseLeave : onMouseLeave,
@@ -4127,19 +4140,24 @@ var InteractiveWrapper = (0, import_react8.forwardRef)(
4127
4140
  ...checked !== void 0 ? { checked } : {},
4128
4141
  style: finalStyle,
4129
4142
  ...!isNative && className ? { className } : {},
4130
- // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
4131
- // and onPressIn/onPressOut are ALSO forwarded — but only when Component is an actual
4132
- // component (react-native-web components accept both prop names), never when it's a
4133
- // literal HTML tag string ('div', 'a', …). React DOM warns "Unknown event handler
4134
- // property" for onPressIn/onPressOut on a host element even when the value is
4135
- // undefined — the check is on the prop KEY being present at all, not its value — so
4136
- // the key must be omitted entirely for string components, not just set to undefined.
4143
+ // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch) —
4144
+ // onPressIn/onPressOut are RN-only prop names and are never forwarded here, even when
4145
+ // Component isn't a literal HTML tag string. A non-string Component on web is just as
4146
+ // likely to be an ordinary web component (React Router's <Link>, Next.js's <Link>, any
4147
+ // custom wrapper) as an actual react-native-web primitive — "not a string" alone was never
4148
+ // a reliable signal that onPressIn/onPressOut are wanted, and forwarding them
4149
+ // unconditionally made React DOM warn "Unknown event handler property" the moment any web
4150
+ // component got an interactive modifier (hover:, active:, …), which is the common case,
4151
+ // not the exception. (A real react-native-web primitive would additionally have this pair
4152
+ // of props silently vanish after hydration anyway, once the browser-only web-substitution
4153
+ // in jsx-runtime.tsx swaps it for a plain host tag — so keeping them pre-hydration would
4154
+ // only have traded one prop-mismatch warning for another.) Genuinely native code paths
4155
+ // still get them via the isNative branch below.
4137
4156
  ...!isNative ? {
4138
4157
  onPointerDown: handlePointerDown,
4139
4158
  onPointerUp: handlePointerUp,
4140
4159
  onPointerLeave: handlePointerLeave,
4141
- onPointerCancel: handlePointerCancel,
4142
- ...typeof Component !== "string" ? { onPressIn, onPressOut } : {}
4160
+ onPointerCancel: handlePointerCancel
4143
4161
  } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
4144
4162
  onMouseEnter: handleMouseEnter,
4145
4163
  onMouseLeave: handleMouseLeave,
package/dist/index.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  useGlobalDarkMode,
40
40
  useGlobalWidth,
41
41
  useSyncExternalStore
42
- } from "./chunk-CJRRPENF.mjs";
42
+ } from "./chunk-WYOKBFSK.mjs";
43
43
 
44
44
  // src/context.tsx
45
45
  import { createContext, useContext } from "react";
@@ -339,25 +339,28 @@ function styled(Component, baseClasses = "") {
339
339
  ...isWeb && combined ? { className: normalizeClassString(combined) } : {},
340
340
  // Only attach state-tracking handlers when interactive modifiers are present.
341
341
  // Always forward user-provided handlers to avoid silently swallowing them.
342
- // onPressIn/onPressOut are forwarded on web too (not just native) since
343
- // react-native-web components rely on receiving them directly — but only
344
- // when effectiveComponent is an actual component, never a literal HTML tag
345
- // string ('div', 'a', …). React DOM warns "Unknown event handler property"
346
- // for onPressIn/onPressOut on a host element even when the value is
347
- // undefined — the check is on the prop KEY being present at all, not its
348
- // value — so the key must be omitted entirely for string components.
349
- ...isWeb ? hasInteractive ? {
342
+ // Gated on isNative, not isWeb: isWeb is false during SSR too (no `window` there),
343
+ // and onPressIn/onPressOut must stay excluded there as well — SSR is exactly where
344
+ // getWebTag() above is skipped (it's isWeb-gated), so effectiveComponent may still be
345
+ // a non-string RN-style reference server-side, and this used to forward onPressIn/
346
+ // onPressOut to it unconditionally in that case (isWeb ? ... : ...'s false branch
347
+ // covered both native AND SSR). onPressIn/onPressOut are RN-only prop names — a
348
+ // non-string effectiveComponent on the web/SSR side is just as likely to be an
349
+ // ordinary web component (React Router's <Link>, Next.js's <Link>, any custom
350
+ // wrapper) as an actual react-native-web primitive, and "not a string" alone isn't a
351
+ // reliable signal either way. Forwarding them made React DOM warn "Unknown event
352
+ // handler property" the moment any such component got an interactive modifier
353
+ // (hover:, active:, …), which is the common case, not the exception.
354
+ ...!isNative ? hasInteractive ? {
350
355
  onPointerDown: handlePointerDown,
351
356
  onPointerUp: handlePointerUp,
352
357
  onPointerLeave: handlePointerLeave,
353
- onPointerCancel: handlePointerCancel,
354
- ...typeof effectiveComponent !== "string" ? { onPressIn, onPressOut } : {}
358
+ onPointerCancel: handlePointerCancel
355
359
  } : {
356
360
  onPointerDown,
357
361
  onPointerUp,
358
362
  onPointerLeave,
359
- onPointerCancel,
360
- ...typeof effectiveComponent !== "string" ? { onPressIn, onPressOut } : {}
363
+ onPointerCancel
361
364
  } : hasInteractive ? { onPressIn: handlePressIn, onPressOut: handlePressOut } : { onPressIn, onPressOut },
362
365
  onMouseEnter: hasInteractive ? handleMouseEnter : onMouseEnter,
363
366
  onMouseLeave: hasInteractive ? handleMouseLeave : onMouseLeave,
@@ -1912,6 +1912,16 @@ var RESOLVERS = {
1912
1912
  };
1913
1913
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1914
1914
  },
1915
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1916
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1917
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1918
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1919
+ content: ({ value, isArbitrary }) => {
1920
+ if (!getEffectiveIsWeb()) return null;
1921
+ if (isArbitrary) return { content: value };
1922
+ const presets = { none: "none" };
1923
+ return value in presets ? { content: presets[value] } : null;
1924
+ },
1915
1925
  // ── Outline extended (web-only) ───────────────────────────────────────────
1916
1926
  outline: ({ value, isArbitrary }, { colors }) => {
1917
1927
  if (!getEffectiveIsWeb()) return null;
@@ -3391,19 +3401,24 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
3391
3401
  ...checked !== void 0 ? { checked } : {},
3392
3402
  style: finalStyle,
3393
3403
  ...!isNative && className ? { className } : {},
3394
- // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
3395
- // and onPressIn/onPressOut are ALSO forwarded — but only when Component is an actual
3396
- // component (react-native-web components accept both prop names), never when it's a
3397
- // literal HTML tag string ('div', 'a', …). React DOM warns "Unknown event handler
3398
- // property" for onPressIn/onPressOut on a host element even when the value is
3399
- // undefined — the check is on the prop KEY being present at all, not its value — so
3400
- // the key must be omitted entirely for string components, not just set to undefined.
3404
+ // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch) —
3405
+ // onPressIn/onPressOut are RN-only prop names and are never forwarded here, even when
3406
+ // Component isn't a literal HTML tag string. A non-string Component on web is just as
3407
+ // likely to be an ordinary web component (React Router's <Link>, Next.js's <Link>, any
3408
+ // custom wrapper) as an actual react-native-web primitive — "not a string" alone was never
3409
+ // a reliable signal that onPressIn/onPressOut are wanted, and forwarding them
3410
+ // unconditionally made React DOM warn "Unknown event handler property" the moment any web
3411
+ // component got an interactive modifier (hover:, active:, …), which is the common case,
3412
+ // not the exception. (A real react-native-web primitive would additionally have this pair
3413
+ // of props silently vanish after hydration anyway, once the browser-only web-substitution
3414
+ // in jsx-runtime.tsx swaps it for a plain host tag — so keeping them pre-hydration would
3415
+ // only have traded one prop-mismatch warning for another.) Genuinely native code paths
3416
+ // still get them via the isNative branch below.
3401
3417
  ...!isNative ? {
3402
3418
  onPointerDown: handlePointerDown,
3403
3419
  onPointerUp: handlePointerUp,
3404
3420
  onPointerLeave: handlePointerLeave,
3405
- onPointerCancel: handlePointerCancel,
3406
- ...typeof Component !== "string" ? { onPressIn, onPressOut } : {}
3421
+ onPointerCancel: handlePointerCancel
3407
3422
  } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3408
3423
  onMouseEnter: handleMouseEnter,
3409
3424
  onMouseLeave: handleMouseLeave,
@@ -3,8 +3,8 @@ import {
3
3
  Fragment,
4
4
  jsx,
5
5
  jsxs
6
- } from "./chunk-RWQKYQWN.mjs";
7
- import "./chunk-CJRRPENF.mjs";
6
+ } from "./chunk-GTDMKS7C.mjs";
7
+ import "./chunk-WYOKBFSK.mjs";
8
8
 
9
9
  // src/jsx-dev-runtime.tsx
10
10
  function jsxDEV(type, props, key, isStaticChildren, source, self) {
@@ -1913,6 +1913,16 @@ var RESOLVERS = {
1913
1913
  };
1914
1914
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1915
1915
  },
1916
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1917
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1918
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1919
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1920
+ content: ({ value, isArbitrary }) => {
1921
+ if (!getEffectiveIsWeb()) return null;
1922
+ if (isArbitrary) return { content: value };
1923
+ const presets = { none: "none" };
1924
+ return value in presets ? { content: presets[value] } : null;
1925
+ },
1916
1926
  // ── Outline extended (web-only) ───────────────────────────────────────────
1917
1927
  outline: ({ value, isArbitrary }, { colors }) => {
1918
1928
  if (!getEffectiveIsWeb()) return null;
@@ -3392,19 +3402,24 @@ var InteractiveWrapper = (0, import_react2.forwardRef)(
3392
3402
  ...checked !== void 0 ? { checked } : {},
3393
3403
  style: finalStyle,
3394
3404
  ...!isNative && className ? { className } : {},
3395
- // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch),
3396
- // and onPressIn/onPressOut are ALSO forwarded — but only when Component is an actual
3397
- // component (react-native-web components accept both prop names), never when it's a
3398
- // literal HTML tag string ('div', 'a', …). React DOM warns "Unknown event handler
3399
- // property" for onPressIn/onPressOut on a host element even when the value is
3400
- // undefined — the check is on the prop KEY being present at all, not its value — so
3401
- // the key must be omitted entirely for string components, not just set to undefined.
3405
+ // On web, onPointerDown/Up drive the wrapper's own pressed state (covers mouse + touch) —
3406
+ // onPressIn/onPressOut are RN-only prop names and are never forwarded here, even when
3407
+ // Component isn't a literal HTML tag string. A non-string Component on web is just as
3408
+ // likely to be an ordinary web component (React Router's <Link>, Next.js's <Link>, any
3409
+ // custom wrapper) as an actual react-native-web primitive — "not a string" alone was never
3410
+ // a reliable signal that onPressIn/onPressOut are wanted, and forwarding them
3411
+ // unconditionally made React DOM warn "Unknown event handler property" the moment any web
3412
+ // component got an interactive modifier (hover:, active:, …), which is the common case,
3413
+ // not the exception. (A real react-native-web primitive would additionally have this pair
3414
+ // of props silently vanish after hydration anyway, once the browser-only web-substitution
3415
+ // in jsx-runtime.tsx swaps it for a plain host tag — so keeping them pre-hydration would
3416
+ // only have traded one prop-mismatch warning for another.) Genuinely native code paths
3417
+ // still get them via the isNative branch below.
3402
3418
  ...!isNative ? {
3403
3419
  onPointerDown: handlePointerDown,
3404
3420
  onPointerUp: handlePointerUp,
3405
3421
  onPointerLeave: handlePointerLeave,
3406
- onPointerCancel: handlePointerCancel,
3407
- ...typeof Component !== "string" ? { onPressIn, onPressOut } : {}
3422
+ onPointerCancel: handlePointerCancel
3408
3423
  } : { onPressIn: handlePressIn, onPressOut: handlePressOut },
3409
3424
  onMouseEnter: handleMouseEnter,
3410
3425
  onMouseLeave: handleMouseLeave,
@@ -4,10 +4,10 @@ import {
4
4
  _invalidateDefaultFontCache,
5
5
  jsx,
6
6
  jsxs
7
- } from "./chunk-RWQKYQWN.mjs";
7
+ } from "./chunk-GTDMKS7C.mjs";
8
8
  import {
9
9
  registerWebElement
10
- } from "./chunk-CJRRPENF.mjs";
10
+ } from "./chunk-WYOKBFSK.mjs";
11
11
  export {
12
12
  Fragment,
13
13
  _invalidateDefaultFontCache,
@@ -1727,6 +1727,16 @@ var RESOLVERS = {
1727
1727
  };
1728
1728
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1729
1729
  },
1730
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1731
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1732
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1733
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1734
+ content: ({ value, isArbitrary }) => {
1735
+ if (!getEffectiveIsWeb()) return null;
1736
+ if (isArbitrary) return { content: value };
1737
+ const presets = { none: "none" };
1738
+ return value in presets ? { content: presets[value] } : null;
1739
+ },
1730
1740
  // ── Outline extended (web-only) ───────────────────────────────────────────
1731
1741
  outline: ({ value, isArbitrary }, { colors }) => {
1732
1742
  if (!getEffectiveIsWeb()) return null;
@@ -3232,7 +3242,7 @@ function pushTemplateLiteralBody(body, into) {
3232
3242
  while ((im = interpolationRe.exec(body)) !== null) {
3233
3243
  pushClassLikeStrings(im[0], into);
3234
3244
  }
3235
- pushTokens(body.replace(/\$\{(?:[^{}]|\{[^{}]*\})*\}/g, " "), into);
3245
+ pushTokens(body.replace(/\$\{(?:[^{}]|\{[^{}]*\})*\}/g, () => "$"), into);
3236
3246
  }
3237
3247
  function pushClassLikeStrings(text, into) {
3238
3248
  const quotedStringRe = /(["'`])((?:(?!\1).)*)\1/g;
@@ -3245,9 +3255,9 @@ function pushClassLikeStrings(text, into) {
3245
3255
  }
3246
3256
  function extractClassStrings(code) {
3247
3257
  const found = /* @__PURE__ */ new Set();
3248
- const simpleRe = /(?:className|kb)=["']([^"']+)["']/g;
3258
+ const simpleRe = /(?:className|kb)=(["'])((?:(?!\1).)*)\1/g;
3249
3259
  let m;
3250
- while ((m = simpleRe.exec(code)) !== null) pushTokens(m[1], found);
3260
+ while ((m = simpleRe.exec(code)) !== null) pushTokens(m[2], found);
3251
3261
  const jsxExprRe = /(?:className|kb)=\{/g;
3252
3262
  while ((m = jsxExprRe.exec(code)) !== null) {
3253
3263
  let depth = 1;
@@ -1693,6 +1693,16 @@ var RESOLVERS = {
1693
1693
  };
1694
1694
  return offsets[value] ? { textUnderlineOffset: offsets[value] } : null;
1695
1695
  },
1696
+ // ── Content (web-only — for before:/after: pseudo-elements, which don't exist on native) ──
1697
+ // Arbitrary value carries its own quotes from the bracket syntax (content-['*'] parses to
1698
+ // the literal string 'you can see it' quotes included), so it passes straight through as a
1699
+ // valid `content: '*'` CSS value with no extra wrapping needed.
1700
+ content: ({ value, isArbitrary }) => {
1701
+ if (!getEffectiveIsWeb()) return null;
1702
+ if (isArbitrary) return { content: value };
1703
+ const presets = { none: "none" };
1704
+ return value in presets ? { content: presets[value] } : null;
1705
+ },
1696
1706
  // ── Outline extended (web-only) ───────────────────────────────────────────
1697
1707
  outline: ({ value, isArbitrary }, { colors }) => {
1698
1708
  if (!getEffectiveIsWeb()) return null;
@@ -3198,7 +3208,7 @@ function pushTemplateLiteralBody(body, into) {
3198
3208
  while ((im = interpolationRe.exec(body)) !== null) {
3199
3209
  pushClassLikeStrings(im[0], into);
3200
3210
  }
3201
- pushTokens(body.replace(/\$\{(?:[^{}]|\{[^{}]*\})*\}/g, " "), into);
3211
+ pushTokens(body.replace(/\$\{(?:[^{}]|\{[^{}]*\})*\}/g, () => "$"), into);
3202
3212
  }
3203
3213
  function pushClassLikeStrings(text, into) {
3204
3214
  const quotedStringRe = /(["'`])((?:(?!\1).)*)\1/g;
@@ -3211,9 +3221,9 @@ function pushClassLikeStrings(text, into) {
3211
3221
  }
3212
3222
  function extractClassStrings(code) {
3213
3223
  const found = /* @__PURE__ */ new Set();
3214
- const simpleRe = /(?:className|kb)=["']([^"']+)["']/g;
3224
+ const simpleRe = /(?:className|kb)=(["'])((?:(?!\1).)*)\1/g;
3215
3225
  let m;
3216
- while ((m = simpleRe.exec(code)) !== null) pushTokens(m[1], found);
3226
+ while ((m = simpleRe.exec(code)) !== null) pushTokens(m[2], found);
3217
3227
  const jsxExprRe = /(?:className|kb)=\{/g;
3218
3228
  while ((m = jsxExprRe.exec(code)) !== null) {
3219
3229
  let depth = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "0.6.10",
3
+ "version": "0.6.12",
4
4
  "description": "React / React Native components and hooks for the Kbach framework",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./dist/index.js",