jy-headless 0.2.27 → 0.2.29

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.
@@ -1,2 +1,3 @@
1
1
  export * from './useDebouncing';
2
2
  export * from './useThrottling';
3
+ export * from './useDropdown';
@@ -0,0 +1,10 @@
1
+ import { DropdownContextValue } from '../types';
2
+ export declare const DropdownContext: import("react").Context<DropdownContextValue<any> | null>;
3
+ declare const useDropdown: <T>(defaultValue?: T | null) => {
4
+ isOpen: boolean;
5
+ selected: T | null;
6
+ toggle: () => void;
7
+ select: (value: T) => void;
8
+ };
9
+ export declare const useDropdownContext: <T>() => DropdownContextValue<T>;
10
+ export default useDropdown;
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var react = require('react');
6
+
7
+ const DropdownContext = react.createContext(null);
8
+ const useDropdown = (defaultValue = null) => {
9
+ const [isOpen, setIsOpen] = react.useState(false);
10
+ const [selected, setSelected] = react.useState(defaultValue);
11
+ const toggle = () => setIsOpen((prev) => !prev);
12
+ const select = (value) => {
13
+ setSelected(value);
14
+ setIsOpen(false);
15
+ };
16
+ return {
17
+ isOpen,
18
+ selected,
19
+ toggle,
20
+ select,
21
+ };
22
+ };
23
+ const useDropdownContext = () => {
24
+ const context = react.useContext(DropdownContext);
25
+ if (!context)
26
+ throw new Error('Dropdown components must be used within <Dropdown>');
27
+ return context;
28
+ };
29
+
30
+ exports.DropdownContext = DropdownContext;
31
+ exports.default = useDropdown;
32
+ exports.useDropdownContext = useDropdownContext;
package/cjs/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { default as Button } from './buttons';
2
- export { default as Input } from './inputs';
1
+ export * from './buttons';
2
+ export * from './inputs';
3
+ export * from './selectors';
3
4
  export * from './types';
4
5
  export * from './utils';
5
6
  export * from './hooks';
package/cjs/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var Button = require('./buttons/Button/Button.js');
4
- var Input = require('./inputs/Input/Input.js');
3
+ require('react/jsx-runtime');
5
4
  require('react');
5
+ require('./selectors/Dropdown/Dropdown.js');
6
+ var useDropdown = require('./hooks/useDropdown.js');
6
7
 
7
8
 
8
9
 
9
- exports.Button = Button;
10
- exports.Input = Input;
10
+ exports.DropdownContext = useDropdown.DropdownContext;
11
+ exports.useDropdownContext = useDropdown.useDropdownContext;
@@ -5,7 +5,7 @@ var useThrottling = require('../../hooks/useThrottling.js');
5
5
 
6
6
  const Input = ({ id, suffixElement, prefixElement, wrapperStyle, wrapperClass = [], onChange, timeout = 300, useThrottle = false, children, ...props }) => {
7
7
  const handleChange = onChange && useThrottle ? useThrottling(onChange, timeout) : onChange;
8
- return (jsxRuntime.jsxs("span", { "data-testid": 'input-wrapper', id: [id, 'input-wrapper'].join('-'), className: wrapperClass?.join(' '), style: wrapperStyle, children: [prefixElement, jsxRuntime.jsx("input", { id: id, onChange: handleChange, ...props }), suffixElement] }));
8
+ return (jsxRuntime.jsxs("span", { "data-testid": 'input-wrapper', id: [id, 'input-wrapper'].join('-'), className: wrapperClass?.join(' '), style: wrapperStyle, children: [prefixElement, jsxRuntime.jsx("input", { role: 'textbox', id: id, onChange: handleChange, ...props }), suffixElement] }));
9
9
  };
10
10
 
11
11
  module.exports = Input;
