@virastack/password 1.0.2 → 1.1.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/dist/index.d.ts DELETED
@@ -1,73 +0,0 @@
1
- import React, { ReactNode } from 'react';
2
-
3
- /**
4
- * Generates the input type based on visibility.
5
- */
6
- declare const getInputType: (isVisible: boolean) => "text" | "password";
7
- /**
8
- * Generates ARIA attributes for the toggle button.
9
- */
10
- declare const getButtonAriaAttributes: (isVisible: boolean, inputId: string, label?: string) => {
11
- 'aria-label': string;
12
- 'aria-pressed': boolean;
13
- 'aria-controls': string;
14
- type: "button";
15
- };
16
- /**
17
- * Generates ARIA attributes for the input field.
18
- */
19
- declare const getInputAriaAttributes: (isInvalid?: boolean, describedBy?: string) => Record<string, any>;
20
-
21
- interface UseViraPasswordOptions {
22
- /**
23
- * Initial visibility state of the password.
24
- * @default false
25
- */
26
- defaultVisible?: boolean;
27
- /**
28
- * Custom icons for show/hide states.
29
- */
30
- icons?: {
31
- show: ReactNode;
32
- hide: ReactNode;
33
- };
34
- /**
35
- * Whether the input is disabled.
36
- * If true, the toggle button will also be disabled.
37
- */
38
- disabled?: boolean;
39
- /**
40
- * Whether the input is read-only.
41
- * If true, the toggle button will be disabled.
42
- */
43
- readOnly?: boolean;
44
- /**
45
- * ID for the input element. If not provided, a random ID will be generated.
46
- */
47
- id?: string;
48
- /**
49
- * Props to be merged with the generated input props.
50
- */
51
- inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
52
- /**
53
- * Props to be merged with the generated button props.
54
- */
55
- btnProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;
56
- }
57
- interface UseViraPasswordResult {
58
- inputProps: React.InputHTMLAttributes<HTMLInputElement>;
59
- btnProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
60
- isVisible: boolean;
61
- toggle: () => void;
62
- setVisible: (visible: boolean) => void;
63
- }
64
- /**
65
- * A utility to merge event handlers and other props.
66
- */
67
- declare const mergeProps: <T extends Record<string, any>>(...args: (T | undefined)[]) => T;
68
- declare const useViraPassword: (options?: UseViraPasswordOptions) => UseViraPasswordResult;
69
-
70
- declare const EyeIcon: (props: React.SVGProps<SVGSVGElement>) => React.ReactSVGElement;
71
- declare const EyeOffIcon: (props: React.SVGProps<SVGSVGElement>) => React.ReactSVGElement;
72
-
73
- export { EyeIcon, EyeOffIcon, type UseViraPasswordOptions, type UseViraPasswordResult, getButtonAriaAttributes, getInputAriaAttributes, getInputType, mergeProps, useViraPassword };
package/dist/index.js DELETED
@@ -1,146 +0,0 @@
1
- "use client";
2
- 'use strict';
3
-
4
- var React = require('react');
5
-
6
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
-
8
- var React__default = /*#__PURE__*/_interopDefault(React);
9
-
10
- // src/core/logic.ts
11
- var getInputType = (isVisible) => {
12
- return isVisible ? "text" : "password";
13
- };
14
- var getButtonAriaAttributes = (isVisible, inputId, label = "Toggle password visibility") => {
15
- return {
16
- "aria-label": label,
17
- "aria-pressed": isVisible,
18
- "aria-controls": inputId,
19
- type: "button"
20
- };
21
- };
22
- var getInputAriaAttributes = (isInvalid, describedBy) => {
23
- const attrs = {};
24
- if (isInvalid !== void 0) {
25
- attrs["aria-invalid"] = isInvalid;
26
- }
27
- if (describedBy) {
28
- attrs["aria-describedby"] = describedBy;
29
- }
30
- return attrs;
31
- };
32
- var EyeIcon = (props) => React__default.default.createElement(
33
- "svg",
34
- {
35
- xmlns: "http://www.w3.org/2000/svg",
36
- width: "16",
37
- height: "16",
38
- viewBox: "0 0 24 24",
39
- fill: "none",
40
- stroke: "currentColor",
41
- strokeWidth: "2",
42
- strokeLinecap: "round",
43
- strokeLinejoin: "round",
44
- ...props
45
- },
46
- React__default.default.createElement("path", { d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }),
47
- React__default.default.createElement("circle", { cx: "12", cy: "12", r: "3" })
48
- );
49
- var EyeOffIcon = (props) => React__default.default.createElement(
50
- "svg",
51
- {
52
- xmlns: "http://www.w3.org/2000/svg",
53
- width: "16",
54
- height: "16",
55
- viewBox: "0 0 24 24",
56
- fill: "none",
57
- stroke: "currentColor",
58
- strokeWidth: "2",
59
- strokeLinecap: "round",
60
- strokeLinejoin: "round",
61
- ...props
62
- },
63
- React__default.default.createElement("path", { d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }),
64
- React__default.default.createElement("path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }),
65
- React__default.default.createElement("path", { d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }),
66
- React__default.default.createElement("path", { d: "m2 2 20 20" })
67
- );
68
-
69
- // src/react/useViraPassword.ts
70
- var mergeProps = (...args) => {
71
- const result = {};
72
- for (const props of args) {
73
- if (!props) continue;
74
- for (const key in props) {
75
- const val = props[key];
76
- const existing = result[key];
77
- if (key.startsWith("on") && typeof val === "function" && typeof existing === "function") {
78
- result[key] = (...args2) => {
79
- existing(...args2);
80
- val(...args2);
81
- };
82
- } else if (key === "className" && typeof val === "string" && typeof existing === "string") {
83
- result[key] = [existing, val].filter(Boolean).join(" ");
84
- } else {
85
- result[key] = val;
86
- }
87
- }
88
- }
89
- return result;
90
- };
91
- var useViraPassword = (options = {}) => {
92
- const {
93
- defaultVisible = false,
94
- icons,
95
- disabled = false,
96
- readOnly = false,
97
- id: providedId,
98
- inputProps: userInputProps,
99
- btnProps: userBtnProps
100
- } = options;
101
- const [isVisible, setIsVisible] = React.useState(defaultVisible);
102
- const generatedId = React.useId();
103
- const inputId = providedId || `virapassword-input-${generatedId}`;
104
- const toggle = React.useCallback(() => {
105
- if (disabled || readOnly) return;
106
- setIsVisible((prev) => !prev);
107
- }, [disabled, readOnly]);
108
- const setVisible = React.useCallback((visible) => {
109
- if (disabled || readOnly) return;
110
- setIsVisible(visible);
111
- }, [disabled, readOnly]);
112
- const showIcon = icons?.show ?? React__default.default.createElement(EyeIcon);
113
- const hideIcon = icons?.hide ?? React__default.default.createElement(EyeOffIcon);
114
- const baseInputProps = {
115
- id: inputId,
116
- type: getInputType(isVisible),
117
- disabled,
118
- readOnly,
119
- ...getInputAriaAttributes()
120
- };
121
- const baseBtnProps = {
122
- onClick: toggle,
123
- disabled: disabled || readOnly,
124
- children: isVisible ? hideIcon : showIcon,
125
- ...getButtonAriaAttributes(isVisible, inputId)
126
- };
127
- const mergedInputProps = mergeProps(baseInputProps, userInputProps);
128
- const mergedBtnProps = mergeProps(baseBtnProps, userBtnProps);
129
- return {
130
- inputProps: mergedInputProps,
131
- btnProps: mergedBtnProps,
132
- isVisible,
133
- toggle,
134
- setVisible
135
- };
136
- };
137
-
138
- exports.EyeIcon = EyeIcon;
139
- exports.EyeOffIcon = EyeOffIcon;
140
- exports.getButtonAriaAttributes = getButtonAriaAttributes;
141
- exports.getInputAriaAttributes = getInputAriaAttributes;
142
- exports.getInputType = getInputType;
143
- exports.mergeProps = mergeProps;
144
- exports.useViraPassword = useViraPassword;
145
- //# sourceMappingURL=index.js.map
146
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/logic.ts","../src/icons/index.ts","../src/react/useViraPassword.ts"],"names":["React","args","useState","useId","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Generates the input type based on visibility.\n */\nexport const getInputType = (isVisible: boolean): 'text' | 'password' => {\n return isVisible ? 'text' : 'password';\n};\n\n/**\n * Generates ARIA attributes for the toggle button.\n */\nexport const getButtonAriaAttributes = (\n isVisible: boolean,\n inputId: string,\n label: string = 'Toggle password visibility'\n) => {\n return {\n 'aria-label': label,\n 'aria-pressed': isVisible,\n 'aria-controls': inputId,\n type: 'button' as const,\n };\n};\n\n/**\n * Generates ARIA attributes for the input field.\n */\nexport const getInputAriaAttributes = (\n isInvalid?: boolean,\n describedBy?: string\n) => {\n const attrs: Record<string, any> = {};\n \n if (isInvalid !== undefined) {\n attrs['aria-invalid'] = isInvalid;\n }\n \n if (describedBy) {\n attrs['aria-describedby'] = describedBy;\n }\n \n return attrs;\n};\n","import React from 'react';\n\nexport const EyeIcon = (props: React.SVGProps<SVGSVGElement>) => (\n React.createElement('svg', {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: \"2\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n ...props\n },\n React.createElement('path', { d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" }),\n React.createElement('circle', { cx: \"12\", cy: \"12\", r: \"3\" })\n )\n);\n\nexport const EyeOffIcon = (props: React.SVGProps<SVGSVGElement>) => (\n React.createElement('svg', {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: \"2\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n ...props\n },\n React.createElement('path', { d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" }),\n React.createElement('path', { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\" }),\n React.createElement('path', { d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" }),\n React.createElement('path', { d: \"m2 2 20 20\" })\n )\n);\n","'use client';\n\nimport React, { useState, useId, useCallback, ReactNode } from 'react';\nimport { EyeIcon, EyeOffIcon } from '../icons';\nimport { getInputType, getButtonAriaAttributes, getInputAriaAttributes } from '../core/logic';\n\nexport interface UseViraPasswordOptions {\n /**\n * Initial visibility state of the password.\n * @default false\n */\n defaultVisible?: boolean;\n \n /**\n * Custom icons for show/hide states.\n */\n icons?: {\n show: ReactNode;\n hide: ReactNode;\n };\n \n /**\n * Whether the input is disabled.\n * If true, the toggle button will also be disabled.\n */\n disabled?: boolean;\n \n /**\n * Whether the input is read-only.\n * If true, the toggle button will be disabled.\n */\n readOnly?: boolean;\n\n /**\n * ID for the input element. If not provided, a random ID will be generated.\n */\n id?: string;\n\n /**\n * Props to be merged with the generated input props.\n */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n\n /**\n * Props to be merged with the generated button props.\n */\n btnProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;\n}\n\nexport interface UseViraPasswordResult {\n inputProps: React.InputHTMLAttributes<HTMLInputElement>;\n btnProps: React.ButtonHTMLAttributes<HTMLButtonElement>;\n isVisible: boolean;\n toggle: () => void;\n setVisible: (visible: boolean) => void;\n}\n\n/**\n * A utility to merge event handlers and other props.\n */\nconst mergeProps = <T extends Record<string, any>>(\n ...args: (T | undefined)[]\n): T => {\n const result: Record<string, any> = {};\n\n for (const props of args) {\n if (!props) continue;\n\n for (const key in props) {\n const val = props[key];\n const existing = result[key];\n\n if (\n key.startsWith('on') &&\n typeof val === 'function' &&\n typeof existing === 'function'\n ) {\n result[key] = (...args: any[]) => {\n existing(...args);\n val(...args);\n };\n } else if (key === 'className' && typeof val === 'string' && typeof existing === 'string') {\n result[key] = [existing, val].filter(Boolean).join(' ');\n } else {\n result[key] = val;\n }\n }\n }\n\n return result as T;\n};\n\nexport const useViraPassword = (options: UseViraPasswordOptions = {}): UseViraPasswordResult => {\n const {\n defaultVisible = false,\n icons,\n disabled = false,\n readOnly = false,\n id: providedId,\n inputProps: userInputProps,\n btnProps: userBtnProps,\n } = options;\n\n const [isVisible, setIsVisible] = useState(defaultVisible);\n const generatedId = useId();\n const inputId = providedId || `virapassword-input-${generatedId}`;\n\n const toggle = useCallback(() => {\n if (disabled || readOnly) return;\n setIsVisible((prev) => !prev);\n }, [disabled, readOnly]);\n\n const setVisible = useCallback((visible: boolean) => {\n if (disabled || readOnly) return;\n setIsVisible(visible);\n }, [disabled, readOnly]);\n\n const showIcon = icons?.show ?? React.createElement(EyeIcon);\n const hideIcon = icons?.hide ?? React.createElement(EyeOffIcon);\n\n // Base props for the input\n const baseInputProps: React.InputHTMLAttributes<HTMLInputElement> = {\n id: inputId,\n type: getInputType(isVisible),\n disabled,\n readOnly,\n ...getInputAriaAttributes(),\n };\n\n // Base props for the button\n const baseBtnProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {\n onClick: toggle,\n disabled: disabled || readOnly,\n children: isVisible ? hideIcon : showIcon,\n ...getButtonAriaAttributes(isVisible, inputId),\n };\n\n // Merge user props with base props\n const mergedInputProps = mergeProps(baseInputProps, userInputProps);\n const mergedBtnProps = mergeProps(baseBtnProps, userBtnProps);\n\n return {\n inputProps: mergedInputProps,\n btnProps: mergedBtnProps,\n isVisible,\n toggle,\n setVisible,\n };\n};\n\n// Re-export the mergeProps utility if the user needs it manually\nexport { mergeProps };\n"]}