@swan-io/lake 2.7.25 → 2.7.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-io/lake",
3
- "version": "2.7.25",
3
+ "version": "2.7.26",
4
4
  "engines": {
5
5
  "node": ">=18.0.0",
6
6
  "yarn": "^1.22.0"
@@ -1,4 +1,4 @@
1
- import { ColorVariants } from "../constants/design";
1
+ import { ColorVariants, Radii } from "../constants/design";
2
2
  import { IconName } from "./Icon";
3
3
  import { SpacingValue } from "./Space";
4
4
  type Props = {
@@ -6,6 +6,7 @@ type Props = {
6
6
  size?: number;
7
7
  padding?: SpacingValue | 0;
8
8
  color?: ColorVariants;
9
+ borderRadius?: Radii;
9
10
  };
10
- export declare const BorderedIcon: ({ name, size, padding, color }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ export declare const BorderedIcon: ({ name, size, padding, color, borderRadius, }: Props) => import("react/jsx-runtime").JSX.Element;
11
12
  export {};
@@ -5,13 +5,12 @@ import { Box } from "./Box";
5
5
  import { Icon } from "./Icon";
6
6
  const styles = StyleSheet.create({
7
7
  base: {
8
- borderRadius: radii[8],
9
8
  borderWidth: 1,
10
9
  borderColor: colors.current[100],
11
10
  backgroundColor: colors.current[50],
12
11
  },
13
12
  });
14
- export const BorderedIcon = ({ name, size = 96, padding = 0, color = "current" }) => {
13
+ export const BorderedIcon = ({ name, size = 96, padding = 0, color = "current", borderRadius = 8, }) => {
15
14
  const iconSize = size - padding * 2;
16
15
  return (_jsx(Box, { alignItems: "center", justifyContent: "center", style: [
17
16
  styles.base,
@@ -20,6 +19,7 @@ export const BorderedIcon = ({ name, size = 96, padding = 0, color = "current" }
20
19
  height: size,
21
20
  borderColor: colors[color][100],
22
21
  backgroundColor: colors[color][50],
22
+ borderRadius: radii[borderRadius],
23
23
  },
24
24
  ], children: _jsx(Icon, { name: name, size: iconSize, color: colors[color][500] }) }));
25
25
  };
@@ -21,7 +21,7 @@ type CardParams = {
21
21
  expirationDate: string;
22
22
  cvv: string;
23
23
  color: "Silver" | "Black";
24
- logo: SVGElement | null;
24
+ logo: SVGElement | HTMLImageElement | null;
25
25
  logoScale: number;
26
26
  assetsUrls: Card3dAssetsUrls;
27
27
  onSvgError?: (code: string) => void;
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Environment, OrbitControls, Text, useGLTF, useTexture } from "@react-three/drei";
3
3
  import { Canvas, useFrame } from "@react-three/fiber";
4
+ import { Result } from "@swan-io/boxed";
4
5
  import { forwardRef, useEffect, useRef, useState } from "react";
5
6
  import * as THREE from "three";
6
- import { match } from "ts-pattern";
7
+ import { P, match } from "ts-pattern";
7
8
  import { isNotNullish, isNullish } from "../utils/nullish";
8
9
  import { createSvgImage, getMonochromeSvg } from "../utils/svg";
9
10
  /*
@@ -26,6 +27,10 @@ And this texture is used as an alpha map on a plane.
26
27
  To reproduce the shiny effect on the back of the card, we inject a custom shader in rainbow_mastercard material.
27
28
  This custom shader chunk change the diffuse color depending on camera position.
28
29
  */
30
+ // Uses alpha channel instead of green to make pixel transparent on logo plane
31
+ const logoAlphaMapFragmentShader = `
32
+ diffuseColor.a *= texture2D(alphaMap, vAlphaMapUv).a;
33
+ `;
29
34
  const shinyColorFragmentShader = `
30
35
  float red = cameraPosition.x * cameraPosition.z;
31
36
  float green = cameraPosition.y * cameraPosition.z;
@@ -140,10 +145,14 @@ export const Card = forwardRef(({ ownerName, cardNumber, expirationDate, cvv, co
140
145
  setLogoData(null);
141
146
  return;
142
147
  }
143
- // We transform the logo to white to be able to use it as alpha map
144
- const whiteLogo = getMonochromeSvg(logo, "white");
145
- // Convert to Image element to be able to use it as texture
146
- const image = createSvgImage(whiteLogo);
148
+ const image = match(logo)
149
+ .with(P.instanceOf(HTMLImageElement), image => Result.Ok(image))
150
+ .otherwise(logo => {
151
+ // We transform the logo to white to be able to use it as alpha map
152
+ const whiteLogo = getMonochromeSvg(logo, "white");
153
+ // Convert to Image element to be able to use it as texture
154
+ return createSvgImage(whiteLogo);
155
+ });
147
156
  if (image.isError()) {
148
157
  handleSvgError.current?.(image.getError());
149
158
  return;
@@ -168,7 +177,14 @@ export const Card = forwardRef(({ ownerName, cardNumber, expirationDate, cvv, co
168
177
  CARD_WIDTH / 2 - LOGO_MARGIN_RIGHT,
169
178
  CARD_HEIGHT / 2 - LOGO_MARGIN_TOP,
170
179
  FRONT_TEXT_POSITION,
171
- ], scale: logoScale, children: isNotNullish(logoData) && (_jsxs("mesh", { position: [-logoData.size[0] / 2, -logoData.size[1] / 2, 0], children: [_jsx("planeGeometry", { args: logoData.size }), _jsx("meshStandardMaterial", { color: match(color)
180
+ ], scale: logoScale, children: isNotNullish(logoData) && (_jsxs("mesh", { position: [-logoData.size[0] / 2, -logoData.size[1] / 2, 0], children: [_jsx("planeGeometry", { args: logoData.size }), _jsx("meshStandardMaterial", { ref: material => {
181
+ if (!material) {
182
+ return;
183
+ }
184
+ material.onBeforeCompile = shader => {
185
+ shader.fragmentShader = shader.fragmentShader.replace("#include <alphamap_fragment>", logoAlphaMapFragmentShader);
186
+ };
187
+ }, color: match(color)
172
188
  .with("Silver", () => 0x000000)
173
189
  .with("Black", () => 0xffffff)
174
190
  .exhaustive(), metalness: 0.1, roughness: 0.35, envMapIntensity: ENV_MAP_INTENSITY, transparent: true, alphaMap: logoData.alphaMap })] })) }), _jsx("mesh", { geometry: nodes.black_band.geometry, material: materials.black_band, position: [0, 1.774, BACK_TEXT_POSITION], rotation: [0, Math.PI / 2, 0] }), _jsx("mesh", { geometry: nodes.chip.geometry, material: materials.chip, position: [-2.78, 0.439, FRONT_TEXT_POSITION], rotation: [0, Math.PI / 2, 0] }), _jsx("mesh", { geometry: nodes.chip_pattern.geometry, material: materials.chip_pattern, position: [-2.778, 0.442, FRONT_TEXT_POSITION + 0.001], rotation: [0, Math.PI / 2, 0] }), _jsx("mesh", { geometry: nodes.mc_center.geometry, material: materials.mastercard_orange, position: [3.052, -1.832, FRONT_TEXT_POSITION], rotation: [Math.PI / 2, 0, 0] }), _jsx("mesh", { geometry: nodes.mc_left.geometry, material: materials.mastercard_red, position: [2.676, -1.773, FRONT_TEXT_POSITION], rotation: [Math.PI / 2, 0, 0] }), _jsx("mesh", { geometry: nodes.mc_right.geometry, material: materials.mastercard_yellow, position: [3.47, -1.773, FRONT_TEXT_POSITION], rotation: [-Math.PI / 2, 0, 0] }), _jsx("mesh", { geometry: nodes.metal_circle.geometry, material: materials.rainbow, position: [-2.33, -1.849, BACK_TEXT_POSITION], rotation: [-Math.PI / 2, Math.PI / 2, 0] }), _jsx("mesh", { geometry: nodes.metal_circle001.geometry, material: materials.rainbow_rough, position: [-2.629, -1.849, BACK_TEXT_POSITION - 0.001], rotation: [-Math.PI / 2, Math.PI / 2, 0], scale: [0.35, 1, 0.35] }), _jsx("mesh", { geometry: nodes.metal_circle002.geometry, material: materials.rainbow_rough, position: [-2.33, -1.849, BACK_TEXT_POSITION - 0.001], rotation: [-Math.PI / 2, Math.PI / 2, 0] }), _jsx("mesh", { geometry: nodes.metal_mastercard.geometry, material: materials.rainbow_mastercard, position: [0.914, -1.298, BACK_TEXT_POSITION - 0.001], rotation: [Math.PI / 2, 0, Math.PI], scale: 0.09 })] }) }));