@hashrytech/quick-components-kit 0.18.1 → 0.19.1
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/CHANGELOG.md +12 -0
- package/README.md +6 -0
- package/dist/components/button/Button.svelte +6 -5
- package/dist/components/button/Button.svelte.d.ts +3 -2
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/hamburger-menu/HamburgerMenu.svelte +2 -2
- package/dist/components/hamburger-menu/HamburgerMenu.svelte.d.ts +1 -1
- package/dist/components/select/Select.svelte +53 -21
- package/dist/components/select/Select.svelte.d.ts +8 -4
- package/dist/components/text-input/TextInput.svelte +96 -19
- package/dist/components/text-input/TextInput.svelte.d.ts +18 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/modules/api-proxy.d.ts +2 -0
- package/dist/modules/api-proxy.js +3 -1
- package/dist/ui/banners/banner-1/Banner1.svelte +47 -0
- package/dist/ui/banners/banner-1/Banner1.svelte.d.ts +14 -0
- package/dist/ui/banners/banner-1/index.d.ts +1 -0
- package/dist/ui/banners/banner-1/index.js +1 -0
- package/dist/ui/breadcrumbs/breadcrumbs-1/Breadcrumbs1.svelte +30 -0
- package/dist/ui/breadcrumbs/breadcrumbs-1/Breadcrumbs1.svelte.d.ts +13 -0
- package/dist/ui/breadcrumbs/breadcrumbs-1/index.d.ts +1 -0
- package/dist/ui/breadcrumbs/breadcrumbs-1/index.js +1 -0
- package/dist/ui/featured-products/featured-products-1/FeaturedProducts1.svelte +56 -0
- package/dist/ui/featured-products/featured-products-1/FeaturedProducts1.svelte.d.ts +22 -0
- package/dist/ui/featured-products/featured-products-1/index.d.ts +1 -0
- package/dist/ui/featured-products/featured-products-1/index.js +1 -0
- package/dist/ui/footers/footer-1/Footer1.svelte +81 -0
- package/dist/ui/footers/footer-1/Footer1.svelte.d.ts +18 -0
- package/dist/ui/footers/footer-1/index.d.ts +1 -0
- package/dist/ui/footers/footer-1/index.js +1 -0
- package/dist/ui/headers/header-1/Header1.svelte +94 -0
- package/dist/ui/headers/header-1/Header1.svelte.d.ts +15 -0
- package/dist/ui/headers/header-1/index.d.ts +1 -0
- package/dist/ui/headers/header-1/index.js +1 -0
- package/dist/ui/order-product-line-item/order-product-line-item-1/OrderProductLineItem1.svelte +74 -0
- package/dist/ui/order-product-line-item/order-product-line-item-1/OrderProductLineItem1.svelte.d.ts +15 -0
- package/dist/ui/order-product-line-item/order-product-line-item-1/index.d.ts +1 -0
- package/dist/ui/order-product-line-item/order-product-line-item-1/index.js +1 -0
- package/dist/ui/product-filters/product-filter-1/ProductFilter1.svelte +42 -0
- package/dist/ui/product-filters/product-filter-1/ProductFilter1.svelte.d.ts +26 -0
- package/dist/ui/product-filters/product-filter-1/ProductFilterBlock.svelte +49 -0
- package/dist/ui/product-filters/product-filter-1/ProductFilterBlock.svelte.d.ts +17 -0
- package/dist/ui/product-filters/product-filter-1/index.d.ts +1 -0
- package/dist/ui/product-filters/product-filter-1/index.js +1 -0
- package/dist/ui/product-list/product-list-1/ProductList1.svelte +76 -0
- package/dist/ui/product-list/product-list-1/ProductList1.svelte.d.ts +24 -0
- package/dist/ui/product-list/product-list-1/index.d.ts +1 -0
- package/dist/ui/product-list/product-list-1/index.js +1 -0
- package/dist/ui/product-list-navigation/product-list-navigation-1/ProductListNavigation1.svelte +51 -0
- package/dist/ui/product-list-navigation/product-list-navigation-1/ProductListNavigation1.svelte.d.ts +12 -0
- package/dist/ui/product-list-navigation/product-list-navigation-1/index.d.ts +1 -0
- package/dist/ui/product-list-navigation/product-list-navigation-1/index.js +1 -0
- package/dist/ui/searchbox/Searchbox.svelte +46 -0
- package/dist/ui/searchbox/Searchbox.svelte.d.ts +13 -0
- package/dist/ui/searchbox/index.d.ts +1 -0
- package/dist/ui/searchbox/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @hashrytech/quick-components-kit
|
|
2
2
|
|
|
3
|
+
## 0.19.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix padding for TextInput and add prepend for api proxy
|
|
8
|
+
|
|
9
|
+
## 0.19.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Update: adding ui components and refactoring textbox and select components
|
|
14
|
+
|
|
3
15
|
## 0.18.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -15,6 +15,12 @@ or via yarn:
|
|
|
15
15
|
yarn add @hashrytech/quick-components-kit
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
## To Update Version
|
|
19
|
+
```bash
|
|
20
|
+
npm run change
|
|
21
|
+
npm run version
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Configurations
|
|
19
25
|
Set default theme values for primary and secondary variables:
|
|
20
26
|
- Color gradient
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
children?: Snippet;
|
|
8
8
|
icon?: Snippet;
|
|
9
|
-
|
|
9
|
+
loadingIcon?: Snippet;
|
|
10
|
+
loading?: boolean;
|
|
10
11
|
onclick?: (event: MouseEvent) => void;
|
|
11
12
|
class?: ClassNameValue;
|
|
12
13
|
};
|
|
@@ -16,15 +17,15 @@
|
|
|
16
17
|
<script lang="ts">
|
|
17
18
|
import {twMerge} from 'tailwind-merge';
|
|
18
19
|
|
|
19
|
-
let { disabled=$bindable(), children, icon,
|
|
20
|
+
let { disabled=$bindable(), loading=$bindable(false), children, icon, loadingIcon, onclick, ...props }: ButtonProps = $props();
|
|
20
21
|
|
|
21
22
|
</script>
|
|
22
23
|
|
|
23
24
|
<button {disabled} class={twMerge("flex flex-row items-center gap-2 px-4 py-2 focus:outline-primary-focus bg-primary-button hover:bg-primary-button-hover rounded-primary cursor-pointer focus:ring-primary-focus focus:ring",
|
|
24
25
|
"disabled:bg-primary-button/60 disabled:cursor-default", props.class)}
|
|
25
|
-
{onclick}>
|
|
26
|
-
{#if
|
|
27
|
-
<span>{@render
|
|
26
|
+
{onclick}>
|
|
27
|
+
{#if loadingIcon && loading}
|
|
28
|
+
<span class="shrink-0 animate-spin font-semibold">{@render loadingIcon()}</span>
|
|
28
29
|
{:else if icon}
|
|
29
30
|
<span>{@render icon()}</span>
|
|
30
31
|
{/if}
|
|
@@ -4,10 +4,11 @@ export type ButtonProps = {
|
|
|
4
4
|
disabled?: boolean;
|
|
5
5
|
children?: Snippet;
|
|
6
6
|
icon?: Snippet;
|
|
7
|
-
|
|
7
|
+
loadingIcon?: Snippet;
|
|
8
|
+
loading?: boolean;
|
|
8
9
|
onclick?: (event: MouseEvent) => void;
|
|
9
10
|
class?: ClassNameValue;
|
|
10
11
|
};
|
|
11
|
-
declare const Button: import("svelte").Component<ButtonProps, {}, "disabled">;
|
|
12
|
+
declare const Button: import("svelte").Component<ButtonProps, {}, "disabled" | "loading">;
|
|
12
13
|
type Button = ReturnType<typeof Button>;
|
|
13
14
|
export default Button;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as Button } from './Button.svelte';
|
|
1
|
+
export { default as Button, type ButtonProps } from './Button.svelte';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
export type HamburgerProps = {
|
|
5
5
|
open?: boolean;
|
|
6
6
|
useCloseBtn?: boolean;
|
|
7
|
-
ariaLabel
|
|
7
|
+
ariaLabel?: string;
|
|
8
8
|
linesClasses?: string;
|
|
9
9
|
linesParentClasses?: string;
|
|
10
10
|
onclick?: (event: MouseEvent) => void;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<script lang="ts">
|
|
17
17
|
import {twMerge} from 'tailwind-merge';
|
|
18
18
|
|
|
19
|
-
let { open=$bindable(true), ariaLabel, linesClasses, linesParentClasses, useCloseBtn=true, onclick, ...props }: HamburgerProps = $props();
|
|
19
|
+
let { open=$bindable(true), ariaLabel="menu button", linesClasses, linesParentClasses, useCloseBtn=true, onclick, ...props }: HamburgerProps = $props();
|
|
20
20
|
|
|
21
21
|
</script>
|
|
22
22
|
|
|
@@ -2,7 +2,7 @@ import type { ClassNameValue } from 'tailwind-merge';
|
|
|
2
2
|
export type HamburgerProps = {
|
|
3
3
|
open?: boolean;
|
|
4
4
|
useCloseBtn?: boolean;
|
|
5
|
-
ariaLabel
|
|
5
|
+
ariaLabel?: string;
|
|
6
6
|
linesClasses?: string;
|
|
7
7
|
linesParentClasses?: string;
|
|
8
8
|
onclick?: (event: MouseEvent) => void;
|
|
@@ -4,23 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
export type Option = {
|
|
6
6
|
value: string | number;
|
|
7
|
-
|
|
7
|
+
key: string;
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export type SelectProps = {
|
|
12
12
|
id: string;
|
|
13
13
|
name?: string;
|
|
14
|
-
|
|
14
|
+
labelText?: string;
|
|
15
15
|
disabled?: boolean;
|
|
16
16
|
value?: string | number;
|
|
17
|
-
options
|
|
17
|
+
options?: Option[];
|
|
18
18
|
size?: "sm" | "md" | "lg";
|
|
19
19
|
labelPosition?: "left" | "top" | "right" | "bottom";
|
|
20
20
|
class?: ClassNameValue;
|
|
21
21
|
labelClass?: ClassNameValue;
|
|
22
|
+
firstDivClass?: ClassNameValue;
|
|
23
|
+
secondDivClass?: ClassNameValue;
|
|
22
24
|
optionsClass?: ClassNameValue;
|
|
23
|
-
|
|
25
|
+
error?: string;
|
|
26
|
+
label?: Snippet;
|
|
27
|
+
optionsSnippet?: Snippet;
|
|
24
28
|
icon?: Snippet;
|
|
25
29
|
onchange?: (event: Event) => void;
|
|
26
30
|
};
|
|
@@ -29,12 +33,30 @@
|
|
|
29
33
|
<script lang="ts">
|
|
30
34
|
import { twMerge } from 'tailwind-merge';
|
|
31
35
|
|
|
32
|
-
let {
|
|
36
|
+
let {
|
|
37
|
+
id,
|
|
38
|
+
name,
|
|
39
|
+
label,
|
|
40
|
+
labelText = "",
|
|
41
|
+
labelPosition = "right",
|
|
42
|
+
value = $bindable(),
|
|
43
|
+
options=$bindable([]),
|
|
44
|
+
size = "md",
|
|
45
|
+
disabled = $bindable(false),
|
|
46
|
+
firstDivClass,
|
|
47
|
+
secondDivClass,
|
|
48
|
+
labelClass,
|
|
49
|
+
optionsClass,
|
|
50
|
+
error,
|
|
51
|
+
onchange,
|
|
52
|
+
icon,
|
|
53
|
+
optionsSnippet,
|
|
54
|
+
...restProps}: SelectProps = $props();
|
|
33
55
|
|
|
34
56
|
const sizeMap = {
|
|
35
|
-
sm: "text-sm py-1
|
|
36
|
-
md: "text-base py-2
|
|
37
|
-
lg: "text-lg py-3
|
|
57
|
+
sm: "text-sm py-1 h-[2.05rem]",
|
|
58
|
+
md: "text-base py-2 h-[2.375rem]",
|
|
59
|
+
lg: "text-lg py-3 h-[2.8rem]",
|
|
38
60
|
};
|
|
39
61
|
|
|
40
62
|
const directionClass = {
|
|
@@ -45,18 +67,28 @@
|
|
|
45
67
|
};
|
|
46
68
|
</script>
|
|
47
69
|
|
|
48
|
-
<div class={twMerge("flex
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
70
|
+
<div class={twMerge("flex flex-col gap-1", firstDivClass)}>
|
|
71
|
+
<div class={twMerge("flex", directionClass[labelPosition] ?? directionClass.top, secondDivClass)}>
|
|
72
|
+
{#if label}
|
|
73
|
+
{@render label()}
|
|
74
|
+
{:else}
|
|
75
|
+
{#if labelText}
|
|
76
|
+
<label for={id} class={twMerge("text-sm font-medium text-primary-label-text ml-1 w-full", labelClass)}>{labelText}</label>
|
|
77
|
+
{/if}
|
|
78
|
+
{/if}
|
|
52
79
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{option.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
<select {id} name={name ?? id} bind:value {disabled} onchange={onchange}
|
|
81
|
+
class={twMerge("rounded-primary border border-primary-input-border focus:border-primary-focus focus:ring-primary-focus placeholder:opacity-50 disabled:bg-neutral-300/30 disabled:border-neutral-300/30",
|
|
82
|
+
sizeMap[size], error ? "bg-red-50 border-red-300" : "", restProps.class)}>
|
|
83
|
+
{@render optionsSnippet?.()}
|
|
84
|
+
{#each options as option}
|
|
85
|
+
<option value={option.value} disabled={option.disabled} class={twMerge("", optionsClass)}>
|
|
86
|
+
{option.key}
|
|
87
|
+
</option>
|
|
88
|
+
{/each}
|
|
89
|
+
</select>
|
|
90
|
+
</div>
|
|
91
|
+
{#if error}
|
|
92
|
+
<p class="text-sm text-red-500 mt-0.5 bg-red-100/30 px-2 rounded-primary">{error}</p>
|
|
93
|
+
{/if}
|
|
62
94
|
</div>
|
|
@@ -2,22 +2,26 @@ import type { ClassNameValue } from 'tailwind-merge';
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
export type Option = {
|
|
4
4
|
value: string | number;
|
|
5
|
-
|
|
5
|
+
key: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
};
|
|
8
8
|
export type SelectProps = {
|
|
9
9
|
id: string;
|
|
10
10
|
name?: string;
|
|
11
|
-
|
|
11
|
+
labelText?: string;
|
|
12
12
|
disabled?: boolean;
|
|
13
13
|
value?: string | number;
|
|
14
|
-
options
|
|
14
|
+
options?: Option[];
|
|
15
15
|
size?: "sm" | "md" | "lg";
|
|
16
16
|
labelPosition?: "left" | "top" | "right" | "bottom";
|
|
17
17
|
class?: ClassNameValue;
|
|
18
18
|
labelClass?: ClassNameValue;
|
|
19
|
+
firstDivClass?: ClassNameValue;
|
|
20
|
+
secondDivClass?: ClassNameValue;
|
|
19
21
|
optionsClass?: ClassNameValue;
|
|
20
|
-
|
|
22
|
+
error?: string;
|
|
23
|
+
label?: Snippet;
|
|
24
|
+
optionsSnippet?: Snippet;
|
|
21
25
|
icon?: Snippet;
|
|
22
26
|
onchange?: (event: Event) => void;
|
|
23
27
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { FullAutoFill, HTMLAttributes } from 'svelte/elements';
|
|
3
4
|
import type { ClassNameValue } from 'tailwind-merge';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -9,7 +10,8 @@
|
|
|
9
10
|
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
10
11
|
*/
|
|
11
12
|
export type TextInputSize = "sm" | "md" | "lg";
|
|
12
|
-
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url";
|
|
13
|
+
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url" | "search";
|
|
14
|
+
export type InputMode = "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Props for the TextBox component.
|
|
@@ -31,18 +33,30 @@
|
|
|
31
33
|
export type TextInputProps = {
|
|
32
34
|
id: string;
|
|
33
35
|
name?: string;
|
|
34
|
-
value?: string;
|
|
36
|
+
value?: string|number;
|
|
35
37
|
type?: TextInputType;
|
|
36
38
|
placeholder?: string;
|
|
37
39
|
labelText?: string;
|
|
40
|
+
labelPosition?: "top" | "left" | "right" | "bottom";
|
|
38
41
|
size?: TextInputSize;
|
|
39
42
|
disabled?: boolean;
|
|
40
43
|
required?: boolean;
|
|
41
44
|
error?: string;
|
|
42
|
-
|
|
45
|
+
labelClass?: ClassNameValue;
|
|
46
|
+
firstDivClass?: ClassNameValue;
|
|
47
|
+
secondDivClass?: ClassNameValue;
|
|
48
|
+
thirdDivClass?: ClassNameValue;
|
|
49
|
+
autocomplete?: FullAutoFill | null;
|
|
50
|
+
inputmode?: InputMode;
|
|
51
|
+
min?: number;
|
|
52
|
+
max?: number;
|
|
53
|
+
debounceDelay?: number;
|
|
54
|
+
onInput?: (value: string|number) => void;
|
|
55
|
+
onchange?: (event: Event) => void;
|
|
43
56
|
onmouseup?: () => void;
|
|
44
57
|
label?: Snippet;
|
|
45
|
-
|
|
58
|
+
leftIcon?: Snippet;
|
|
59
|
+
rightIcon?: Snippet;
|
|
46
60
|
class?: ClassNameValue;
|
|
47
61
|
};
|
|
48
62
|
|
|
@@ -51,8 +65,35 @@
|
|
|
51
65
|
|
|
52
66
|
<script lang="ts">
|
|
53
67
|
import { twMerge } from 'tailwind-merge';
|
|
54
|
-
|
|
55
|
-
let {
|
|
68
|
+
|
|
69
|
+
let {
|
|
70
|
+
id,
|
|
71
|
+
type="text",
|
|
72
|
+
name="",
|
|
73
|
+
value=$bindable(""),
|
|
74
|
+
placeholder="",
|
|
75
|
+
labelText="",
|
|
76
|
+
labelClass,
|
|
77
|
+
labelPosition="top",
|
|
78
|
+
size="md",
|
|
79
|
+
disabled=false,
|
|
80
|
+
required=false,
|
|
81
|
+
error,
|
|
82
|
+
firstDivClass,
|
|
83
|
+
secondDivClass,
|
|
84
|
+
thirdDivClass,
|
|
85
|
+
autocomplete,
|
|
86
|
+
inputmode,
|
|
87
|
+
min,
|
|
88
|
+
max,
|
|
89
|
+
debounceDelay=300, //ms
|
|
90
|
+
onchange,
|
|
91
|
+
onInput,
|
|
92
|
+
onmouseup,
|
|
93
|
+
label,
|
|
94
|
+
leftIcon,
|
|
95
|
+
rightIcon,
|
|
96
|
+
...restProps}: TextInputProps = $props();
|
|
56
97
|
|
|
57
98
|
/**
|
|
58
99
|
* Predefined size classes for the TextBox input.
|
|
@@ -61,25 +102,61 @@
|
|
|
61
102
|
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
62
103
|
*/
|
|
63
104
|
let sizeStyle: Record<TextInputSize, string> = {
|
|
64
|
-
sm: "
|
|
65
|
-
md: "
|
|
66
|
-
lg: "
|
|
105
|
+
sm: "text-sm placeholder:text-sm",
|
|
106
|
+
md: "text-sm placeholder:text-sm",
|
|
107
|
+
lg: "text-base placeholder:text-base"
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
let textBoxStyle: Record<TextInputSize, string> = {
|
|
111
|
+
sm: "h-[2.05rem] px-2.5",
|
|
112
|
+
md: "h-[2.375rem] px-2.5",
|
|
113
|
+
lg: "h-[2.8rem] px-3"
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const directionClass = {
|
|
117
|
+
top: "flex-col gap-1",
|
|
118
|
+
bottom: "flex-col-reverse gap-1",
|
|
119
|
+
left: "flex-row items-center gap-2",
|
|
120
|
+
right: "flex-row-reverse items-center gap-2",
|
|
67
121
|
};
|
|
68
122
|
|
|
123
|
+
// --- Debounce logic ---
|
|
124
|
+
let localValue = value; // local for immediate typing
|
|
125
|
+
let debounceTimer: ReturnType<typeof setTimeout>;
|
|
126
|
+
|
|
127
|
+
function handleInput(e: Event) {
|
|
128
|
+
localValue = (e.target as HTMLInputElement).value;
|
|
129
|
+
clearTimeout(debounceTimer);
|
|
130
|
+
debounceTimer = setTimeout(() => {
|
|
131
|
+
value = localValue; // sync to bound value after delay
|
|
132
|
+
onInput?.(value); // call handler if provided
|
|
133
|
+
}, debounceDelay);
|
|
134
|
+
}
|
|
135
|
+
|
|
69
136
|
</script>
|
|
70
137
|
|
|
71
|
-
<div class="
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{#if
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
138
|
+
<div class={twMerge("", firstDivClass)}>
|
|
139
|
+
<div class={twMerge("flex rounded-primary", directionClass[labelPosition] ?? directionClass.top, secondDivClass)}>
|
|
140
|
+
|
|
141
|
+
{#if label}{@render label()}{/if}
|
|
142
|
+
{#if !label && labelText}<label for={id} class={twMerge("text-sm font-medium text-primary-label-text ml-1", labelClass)}>{labelText}</label>{/if}
|
|
143
|
+
|
|
144
|
+
<!-- Text Box -->
|
|
145
|
+
<div class={twMerge("flex flex-row items-center rounded-primary border border-primary-input-border gap-2 focus-within:ring focus-within:border-primary-focus focus-within:ring-primary-focus has-[input:disabled]:bg-neutral-300/30 has-[input:disabled]:border-neutral-300/30",
|
|
146
|
+
error ? "bg-red-50 border-red-300" : "", textBoxStyle[size], thirdDivClass)}>
|
|
147
|
+
|
|
148
|
+
{#if leftIcon}<div class="h-full flex flex-col items-center justify-center">{@render leftIcon()}</div>{/if}
|
|
149
|
+
|
|
150
|
+
<input {disabled} {required} {type} {id} name={name ? name: id} {placeholder} {onmouseup} bind:value {autocomplete} {inputmode} {min} {max} oninput={handleInput}
|
|
151
|
+
class={twMerge("border-0 focus:border-0 focus:ring-0 active:border-0 outline-none p-0 bg-transparent placeholder:text-neutral-600/50 h-full w-full", sizeStyle[size], restProps.class)} />
|
|
152
|
+
|
|
153
|
+
{#if rightIcon}<div class="h-full flex flex-col items-center justify-center">{@render rightIcon()}</div>{/if}
|
|
154
|
+
</div>
|
|
155
|
+
|
|
81
156
|
</div>
|
|
157
|
+
|
|
82
158
|
{#if error}
|
|
83
159
|
<p class="text-sm text-red-500 mt-0.5 bg-red-100/30 px-2 rounded-primary">{error}</p>
|
|
84
160
|
{/if}
|
|
161
|
+
|
|
85
162
|
</div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FullAutoFill } from 'svelte/elements';
|
|
2
3
|
import type { ClassNameValue } from 'tailwind-merge';
|
|
3
4
|
/**
|
|
4
5
|
* Predefined size classes for the TextBox input.
|
|
@@ -7,7 +8,8 @@ import type { ClassNameValue } from 'tailwind-merge';
|
|
|
7
8
|
* - "lg": h-[2.8rem] text-lg placeholder:text-lg
|
|
8
9
|
*/
|
|
9
10
|
export type TextInputSize = "sm" | "md" | "lg";
|
|
10
|
-
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url";
|
|
11
|
+
export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "url" | "search";
|
|
12
|
+
export type InputMode = "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
|
|
11
13
|
/**
|
|
12
14
|
* Props for the TextBox component.
|
|
13
15
|
*
|
|
@@ -28,18 +30,30 @@ export type TextInputType = "text" | "password" | "number" | "email" | "tel" | "
|
|
|
28
30
|
export type TextInputProps = {
|
|
29
31
|
id: string;
|
|
30
32
|
name?: string;
|
|
31
|
-
value?: string;
|
|
33
|
+
value?: string | number;
|
|
32
34
|
type?: TextInputType;
|
|
33
35
|
placeholder?: string;
|
|
34
36
|
labelText?: string;
|
|
37
|
+
labelPosition?: "top" | "left" | "right" | "bottom";
|
|
35
38
|
size?: TextInputSize;
|
|
36
39
|
disabled?: boolean;
|
|
37
40
|
required?: boolean;
|
|
38
41
|
error?: string;
|
|
39
|
-
|
|
42
|
+
labelClass?: ClassNameValue;
|
|
43
|
+
firstDivClass?: ClassNameValue;
|
|
44
|
+
secondDivClass?: ClassNameValue;
|
|
45
|
+
thirdDivClass?: ClassNameValue;
|
|
46
|
+
autocomplete?: FullAutoFill | null;
|
|
47
|
+
inputmode?: InputMode;
|
|
48
|
+
min?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
debounceDelay?: number;
|
|
51
|
+
onInput?: (value: string | number) => void;
|
|
52
|
+
onchange?: (event: Event) => void;
|
|
40
53
|
onmouseup?: () => void;
|
|
41
54
|
label?: Snippet;
|
|
42
|
-
|
|
55
|
+
leftIcon?: Snippet;
|
|
56
|
+
rightIcon?: Snippet;
|
|
43
57
|
class?: ClassNameValue;
|
|
44
58
|
};
|
|
45
59
|
declare const TextInput: import("svelte").Component<TextInputProps, {}, "value">;
|
package/dist/index.d.ts
CHANGED
|
@@ -22,3 +22,7 @@ export * from './modules/api-proxy.js';
|
|
|
22
22
|
export * from './modules/crypto.js';
|
|
23
23
|
export * from './modules/problem-details.js';
|
|
24
24
|
export * from './functions/object-to-form-data.js';
|
|
25
|
+
export * from './ui/headers/header-1/index.js';
|
|
26
|
+
export * from './ui/footers/footer-1/index.js';
|
|
27
|
+
export * from './ui/banners/banner-1/index.js';
|
|
28
|
+
export * from './ui/featured-products/featured-products-1/index.js';
|
package/dist/index.js
CHANGED
|
@@ -24,4 +24,8 @@ export * from './modules/api-proxy.js';
|
|
|
24
24
|
export * from './modules/crypto.js';
|
|
25
25
|
export * from './modules/problem-details.js';
|
|
26
26
|
export * from './functions/object-to-form-data.js';
|
|
27
|
+
export * from './ui/headers/header-1/index.js';
|
|
28
|
+
export * from './ui/footers/footer-1/index.js';
|
|
29
|
+
export * from './ui/banners/banner-1/index.js';
|
|
30
|
+
export * from './ui/featured-products/featured-products-1/index.js';
|
|
27
31
|
// Add more components here...
|
|
@@ -15,6 +15,8 @@ export interface RestApiProxyConfig {
|
|
|
15
15
|
safeResponseHeaders?: string[];
|
|
16
16
|
/** Optional function to extract token from session */
|
|
17
17
|
extractToken?: (locals: App.Locals) => string | undefined;
|
|
18
|
+
/** Optional path to prepend to the proxied path */
|
|
19
|
+
prependPath?: string;
|
|
18
20
|
/** Optional flag to enable debug logging */
|
|
19
21
|
debug?: boolean;
|
|
20
22
|
}
|
|
@@ -11,7 +11,9 @@ export function createProxyHandlers(config) {
|
|
|
11
11
|
const path = event.params.path;
|
|
12
12
|
const queryString = event.url.searchParams.toString();
|
|
13
13
|
const slash = config.appendSlash ? '/' : '';
|
|
14
|
-
const
|
|
14
|
+
const prepend = config.prependPath ? `/${config.prependPath}/` : '/';
|
|
15
|
+
const fullPath = `${prepend}${path}${slash}${queryString ? `?${queryString}` : ''}`;
|
|
16
|
+
console.log("Full Path:", fullPath);
|
|
15
17
|
const url = `${config.host}${fullPath}`;
|
|
16
18
|
if (config.debug)
|
|
17
19
|
console.debug(`API Proxy: Proxying ${event.request.method} request to: ${url}`);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
export type Banner1Props = {
|
|
5
|
+
mainText: string;
|
|
6
|
+
subText?: string;
|
|
7
|
+
image?: string;
|
|
8
|
+
primaryButtonText?: string;
|
|
9
|
+
primaryButtonLink?: string;
|
|
10
|
+
secondaryButtonText?: string;
|
|
11
|
+
secondaryButtonLink?: string;
|
|
12
|
+
class?: ClassNameValue;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import { twMerge } from "tailwind-merge";
|
|
19
|
+
|
|
20
|
+
let { mainText, subText, image, primaryButtonText, primaryButtonLink, secondaryButtonText, secondaryButtonLink, ...restProps }: Banner1Props = $props();
|
|
21
|
+
let style = image ? "background-image: url('" + image + "');" : "";
|
|
22
|
+
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<section class={twMerge("lg:grid", restProps.class)} {style}>
|
|
26
|
+
<div class="mx-auto w-screen max-w-screen-xl px-4 py-16 sm:px-6 sm:py-24 lg:px-8 lg:py-32">
|
|
27
|
+
<div class="mx-auto max-w-prose text-center">
|
|
28
|
+
<h1 class="text-4xl font-bold text-gray-900 sm:text-5xl">{@html mainText}</h1>
|
|
29
|
+
<p class="mt-4 text-base text-pretty text-gray-700 sm:text-lg/relaxed dark:text-gray-200">{subText}</p>
|
|
30
|
+
|
|
31
|
+
{#if primaryButtonText || secondaryButtonText}
|
|
32
|
+
<div class="mt-4 flex justify-center gap-4 sm:mt-6">
|
|
33
|
+
{#if primaryButtonText && primaryButtonLink}
|
|
34
|
+
<a class="inline-block rounded-primary bg-primary-button px-5 py-3 font-medium text-white shadow-primary transition-colors hover:bg-primary-button-hover"
|
|
35
|
+
href={primaryButtonLink}>{primaryButtonText}</a>
|
|
36
|
+
{/if}
|
|
37
|
+
|
|
38
|
+
{#if secondaryButtonText && secondaryButtonLink}
|
|
39
|
+
<a class="inline-block bg-white rounded-primary border border-gray-200 px-5 py-3 font-medium text-gray-700 shadow-primary transition-colors
|
|
40
|
+
hover:bg-gray-50 hover:text-gray-900" href={secondaryButtonLink}>
|
|
41
|
+
{secondaryButtonText}</a>
|
|
42
|
+
{/if}
|
|
43
|
+
</div>
|
|
44
|
+
{/if}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</section>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ClassNameValue } from 'tailwind-merge';
|
|
2
|
+
export type Banner1Props = {
|
|
3
|
+
mainText: string;
|
|
4
|
+
subText?: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
primaryButtonText?: string;
|
|
7
|
+
primaryButtonLink?: string;
|
|
8
|
+
secondaryButtonText?: string;
|
|
9
|
+
secondaryButtonLink?: string;
|
|
10
|
+
class?: ClassNameValue;
|
|
11
|
+
};
|
|
12
|
+
declare const Banner1: import("svelte").Component<Banner1Props, {}, "">;
|
|
13
|
+
type Banner1 = ReturnType<typeof Banner1>;
|
|
14
|
+
export default Banner1;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Banner1 } from './Banner1.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Banner1 } from './Banner1.svelte';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { twMerge, type ClassNameValue } from "tailwind-merge";
|
|
3
|
+
let {filters=$bindable([]), onRemove, onClear, ...restProps}:
|
|
4
|
+
{
|
|
5
|
+
filters: { key: string; value: string }[];
|
|
6
|
+
onRemove: (key: string, value: string) => void;
|
|
7
|
+
onClear: () => void;
|
|
8
|
+
class?: ClassNameValue;
|
|
9
|
+
} = $props();
|
|
10
|
+
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<nav aria-label="Breadcrumb filters" class={twMerge("flex flex-wrap items-center gap-2 text-sm", restProps.class)}>
|
|
14
|
+
|
|
15
|
+
<!-- Dynamic filters -->
|
|
16
|
+
{#if filters.length > 0}
|
|
17
|
+
{#each filters as { key, value }}
|
|
18
|
+
<button class="flex items-center gap-1 rounded-full bg-neutral-100 px-3 py-1 text-neutral-700 hover:bg-neutral-200 cursor-pointer break-all" onclick={() => onRemove?.(key, value)}>
|
|
19
|
+
<span class="capitalize text-neutral-600">{key}:</span>
|
|
20
|
+
<span class="font-medium">{value}</span>
|
|
21
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-4 w-4 text-neutral-500 shrink-0">
|
|
22
|
+
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0
|
|
23
|
+
01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
24
|
+
</svg>
|
|
25
|
+
</button>
|
|
26
|
+
{/each}
|
|
27
|
+
<!-- Clear all -->
|
|
28
|
+
<button class="text-red-600 hover:underline cursor-pointer" onclick={onClear}>Clear all</button>
|
|
29
|
+
{/if}
|
|
30
|
+
</nav>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ClassNameValue } from "tailwind-merge";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
filters: {
|
|
4
|
+
key: string;
|
|
5
|
+
value: string;
|
|
6
|
+
}[];
|
|
7
|
+
onRemove: (key: string, value: string) => void;
|
|
8
|
+
onClear: () => void;
|
|
9
|
+
class?: ClassNameValue;
|
|
10
|
+
};
|
|
11
|
+
declare const Breadcrumbs1: import("svelte").Component<$$ComponentProps, {}, "filters">;
|
|
12
|
+
type Breadcrumbs1 = ReturnType<typeof Breadcrumbs1>;
|
|
13
|
+
export default Breadcrumbs1;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Breadcrumbs1 } from './Breadcrumbs1.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Breadcrumbs1 } from './Breadcrumbs1.svelte';
|