Merge branch 'feature/camera-scan' into develop
This commit is contained in:
commit
eeeba456c6
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@blackbox-vision/react-qr-reader": "^5.0.0",
|
||||||
"@chainlink/contracts": "^0.2.1",
|
"@chainlink/contracts": "^0.2.1",
|
||||||
"@craco/craco": "^6.2.0",
|
"@craco/craco": "^6.2.0",
|
||||||
"@fontsource/fira-code": "^4.5.1",
|
"@fontsource/fira-code": "^4.5.1",
|
||||||
|
@ -1209,6 +1210,19 @@
|
||||||
"version": "0.2.3",
|
"version": "0.2.3",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@blackbox-vision/react-qr-reader": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@blackbox-vision/react-qr-reader/-/react-qr-reader-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VLNKwwJTv4UX1inUNgt2aGC2yIhKBYptW9EOhn7Nq//WzjD5KvHG7WR48HTzGUZ2s/EA0XlxZSfKOarHV1Vb/A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@zxing/browser": "0.0.7",
|
||||||
|
"@zxing/library": "^0.18.3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@chainlink/contracts": {
|
"node_modules/@chainlink/contracts": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.1.tgz",
|
||||||
|
@ -3512,6 +3526,37 @@
|
||||||
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
|
||||||
"integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg=="
|
"integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@zxing/browser": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-AepzMgDnD6EjxewqmXpHJsi4S3Gw9ilZJLIbTf6fWuWySEcHBodnGu3p7FWlgq1Sd5QyfPhTum5z3CBkkhMVng==",
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@zxing/text-encoding": "^0.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@zxing/library": "^0.18.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@zxing/library": {
|
||||||
|
"version": "0.18.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.18.6.tgz",
|
||||||
|
"integrity": "sha512-bulZ9JHoLFd9W36pi+7e7DnEYNJhljYjZ1UTsKPOoLMU3qtC+REHITeCRNx40zTRJZx18W5TBRXt5pq2Uopjsw==",
|
||||||
|
"dependencies": {
|
||||||
|
"ts-custom-error": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.4.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@zxing/text-encoding": "~0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@zxing/text-encoding": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/abab": {
|
"node_modules/abab": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
|
@ -17825,6 +17870,14 @@
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-custom-error": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ts-pnp": {
|
"node_modules/ts-pnp": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -20240,6 +20293,15 @@
|
||||||
"@bcoe/v8-coverage": {
|
"@bcoe/v8-coverage": {
|
||||||
"version": "0.2.3"
|
"version": "0.2.3"
|
||||||
},
|
},
|
||||||
|
"@blackbox-vision/react-qr-reader": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@blackbox-vision/react-qr-reader/-/react-qr-reader-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VLNKwwJTv4UX1inUNgt2aGC2yIhKBYptW9EOhn7Nq//WzjD5KvHG7WR48HTzGUZ2s/EA0XlxZSfKOarHV1Vb/A==",
|
||||||
|
"requires": {
|
||||||
|
"@zxing/browser": "0.0.7",
|
||||||
|
"@zxing/library": "^0.18.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@chainlink/contracts": {
|
"@chainlink/contracts": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.1.tgz",
|
||||||
|
@ -21700,6 +21762,29 @@
|
||||||
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
|
||||||
"integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg=="
|
"integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg=="
|
||||||
},
|
},
|
||||||
|
"@zxing/browser": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-AepzMgDnD6EjxewqmXpHJsi4S3Gw9ilZJLIbTf6fWuWySEcHBodnGu3p7FWlgq1Sd5QyfPhTum5z3CBkkhMVng==",
|
||||||
|
"requires": {
|
||||||
|
"@zxing/text-encoding": "^0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@zxing/library": {
|
||||||
|
"version": "0.18.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.18.6.tgz",
|
||||||
|
"integrity": "sha512-bulZ9JHoLFd9W36pi+7e7DnEYNJhljYjZ1UTsKPOoLMU3qtC+REHITeCRNx40zTRJZx18W5TBRXt5pq2Uopjsw==",
|
||||||
|
"requires": {
|
||||||
|
"@zxing/text-encoding": "~0.9.0",
|
||||||
|
"ts-custom-error": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@zxing/text-encoding": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"abab": {
|
"abab": {
|
||||||
"version": "2.0.5"
|
"version": "2.0.5"
|
||||||
},
|
},
|
||||||
|
@ -31387,6 +31472,11 @@
|
||||||
"tryer": {
|
"tryer": {
|
||||||
"version": "1.0.1"
|
"version": "1.0.1"
|
||||||
},
|
},
|
||||||
|
"ts-custom-error": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A=="
|
||||||
|
},
|
||||||
"ts-pnp": {
|
"ts-pnp": {
|
||||||
"version": "1.2.0"
|
"version": "1.2.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@blackbox-vision/react-qr-reader": "^5.0.0",
|
||||||
"@chainlink/contracts": "^0.2.1",
|
"@chainlink/contracts": "^0.2.1",
|
||||||
"@craco/craco": "^6.2.0",
|
"@craco/craco": "^6.2.0",
|
||||||
"@fontsource/fira-code": "^4.5.1",
|
"@fontsource/fira-code": "^4.5.1",
|
||||||
|
|
20
src/Home.tsx
20
src/Home.tsx
|
@ -3,7 +3,9 @@ import { NavLink, useHistory } from "react-router-dom";
|
||||||
import { commify } from "@ethersproject/units";
|
import { commify } from "@ethersproject/units";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn";
|
import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn";
|
||||||
|
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
|
||||||
import Logo from "./Logo";
|
import Logo from "./Logo";
|
||||||
|
import CameraScanner from "./search/CameraScanner";
|
||||||
import Timestamp from "./components/Timestamp";
|
import Timestamp from "./components/Timestamp";
|
||||||
import { RuntimeContext } from "./useRuntime";
|
import { RuntimeContext } from "./useRuntime";
|
||||||
import { useLatestBlock } from "./useLatestBlock";
|
import { useLatestBlock } from "./useLatestBlock";
|
||||||
|
@ -30,11 +32,13 @@ const Home: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const latestBlock = useLatestBlock(provider);
|
const latestBlock = useLatestBlock(provider);
|
||||||
|
const [isScanning, setScanning] = useState<boolean>(false);
|
||||||
|
|
||||||
document.title = "Home | Otterscan";
|
document.title = "Home | Otterscan";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="m-auto">
|
<div className="m-auto">
|
||||||
|
{isScanning && <CameraScanner turnOffScan={() => setScanning(false)} />}
|
||||||
<Logo />
|
<Logo />
|
||||||
<form
|
<form
|
||||||
className="flex flex-col"
|
className="flex flex-col"
|
||||||
|
@ -42,16 +46,26 @@ const Home: React.FC = () => {
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
>
|
>
|
||||||
|
<div className="flex mb-10">
|
||||||
<input
|
<input
|
||||||
className="w-full border rounded focus:outline-none px-2 py-1 mb-10"
|
className="w-full border-l border-t border-b rounded-l focus:outline-none px-2 py-1"
|
||||||
type="text"
|
type="text"
|
||||||
size={50}
|
size={50}
|
||||||
placeholder="Search by address / txn hash / block number / ENS name"
|
placeholder="Search by address / txn hash / block number / ENS name"
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
autoFocus
|
autoFocus
|
||||||
></input>
|
/>
|
||||||
<button
|
<button
|
||||||
className="mx-auto px-3 py-1 mb-10 rounded bg-gray-100 hover:bg-gray-200 focus:outline-none"
|
className="border rounded-r bg-skin-button-fill hover:bg-skin-button-hover-fill focus:outline-none px-2 py-1 text-base text-skin-button flex justify-center items-center"
|
||||||
|
type="button"
|
||||||
|
onClick={() => setScanning(true)}
|
||||||
|
title="Scan an ETH address using your camera"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faQrcode} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="mx-auto px-3 py-1 mb-10 rounded bg-skin-button-fill hover:bg-skin-button-hover-fill focus:outline-none"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
Search
|
Search
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React, { useState, useRef, useContext } from "react";
|
import React, { useState, useRef, useContext } from "react";
|
||||||
import { Link, useHistory } from "react-router-dom";
|
import { Link, useHistory } from "react-router-dom";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
|
||||||
import useKeyboardShortcut from "use-keyboard-shortcut";
|
import useKeyboardShortcut from "use-keyboard-shortcut";
|
||||||
import PriceBox from "./PriceBox";
|
import PriceBox from "./PriceBox";
|
||||||
|
import CameraScanner from "./search/CameraScanner";
|
||||||
import { RuntimeContext } from "./useRuntime";
|
import { RuntimeContext } from "./useRuntime";
|
||||||
|
|
||||||
const Title: React.FC = () => {
|
const Title: React.FC = () => {
|
||||||
|
@ -29,7 +32,11 @@ const Title: React.FC = () => {
|
||||||
searchRef.current?.focus();
|
searchRef.current?.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [isScanning, setScanning] = useState<boolean>(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{isScanning && <CameraScanner turnOffScan={() => setScanning(false)} />}
|
||||||
<div className="px-9 py-2 flex justify-between items-baseline">
|
<div className="px-9 py-2 flex justify-between items-baseline">
|
||||||
<Link className="self-center" to="/">
|
<Link className="self-center" to="/">
|
||||||
<div className="text-2xl text-link-blue font-title font-bold flex items-center space-x-2">
|
<div className="text-2xl text-link-blue font-title font-bold flex items-center space-x-2">
|
||||||
|
@ -61,7 +68,15 @@ const Title: React.FC = () => {
|
||||||
ref={searchRef}
|
ref={searchRef}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
className="rounded-r border-t border-b border-r bg-gray-100 hover:bg-gray-200 focus:outline-none px-2 py-1 text-sm text-gray-500"
|
className="border bg-skin-button-fill hover:bg-skin-button-hover-fill focus:outline-none px-2 py-1 text-sm text-skin-button"
|
||||||
|
type="button"
|
||||||
|
onClick={() => setScanning(true)}
|
||||||
|
title="Scan an ETH address using your camera"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faQrcode} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="rounded-r border-t border-b border-r bg-skin-button-fill hover:bg-skin-button-hover-fill focus:outline-none px-2 py-1 text-sm text-skin-button"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
Search
|
Search
|
||||||
|
@ -69,6 +84,7 @@ const Title: React.FC = () => {
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
|
--color-button-fill: 244, 244, 245; /* gray-100 */
|
||||||
|
--color-button-hover-fill: 228, 228, 231; /* gray-200 */
|
||||||
|
--color-button-text: 113, 113, 122; /* gray-500 */
|
||||||
|
|
||||||
--color-from-border: 254, 226, 226;
|
--color-from-border: 254, 226, 226;
|
||||||
--color-from-text: 220, 38, 38;
|
--color-from-text: 220, 38, 38;
|
||||||
--color-from-fill: 254, 242, 242;
|
--color-from-fill: 254, 242, 242;
|
||||||
|
@ -11,4 +15,16 @@
|
||||||
|
|
||||||
--color-table-row-hover: 243, 244, 246;
|
--color-table-row-hover: 243, 244, 246;
|
||||||
}
|
}
|
||||||
|
.test-theme {
|
||||||
|
--color-button-fill: 14, 165, 233; /* sky-500 */
|
||||||
|
--color-button-hover-fill: 56, 189, 248; /* sky-400 */
|
||||||
|
--color-button-text: 186, 230, 253; /* sky-200 */
|
||||||
|
|
||||||
|
--color-from-border: 251, 146, 60;
|
||||||
|
--color-from-text: 249, 115, 22;
|
||||||
|
--color-from-fill: 254, 215, 170;
|
||||||
|
--color-to-fill: 125, 211, 252;
|
||||||
|
|
||||||
|
--color-table-row-hover: 2, 132, 199;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import React from "react";
|
||||||
|
import { useHistory } from "react-router-dom";
|
||||||
|
import { isAddress } from "@ethersproject/address";
|
||||||
|
import { QrReader } from "@blackbox-vision/react-qr-reader";
|
||||||
|
import { OnResultFunction } from "@blackbox-vision/react-qr-reader/dist-types/types";
|
||||||
|
import { BarcodeFormat } from "@zxing/library";
|
||||||
|
import { Dialog } from "@headlessui/react";
|
||||||
|
|
||||||
|
type CameraScannerProps = {
|
||||||
|
turnOffScan: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CameraScanner: React.FC<CameraScannerProps> = ({ turnOffScan }) => {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const evaluateScan: OnResultFunction = (result, error, codeReader) => {
|
||||||
|
console.log("scan");
|
||||||
|
if (!error && result?.getBarcodeFormat() === BarcodeFormat.QR_CODE) {
|
||||||
|
const text = result.getText();
|
||||||
|
console.log(`Scanned: ${text}`);
|
||||||
|
if (!isAddress(text)) {
|
||||||
|
console.warn("Not an ETH address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
history.push(`/search?q=${text}`);
|
||||||
|
turnOffScan();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
className="fixed z-10 inset-0 overflow-y-auto"
|
||||||
|
open={true}
|
||||||
|
onClose={turnOffScan}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-center min-h-screen">
|
||||||
|
<Dialog.Overlay className="fixed inset-0 bg-black opacity-30" />
|
||||||
|
<Dialog.Title className="absolute top-0 w-full text-center bg-white text-lg">
|
||||||
|
Point an ETH address QR code to camera
|
||||||
|
</Dialog.Title>
|
||||||
|
<div className="absolute inset-0 bg-transparent rounded min-w-max max-w-3xl w-full h-screen max-h-screen m-auto">
|
||||||
|
<QrReader
|
||||||
|
className="m-auto"
|
||||||
|
constraints={{}}
|
||||||
|
onResult={evaluateScan}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CameraScanner;
|
|
@ -35,11 +35,16 @@ module.exports = {
|
||||||
},
|
},
|
||||||
textColor: {
|
textColor: {
|
||||||
skin: {
|
skin: {
|
||||||
|
button: withOpacity("--color-button-text"),
|
||||||
|
|
||||||
from: withOpacity("--color-from-text"),
|
from: withOpacity("--color-from-text"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
skin: {
|
skin: {
|
||||||
|
"button-fill": withOpacity("--color-button-fill"),
|
||||||
|
"button-hover-fill": withOpacity("--color-button-hover-fill"),
|
||||||
|
|
||||||
from: withOpacity("--color-from-fill"),
|
from: withOpacity("--color-from-fill"),
|
||||||
to: withOpacity("--color-to-fill"),
|
to: withOpacity("--color-to-fill"),
|
||||||
"table-hover": withOpacity("--color-table-row-hover"),
|
"table-hover": withOpacity("--color-table-row-hover"),
|
||||||
|
|
Loading…
Reference in New Issue