@getmicdrop/svelte-components 5.3.12 → 5.3.13
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/calendar/AboutShow/AboutShow.svelte +172 -172
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
- package/dist/calendar/FAQs/FAQs.svelte +75 -75
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
- package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
- package/dist/calendar/PublicCard/PublicCard.svelte +145 -145
- package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
- package/dist/components/Layout/Grid.svelte +109 -109
- package/dist/components/Layout/Section.svelte +80 -80
- package/dist/components/Layout/Sidebar.svelte +108 -108
- package/dist/components/Layout/Stack.svelte +90 -90
- package/dist/constants/formOptions.js +26 -26
- package/dist/constants/validation.js +91 -91
- package/dist/constants/validation.spec.js +64 -64
- package/dist/datetime/__tests__/format.test.d.ts +2 -0
- package/dist/datetime/__tests__/format.test.d.ts.map +1 -0
- package/dist/datetime/__tests__/format.test.js +268 -0
- package/dist/datetime/__tests__/integration.test.d.ts +2 -0
- package/dist/datetime/__tests__/integration.test.d.ts.map +1 -0
- package/dist/datetime/__tests__/integration.test.js +243 -0
- package/dist/datetime/__tests__/parse.test.d.ts +2 -0
- package/dist/datetime/__tests__/parse.test.d.ts.map +1 -0
- package/dist/datetime/__tests__/parse.test.js +261 -0
- package/dist/datetime/__tests__/timezone.test.d.ts +2 -0
- package/dist/datetime/__tests__/timezone.test.d.ts.map +1 -0
- package/dist/datetime/__tests__/timezone.test.js +214 -0
- package/dist/datetime/constants.d.ts +133 -0
- package/dist/datetime/constants.d.ts.map +1 -0
- package/dist/datetime/constants.js +112 -0
- package/dist/datetime/format.d.ts +158 -0
- package/dist/datetime/format.d.ts.map +1 -0
- package/dist/datetime/format.js +315 -0
- package/dist/datetime/index.d.ts +42 -0
- package/dist/datetime/index.d.ts.map +1 -0
- package/dist/datetime/index.js +44 -0
- package/dist/datetime/parse.d.ts +149 -0
- package/dist/datetime/parse.d.ts.map +1 -0
- package/dist/datetime/parse.js +276 -0
- package/dist/datetime/timezone.d.ts +95 -0
- package/dist/datetime/timezone.d.ts.map +1 -0
- package/dist/datetime/timezone.js +241 -0
- package/dist/datetime/types.d.ts +105 -0
- package/dist/datetime/types.d.ts.map +1 -0
- package/dist/datetime/types.js +31 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +232 -218
- package/dist/patterns/data/DataGrid.svelte +45 -45
- package/dist/patterns/data/DataList.svelte +24 -24
- package/dist/patterns/data/DataTable.svelte +40 -40
- package/dist/patterns/forms/FormActions.spec.js +88 -88
- package/dist/patterns/forms/FormActions.stories.svelte +97 -97
- package/dist/patterns/forms/FormActions.svelte +46 -46
- package/dist/patterns/forms/FormGrid.svelte +33 -33
- package/dist/patterns/forms/FormSection.svelte +32 -32
- package/dist/patterns/forms/FormValidationSummary.spec.js +203 -203
- package/dist/patterns/forms/FormValidationSummary.stories.svelte +97 -97
- package/dist/patterns/forms/FormValidationSummary.svelte +67 -67
- package/dist/patterns/layout/Grid.svelte +35 -35
- package/dist/patterns/layout/Sidebar.svelte +39 -39
- package/dist/patterns/layout/Stack.svelte +45 -45
- package/dist/patterns/navigation/BottomNav.spec.js +130 -130
- package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
- package/dist/patterns/navigation/BottomNav.svelte +54 -54
- package/dist/patterns/navigation/Header.spec.js +203 -203
- package/dist/patterns/navigation/Header.stories.svelte +77 -77
- package/dist/patterns/navigation/Header.svelte +240 -240
- package/dist/patterns/page/PageHeader.svelte +36 -36
- package/dist/patterns/page/PageLayout.svelte +40 -40
- package/dist/patterns/page/PageLoader.spec.js +54 -54
- package/dist/patterns/page/PageLoader.stories.svelte +137 -137
- package/dist/patterns/page/PageLoader.svelte +41 -41
- package/dist/patterns/page/SectionHeader.svelte +41 -41
- package/dist/presets/badges.js +112 -112
- package/dist/presets/buttons.js +76 -76
- package/dist/presets/index.js +9 -9
- package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
- package/dist/primitives/Accordion/Accordion.svelte +61 -61
- package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
- package/dist/primitives/Alert/Alert.spec.js +170 -170
- package/dist/primitives/Alert/Alert.stories.svelte +88 -88
- package/dist/primitives/Alert/Alert.svelte +65 -65
- package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
- package/dist/primitives/Avatar/Avatar.svelte +66 -66
- package/dist/primitives/Badges/Badge.spec.js +103 -103
- package/dist/primitives/Badges/Badge.stories.svelte +86 -86
- package/dist/primitives/Badges/Badge.svelte +142 -142
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +127 -127
- package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
- package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +120 -120
- package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
- package/dist/primitives/Button/Button.spec.js +211 -211
- package/dist/primitives/Button/Button.stories.svelte +76 -76
- package/dist/primitives/Button/Button.svelte +301 -301
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +48 -48
- package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
- package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
- package/dist/primitives/Card.spec.js +49 -49
- package/dist/primitives/Card.stories.svelte +22 -22
- package/dist/primitives/Card.svelte +28 -28
- package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
- package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
- package/dist/primitives/DarkModeToggle.spec.js +357 -357
- package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
- package/dist/primitives/DarkModeToggle.svelte +136 -136
- package/dist/primitives/Drawer/Drawer.stories.svelte +100 -100
- package/dist/primitives/Drawer/Drawer.svelte +214 -214
- package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
- package/dist/primitives/Dropdown/Dropdown.svelte +148 -148
- package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
- package/dist/primitives/Icons/ArrowLeft.svelte +20 -20
- package/dist/primitives/Icons/ArrowRight.svelte +20 -20
- package/dist/primitives/Icons/Availability.svelte +26 -26
- package/dist/primitives/Icons/Back.svelte +26 -26
- package/dist/primitives/Icons/CheckCircle.svelte +18 -18
- package/dist/primitives/Icons/CheckCircleOutline.svelte +27 -27
- package/dist/primitives/Icons/ChevronLeft.svelte +16 -16
- package/dist/primitives/Icons/ChevronRight.svelte +16 -16
- package/dist/primitives/Icons/Copy.svelte +27 -27
- package/dist/primitives/Icons/Cross.svelte +17 -17
- package/dist/primitives/Icons/DownArrow.svelte +20 -20
- package/dist/primitives/Icons/ErrorCircle.svelte +18 -18
- package/dist/primitives/Icons/FacebookIcon.svelte +13 -13
- package/dist/primitives/Icons/Home.svelte +27 -27
- package/dist/primitives/Icons/Icon.spec.js +175 -175
- package/dist/primitives/Icons/Icon.stories.svelte +100 -100
- package/dist/primitives/Icons/Icon.svelte +63 -63
- package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
- package/dist/primitives/Icons/ImageOutline.svelte +19 -19
- package/dist/primitives/Icons/Info.svelte +19 -19
- package/dist/primitives/Icons/InstagramIcon.svelte +19 -19
- package/dist/primitives/Icons/LogoInstagram.svelte +15 -15
- package/dist/primitives/Icons/Message.svelte +27 -27
- package/dist/primitives/Icons/MoonIcon.svelte +16 -16
- package/dist/primitives/Icons/More.svelte +33 -33
- package/dist/primitives/Icons/MoreHori.spec.js +67 -67
- package/dist/primitives/Icons/MoreHori.svelte +34 -34
- package/dist/primitives/Icons/Notification.svelte +26 -26
- package/dist/primitives/Icons/Payment.svelte +26 -26
- package/dist/primitives/Icons/Profile.svelte +33 -33
- package/dist/primitives/Icons/Reload.svelte +41 -41
- package/dist/primitives/Icons/Shows.svelte +33 -33
- package/dist/primitives/Icons/Signout.svelte +33 -33
- package/dist/primitives/Icons/SunIcon.svelte +19 -19
- package/dist/primitives/Icons/TiktokIcon.svelte +13 -13
- package/dist/primitives/Icons/TrashBinOutline.svelte +19 -19
- package/dist/primitives/Icons/TwitterIcon.svelte +13 -13
- package/dist/primitives/Icons/WarningIcon.spec.js +30 -30
- package/dist/primitives/Icons/WarningIcon.svelte +24 -24
- package/dist/primitives/Input/Input.spec.js +573 -573
- package/dist/primitives/Input/Input.stories.svelte +139 -139
- package/dist/primitives/Input/Input.svelte +444 -444
- package/dist/primitives/Input/Select.spec.js +218 -218
- package/dist/primitives/Input/Select.stories.svelte +112 -112
- package/dist/primitives/Input/Select.svelte +232 -232
- package/dist/primitives/Input/Textarea.stories.svelte +137 -137
- package/dist/primitives/Input/Textarea.svelte +79 -79
- package/dist/primitives/Label/Label.svelte +37 -37
- package/dist/primitives/Modal/Modal.spec.js +95 -95
- package/dist/primitives/Modal/Modal.stories.svelte +86 -86
- package/dist/primitives/Modal/Modal.svelte +158 -158
- package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
- package/dist/primitives/Pagination/Pagination.svelte +261 -261
- package/dist/primitives/Radio/Radio.stories.svelte +80 -80
- package/dist/primitives/Radio/Radio.svelte +67 -67
- package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
- package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
- package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
- package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
- package/dist/primitives/Skeleton/Skeleton.svelte +52 -52
- package/dist/primitives/Spinner/Spinner.spec.js +75 -75
- package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
- package/dist/primitives/Spinner/Spinner.svelte +57 -57
- package/dist/primitives/Tabs/TabItem.svelte +51 -51
- package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
- package/dist/primitives/Tabs/Tabs.svelte +128 -128
- package/dist/primitives/Toggle.spec.js +127 -127
- package/dist/primitives/Toggle.stories.svelte +92 -92
- package/dist/primitives/Toggle.svelte +71 -71
- package/dist/primitives/Typography/Typography.svelte +53 -53
- package/dist/primitives/ValidationError.spec.js +103 -103
- package/dist/primitives/ValidationError.stories.svelte +111 -111
- package/dist/primitives/ValidationError.svelte +29 -29
- package/dist/recipes/CropImage/CropImage.spec.js +216 -216
- package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
- package/dist/recipes/CropImage/CropImage.svelte +238 -238
- package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
- package/dist/recipes/ImageUploader/ImageUploader.svelte +980 -980
- package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
- package/dist/recipes/feedback/EmptyState/EmptyState.svelte +47 -47
- package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
- package/dist/recipes/feedback/ErrorDisplay.stories.svelte +112 -112
- package/dist/recipes/feedback/ErrorDisplay.svelte +38 -38
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +129 -129
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +167 -167
- package/dist/recipes/fields/CheckboxField.svelte +85 -85
- package/dist/recipes/fields/FormField.svelte +58 -58
- package/dist/recipes/fields/RadioGroup.svelte +95 -95
- package/dist/recipes/fields/SelectField.svelte +82 -82
- package/dist/recipes/fields/TextareaField.svelte +101 -101
- package/dist/recipes/fields/ToggleField.svelte +60 -60
- package/dist/recipes/fields/index.js +7 -7
- package/dist/recipes/inputs/MultiSelect.spec.js +257 -257
- package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
- package/dist/recipes/inputs/MultiSelect.svelte +244 -244
- package/dist/recipes/inputs/OTPInput.spec.js +238 -238
- package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
- package/dist/recipes/inputs/OTPInput.svelte +102 -102
- package/dist/recipes/inputs/PasswordInput.svelte +100 -100
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +173 -173
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +108 -108
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +300 -300
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +165 -165
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +337 -337
- package/dist/recipes/inputs/Search.svelte +85 -85
- package/dist/recipes/inputs/SelectDropdown.svelte +161 -161
- package/dist/recipes/modals/AlertModal.svelte +130 -130
- package/dist/recipes/modals/ConfirmationModal.spec.js +191 -191
- package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
- package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
- package/dist/recipes/modals/InputModal.svelte +182 -182
- package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
- package/dist/recipes/modals/ModalStateManager.svelte +77 -77
- package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
- package/dist/recipes/modals/StatusModal.svelte +206 -206
- package/dist/services/EventService.js +75 -75
- package/dist/services/EventService.spec.js +217 -217
- package/dist/services/ShowService.spec.js +342 -342
- package/dist/stores/auth.js +93 -6
- package/dist/stores/auth.spec.js +310 -2
- package/dist/stores/toaster.js +13 -13
- package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
- package/dist/stories/ButtonAuditReview.svelte +427 -427
- package/dist/stories/PatternsGallery.stories.svelte +19 -19
- package/dist/stories/PatternsGallery.svelte +388 -388
- package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
- package/dist/stories/PrimitivesGallery.svelte +752 -752
- package/dist/stories/RecipesGallery.stories.svelte +19 -19
- package/dist/stories/RecipesGallery.svelte +441 -441
- package/dist/stories/button-audit-manifest.json +11186 -11186
- package/dist/tailwind/preset.cjs +82 -82
- package/dist/telemetry.js +357 -357
- package/dist/tokens/tokens.css +87 -87
- package/dist/utils/apiConfig.js +49 -49
- package/dist/utils/utils.js +9 -1
- package/package.json +233 -191
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
/**
|
|
3
|
-
* PasswordInput - Password field with show/hide toggle and strength indicator
|
|
4
|
-
*
|
|
5
|
-
* Combines Input (password type) with PasswordStrengthIndicator for
|
|
6
|
-
* a complete password entry experience.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* <PasswordInput
|
|
10
|
-
* label="New Password"
|
|
11
|
-
* bind:value={password}
|
|
12
|
-
* showStrength
|
|
13
|
-
* error={$errors.password}
|
|
14
|
-
* required
|
|
15
|
-
* />
|
|
16
|
-
*/
|
|
17
|
-
import Input from '../../primitives/Input/Input.svelte';
|
|
18
|
-
import PasswordStrengthIndicator from './PasswordStrengthIndicator/PasswordStrengthIndicator.svelte';
|
|
19
|
-
|
|
20
|
-
let {
|
|
21
|
-
/** Password value */
|
|
22
|
-
value = $bindable(''),
|
|
23
|
-
/** Label text */
|
|
24
|
-
label = '',
|
|
25
|
-
/** Placeholder text */
|
|
26
|
-
placeholder = '',
|
|
27
|
-
/** Input name attribute */
|
|
28
|
-
name = '',
|
|
29
|
-
/** Input id attribute */
|
|
30
|
-
id = '',
|
|
31
|
-
/** Whether the field is required */
|
|
32
|
-
required = false,
|
|
33
|
-
/** Whether the field is disabled */
|
|
34
|
-
disabled = false,
|
|
35
|
-
/** Error message to display */
|
|
36
|
-
error = '',
|
|
37
|
-
/** Hint text shown below input */
|
|
38
|
-
hint = '',
|
|
39
|
-
/** Show password strength indicator */
|
|
40
|
-
showStrength = false,
|
|
41
|
-
/** Size variant */
|
|
42
|
-
size = 'md',
|
|
43
|
-
/** Minimum password length */
|
|
44
|
-
minlength = null,
|
|
45
|
-
/** Maximum password length */
|
|
46
|
-
maxlength = null,
|
|
47
|
-
/** Autocomplete attribute */
|
|
48
|
-
autocomplete = 'new-password',
|
|
49
|
-
/** Whether to show the password toggle button */
|
|
50
|
-
showPasswordToggle = true,
|
|
51
|
-
/** Additional class for the wrapper div */
|
|
52
|
-
class: className = '',
|
|
53
|
-
// Callbacks
|
|
54
|
-
oninput,
|
|
55
|
-
onblur,
|
|
56
|
-
onfocus,
|
|
57
|
-
} = $props();
|
|
58
|
-
|
|
59
|
-
// Password strength tracking
|
|
60
|
-
let strengthScore = $state(-1);
|
|
61
|
-
let strengthText = $state('');
|
|
62
|
-
let strengthColor = $state('');
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<div class={className}>
|
|
66
|
-
<Input
|
|
67
|
-
type="password"
|
|
68
|
-
{id}
|
|
69
|
-
{name}
|
|
70
|
-
{placeholder}
|
|
71
|
-
{label}
|
|
72
|
-
{required}
|
|
73
|
-
{disabled}
|
|
74
|
-
{size}
|
|
75
|
-
{minlength}
|
|
76
|
-
{maxlength}
|
|
77
|
-
{autocomplete}
|
|
78
|
-
{showPasswordToggle}
|
|
79
|
-
errorText={error}
|
|
80
|
-
hintText={hint}
|
|
81
|
-
disableBuiltInValidation
|
|
82
|
-
bind:value
|
|
83
|
-
{oninput}
|
|
84
|
-
{onblur}
|
|
85
|
-
{onfocus}
|
|
86
|
-
/>
|
|
87
|
-
|
|
88
|
-
{#if showStrength && value}
|
|
89
|
-
<PasswordStrengthIndicator
|
|
90
|
-
password={value}
|
|
91
|
-
bind:score={strengthScore}
|
|
92
|
-
bind:strengthText
|
|
93
|
-
bind:textColor={strengthColor}
|
|
94
|
-
>
|
|
95
|
-
<p class="text-xs {strengthColor}">
|
|
96
|
-
Password strength: {strengthText}
|
|
97
|
-
</p>
|
|
98
|
-
</PasswordStrengthIndicator>
|
|
99
|
-
{/if}
|
|
100
|
-
</div>
|
|
1
|
+
<script>
|
|
2
|
+
/**
|
|
3
|
+
* PasswordInput - Password field with show/hide toggle and strength indicator
|
|
4
|
+
*
|
|
5
|
+
* Combines Input (password type) with PasswordStrengthIndicator for
|
|
6
|
+
* a complete password entry experience.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* <PasswordInput
|
|
10
|
+
* label="New Password"
|
|
11
|
+
* bind:value={password}
|
|
12
|
+
* showStrength
|
|
13
|
+
* error={$errors.password}
|
|
14
|
+
* required
|
|
15
|
+
* />
|
|
16
|
+
*/
|
|
17
|
+
import Input from '../../primitives/Input/Input.svelte';
|
|
18
|
+
import PasswordStrengthIndicator from './PasswordStrengthIndicator/PasswordStrengthIndicator.svelte';
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
/** Password value */
|
|
22
|
+
value = $bindable(''),
|
|
23
|
+
/** Label text */
|
|
24
|
+
label = '',
|
|
25
|
+
/** Placeholder text */
|
|
26
|
+
placeholder = '',
|
|
27
|
+
/** Input name attribute */
|
|
28
|
+
name = '',
|
|
29
|
+
/** Input id attribute */
|
|
30
|
+
id = '',
|
|
31
|
+
/** Whether the field is required */
|
|
32
|
+
required = false,
|
|
33
|
+
/** Whether the field is disabled */
|
|
34
|
+
disabled = false,
|
|
35
|
+
/** Error message to display */
|
|
36
|
+
error = '',
|
|
37
|
+
/** Hint text shown below input */
|
|
38
|
+
hint = '',
|
|
39
|
+
/** Show password strength indicator */
|
|
40
|
+
showStrength = false,
|
|
41
|
+
/** Size variant */
|
|
42
|
+
size = 'md',
|
|
43
|
+
/** Minimum password length */
|
|
44
|
+
minlength = null,
|
|
45
|
+
/** Maximum password length */
|
|
46
|
+
maxlength = null,
|
|
47
|
+
/** Autocomplete attribute */
|
|
48
|
+
autocomplete = 'new-password',
|
|
49
|
+
/** Whether to show the password toggle button */
|
|
50
|
+
showPasswordToggle = true,
|
|
51
|
+
/** Additional class for the wrapper div */
|
|
52
|
+
class: className = '',
|
|
53
|
+
// Callbacks
|
|
54
|
+
oninput,
|
|
55
|
+
onblur,
|
|
56
|
+
onfocus,
|
|
57
|
+
} = $props();
|
|
58
|
+
|
|
59
|
+
// Password strength tracking
|
|
60
|
+
let strengthScore = $state(-1);
|
|
61
|
+
let strengthText = $state('');
|
|
62
|
+
let strengthColor = $state('');
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<div class={className}>
|
|
66
|
+
<Input
|
|
67
|
+
type="password"
|
|
68
|
+
{id}
|
|
69
|
+
{name}
|
|
70
|
+
{placeholder}
|
|
71
|
+
{label}
|
|
72
|
+
{required}
|
|
73
|
+
{disabled}
|
|
74
|
+
{size}
|
|
75
|
+
{minlength}
|
|
76
|
+
{maxlength}
|
|
77
|
+
{autocomplete}
|
|
78
|
+
{showPasswordToggle}
|
|
79
|
+
errorText={error}
|
|
80
|
+
hintText={hint}
|
|
81
|
+
disableBuiltInValidation
|
|
82
|
+
bind:value
|
|
83
|
+
{oninput}
|
|
84
|
+
{onblur}
|
|
85
|
+
{onfocus}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
{#if showStrength && value}
|
|
89
|
+
<PasswordStrengthIndicator
|
|
90
|
+
password={value}
|
|
91
|
+
bind:score={strengthScore}
|
|
92
|
+
bind:strengthText
|
|
93
|
+
bind:textColor={strengthColor}
|
|
94
|
+
>
|
|
95
|
+
<p class="text-xs {strengthColor}">
|
|
96
|
+
Password strength: {strengthText}
|
|
97
|
+
</p>
|
|
98
|
+
</PasswordStrengthIndicator>
|
|
99
|
+
{/if}
|
|
100
|
+
</div>
|
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
import { render, screen, waitFor } from "@testing-library/svelte";
|
|
2
|
-
import { expect, describe, test, vi } from "vitest";
|
|
3
|
-
import PasswordStrengthIndicator from "./PasswordStrengthIndicator.svelte";
|
|
4
|
-
|
|
5
|
-
// Debounce delay + buffer
|
|
6
|
-
const DEBOUNCE_WAIT = 500;
|
|
7
|
-
|
|
8
|
-
function setupTest(args = {}) {
|
|
9
|
-
const { component, container } = render(PasswordStrengthIndicator, {
|
|
10
|
-
props: {
|
|
11
|
-
password: "",
|
|
12
|
-
...args,
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
return { component, container };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe("PasswordStrengthIndicator Component Tests", () => {
|
|
19
|
-
test("Does not render when password is empty", () => {
|
|
20
|
-
const { container } = setupTest({ password: "" });
|
|
21
|
-
const indicator = container.querySelector(".pt-2");
|
|
22
|
-
expect(indicator).not.toBeInTheDocument();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("Renders after debounce when password has value", async () => {
|
|
26
|
-
const { container } = setupTest({ password: "test" });
|
|
27
|
-
await waitFor(
|
|
28
|
-
() => {
|
|
29
|
-
const indicator = container.querySelector(".pt-2");
|
|
30
|
-
expect(indicator).toBeInTheDocument();
|
|
31
|
-
},
|
|
32
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("Has three strength bars", async () => {
|
|
37
|
-
const { container } = setupTest({ password: "test" });
|
|
38
|
-
await waitFor(
|
|
39
|
-
() => {
|
|
40
|
-
const bars = container.querySelectorAll(".h-1.flex-1.rounded-full");
|
|
41
|
-
expect(bars.length).toBe(3);
|
|
42
|
-
},
|
|
43
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test("Shows filled bars for weak password", async () => {
|
|
48
|
-
const { container } = setupTest({ password: "ab" });
|
|
49
|
-
await waitFor(
|
|
50
|
-
() => {
|
|
51
|
-
// At least one bar should be filled with a color
|
|
52
|
-
const coloredBars = container.querySelectorAll(
|
|
53
|
-
".bg-red-600, .bg-green-600"
|
|
54
|
-
);
|
|
55
|
-
expect(coloredBars.length).toBeGreaterThan(0);
|
|
56
|
-
},
|
|
57
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("Shows filled bars for good password", async () => {
|
|
62
|
-
const { container } = setupTest({ password: "Abc12345" });
|
|
63
|
-
await waitFor(
|
|
64
|
-
() => {
|
|
65
|
-
// All 3 bars should be filled for a good password
|
|
66
|
-
const successBars = container.querySelectorAll(".bg-green-600");
|
|
67
|
-
expect(successBars.length).toBe(3);
|
|
68
|
-
},
|
|
69
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
70
|
-
);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test("Exports score prop", () => {
|
|
74
|
-
const { component } = setupTest({ password: "test123" });
|
|
75
|
-
// Score should be accessible
|
|
76
|
-
expect(component).toBeDefined();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("Exports strengthText prop", () => {
|
|
80
|
-
const { component } = setupTest({ password: "test123" });
|
|
81
|
-
expect(component).toBeDefined();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("Exports textColor prop", () => {
|
|
85
|
-
const { component } = setupTest({ password: "test123" });
|
|
86
|
-
expect(component).toBeDefined();
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("Uses danger color for weak passwords", async () => {
|
|
90
|
-
const { container } = setupTest({ password: "weak" });
|
|
91
|
-
await waitFor(
|
|
92
|
-
() => {
|
|
93
|
-
const dangerBars = container.querySelectorAll(".bg-red-600");
|
|
94
|
-
expect(dangerBars.length).toBeGreaterThan(0);
|
|
95
|
-
},
|
|
96
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
97
|
-
);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test("Uses success color for good/strong passwords", async () => {
|
|
101
|
-
const { container } = setupTest({ password: "StrongP@ss123" });
|
|
102
|
-
await waitFor(
|
|
103
|
-
() => {
|
|
104
|
-
const successBars = container.querySelectorAll(".bg-green-600");
|
|
105
|
-
expect(successBars.length).toBe(3);
|
|
106
|
-
},
|
|
107
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
108
|
-
);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("Has transition animation classes on bars", async () => {
|
|
112
|
-
const { container } = setupTest({ password: "test" });
|
|
113
|
-
await waitFor(
|
|
114
|
-
() => {
|
|
115
|
-
const bars = container.querySelectorAll(".h-1.flex-1.rounded-full");
|
|
116
|
-
expect(bars.length).toBe(3);
|
|
117
|
-
bars.forEach((bar) => {
|
|
118
|
-
expect(bar).toHaveClass("transition-colors");
|
|
119
|
-
expect(bar).toHaveClass("duration-300");
|
|
120
|
-
});
|
|
121
|
-
},
|
|
122
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test("Very long password shows strong indicator", async () => {
|
|
127
|
-
const { container } = setupTest({ password: "1234567890123" }); // 13 chars
|
|
128
|
-
await waitFor(
|
|
129
|
-
() => {
|
|
130
|
-
const successBars = container.querySelectorAll(".bg-green-600");
|
|
131
|
-
expect(successBars.length).toBe(3);
|
|
132
|
-
},
|
|
133
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe("Password Strength Scoring", () => {
|
|
139
|
-
test("Score 2+ (Good) shows 3 success bars - 8+ chars with 2 diversity", async () => {
|
|
140
|
-
const { container } = setupTest({ password: "Abcdefgh" }); // Upper + lower
|
|
141
|
-
await waitFor(
|
|
142
|
-
() => {
|
|
143
|
-
const successBars = container.querySelectorAll(".bg-green-600");
|
|
144
|
-
expect(successBars.length).toBe(3);
|
|
145
|
-
},
|
|
146
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
147
|
-
);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test("Score 3 (Strong) - 10+ chars, multiple diversity", async () => {
|
|
151
|
-
const { container } = setupTest({ password: "Abcdefgh1!" }); // Upper, lower, number, symbol
|
|
152
|
-
await waitFor(
|
|
153
|
-
() => {
|
|
154
|
-
const successBars = container.querySelectorAll(".bg-green-600");
|
|
155
|
-
expect(successBars.length).toBe(3);
|
|
156
|
-
},
|
|
157
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
158
|
-
);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test("Weak password shows danger color bars", async () => {
|
|
162
|
-
const { container } = setupTest({ password: "abcdef" });
|
|
163
|
-
await waitFor(
|
|
164
|
-
() => {
|
|
165
|
-
const coloredBars = container.querySelectorAll(
|
|
166
|
-
".bg-red-600, .bg-green-600"
|
|
167
|
-
);
|
|
168
|
-
expect(coloredBars.length).toBeGreaterThan(0);
|
|
169
|
-
},
|
|
170
|
-
{ timeout: DEBOUNCE_WAIT }
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
});
|
|
1
|
+
import { render, screen, waitFor } from "@testing-library/svelte";
|
|
2
|
+
import { expect, describe, test, vi } from "vitest";
|
|
3
|
+
import PasswordStrengthIndicator from "./PasswordStrengthIndicator.svelte";
|
|
4
|
+
|
|
5
|
+
// Debounce delay + buffer
|
|
6
|
+
const DEBOUNCE_WAIT = 500;
|
|
7
|
+
|
|
8
|
+
function setupTest(args = {}) {
|
|
9
|
+
const { component, container } = render(PasswordStrengthIndicator, {
|
|
10
|
+
props: {
|
|
11
|
+
password: "",
|
|
12
|
+
...args,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
return { component, container };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("PasswordStrengthIndicator Component Tests", () => {
|
|
19
|
+
test("Does not render when password is empty", () => {
|
|
20
|
+
const { container } = setupTest({ password: "" });
|
|
21
|
+
const indicator = container.querySelector(".pt-2");
|
|
22
|
+
expect(indicator).not.toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("Renders after debounce when password has value", async () => {
|
|
26
|
+
const { container } = setupTest({ password: "test" });
|
|
27
|
+
await waitFor(
|
|
28
|
+
() => {
|
|
29
|
+
const indicator = container.querySelector(".pt-2");
|
|
30
|
+
expect(indicator).toBeInTheDocument();
|
|
31
|
+
},
|
|
32
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("Has three strength bars", async () => {
|
|
37
|
+
const { container } = setupTest({ password: "test" });
|
|
38
|
+
await waitFor(
|
|
39
|
+
() => {
|
|
40
|
+
const bars = container.querySelectorAll(".h-1.flex-1.rounded-full");
|
|
41
|
+
expect(bars.length).toBe(3);
|
|
42
|
+
},
|
|
43
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("Shows filled bars for weak password", async () => {
|
|
48
|
+
const { container } = setupTest({ password: "ab" });
|
|
49
|
+
await waitFor(
|
|
50
|
+
() => {
|
|
51
|
+
// At least one bar should be filled with a color
|
|
52
|
+
const coloredBars = container.querySelectorAll(
|
|
53
|
+
".bg-red-600, .bg-green-600"
|
|
54
|
+
);
|
|
55
|
+
expect(coloredBars.length).toBeGreaterThan(0);
|
|
56
|
+
},
|
|
57
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("Shows filled bars for good password", async () => {
|
|
62
|
+
const { container } = setupTest({ password: "Abc12345" });
|
|
63
|
+
await waitFor(
|
|
64
|
+
() => {
|
|
65
|
+
// All 3 bars should be filled for a good password
|
|
66
|
+
const successBars = container.querySelectorAll(".bg-green-600");
|
|
67
|
+
expect(successBars.length).toBe(3);
|
|
68
|
+
},
|
|
69
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("Exports score prop", () => {
|
|
74
|
+
const { component } = setupTest({ password: "test123" });
|
|
75
|
+
// Score should be accessible
|
|
76
|
+
expect(component).toBeDefined();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("Exports strengthText prop", () => {
|
|
80
|
+
const { component } = setupTest({ password: "test123" });
|
|
81
|
+
expect(component).toBeDefined();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("Exports textColor prop", () => {
|
|
85
|
+
const { component } = setupTest({ password: "test123" });
|
|
86
|
+
expect(component).toBeDefined();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("Uses danger color for weak passwords", async () => {
|
|
90
|
+
const { container } = setupTest({ password: "weak" });
|
|
91
|
+
await waitFor(
|
|
92
|
+
() => {
|
|
93
|
+
const dangerBars = container.querySelectorAll(".bg-red-600");
|
|
94
|
+
expect(dangerBars.length).toBeGreaterThan(0);
|
|
95
|
+
},
|
|
96
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("Uses success color for good/strong passwords", async () => {
|
|
101
|
+
const { container } = setupTest({ password: "StrongP@ss123" });
|
|
102
|
+
await waitFor(
|
|
103
|
+
() => {
|
|
104
|
+
const successBars = container.querySelectorAll(".bg-green-600");
|
|
105
|
+
expect(successBars.length).toBe(3);
|
|
106
|
+
},
|
|
107
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("Has transition animation classes on bars", async () => {
|
|
112
|
+
const { container } = setupTest({ password: "test" });
|
|
113
|
+
await waitFor(
|
|
114
|
+
() => {
|
|
115
|
+
const bars = container.querySelectorAll(".h-1.flex-1.rounded-full");
|
|
116
|
+
expect(bars.length).toBe(3);
|
|
117
|
+
bars.forEach((bar) => {
|
|
118
|
+
expect(bar).toHaveClass("transition-colors");
|
|
119
|
+
expect(bar).toHaveClass("duration-300");
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("Very long password shows strong indicator", async () => {
|
|
127
|
+
const { container } = setupTest({ password: "1234567890123" }); // 13 chars
|
|
128
|
+
await waitFor(
|
|
129
|
+
() => {
|
|
130
|
+
const successBars = container.querySelectorAll(".bg-green-600");
|
|
131
|
+
expect(successBars.length).toBe(3);
|
|
132
|
+
},
|
|
133
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe("Password Strength Scoring", () => {
|
|
139
|
+
test("Score 2+ (Good) shows 3 success bars - 8+ chars with 2 diversity", async () => {
|
|
140
|
+
const { container } = setupTest({ password: "Abcdefgh" }); // Upper + lower
|
|
141
|
+
await waitFor(
|
|
142
|
+
() => {
|
|
143
|
+
const successBars = container.querySelectorAll(".bg-green-600");
|
|
144
|
+
expect(successBars.length).toBe(3);
|
|
145
|
+
},
|
|
146
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("Score 3 (Strong) - 10+ chars, multiple diversity", async () => {
|
|
151
|
+
const { container } = setupTest({ password: "Abcdefgh1!" }); // Upper, lower, number, symbol
|
|
152
|
+
await waitFor(
|
|
153
|
+
() => {
|
|
154
|
+
const successBars = container.querySelectorAll(".bg-green-600");
|
|
155
|
+
expect(successBars.length).toBe(3);
|
|
156
|
+
},
|
|
157
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("Weak password shows danger color bars", async () => {
|
|
162
|
+
const { container } = setupTest({ password: "abcdef" });
|
|
163
|
+
await waitFor(
|
|
164
|
+
() => {
|
|
165
|
+
const coloredBars = container.querySelectorAll(
|
|
166
|
+
".bg-red-600, .bg-green-600"
|
|
167
|
+
);
|
|
168
|
+
expect(coloredBars.length).toBeGreaterThan(0);
|
|
169
|
+
},
|
|
170
|
+
{ timeout: DEBOUNCE_WAIT }
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
});
|