@greghowe79/the-lib 0.7.2 → 0.7.4
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/lib/components/input/input.qwik.cjs +83 -12
- package/lib/components/input/input.qwik.mjs +86 -15
- package/lib/components/input/styles.css.qwik.cjs +1 -1
- package/lib/components/input/styles.css.qwik.mjs +1 -1
- package/lib-types/components/input/input.d.ts +8 -3
- package/lib-types/stories/input.stories.d.ts +2 -0
- package/package.json +1 -1
|
@@ -4,12 +4,34 @@ const jsxRuntime = require("@builder.io/qwik/jsx-runtime");
|
|
|
4
4
|
const qwik = require("@builder.io/qwik");
|
|
5
5
|
const styles = require("./styles.css.qwik.cjs");
|
|
6
6
|
require("@fontsource/roboto-condensed/500.css");
|
|
7
|
-
const
|
|
7
|
+
const displayLocalImage = qwik.$((file, imageUrl) => {
|
|
8
|
+
const allowedExtensions = [
|
|
9
|
+
".jpg",
|
|
10
|
+
".jpeg",
|
|
11
|
+
".png",
|
|
12
|
+
".avif"
|
|
13
|
+
];
|
|
14
|
+
const fileExtension = file.name.split(".").pop()?.toLowerCase();
|
|
15
|
+
if (fileExtension && allowedExtensions.includes("." + fileExtension)) {
|
|
16
|
+
if (imageUrl) imageUrl.value = URL.createObjectURL(file);
|
|
17
|
+
} else {
|
|
18
|
+
console.error("Unsupported file format");
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
const uploadImage = qwik.$(async (_event, input, currentFile, selectedFile, imageUrl) => {
|
|
22
|
+
const file = input.files?.[0];
|
|
23
|
+
if (file) {
|
|
24
|
+
displayLocalImage(file, imageUrl);
|
|
25
|
+
if (currentFile) currentFile.value = qwik.noSerialize(file);
|
|
26
|
+
if (selectedFile) selectedFile.value = file.name;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const Input = qwik.component$(({ id, type, placeholder, value, error, onValidate$, onInput$, bgLight, currentFile, selectedFile, icon }) => {
|
|
8
30
|
qwik.useStylesScoped$(styles);
|
|
9
31
|
const internalError = qwik.useSignal(null);
|
|
10
32
|
const showError = error ?? internalError;
|
|
11
33
|
const inputHandler = qwik.$(async (_, elem) => {
|
|
12
|
-
value.value = elem.value;
|
|
34
|
+
if (value) value.value = elem.value;
|
|
13
35
|
if (onInput$) {
|
|
14
36
|
await onInput$();
|
|
15
37
|
}
|
|
@@ -21,17 +43,64 @@ const Input = qwik.component$(({ id, type, placeholder, value, error, onValidate
|
|
|
21
43
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
22
44
|
class: "input-container",
|
|
23
45
|
children: [
|
|
24
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
46
|
+
type === "file" ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
47
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
48
|
+
class: "flex_wrapper",
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
51
|
+
class: "label_wrapper",
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", {
|
|
54
|
+
for: id,
|
|
55
|
+
class: `input-label-upload ${bgLight ? "bg_light" : ""}`,
|
|
56
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
57
|
+
children: "Upload"
|
|
58
|
+
})
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", {
|
|
61
|
+
class: "input",
|
|
62
|
+
type,
|
|
63
|
+
id,
|
|
64
|
+
name: id,
|
|
65
|
+
accept: ".png, .jpg, .jpeg, .avif",
|
|
66
|
+
onChange$: (_, el) => uploadImage(_, el, currentFile, selectedFile),
|
|
67
|
+
required: true
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
72
|
+
class: "preview_container",
|
|
73
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
74
|
+
class: "prev_wrap",
|
|
75
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("p", {
|
|
76
|
+
class: "preview",
|
|
77
|
+
children: selectedFile?.value
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
})
|
|
83
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx("label", {
|
|
25
84
|
class: `input-label ${bgLight ? "bg_light" : ""}`,
|
|
26
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
85
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
86
|
+
class: icon ? "input-wrapper" : "no_icon",
|
|
87
|
+
children: [
|
|
88
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx("span", {
|
|
89
|
+
class: "input-icon",
|
|
90
|
+
"aria-hidden": "true",
|
|
91
|
+
children: typeof icon === "function" ? icon({}, null, 0) : icon
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", {
|
|
94
|
+
id,
|
|
95
|
+
type,
|
|
96
|
+
class: `input ${showError.value ? "error" : ""}`,
|
|
97
|
+
placeholder,
|
|
98
|
+
"bind:value": value,
|
|
99
|
+
onInput$: inputHandler,
|
|
100
|
+
onBlur$: inputHandler,
|
|
101
|
+
required: true
|
|
102
|
+
})
|
|
103
|
+
]
|
|
35
104
|
})
|
|
36
105
|
}),
|
|
37
106
|
showError.value && /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
@@ -42,3 +111,5 @@ const Input = qwik.component$(({ id, type, placeholder, value, error, onValidate
|
|
|
42
111
|
});
|
|
43
112
|
});
|
|
44
113
|
exports.Input = Input;
|
|
114
|
+
exports.displayLocalImage = displayLocalImage;
|
|
115
|
+
exports.uploadImage = uploadImage;
|
|
@@ -1,13 +1,35 @@
|
|
|
1
|
-
import { jsxs, jsx } from "@builder.io/qwik/jsx-runtime";
|
|
2
|
-
import { component$, useStylesScoped$, useSignal
|
|
1
|
+
import { jsxs, jsx, Fragment } from "@builder.io/qwik/jsx-runtime";
|
|
2
|
+
import { $, noSerialize, component$, useStylesScoped$, useSignal } from "@builder.io/qwik";
|
|
3
3
|
import styles from "./styles.css.qwik.mjs";
|
|
4
4
|
import "@fontsource/roboto-condensed/500.css";
|
|
5
|
-
const
|
|
5
|
+
const displayLocalImage = $((file, imageUrl) => {
|
|
6
|
+
const allowedExtensions = [
|
|
7
|
+
".jpg",
|
|
8
|
+
".jpeg",
|
|
9
|
+
".png",
|
|
10
|
+
".avif"
|
|
11
|
+
];
|
|
12
|
+
const fileExtension = file.name.split(".").pop()?.toLowerCase();
|
|
13
|
+
if (fileExtension && allowedExtensions.includes("." + fileExtension)) {
|
|
14
|
+
if (imageUrl) imageUrl.value = URL.createObjectURL(file);
|
|
15
|
+
} else {
|
|
16
|
+
console.error("Unsupported file format");
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const uploadImage = $(async (_event, input, currentFile, selectedFile, imageUrl) => {
|
|
20
|
+
const file = input.files?.[0];
|
|
21
|
+
if (file) {
|
|
22
|
+
displayLocalImage(file, imageUrl);
|
|
23
|
+
if (currentFile) currentFile.value = noSerialize(file);
|
|
24
|
+
if (selectedFile) selectedFile.value = file.name;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const Input = component$(({ id, type, placeholder, value, error, onValidate$, onInput$, bgLight, currentFile, selectedFile, icon }) => {
|
|
6
28
|
useStylesScoped$(styles);
|
|
7
29
|
const internalError = useSignal(null);
|
|
8
30
|
const showError = error ?? internalError;
|
|
9
31
|
const inputHandler = $(async (_, elem) => {
|
|
10
|
-
value.value = elem.value;
|
|
32
|
+
if (value) value.value = elem.value;
|
|
11
33
|
if (onInput$) {
|
|
12
34
|
await onInput$();
|
|
13
35
|
}
|
|
@@ -19,17 +41,64 @@ const Input = component$(({ id, type, placeholder, value, error, onValidate$, on
|
|
|
19
41
|
return /* @__PURE__ */ jsxs("div", {
|
|
20
42
|
class: "input-container",
|
|
21
43
|
children: [
|
|
22
|
-
/* @__PURE__ */ jsx(
|
|
44
|
+
type === "file" ? /* @__PURE__ */ jsx(Fragment, {
|
|
45
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
46
|
+
class: "flex_wrapper",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsxs("div", {
|
|
49
|
+
class: "label_wrapper",
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsx("label", {
|
|
52
|
+
for: id,
|
|
53
|
+
class: `input-label-upload ${bgLight ? "bg_light" : ""}`,
|
|
54
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
55
|
+
children: "Upload"
|
|
56
|
+
})
|
|
57
|
+
}),
|
|
58
|
+
/* @__PURE__ */ jsx("input", {
|
|
59
|
+
class: "input",
|
|
60
|
+
type,
|
|
61
|
+
id,
|
|
62
|
+
name: id,
|
|
63
|
+
accept: ".png, .jpg, .jpeg, .avif",
|
|
64
|
+
onChange$: (_, el) => uploadImage(_, el, currentFile, selectedFile),
|
|
65
|
+
required: true
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ jsx("div", {
|
|
70
|
+
class: "preview_container",
|
|
71
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
72
|
+
class: "prev_wrap",
|
|
73
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
74
|
+
class: "preview",
|
|
75
|
+
children: selectedFile?.value
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
})
|
|
81
|
+
}) : /* @__PURE__ */ jsx("label", {
|
|
23
82
|
class: `input-label ${bgLight ? "bg_light" : ""}`,
|
|
24
|
-
children: /* @__PURE__ */
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
83
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
84
|
+
class: icon ? "input-wrapper" : "no_icon",
|
|
85
|
+
children: [
|
|
86
|
+
icon && /* @__PURE__ */ jsx("span", {
|
|
87
|
+
class: "input-icon",
|
|
88
|
+
"aria-hidden": "true",
|
|
89
|
+
children: typeof icon === "function" ? icon({}, null, 0) : icon
|
|
90
|
+
}),
|
|
91
|
+
/* @__PURE__ */ jsx("input", {
|
|
92
|
+
id,
|
|
93
|
+
type,
|
|
94
|
+
class: `input ${showError.value ? "error" : ""}`,
|
|
95
|
+
placeholder,
|
|
96
|
+
"bind:value": value,
|
|
97
|
+
onInput$: inputHandler,
|
|
98
|
+
onBlur$: inputHandler,
|
|
99
|
+
required: true
|
|
100
|
+
})
|
|
101
|
+
]
|
|
33
102
|
})
|
|
34
103
|
}),
|
|
35
104
|
showError.value && /* @__PURE__ */ jsx("div", {
|
|
@@ -40,5 +109,7 @@ const Input = component$(({ id, type, placeholder, value, error, onValidate$, on
|
|
|
40
109
|
});
|
|
41
110
|
});
|
|
42
111
|
export {
|
|
43
|
-
Input
|
|
112
|
+
Input,
|
|
113
|
+
displayLocalImage,
|
|
114
|
+
uploadImage
|
|
44
115
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const styles = ".input-label:not([type='checkbox']) {\r\n border-radius:
|
|
2
|
+
const styles = ".input-container {\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n\r\n.input-label:not([type='checkbox']) {\r\n border-radius: 0.5rem;\r\n font-size: 0.8125rem;\r\n line-height: 1.85;\r\n letter-spacing: 0.0625rem;\r\n color: #333;\r\n position: relative;\r\n height: 3.125rem;\r\n display: flex;\r\n min-width: 0;\r\n background: rgba(0, 0, 0, 0.04);\r\n transition:\r\n color 0.3s ease,\r\n box-shadow 0.3s ease,\r\n background 0.3s ease;\r\n}\r\n\r\n.input-label.bg_light:not([type='checkbox']) {\r\n background: white;\r\n}\r\n\r\n.input {\r\n background: transparent;\r\n padding: 0 0.9375rem;\r\n flex: 1;\r\n font-size: 1rem;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n font-weight: 100;\r\n letter-spacing: inherit;\r\n color: inherit;\r\n height: 100%;\r\n border: none;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n appearance: none;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n opacity: 0.4;\r\n width: calc(100% - 0.9375rem * 2);\r\n}\r\n\r\n.input:focus {\r\n outline: none;\r\n opacity: 1;\r\n}\r\n\r\n.error-message {\r\n color: #e74c3c;\r\n font-size: 0.875rem;\r\n margin-top: 0.25rem;\r\n font-size: 1rem;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n\r\n.flex_wrapper {\r\n display: flex;\r\n justify-content: flex-start;\r\n align-items: center;\r\n}\r\n\r\n.label_wrapper {\r\n display: inline-flex;\r\n align-items: center;\r\n border-radius: 0.5rem 0 0 0.5rem;\r\n height: 3.4375rem;\r\n background-color: #0095ae;\r\n}\r\n\r\n.preview_container {\r\n height: 3.4375rem;\r\n display: flex;\r\n align-items: center;\r\n background: rgba(0, 0, 0, 0.04);\r\n border-radius: 0 0.5rem 0.5rem 0;\r\n color: #333;\r\n letter-spacing: 0.0625rem;\r\n font-size: 0.875rem;\r\n width: calc(100% - 3.4375rem);\r\n}\r\n\r\n.prev_wrap {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: calc(100% - 6.25rem);\r\n}\r\n\r\n.preview {\r\n margin: 0;\r\n border: none;\r\n}\r\n\r\n.input[type='file'] {\r\n position: absolute;\r\n width: 0.0625rem;\r\n height: 0.0625rem;\r\n padding: 0;\r\n margin: -0.0625rem;\r\n overflow: hidden;\r\n clip: rect(0, 0, 0, 0);\r\n border: 0;\r\n}\r\n\r\n.input-label {\r\n cursor: pointer;\r\n}\r\n\r\n.input-label-upload {\r\n cursor: pointer;\r\n width: 6.25rem;\r\n color: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 3.4375rem;\r\n}\r\n\r\n.input-label:hover {\r\n background-color: rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.input-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n padding: 0 0.9375rem;\r\n}\r\n\r\n.input-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n}\r\n\r\n.input.with-icon {\r\n padding-left: 2.5rem;\r\n}\r\n.no_icon {\r\n width: 100%;\r\n}\r\n";
|
|
3
3
|
module.exports = styles;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const styles = ".input-label:not([type='checkbox']) {\r\n border-radius:
|
|
1
|
+
const styles = ".input-container {\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n\r\n.input-label:not([type='checkbox']) {\r\n border-radius: 0.5rem;\r\n font-size: 0.8125rem;\r\n line-height: 1.85;\r\n letter-spacing: 0.0625rem;\r\n color: #333;\r\n position: relative;\r\n height: 3.125rem;\r\n display: flex;\r\n min-width: 0;\r\n background: rgba(0, 0, 0, 0.04);\r\n transition:\r\n color 0.3s ease,\r\n box-shadow 0.3s ease,\r\n background 0.3s ease;\r\n}\r\n\r\n.input-label.bg_light:not([type='checkbox']) {\r\n background: white;\r\n}\r\n\r\n.input {\r\n background: transparent;\r\n padding: 0 0.9375rem;\r\n flex: 1;\r\n font-size: 1rem;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n font-weight: 100;\r\n letter-spacing: inherit;\r\n color: inherit;\r\n height: 100%;\r\n border: none;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n appearance: none;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n opacity: 0.4;\r\n width: calc(100% - 0.9375rem * 2);\r\n}\r\n\r\n.input:focus {\r\n outline: none;\r\n opacity: 1;\r\n}\r\n\r\n.error-message {\r\n color: #e74c3c;\r\n font-size: 0.875rem;\r\n margin-top: 0.25rem;\r\n font-size: 1rem;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n\r\n.flex_wrapper {\r\n display: flex;\r\n justify-content: flex-start;\r\n align-items: center;\r\n}\r\n\r\n.label_wrapper {\r\n display: inline-flex;\r\n align-items: center;\r\n border-radius: 0.5rem 0 0 0.5rem;\r\n height: 3.4375rem;\r\n background-color: #0095ae;\r\n}\r\n\r\n.preview_container {\r\n height: 3.4375rem;\r\n display: flex;\r\n align-items: center;\r\n background: rgba(0, 0, 0, 0.04);\r\n border-radius: 0 0.5rem 0.5rem 0;\r\n color: #333;\r\n letter-spacing: 0.0625rem;\r\n font-size: 0.875rem;\r\n width: calc(100% - 3.4375rem);\r\n}\r\n\r\n.prev_wrap {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: calc(100% - 6.25rem);\r\n}\r\n\r\n.preview {\r\n margin: 0;\r\n border: none;\r\n}\r\n\r\n.input[type='file'] {\r\n position: absolute;\r\n width: 0.0625rem;\r\n height: 0.0625rem;\r\n padding: 0;\r\n margin: -0.0625rem;\r\n overflow: hidden;\r\n clip: rect(0, 0, 0, 0);\r\n border: 0;\r\n}\r\n\r\n.input-label {\r\n cursor: pointer;\r\n}\r\n\r\n.input-label-upload {\r\n cursor: pointer;\r\n width: 6.25rem;\r\n color: #fff;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 3.4375rem;\r\n}\r\n\r\n.input-label:hover {\r\n background-color: rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.input-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n padding: 0 0.9375rem;\r\n}\r\n\r\n.input-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n}\r\n\r\n.input.with-icon {\r\n padding-left: 2.5rem;\r\n}\r\n.no_icon {\r\n width: 100%;\r\n}\r\n";
|
|
2
2
|
export {
|
|
3
3
|
styles as default
|
|
4
4
|
};
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { QRL, Signal } from '@builder.io/qwik';
|
|
1
|
+
import { Component, JSXOutput, QRL, Signal } from '@builder.io/qwik';
|
|
2
2
|
import '@fontsource/roboto-condensed/500.css';
|
|
3
3
|
export type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'hidden' | 'checkbox' | 'radio' | 'file';
|
|
4
4
|
export interface InputProps {
|
|
5
5
|
id: string;
|
|
6
6
|
type: InputType;
|
|
7
7
|
placeholder?: string;
|
|
8
|
-
value
|
|
8
|
+
value?: Signal<string>;
|
|
9
9
|
error?: Signal<string | null>;
|
|
10
10
|
onValidate$?: QRL<(value: string) => Promise<string>>;
|
|
11
11
|
onInput$?: QRL<() => void>;
|
|
12
12
|
bgLight?: boolean;
|
|
13
|
+
currentFile?: Signal<any>;
|
|
14
|
+
selectedFile?: Signal<string>;
|
|
15
|
+
icon?: JSXOutput | Component<unknown>;
|
|
13
16
|
}
|
|
14
|
-
export declare const
|
|
17
|
+
export declare const displayLocalImage: QRL<(file: File, imageUrl?: Signal<string>) => void>;
|
|
18
|
+
export declare const uploadImage: QRL<(_event: Event, input: HTMLInputElement, currentFile?: Signal<any>, selectedFile?: Signal<string>, imageUrl?: Signal<string>) => Promise<void>>;
|
|
19
|
+
export declare const Input: Component<InputProps>;
|