@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.
Files changed (58) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +6 -0
  3. package/dist/components/button/Button.svelte +6 -5
  4. package/dist/components/button/Button.svelte.d.ts +3 -2
  5. package/dist/components/button/index.d.ts +1 -1
  6. package/dist/components/hamburger-menu/HamburgerMenu.svelte +2 -2
  7. package/dist/components/hamburger-menu/HamburgerMenu.svelte.d.ts +1 -1
  8. package/dist/components/select/Select.svelte +53 -21
  9. package/dist/components/select/Select.svelte.d.ts +8 -4
  10. package/dist/components/text-input/TextInput.svelte +96 -19
  11. package/dist/components/text-input/TextInput.svelte.d.ts +18 -4
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.js +4 -0
  14. package/dist/modules/api-proxy.d.ts +2 -0
  15. package/dist/modules/api-proxy.js +3 -1
  16. package/dist/ui/banners/banner-1/Banner1.svelte +47 -0
  17. package/dist/ui/banners/banner-1/Banner1.svelte.d.ts +14 -0
  18. package/dist/ui/banners/banner-1/index.d.ts +1 -0
  19. package/dist/ui/banners/banner-1/index.js +1 -0
  20. package/dist/ui/breadcrumbs/breadcrumbs-1/Breadcrumbs1.svelte +30 -0
  21. package/dist/ui/breadcrumbs/breadcrumbs-1/Breadcrumbs1.svelte.d.ts +13 -0
  22. package/dist/ui/breadcrumbs/breadcrumbs-1/index.d.ts +1 -0
  23. package/dist/ui/breadcrumbs/breadcrumbs-1/index.js +1 -0
  24. package/dist/ui/featured-products/featured-products-1/FeaturedProducts1.svelte +56 -0
  25. package/dist/ui/featured-products/featured-products-1/FeaturedProducts1.svelte.d.ts +22 -0
  26. package/dist/ui/featured-products/featured-products-1/index.d.ts +1 -0
  27. package/dist/ui/featured-products/featured-products-1/index.js +1 -0
  28. package/dist/ui/footers/footer-1/Footer1.svelte +81 -0
  29. package/dist/ui/footers/footer-1/Footer1.svelte.d.ts +18 -0
  30. package/dist/ui/footers/footer-1/index.d.ts +1 -0
  31. package/dist/ui/footers/footer-1/index.js +1 -0
  32. package/dist/ui/headers/header-1/Header1.svelte +94 -0
  33. package/dist/ui/headers/header-1/Header1.svelte.d.ts +15 -0
  34. package/dist/ui/headers/header-1/index.d.ts +1 -0
  35. package/dist/ui/headers/header-1/index.js +1 -0
  36. package/dist/ui/order-product-line-item/order-product-line-item-1/OrderProductLineItem1.svelte +74 -0
  37. package/dist/ui/order-product-line-item/order-product-line-item-1/OrderProductLineItem1.svelte.d.ts +15 -0
  38. package/dist/ui/order-product-line-item/order-product-line-item-1/index.d.ts +1 -0
  39. package/dist/ui/order-product-line-item/order-product-line-item-1/index.js +1 -0
  40. package/dist/ui/product-filters/product-filter-1/ProductFilter1.svelte +42 -0
  41. package/dist/ui/product-filters/product-filter-1/ProductFilter1.svelte.d.ts +26 -0
  42. package/dist/ui/product-filters/product-filter-1/ProductFilterBlock.svelte +49 -0
  43. package/dist/ui/product-filters/product-filter-1/ProductFilterBlock.svelte.d.ts +17 -0
  44. package/dist/ui/product-filters/product-filter-1/index.d.ts +1 -0
  45. package/dist/ui/product-filters/product-filter-1/index.js +1 -0
  46. package/dist/ui/product-list/product-list-1/ProductList1.svelte +76 -0
  47. package/dist/ui/product-list/product-list-1/ProductList1.svelte.d.ts +24 -0
  48. package/dist/ui/product-list/product-list-1/index.d.ts +1 -0
  49. package/dist/ui/product-list/product-list-1/index.js +1 -0
  50. package/dist/ui/product-list-navigation/product-list-navigation-1/ProductListNavigation1.svelte +51 -0
  51. package/dist/ui/product-list-navigation/product-list-navigation-1/ProductListNavigation1.svelte.d.ts +12 -0
  52. package/dist/ui/product-list-navigation/product-list-navigation-1/index.d.ts +1 -0
  53. package/dist/ui/product-list-navigation/product-list-navigation-1/index.js +1 -0
  54. package/dist/ui/searchbox/Searchbox.svelte +46 -0
  55. package/dist/ui/searchbox/Searchbox.svelte.d.ts +13 -0
  56. package/dist/ui/searchbox/index.d.ts +1 -0
  57. package/dist/ui/searchbox/index.js +1 -0
  58. 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
