@djangocfg/widget-visual 0.1.1 → 0.1.3
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 +11 -9
- package/src/design/ColorPicker/ColorPicker.tsx +15 -18
- package/src/design/ColorPicker/parts/ColorPickerArea.tsx +3 -2
- package/src/design/ColorPicker/parts/ColorPickerInput.tsx +2 -5
- package/src/gallery/components/media/GalleryImage.tsx +4 -1
- package/src/gallery/gallery.stories.tsx +3 -3
- package/src/lottie/types.ts +4 -2
- package/src/marquee/Marquee.tsx +2 -2
- package/src/qrcode/QRCode.tsx +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/widget-visual",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Presentation pieces: a colour picker and palette, a marquee, a QR code, an image gallery and a Lottie player",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"color-picker",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"default": "./src/gallery/index.ts"
|
|
53
53
|
},
|
|
54
54
|
"./lottie-player": {
|
|
55
|
-
"types": "./src/lottie/index.
|
|
56
|
-
"default": "./src/lottie/index.
|
|
55
|
+
"types": "./src/lottie/index.tsx",
|
|
56
|
+
"default": "./src/lottie/index.tsx"
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"files": [
|
|
@@ -66,28 +66,30 @@
|
|
|
66
66
|
"scripts": {
|
|
67
67
|
"check": "tsc --noEmit",
|
|
68
68
|
"check-types": "tsc --noEmit",
|
|
69
|
+
"lint": "eslint .",
|
|
69
70
|
"test": "vitest run",
|
|
70
71
|
"test:watch": "vitest"
|
|
71
72
|
},
|
|
72
73
|
"dependencies": {
|
|
73
|
-
"@djangocfg/widget-kit": "^0.1.
|
|
74
|
+
"@djangocfg/widget-kit": "^0.1.3",
|
|
74
75
|
"@radix-ui/react-direction": "^1.1.2",
|
|
75
76
|
"@radix-ui/react-slot": "^1.3.0",
|
|
77
|
+
"@types/qrcode": "^1.5.6",
|
|
76
78
|
"class-variance-authority": "^0.7.1",
|
|
77
79
|
"qrcode": "^1.5.4",
|
|
78
80
|
"react-lottie-player": "^2.1.0"
|
|
79
81
|
},
|
|
80
82
|
"peerDependencies": {
|
|
81
|
-
"@djangocfg/i18n": "^2.1.
|
|
82
|
-
"@djangocfg/ui-core": "^2.1.
|
|
83
|
+
"@djangocfg/i18n": "^2.1.544",
|
|
84
|
+
"@djangocfg/ui-core": "^2.1.544",
|
|
83
85
|
"lucide-react": "^0.545.0",
|
|
84
86
|
"react": "^19.0.0",
|
|
85
87
|
"react-dom": "^19.0.0"
|
|
86
88
|
},
|
|
87
89
|
"devDependencies": {
|
|
88
|
-
"@djangocfg/i18n": "^2.1.
|
|
89
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
90
|
-
"@djangocfg/ui-core": "^2.1.
|
|
90
|
+
"@djangocfg/i18n": "^2.1.544",
|
|
91
|
+
"@djangocfg/typescript-config": "^2.1.544",
|
|
92
|
+
"@djangocfg/ui-core": "^2.1.544",
|
|
91
93
|
"@storybook/react-vite": "^10.5.0",
|
|
92
94
|
"@types/node": "^25.9.5",
|
|
93
95
|
"@types/qrcode": "^1.5.6",
|
|
@@ -15,28 +15,12 @@ import { Button } from '@djangocfg/ui-core/components';
|
|
|
15
15
|
import { ColorPickerStoreProvider, useStoreContext, useStore } from './context/ColorPickerStore';
|
|
16
16
|
import { ColorPickerProvider, useColorPickerContext } from './context/ColorPickerContext';
|
|
17
17
|
import { hexToRgb, rgbToHsv, rgbToHex } from './lib/color-utils';
|
|
18
|
-
import type { ColorPickerProps
|
|
18
|
+
import type { ColorPickerProps } from './types';
|
|
19
19
|
|
|
20
20
|
const ROOT_NAME = 'ColorPicker';
|
|
21
21
|
const TRIGGER_NAME = 'ColorPickerTrigger';
|
|
22
22
|
const CONTENT_NAME = 'ColorPickerContent';
|
|
23
23
|
|
|
24
|
-
function useLazyRef<T>(init: () => T): React.RefObject<T> {
|
|
25
|
-
const ref = React.useRef<T | null>(null);
|
|
26
|
-
if (ref.current === null) {
|
|
27
|
-
ref.current = init();
|
|
28
|
-
}
|
|
29
|
-
return ref as React.RefObject<T>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function useAsRef<T>(value: T) {
|
|
33
|
-
const ref = React.useRef(value);
|
|
34
|
-
React.useEffect(() => {
|
|
35
|
-
ref.current = value;
|
|
36
|
-
});
|
|
37
|
-
return ref;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
24
|
export function ColorPicker(props: ColorPickerProps) {
|
|
41
25
|
const {
|
|
42
26
|
value: valueProp,
|
|
@@ -59,11 +43,16 @@ export function ColorPicker(props: ColorPickerProps) {
|
|
|
59
43
|
const colorString = valueProp ?? defaultValue;
|
|
60
44
|
const color = hexToRgb(colorString);
|
|
61
45
|
|
|
46
|
+
// Mount-time seed for the store, deliberately frozen. These feed the
|
|
47
|
+
// provider's `initial*` props, which it reads once; recomputing them on a
|
|
48
|
+
// prop change would suggest a later `value` re-seeds the picker, and it does
|
|
49
|
+
// not — the store owns the colour after mount.
|
|
62
50
|
const initialState = React.useMemo(() => ({
|
|
63
51
|
color,
|
|
64
52
|
hsv: rgbToHsv(color),
|
|
65
53
|
open: openProp ?? defaultOpen ?? false,
|
|
66
54
|
format: formatProp ?? defaultFormat,
|
|
55
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
56
|
}), []);
|
|
68
57
|
|
|
69
58
|
return (
|
|
@@ -93,7 +82,15 @@ export function ColorPicker(props: ColorPickerProps) {
|
|
|
93
82
|
|
|
94
83
|
ColorPicker.displayName = ROOT_NAME;
|
|
95
84
|
|
|
96
|
-
|
|
85
|
+
type ColorPickerImplProps = Omit<
|
|
86
|
+
ColorPickerProps,
|
|
87
|
+
| 'defaultValue'
|
|
88
|
+
| 'onValueChange'
|
|
89
|
+
| 'onOpenChange'
|
|
90
|
+
| 'format'
|
|
91
|
+
| 'defaultFormat'
|
|
92
|
+
| 'onFormatChange'
|
|
93
|
+
>;
|
|
97
94
|
|
|
98
95
|
function ColorPickerImpl(props: ColorPickerImplProps) {
|
|
99
96
|
const {
|
|
@@ -11,9 +11,10 @@ import type { HSVColorValue } from '../types';
|
|
|
11
11
|
|
|
12
12
|
const AREA_NAME = 'ColorPickerArea';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// No `asChild`: the area owns pointer capture and its own geometry, so it
|
|
15
|
+
// cannot delegate its element to a caller's.
|
|
16
|
+
export function ColorPickerArea(props: React.ComponentProps<'div'>) {
|
|
15
17
|
const {
|
|
16
|
-
asChild,
|
|
17
18
|
onPointerDown: onPointerDownProp,
|
|
18
19
|
onPointerMove: onPointerMoveProp,
|
|
19
20
|
onPointerUp: onPointerUpProp,
|
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
rgbToHsv,
|
|
12
12
|
rgbToHsl,
|
|
13
13
|
hslToRgb,
|
|
14
|
+
hsvToRgb,
|
|
14
15
|
parseColorString,
|
|
15
16
|
} from '../lib/color-utils';
|
|
16
|
-
import type { ColorValue,
|
|
17
|
+
import type { ColorValue, ColorPickerInputProps } from '../types';
|
|
17
18
|
|
|
18
19
|
const INPUT_NAME = 'ColorPickerInput';
|
|
19
20
|
|
|
@@ -506,7 +507,3 @@ function HsbInput(props: HsbInputProps) {
|
|
|
506
507
|
);
|
|
507
508
|
}
|
|
508
509
|
|
|
509
|
-
function hsvToRgb(hsv: import('../types').HSVColorValue): ColorValue {
|
|
510
|
-
const { hsvToRgb: fn } = require('../lib/color-utils');
|
|
511
|
-
return fn(hsv);
|
|
512
|
-
}
|
|
@@ -19,7 +19,10 @@ export const GalleryImage = memo(function GalleryImage({
|
|
|
19
19
|
onLoad,
|
|
20
20
|
onError,
|
|
21
21
|
onClick,
|
|
22
|
-
|
|
22
|
+
// Accepted but not yet honoured: the fetch is driven by `useImageLoader`'s
|
|
23
|
+
// `Image()`, which has no priority hint to forward. Threading one through is
|
|
24
|
+
// a change to that hook, not to this component.
|
|
25
|
+
priority: _priority = false,
|
|
23
26
|
objectFit = 'cover',
|
|
24
27
|
className,
|
|
25
28
|
}: GalleryImageProps) {
|
|
@@ -126,15 +126,15 @@ export const GridMasonry: Story = {
|
|
|
126
126
|
render: () => (
|
|
127
127
|
<div className="space-y-8 w-[820px]">
|
|
128
128
|
<div>
|
|
129
|
-
<div className="text-xs font-medium text-muted-foreground mb-2">layout="mosaic-5"</div>
|
|
129
|
+
<div className="text-xs font-medium text-muted-foreground mb-2">{'layout="mosaic-5"'}</div>
|
|
130
130
|
<GalleryGrid images={IMAGES} layout="mosaic-5" rounded="lg" gap={2} showMoreBadge />
|
|
131
131
|
</div>
|
|
132
132
|
<div>
|
|
133
|
-
<div className="text-xs font-medium text-muted-foreground mb-2">layout="hero-left"</div>
|
|
133
|
+
<div className="text-xs font-medium text-muted-foreground mb-2">{'layout="hero-left"'}</div>
|
|
134
134
|
<GalleryGrid images={IMAGES.slice(0, 3)} layout="hero-left" rounded="lg" gap={2} />
|
|
135
135
|
</div>
|
|
136
136
|
<div>
|
|
137
|
-
<div className="text-xs font-medium text-muted-foreground mb-2">layout="grid-2x2"</div>
|
|
137
|
+
<div className="text-xs font-medium text-muted-foreground mb-2">{'layout="grid-2x2"'}</div>
|
|
138
138
|
<GalleryGrid images={IMAGES.slice(0, 4)} layout="grid-2x2" rounded="lg" gap={2} />
|
|
139
139
|
</div>
|
|
140
140
|
</div>
|
package/src/lottie/types.ts
CHANGED
|
@@ -133,6 +133,8 @@ export interface LottieAnimationData {
|
|
|
133
133
|
h: number;
|
|
134
134
|
nm: string;
|
|
135
135
|
ddd: number;
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
// Opaque Lottie JSON: this package passes the document straight to the
|
|
137
|
+
// player and never reads inside these.
|
|
138
|
+
assets: unknown[];
|
|
139
|
+
layers: unknown[];
|
|
138
140
|
}
|
package/src/marquee/Marquee.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { cva
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { Slot as SlotPrimitive } from '@radix-ui/react-slot';
|
|
5
5
|
import { useDirection as useDirectionPrimitive } from '@radix-ui/react-direction';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { useComposedRefs } from '@djangocfg/ui-core/lib';
|
|
8
8
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
9
|
-
import type { MarqueeProps, MarqueeContextValue, MarqueeEdgeProps,
|
|
9
|
+
import type { MarqueeProps, MarqueeContextValue, MarqueeEdgeProps, Orientation } from './types';
|
|
10
10
|
|
|
11
11
|
const ROOT_NAME = 'Marquee';
|
|
12
12
|
const CONTENT_NAME = 'MarqueeContent';
|
package/src/qrcode/QRCode.tsx
CHANGED
|
@@ -387,6 +387,10 @@ export function QRCodeDownload(props: QRCodeDownloadProps) {
|
|
|
387
387
|
URL.revokeObjectURL(link.href);
|
|
388
388
|
}
|
|
389
389
|
},
|
|
390
|
+
// The single handler, not the whole rest-props object: `buttonProps` is a
|
|
391
|
+
// new reference every render, so depending on it would rebuild this
|
|
392
|
+
// callback unconditionally.
|
|
393
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
390
394
|
[dataUrl, svgString, filename, format, buttonProps.onClick],
|
|
391
395
|
);
|
|
392
396
|
|