@pathscale/ui 1.1.78 → 1.1.79

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,20 +1,70 @@
1
1
  import { type Component, type JSX } from "solid-js";
2
2
  import type { IComponentBaseProps } from "../types";
3
3
  export type PasswordFieldProps = IComponentBaseProps & {
4
+ id?: string;
4
5
  name?: string;
5
6
  label?: JSX.Element;
6
7
  placeholder?: string;
7
8
  disabled?: boolean;
8
9
  invalid?: boolean;
10
+ required?: boolean;
11
+ autofocus?: boolean;
9
12
  autocomplete?: "current-password" | "new-password" | "off";
13
+ "aria-describedby"?: string;
10
14
  startIcon?: JSX.Element;
11
15
  showLabel: string;
12
16
  hideLabel: string;
13
17
  value?: string;
18
+ inputRef?: (el: HTMLInputElement) => void;
14
19
  onInput?: (value: string) => void;
15
20
  onBlur?: () => void;
21
+ visibleIcon?: JSX.Element;
22
+ hiddenIcon?: JSX.Element;
23
+ onVisibilityChange?: (visible: boolean) => void;
16
24
  class?: string;
17
25
  inputClass?: string;
18
26
  };
27
+ export type PasswordToggleSnapshot = {
28
+ hadFocus: boolean;
29
+ selectionStart: number | null;
30
+ selectionEnd: number | null;
31
+ selectionDirection: "forward" | "backward" | "none" | null;
32
+ valueBeforeToggle: string | null;
33
+ };
34
+ type PasswordFieldInputContractParams = Pick<PasswordFieldProps, "id" | "name" | "label" | "placeholder" | "required" | "autofocus" | "autocomplete" | "aria-describedby" | "value" | "disabled" | "invalid" | "startIcon" | "inputClass"> & {
35
+ isVisible: boolean;
36
+ };
37
+ export declare const createPasswordFieldInputContract: (params: PasswordFieldInputContractParams) => {
38
+ id: string | undefined;
39
+ name: string | undefined;
40
+ label: JSX.Element;
41
+ type: string;
42
+ placeholder: string | undefined;
43
+ required: boolean | undefined;
44
+ autofocus: boolean | undefined;
45
+ autocomplete: "off" | "current-password" | "new-password" | undefined;
46
+ "aria-describedby": string | undefined;
47
+ value: string | undefined;
48
+ isDisabled: boolean;
49
+ isInvalid: boolean;
50
+ startIcon: JSX.Element;
51
+ class: string;
52
+ };
53
+ type PasswordFieldLike = {
54
+ value: string;
55
+ selectionStart: number | null;
56
+ selectionEnd: number | null;
57
+ selectionDirection: "forward" | "backward" | "none" | null;
58
+ focus: (options?: {
59
+ preventScroll?: boolean;
60
+ }) => void;
61
+ setSelectionRange: (selectionStart: number, selectionEnd: number, selectionDirection?: "forward" | "backward" | "none") => void;
62
+ dispatchEvent: (event: Event) => boolean;
63
+ };
64
+ export declare const getPasswordInputType: (isVisible: boolean) => "text" | "password";
65
+ export declare const selectPasswordToggleIcon: (isVisible: boolean, visibleIcon: JSX.Element | undefined, hiddenIcon: JSX.Element | undefined, fallback: JSX.Element) => JSX.Element;
66
+ export declare const capturePasswordToggleSnapshot: (field: PasswordFieldLike | undefined, activeElement: EventTarget | null) => PasswordToggleSnapshot;
67
+ export declare const restorePasswordFieldAfterToggle: (field: PasswordFieldLike | undefined, snapshot: PasswordToggleSnapshot) => void;
68
+ export declare const preventPasswordTogglePointerDown: (event: Pick<PointerEvent, "preventDefault">) => void;
19
69
  declare const PasswordField: Component<PasswordFieldProps>;
20
70
  export default PasswordField;
@@ -5,27 +5,100 @@ import * as __WEBPACK_EXTERNAL_MODULE__button_index_js_557db1f7__ from "../butto
5
5
  import * as __WEBPACK_EXTERNAL_MODULE__icon_index_js_1f7a158c__ from "../icon/index.js";
6
6
  import * as __WEBPACK_EXTERNAL_MODULE__input_index_js_00da0e74__ from "../input/index.js";
7
7
  var _tmpl$ = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)("<div>");