- activeIcon?: Snippet;
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, activeIcon, onclick, ...props }: ButtonProps = $props();
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 activeIcon}
27
- <span>{@render activeIcon()}</span>
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
- activeIcon?: Snippet;
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: string;
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: string;
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
- label: string;
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
- label?: string;
14
+ labelText?: string;
15
15
  disabled?: boolean;
16
16
  value?: string | number;
17
- options: Option[];
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
- parentDivClass?: ClassNameValue;
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 { id, name, label = "", labelPosition = "top", value = $bindable(), options=$bindable([]), size = "md", disabled = $bindable(false), labelClass, parentDivClass, optionsClass, onchange, ...restProps}: SelectProps = $props();
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 px-2 h-8",
36
- md: "text-base py-2 px-3 h-10",
37
- lg: "text-lg py-3 px-4 h-12",
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", directionClass[labelPosition] ?? directionClass.top, parentDivClass)}>
49
- {#if label}
50
- <label for={id} class={twMerge("text-sm font-medium text-primary-label-text ml-1", labelClass)}>{label}</label>
51
- {/if}
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
- <select {id} name={name ?? id} bind:value {disabled} onchange={onchange}
54
- 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",
55
- sizeMap[size], restProps.class)}>
56
- {#each options as option}
57
- <option value={option.value} disabled={option.disabled} class={twMerge("", optionsClass)}>
58
- {option.label}
59
- </option>
60
- {/each}
61
- </select>
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
- label: string;
5
+ key: string;
6
6
  disabled?: boolean;
7
7
  };
8
8
  export type SelectProps = {
9
9
  id: string;
10
10
  name?: string;
11
- label?: string;
11
+ labelText?: string;
12
12
  disabled?: boolean;
13
13
  value?: string | number;
14
- options: Option[];
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
- parentDivClass?: ClassNameValue;
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
- onchange?: () => void;
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
- icon?: Snippet;
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 { id, type="text", name="", value=$bindable(""), placeholder="", labelText, size="md", disabled=false, required=false, error, onchange, onmouseup, label, icon, ...props}: TextInputProps = $props();
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: "h-[2.05rem] text-sm placeholder:text-sm",
65
- md: "h-[2.375rem] text-sm placeholder:text-sm",
66
- lg: "h-[2.8rem] text-base placeholder:text-base"
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="flex flex-col gap-1 w-full">
72
- {#if label}{@render label()}{:else}{#if labelText}<label for={id} class="text-sm font-medium text-primary-label-text ml-1">{labelText}</label>{/if}{/if}
73
- <div class="relative">
74
- {#if icon}<div class="absolute inset-y-0 left-0 flex items-center justify-center rounded-l-primary m-0.5 w-10">{@render icon()}</div>{/if}
75
- <input {disabled} {required} {type} {id} name={name ? name: id} {placeholder} {onchange} {onmouseup} bind:value
76
- 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",
77
- error ? "bg-red-50 border-red-300" : "",
78
- icon ? "pl-10" : "",
79
- sizeStyle[size], props.class)}
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
- onchange?: () => void;
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
- icon?: Snippet;
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 fullPath = `/${path}${slash}${queryString ? `?${queryString}` : ''}`;
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';