@rpcbase/ui 0.21.0 → 0.22.0

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": "@rpcbase/ui",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -15,6 +15,7 @@ export const Checkbox = ({
15
15
  defaultChecked,
16
16
  checked,
17
17
  onChange,
18
+ color = "gray",
18
19
  ...props
19
20
  }: CheckboxProps) => {
20
21
  return (
@@ -29,7 +30,7 @@ export const Checkbox = ({
29
30
  defaultChecked={defaultChecked}
30
31
  checked={checked}
31
32
  onChange={onChange}
32
- className="col-start-1 row-start-1 appearance-none cursor-pointer rounded-sm border border-gray-300 bg-white checked:border-sky-600 checked:bg-sky-600 indeterminate:border-sky-600 indeterminate:bg-sky-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-600 disabled:border-gray-300 disabled:bg-gray-100 disabled:checked:bg-gray-100 forced-colors:appearance-auto"
33
+ className={`col-start-1 row-start-1 appearance-none cursor-pointer rounded-sm border border-gray-300 bg-white checked:border-${color}-600 checked:bg-${color}-600 indeterminate:border-${color}-600 indeterminate:bg-${color}-600 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-${color}-600 disabled:border-gray-300 disabled:bg-gray-100 disabled:checked:bg-gray-100 forced-colors:appearance-auto`}
33
34
  />
34
35
  <svg
35
36
  fill="none"
@@ -0,0 +1,106 @@
1
+ import React, { useRef, useEffect, useState } from "react"
2
+ import { decode } from "blurhash"
3
+
4
+ // Set to true to enable mouseover debugging (this will show the blurhash image unless hovered)
5
+ const DEBUG = false
6
+
7
+ export const Image = ({
8
+ src,
9
+ hash,
10
+ alt = "",
11
+ className,
12
+ }: {
13
+ src: string
14
+ hash: [number, number, string]
15
+ alt?: string
16
+ className?: string
17
+ }) => {
18
+ const [imageLoaded, setImageLoaded] = useState(false)
19
+ const [blurhashUrl, setBlurhashUrl] = useState<string | null>(null)
20
+
21
+ const imgRef = useRef<HTMLImageElement>(null)
22
+
23
+ useEffect(() => {
24
+ if (!hash) return
25
+
26
+ const [width, height, buffer] = hash
27
+ const pixels = decode(buffer, width, height)
28
+
29
+ const canvas = document.createElement("canvas")
30
+ const ctx = canvas.getContext("2d")
31
+
32
+ if (ctx) {
33
+ canvas.width = width
34
+ canvas.height = height
35
+
36
+ const imageData = new ImageData(
37
+ new Uint8ClampedArray(pixels),
38
+ width,
39
+ height
40
+ )
41
+ ctx.putImageData(imageData, 0, 0)
42
+
43
+ setBlurhashUrl(canvas.toDataURL())
44
+ }
45
+ }, [hash])
46
+
47
+ // Handle Cached Images
48
+ useEffect(() => {
49
+ if (imgRef.current && imgRef.current.complete) {
50
+ setImageLoaded(true)
51
+ }
52
+ }, [src])
53
+
54
+ const onMouseEnter = () => {
55
+ if (DEBUG) {
56
+ setImageLoaded(true)
57
+ }
58
+ }
59
+
60
+ const onMouseLeave = () => {
61
+ if (DEBUG) {
62
+ setImageLoaded(false)
63
+ }
64
+ }
65
+
66
+ return (
67
+ <div
68
+ style={{ position: "relative", overflow: "hidden" }}
69
+ className={className}
70
+ onMouseEnter={onMouseEnter}
71
+ onMouseLeave={onMouseLeave}
72
+ >
73
+ {blurhashUrl && !imageLoaded && (
74
+ <img
75
+ src={blurhashUrl}
76
+ style={{
77
+ position: "absolute",
78
+ top: 0,
79
+ left: 0,
80
+ width: "100%",
81
+ height: "100%",
82
+ objectFit: "cover",
83
+ }}
84
+ />
85
+ )}
86
+ <img
87
+ ref={imgRef}
88
+ src={src}
89
+ alt={alt}
90
+ style={{
91
+ width: "100%",
92
+ height: "100%",
93
+ objectFit: "cover",
94
+ display: imageLoaded ? "block" : "none",
95
+ position: "absolute",
96
+ top: 0,
97
+ left: 0,
98
+ }}
99
+ onLoad={() => {
100
+ setImageLoaded(true)
101
+ }}
102
+ onError={(e) => console.error("Image failed to load:", src, e)}
103
+ />
104
+ </div>
105
+ )
106
+ }