@greghowe79/the-lib 0.7.2 → 0.7.3

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.
@@ -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 Input = qwik.component$(({ id, type, placeholder, value, error, onValidate$, onInput$, bgLight }) => {
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 }) => {
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,7 +43,44 @@ 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("label", {
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
85
  children: /* @__PURE__ */ jsxRuntime.jsx("input", {
27
86
  id,
@@ -42,3 +101,5 @@ const Input = qwik.component$(({ id, type, placeholder, value, error, onValidate
42
101
  });
43
102
  });
44
103
  exports.Input = Input;
104
+ exports.displayLocalImage = displayLocalImage;
105
+ exports.uploadImage = uploadImage;
@@ -1,13 +1,35 @@
1
- import { jsxs, jsx } from "@builder.io/qwik/jsx-runtime";
2
- import { component$, useStylesScoped$, useSignal, $ } from "@builder.io/qwik";
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 Input = component$(({ id, type, placeholder, value, error, onValidate$, onInput$, bgLight }) => {
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 }) => {
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,7 +41,44 @@ 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("label", {
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
83
  children: /* @__PURE__ */ jsx("input", {
25
84
  id,
@@ -40,5 +99,7 @@ const Input = component$(({ id, type, placeholder, value, error, onValidate$, on
40
99
  });
41
100
  });
42
101
  export {
43
- Input
102
+ Input,
103
+ displayLocalImage,
104
+ uploadImage
44
105
  };
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const styles = ".input-label:not([type='checkbox']) {\r\n border-radius: 8px;\r\n font-size: 13px;\r\n line-height: 1.85;\r\n letter-spacing: 1px;\r\n color: #333;\r\n position: relative;\r\n height: 50px;\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 15px;\r\n flex: 1;\r\n font-size: 16px;\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}\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: 16px;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n";
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}\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";
3
3
  module.exports = styles;
@@ -1,4 +1,4 @@
1
- const styles = ".input-label:not([type='checkbox']) {\r\n border-radius: 8px;\r\n font-size: 13px;\r\n line-height: 1.85;\r\n letter-spacing: 1px;\r\n color: #333;\r\n position: relative;\r\n height: 50px;\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 15px;\r\n flex: 1;\r\n font-size: 16px;\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}\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: 16px;\r\n font-family: 'Roboto Condensed', sans-serif;\r\n}\r\n";
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}\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";
2
2
  export {
3
3
  styles as default
4
4
  };
@@ -5,10 +5,14 @@ export interface InputProps {
5
5
  id: string;
6
6
  type: InputType;
7
7
  placeholder?: string;
8
- value: Signal<string>;
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>;
13
15
  }
16
+ export declare const displayLocalImage: QRL<(file: File, imageUrl?: Signal<string>) => void>;
17
+ export declare const uploadImage: QRL<(_event: Event, input: HTMLInputElement, currentFile?: Signal<any>, selectedFile?: Signal<string>, imageUrl?: Signal<string>) => Promise<void>>;
14
18
  export declare const Input: import("@builder.io/qwik").Component<InputProps>;
@@ -5,3 +5,4 @@ export default meta;
5
5
  type Story = StoryObj<InputProps>;
6
6
  export declare const Email: Story;
7
7
  export declare const InputLightBackground: Story;
8
+ export declare const FileUpload: Story;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greghowe79/the-lib",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "description": "Collection of fast components for Qwik",
5
5
  "main": "./lib/index.qwik.mjs",
6
6
  "qwik": "./lib/index.qwik.mjs",