@djangocfg/widget-visual 0.1.1 → 0.1.2

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": "@djangocfg/widget-visual",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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.ts",
56
- "default": "./src/lottie/index.ts"
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.1",
74
+ "@djangocfg/widget-kit": "^0.1.2",
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.542",
82
- "@djangocfg/ui-core": "^2.1.542",
83
+ "@djangocfg/i18n": "^2.1.543",
84
+ "@djangocfg/ui-core": "^2.1.543",
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.542",
89
- "@djangocfg/typescript-config": "^2.1.542",
90
- "@djangocfg/ui-core": "^2.1.542",
90
+ "@djangocfg/i18n": "^2.1.543",
91
+ "@djangocfg/typescript-config": "^2.1.543",
92
+ "@djangocfg/ui-core": "^2.1.543",
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, DivProps, StoreState, ColorValue } from './types';
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
- interface ColorPickerImplProps extends Omit<ColorPickerProps, 'defaultValue' | 'onValueChange' | 'onOpenChange' | 'format' | 'defaultFormat' | 'onFormatChange'> {}
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
- export function ColorPickerArea(props: React.ComponentProps<'div'> & { asChild?: boolean }) {
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, ColorFormat, ColorPickerInputProps } from '../types';
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
- priority = false,
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>
@@ -133,6 +133,8 @@ export interface LottieAnimationData {
133
133
  h: number;
134
134
  nm: string;
135
135
  ddd: number;
136
- assets: any[];
137
- layers: any[];
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
  }
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { cva, type VariantProps } from 'class-variance-authority';
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, Side, Orientation } from './types';
9
+ import type { MarqueeProps, MarqueeContextValue, MarqueeEdgeProps, Orientation } from './types';
10
10
 
11
11
  const ROOT_NAME = 'Marquee';
12
12
  const CONTENT_NAME = 'MarqueeContent';
@@ -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