jy-headless 0.2.29 → 0.2.30

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/cjs/index.js CHANGED
@@ -2,10 +2,18 @@
2
2
 
3
3
  require('react/jsx-runtime');
4
4
  require('react');
5
+ var Input = require('./inputs/Input/Input.js');
6
+ var ImageInput = require('./inputs/ImageInput/ImageInput.js');
5
7
  require('./selectors/Dropdown/Dropdown.js');
6
8
  var useDropdown = require('./hooks/useDropdown.js');
7
9
 
10
+ function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); }
8
11
 
12
+ var Input__namespace = /*#__PURE__*/_interopNamespaceDefaultOnly(Input);
9
13
 
14
+
15
+
16
+ exports.Input = Input__namespace;
17
+ exports.ImageInputContext = ImageInput.ImageInputContext;
10
18
  exports.DropdownContext = useDropdown.DropdownContext;
11
19
  exports.useDropdownContext = useDropdown.useDropdownContext;
@@ -0,0 +1,7 @@
1
+ import { ImageAttribute, ImageInputContextData, ImageInputProps, LabelAttribute } from '../../types';
2
+ export declare const ImageInputContext: import("react").Context<ImageInputContextData | null>;
3
+ declare const ImageInput: (({ accepts, id, value, draggable, onChange, children, ...props }: ImageInputProps) => import("react/jsx-runtime").JSX.Element) & {
4
+ Preview: ({ src: defaultSrc, ...props }: ImageAttribute) => import("react/jsx-runtime").JSX.Element;
5
+ Uploader: ({ children, ...props }: LabelAttribute) => import("react/jsx-runtime").JSX.Element;
6
+ };
7
+ export default ImageInput;
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+
6
+ const ImageInputContext = react.createContext(null);
7
+ const getAccepts = (accepts) => {
8
+ return accepts && accepts.length > 0 ? accepts.map((it) => `image/${it}`).join() : 'image/*';
9
+ };
10
+ const ImageInputRoot = ({ accepts, id, value, draggable = false, onChange, children, ...props }) => {
11
+ const [previewUrl, setPreviewUrl] = react.useState('');
12
+ const [dragOver, setDragOver] = react.useState(false);
13
+ const inputId = [id, 'image-input'].join('-');
14
+ react.useEffect(() => {
15
+ if (!value)
16
+ setPreviewUrl('');
17
+ }, [value]);
18
+ const setImagePreview = (file) => {
19
+ const reader = new FileReader();
20
+ reader.onload = (e) => {
21
+ setPreviewUrl(e.target.result);
22
+ };
23
+ reader.readAsDataURL(file);
24
+ };
25
+ const onImageChange = (e) => {
26
+ const file = e.target.files?.[0];
27
+ if (!file)
28
+ return;
29
+ setImagePreview(file);
30
+ onChange?.(file);
31
+ };
32
+ const onDrop = (e) => {
33
+ if (!draggable)
34
+ return;
35
+ e.preventDefault();
36
+ setDragOver(false);
37
+ const file = e.dataTransfer.files?.[0];
38
+ if (file && file.type.startsWith('image/')) {
39
+ setImagePreview(file);
40
+ onChange?.(file);
41
+ }
42
+ };
43
+ const onDragOver = (e) => {
44
+ if (!draggable)
45
+ return;
46
+ e.preventDefault();
47
+ setDragOver(true);
48
+ };
49
+ const onDragLeave = () => setDragOver(false);
50
+ return (jsxRuntime.jsxs("span", { ...props, onDrop: onDrop, onDragOver: onDragOver, onDragEnter: onDragOver, onDragLeave: onDragLeave, children: [jsxRuntime.jsx("input", { "data-testid": inputId, id: inputId, type: 'file', accept: getAccepts(accepts ?? []), onChange: onImageChange, style: { display: 'none' } }), jsxRuntime.jsx(ImageInputContext.Provider, { value: { id: inputId, previewUrl, dragOver }, children: children })] }));
51
+ };
52
+ const ImageInputUploader = ({ children, ...props }) => {
53
+ const context = react.useContext(ImageInputContext);
54
+ if (!context) {
55
+ throw new Error('ImageInput.* 컴포넌트는 ImageInput 내에서만 사용해야 합니다.');
56
+ }
57
+ const { id } = context;
58
+ return (jsxRuntime.jsx("label", { htmlFor: id ?? '', ...props, children: children }));
59
+ };
60
+ const ImageInputPreview = ({ src: defaultSrc, ...props }) => {
61
+ const context = react.useContext(ImageInputContext);
62
+ if (!context) {
63
+ throw new Error('ImageInput.* 컴포넌트는 ImageInput 내에서만 사용해야 합니다.');
64
+ }
65
+ const { previewUrl } = context;
66
+ return jsxRuntime.jsx("img", { ...props, src: previewUrl ?? defaultSrc ?? '' });
67
+ };
68
+ Object.assign(ImageInputRoot, {
69
+ Preview: ImageInputPreview,
70
+ Uploader: ImageInputUploader,
71
+ });
72
+
73
+ exports.ImageInputContext = ImageInputContext;
@@ -1 +1,2 @@
1
- export { default } from './Input/Input';
1
+ export * as Input from './Input/Input';
2
+ export * from './ImageInput/ImageInput';
@@ -1,7 +1,11 @@
1
- import { HTMLAttributes } from 'react';
1
+ import { HTMLAttributes, ImgHTMLAttributes } from 'react';
2
2
  export interface DivAttribute<T> extends HTMLAttributes<HTMLDivElement> {
3
3
  value?: T;
4
4
  }