@@ -0,0 +1,8 @@
1
+ import { DivAttribute, DropdownProps, SpanAttribute } from '../../types';
2
+ declare const Dropdown: (<T>({ select, selected, isOpen, toggle, children, ...props }: DropdownProps<T>) => import("react/jsx-runtime").JSX.Element) & {
3
+ Button: <T>({ onClick, children, ...props }: SpanAttribute<T>) => import("react/jsx-runtime").JSX.Element;
4
+ Options: <T>({ children, ...props }: DivAttribute<T>) => import("react/jsx-runtime").JSX.Element | null;
5
+ Option: <T>({ children, value, ...props }: DivAttribute<T>) => import("react/jsx-runtime").JSX.Element;
6
+ Viewer: ({ children, ...props }: SpanAttribute<null>) => import("react/jsx-runtime").JSX.Element;
7
+ };
8
+ export default Dropdown;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var useDropdown = require('../../hooks/useDropdown.js');
6
+
7
+ const DropdownRoot = ({ select, selected, isOpen, toggle, children, ...props }) => {
8
+ const dropdownRef = react.useRef(null);
9
+ const unControlled = useDropdown.default();
10
+ const customValue = {
11
+ isOpen: isOpen ?? unControlled.isOpen,
12
+ toggle: toggle ?? unControlled.toggle,
13
+ select: select ?? unControlled.select,
14
+ selected: selected ?? unControlled.selected,
15
+ };
16
+ react.useEffect(() => {
17
+ if (!dropdownRef.current)
18
+ return;
19
+ const onClickOutside = (e) => {
20
+ if (!dropdownRef.current?.contains(e.target)) {
21
+ if (isOpen && toggle) {
22
+ toggle();
23
+ }
24
+ }
25
+ };
26
+ window.addEventListener('click', onClickOutside);
27
+ return () => window.removeEventListener('click', onClickOutside);
28
+ }, [customValue]);
29
+ return (jsxRuntime.jsx("div", { ...props, ref: dropdownRef, children: jsxRuntime.jsx(useDropdown.DropdownContext.Provider, { value: customValue, children: children }) }));
30
+ };
31
+ const DropdownViewer = ({ children, ...props }) => {
32
+ return (jsxRuntime.jsx("span", { role: 'viewer', ...props, children: children }));
33
+ };
34
+ const DropdownButton = ({ onClick, children, ...props }) => {
35
+ const { toggle } = useDropdown.useDropdownContext();
36
+ return (jsxRuntime.jsx("span", { ...props, onClick: toggle, children: children }));
37
+ };
38
+ const DropdownOptions = ({ children, ...props }) => {
39
+ const { isOpen } = useDropdown.useDropdownContext();
40
+ if (!isOpen)
41
+ return null;
42
+ return jsxRuntime.jsx("div", { ...props, children: children });
43
+ };
44
+ const DropdownOption = ({ children, value, ...props }) => {
45
+ const { select } = useDropdown.useDropdownContext();
46
+ return (jsxRuntime.jsx("div", { role: "option", onClick: () => select(value), ...props, children: children }));
47
+ };
48
+ Object.assign(DropdownRoot, {
49
+ Button: DropdownButton,
50
+ Options: DropdownOptions,
51
+ Option: DropdownOption,
52
+ Viewer: DropdownViewer,
53
+ });
@@ -0,0 +1,4 @@
1
+ declare const DropdownDefaultTrigger: ({ value }: {
2
+ value: boolean;
3
+ }) => import("react/jsx-runtime").JSX.Element;
4
+ export default DropdownDefaultTrigger;
@@ -0,0 +1 @@
1
+ export { default } from './Dropdown/Dropdown';
@@ -0,0 +1,7 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface DivAttribute<T> extends HTMLAttributes<HTMLDivElement> {
3
+ value?: T;
4
+ }
5
+ export interface SpanAttribute<T> extends HTMLAttributes<HTMLSpanElement> {
6
+ value?: T;
7
+ }
@@ -1,2 +1,4 @@
1
1
  export * from './buttons';
2
2
  export * from './inputs';
3
+ export * from './selectors';
4
+ export * from './common';
@@ -0,0 +1,16 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface DropdownContextValue<T> {
3
+ isOpen: boolean;
4
+ toggle: () => void;
5
+ select: (value: T) => void;
6
+ selected: T | null;
7
+ }
8
+ export interface DropdownProps<T> extends HTMLAttributes<HTMLElement> {
9
+ isOpen?: boolean;
10
+ toggle?: () => void;
11
+ select?: (value: T) => void;
12
+ selected?: T | null;
13
+ }
14
+ export interface UseDropdownProps<T> {
15
+ defaultValue?: T;
16
+ }
package/hooks/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './useDebouncing';
2
2
  export * from './useThrottling';
