lutra 0.0.33 → 0.1.0

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 (242) hide show
  1. package/README.md +4 -24
  2. package/dist/components/AspectRatio.svelte +26 -0
  3. package/dist/components/AspectRatio.svelte.d.ts +8 -0
  4. package/dist/components/Dialog.svelte +78 -0
  5. package/dist/components/Dialog.svelte.d.ts +14 -0
  6. package/dist/components/Layout.svelte +32 -0
  7. package/dist/components/Layout.svelte.d.ts +11 -0
  8. package/dist/components/PageContent.svelte +108 -0
  9. package/dist/components/PageContent.svelte.d.ts +38 -0
  10. package/dist/components/Theme.svelte +87 -0
  11. package/dist/components/Theme.svelte.d.ts +17 -0
  12. package/dist/{display → components}/Tooltip.svelte +33 -8
  13. package/dist/components/Tooltip.svelte.d.ts +12 -0
  14. package/dist/config.d.ts +30 -0
  15. package/dist/config.js +18 -0
  16. package/dist/css/0-layers.css +1 -0
  17. package/dist/css/1-props.css +775 -0
  18. package/dist/css/2-base.css +209 -0
  19. package/dist/css/3-typo.css +65 -0
  20. package/dist/css/4-layout.css +5 -0
  21. package/dist/css/5-media.css +21 -0
  22. package/dist/css/lutra.css +6 -0
  23. package/dist/index.d.ts +5 -1
  24. package/dist/index.js +5 -2
  25. package/dist/types.d.ts +39 -0
  26. package/dist/types.js +25 -0
  27. package/package.json +29 -82
  28. package/dist/color.css +0 -0
  29. package/dist/display/Avatar.svelte +0 -61
  30. package/dist/display/Avatar.svelte.d.ts +0 -19
  31. package/dist/display/Badge.svelte +0 -91
  32. package/dist/display/Badge.svelte.d.ts +0 -30
  33. package/dist/display/Callout.svelte +0 -109
  34. package/dist/display/Callout.svelte.d.ts +0 -28
  35. package/dist/display/Close.svelte +0 -58
  36. package/dist/display/Close.svelte.d.ts +0 -18
  37. package/dist/display/Code.svelte +0 -190
  38. package/dist/display/Code.svelte.d.ts +0 -32
  39. package/dist/display/ContextTip.svelte +0 -23
  40. package/dist/display/ContextTip.svelte.d.ts +0 -18
  41. package/dist/display/DataList.svelte +0 -16
  42. package/dist/display/DataList.svelte.d.ts +0 -21
  43. package/dist/display/Details.svelte +0 -49
  44. package/dist/display/Details.svelte.d.ts +0 -27
  45. package/dist/display/Hero.svelte +0 -50
  46. package/dist/display/Hero.svelte.d.ts +0 -26
  47. package/dist/display/Icon.svelte +0 -39
  48. package/dist/display/Icon.svelte.d.ts +0 -19
  49. package/dist/display/IconButton.svelte +0 -91
  50. package/dist/display/IconButton.svelte.d.ts +0 -27
  51. package/dist/display/Image.svelte +0 -91
  52. package/dist/display/Image.svelte.d.ts +0 -26
  53. package/dist/display/Indicator.svelte +0 -352
  54. package/dist/display/Indicator.svelte.d.ts +0 -23
  55. package/dist/display/Inset.svelte +0 -18
  56. package/dist/display/Inset.svelte.d.ts +0 -18
  57. package/dist/display/LineChart.svelte +0 -385
  58. package/dist/display/LineChart.svelte.d.ts +0 -24
  59. package/dist/display/LoadingIndicator.svelte +0 -33
  60. package/dist/display/LoadingIndicator.svelte.d.ts +0 -15
  61. package/dist/display/Modal.svelte +0 -116
  62. package/dist/display/Modal.svelte.d.ts +0 -27
  63. package/dist/display/Notification.svelte +0 -104
  64. package/dist/display/Notification.svelte.d.ts +0 -23
  65. package/dist/display/Panel.svelte +0 -23
  66. package/dist/display/Panel.svelte.d.ts +0 -19
  67. package/dist/display/Popup.svelte +0 -111
  68. package/dist/display/Popup.svelte.d.ts +0 -25
  69. package/dist/display/Stat.svelte +0 -81
  70. package/dist/display/Stat.svelte.d.ts +0 -30
  71. package/dist/display/Table.svelte +0 -28
  72. package/dist/display/Table.svelte.d.ts +0 -24
  73. package/dist/display/TablePaginator.svelte +0 -51
  74. package/dist/display/TablePaginator.svelte.d.ts +0 -21
  75. package/dist/display/Tag.svelte +0 -90
  76. package/dist/display/Tag.svelte.d.ts +0 -32
  77. package/dist/display/Tooltip.svelte.d.ts +0 -23
  78. package/dist/display/chart.d.ts +0 -78
  79. package/dist/display/chart.js +0 -212
  80. package/dist/display/index.d.ts +0 -24
  81. package/dist/display/index.js +0 -24
  82. package/dist/display/notifications.svelte.d.ts +0 -21
  83. package/dist/display/notifications.svelte.js +0 -31
  84. package/dist/form/Button.svelte +0 -39
  85. package/dist/form/Button.svelte.d.ts +0 -26
  86. package/dist/form/FieldActions.svelte +0 -68
  87. package/dist/form/FieldActions.svelte.d.ts +0 -20
  88. package/dist/form/FieldContainer.svelte +0 -37
  89. package/dist/form/FieldContainer.svelte.d.ts +0 -19
  90. package/dist/form/FieldContent.svelte +0 -153
  91. package/dist/form/FieldContent.svelte.d.ts +0 -31
  92. package/dist/form/FieldError.svelte +0 -14
  93. package/dist/form/FieldError.svelte.d.ts +0 -18
  94. package/dist/form/FieldSection.svelte +0 -86
  95. package/dist/form/FieldSection.svelte.d.ts +0 -20
  96. package/dist/form/Fieldset.svelte +0 -68
  97. package/dist/form/Fieldset.svelte.d.ts +0 -31
  98. package/dist/form/Form.svelte +0 -136
  99. package/dist/form/Form.svelte.d.ts +0 -38
  100. package/dist/form/ImageUpload.svelte +0 -259
  101. package/dist/form/ImageUpload.svelte.d.ts +0 -31
  102. package/dist/form/Input.svelte +0 -326
  103. package/dist/form/Input.svelte.d.ts +0 -117
  104. package/dist/form/InputLength.svelte +0 -32
  105. package/dist/form/InputLength.svelte.d.ts +0 -20
  106. package/dist/form/Label.svelte +0 -44
  107. package/dist/form/Label.svelte.d.ts +0 -25
  108. package/dist/form/LogoUpload.svelte +0 -100
  109. package/dist/form/LogoUpload.svelte.d.ts +0 -29
  110. package/dist/form/Select.svelte +0 -136
  111. package/dist/form/Select.svelte.d.ts +0 -70
  112. package/dist/form/Textarea.svelte +0 -163
  113. package/dist/form/Textarea.svelte.d.ts +0 -108
  114. package/dist/form/Toggle.svelte +0 -2
  115. package/dist/form/Toggle.svelte.d.ts +0 -15
  116. package/dist/form/client.svelte.d.ts +0 -44
  117. package/dist/form/client.svelte.js +0 -98
  118. package/dist/form/form.d.ts +0 -54
  119. package/dist/form/form.js +0 -340
  120. package/dist/form/index.d.ts +0 -18
  121. package/dist/form/index.js +0 -18
  122. package/dist/form/types.d.ts +0 -62
  123. package/dist/form/types.js +0 -1
  124. package/dist/icons/IconAlert.svelte +0 -3
  125. package/dist/icons/IconAlert.svelte.d.ts +0 -23
  126. package/dist/icons/IconCopy.svelte +0 -3
  127. package/dist/icons/IconCopy.svelte.d.ts +0 -23
  128. package/dist/icons/IconDone.svelte +0 -3
  129. package/dist/icons/IconDone.svelte.d.ts +0 -23
  130. package/dist/icons/IconError.svelte +0 -3
  131. package/dist/icons/IconError.svelte.d.ts +0 -23
  132. package/dist/icons/IconHelp.svelte +0 -3
  133. package/dist/icons/IconHelp.svelte.d.ts +0 -23
  134. package/dist/icons/IconHide.svelte +0 -3
  135. package/dist/icons/IconHide.svelte.d.ts +0 -23
  136. package/dist/icons/IconInfo.svelte +0 -3
  137. package/dist/icons/IconInfo.svelte.d.ts +0 -23
  138. package/dist/icons/IconLink.svelte +0 -3
  139. package/dist/icons/IconLink.svelte.d.ts +0 -23
  140. package/dist/icons/IconMenuBurger.svelte +0 -3
  141. package/dist/icons/IconMenuBurger.svelte.d.ts +0 -23
  142. package/dist/icons/IconMenuDots.svelte +0 -3
  143. package/dist/icons/IconMenuDots.svelte.d.ts +0 -23
  144. package/dist/icons/IconSearch.svelte +0 -3
  145. package/dist/icons/IconSearch.svelte.d.ts +0 -23
  146. package/dist/icons/IconShow.svelte +0 -3
  147. package/dist/icons/IconShow.svelte.d.ts +0 -23
  148. package/dist/icons/IconSuccess.svelte +0 -3
  149. package/dist/icons/IconSuccess.svelte.d.ts +0 -23
  150. package/dist/icons/IconWarning.svelte +0 -3
  151. package/dist/icons/IconWarning.svelte.d.ts +0 -23
  152. package/dist/icons/index.d.ts +0 -14
  153. package/dist/icons/index.js +0 -14
  154. package/dist/layout/Layout.svelte +0 -47
  155. package/dist/layout/Layout.svelte.d.ts +0 -22
  156. package/dist/layout/LayoutFooter.svelte +0 -21
  157. package/dist/layout/LayoutFooter.svelte.d.ts +0 -18
  158. package/dist/layout/LayoutGrid.svelte +0 -51
  159. package/dist/layout/LayoutGrid.svelte.d.ts +0 -27
  160. package/dist/layout/LayoutHeader.svelte +0 -97
  161. package/dist/layout/LayoutHeader.svelte.d.ts +0 -34
  162. package/dist/layout/LayoutSideMenu.svelte +0 -55
  163. package/dist/layout/LayoutSideMenu.svelte.d.ts +0 -21
  164. package/dist/layout/LayoutTypes.d.ts +0 -15
  165. package/dist/layout/LayoutTypes.js +0 -9
  166. package/dist/layout/Overlay.svelte +0 -20
  167. package/dist/layout/Overlay.svelte.d.ts +0 -25
  168. package/dist/layout/OverlayContainer.svelte +0 -28
  169. package/dist/layout/OverlayContainer.svelte.d.ts +0 -15
  170. package/dist/layout/OverlayLayer.svelte +0 -140
  171. package/dist/layout/OverlayLayer.svelte.d.ts +0 -19
  172. package/dist/layout/PageContent.svelte +0 -82
  173. package/dist/layout/PageContent.svelte.d.ts +0 -25
  174. package/dist/layout/Theme.svelte +0 -243
  175. package/dist/layout/Theme.svelte.d.ts +0 -19
  176. package/dist/layout/UIContent.svelte +0 -15
  177. package/dist/layout/UIContent.svelte.d.ts +0 -18
  178. package/dist/layout/index.d.ts +0 -11
  179. package/dist/layout/index.js +0 -11
  180. package/dist/layout/overlays.svelte.d.ts +0 -34
  181. package/dist/layout/overlays.svelte.js +0 -44
  182. package/dist/nav/Breadcrumb.svelte +0 -82
  183. package/dist/nav/Breadcrumb.svelte.d.ts +0 -28
  184. package/dist/nav/Menu.svelte +0 -170
  185. package/dist/nav/Menu.svelte.d.ts +0 -27
  186. package/dist/nav/MenuItem.svelte +0 -147
  187. package/dist/nav/MenuItem.svelte.d.ts +0 -22
  188. package/dist/nav/MenuTypes.d.ts +0 -58
  189. package/dist/nav/MenuTypes.js +0 -1
  190. package/dist/nav/NavMenu.svelte +0 -181
  191. package/dist/nav/NavMenu.svelte.d.ts +0 -19
  192. package/dist/nav/TabbedContent.svelte +0 -43
  193. package/dist/nav/TabbedContent.svelte.d.ts +0 -23
  194. package/dist/nav/Tabs.svelte +0 -158
  195. package/dist/nav/Tabs.svelte.d.ts +0 -25
  196. package/dist/nav/index.d.ts +0 -7
  197. package/dist/nav/index.js +0 -6
  198. package/dist/style.css +0 -950
  199. package/dist/typo/Clamp.svelte +0 -25
  200. package/dist/typo/Clamp.svelte.d.ts +0 -24
  201. package/dist/typo/H.svelte +0 -52
  202. package/dist/typo/H.svelte.d.ts +0 -28
  203. package/dist/typo/H1.svelte +0 -14
  204. package/dist/typo/H1.svelte.d.ts +0 -26
  205. package/dist/typo/H2.svelte +0 -14
  206. package/dist/typo/H2.svelte.d.ts +0 -26
  207. package/dist/typo/H3.svelte +0 -14
  208. package/dist/typo/H3.svelte.d.ts +0 -26
  209. package/dist/typo/H4.svelte +0 -14
  210. package/dist/typo/H4.svelte.d.ts +0 -26
  211. package/dist/typo/H5.svelte +0 -14
  212. package/dist/typo/H5.svelte.d.ts +0 -26
  213. package/dist/typo/H6.svelte +0 -14
  214. package/dist/typo/H6.svelte.d.ts +0 -26
  215. package/dist/typo/P.svelte +0 -34
  216. package/dist/typo/P.svelte.d.ts +0 -26
  217. package/dist/typo/index.d.ts +0 -9
  218. package/dist/typo/index.js +0 -9
  219. package/dist/utils/StringOrComponent.svelte +0 -14
  220. package/dist/utils/StringOrComponent.svelte.d.ts +0 -19
  221. package/dist/utils/StringOrSnippet.svelte +0 -11
  222. package/dist/utils/StringOrSnippet.svelte.d.ts +0 -19
  223. package/dist/utils/attr.d.ts +0 -5
  224. package/dist/utils/attr.js +0 -21
  225. package/dist/utils/color.d.ts +0 -51
  226. package/dist/utils/color.js +0 -97
  227. package/dist/utils/defaults.d.ts +0 -4
  228. package/dist/utils/defaults.js +0 -1
  229. package/dist/utils/dom.d.ts +0 -15
  230. package/dist/utils/dom.js +0 -74
  231. package/dist/utils/hooks.server.d.ts +0 -2
  232. package/dist/utils/hooks.server.js +0 -16
  233. package/dist/utils/id.d.ts +0 -1
  234. package/dist/utils/id.js +0 -3
  235. package/dist/utils/index.d.ts +0 -9
  236. package/dist/utils/index.js +0 -6
  237. package/dist/utils/isSnippet.d.ts +0 -3
  238. package/dist/utils/isSnippet.js +0 -11
  239. package/dist/utils/keyboard.svelte.d.ts +0 -22
  240. package/dist/utils/keyboard.svelte.js +0 -161
  241. /package/dist/{utils → util}/transitions.d.ts +0 -0
  242. /package/dist/{utils → util}/transitions.js +0 -0