5
5
  export interface SpanAttribute<T> extends HTMLAttributes<HTMLSpanElement> {
6
6
  value?: T;
7
7
  }
8
+ export interface LabelAttribute extends HTMLAttributes<HTMLLabelElement> {
9
+ }
10
+ export interface ImageAttribute extends ImgHTMLAttributes<HTMLImageElement> {
11
+ }
@@ -7,3 +7,15 @@ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
7
7
  useThrottle?: boolean;
8
8
  timeout?: number;
9
9
  }
10
+ export interface ImageInputContextData {
11
+ id?: string;
12
+ previewUrl?: string;
13
+ dragOver?: boolean;
14
+ }
15
+ export type ImageType = 'jpeg' | 'png' | 'gif' | 'svg' | 'bmp' | 'webp' | 'heic' | 'heif' | 'tiff' | 'x-icon' | 'vn';
16
+ export interface ImageInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
17
+ accepts?: ImageType[];
18
+ draggable?: boolean;
19
+ onChange?: (file: File) => void;
20
+ value?: File;
21
+ }
package/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  import 'react/jsx-runtime';
2
2
  import 'react';
3
+ import * as Input from './inputs/Input/Input.js';
4
+ export { Input };
5
+ export { ImageInputContext } from './inputs/ImageInput/ImageInput.js';
3
6
  import './selectors/Dropdown/Dropdown.js';
4
7
  export { DropdownContext, useDropdownContext } from './hooks/useDropdown.js';
