@uibit/image-reveal 0.1.1 → 0.2.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![NPM Version](https://img.shields.io/npm/v/@uibit/image-reveal.svg?style=flat-square&color=black)](https://www.npmjs.com/package/@uibit/image-reveal)
4
4
 
5
5
 
6
- [Interactive Demonstration](https://rawlings.github.io/uibit/image-xray)
6
+ [Interactive Demonstration](https://rawlings.github.io/uibit/components/image-reveal)
7
7
 
8
8
  ## Installation
9
9
 
@@ -1,32 +1,32 @@
1
1
  import { Component, ChangeDetectionStrategy, ElementRef, input, effect, output } from '@angular/core';
2
2
  import '@uibit/image-reveal';
3
3
  import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
4
-
5
4
  @Component({
6
- selector: 'uibit-image-reveal',
7
- template: '<ng-content></ng-content>',
8
- changeDetection: ChangeDetectionStrategy.OnPush,
9
- standalone: true,
10
- host: {
11
- '(reveal-move)': 'revealMove.emit($event)'
12
- }
5
+ selector: 'uibit-image-reveal',
6
+ template: '<ng-content></ng-content>',
7
+ changeDetection: ChangeDetectionStrategy.OnPush,
8
+ standalone: true,
9
+ host: {
10
+ '(reveal-move)': 'revealMove.emit($event)'
11
+ }
13
12
  })
14
13
  export class NgxImageReveal {
15
- constructor(private el: ElementRef<HTMLElementClass>) {
16
- effect(() => {
17
- if (this.el.nativeElement) {
18
- this.el.nativeElement.size = this.size();
19
- }
20
- });
21
- effect(() => {
22
- if (this.el.nativeElement) {
23
- this.el.nativeElement.locale = this.locale();
24
- }
25
- });
26
- }
27
-
28
- readonly size = input<string, any>('');
29
- readonly locale = input<string, any>('');
30
-
31
- readonly revealMove = output<CustomEvent<{ x: number, y: number }>>();
14
+ constructor(private el: ElementRef<HTMLElementClass>){
15
+ effect(()=>{
16
+ if (this.el.nativeElement) {
17
+ this.el.nativeElement.size = this.size();
18
+ }
19
+ });
20
+ effect(()=>{
21
+ if (this.el.nativeElement) {
22
+ this.el.nativeElement.locale = this.locale();
23
+ }
24
+ });
25
+ }
26
+ readonly size = input<string>('');
27
+ readonly locale = input<string>('');
28
+ readonly revealMove = output<CustomEvent<{
29
+ x: number;
30
+ y: number;
31
+ }>>();
32
32
  }
@@ -4,7 +4,11 @@ import '@uibit/image-reveal';
4
4
  declare global {
5
5
  namespace astroHTML.JSX {
6
6
  interface IntrinsicElements {
7
- 'uibit-image-reveal': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes;
7
+ 'uibit-image-reveal': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes & {
8
+ size?: string;
9
+ locale?: string;
10
+ "on:reveal-move"?: (event: CustomEvent<{ x: number, y: number }>) => void;
11
+ };
8
12
  }
9
13
  }
10
14
  }
@@ -8,6 +8,8 @@ declare module 'preact' {
8
8
  'uibit-image-reveal': JSX.HTMLAttributes<HTMLElementClass> & {
9
9
  size?: string;
10
10
  locale?: string;
11
+ onRevealMove?: (event: CustomEvent<{ x: number, y: number }>) => void;
12
+ "on:reveal-move"?: (event: CustomEvent<{ x: number, y: number }>) => void;
11
13
  };
12
14
  }
13
15
  }
@@ -0,0 +1,83 @@
1
+ import React, { useRef, useEffect, useLayoutEffect, useImperativeHandle } from 'react';
2
+ import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
3
+ import '@uibit/image-reveal';
4
+ const useTypeOfLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
5
+ export interface ImageRevealProps extends Omit<React.HTMLAttributes<HTMLElementClass>, 'size' | 'locale' | 'onRevealMove'> {
6
+ children?: React.ReactNode;
7
+ size?: string;
8
+ locale?: string;
9
+ onRevealMove?: (event: CustomEvent<{
10
+ x: number;
11
+ y: number;
12
+ }>) => void;
13
+ }
14
+ export const ImageReveal = ({ ref, children, ...props }: ImageRevealProps & {
15
+ ref?: React.Ref<HTMLElementClass>;
16
+ })=>{
17
+ const innerRef = useRef<HTMLElementClass>(null);
18
+ const propsRef = useRef(props);
19
+ propsRef.current = props;
20
+ useImperativeHandle(ref, ()=>innerRef.current!);
21
+ useTypeOfLayoutEffect(()=>{
22
+ const element = innerRef.current;
23
+ if (element && props.size !== undefined) {
24
+ (element as any).size = props.size;
25
+ }
26
+ }, [
27
+ props.size
28
+ ]);
29
+ useTypeOfLayoutEffect(()=>{
30
+ const element = innerRef.current;
31
+ if (element && props.locale !== undefined) {
32
+ (element as any).locale = props.locale;
33
+ }
34
+ }, [
35
+ props.locale
36
+ ]);
37
+ useTypeOfLayoutEffect(()=>{
38
+ const element = innerRef.current;
39
+ if (!element) return;
40
+ const handleEvent = (event: Event)=>{
41
+ if (propsRef.current.onRevealMove) {
42
+ propsRef.current.onRevealMove(event as any);
43
+ }
44
+ };
45
+ element.addEventListener('reveal-move', handleEvent);
46
+ return ()=>{
47
+ element.removeEventListener('reveal-move', handleEvent);
48
+ };
49
+ }, []);
50
+ const domProps = {
51
+ ...props
52
+ };
53
+ const customPropNames = [
54
+ 'size',
55
+ 'locale',
56
+ 'onRevealMove'
57
+ ];
58
+ for (const key of customPropNames){
59
+ delete (domProps as any)[key];
60
+ }
61
+ return React.createElement('uibit-image-reveal', {
62
+ ref: innerRef,
63
+ ...domProps
64
+ }, children);
65
+ };
66
+ declare global {
67
+ namespace React {
68
+ namespace JSX {
69
+ interface IntrinsicElements {
70
+ 'uibit-image-reveal': React.ClassAttributes<HTMLElementClass> & React.HTMLAttributes<HTMLElementClass> & {
71
+ children?: React.ReactNode;
72
+ class?: string;
73
+ size?: string;
74
+ locale?: string;
75
+ onRevealMove?: (event: CustomEvent<{
76
+ x: number;
77
+ y: number;
78
+ }>) => void;
79
+ };
80
+ }
81
+ }
82
+ }
83
+ }
@@ -8,7 +8,7 @@ declare module 'solid-js' {
8
8
  'uibit-image-reveal': Partial<HTMLElementClass> & JSX.HTMLAttributes<HTMLElementClass> & {
9
9
  size?: string;
10
10
  locale?: string;
11
- "on:reveal-move"?: (event: CustomEvent) => void;
11
+ "on:reveal-move"?: (event: CustomEvent<{ x: number, y: number }>) => void;
12
12
  };
13
13
  }
14
14
  }
@@ -7,6 +7,8 @@ declare module '@stencil/core' {
7
7
  'uibit-image-reveal': HTMLElementClass & {
8
8
  size?: string;
9
9
  locale?: string;
10
+ onRevealMove?: (event: CustomEvent<{ x: number, y: number }>) => void;
11
+ "on:reveal-move"?: (event: CustomEvent<{ x: number, y: number }>) => void;
10
12
  };
11
13
  }
12
14
  }