@@ -1,259 +0,0 @@
1
- <script lang="ts">import { getContext, onMount } from "svelte";
2
- import imageCompression from "browser-image-compression";
3
- import { fade } from "svelte/transition";
4
- import { addNotification } from "../display/index.js";
5
- let {
6
- src,
7
- uploadUrl,
8
- name,
9
- id = `ImageUpload-${name}`,
10
- title = name,
11
- button,
12
- maxSize = 256e3,
13
- compressSize = 0.5,
14
- // MB
15
- compressMaxWidth = 512,
16
- // px
17
- accept = "image/png,image/svg+xml,image/jpg",
18
- removable = false,
19
- shape = "square",
20
- onFile,
21
- children
22
- } = $props();
23
- let files = $state(null);
24
- let el = $state(null);
25
- let urlEl = $state(null);
26
- let error = $state(null);
27
- let resizeProgress = $state(0);
28
- let uploadState = $state("idle");
29
- const beforeSubmit = getContext("form.beforeSubmit");
30
- beforeSubmit(id, async ({ data, cancel }) => {
31
- if (!files || !files[0]) {
32
- return;
33
- }
34
- try {
35
- uploadState = "resizing";
36
- resizeProgress = 0;
37
- const compressedFile = await imageCompression(files[0], {
38
- maxSizeMB: compressSize,
39
- maxWidthOrHeight: compressMaxWidth,
40
- useWebWorker: true,
41
- onProgress: (progress) => resizeProgress = progress
42
- });
43
- console.log("compressedFile instanceof Blob", compressedFile instanceof Blob);
44
- console.log(`compressedFile size ${compressedFile.size / 1024 / 1024} MB`);
45
- uploadState = "uploading";
46
- const response = await fetch(uploadUrl, {
47
- method: "PUT",
48
- headers: {
49
- "Content-Type": files[0].type
50
- },
51
- body: compressedFile
52
- });
53
- uploadState = "idle";
54
- if (!response.ok) {
55
- addNotification({ content: "Something went wrong. Please try again.", autoClose: 3e3 });
56
- cancel();
57
- }
58
- console.log("setting", name, new URL(response.url).href.split("?")[0]);
59
- const imgUrl = new URL(response.url).href.split("?")[0];
60
- data.set(name, imgUrl);
61
- src = imgUrl;
62
- console.log("response", response, response.url);
63
- console.log("data", data.forEach((v, k) => console.log(k, v)));
64
- } catch (err) {
65
- console.error("error", err);
66
- addNotification({ content: "Something went wrong. Please try again.", autoClose: 3e3 });
67
- cancel();
68
- }
69
- });
70
- function handleFile(event) {
71
- error = null;
72
- const file = files ? files[0] : null;
73
- if (file && file.type.startsWith("image/") && file.size < maxSize) {
74
- if (onFile) onFile(file);
75
- src = URL.createObjectURL(file);
76
- } else if (file && file.type.startsWith("image/") && file.size > maxSize) {
77
- error = `Image must be less than ${maxSize / 1024 / 1024}MB.`;
78
- } else {
79
- error = `File must be an image.`;
80
- }
81
- }
82
- function remove(e) {
83
- e.preventDefault();
84
- e.stopPropagation();
85
- src = "";
86
- files = null;
87
- }
88
- function pick(e) {
89
- e.preventDefault();
90
- e.stopPropagation();
91
- el.click();
92
- }
93
- let jsEnabled = $state(false);
94
- onMount(() => {
95
- jsEnabled = true;
96
- });
97
- </script>
98
-
99
- <div class="ImageUpload {shape}">
100
- <div class="Image" class:hasSrc={!!src}>
101
- {#if src}
102
- <img src={src} alt="{title} logo" />
103
- {/if}
104
- {#if uploadState !== 'idle'}
105
- <div class="Loading" in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}>
106
- {#if uploadState === 'resizing'}
107
- <small>Resizing.. {resizeProgress}%</small>
108
- {:else if uploadState === 'uploading'}
109
- <small>Uploading..</small>
110
- {/if}
111
- </div>
112
- {/if}
113
- </div>
114
- <div class="ImageUploadActions" style="{!jsEnabled ? 'display: none;' : ''}">
115
- {#if children}
116
- <div class="description">
117
- {@render children()}
118
- </div>
119
- {/if}
120
- <button type="button" class="button outlined" onclick={pick}>
121
- {button}
122
- </button>
123
- {#if removable && src}
124
- <button type="button" class="button warn" onclick={remove}>
125
- Remove
126
- </button>
127
- {/if}
128
- {#if error}
129
- <div class="error">
130
- <small>{error}</small>
131
- </div>
132
- {/if}
133
- <input
134
- type="file"
135
- {accept}
136
- {id}
137
- bind:files
138
- onchange={handleFile}
139
- bind:this={el}
140
- />
141
- <input type="hidden" {name} value={src} bind:this={urlEl} />
142
- </div>
143
- <noscript>
144
- <small>Sorry, you need to enable Javascript to upload images.</small>
145
- </noscript>
146
- </div>
147
-
148
- <style>
149
- .ImageUpload {
150
- display: grid;
151
- grid-template-columns: 1fr;
152
- align-items: center;
153
- gap: 1rem;
154
- container-type: inline-size;
155
- }
156
- .Image {
157
- border: 1px solid var(--border-light);
158
- pointer-events: none;
159
- position: relative;
160
- display: none;
161
- }
162
- .Image.hasSrc {
163
- display: block;
164
- }
165
- .Image img {
166
- display: block;
167
- object-fit: contain;
168
- width: 100%;
169
- height: 100%;
170
- }
171
- .ImageUpload.square .Image img {
172
- object-fit: cover;
173
- }
174
- .ImageUpload.circle .Image {
175
- border-radius: 50%;
176
- overflow: hidden;
177
- }
178
- .ImageUpload.circle .Image img {
179
- object-fit: cover;
180
- }
181
- .placeholder {
182
- display: flex;
183
- align-items: center;
184
- justify-content: center;
185
- height: 100%;
186
- width: 100%;
187
- object-fit: contain;
188
- padding: 1rem;
189
- text-align: center;
190
- border: 1px dashed var(--border-color);
191
- border-radius: var(--border-radius);
192
- }
193
- .Loading {
194
- position: absolute;
195
- top: 0;
196
- left: 0;
197
- right: 0;
198
- bottom: 0;
199
- z-index: 5;
200
- backdrop-filter: blur(5px);
201
- background: var(--bg-overlay);
202
- display: flex;
203
- align-items: center;
204
- justify-content: center;
205
- flex-direction: column;
206
- gap: 1rem;
207
- padding: 1rem;
208
- }
209
- input {
210
- display: none;
211
- }
212
- .error {
213
- margin-top: 0.75rem;
214
- }
215
- .ImageUpload.banner {
216
- grid-template-areas: "image";
217
- width: 100%;
218
- }
219
- .ImageUpload.banner .Image {
220
- height: 100%;
221
- grid-area: image;
222
- overflow: hidden;
223
- object-fit: cover;
224
- height: 15rem;
225
- aspect-ratio: initial !important;
226
- }
227
- .ImageUpload.banner .Image img {
228
- object-fit: cover;
229
- }
230
- .ImageUpload.banner .ImageUploadActions {
231
- display: flex;
232
- grid-area: image;
233
- flex-direction: column;
234
- justify-content: center;
235
- padding: 1rem;
236
- }
237
- .ImageUpload.banner:hover .ImageUploadActions {
238
- background: var(--bg-overlay);
239
- }
240
- .ImageUploadActions {
241
- display: grid;
242
- grid-template-columns: 1fr 1fr;
243
- gap: 0.75rem;
244
- align-items: start;
245
- }
246
- @container (min-width: 320px) {
247
- .ImageUpload:not(.banner) {
248
- grid-template-columns: minmax(auto, var(--max-image-width)) 1fr;
249
- gap: 2rem;
250
- }
251
- .ImageUpload.banner .ImageUploadActions {
252
- padding: 3rem;
253
- }
254
- .ImageUploadActions {
255
- grid-template-columns: 1fr;
256
- gap: 1rem;
257
- }
258
- }
259
- </style>
@@ -1,31 +0,0 @@
1
- import { type Snippet } from 'svelte';
2
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
- $$bindings?: Bindings;
5
- } & Exports;
6
- (internal: unknown, props: Props & {
7
- $$events?: Events;
8
- $$slots?: Slots;
9
- }): Exports;
10
- z_$$bindings?: Bindings;
11
- }
12
- declare const ImageUpload: $$__sveltets_2_IsomorphicComponent<{
13
- src?: string | null;
14
- uploadUrl: string;
15
- name: string;
16
- id?: string;
17
- title?: string;
18
- button: string;
19
- maxSize?: number;
20
- compressSize?: number;
21
- compressMaxWidth?: number;
22
- accept?: string;
23
- removable?: boolean;
24
- shape?: "square" | "circle" | "banner";
25
- onFile?: (file: File) => void;
26
- children?: Snippet;
27
- }, {
28
- [evt: string]: CustomEvent<any>;
29
- }, {}, {}, "">;
30
- type ImageUpload = InstanceType<typeof ImageUpload>;
31
- export default ImageUpload;
@@ -1,326 +0,0 @@
1
- <script lang="ts">import { getContext, onMount } from "svelte";
2
- import { createId } from "../utils/id.js";
3
- import Copy from "../icons/IconCopy.svelte";
4
- import Done from "../icons/IconDone.svelte";
5
- import Show from "../icons/IconShow.svelte";
6
- import Hide from "../icons/IconHide.svelte";
7
- import Tooltip from "../display/Tooltip.svelte";
8
- import IconButton from "../display/IconButton.svelte";
9
- import { fieldChange, fieldKeydown, ignoreKeys } from "./client.svelte.js";
10
- import FieldError from "./FieldError.svelte";
11
- import { getFromObjWithStringPath } from "./form.js";
12
- import { ZodType } from "zod";
13
- import FieldContent from "./FieldContent.svelte";
14
- import { on } from "svelte/events";
15
- import { fade } from "svelte/transition";
16
- import Theme from "../layout/Theme.svelte";
17
- let {
18
- alt,
19
- autofocus,
20
- autocapitalize,
21
- autocomplete,
22
- autocorrect,
23
- capture,
24
- checked,
25
- contained,
26
- copyable,
27
- defaultValue,
28
- disabled,
29
- enterkeyhint,
30
- height,
31
- help,
32
- id = $bindable(createId()),
33
- indeterminate,
34
- inputmode,
35
- label,
36
- labelTip,
37
- list,
38
- maxlength,
39
- minlength,
40
- max,
41
- min,
42
- multiple,
43
- name,
44
- pattern,
45
- placeholder,
46
- suffix,
47
- onblur,
48
- onchange,
49
- onclick,
50
- onfocus,
51
- onkeydown,
52
- onkeyup,
53
- onkeypress,
54
- prefix,
55
- readonly,
56
- required,
57
- shape = "rounded",
58
- size,
59
- src,
60
- step,
61
- title,
62
- type,
63
- unit,
64
- value = $bindable(""),
65
- viewable,
66
- webkitdirectory,
67
- ...rest
68
- } = $props();
69
- let el = $state();
70
- let copyTitle = $state("Copy");
71
- let viewTitle = $state("Show");
72
- let copyTooltipOpen = $state(false);
73
- let copyBtnIcon = $state(Copy);
74
- let viewBtnIcon = $state(Show);
75
- const form = getContext("form");
76
- const field = $derived(form?.fields[name]);
77
- const issue = $derived(form?.issues?.find((issue2) => issue2.name === name));
78
- $effect(() => {
79
- console.log("issue", issue);
80
- });
81
- const validator = getContext("form.validators")?.[name];
82
- const data = form?.data;
83
- const originalData = form?.originalData;
84
- function view(e) {
85
- e.preventDefault();
86
- if (!el) return;
87
- if (el.type === "password") {
88
- el.type = "text";
89
- viewBtnIcon = Hide;
90
- viewTitle = "Hide";
91
- } else {
92
- el.type = "password";
93
- viewBtnIcon = Show;
94
- viewTitle = "Show";
95
- }
96
- el.focus();
97
- }
98
- function copy(e) {
99
- e.preventDefault();
100
- if (!el) return;
101
- if (navigator.clipboard) {
102
- navigator.clipboard.writeText(value.toString());
103
- } else {
104
- el.focus();
105
- el.select();
106
- document.execCommand("copy");
107
- }
108
- copyBtnIcon = Done;
109
- copyTitle = "Copied!";
110
- copyTooltipOpen = true;
111
- setTimeout(() => {
112
- copyBtnIcon = Copy;
113
- copyTitle = "Copy";
114
- copyTooltipOpen = false;
115
- }, 1500);
116
- el.focus();
117
- }
118
- if (!value) value = form ? getFromObjWithStringPath(Object.assign(originalData ?? {}, data ?? {}), name) || form?.fields?.[name]?.defaultValue : "";
119
- onMount(() => {
120
- if (value) fieldChange(form, name, () => el)({});
121
- });
122
- let focused = $state(false);
123
- let rangeValueLeft = $derived.by(() => {
124
- if (!el) return 0;
125
- value;
126
- return (el.valueAsNumber - min) / (max - min) * 100;
127
- });
128
- function focus(e) {
129
- focused = true;
130
- if (onfocus) return onfocus(e);
131
- }
132
- function blur(e) {
133
- focused = false;
134
- if (onblur) return onblur(e);
135
- }
136
- </script>
137
-
138
- {#snippet input()}
139
- {#if type === 'checkbox'}
140
- <input
141
- type="checkbox"
142
- bind:this={el}
143
- {alt}
144
- {autofocus}
145
- {disabled}
146
- {enterkeyhint}
147
- {height}
148
- {id}
149
- {indeterminate}
150
- {inputmode}
151
- {name}
152
- onblur={blur}
153
- {onclick}
154
- onchange={fieldChange(form, name, () => el, validator, onchange)}
155
- onfocus={focus}
156
- onkeydown={fieldKeydown(form, name, () => el, validator, onkeydown)}
157
- {onkeyup}
158
- {onkeypress}
159
- {readonly}
160
- required={required || field?.required}
161
- {title}
162
- bind:checked={value}
163
- {...rest}
164
- />
165
- {:else}
166
- <input
167
- bind:this={el}
168
- {alt}
169
- {autofocus}
170
- autocapitalize={typeof autocapitalize === 'string' ? autocapitalize : (typeof autocapitalize === 'boolean' ? (autocapitalize ? 'on' : 'off') : undefined)}
171
- {autocomplete}
172
- autocorrect={typeof autocorrect === 'boolean' ? (autocorrect ? 'on' : 'off') : undefined}
173
- {capture}
174
- {checked}
175
- {disabled}
176
- {enterkeyhint}
177
- {height}
178
- {id}
179
- {inputmode}
180
- {list}
181
- maxlength={maxlength ? maxlength : field?.maxlength}
182
- minlength={minlength ? minlength : field?.minlength}
183
- max={max ? max : field?.max}
184
- min={min ? min : field?.min}
185
- {multiple}
186
- {name}
187
- onblur={blur}
188
- {onclick}
189
- onchange={fieldChange(form, name, () => el, validator, onchange)}
190
- onfocus={focus}
191
- onkeydown={fieldKeydown(form, name, () => el, validator, onkeydown)}
192
- {onkeyup}
193
- {onkeypress}
194
- pattern={pattern ? pattern : field?.pattern}
195
- {placeholder}
196
- {readonly}
197
- required={required || field?.required}
198
- {size}
199
- {src}
200
- {step}
201
- {title}
202
- {type}
203
- bind:value={value}
204
- {webkitdirectory}
205
- {...rest}
206
- />
207
- {/if}
208
- {/snippet}
209
-
210
- {#if type === 'hidden'}
211
- {@render input()}
212
- {:else}
213
- <FieldContent
214
- {id}
215
- {label}
216
- {labelTip}
217
- contained={type === "checkbox" || type === "radio" || type === "color" || type === "range" ? false : true}
218
- direction={(type === "checkbox" || type === "radio") ? 'row' : 'column'}
219
- {field}
220
- {issue}
221
- {type}
222
- {help}
223
- {prefix}
224
- {suffix}
225
- {required}
226
- >
227
-
228
- {#if type === "checkbox" || type === "radio"}
229
- {@render input()}
230
- {:else if type === "range"}
231
- <div class="Range">
232
- {#if min?.toString().length}
233
- <span>{min}{unit}</span>
234
- {/if}
235
- <div class="RangeInput">
236
- {@render input()}
237
- {#if focused && min?.toString().length && max?.toString().length}
238
- <Theme theme="invert">
239
- <div
240
- class="RangeValue"
241
- in:fade={{ duration: 100 }}
242
- out:fade={{ duration: 100 }}
243
- style="left: {rangeValueLeft}%"
244
- >
245
- {value}{unit}
246
- </div>
247
- </Theme>
248
- {/if}
249
- </div>
250
- {#if max?.toString().length}
251
- <span>{max}{unit}</span>
252
- {/if}
253
- </div>
254
- {:else}
255
-
256
- {@render input()}
257
-
258
- {#if copyable}
259
- <Tooltip tip={copyTitle} open={copyTooltipOpen}>
260
- <IconButton icon={copyBtnIcon} onclick={copy} disabled={copyTooltipOpen} />
261
- </Tooltip>
262
- {/if}
263
-
264
- {#if type === "password" && viewable}
265
- <Tooltip tip={viewTitle}>
266
- <IconButton icon={viewBtnIcon} onclick={view} />
267
- </Tooltip>
268
- {/if}
269
-
270
- {/if}
271
- </FieldContent>
272
- {/if}
273
-
274
- <style>
275
- /**
276
- * Input element
277
- */
278
- input:not([type="checkbox"]):not([type="radio"]) {
279
- border: none;
280
- flex-grow: 1;
281
- flex-shrink: 0;
282
- }
283
- input:not([type="checkbox"]):not([type="radio"]):focus-visible,
284
- input:not([type="checkbox"]):not([type="radio"]):active {
285
- outline: none;
286
- }
287
- input[type="range"] {
288
- display: block;
289
- }
290
- /**
291
- * Checkbox and radio
292
- */
293
- input[type="checkbox"] {
294
- border-radius: 6px;
295
- }
296
- .Range {
297
- display: flex;
298
- gap: 0.5em;
299
- align-items: center;
300
- }
301
- .RangeValue {
302
- position: absolute;
303
- top: 0;
304
- font-size: max(0.85em, 9px);
305
- color: var(--text-subtle);
306
- background: var(--bg-app);
307
- padding: 0.15em 0.35em;
308
- border-radius: var(--border-radius);
309
- transform: translate(-50%, -125%);
310
- border: var(--border);
311
- min-inline-size: 1em;
312
- box-shadow: 0 0.5rem 1rem var(--shadow);
313
- font-weight: 600;
314
- }
315
- .Range span {
316
- font-size: 0.75em;
317
- color: var(--text-subtle);
318
- }
319
- .RangeInput {
320
- position: relative;
321
- flex-grow: 1;
322
- }
323
- .RangeInput :global(input) {
324
- width: 100%;
325
- }
326
- </style>