@rkosafo/cai.components 0.0.1 → 0.0.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.
- package/dist/baseEditor/index.svelte +32 -0
- package/dist/baseEditor/index.svelte.d.ts +18 -0
- package/dist/builders/filters/FilterBuilder.svelte +638 -0
- package/dist/builders/filters/FilterBuilder.svelte.d.ts +4 -0
- package/dist/builders/filters/index.d.ts +1 -0
- package/dist/builders/filters/index.js +1 -0
- package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -0
- package/dist/forms/FormCheckbox/FormCheckbox.svelte.d.ts +4 -0
- package/dist/forms/FormCheckbox/index.d.ts +1 -0
- package/dist/forms/FormCheckbox/index.js +1 -0
- package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -0
- package/dist/forms/FormDatepicker/FormDatepicker.svelte.d.ts +13 -0
- package/dist/forms/FormDatepicker/index.d.ts +1 -0
- package/dist/forms/FormDatepicker/index.js +1 -0
- package/dist/forms/FormInput/FormInput.svelte +87 -0
- package/dist/forms/FormInput/FormInput.svelte.d.ts +4 -0
- package/dist/forms/FormInput/index.d.ts +1 -0
- package/dist/forms/FormInput/index.js +1 -0
- package/dist/forms/FormRadio/FormRadio.svelte +53 -0
- package/dist/forms/FormRadio/FormRadio.svelte.d.ts +4 -0
- package/dist/forms/FormRadio/index.d.ts +1 -0
- package/dist/forms/FormRadio/index.js +1 -0
- package/dist/forms/FormSelect/FormSelect.svelte +86 -0
- package/dist/forms/FormSelect/FormSelect.svelte.d.ts +4 -0
- package/dist/forms/FormSelect/index.d.ts +1 -0
- package/dist/forms/FormSelect/index.js +1 -0
- package/dist/forms/FormTextarea/FormTextarea.svelte +77 -0
- package/dist/forms/FormTextarea/FormTextarea.svelte.d.ts +4 -0
- package/dist/forms/FormTextarea/index.d.ts +1 -0
- package/dist/forms/FormTextarea/index.js +1 -0
- package/dist/forms/checkbox/Checkbox.svelte +82 -0
- package/dist/forms/checkbox/Checkbox.svelte.d.ts +4 -0
- package/dist/forms/checkbox/CheckboxButton.svelte +92 -0
- package/dist/forms/checkbox/CheckboxButton.svelte.d.ts +18 -0
- package/dist/forms/checkbox/index.d.ts +3 -0
- package/dist/forms/checkbox/index.js +3 -0
- package/dist/forms/checkbox/theme.d.ts +317 -0
- package/dist/forms/checkbox/theme.js +113 -0
- package/dist/forms/datepicker/Datepicker.svelte +706 -0
- package/dist/forms/datepicker/Datepicker.svelte.d.ts +41 -0
- package/dist/forms/datepicker/index.d.ts +2 -0
- package/dist/forms/datepicker/index.js +2 -0
- package/dist/forms/datepicker/theme.d.ts +385 -0
- package/dist/forms/datepicker/theme.js +56 -0
- package/dist/forms/form/Form.svelte +69 -0
- package/dist/forms/form/Form.svelte.d.ts +6 -0
- package/dist/forms/form/index.d.ts +2 -0
- package/dist/forms/form/index.js +2 -0
- package/dist/forms/input/Input.svelte +363 -0
- package/dist/forms/input/Input.svelte.d.ts +4 -0
- package/dist/forms/input/index.d.ts +4 -0
- package/dist/forms/input/index.js +5 -0
- package/dist/forms/input/theme.d.ts +301 -0
- package/dist/forms/input/theme.js +100 -0
- package/dist/forms/label/Label.svelte +38 -0
- package/dist/forms/label/Label.svelte.d.ts +15 -0
- package/dist/forms/label/index.d.ts +2 -0
- package/dist/forms/label/index.js +2 -0
- package/dist/forms/label/theme.d.ts +75 -0
- package/dist/forms/label/theme.js +29 -0
- package/dist/forms/radio/Radio.svelte +48 -0
- package/dist/forms/radio/Radio.svelte.d.ts +25 -0
- package/dist/forms/radio/RadioButton.svelte +22 -0
- package/dist/forms/radio/RadioButton.svelte.d.ts +25 -0
- package/dist/forms/radio/index.d.ts +3 -0
- package/dist/forms/radio/index.js +3 -0
- package/dist/forms/radio/theme.d.ts +290 -0
- package/dist/forms/radio/theme.js +95 -0
- package/dist/forms/select/Select.svelte +50 -0
- package/dist/forms/select/Select.svelte.d.ts +4 -0
- package/dist/forms/select/index.d.ts +1 -0
- package/dist/forms/select/index.js +1 -0
- package/dist/forms/textarea/Textarea.svelte +165 -0
- package/dist/forms/textarea/Textarea.svelte.d.ts +4 -0
- package/dist/forms/textarea/index.d.ts +2 -0
- package/dist/forms/textarea/index.js +2 -0
- package/dist/forms/textarea/theme.d.ts +100 -0
- package/dist/forms/textarea/theme.js +35 -0
- package/dist/index.d.ts +42 -2
- package/dist/index.js +42 -2
- package/dist/layout/TF/Content/Content.svelte +28 -0
- package/dist/layout/TF/Content/Content.svelte.d.ts +8 -0
- package/dist/layout/TF/Content/index.d.ts +1 -0
- package/dist/layout/TF/Content/index.js +1 -0
- package/dist/layout/TF/Header/Header.svelte +159 -0
- package/dist/layout/TF/Header/Header.svelte.d.ts +21 -0
- package/dist/layout/TF/Header/index.d.ts +1 -0
- package/dist/layout/TF/Header/index.js +1 -0
- package/dist/layout/TF/Sidebar/Sidebar.svelte +74 -0
- package/dist/layout/TF/Sidebar/Sidebar.svelte.d.ts +23 -0
- package/dist/layout/TF/Sidebar/index.d.ts +1 -0
- package/dist/layout/TF/Sidebar/index.js +1 -0
- package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -0
- package/dist/layout/TF/Wrapper/Wrapper.svelte.d.ts +8 -0
- package/dist/layout/TF/Wrapper/index.d.ts +1 -0
- package/dist/layout/TF/Wrapper/index.js +1 -0
- package/dist/layout/TF/index.d.ts +5 -0
- package/dist/layout/TF/index.js +5 -0
- package/dist/themes/ThemeProvider.svelte +20 -0
- package/dist/themes/ThemeProvider.svelte.d.ts +9 -0
- package/dist/themes/index.d.ts +7 -0
- package/dist/themes/index.js +1 -0
- package/dist/themes/themeUtils.d.ts +24 -0
- package/dist/themes/themeUtils.js +74 -0
- package/dist/themes/themes.d.ts +18 -0
- package/dist/themes/themes.js +18 -0
- package/dist/types/index.d.ts +755 -0
- package/dist/types/index.js +1 -0
- package/dist/typography/heading/Heading.svelte +35 -0
- package/dist/typography/heading/Heading.svelte.d.ts +10 -0
- package/dist/typography/heading/index.d.ts +2 -0
- package/dist/typography/heading/index.js +2 -0
- package/dist/typography/heading/theme.d.ts +30 -0
- package/dist/typography/heading/theme.js +17 -0
- package/dist/ui/accordion/Accordion.svelte +49 -0
- package/dist/ui/accordion/Accordion.svelte.d.ts +4 -0
- package/dist/ui/accordion/AccordionItem.svelte +173 -0
- package/dist/ui/accordion/AccordionItem.svelte.d.ts +4 -0
- package/dist/ui/accordion/index.d.ts +3 -0
- package/dist/ui/accordion/index.js +3 -0
- package/dist/ui/accordion/theme.d.ts +96 -0
- package/dist/ui/accordion/theme.js +59 -0
- package/dist/ui/alert/Alert.svelte +83 -0
- package/dist/ui/alert/Alert.svelte.d.ts +5 -0
- package/dist/ui/alert/index.d.ts +2 -0
- package/dist/ui/alert/index.js +2 -0
- package/dist/ui/alert/theme.d.ts +108 -0
- package/dist/ui/alert/theme.js +149 -0
- package/dist/ui/alertDialog/AlertDialog.svelte +40 -0
- package/dist/ui/alertDialog/AlertDialog.svelte.d.ts +4 -0
- package/dist/ui/alertDialog/index.d.ts +1 -0
- package/dist/ui/alertDialog/index.js +1 -0
- package/dist/ui/avatar/Avatar.svelte +77 -0
- package/dist/ui/avatar/Avatar.svelte.d.ts +4 -0
- package/dist/ui/avatar/index.d.ts +2 -0
- package/dist/ui/avatar/index.js +2 -0
- package/dist/ui/avatar/theme.d.ts +63 -0
- package/dist/ui/avatar/theme.js +31 -0
- package/dist/ui/buttons/Button.svelte +102 -0
- package/dist/ui/buttons/Button.svelte.d.ts +4 -0
- package/dist/ui/buttons/GradientButton.svelte +59 -0
- package/dist/ui/buttons/GradientButton.svelte.d.ts +4 -0
- package/dist/ui/buttons/index.d.ts +3 -0
- package/dist/ui/buttons/index.js +3 -0
- package/dist/ui/buttons/theme.d.ts +704 -0
- package/dist/ui/buttons/theme.js +332 -0
- package/dist/ui/datatable/Datatable.svelte +516 -0
- package/dist/ui/datatable/Datatable.svelte.d.ts +5 -0
- package/dist/ui/datatable/index.d.ts +2 -0
- package/dist/ui/datatable/index.js +2 -0
- package/dist/ui/drawer/Drawer.svelte +280 -0
- package/dist/ui/drawer/Drawer.svelte.d.ts +37 -0
- package/dist/ui/drawer/index.d.ts +2 -0
- package/dist/ui/drawer/index.js +2 -0
- package/dist/ui/drawer/theme.d.ts +211 -0
- package/dist/ui/drawer/theme.js +46 -0
- package/dist/ui/dropdown/Dropdown.svelte +36 -0
- package/dist/ui/dropdown/Dropdown.svelte.d.ts +4 -0
- package/dist/ui/dropdown/DropdownDivider.svelte +11 -0
- package/dist/ui/dropdown/DropdownDivider.svelte.d.ts +4 -0
- package/dist/ui/dropdown/DropdownGroup.svelte +14 -0
- package/dist/ui/dropdown/DropdownGroup.svelte.d.ts +4 -0
- package/dist/ui/dropdown/DropdownHeader.svelte +14 -0
- package/dist/ui/dropdown/DropdownHeader.svelte.d.ts +4 -0
- package/dist/ui/dropdown/DropdownItem.svelte +52 -0
- package/dist/ui/dropdown/DropdownItem.svelte.d.ts +4 -0
- package/dist/ui/dropdown/index.d.ts +6 -0
- package/dist/ui/dropdown/index.js +6 -0
- package/dist/ui/dropdown/theme.d.ts +55 -0
- package/dist/ui/dropdown/theme.js +20 -0
- package/dist/ui/footer/Footer.svelte +15 -0
- package/dist/ui/footer/Footer.svelte.d.ts +4 -0
- package/dist/ui/footer/FooterBrand.svelte +37 -0
- package/dist/ui/footer/FooterBrand.svelte.d.ts +4 -0
- package/dist/ui/footer/FooterCopyright.svelte +45 -0
- package/dist/ui/footer/FooterCopyright.svelte.d.ts +4 -0
- package/dist/ui/footer/FooterIcon.svelte +22 -0
- package/dist/ui/footer/FooterIcon.svelte.d.ts +4 -0
- package/dist/ui/footer/FooterLink.svelte +33 -0
- package/dist/ui/footer/FooterLink.svelte.d.ts +4 -0
- package/dist/ui/footer/FooterLinkGroup.svelte +13 -0
- package/dist/ui/footer/FooterLinkGroup.svelte.d.ts +4 -0
- package/dist/ui/footer/index.d.ts +7 -0
- package/dist/ui/footer/index.js +7 -0
- package/dist/ui/footer/theme.d.ts +137 -0
- package/dist/ui/footer/theme.js +39 -0
- package/dist/ui/indicator/Indicator.svelte +42 -0
- package/dist/ui/indicator/Indicator.svelte.d.ts +4 -0
- package/dist/ui/indicator/index.d.ts +2 -0
- package/dist/ui/indicator/index.js +2 -0
- package/dist/ui/indicator/theme.d.ts +177 -0
- package/dist/ui/indicator/theme.js +114 -0
- package/dist/ui/modal/Modal.svelte +265 -0
- package/dist/ui/modal/Modal.svelte.d.ts +38 -0
- package/dist/ui/modal/index.d.ts +2 -0
- package/dist/ui/modal/index.js +2 -0
- package/dist/ui/modal/theme.d.ts +190 -0
- package/dist/ui/modal/theme.js +41 -0
- package/dist/ui/notificationList/NotificationList.svelte +123 -0
- package/dist/ui/notificationList/NotificationList.svelte.d.ts +25 -0
- package/dist/ui/notificationList/index.d.ts +1 -0
- package/dist/ui/notificationList/index.js +1 -0
- package/dist/ui/pageLoader/PageLoader.svelte +10 -0
- package/dist/ui/pageLoader/PageLoader.svelte.d.ts +4 -0
- package/dist/ui/pageLoader/index.d.ts +1 -0
- package/dist/ui/pageLoader/index.js +1 -0
- package/dist/ui/paginate/Paginate.svelte +96 -0
- package/dist/ui/paginate/Paginate.svelte.d.ts +4 -0
- package/dist/ui/paginate/index.d.ts +1 -0
- package/dist/ui/paginate/index.js +1 -0
- package/dist/ui/tab/Tab.svelte +65 -0
- package/dist/ui/tab/Tab.svelte.d.ts +4 -0
- package/dist/ui/tab/index.d.ts +2 -0
- package/dist/ui/tab/index.js +2 -0
- package/dist/ui/tab/theme.d.ts +135 -0
- package/dist/ui/tab/theme.js +83 -0
- package/dist/ui/table/Table.svelte +385 -0
- package/dist/ui/table/Table.svelte.d.ts +4 -0
- package/dist/ui/table/index.d.ts +1 -0
- package/dist/ui/table/index.js +1 -0
- package/dist/ui/tableLoader/TableLoader.svelte +24 -0
- package/dist/ui/tableLoader/TableLoader.svelte.d.ts +13 -0
- package/dist/ui/tableLoader/index.d.ts +1 -0
- package/dist/ui/tableLoader/index.js +1 -0
- package/dist/ui/toolbar/Toolbar.svelte +59 -0
- package/dist/ui/toolbar/Toolbar.svelte.d.ts +17 -0
- package/dist/ui/toolbar/ToolbarButton.svelte +56 -0
- package/dist/ui/toolbar/ToolbarButton.svelte.d.ts +17 -0
- package/dist/ui/toolbar/ToolbarGroup.svelte +43 -0
- package/dist/ui/toolbar/ToolbarGroup.svelte.d.ts +16 -0
- package/dist/ui/toolbar/index.d.ts +4 -0
- package/dist/ui/toolbar/index.js +4 -0
- package/dist/ui/toolbar/theme.d.ts +320 -0
- package/dist/ui/toolbar/theme.js +155 -0
- package/dist/utils/Popper.svelte +257 -0
- package/dist/utils/Popper.svelte.d.ts +4 -0
- package/dist/utils/action.d.ts +16 -0
- package/dist/utils/action.js +107 -0
- package/dist/utils/closeButton/CloseButton.svelte +88 -0
- package/dist/utils/closeButton/CloseButton.svelte.d.ts +12 -0
- package/dist/utils/closeButton/index.d.ts +2 -0
- package/dist/utils/closeButton/index.js +2 -0
- package/dist/utils/closeButton/theme.d.ts +100 -0
- package/dist/utils/closeButton/theme.js +69 -0
- package/dist/utils/dismissable.d.ts +9 -0
- package/dist/utils/dismissable.js +16 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +35 -0
- package/dist/utils/paginate.svelte.d.ts +22 -0
- package/dist/utils/paginate.svelte.js +167 -0
- package/dist/utils/singleSelection.svelte.d.ts +15 -0
- package/dist/utils/singleSelection.svelte.js +49 -0
- package/dist/utils/svelte-legos.d.ts +7 -0
- package/dist/utils/svelte-legos.js +14 -0
- package/package.json +24 -2
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Checkbox, key, Label } from '../../index.js';
|
|
3
|
+
import type { FormCheckboxProps, FormSelectProps } from '../../types/index.js';
|
|
4
|
+
import { getContext } from 'svelte';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
label = '',
|
|
8
|
+
required,
|
|
9
|
+
name,
|
|
10
|
+
disabled,
|
|
11
|
+
contextKey = null,
|
|
12
|
+
placeholder,
|
|
13
|
+
multiple = false,
|
|
14
|
+
onChange,
|
|
15
|
+
...otherProps
|
|
16
|
+
}: FormCheckboxProps = $props();
|
|
17
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
18
|
+
|
|
19
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
20
|
+
const error = $derived($errors[name]?.join(', '));
|
|
21
|
+
const value = $derived($data[name]);
|
|
22
|
+
|
|
23
|
+
function handleChange(e: Event) {
|
|
24
|
+
const value = (e.target as HTMLInputElement).checked;
|
|
25
|
+
setData({ ...$data, [name]: value });
|
|
26
|
+
if (onChange) onChange(e);
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class="relative space-y-1">
|
|
31
|
+
<Checkbox {disabled} onchange={handleChange} {...otherProps} checked={value}
|
|
32
|
+
>{label}
|
|
33
|
+
{#if required}
|
|
34
|
+
<span class="pt-1 pl-1 text-red-500">*</span>
|
|
35
|
+
{/if}
|
|
36
|
+
</Checkbox>
|
|
37
|
+
|
|
38
|
+
{#if hasError}
|
|
39
|
+
<Label
|
|
40
|
+
class="v-error-container absolute top-8 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
41
|
+
'text-red-600'}"
|
|
42
|
+
>
|
|
43
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
44
|
+
{error}
|
|
45
|
+
</span>
|
|
46
|
+
<iconify-icon
|
|
47
|
+
icon="solar:danger-circle-bold-duotone"
|
|
48
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
49
|
+
style="font-size: 18px;"
|
|
50
|
+
></iconify-icon>
|
|
51
|
+
</Label>
|
|
52
|
+
{/if}
|
|
53
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormCheckbox } from "./FormCheckbox.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormCheckbox } from "./FormCheckbox.svelte";
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Converts a string to a Date object, handling multiple common formats
|
|
4
|
+
* @param dateString - The string to convert to a date
|
|
5
|
+
* @returns Date object or null if parsing fails
|
|
6
|
+
*/
|
|
7
|
+
export function stringToDate(dateString: string): Date | undefined {
|
|
8
|
+
if (!dateString) return undefined;
|
|
9
|
+
|
|
10
|
+
// Try ISO format first (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss)
|
|
11
|
+
let date = new Date(dateString);
|
|
12
|
+
if (!isNaN(date.getTime())) return date;
|
|
13
|
+
|
|
14
|
+
// Try common formats with different separators
|
|
15
|
+
const formats = [
|
|
16
|
+
// DD/MM/YYYY or MM/DD/YYYY
|
|
17
|
+
/(\d{1,2})[\/\-\.](\d{1,2})[\/\-\.](\d{4})/,
|
|
18
|
+
// YYYY/MM/DD
|
|
19
|
+
/(\d{4})[\/\-\.](\d{1,2})[\/\-\.](\d{1,2})/,
|
|
20
|
+
// Month name formats (MMM DD, YYYY)
|
|
21
|
+
/([A-Za-z]+)\s(\d{1,2}),?\s(\d{4})/,
|
|
22
|
+
// Unix timestamp (as string)
|
|
23
|
+
/^\d{10,13}$/
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
for (const regex of formats) {
|
|
27
|
+
const match = dateString.match(regex);
|
|
28
|
+
if (!match) continue;
|
|
29
|
+
|
|
30
|
+
if (regex === formats[3]) {
|
|
31
|
+
// Unix timestamp
|
|
32
|
+
const timestamp = parseInt(dateString);
|
|
33
|
+
return new Date(timestamp * (dateString.length === 10 ? 1000 : 1));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let day, month, year;
|
|
37
|
+
if (regex === formats[0]) {
|
|
38
|
+
// DD/MM/YYYY or MM/DD/YYYY
|
|
39
|
+
const first = parseInt(match[1]);
|
|
40
|
+
const second = parseInt(match[2]);
|
|
41
|
+
|
|
42
|
+
// Determine if format is DD/MM or MM/DD
|
|
43
|
+
if (first > 12) {
|
|
44
|
+
day = first;
|
|
45
|
+
month = second - 1;
|
|
46
|
+
} else if (second > 12) {
|
|
47
|
+
day = second;
|
|
48
|
+
month = first - 1;
|
|
49
|
+
} else {
|
|
50
|
+
// Ambiguous case, default to DD/MM
|
|
51
|
+
day = second;
|
|
52
|
+
month = first - 1;
|
|
53
|
+
}
|
|
54
|
+
year = parseInt(match[3]);
|
|
55
|
+
} else if (regex === formats[1]) {
|
|
56
|
+
// YYYY/MM/DD
|
|
57
|
+
year = parseInt(match[1]);
|
|
58
|
+
month = parseInt(match[2]) - 1;
|
|
59
|
+
day = parseInt(match[3]);
|
|
60
|
+
} else if (regex === formats[2]) {
|
|
61
|
+
// Month name
|
|
62
|
+
month = new Date(`${match[1]} 1, 2000`).getMonth();
|
|
63
|
+
day = parseInt(match[2]);
|
|
64
|
+
year = parseInt(match[3]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
date = new Date(year, month, day);
|
|
68
|
+
if (!isNaN(date.getTime())) return date;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Try the Date constructor one more time in case of locale-specific formats
|
|
72
|
+
date = new Date(dateString);
|
|
73
|
+
return isNaN(date.getTime()) ? undefined : date;
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<script lang="ts">
|
|
78
|
+
import { key, type DateOrRange, type FormDatepickerProps } from '../../index.js';
|
|
79
|
+
import { getContext } from 'svelte';
|
|
80
|
+
import Label from '../label/Label.svelte';
|
|
81
|
+
import Datepicker from '../datepicker/Datepicker.svelte';
|
|
82
|
+
|
|
83
|
+
let {
|
|
84
|
+
label = '',
|
|
85
|
+
required,
|
|
86
|
+
name,
|
|
87
|
+
disabled,
|
|
88
|
+
contextKey = null,
|
|
89
|
+
placeholder,
|
|
90
|
+
range,
|
|
91
|
+
locale,
|
|
92
|
+
dateFormat,
|
|
93
|
+
onchange,
|
|
94
|
+
...otherProps
|
|
95
|
+
// onchange,
|
|
96
|
+
}: FormDatepickerProps & { onchange?: (value: DateOrRange) => void } = $props();
|
|
97
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
98
|
+
|
|
99
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
100
|
+
const error = $derived($errors[name]?.join(', '));
|
|
101
|
+
const formatDate = (date?: Date): string => date?.toLocaleDateString(locale, dateFormat) ?? '';
|
|
102
|
+
const value = $derived($data[name] ? stringToDate($data[name]) : undefined);
|
|
103
|
+
const rangeDate = $derived(getRange());
|
|
104
|
+
|
|
105
|
+
function getRange() {
|
|
106
|
+
if (!range) return { from: undefined, to: undefined };
|
|
107
|
+
const splits = $data[name].split(' - ');
|
|
108
|
+
return {
|
|
109
|
+
from: stringToDate(splits[0]),
|
|
110
|
+
to: stringToDate(splits[1])
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function handleChange(e: DateOrRange) {
|
|
115
|
+
if (!range) {
|
|
116
|
+
setData({ ...$data, [name]: formatDate(e as Date) });
|
|
117
|
+
} else if (typeof e === 'object' && 'from' in e && 'to' in e) {
|
|
118
|
+
const d = `${formatDate(e.from)} - ${formatDate(e.to)}`;
|
|
119
|
+
setData({ ...$data, [name]: d });
|
|
120
|
+
}
|
|
121
|
+
if (onchange) onchange(e);
|
|
122
|
+
}
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<div class="relative space-y-1">
|
|
126
|
+
<Label
|
|
127
|
+
>{label}
|
|
128
|
+
{#if required}
|
|
129
|
+
<span class="pl-1 text-red-500">*</span>
|
|
130
|
+
{/if}
|
|
131
|
+
</Label>
|
|
132
|
+
|
|
133
|
+
<Datepicker
|
|
134
|
+
{disabled}
|
|
135
|
+
{range}
|
|
136
|
+
{value}
|
|
137
|
+
onselect={handleChange}
|
|
138
|
+
rangeFrom={rangeDate.from}
|
|
139
|
+
rangeTo={rangeDate.to}
|
|
140
|
+
{name}
|
|
141
|
+
{...otherProps}
|
|
142
|
+
/>
|
|
143
|
+
|
|
144
|
+
{#if hasError}
|
|
145
|
+
<Label
|
|
146
|
+
class="v-error-container absolute top-8 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
147
|
+
'text-red-600'}"
|
|
148
|
+
>
|
|
149
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
150
|
+
{error}
|
|
151
|
+
</span>
|
|
152
|
+
<iconify-icon
|
|
153
|
+
icon="solar:danger-circle-bold-duotone"
|
|
154
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
155
|
+
style="font-size: 18px;"
|
|
156
|
+
></iconify-icon>
|
|
157
|
+
</Label>
|
|
158
|
+
{/if}
|
|
159
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a string to a Date object, handling multiple common formats
|
|
3
|
+
* @param dateString - The string to convert to a date
|
|
4
|
+
* @returns Date object or null if parsing fails
|
|
5
|
+
*/
|
|
6
|
+
export declare function stringToDate(dateString: string): Date | undefined;
|
|
7
|
+
import { type DateOrRange, type FormDatepickerProps } from '../../index.js';
|
|
8
|
+
type $$ComponentProps = FormDatepickerProps & {
|
|
9
|
+
onchange?: (value: DateOrRange) => void;
|
|
10
|
+
};
|
|
11
|
+
declare const FormDatepicker: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type FormDatepicker = ReturnType<typeof FormDatepicker>;
|
|
13
|
+
export default FormDatepicker;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormDatepicker } from "./FormDatepicker.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormDatepicker } from "./FormDatepicker.svelte";
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
function formatInput(value: string, type: string | null, pattern: string | null) {
|
|
3
|
+
if (!value) return '';
|
|
4
|
+
if (!type) return value;
|
|
5
|
+
switch (type) {
|
|
6
|
+
case 'number':
|
|
7
|
+
const v = +value;
|
|
8
|
+
if (isNaN(v)) return '';
|
|
9
|
+
return v.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
10
|
+
default:
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getNestedValue<T extends Record<string, any>>(obj: T, path: string): any {
|
|
16
|
+
return path
|
|
17
|
+
.split('.')
|
|
18
|
+
.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : null), obj);
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<script lang="ts">
|
|
23
|
+
import { key, type FormInputProps } from '../../index.js';
|
|
24
|
+
import { getContext } from 'svelte';
|
|
25
|
+
import Input from '../input/Input.svelte';
|
|
26
|
+
import { nanoid } from 'nanoid';
|
|
27
|
+
import Label from '../label/Label.svelte';
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
name = '',
|
|
31
|
+
label = '',
|
|
32
|
+
required,
|
|
33
|
+
readonly,
|
|
34
|
+
contextKey = null,
|
|
35
|
+
type = 'text',
|
|
36
|
+
pattern = null,
|
|
37
|
+
placeholder,
|
|
38
|
+
...otherProps
|
|
39
|
+
}: FormInputProps = $props();
|
|
40
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
41
|
+
|
|
42
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
43
|
+
const error = $derived($errors[name]?.join(', '));
|
|
44
|
+
const isSuccess = $derived(!readonly && !hasError && $touched[name]);
|
|
45
|
+
let id = nanoid();
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div class="relative space-y-1">
|
|
49
|
+
<Label
|
|
50
|
+
>{label}
|
|
51
|
+
{#if required}
|
|
52
|
+
<span class="pl-1 text-red-500">*</span>
|
|
53
|
+
{/if}
|
|
54
|
+
</Label>
|
|
55
|
+
{#if readonly}
|
|
56
|
+
<div class="min-h-[42px] rounded-md border border-gray-300 bg-gray-100 p-2">
|
|
57
|
+
<span>{formatInput(getNestedValue($data, name) || '', type, pattern)}</span>
|
|
58
|
+
</div>
|
|
59
|
+
{:else}
|
|
60
|
+
<Input
|
|
61
|
+
{name}
|
|
62
|
+
{type}
|
|
63
|
+
{id}
|
|
64
|
+
{placeholder}
|
|
65
|
+
{readonly}
|
|
66
|
+
color={readonly ? 'gray' : hasError ? 'red' : isSuccess ? 'green' : 'default'}
|
|
67
|
+
value={getNestedValue($data, name) || ''}
|
|
68
|
+
{...otherProps}
|
|
69
|
+
/>
|
|
70
|
+
{/if}
|
|
71
|
+
|
|
72
|
+
{#if hasError}
|
|
73
|
+
<Label
|
|
74
|
+
class="v-error-container absolute top-9 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
75
|
+
'text-red-600'}"
|
|
76
|
+
>
|
|
77
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
78
|
+
{error}
|
|
79
|
+
</span>
|
|
80
|
+
<iconify-icon
|
|
81
|
+
icon="solar:danger-circle-bold-duotone"
|
|
82
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
83
|
+
style="font-size: 18px;"
|
|
84
|
+
></iconify-icon>
|
|
85
|
+
</Label>
|
|
86
|
+
{/if}
|
|
87
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormInput } from "./FormInput.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormInput } from "./FormInput.svelte";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Checkbox, key, Label } from '../../index.js';
|
|
3
|
+
import type { FormCheckboxProps, FormRadioProps, FormSelectProps } from '../../types/index.js';
|
|
4
|
+
import { getContext } from 'svelte';
|
|
5
|
+
import Radio from '../radio/Radio.svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
label = '',
|
|
9
|
+
required,
|
|
10
|
+
name,
|
|
11
|
+
disabled,
|
|
12
|
+
contextKey = null,
|
|
13
|
+
placeholder,
|
|
14
|
+
multiple = false,
|
|
15
|
+
onchange,
|
|
16
|
+
...otherProps
|
|
17
|
+
}: FormRadioProps<any> = $props();
|
|
18
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
19
|
+
|
|
20
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
21
|
+
const error = $derived($errors[name]?.join(', '));
|
|
22
|
+
const value = $derived($data[name]);
|
|
23
|
+
|
|
24
|
+
function handleChange(e: Event) {
|
|
25
|
+
const value = (e.target as HTMLInputElement).value;
|
|
26
|
+
setData({ ...$data, [name]: value });
|
|
27
|
+
if (onchange) onchange(e as any);
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div class="relative space-y-1">
|
|
32
|
+
<Radio {disabled} onchange={handleChange} {...otherProps} group={value}
|
|
33
|
+
>{label}
|
|
34
|
+
{#if required}
|
|
35
|
+
<span class="pt-1 pl-1 text-red-500">*</span>
|
|
36
|
+
{/if}
|
|
37
|
+
{#if hasError}
|
|
38
|
+
<Label
|
|
39
|
+
class="v-error-container absolute top-0 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
40
|
+
'text-red-600'}"
|
|
41
|
+
>
|
|
42
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
43
|
+
{error}
|
|
44
|
+
</span>
|
|
45
|
+
<iconify-icon
|
|
46
|
+
icon="solar:danger-circle-bold-duotone"
|
|
47
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
48
|
+
style="font-size: 18px;"
|
|
49
|
+
></iconify-icon>
|
|
50
|
+
</Label>
|
|
51
|
+
{/if}
|
|
52
|
+
</Radio>
|
|
53
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormRadio } from "./FormRadio.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormRadio } from "./FormRadio.svelte";
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { key, Label } from '../../index.js';
|
|
3
|
+
import type { FormSelectProps } from '../../types/index.js';
|
|
4
|
+
import { getContext } from 'svelte';
|
|
5
|
+
import Select from '../select/Select.svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
label = '',
|
|
9
|
+
required,
|
|
10
|
+
name = '',
|
|
11
|
+
disabled,
|
|
12
|
+
contextKey = null,
|
|
13
|
+
placeholder,
|
|
14
|
+
multiple = false,
|
|
15
|
+
onChange,
|
|
16
|
+
...otherProps
|
|
17
|
+
// onchange,
|
|
18
|
+
}: FormSelectProps = $props();
|
|
19
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
20
|
+
|
|
21
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
22
|
+
const error = $derived($errors[name]?.join(', '));
|
|
23
|
+
const value = $derived($data[name]);
|
|
24
|
+
const isSuccess = $derived(!disabled && !hasError && $touched[name]);
|
|
25
|
+
|
|
26
|
+
let renderId = $state(0);
|
|
27
|
+
|
|
28
|
+
function handleChange(e: any) {
|
|
29
|
+
if (!e) return;
|
|
30
|
+
if (!multiple) {
|
|
31
|
+
setData({ ...$data, [name]: e.value });
|
|
32
|
+
} else {
|
|
33
|
+
const d = e.map((a: any) => a.value);
|
|
34
|
+
setData({ ...$data, [name]: d });
|
|
35
|
+
}
|
|
36
|
+
if (onChange) onChange(e);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// $effect(() => {
|
|
40
|
+
// if (hasError) renderId++;
|
|
41
|
+
// if (isSuccess) {
|
|
42
|
+
// alert(isSuccess);
|
|
43
|
+
// renderId++;
|
|
44
|
+
// alert('herr');
|
|
45
|
+
// }
|
|
46
|
+
// });
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<div class="relative space-y-1">
|
|
50
|
+
<Label
|
|
51
|
+
>{label}
|
|
52
|
+
{#if required}
|
|
53
|
+
<span class="pl-1 text-red-500">*</span>
|
|
54
|
+
{/if}
|
|
55
|
+
</Label>
|
|
56
|
+
|
|
57
|
+
<!-- {#key renderId} -->
|
|
58
|
+
<Select
|
|
59
|
+
{name}
|
|
60
|
+
{multiple}
|
|
61
|
+
{value}
|
|
62
|
+
{disabled}
|
|
63
|
+
onChange={handleChange}
|
|
64
|
+
{hasError}
|
|
65
|
+
minHeight={40}
|
|
66
|
+
hasSuccess={isSuccess}
|
|
67
|
+
{...otherProps}
|
|
68
|
+
/>
|
|
69
|
+
<!-- {/key} -->
|
|
70
|
+
|
|
71
|
+
{#if hasError}
|
|
72
|
+
<Label
|
|
73
|
+
class="v-error-container absolute top-8 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
74
|
+
'text-red-600'}"
|
|
75
|
+
>
|
|
76
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
77
|
+
{error}
|
|
78
|
+
</span>
|
|
79
|
+
<iconify-icon
|
|
80
|
+
icon="solar:danger-circle-bold-duotone"
|
|
81
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
82
|
+
style="font-size: 18px;"
|
|
83
|
+
></iconify-icon>
|
|
84
|
+
</Label>
|
|
85
|
+
{/if}
|
|
86
|
+
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormSelect } from './FormSelect.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormSelect } from './FormSelect.svelte';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { key, type FormTextareaProps } from '../../index.js';
|
|
3
|
+
import { getContext } from 'svelte';
|
|
4
|
+
import Label from '../label/Label.svelte';
|
|
5
|
+
import Textarea from '../textarea/Textarea.svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
label = '',
|
|
9
|
+
required,
|
|
10
|
+
name,
|
|
11
|
+
readonly,
|
|
12
|
+
contextKey = null,
|
|
13
|
+
placeholder,
|
|
14
|
+
onchange,
|
|
15
|
+
...otherProps
|
|
16
|
+
// onchange,
|
|
17
|
+
}: FormTextareaProps = $props();
|
|
18
|
+
const { touched, errors, data, setData }: any = getContext(contextKey || key);
|
|
19
|
+
|
|
20
|
+
const hasError = $derived($touched[name] && $errors[name]?.length);
|
|
21
|
+
const error = $derived($errors[name]?.join(', '));
|
|
22
|
+
const isSuccess = $derived(!readonly && !hasError && $touched[name]);
|
|
23
|
+
const isTouched = $derived(!readonly && $touched[name]);
|
|
24
|
+
|
|
25
|
+
function handeleChange(e: Event) {
|
|
26
|
+
const value = (e.target as HTMLTextAreaElement).value;
|
|
27
|
+
// console.log({ value });
|
|
28
|
+
setData({ ...$data, [name]: value });
|
|
29
|
+
if (onchange) onchange(e as any);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getNestedValue<T extends Record<string, any>>(obj: T, path: string): any {
|
|
33
|
+
return path
|
|
34
|
+
.split('.')
|
|
35
|
+
.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : null), obj);
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="relative space-y-1">
|
|
40
|
+
<Label
|
|
41
|
+
>{label}
|
|
42
|
+
{#if required}
|
|
43
|
+
<span class="pl-1 text-red-500">*</span>
|
|
44
|
+
{/if}
|
|
45
|
+
</Label>
|
|
46
|
+
|
|
47
|
+
<Textarea
|
|
48
|
+
color={readonly ? 'gray' : hasError ? 'red' : isSuccess ? 'green' : 'default'}
|
|
49
|
+
{readonly}
|
|
50
|
+
value={getNestedValue($data, name) || ''}
|
|
51
|
+
onchange={handeleChange}
|
|
52
|
+
class="flex w-full"
|
|
53
|
+
{...otherProps}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
{#if hasError}
|
|
57
|
+
<Label
|
|
58
|
+
class="v-error-container absolute top-8 right-2 flex items-center gap-1 text-sm {hasError &&
|
|
59
|
+
'text-red-600'}"
|
|
60
|
+
>
|
|
61
|
+
<span class="v-error-message hidden backdrop-blur-sm">
|
|
62
|
+
{error}
|
|
63
|
+
</span>
|
|
64
|
+
<iconify-icon
|
|
65
|
+
icon="solar:danger-circle-bold-duotone"
|
|
66
|
+
class="v-error-svg ml-auto cursor-pointer text-red-500 select-none hover:text-red-600"
|
|
67
|
+
style="font-size: 18px;"
|
|
68
|
+
></iconify-icon>
|
|
69
|
+
</Label>
|
|
70
|
+
{/if}
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<!-- <style>
|
|
74
|
+
.v-error-container:hover .v-error-message {
|
|
75
|
+
display: block !important;
|
|
76
|
+
}
|
|
77
|
+
</style> -->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormTextarea } from "./FormTextarea.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FormTextarea } from "./FormTextarea.svelte";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getTheme, warnThemeDeprecation } from '../../themes/themeUtils.js';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { checkbox } from './index.js';
|
|
5
|
+
import { Label, type CheckboxItem, type CheckboxProps } from '../../index.js';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
children,
|
|
9
|
+
color = 'primary',
|
|
10
|
+
custom,
|
|
11
|
+
inline,
|
|
12
|
+
tinted,
|
|
13
|
+
rounded,
|
|
14
|
+
group = $bindable([]),
|
|
15
|
+
choices = [],
|
|
16
|
+
checked = $bindable(false),
|
|
17
|
+
indeterminate,
|
|
18
|
+
classes,
|
|
19
|
+
class: className,
|
|
20
|
+
divClass,
|
|
21
|
+
disabled = false,
|
|
22
|
+
value,
|
|
23
|
+
labelProps = {},
|
|
24
|
+
...restProps
|
|
25
|
+
}: CheckboxProps = $props();
|
|
26
|
+
|
|
27
|
+
warnThemeDeprecation('Checkbox', { divClass }, { divClass: 'div' });
|
|
28
|
+
const styling = $derived(classes ?? { div: divClass });
|
|
29
|
+
|
|
30
|
+
const theme = getTheme('checkbox');
|
|
31
|
+
|
|
32
|
+
const disabledValue = $derived(disabled === null ? undefined : disabled);
|
|
33
|
+
const { base, div: divStyle } = $derived(
|
|
34
|
+
checkbox({ color, tinted, custom, rounded, inline, disabled: disabledValue })
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Separate label rendering logic
|
|
38
|
+
function renderLabel(choice?: CheckboxItem) {
|
|
39
|
+
if (!choice) return '';
|
|
40
|
+
|
|
41
|
+
if (children) {
|
|
42
|
+
return children(choice);
|
|
43
|
+
}
|
|
44
|
+
return choice.label || '';
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
{#if choices.length > 0}
|
|
49
|
+
{#each choices as choice, i}
|
|
50
|
+
<div class={divStyle({ class: clsx(theme?.div, styling.div) })}>
|
|
51
|
+
<Label show={true} {...labelProps}>
|
|
52
|
+
<input
|
|
53
|
+
type="checkbox"
|
|
54
|
+
value={choice.value}
|
|
55
|
+
checked={choice.checked ?? false}
|
|
56
|
+
{disabled}
|
|
57
|
+
bind:group
|
|
58
|
+
{...restProps}
|
|
59
|
+
class={base({ class: clsx(theme?.base, className) })}
|
|
60
|
+
/>
|
|
61
|
+
{renderLabel(choice)}
|
|
62
|
+
</Label>
|
|
63
|
+
</div>
|
|
64
|
+
{/each}
|
|
65
|
+
{:else}
|
|
66
|
+
<div class={divStyle({ class: clsx(theme?.div, styling.div) })}>
|
|
67
|
+
<Label show={true} {...labelProps}>
|
|
68
|
+
<input
|
|
69
|
+
type="checkbox"
|
|
70
|
+
{value}
|
|
71
|
+
bind:checked
|
|
72
|
+
{indeterminate}
|
|
73
|
+
{disabled}
|
|
74
|
+
{...restProps}
|
|
75
|
+
class={base({ class: clsx(theme?.base, className) })}
|
|
76
|
+
/>
|
|
77
|
+
{#if children}
|
|
78
|
+
{@render children({ value, checked, disabled })}
|
|
79
|
+
{/if}
|
|
80
|
+
</Label>
|
|
81
|
+
</div>
|
|
82
|
+
{/if}
|