3
+ export * from './useDropdown';
@@ -0,0 +1,10 @@
1
+ import { DropdownContextValue } from '../types';
2
+ export declare const DropdownContext: import("react").Context<DropdownContextValue<any> | null>;
3
+ declare const useDropdown: <T>(defaultValue?: T | null) => {
4
+ isOpen: boolean;
5
+ selected: T | null;
6
+ toggle: () => void;
7
+ select: (value: T) => void;
8
+ };
9
+ export declare const useDropdownContext: <T>() => DropdownContextValue<T>;
10
+ export default useDropdown;
@@ -0,0 +1,26 @@
1
+ import { createContext, useContext, useState } from 'react';
2
+
3
+ const DropdownContext = createContext(null);
4
+ const useDropdown = (defaultValue = null) => {
5
+ const [isOpen, setIsOpen] = useState(false);
6
+ const [selected, setSelected] = useState(defaultValue);
7
+ const toggle = () => setIsOpen((prev) => !prev);
8
+ const select = (value) => {
9
+ setSelected(value);
10
+ setIsOpen(false);
11
+ };
12
+ return {
13
+ isOpen,
14
+ selected,
15
+ toggle,
16
+ select,
17
+ };
18
+ };
19
+ const useDropdownContext = () => {
20
+ const context = useContext(DropdownContext);
21
+ if (!context)
22
+ throw new Error('Dropdown components must be used within <Dropdown>');
23
+ return context;
24
+ };
25
+
26
+ export { DropdownContext, useDropdown as default, useDropdownContext };
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { default as Button } from './buttons';
2
- export { default as Input } from './inputs';
1
+ export * from './buttons';
2
+ export * from './inputs';
3
+ export * from './selectors';
3
4
  export * from './types';
4
5
  export * from './utils';
5
6
  export * from './hooks';
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export { default as Button } from './buttons/Button/Button.js';
2
- export { default as Input } from './inputs/Input/Input.js';
1
+ import 'react/jsx-runtime';
3
2
  import 'react';
3
+ import './selectors/Dropdown/Dropdown.js';
4
+ export { DropdownContext, useDropdownContext } from './hooks/useDropdown.js';
@@ -3,7 +3,7 @@ import useThrottling from '../../hooks/useThrottling.js';
3
3
 
4
4
  const Input = ({ id, suffixElement, prefixElement, wrapperStyle, wrapperClass = [], onChange, timeout = 300, useThrottle = false, children, ...props }) => {
5
5
  const handleChange = onChange && useThrottle ? useThrottling(onChange, timeout) : onChange;
6
- return (jsxs("span", { "data-testid": 'input-wrapper', id: [id, 'input-wrapper'].join('-'), className: wrapperClass?.join(' '), style: wrapperStyle, children: [prefixElement, jsx("input", { id: id, onChange: handleChange, ...props }), suffixElement] }));
6
+ return (jsxs("span", { "data-testid": 'input-wrapper', id: [id, 'input-wrapper'].join('-'), className: wrapperClass?.join(' '), style: wrapperStyle, children: [prefixElement, jsx("input", { role: 'textbox', id: id, onChange: handleChange, ...props }), suffixElement] }));
7
7
  };
8
8
 
9
9
  export { Input as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jy-headless",
3
- "version": "0.2.27",
3
+ "version": "0.2.29",
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",
@@ -28,45 +28,30 @@
28
28
  "require": "./cjs/hooks/useDebouncing.js",
29
29
  "types": "./hooks/useDebouncing.d.ts"
30
30
  },
31
+ "./useDropdown": {
32
+ "import": "./hooks/useDropdown.js",
33
+ "require": "./cjs/hooks/useDropdown.js",
34
+ "types": "./hooks/useDropdown.d.ts"
35
+ },
31
36
  "./useThrottling": {
32
37
  "import": "./hooks/useThrottling.js",
33
38
  "require": "./cjs/hooks/useThrottling.js",
34
39
  "types": "./hooks/useThrottling.d.ts"
35
40
  },
36
41
  "./index": {
37
- "import": "./utils/index.js",
38
- "require": "./cjs/utils/index.js",
39
- "types": "./utils/index.d.ts"
42
+ "import": "./index.js",
43
+ "require": "./cjs/index.js",
44
+ "types": "./index.d.ts"
40
45
  },
