react-native-figma-shadow 0.1.0-alpha.1
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.
- package/LICENSE +21 -0
- package/README.md +152 -0
- package/android/CMakeLists.txt +30 -0
- package/android/build.gradle +76 -0
- package/android/gradle.properties +3 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/figmashadow/FigmaShadowView.kt +224 -0
- package/android/src/main/java/com/figmashadow/FigmaShadowViewManager.kt +71 -0
- package/android/src/main/java/com/figmashadow/FigmaShadowViewPackage.kt +30 -0
- package/android/src/main/jni/cpp-adapter.cpp +77 -0
- package/cpp/figmashadow/Color.cpp +225 -0
- package/cpp/figmashadow/Color.h +14 -0
- package/cpp/figmashadow/FigmaShadow.cpp +114 -0
- package/cpp/figmashadow/FigmaShadow.h +30 -0
- package/cpp/figmashadow/Parser.cpp +150 -0
- package/cpp/figmashadow/Parser.h +16 -0
- package/cpp/figmashadow/Rasterizer.cpp +276 -0
- package/cpp/figmashadow/Rasterizer.h +21 -0
- package/cpp/figmashadow/Types.h +66 -0
- package/docs/ARCHITECTURE.md +67 -0
- package/docs/images/fs_drop.png +0 -0
- package/docs/images/fs_inset.png +0 -0
- package/docs/images/fs_offset.png +0 -0
- package/ios/FigmaShadowView.h +9 -0
- package/ios/FigmaShadowView.mm +207 -0
- package/lib/commonjs/FigmaShadowViewNativeComponent.js +10 -0
- package/lib/commonjs/FigmaShadowViewNativeComponent.js.map +1 -0
- package/lib/commonjs/index.js +106 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/parseShadow.js +145 -0
- package/lib/commonjs/parseShadow.js.map +1 -0
- package/lib/module/FigmaShadowViewNativeComponent.js +5 -0
- package/lib/module/FigmaShadowViewNativeComponent.js.map +1 -0
- package/lib/module/index.js +88 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/parseShadow.js +139 -0
- package/lib/module/parseShadow.js.map +1 -0
- package/lib/typescript/src/FigmaShadowViewNativeComponent.d.ts +24 -0
- package/lib/typescript/src/FigmaShadowViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +40 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/parseShadow.d.ts +22 -0
- package/lib/typescript/src/parseShadow.d.ts.map +1 -0
- package/package.json +122 -0
- package/react-native-figma-shadow.podspec +25 -0
- package/react-native.config.js +19 -0
- package/src/FigmaShadowViewNativeComponent.ts +30 -0
- package/src/index.tsx +134 -0
- package/src/parseShadow.ts +134 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Shadow = Shadow;
|
|
7
|
+
Object.defineProperty(exports, "computeBleed", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _parseShadow.computeBleed;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
exports.default = void 0;
|
|
14
|
+
Object.defineProperty(exports, "parseBoxShadow", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () {
|
|
17
|
+
return _parseShadow.parseBoxShadow;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
21
|
+
var _reactNative = require("react-native");
|
|
22
|
+
var _FigmaShadowViewNativeComponent = _interopRequireDefault(require("./FigmaShadowViewNativeComponent"));
|
|
23
|
+
var _parseShadow = require("./parseShadow");
|
|
24
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
25
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
26
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
27
|
+
function resolveRadii(props) {
|
|
28
|
+
const base = props.borderRadius ?? 0;
|
|
29
|
+
return {
|
|
30
|
+
tl: props.borderTopLeftRadius ?? base,
|
|
31
|
+
tr: props.borderTopRightRadius ?? base,
|
|
32
|
+
br: props.borderBottomRightRadius ?? base,
|
|
33
|
+
bl: props.borderBottomLeftRadius ?? base
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Wraps its children and paints a pixel-consistent CSS-style shadow behind them
|
|
39
|
+
* on both platforms.
|
|
40
|
+
*
|
|
41
|
+
* Layout is neutral: the shadow bleeds into space the component reserves with
|
|
42
|
+
* negative margins, so siblings are laid out as if only the children were there.
|
|
43
|
+
*/
|
|
44
|
+
function Shadow(props) {
|
|
45
|
+
const {
|
|
46
|
+
shadow = '',
|
|
47
|
+
backgroundColor,
|
|
48
|
+
highQuality = false,
|
|
49
|
+
style,
|
|
50
|
+
children,
|
|
51
|
+
// Pulled out so they are not spread onto the native view (which only takes
|
|
52
|
+
// per-corner radii); `backgroundColor` is forwarded below as `fillColor` to
|
|
53
|
+
// avoid colliding with RN's built-in view prop.
|
|
54
|
+
borderRadius: _borderRadius,
|
|
55
|
+
borderTopLeftRadius: _btl,
|
|
56
|
+
borderTopRightRadius: _btr,
|
|
57
|
+
borderBottomRightRadius: _bbr,
|
|
58
|
+
borderBottomLeftRadius: _bbl,
|
|
59
|
+
...rest
|
|
60
|
+
} = props;
|
|
61
|
+
const layers = (0, _react.useMemo)(() => (0, _parseShadow.parseBoxShadow)(shadow), [shadow]);
|
|
62
|
+
const bleed = (0, _react.useMemo)(() => (0, _parseShadow.computeBleed)(layers), [layers]);
|
|
63
|
+
const radii = resolveRadii(props);
|
|
64
|
+
const geometry = {
|
|
65
|
+
marginLeft: -bleed.left,
|
|
66
|
+
marginTop: -bleed.top,
|
|
67
|
+
marginRight: -bleed.right,
|
|
68
|
+
marginBottom: -bleed.bottom,
|
|
69
|
+
paddingLeft: bleed.left,
|
|
70
|
+
paddingTop: bleed.top,
|
|
71
|
+
paddingRight: bleed.right,
|
|
72
|
+
paddingBottom: bleed.bottom
|
|
73
|
+
};
|
|
74
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
75
|
+
style: [styles.outer, style],
|
|
76
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FigmaShadowViewNativeComponent.default, {
|
|
77
|
+
...rest,
|
|
78
|
+
shadow: shadow,
|
|
79
|
+
fillColor: backgroundColor,
|
|
80
|
+
highQuality: highQuality,
|
|
81
|
+
borderTopLeftRadius: radii.tl,
|
|
82
|
+
borderTopRightRadius: radii.tr,
|
|
83
|
+
borderBottomRightRadius: radii.br,
|
|
84
|
+
borderBottomLeftRadius: radii.bl,
|
|
85
|
+
bleedLeft: bleed.left,
|
|
86
|
+
bleedTop: bleed.top,
|
|
87
|
+
bleedRight: bleed.right,
|
|
88
|
+
bleedBottom: bleed.bottom,
|
|
89
|
+
pixelRatio: _reactNative.PixelRatio.get(),
|
|
90
|
+
style: [styles.native, geometry],
|
|
91
|
+
children: children
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const styles = _reactNative.StyleSheet.create({
|
|
96
|
+
outer: {
|
|
97
|
+
// The shadow bleeds past this layout box; an ancestor with `overflow:
|
|
98
|
+
// hidden` will clip it, exactly as it would in CSS.
|
|
99
|
+
overflow: 'visible'
|
|
100
|
+
},
|
|
101
|
+
native: {
|
|
102
|
+
overflow: 'visible'
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
var _default = exports.default = Shadow;
|
|
106
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_FigmaShadowViewNativeComponent","_interopRequireDefault","_parseShadow","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","resolveRadii","props","base","borderRadius","tl","borderTopLeftRadius","tr","borderTopRightRadius","br","borderBottomRightRadius","bl","borderBottomLeftRadius","Shadow","shadow","backgroundColor","highQuality","style","children","_borderRadius","_btl","_btr","_bbr","_bbl","rest","layers","useMemo","parseBoxShadow","bleed","computeBleed","radii","geometry","marginLeft","left","marginTop","top","marginRight","right","marginBottom","bottom","paddingLeft","paddingTop","paddingRight","paddingBottom","jsx","View","styles","outer","fillColor","bleedLeft","bleedTop","bleedRight","bleedBottom","pixelRatio","PixelRatio","native","StyleSheet","create","overflow","_default","exports"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AASA,IAAAE,+BAAA,GAAAC,sBAAA,CAAAH,OAAA;AACA,IAAAI,YAAA,GAAAJ,OAAA;AAA8E,IAAAK,WAAA,GAAAL,OAAA;AAAA,SAAAG,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAAA,SAAAP,wBAAAO,CAAA,EAAAG,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAX,uBAAA,YAAAA,CAAAO,CAAA,EAAAG,CAAA,SAAAA,CAAA,IAAAH,CAAA,IAAAA,CAAA,CAAAC,UAAA,SAAAD,CAAA,MAAAO,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAR,OAAA,EAAAF,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAS,CAAA,MAAAF,CAAA,GAAAJ,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAE,CAAA,CAAAI,GAAA,CAAAX,CAAA,UAAAO,CAAA,CAAAK,GAAA,CAAAZ,CAAA,GAAAO,CAAA,CAAAM,GAAA,CAAAb,CAAA,EAAAS,CAAA,gBAAAN,CAAA,IAAAH,CAAA,gBAAAG,CAAA,OAAAW,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAG,CAAA,OAAAK,CAAA,IAAAD,CAAA,GAAAS,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAG,CAAA,OAAAK,CAAA,CAAAI,GAAA,IAAAJ,CAAA,CAAAK,GAAA,IAAAN,CAAA,CAAAE,CAAA,EAAAN,CAAA,EAAAK,CAAA,IAAAC,CAAA,CAAAN,CAAA,IAAAH,CAAA,CAAAG,CAAA,WAAAM,CAAA,KAAAT,CAAA,EAAAG,CAAA;AAqC9E,SAASgB,YAAYA,CAACC,KAAkB,EAAE;EACxC,MAAMC,IAAI,GAAGD,KAAK,CAACE,YAAY,IAAI,CAAC;EACpC,OAAO;IACLC,EAAE,EAAEH,KAAK,CAACI,mBAAmB,IAAIH,IAAI;IACrCI,EAAE,EAAEL,KAAK,CAACM,oBAAoB,IAAIL,IAAI;IACtCM,EAAE,EAAEP,KAAK,CAACQ,uBAAuB,IAAIP,IAAI;IACzCQ,EAAE,EAAET,KAAK,CAACU,sBAAsB,IAAIT;EACtC,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASU,MAAMA,CAACX,KAAkB,EAAE;EACzC,MAAM;IACJY,MAAM,GAAG,EAAE;IACXC,eAAe;IACfC,WAAW,GAAG,KAAK;IACnBC,KAAK;IACLC,QAAQ;IACR;IACA;IACA;IACAd,YAAY,EAAEe,aAAa;IAC3Bb,mBAAmB,EAAEc,IAAI;IACzBZ,oBAAoB,EAAEa,IAAI;IAC1BX,uBAAuB,EAAEY,IAAI;IAC7BV,sBAAsB,EAAEW,IAAI;IAC5B,GAAGC;EACL,CAAC,GAAGtB,KAAK;EAET,MAAMuB,MAAM,GAAG,IAAAC,cAAO,EAAC,MAAM,IAAAC,2BAAc,EAACb,MAAM,CAAC,EAAE,CAACA,MAAM,CAAC,CAAC;EAC9D,MAAMc,KAAiB,GAAG,IAAAF,cAAO,EAAC,MAAM,IAAAG,yBAAY,EAACJ,MAAM,CAAC,EAAE,CAACA,MAAM,CAAC,CAAC;EACvE,MAAMK,KAAK,GAAG7B,YAAY,CAACC,KAAK,CAAC;EAEjC,MAAM6B,QAAmB,GAAG;IAC1BC,UAAU,EAAE,CAACJ,KAAK,CAACK,IAAI;IACvBC,SAAS,EAAE,CAACN,KAAK,CAACO,GAAG;IACrBC,WAAW,EAAE,CAACR,KAAK,CAACS,KAAK;IACzBC,YAAY,EAAE,CAACV,KAAK,CAACW,MAAM;IAC3BC,WAAW,EAAEZ,KAAK,CAACK,IAAI;IACvBQ,UAAU,EAAEb,KAAK,CAACO,GAAG;IACrBO,YAAY,EAAEd,KAAK,CAACS,KAAK;IACzBM,aAAa,EAAEf,KAAK,CAACW;EACvB,CAAC;EAED,oBACE,IAAA1D,WAAA,CAAA+D,GAAA,EAACnE,YAAA,CAAAoE,IAAI;IAAC5B,KAAK,EAAE,CAAC6B,MAAM,CAACC,KAAK,EAAE9B,KAAK,CAAE;IAAAC,QAAA,eACjC,IAAArC,WAAA,CAAA+D,GAAA,EAAClE,+BAAA,CAAAM,OAAe;MAAA,GACVwC,IAAI;MACRV,MAAM,EAAEA,MAAO;MACfkC,SAAS,EAAEjC,eAAgB;MAC3BC,WAAW,EAAEA,WAAY;MACzBV,mBAAmB,EAAEwB,KAAK,CAACzB,EAAG;MAC9BG,oBAAoB,EAAEsB,KAAK,CAACvB,EAAG;MAC/BG,uBAAuB,EAAEoB,KAAK,CAACrB,EAAG;MAClCG,sBAAsB,EAAEkB,KAAK,CAACnB,EAAG;MACjCsC,SAAS,EAAErB,KAAK,CAACK,IAAK;MACtBiB,QAAQ,EAAEtB,KAAK,CAACO,GAAI;MACpBgB,UAAU,EAAEvB,KAAK,CAACS,KAAM;MACxBe,WAAW,EAAExB,KAAK,CAACW,MAAO;MAC1Bc,UAAU,EAAEC,uBAAU,CAAC5D,GAAG,CAAC,CAAE;MAC7BuB,KAAK,EAAE,CAAC6B,MAAM,CAACS,MAAM,EAAExB,QAAQ,CAAE;MAAAb,QAAA,EAEhCA;IAAQ,CACM;EAAC,CACd,CAAC;AAEX;AAEA,MAAM4B,MAAM,GAAGU,uBAAU,CAACC,MAAM,CAAC;EAC/BV,KAAK,EAAE;IACL;IACA;IACAW,QAAQ,EAAE;EACZ,CAAC;EACDH,MAAM,EAAE;IACNG,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAA5E,OAAA,GAEY6B,MAAM","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.computeBleed = computeBleed;
|
|
7
|
+
exports.hasVisibleShadow = hasVisibleShadow;
|
|
8
|
+
exports.parseBoxShadow = parseBoxShadow;
|
|
9
|
+
/**
|
|
10
|
+
* A minimal `box-shadow` parser used on the JS side purely to compute how far
|
|
11
|
+
* the shadow bleeds past the element box. The authoritative parse (colors,
|
|
12
|
+
* rendering) happens in the shared C++ core; this only needs geometry.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// A Gaussian with sigma = blur / 2; 3 sigma (= 1.5 * blur) captures 99.7% of it.
|
|
16
|
+
const BLUR_EXTENT_FACTOR = 1.5;
|
|
17
|
+
function splitTopLevel(input, delimiter) {
|
|
18
|
+
const out = [];
|
|
19
|
+
let depth = 0;
|
|
20
|
+
let current = '';
|
|
21
|
+
for (const ch of input) {
|
|
22
|
+
if (ch === '(') {
|
|
23
|
+
depth++;
|
|
24
|
+
} else if (ch === ')') {
|
|
25
|
+
depth = Math.max(0, depth - 1);
|
|
26
|
+
}
|
|
27
|
+
if (ch === delimiter && depth === 0) {
|
|
28
|
+
out.push(current);
|
|
29
|
+
current = '';
|
|
30
|
+
} else {
|
|
31
|
+
current += ch;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
out.push(current);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
function tokenize(layer) {
|
|
38
|
+
const out = [];
|
|
39
|
+
let depth = 0;
|
|
40
|
+
let current = '';
|
|
41
|
+
for (const ch of layer) {
|
|
42
|
+
if (ch === '(') {
|
|
43
|
+
depth++;
|
|
44
|
+
} else if (ch === ')') {
|
|
45
|
+
depth = Math.max(0, depth - 1);
|
|
46
|
+
}
|
|
47
|
+
if (/\s/.test(ch) && depth === 0) {
|
|
48
|
+
if (current) {
|
|
49
|
+
out.push(current);
|
|
50
|
+
current = '';
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
current += ch;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (current) {
|
|
57
|
+
out.push(current);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function parseLength(token) {
|
|
62
|
+
const match = /^(-?\d*\.?\d+)(px|dp|dip|pt)?$/i.exec(token.trim());
|
|
63
|
+
if (!match) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return parseFloat(match[1]);
|
|
67
|
+
}
|
|
68
|
+
function parseBoxShadow(input) {
|
|
69
|
+
if (!input) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
let s = input.trim();
|
|
73
|
+
const colon = s.indexOf(':');
|
|
74
|
+
if (colon !== -1) {
|
|
75
|
+
const head = s.slice(0, colon).trim().toLowerCase();
|
|
76
|
+
if (head === 'box-shadow' || head === 'boxshadow') {
|
|
77
|
+
s = s.slice(colon + 1).trim();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (s.endsWith(';')) {
|
|
81
|
+
s = s.slice(0, -1).trim();
|
|
82
|
+
}
|
|
83
|
+
if (!s || s.toLowerCase() === 'none') {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const layers = [];
|
|
87
|
+
for (const part of splitTopLevel(s, ',')) {
|
|
88
|
+
const trimmed = part.trim();
|
|
89
|
+
if (!trimmed) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
let inset = false;
|
|
93
|
+
const lengths = [];
|
|
94
|
+
for (const token of tokenize(trimmed)) {
|
|
95
|
+
if (token.toLowerCase() === 'inset') {
|
|
96
|
+
inset = true;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const len = parseLength(token);
|
|
100
|
+
if (len !== null) {
|
|
101
|
+
lengths.push(len);
|
|
102
|
+
}
|
|
103
|
+
// anything else (a color) is irrelevant to bleed
|
|
104
|
+
}
|
|
105
|
+
if (lengths.length < 2) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
layers.push({
|
|
109
|
+
offsetX: lengths[0],
|
|
110
|
+
offsetY: lengths[1],
|
|
111
|
+
blur: Math.max(0, lengths[2] ?? 0),
|
|
112
|
+
spread: lengths[3] ?? 0,
|
|
113
|
+
inset
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return layers;
|
|
117
|
+
}
|
|
118
|
+
function computeBleed(layers) {
|
|
119
|
+
const bleed = {
|
|
120
|
+
left: 0,
|
|
121
|
+
top: 0,
|
|
122
|
+
right: 0,
|
|
123
|
+
bottom: 0
|
|
124
|
+
};
|
|
125
|
+
for (const layer of layers) {
|
|
126
|
+
if (layer.inset) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const extent = layer.blur * BLUR_EXTENT_FACTOR + Math.max(0, layer.spread);
|
|
130
|
+
bleed.right = Math.max(bleed.right, extent + Math.max(0, layer.offsetX));
|
|
131
|
+
bleed.left = Math.max(bleed.left, extent + Math.max(0, -layer.offsetX));
|
|
132
|
+
bleed.bottom = Math.max(bleed.bottom, extent + Math.max(0, layer.offsetY));
|
|
133
|
+
bleed.top = Math.max(bleed.top, extent + Math.max(0, -layer.offsetY));
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
left: Math.ceil(bleed.left),
|
|
137
|
+
top: Math.ceil(bleed.top),
|
|
138
|
+
right: Math.ceil(bleed.right),
|
|
139
|
+
bottom: Math.ceil(bleed.bottom)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function hasVisibleShadow(layers) {
|
|
143
|
+
return layers.length > 0;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=parseShadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["BLUR_EXTENT_FACTOR","splitTopLevel","input","delimiter","out","depth","current","ch","Math","max","push","tokenize","layer","test","parseLength","token","match","exec","trim","parseFloat","parseBoxShadow","s","colon","indexOf","head","slice","toLowerCase","endsWith","layers","part","trimmed","inset","lengths","len","length","offsetX","offsetY","blur","spread","computeBleed","bleed","left","top","right","bottom","extent","ceil","hasVisibleShadow"],"sourceRoot":"../../src","sources":["parseShadow.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["codegenNativeComponent"],"sourceRoot":"../../src","sources":["FigmaShadowViewNativeComponent.ts"],"mappings":";;AAEA,OAAOA,sBAAsB,MAAM,yDAAyD;AA2B5F,eAAeA,sBAAsB,CAAc,iBAAiB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
|
+
import { PixelRatio, StyleSheet, View } from 'react-native';
|
|
5
|
+
import FigmaShadowView from './FigmaShadowViewNativeComponent';
|
|
6
|
+
import { computeBleed, parseBoxShadow } from './parseShadow';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
export { parseBoxShadow, computeBleed } from './parseShadow';
|
|
9
|
+
function resolveRadii(props) {
|
|
10
|
+
const base = props.borderRadius ?? 0;
|
|
11
|
+
return {
|
|
12
|
+
tl: props.borderTopLeftRadius ?? base,
|
|
13
|
+
tr: props.borderTopRightRadius ?? base,
|
|
14
|
+
br: props.borderBottomRightRadius ?? base,
|
|
15
|
+
bl: props.borderBottomLeftRadius ?? base
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Wraps its children and paints a pixel-consistent CSS-style shadow behind them
|
|
21
|
+
* on both platforms.
|
|
22
|
+
*
|
|
23
|
+
* Layout is neutral: the shadow bleeds into space the component reserves with
|
|
24
|
+
* negative margins, so siblings are laid out as if only the children were there.
|
|
25
|
+
*/
|
|
26
|
+
export function Shadow(props) {
|
|
27
|
+
const {
|
|
28
|
+
shadow = '',
|
|
29
|
+
backgroundColor,
|
|
30
|
+
highQuality = false,
|
|
31
|
+
style,
|
|
32
|
+
children,
|
|
33
|
+
// Pulled out so they are not spread onto the native view (which only takes
|
|
34
|
+
// per-corner radii); `backgroundColor` is forwarded below as `fillColor` to
|
|
35
|
+
// avoid colliding with RN's built-in view prop.
|
|
36
|
+
borderRadius: _borderRadius,
|
|
37
|
+
borderTopLeftRadius: _btl,
|
|
38
|
+
borderTopRightRadius: _btr,
|
|
39
|
+
borderBottomRightRadius: _bbr,
|
|
40
|
+
borderBottomLeftRadius: _bbl,
|
|
41
|
+
...rest
|
|
42
|
+
} = props;
|
|
43
|
+
const layers = useMemo(() => parseBoxShadow(shadow), [shadow]);
|
|
44
|
+
const bleed = useMemo(() => computeBleed(layers), [layers]);
|
|
45
|
+
const radii = resolveRadii(props);
|
|
46
|
+
const geometry = {
|
|
47
|
+
marginLeft: -bleed.left,
|
|
48
|
+
marginTop: -bleed.top,
|
|
49
|
+
marginRight: -bleed.right,
|
|
50
|
+
marginBottom: -bleed.bottom,
|
|
51
|
+
paddingLeft: bleed.left,
|
|
52
|
+
paddingTop: bleed.top,
|
|
53
|
+
paddingRight: bleed.right,
|
|
54
|
+
paddingBottom: bleed.bottom
|
|
55
|
+
};
|
|
56
|
+
return /*#__PURE__*/_jsx(View, {
|
|
57
|
+
style: [styles.outer, style],
|
|
58
|
+
children: /*#__PURE__*/_jsx(FigmaShadowView, {
|
|
59
|
+
...rest,
|
|
60
|
+
shadow: shadow,
|
|
61
|
+
fillColor: backgroundColor,
|
|
62
|
+
highQuality: highQuality,
|
|
63
|
+
borderTopLeftRadius: radii.tl,
|
|
64
|
+
borderTopRightRadius: radii.tr,
|
|
65
|
+
borderBottomRightRadius: radii.br,
|
|
66
|
+
borderBottomLeftRadius: radii.bl,
|
|
67
|
+
bleedLeft: bleed.left,
|
|
68
|
+
bleedTop: bleed.top,
|
|
69
|
+
bleedRight: bleed.right,
|
|
70
|
+
bleedBottom: bleed.bottom,
|
|
71
|
+
pixelRatio: PixelRatio.get(),
|
|
72
|
+
style: [styles.native, geometry],
|
|
73
|
+
children: children
|
|
74
|
+
})
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const styles = StyleSheet.create({
|
|
78
|
+
outer: {
|
|
79
|
+
// The shadow bleeds past this layout box; an ancestor with `overflow:
|
|
80
|
+
// hidden` will clip it, exactly as it would in CSS.
|
|
81
|
+
overflow: 'visible'
|
|
82
|
+
},
|
|
83
|
+
native: {
|
|
84
|
+
overflow: 'visible'
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
export default Shadow;
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useMemo","PixelRatio","StyleSheet","View","FigmaShadowView","computeBleed","parseBoxShadow","jsx","_jsx","resolveRadii","props","base","borderRadius","tl","borderTopLeftRadius","tr","borderTopRightRadius","br","borderBottomRightRadius","bl","borderBottomLeftRadius","Shadow","shadow","backgroundColor","highQuality","style","children","_borderRadius","_btl","_btr","_bbr","_bbl","rest","layers","bleed","radii","geometry","marginLeft","left","marginTop","top","marginRight","right","marginBottom","bottom","paddingLeft","paddingTop","paddingRight","paddingBottom","styles","outer","fillColor","bleedLeft","bleedTop","bleedRight","bleedBottom","pixelRatio","get","native","create","overflow"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A minimal `box-shadow` parser used on the JS side purely to compute how far
|
|
5
|
+
* the shadow bleeds past the element box. The authoritative parse (colors,
|
|
6
|
+
* rendering) happens in the shared C++ core; this only needs geometry.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// A Gaussian with sigma = blur / 2; 3 sigma (= 1.5 * blur) captures 99.7% of it.
|
|
10
|
+
const BLUR_EXTENT_FACTOR = 1.5;
|
|
11
|
+
function splitTopLevel(input, delimiter) {
|
|
12
|
+
const out = [];
|
|
13
|
+
let depth = 0;
|
|
14
|
+
let current = '';
|
|
15
|
+
for (const ch of input) {
|
|
16
|
+
if (ch === '(') {
|
|
17
|
+
depth++;
|
|
18
|
+
} else if (ch === ')') {
|
|
19
|
+
depth = Math.max(0, depth - 1);
|
|
20
|
+
}
|
|
21
|
+
if (ch === delimiter && depth === 0) {
|
|
22
|
+
out.push(current);
|
|
23
|
+
current = '';
|
|
24
|
+
} else {
|
|
25
|
+
current += ch;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
out.push(current);
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
function tokenize(layer) {
|
|
32
|
+
const out = [];
|
|
33
|
+
let depth = 0;
|
|
34
|
+
let current = '';
|
|
35
|
+
for (const ch of layer) {
|
|
36
|
+
if (ch === '(') {
|
|
37
|
+
depth++;
|
|
38
|
+
} else if (ch === ')') {
|
|
39
|
+
depth = Math.max(0, depth - 1);
|
|
40
|
+
}
|
|
41
|
+
if (/\s/.test(ch) && depth === 0) {
|
|
42
|
+
if (current) {
|
|
43
|
+
out.push(current);
|
|
44
|
+
current = '';
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
current += ch;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (current) {
|
|
51
|
+
out.push(current);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
function parseLength(token) {
|
|
56
|
+
const match = /^(-?\d*\.?\d+)(px|dp|dip|pt)?$/i.exec(token.trim());
|
|
57
|
+
if (!match) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return parseFloat(match[1]);
|
|
61
|
+
}
|
|
62
|
+
export function parseBoxShadow(input) {
|
|
63
|
+
if (!input) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
let s = input.trim();
|
|
67
|
+
const colon = s.indexOf(':');
|
|
68
|
+
if (colon !== -1) {
|
|
69
|
+
const head = s.slice(0, colon).trim().toLowerCase();
|
|
70
|
+
if (head === 'box-shadow' || head === 'boxshadow') {
|
|
71
|
+
s = s.slice(colon + 1).trim();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (s.endsWith(';')) {
|
|
75
|
+
s = s.slice(0, -1).trim();
|
|
76
|
+
}
|
|
77
|
+
if (!s || s.toLowerCase() === 'none') {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const layers = [];
|
|
81
|
+
for (const part of splitTopLevel(s, ',')) {
|
|
82
|
+
const trimmed = part.trim();
|
|
83
|
+
if (!trimmed) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
let inset = false;
|
|
87
|
+
const lengths = [];
|
|
88
|
+
for (const token of tokenize(trimmed)) {
|
|
89
|
+
if (token.toLowerCase() === 'inset') {
|
|
90
|
+
inset = true;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const len = parseLength(token);
|
|
94
|
+
if (len !== null) {
|
|
95
|
+
lengths.push(len);
|
|
96
|
+
}
|
|
97
|
+
// anything else (a color) is irrelevant to bleed
|
|
98
|
+
}
|
|
99
|
+
if (lengths.length < 2) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
layers.push({
|
|
103
|
+
offsetX: lengths[0],
|
|
104
|
+
offsetY: lengths[1],
|
|
105
|
+
blur: Math.max(0, lengths[2] ?? 0),
|
|
106
|
+
spread: lengths[3] ?? 0,
|
|
107
|
+
inset
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return layers;
|
|
111
|
+
}
|
|
112
|
+
export function computeBleed(layers) {
|
|
113
|
+
const bleed = {
|
|
114
|
+
left: 0,
|
|
115
|
+
top: 0,
|
|
116
|
+
right: 0,
|
|
117
|
+
bottom: 0
|
|
118
|
+
};
|
|
119
|
+
for (const layer of layers) {
|
|
120
|
+
if (layer.inset) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const extent = layer.blur * BLUR_EXTENT_FACTOR + Math.max(0, layer.spread);
|
|
124
|
+
bleed.right = Math.max(bleed.right, extent + Math.max(0, layer.offsetX));
|
|
125
|
+
bleed.left = Math.max(bleed.left, extent + Math.max(0, -layer.offsetX));
|
|
126
|
+
bleed.bottom = Math.max(bleed.bottom, extent + Math.max(0, layer.offsetY));
|
|
127
|
+
bleed.top = Math.max(bleed.top, extent + Math.max(0, -layer.offsetY));
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
left: Math.ceil(bleed.left),
|
|
131
|
+
top: Math.ceil(bleed.top),
|
|
132
|
+
right: Math.ceil(bleed.right),
|
|
133
|
+
bottom: Math.ceil(bleed.bottom)
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export function hasVisibleShadow(layers) {
|
|
137
|
+
return layers.length > 0;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=parseShadow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["BLUR_EXTENT_FACTOR","splitTopLevel","input","delimiter","out","depth","current","ch","Math","max","push","tokenize","layer","test","parseLength","token","match","exec","trim","parseFloat","parseBoxShadow","s","colon","indexOf","head","slice","toLowerCase","endsWith","layers","part","trimmed","inset","lengths","len","length","offsetX","offsetY","blur","spread","computeBleed","bleed","left","top","right","bottom","extent","ceil","hasVisibleShadow"],"sourceRoot":"../../src","sources":["parseShadow.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ViewProps } from 'react-native';
|
|
2
|
+
import type { Float, WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
|
|
3
|
+
export interface NativeProps extends ViewProps {
|
|
4
|
+
/** A CSS `box-shadow` value, exactly as copied from Figma / a stylesheet. */
|
|
5
|
+
shadow?: string;
|
|
6
|
+
/** Optional fill painted inside the content box, below inset shadows. */
|
|
7
|
+
fillColor?: string;
|
|
8
|
+
borderTopLeftRadius?: WithDefault<Float, 0>;
|
|
9
|
+
borderTopRightRadius?: WithDefault<Float, 0>;
|
|
10
|
+
borderBottomRightRadius?: WithDefault<Float, 0>;
|
|
11
|
+
borderBottomLeftRadius?: WithDefault<Float, 0>;
|
|
12
|
+
/** Bleed insets (device-independent px) computed on the JS side. */
|
|
13
|
+
bleedLeft?: WithDefault<Float, 0>;
|
|
14
|
+
bleedTop?: WithDefault<Float, 0>;
|
|
15
|
+
bleedRight?: WithDefault<Float, 0>;
|
|
16
|
+
bleedBottom?: WithDefault<Float, 0>;
|
|
17
|
+
/** `PixelRatio.get()` — passed so the raster matches the screen density. */
|
|
18
|
+
pixelRatio?: WithDefault<Float, 1>;
|
|
19
|
+
/** Use the slower, exact rounded-corner quadrature. */
|
|
20
|
+
highQuality?: WithDefault<boolean, false>;
|
|
21
|
+
}
|
|
22
|
+
declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
|
|
23
|
+
export default _default;
|
|
24
|
+
//# sourceMappingURL=FigmaShadowViewNativeComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FigmaShadowViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/FigmaShadowViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAGpF,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mBAAmB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC5C,oBAAoB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7C,uBAAuB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAChD,sBAAsB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAE/C,oEAAoE;IACpE,SAAS,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAEpC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAEnC,uDAAuD;IACvD,WAAW,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;CAC3C;;AAED,wBAAsE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type StyleProp, type ViewProps, type ViewStyle } from 'react-native';
|
|
3
|
+
export type { EdgeInsets, ParsedShadowLayer } from './parseShadow';
|
|
4
|
+
export { parseBoxShadow, computeBleed } from './parseShadow';
|
|
5
|
+
export interface ShadowProps extends Omit<ViewProps, 'style'> {
|
|
6
|
+
/**
|
|
7
|
+
* A CSS `box-shadow` value — the exact string Figma's "Copy as CSS" produces,
|
|
8
|
+
* or what you already use on the web. Supports multiple comma-separated
|
|
9
|
+
* shadows, `inset`, spread, and any CSS color. Renders identically on iOS and
|
|
10
|
+
* Android.
|
|
11
|
+
*/
|
|
12
|
+
shadow?: string;
|
|
13
|
+
/** Uniform corner radius for the shadow shape. Match your child's radius. */
|
|
14
|
+
borderRadius?: number;
|
|
15
|
+
borderTopLeftRadius?: number;
|
|
16
|
+
borderTopRightRadius?: number;
|
|
17
|
+
borderBottomRightRadius?: number;
|
|
18
|
+
borderBottomLeftRadius?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Fill painted inside the content box, below any inset shadow and below the
|
|
21
|
+
* children. Use this (instead of a background on the child) when you want an
|
|
22
|
+
* inset shadow to sit above the fill, like CSS.
|
|
23
|
+
*/
|
|
24
|
+
backgroundColor?: string;
|
|
25
|
+
/** Opt into the slower, exact rounded-corner convolution. */
|
|
26
|
+
highQuality?: boolean;
|
|
27
|
+
/** Applied to the outer layout box. */
|
|
28
|
+
style?: StyleProp<ViewStyle>;
|
|
29
|
+
children?: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Wraps its children and paints a pixel-consistent CSS-style shadow behind them
|
|
33
|
+
* on both platforms.
|
|
34
|
+
*
|
|
35
|
+
* Layout is neutral: the shadow bleeds into space the component reserves with
|
|
36
|
+
* negative margins, so siblings are laid out as if only the children were there.
|
|
37
|
+
*/
|
|
38
|
+
export declare function Shadow(props: ShadowProps): React.JSX.Element;
|
|
39
|
+
export default Shadow;
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAKtB,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7D,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,uCAAuC;IACvC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAYD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,qBAuDxC;AAaD,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal `box-shadow` parser used on the JS side purely to compute how far
|
|
3
|
+
* the shadow bleeds past the element box. The authoritative parse (colors,
|
|
4
|
+
* rendering) happens in the shared C++ core; this only needs geometry.
|
|
5
|
+
*/
|
|
6
|
+
export interface ParsedShadowLayer {
|
|
7
|
+
offsetX: number;
|
|
8
|
+
offsetY: number;
|
|
9
|
+
blur: number;
|
|
10
|
+
spread: number;
|
|
11
|
+
inset: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface EdgeInsets {
|
|
14
|
+
left: number;
|
|
15
|
+
top: number;
|
|
16
|
+
right: number;
|
|
17
|
+
bottom: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function parseBoxShadow(input: string | undefined | null): ParsedShadowLayer[];
|
|
20
|
+
export declare function computeBleed(layers: ParsedShadowLayer[]): EdgeInsets;
|
|
21
|
+
export declare function hasVisibleShadow(layers: ParsedShadowLayer[]): boolean;
|
|
22
|
+
//# sourceMappingURL=parseShadow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseShadow.d.ts","sourceRoot":"","sources":["../../../src/parseShadow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAmDD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,iBAAiB,EAAE,CAuCpF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,UAAU,CAkBpE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAErE"}
|