@@ -1,33 +1,59 @@
1
1
  <script lang="ts">
2
2
  import '@uibit/image-reveal';
3
3
  import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
4
-
5
- let {
6
- size = undefined,
7
- locale = undefined,
8
- xray = undefined,
9
- children
4
+
5
+ let {
6
+ size = $bindable(),
7
+ locale = $bindable(),
8
+ xray = undefined,
9
+ children,
10
+ ...restProps
10
11
  } = $props<{
11
- children?: any;
12
+ children?: import('svelte').Snippet;
12
13
  size?: string;
13
14
  locale?: string;
14
15
  xray?: import('svelte').Snippet;
16
+ [key: string]: any;
15
17
  }>();
16
-
17
- let elementRef: HTMLElementClass | null = $state(null);
18
-
19
- $effect(() => {
20
- if (elementRef && size !== undefined) {
18
+
19
+ let elementRef: HTMLElementClass | null = $state(null);
20
+
21
+ $effect(() => {
22
+ if (elementRef && size !== undefined && elementRef.size !== size) {
21
23
  elementRef.size = size;
22
24
  }
23
- if (elementRef && locale !== undefined) {
25
+ if (elementRef && locale !== undefined && elementRef.locale !== locale) {
24
26
  elementRef.locale = locale;
25
27
  }
26
28
  });
27
-
29
+
30
+ $effect(() => {
31
+ const element = elementRef;
32
+ if (!element) return;
33
+
34
+ const handleEvent = () => {
35
+ if (size !== element.size) {
36
+ size = element.size as any;
37
+ }
38
+ if (locale !== element.locale) {
39
+ locale = element.locale as any;
40
+ }
41
+ };
42
+
43
+ const events = ['change', 'input', 'reveal-move'];
44
+ for (const event of events) {
45
+ element.addEventListener(event, handleEvent);
46
+ }
47
+ return () => {
48
+ for (const event of events) {
49
+ element.removeEventListener(event, handleEvent);
50
+ }
51
+ };
52
+ });
53
+
28
54
  </script>
29
55
 
30
- <uibit-image-reveal bind:this={elementRef} {...$$restProps}>
56
+ <uibit-image-reveal bind:this={elementRef} {...restProps}>
31
57
  {#if xray}
32
58
  <div slot="xray">
33
59
  {@render xray()}
@@ -1,25 +1,69 @@
1
- import { defineComponent, h } from 'vue';
1
+ import { defineComponent, h, ref, watch } from 'vue';
2
2
  import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
3
3
  import '@uibit/image-reveal';
4
-
5
4
  export const ImageReveal = defineComponent({
6
- name: 'ImageReveal',
7
- props: {
8
- size: { type: [String, Number, Boolean, Array, Object] as any },
9
- locale: { type: [String, Number, Boolean, Array, Object] as any }
10
- },
11
- emits: ['reveal-move'],
12
- setup(props, { slots, emit }) {
13
- return () => {
14
- const eventListeners: Record<string, any> = {};
15
- eventListeners['onReveal-move'] = (event: Event) => {
16
- emit('reveal-move', event);
17
- };
18
-
19
- return h('uibit-image-reveal', {
20
- ...props,
21
- ...eventListeners
22
- }, slots.default?.());
23
- };
24
- }
5
+ name: 'ImageReveal',
6
+ props: {
7
+ size: {
8
+ type: [
9
+ String,
10
+ Number,
11
+ Boolean,
12
+ Array,
13
+ Object
14
+ ] as any
15
+ },
16
+ locale: {
17
+ type: [
18
+ String,
19
+ Number,
20
+ Boolean,
21
+ Array,
22
+ Object
23
+ ] as any
24
+ }
25
+ },
26
+ emits: [
27
+ 'reveal-move'
28
+ ],
29
+ setup (props, { slots, emit }) {
30
+ const elementRef = ref<HTMLElementClass | null>(null);
31
+ if (false) {
32
+ watch(()=>props.modelValue, (newVal)=>{
33
+ if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
34
+ elementRef.value.value = newVal;
35
+ }
36
+ });
37
+ watch(()=>props.value, (newVal)=>{
38
+ if (elementRef.value && newVal !== undefined && elementRef.value.value !== newVal) {
39
+ elementRef.value.value = newVal;
40
+ }
41
+ });
42
+ }
43
+ watch(()=>props.size, (newVal)=>{
44
+ if (elementRef.value && newVal !== undefined) {
45
+ (elementRef.value as any).size = newVal;
46
+ }
47
+ });
48
+ watch(()=>props.locale, (newVal)=>{
49
+ if (elementRef.value && newVal !== undefined) {
50
+ (elementRef.value as any).locale = newVal;
51
+ }
52
+ });
53
+ return ()=>{
54
+ const eventListeners: Record<string, any> = {};
55
+ eventListeners['onReveal-move'] = (event: Event)=>{
56
+ emit('reveal-move', event);
57
+ };
58
+ const mergedProps = {
59
+ ...props,
60
+ ...eventListeners,
61
+ ref: elementRef
62
+ };
63
+ if (false && props.modelValue !== undefined) {
64
+ (mergedProps as any).value = props.modelValue;
65
+ }
66
+ return h('uibit-image-reveal', mergedProps, slots.default?.());
67
+ };
68
+ }
25
69
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uibit/image-reveal",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "A floating circular lens that follows the cursor or touch point, revealing a synchronized secondary image exactly where the user looks. Built for luxury and high-tech product storytelling.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -11,7 +11,7 @@
11
11
  "import": "./dist/index.js"
12
12
  },
13
13
  "./custom-elements.json": "./custom-elements.json",
14
- "./react": "./dist/frameworks/react/index.d.ts",
14
+ "./react": "./dist/frameworks/react/index.ts",
15
15
  "./vue": "./dist/frameworks/vue/index.ts",
16
16
  "./svelte": "./dist/frameworks/svelte/index.svelte",
17
17
  "./angular": "./dist/frameworks/angular/index.ts",
@@ -52,7 +52,7 @@
52
52
  "@types/node": "^20.19.43",
53
53
  "lit": "^3.3.3",
54
54
  "typescript": "7.0.2",
55
- "@uibit/codegen": "0.1.0"
55
+ "@uibit/codegen": "0.2.0"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "lit": "^3.0.0",
@@ -1,19 +0,0 @@
1
- import type { HTMLAttributes, ClassAttributes } from 'react';
2
- import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
3
- import '@uibit/image-reveal';
4
-
5
- declare global {
6
- namespace React {
7
- namespace JSX {
8
- interface IntrinsicElements {
9
- 'uibit-image-reveal': ClassAttributes<HTMLElementClass> & HTMLAttributes<HTMLElementClass> & {
10
- children?: React.ReactNode;
11
- class?: string;
12
- size?: string;
13
- locale?: string;
14
- onRevealMove?: (event: any) => void;
15
- };
16
- }
17
- }
18
- }
19
- }