41
46
  "./Input": {
42
47
  "import": "./inputs/Input/Input.js",
43
48
  "require": "./cjs/inputs/Input/Input.js",
44
49
  "types": "./inputs/Input/Input.d.ts"
45
50
  },
46
- "./cjs/types": {
47
- "import": "./cjs/types/index.js",
48
- "require": "./cjs/cjs/types/index.js",
49
- "types": "./cjs/types/index.d.ts"
50
- },
51
- "./cjs/utils": {
52
- "import": "./cjs/utils/index.js",
53
- "require": "./cjs/cjs/utils/index.js",
54
- "types": "./cjs/utils/index.d.ts"
55
- },
56
- "./ArrayUtils": {
57
- "import": "./utils/ArrayUtils.js",
58
- "require": "./cjs/utils/ArrayUtils.js",
59
- "types": "./utils/ArrayUtils.d.ts"
60
- },
61
- "./types": {
62
- "import": "./types/index.js",
63
- "require": "./cjs/types/index.js",
64
- "types": "./types/index.d.ts"
65
- },
66
- "./utils": {
67
- "import": "./utils/index.js",
68
- "require": "./cjs/utils/index.js",
69
- "types": "./utils/index.d.ts"
51
+ "./Dropdown": {
52
+ "import": "./selectors/Dropdown/Dropdown.js",
53
+ "require": "./cjs/selectors/Dropdown/Dropdown.js",
54
+ "types": "./selectors/Dropdown/Dropdown.d.ts"
70
55
  }
71
56
  },
72
57
  "keywords": [
@@ -0,0 +1,8 @@
1
+ import { DivAttribute, DropdownProps, SpanAttribute } from '../../types';
2
+ declare const Dropdown: (<T>({ select, selected, isOpen, toggle, children, ...props }: DropdownProps<T>) => import("react/jsx-runtime").JSX.Element) & {
3
+ Button: <T>({ onClick, children, ...props }: SpanAttribute<T>) => import("react/jsx-runtime").JSX.Element;
4
+ Options: <T>({ children, ...props }: DivAttribute<T>) => import("react/jsx-runtime").JSX.Element | null;
5
+ Option: <T>({ children, value, ...props }: DivAttribute<T>) => import("react/jsx-runtime").JSX.Element;
6
+ Viewer: ({ children, ...props }: SpanAttribute<null>) => import("react/jsx-runtime").JSX.Element;
7
+ };
8
+ export default Dropdown;
@@ -0,0 +1,51 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useRef, useEffect } from 'react';
3
+ import useDropdown, { DropdownContext, useDropdownContext } from '../../hooks/useDropdown.js';
4
+
5
+ const DropdownRoot = ({ select, selected, isOpen, toggle, children, ...props }) => {
6
+ const dropdownRef = useRef(null);
7
+ const unControlled = useDropdown();
8
+ const customValue = {
9
+ isOpen: isOpen ?? unControlled.isOpen,
10
+ toggle: toggle ?? unControlled.toggle,
11
+ select: select ?? unControlled.select,
12
+ selected: selected ?? unControlled.selected,
13
+ };
14
+ useEffect(() => {
15
+ if (!dropdownRef.current)
16
+ return;
17
+ const onClickOutside = (e) => {
18
+ if (!dropdownRef.current?.contains(e.target)) {
19
+ if (isOpen && toggle) {
20
+ toggle();
21
+ }
22
+ }
23
+ };
24
+ window.addEventListener('click', onClickOutside);
25
+ return () => window.removeEventListener('click', onClickOutside);
26
+ }, [customValue]);
27
+ return (jsx("div", { ...props, ref: dropdownRef, children: jsx(DropdownContext.Provider, { value: customValue, children: children }) }));
28
+ };
29
+ const DropdownViewer = ({ children, ...props }) => {
30
+ return (jsx("span", { role: 'viewer', ...props, children: children }));
31
+ };
32
+ const DropdownButton = ({ onClick, children, ...props }) => {
33
+ const { toggle } = useDropdownContext();
34
+ return (jsx("span", { ...props, onClick: toggle, children: children }));
35
+ };
36
+ const DropdownOptions = ({ children, ...props }) => {
37
+ const { isOpen } = useDropdownContext();
38
+ if (!isOpen)
39
+ return null;
40
+ return jsx("div", { ...props, children: children });
41
+ };
42
+ const DropdownOption = ({ children, value, ...props }) => {
43
+ const { select } = useDropdownContext();
44
+ return (jsx("div", { role: "option", onClick: () => select(value), ...props, children: children }));
45
+ };
46
+ Object.assign(DropdownRoot, {
47
+ Button: DropdownButton,
48
+ Options: DropdownOptions,
49
+ Option: DropdownOption,
50
+ Viewer: DropdownViewer,
51
+ });
@@ -0,0 +1,4 @@
1
+ declare const DropdownDefaultTrigger: ({ value }: {
2
+ value: boolean;
3
+ }) => import("react/jsx-runtime").JSX.Element;
4
+ export default DropdownDefaultTrigger;
@@ -0,0 +1 @@
1
+ export { default } from './Dropdown/Dropdown';
@@ -0,0 +1,7 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface DivAttribute<T> extends HTMLAttributes<HTMLDivElement> {
3
+ value?: T;
4
+ }
5
+ export interface SpanAttribute<T> extends HTMLAttributes<HTMLSpanElement> {
6
+ value?: T;
7
+ }
package/types/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './buttons';
2
2
  export * from './inputs';