@@ -0,0 +1,7 @@
1
+ import { ImageAttribute, ImageInputContextData, ImageInputProps, LabelAttribute } from '../../types';
2
+ export declare const ImageInputContext: import("react").Context<ImageInputContextData | null>;
3
+ declare const ImageInput: (({ accepts, id, value, draggable, onChange, children, ...props }: ImageInputProps) => import("react/jsx-runtime").JSX.Element) & {
4
+ Preview: ({ src: defaultSrc, ...props }: ImageAttribute) => import("react/jsx-runtime").JSX.Element;
5
+ Uploader: ({ children, ...props }: LabelAttribute) => import("react/jsx-runtime").JSX.Element;
6
+ };
7
+ export default ImageInput;
@@ -0,0 +1,71 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { createContext, useState, useEffect, useContext } from 'react';
3
+
4
+ const ImageInputContext = createContext(null);
5
+ const getAccepts = (accepts) => {
6
+ return accepts && accepts.length > 0 ? accepts.map((it) => `image/${it}`).join() : 'image/*';
7
+ };
8
+ const ImageInputRoot = ({ accepts, id, value, draggable = false, onChange, children, ...props }) => {
9
+ const [previewUrl, setPreviewUrl] = useState('');
10
+ const [dragOver, setDragOver] = useState(false);
11
+ const inputId = [id, 'image-input'].join('-');
12
+ useEffect(() => {
13
+ if (!value)
14
+ setPreviewUrl('');
15
+ }, [value]);
16
+ const setImagePreview = (file) => {
17
+ const reader = new FileReader();
18
+ reader.onload = (e) => {
19
+ setPreviewUrl(e.target.result);
20
+ };
21
+ reader.readAsDataURL(file);
22
+ };
23
+ const onImageChange = (e) => {
24
+ const file = e.target.files?.[0];
25
+ if (!file)
26
+ return;
27
+ setImagePreview(file);
28
+ onChange?.(file);
29
+ };
30
+ const onDrop = (e) => {
31
+ if (!draggable)
32
+ return;
33
+ e.preventDefault();
34
+ setDragOver(false);
35
+ const file = e.dataTransfer.files?.[0];
36
+ if (file && file.type.startsWith('image/')) {
37
+ setImagePreview(file);
38
+ onChange?.(file);
39
+ }
40
+ };
41
+ const onDragOver = (e) => {
42
+ if (!draggable)
43
+ return;
44
+ e.preventDefault();
45
+ setDragOver(true);
46
+ };
47
+ const onDragLeave = () => setDragOver(false);
48
+ return (jsxs("span", { ...props, onDrop: onDrop, onDragOver: onDragOver, onDragEnter: onDragOver, onDragLeave: onDragLeave, children: [jsx("input", { "data-testid": inputId, id: inputId, type: 'file', accept: getAccepts(accepts ?? []), onChange: onImageChange, style: { display: 'none' } }), jsx(ImageInputContext.Provider, { value: { id: inputId, previewUrl, dragOver }, children: children })] }));
49
+ };
50
+ const ImageInputUploader = ({ children, ...props }) => {
51
+ const context = useContext(ImageInputContext);
52
+ if (!context) {
53
+ throw new Error('ImageInput.* 컴포넌트는 ImageInput 내에서만 사용해야 합니다.');
54
+ }
55
+ const { id } = context;
56
+ return (jsx("label", { htmlFor: id ?? '', ...props, children: children }));
57
+ };
58
+ const ImageInputPreview = ({ src: defaultSrc, ...props }) => {
59
+ const context = useContext(ImageInputContext);
60
+ if (!context) {
61
+ throw new Error('ImageInput.* 컴포넌트는 ImageInput 내에서만 사용해야 합니다.');
62
+ }
63
+ const { previewUrl } = context;
64
+ return jsx("img", { ...props, src: previewUrl ?? defaultSrc ?? '' });
65
+ };
66
+ Object.assign(ImageInputRoot, {
67
+ Preview: ImageInputPreview,
68
+ Uploader: ImageInputUploader,
69
+ });
70
+
71
+ export { ImageInputContext };
package/inputs/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { default } from './Input/Input';
1
+ export * as Input from './Input/Input';
2
+ export * from './ImageInput/ImageInput';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jy-headless",
3
- "version": "0.2.29",
3
+ "version": "0.2.30",
4
4
  "description": "A lightweight and customizable headless UI library for React components",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/yCZwIqY/jy-headless",
@@ -13,21 +13,11 @@
13
13
  "require": "./cjs/index.js",
14
14
  "types": "./index.d.ts"
15
15
  },
16
- "./Button": {
17
- "import": "./cjs/buttons/Button/Button.js",
18
- "require": "./cjs/cjs/buttons/Button/Button.js",
19
- "types": "./cjs/buttons/Button/Button.d.ts"
20
- },
21
16
  "./cjs": {
22
17
  "import": "./cjs/index.js",
23
18
  "require": "./cjs/cjs/index.js",
24
19
  "types": "./cjs/index.d.ts"
25
20
  },
26
- "./useDebouncing": {
27
- "import": "./hooks/useDebouncing.js",
28
- "require": "./cjs/hooks/useDebouncing.js",
29
- "types": "./hooks/useDebouncing.d.ts"
30
- },
31
21
  "./useDropdown": {
32
22
  "import": "./hooks/useDropdown.js",
33
23
  "require": "./cjs/hooks/useDropdown.js",
@@ -43,6 +33,11 @@
43
33
  "require": "./cjs/index.js",
44
34
  "types": "./index.d.ts"
45
35
  },