8
- const PasswordField_PasswordField = (props)=>{
8
+ const createPasswordFieldInputContract = (params)=>({
9
+ id: params.id,
10
+ name: params.name,
11
+ label: params.label,
12
+ type: getPasswordInputType(params.isVisible),
13
+ placeholder: params.placeholder,
14
+ required: params.required,
15
+ autofocus: params.autofocus,
16
+ autocomplete: params.autocomplete,
17
+ "aria-describedby": params["aria-describedby"],
18
+ value: params.value,
19
+ isDisabled: Boolean(params.disabled),
20
+ isInvalid: Boolean(params.invalid),
21
+ startIcon: params.startIcon,
22
+ class: (0, __WEBPACK_EXTERNAL_MODULE_tailwind_merge_e05e3e95__.twMerge)("w-full", params.inputClass)
23
+ });
24
+ const getPasswordInputType = (isVisible)=>isVisible ? "text" : "password";
25
+ const selectPasswordToggleIcon = (isVisible, visibleIcon, hiddenIcon, fallback)=>(isVisible ? visibleIcon : hiddenIcon) ?? fallback;
26
+ const capturePasswordToggleSnapshot = (field, activeElement)=>({
27
+ hadFocus: activeElement === field,
28
+ selectionStart: field?.selectionStart ?? null,
29
+ selectionEnd: field?.selectionEnd ?? null,
30
+ selectionDirection: field?.selectionDirection ?? null,
31
+ valueBeforeToggle: field?.value ?? null
32
+ });
33
+ const restorePasswordFieldAfterToggle = (field, snapshot)=>{
34
+ if (!field) return;
35
+ if (null !== snapshot.valueBeforeToggle && field.value !== snapshot.valueBeforeToggle) {
36
+ field.value = snapshot.valueBeforeToggle;
37
+ field.dispatchEvent(new Event("input", {
38
+ bubbles: true
39
+ }));
40
+ }
41
+ if (!snapshot.hadFocus) return;
42
+ field.focus({
43
+ preventScroll: true
44
+ });
45
+ if (null === snapshot.selectionStart || null === snapshot.selectionEnd) return;
46
+ try {
47
+ field.setSelectionRange(snapshot.selectionStart, snapshot.selectionEnd, snapshot.selectionDirection ?? void 0);
48
+ } catch {}
49
+ };
50
+ const preventPasswordTogglePointerDown = (event)=>event.preventDefault();
51
+ const PasswordField = (props)=>{
9
52
  const [local] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.splitProps)(props, [
53
+ "id",
10
54
  "name",
11
55
  "label",
12
56
  "placeholder",
13
57
  "disabled",
14
58
  "invalid",
59
+ "required",
60
+ "autofocus",
15
61
  "autocomplete",
62
+ "aria-describedby",
16
63
  "startIcon",
17
64
  "showLabel",
18
65
  "hideLabel",
19
66
  "value",
67
+ "inputRef",
20
68
  "onInput",
21
69
  "onBlur",
70
+ "visibleIcon",
71
+ "hiddenIcon",
72
+ "onVisibilityChange",
22
73
  "inputClass",
23
74
  "class",
24
75
  "className",
25
76
  "dataTheme"
26
77
  ]);
27
78
  const [isVisible, setIsVisible] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(false);
79
+ let fieldRef;
28
80
  const toggleLabel = ()=>isVisible() ? local.hideLabel : local.showLabel;
81
+ const toggleIcon = ()=>selectPasswordToggleIcon(isVisible(), local.visibleIcon, local.hiddenIcon, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE__icon_index_js_1f7a158c__["default"], {
82
+ width: 16,
83
+ height: 16,
84
+ get name () {
85
+ return isVisible() ? "icon-[lucide--eye-off]" : "icon-[lucide--eye]";
86
+ },
87
+ class: "h-4 w-4"
88
+ }));
89
+ const setFieldRef = (el)=>{
90
+ fieldRef = el;
91
+ local.inputRef?.(el);
92
+ };
93
+ const toggleVisibility = ()=>{
94
+ const snapshot = capturePasswordToggleSnapshot(fieldRef, "undefined" != typeof document ? document.activeElement : null);
95
+ const nextVisible = !isVisible();
96
+ setIsVisible(nextVisible);
97
+ local.onVisibilityChange?.(nextVisible);
98
+ queueMicrotask(()=>{
99
+ restorePasswordFieldAfterToggle(fieldRef, snapshot);
100
+ });
101
+ };
29
102
  return (()=>{
30
103
  var _el$ = _tmpl$();
31
104
  (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.spread)(_el$, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(()=>({
@@ -39,41 +112,27 @@ const PasswordField_PasswordField = (props)=>{
39
112
  return isVisible() ? "true" : "false";
40
113
  }
41
114
  }), false, true);
42
- (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.insert)(_el$, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE__input_index_js_00da0e74__["default"], (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)({
43
- get name () {
44
- return local.name;
45
- },
46
- get label () {
47
- return local.label;
48
- },
49
- get type () {
50
- return isVisible() ? "text" : "password";
51
- },
52
- get placeholder () {
53
- return local.placeholder;
54
- },
55
- get autocomplete () {
56
- return local.autocomplete;
57
- },
58
- get value () {
59
- return local.value;
60
- },
61
- get isDisabled () {
62
- return Boolean(local.disabled);
63
- },
64
- get isInvalid () {
65
- return Boolean(local.invalid);
66
- },
67
- get startIcon () {
68
- return local.startIcon;
69
- },
115
+ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.insert)(_el$, (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE__input_index_js_00da0e74__["default"], (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.mergeProps)(()=>createPasswordFieldInputContract({
116
+ id: local.id,
117
+ name: local.name,
118
+ label: local.label,
119
+ isVisible: isVisible(),
120
+ placeholder: local.placeholder,
121
+ required: local.required,
122
+ autofocus: local.autofocus,
123
+ autocomplete: local.autocomplete,
124
+ "aria-describedby": local["aria-describedby"],
125
+ value: local.value,
126
+ disabled: local.disabled,
127
+ invalid: local.invalid,
128
+ startIcon: local.startIcon,
129
+ inputClass: local.inputClass
130
+ }), {
131
+ ref: setFieldRef,
70
132
  onInput: (event)=>{
71
133
  local.onInput?.(event.currentTarget.value);
72
134
  },
73
- onBlur: ()=>local.onBlur?.()
74
- }, ()=>({
75
- class: (0, __WEBPACK_EXTERNAL_MODULE_tailwind_merge_e05e3e95__.twMerge)("w-full", local.inputClass)
76
- }), {
135
+ onBlur: ()=>local.onBlur?.(),
77
136
  get endIcon () {
78
137
  return (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE__button_index_js_557db1f7__["default"], {
79
138
  type: "button",
@@ -81,7 +140,11 @@ const PasswordField_PasswordField = (props)=>{
81
140
  size: "sm",
82
141
  isIconOnly: true,
83
142
  class: "h-7 min-h-7 w-7 min-w-7",
84
- onClick: ()=>setIsVisible((value)=>!value),
143
+ get isDisabled () {
144
+ return Boolean(local.disabled);
145
+ },
146
+ onPointerDown: preventPasswordTogglePointerDown,
147
+ onClick: toggleVisibility,
85
148
  get ["aria-label"] () {
86
149
  return toggleLabel();
87
150
  },
@@ -92,14 +155,7 @@ const PasswordField_PasswordField = (props)=>{
92
155
  return toggleLabel();
93
156
  },
94
157
  get children () {
95
- return (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.createComponent)(__WEBPACK_EXTERNAL_MODULE__icon_index_js_1f7a158c__["default"], {
96
- width: 16,
97
- height: 16,
98
- get name () {
99
- return isVisible() ? "icon-[lucide--eye-off]" : "icon-[lucide--eye]";
100
- },
101
- class: "h-4 w-4"
102
- });
158
+ return toggleIcon();
103
159
  }
104
160
  });
105
161
  }
@@ -107,5 +163,5 @@ const PasswordField_PasswordField = (props)=>{
107
163
  return _el$;
108
164
  })();
109
165
  };
110
- const PasswordField = PasswordField_PasswordField;
111
- export { PasswordField as default };
166
+ const password_field_PasswordField = PasswordField;
167
+ export { capturePasswordToggleSnapshot, createPasswordFieldInputContract, password_field_PasswordField as default, getPasswordInputType, preventPasswordTogglePointerDown, restorePasswordFieldAfterToggle, selectPasswordToggleIcon };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pathscale/ui",
3
- "version": "1.1.78",
3
+ "version": "1.1.79",
4
4
  "author": "pathscale",
5
5
  "repository": {
6
6
  "type": "git",