3
+ export * from './selectors';
4
+ export * from './common';
@@ -0,0 +1,16 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface DropdownContextValue<T> {
3
+ isOpen: boolean;
4
+ toggle: () => void;
5
+ select: (value: T) => void;
6
+ selected: T | null;
7
+ }
8
+ export interface DropdownProps<T> extends HTMLAttributes<HTMLElement> {
9
+ isOpen?: boolean;
10
+ toggle?: () => void;
11
+ select?: (value: T) => void;
12
+ selected?: T | null;
13
+ }
14
+ export interface UseDropdownProps<T> {
15
+ defaultValue?: T;
16
+ }
package/version.txt CHANGED
@@ -1 +1 @@
1
- 0.2.27
1
+ 0.2.29
@@ -1,6 +0,0 @@
1
- import { ButtonHTMLAttributes } from 'react';
2
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
- debounce?: boolean;
4
- loading?: boolean;
5
- readOnly?: boolean;
6
- }
@@ -1,2 +0,0 @@
1
- 'use strict';
2
-
@@ -1,7 +0,0 @@
1
- import { CSSProperties, InputHTMLAttributes, ReactElement, ReactNode } from 'react';
2
- export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
3
- suffixElement?: ReactElement | ReactNode;
4
- prefixElement?: ReactElement | ReactNode;
5
- wrapperStyle?: CSSProperties;
6
- wrapperClass?: string | string[];
7
- }
@@ -1,9 +0,0 @@
1
- 'use strict';
2
-
3
- const ArrayUtils = {
4
- toFlat(...args) {
5
- return args.flat().map(String).filter(Boolean);
6
- },
7
- };
8
-
9
- module.exports = ArrayUtils;
@@ -1,7 +0,0 @@
1
- 'use strict';
2
-
3
- var ArrayUtils = require('./ArrayUtils.js');
4
-
5
-
6
-
7
- module.exports = ArrayUtils;
@@ -1,6 +0,0 @@
1
- import { ButtonHTMLAttributes } from 'react';
2
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
- debounce?: boolean;
4
- loading?: boolean;
5
- readOnly?: boolean;
6
- }
package/types/index.js DELETED
@@ -1 +0,0 @@
1
-
@@ -1,7 +0,0 @@
1
- import { CSSProperties, InputHTMLAttributes, ReactElement, ReactNode } from 'react';
2
- export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
3
- suffixElement?: ReactElement | ReactNode;
4
- prefixElement?: ReactElement | ReactNode;
5
- wrapperStyle?: CSSProperties;
6
- wrapperClass?: string | string[];
7
- }
@@ -1,7 +0,0 @@
1
- const ArrayUtils = {
2
- toFlat(...args) {
3
- return args.flat().map(String).filter(Boolean);
4
- },
5
- };
6
-
7
- export { ArrayUtils as default };
package/utils/index.js DELETED
@@ -1 +0,0 @@
1
- export { default } from './ArrayUtils.js';