36
+ "./ImageInput": {
37
+ "import": "./inputs/ImageInput/ImageInput.js",
38
+ "require": "./cjs/inputs/ImageInput/ImageInput.js",
39
+ "types": "./inputs/ImageInput/ImageInput.d.ts"
40
+ },
46
41
  "./Input": {
47
42
  "import": "./inputs/Input/Input.js",
48
43
  "require": "./cjs/inputs/Input/Input.js",
@@ -1,7 +1,11 @@
1
- import { HTMLAttributes } from 'react';
1
+ import { HTMLAttributes, ImgHTMLAttributes } from 'react';
2
2
  export interface DivAttribute<T> extends HTMLAttributes<HTMLDivElement> {
3
3
  value?: T;
4
4
  }
5
5
  export interface SpanAttribute<T> extends HTMLAttributes<HTMLSpanElement> {
6
6
  value?: T;
7
7
  }
8
+ export interface LabelAttribute extends HTMLAttributes<HTMLLabelElement> {
9
+ }
10
+ export interface ImageAttribute extends ImgHTMLAttributes<HTMLImageElement> {
11
+ }
@@ -7,3 +7,15 @@ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
7
7
  useThrottle?: boolean;
8
8
  timeout?: number;
9
9
  }
10
+ export interface ImageInputContextData {
11
+ id?: string;
12
+ previewUrl?: string;
13
+ dragOver?: boolean;
14
+ }
15
+ export type ImageType = 'jpeg' | 'png' | 'gif' | 'svg' | 'bmp' | 'webp' | 'heic' | 'heif' | 'tiff' | 'x-icon' | 'vn';
16
+ export interface ImageInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
17
+ accepts?: ImageType[];
18
+ draggable?: boolean;
19
+ onChange?: (file: File) => void;
20
+ value?: File;
21
+ }
package/version.txt CHANGED
@@ -1 +1 @@
1
- 0.2.29
1
+ 0.2.30
@@ -1,9 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import useDebouncing from '../../hooks/useDebouncing.js';
3
-
4
- const Button = ({ onClick, loading = false, readOnly = false, disabled = false, useDebounce = false, timeout = 300, children, ...props }) => {
5
- const handleClick = onClick && useDebounce ? useDebouncing(onClick, timeout || 300) : onClick;
6
- return (jsx("button", { onClick: handleClick, disabled: disabled || loading || readOnly, ...props, children: children }));
7
- };
8
-
9
- export { Button as default };
@@ -1,11 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var useDebouncing = require('../../hooks/useDebouncing.js');
5
-
6
- const Button = ({ onClick, loading = false, readOnly = false, disabled = false, useDebounce = false, timeout = 300, children, ...props }) => {
7
- const handleClick = onClick && useDebounce ? useDebouncing(onClick, timeout || 300) : onClick;
8
- return (jsxRuntime.jsx("button", { onClick: handleClick, disabled: disabled || loading || readOnly, ...props, children: children }));
9
- };
10
-
11
- module.exports = Button;
@@ -1,16 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
-
5
- const useDebouncing = (callback, delay) => {
6
- const timer = react.useRef(null);
7
- return react.useCallback(() => {
8
- if (timer.current)
9
- clearTimeout(timer.current);
10
- timer.current = setTimeout(() => {
11
- callback();
12
- }, delay);
13
- }, [callback, delay]);
14
- };
15
-
16
- module.exports = useDebouncing;
@@ -1,4 +0,0 @@
1
- declare const DropdownDefaultTrigger: ({ value }: {
2
- value: boolean;
3
- }) => import("react/jsx-runtime").JSX.Element;
4
- export default DropdownDefaultTrigger;
@@ -1,14 +0,0 @@
1
- import { useRef, useCallback } from 'react';
2
-
3
- const useDebouncing = (callback, delay) => {
4
- const timer = useRef(null);
5
- return useCallback(() => {
6
- if (timer.current)
7
- clearTimeout(timer.current);
8
- timer.current = setTimeout(() => {
9
- callback();
10
- }, delay);
11
- }, [callback, delay]);
12
- };
13
-
14
- export { useDebouncing as default };
@@ -1,4 +0,0 @@
1
- declare const DropdownDefaultTrigger: ({ value }: {
2
- value: boolean;
3
- }) => import("react/jsx-runtime").JSX.Element;
4
- export default DropdownDefaultTrigger;