tide-design-system 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{IconAccountBalance-91cf067b.js → IconAccountBalance-0c552905.js} +1 -1
- package/dist/{IconAdd-95c51c0e.js → IconAdd-50766b43.js} +1 -1
- package/dist/{IconAi-08172540.js → IconAi-3f1ad2fe.js} +1 -1
- package/dist/{IconAlignSpace-9ab2bdf2.js → IconAlignSpace-804660fd.js} +1 -1
- package/dist/{IconApplePay-1ee6317b.js → IconApplePay-75b9850c.js} +1 -1
- package/dist/{IconArrowBack-a2226a94.js → IconArrowBack-3bde832a.js} +1 -1
- package/dist/{IconArrowForward-e1ca9957.js → IconArrowForward-0582323f.js} +1 -1
- package/dist/{IconArrowRight-53382084.js → IconArrowRight-c37875ce.js} +1 -1
- package/dist/{IconAssignment-332c2b2b.js → IconAssignment-b9549d2c.js} +1 -1
- package/dist/{IconAwardStar-1ca35385.js → IconAwardStar-a1b0a840.js} +1 -1
- package/dist/{IconBookmark-49b42628.js → IconBookmark-26e82ff4.js} +1 -1
- package/dist/{IconCalendarMonth-22c938d7.js → IconCalendarMonth-55806114.js} +1 -1
- package/dist/{IconCall-989a47fc.js → IconCall-dfc29049.js} +1 -1
- package/dist/{IconCheck-a3467b47.js → IconCheck-1d4a84f9.js} +1 -1
- package/dist/{IconChevronLeft-c1d90bb7.js → IconChevronLeft-8a9307a6.js} +1 -1
- package/dist/{IconChevronRight-ad47891f.js → IconChevronRight-46940da9.js} +1 -1
- package/dist/{IconClear-7c8fad4e.js → IconClear-1dc6a4df.js} +1 -1
- package/dist/{IconClose-4b6c5aed.js → IconClose-93976f13.js} +1 -1
- package/dist/{IconCycle-99d40f2d.js → IconCycle-b8bc8146.js} +1 -1
- package/dist/{IconDelete-446eff93.js → IconDelete-2970a09b.js} +1 -1
- package/dist/{IconDiamond-765a7d8d.js → IconDiamond-ba4bae95.js} +1 -1
- package/dist/{IconEdit-ce05f3b5.js → IconEdit-3612d58e.js} +1 -1
- package/dist/{IconError-7983707a.js → IconError-643df67d.js} +1 -1
- package/dist/{IconExpandContent-8b6e2125.js → IconExpandContent-71109869.js} +1 -1
- package/dist/{IconExpandLess-9e23f1e9.js → IconExpandLess-9c6c12b6.js} +1 -1
- package/dist/{IconExpandMore-ded098a7.js → IconExpandMore-fcd92910.js} +1 -1
- package/dist/{IconFacebook-3cab65a8.js → IconFacebook-b0d62bbb.js} +1 -1
- package/dist/{IconFavorite-5fe831f4.js → IconFavorite-d59dfc0b.js} +1 -1
- package/dist/{IconFavoriteFilled-58fa0bf7.js → IconFavoriteFilled-fd2c5862.js} +1 -1
- package/dist/{IconFormatBold-889f6b8b.js → IconFormatBold-6f1aa639.js} +1 -1
- package/dist/{IconFormatItalic-103eba00.js → IconFormatItalic-a82848b2.js} +1 -1
- package/dist/{IconFormatListBulleted-4c824025.js → IconFormatListBulleted-4f4a0a99.js} +1 -1
- package/dist/{IconForum-abc2fe82.js → IconForum-194dedbd.js} +1 -1
- package/dist/{IconGoogle-281b6d80.js → IconGoogle-46e6c4f1.js} +1 -1
- package/dist/{IconGooglePay-cc83c5c8.js → IconGooglePay-090b70a8.js} +1 -1
- package/dist/{IconGrid-ef763745.js → IconGrid-0f7c079c.js} +1 -1
- package/dist/{IconHelp-2ad33f76.js → IconHelp-e91f36a5.js} +1 -1
- package/dist/{IconInfo-5878df77.js → IconInfo-df1f06a5.js} +1 -1
- package/dist/{IconInsertText-0c62badf.js → IconInsertText-e371c1cd.js} +1 -1
- package/dist/{IconInstagram-69e21cfb.js → IconInstagram-af4ea628.js} +1 -1
- package/dist/{IconIosShare-be5f117c.js → IconIosShare-7253c1df.js} +1 -1
- package/dist/{IconLayout-c1ffbcd3.js → IconLayout-225d9fb6.js} +1 -1
- package/dist/{IconLinkedIn-807ef6f5.js → IconLinkedIn-ab7e007c.js} +1 -1
- package/dist/{IconLocalShipping-2c6d71e0.js → IconLocalShipping-2c8ac96c.js} +1 -1
- package/dist/{IconLock-9178e816.js → IconLock-b4e1bd5d.js} +1 -1
- package/dist/{IconMail-0123a7c6.js → IconMail-50eca4b4.js} +1 -1
- package/dist/{IconMenu-33ed2d99.js → IconMenu-7789a1f9.js} +1 -1
- package/dist/{IconMoreHoriz-c281099f.js → IconMoreHoriz-35960212.js} +1 -1
- package/dist/{IconNotifications-89f80e0f.js → IconNotifications-a6690c77.js} +1 -1
- package/dist/{IconOpenInNew-87ad0454.js → IconOpenInNew-8b812d7f.js} +1 -1
- package/dist/{IconPalette-7ee5b40c.js → IconPalette-18b6e766.js} +1 -1
- package/dist/{IconPaypal-e311eadd.js → IconPaypal-75ff8ed5.js} +1 -1
- package/dist/{IconPerson-932fbcbc.js → IconPerson-3c8a4c27.js} +1 -1
- package/dist/{IconPhotoCamera-fdbd5767.js → IconPhotoCamera-0fbb9344.js} +1 -1
- package/dist/{IconPinterest-2d19c2eb.js → IconPinterest-28ae7c92.js} +1 -1
- package/dist/{IconPlayArrow-9837a5c0.js → IconPlayArrow-6d779a71.js} +1 -1
- package/dist/{IconRemove-29ef8f82.js → IconRemove-1f655305.js} +1 -1
- package/dist/{IconRoundedCorners-8ad194fc.js → IconRoundedCorners-1f9eba28.js} +1 -1
- package/dist/{IconSearch-5ff23d26.js → IconSearch-c6843cf3.js} +1 -1
- package/dist/{IconSell-0e0ecd20.js → IconSell-c7818ac8.js} +1 -1
- package/dist/{IconShare-47084765.js → IconShare-b81bc4cd.js} +1 -1
- package/dist/{IconShoppingCart-9d6495b3.js → IconShoppingCart-b6cc2022.js} +1 -1
- package/dist/{IconSms-5ba18382.js → IconSms-dc4c1454.js} +1 -1
- package/dist/{IconStar-ef69284b.js → IconStar-c4305bd6.js} +1 -1
- package/dist/{IconSwapVert-05e14e3d.js → IconSwapVert-00e66af6.js} +1 -1
- package/dist/{IconThreeDRotation-2433b2e8.js → IconThreeDRotation-b19a9312.js} +1 -1
- package/dist/{IconTune-3c6452f0.js → IconTune-dee47734.js} +1 -1
- package/dist/{IconTwitter-a634cef4.js → IconTwitter-2ab4e06b.js} +1 -1
- package/dist/{IconVideocam-5712435e.js → IconVideocam-0d0142aa.js} +1 -1
- package/dist/{IconViewInAr-d38a23d5.js → IconViewInAr-7cd92579.js} +1 -1
- package/dist/{IconVisibility-8cdf7151.js → IconVisibility-84655778.js} +1 -1
- package/dist/{IconWarning-b9e61180.js → IconWarning-cab4938a.js} +1 -1
- package/dist/{IconYoutube-92447826.js → IconYoutube-ab7e33d3.js} +1 -1
- package/dist/css/dynamic-utilities.css +0 -1
- package/dist/css/main.css +0 -1
- package/dist/css/utilities.css +9 -8
- package/dist/css/variables.css +21 -17
- package/dist/index-32686488.js +2106 -0
- package/dist/style.css +1 -1
- package/dist/tide-design-system.js +48 -0
- package/dist/types/FacetRange.ts +84 -0
- package/dist/types/Field.ts +0 -1
- package/dist/types/Form.ts +57 -0
- package/dist/types/Realm.ts +1 -0
- package/dist/types/Select.ts +6 -0
- package/dist/types/Storybook.ts +206 -1
- package/dist/types/Styles.ts +64 -30
- package/dist/types/Validation.ts +7 -1
- package/dist/utilities/format.ts +75 -39
- package/dist/utilities/storybook.ts +35 -1
- package/dist/utilities/validation.ts +139 -34
- package/package.json +1 -1
- package/dist/css/dynamic-inputs.css +0 -43
- package/dist/index-c5bc4216.js +0 -1910
- package/dist/tide2-design-system.js +0 -36
- package/dist/types/StorybookStyles.ts +0 -209
- package/dist/types/Vehicle.ts +0 -139
- package/dist/types/VehicleDetail.ts +0 -44
- package/dist/types/index.d.ts +0 -7
- package/dist/utilities/forms.ts +0 -47
- package/dist/utilities/media.ts +0 -77
package/dist/types/Styles.ts
CHANGED
|
@@ -22,18 +22,26 @@ export const CSS = {
|
|
|
22
22
|
END: 'tide-axis2-end',
|
|
23
23
|
START: 'tide-axis2-start',
|
|
24
24
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
BG: {
|
|
26
|
+
PRIMARY: 'tide-bg-primary',
|
|
27
|
+
SECONDARY: 'tide-bg-secondary',
|
|
28
|
+
SURFACE: {
|
|
29
|
+
ACCENT: 'tide-bg-surface-accent',
|
|
30
|
+
ACCENT_VARIANT: 'tide-bg-surface-accent-variant',
|
|
31
|
+
BRAND: 'tide-bg-surface-brand',
|
|
32
|
+
DEFAULT: 'tide-bg-surface',
|
|
33
|
+
FLOATING: 'tide-bg-surface-floating',
|
|
34
|
+
GRADIENT: 'tide-bg-surface-gradient',
|
|
35
|
+
VARIANT: 'tide-bg-surface-variant',
|
|
33
36
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
},
|
|
38
|
+
BORDER: {
|
|
39
|
+
COLOR: {
|
|
40
|
+
DEFAULT: 'tide-border',
|
|
41
|
+
FLOATING: 'tide-border-floating',
|
|
42
|
+
HIGH: 'tide-border-high',
|
|
43
|
+
LOW: 'tide-border-low',
|
|
44
|
+
PRIMARY: 'tide-border-primary',
|
|
37
45
|
},
|
|
38
46
|
RADIUS: {
|
|
39
47
|
FULL: 'tide-radius-full',
|
|
@@ -41,13 +49,27 @@ export const CSS = {
|
|
|
41
49
|
ONE: 'tide-radius-1',
|
|
42
50
|
QUARTER: 'tide-radius-1/4',
|
|
43
51
|
},
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
SIDE: {
|
|
53
|
+
BOTTOM: {
|
|
54
|
+
ONE: 'tide-border-bottom-1',
|
|
55
|
+
TWO: 'tide-border-bottom-2',
|
|
56
|
+
},
|
|
57
|
+
FULL: {
|
|
58
|
+
ONE: 'tide-border-1',
|
|
59
|
+
TWO: 'tide-border-2',
|
|
60
|
+
},
|
|
61
|
+
LEFT: {
|
|
62
|
+
ONE: 'tide-border-left-1',
|
|
63
|
+
TWO: 'tide-border-left-2',
|
|
64
|
+
},
|
|
65
|
+
RIGHT: {
|
|
66
|
+
ONE: 'tide-border-right-1',
|
|
67
|
+
TWO: 'tide-border-right-2',
|
|
68
|
+
},
|
|
69
|
+
TOP: {
|
|
70
|
+
ONE: 'tide-border-top-1',
|
|
71
|
+
TWO: 'tide-border-top-2',
|
|
72
|
+
},
|
|
51
73
|
},
|
|
52
74
|
},
|
|
53
75
|
BOX_SIZING: {
|
|
@@ -60,17 +82,18 @@ export const CSS = {
|
|
|
60
82
|
CURSOR: {
|
|
61
83
|
NOT_ALLOWED: 'tide-cursor-not-allowed',
|
|
62
84
|
POINTER: 'tide-cursor-pointer',
|
|
85
|
+
TEXT: 'tide-cursor-text',
|
|
63
86
|
},
|
|
64
87
|
DISPLAY: {
|
|
65
88
|
BLOCK: 'tide-display-block',
|
|
66
89
|
CONTENTS: 'tide-contents',
|
|
67
90
|
FLEX: 'tide-display-flex',
|
|
68
91
|
GRID: 'tide-display-grid',
|
|
69
|
-
HIDDEN: 'tide-display-hidden',
|
|
70
92
|
INITIAL: 'initial',
|
|
71
93
|
INLINE: 'tide-display-inline',
|
|
72
94
|
INLINE_BLOCK: 'tide-display-inline-block',
|
|
73
95
|
INLINE_FLEX: 'tide-display-inline-flex',
|
|
96
|
+
NONE: 'tide-display-none',
|
|
74
97
|
},
|
|
75
98
|
FLEX: {
|
|
76
99
|
DIRECTION: {
|
|
@@ -90,6 +113,17 @@ export const CSS = {
|
|
|
90
113
|
WRAP: 'tide-flex-wrap',
|
|
91
114
|
},
|
|
92
115
|
FONT: {
|
|
116
|
+
COLOR: {
|
|
117
|
+
PRIMARY: 'tide-font-on-primary',
|
|
118
|
+
SECONDARY: 'tide-font-on-secondary',
|
|
119
|
+
SURFACE: {
|
|
120
|
+
BRAND: 'tide-font-on-surface-brand',
|
|
121
|
+
DEFAULT: 'tide-font-on-surface',
|
|
122
|
+
INVERSE: 'tide-font-on-surface-inverse',
|
|
123
|
+
VARIANT: 'tide-font-on-surface-variant',
|
|
124
|
+
VARIANT_INVERSE: 'tide-font-on-surface-variant-inverse',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
93
127
|
SIZE: {
|
|
94
128
|
FOURTEEN: 'tide-font-14',
|
|
95
129
|
SIXTEEN: 'tide-font-16',
|
|
@@ -303,7 +337,7 @@ export const cssSortOrder = [
|
|
|
303
337
|
CSS.DISPLAY.CONTENTS,
|
|
304
338
|
CSS.DISPLAY.FLEX,
|
|
305
339
|
CSS.DISPLAY.GRID,
|
|
306
|
-
CSS.DISPLAY.
|
|
340
|
+
CSS.DISPLAY.NONE,
|
|
307
341
|
CSS.DISPLAY.INITIAL,
|
|
308
342
|
CSS.DISPLAY.INLINE,
|
|
309
343
|
CSS.DISPLAY.INLINE_BLOCK,
|
|
@@ -379,16 +413,16 @@ export const cssSortOrder = [
|
|
|
379
413
|
CSS.MARGIN.LEFT.TWO,
|
|
380
414
|
CSS.MARGIN.LEFT.FOUR,
|
|
381
415
|
CSS.MARGIN.LEFT.AUTO,
|
|
382
|
-
CSS.BORDER.FULL.ONE,
|
|
383
|
-
CSS.BORDER.FULL.TWO,
|
|
384
|
-
CSS.BORDER.TOP.ONE,
|
|
385
|
-
CSS.BORDER.TOP.TWO,
|
|
386
|
-
CSS.BORDER.RIGHT.ONE,
|
|
387
|
-
CSS.BORDER.RIGHT.TWO,
|
|
388
|
-
CSS.BORDER.BOTTOM.ONE,
|
|
389
|
-
CSS.BORDER.BOTTOM.TWO,
|
|
390
|
-
CSS.BORDER.LEFT.ONE,
|
|
391
|
-
CSS.BORDER.LEFT.TWO,
|
|
416
|
+
CSS.BORDER.SIDE.FULL.ONE,
|
|
417
|
+
CSS.BORDER.SIDE.FULL.TWO,
|
|
418
|
+
CSS.BORDER.SIDE.TOP.ONE,
|
|
419
|
+
CSS.BORDER.SIDE.TOP.TWO,
|
|
420
|
+
CSS.BORDER.SIDE.RIGHT.ONE,
|
|
421
|
+
CSS.BORDER.SIDE.RIGHT.TWO,
|
|
422
|
+
CSS.BORDER.SIDE.BOTTOM.ONE,
|
|
423
|
+
CSS.BORDER.SIDE.BOTTOM.TWO,
|
|
424
|
+
CSS.BORDER.SIDE.LEFT.ONE,
|
|
425
|
+
CSS.BORDER.SIDE.LEFT.TWO,
|
|
392
426
|
CSS.BORDER.RADIUS.ONE,
|
|
393
427
|
CSS.BORDER.RADIUS.HALF,
|
|
394
428
|
CSS.BORDER.RADIUS.QUARTER,
|
package/dist/types/Validation.ts
CHANGED
|
@@ -11,8 +11,14 @@ export const VALIDATOR = {
|
|
|
11
11
|
|
|
12
12
|
export type ValidationError = string | boolean;
|
|
13
13
|
export type ValidationResult = {
|
|
14
|
-
valid: boolean;
|
|
15
14
|
message: string;
|
|
15
|
+
valid: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type ValidationLength = {
|
|
19
|
+
maxlength?: number;
|
|
20
|
+
minlength?: number;
|
|
21
|
+
value: string;
|
|
16
22
|
};
|
|
17
23
|
|
|
18
24
|
export type Validator = (value: string) => ValidationResult;
|
package/dist/utilities/format.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
const capitalizeFirst = (string: string) => {
|
|
2
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
3
|
+
};
|
|
2
4
|
|
|
3
5
|
const formatCamelCase = (input: string): string => {
|
|
4
6
|
return input && typeof input === 'string'
|
|
@@ -22,9 +24,26 @@ const formatKebabCase = (input: string): string => {
|
|
|
22
24
|
: input;
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
const formatLabel = (value: string) => {
|
|
28
|
+
const labelMap: { [key: string]: string } = {
|
|
29
|
+
false: 'No',
|
|
30
|
+
true: 'Yes',
|
|
31
|
+
};
|
|
32
|
+
return Object.hasOwn(labelMap, value) ? labelMap[value] : value;
|
|
33
|
+
};
|
|
34
|
+
|
|
25
35
|
const formatNumber = (input: number | string): string => {
|
|
26
|
-
|
|
27
|
-
|
|
36
|
+
let output = input && typeof input === 'number' ? new Intl.NumberFormat().format(input) : String(input || '');
|
|
37
|
+
let digits = output;
|
|
38
|
+
|
|
39
|
+
if (input && typeof input === 'string') {
|
|
40
|
+
digits = digits.replace(/\D/g, '');
|
|
41
|
+
if (Number(digits)) {
|
|
42
|
+
output = new Intl.NumberFormat().format(Number(digits));
|
|
43
|
+
} else {
|
|
44
|
+
output = '0';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
28
47
|
|
|
29
48
|
return output;
|
|
30
49
|
};
|
|
@@ -42,38 +61,39 @@ const formatPascalCase = (input: string): string => {
|
|
|
42
61
|
};
|
|
43
62
|
|
|
44
63
|
const formatPhone = (input: number | string): string => {
|
|
45
|
-
|
|
46
|
-
let
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
output = `${digits.slice(0, 1)}-${digits.slice(1, 4)}-${digits.slice(4, 7)}-${digits.slice(7)}`;
|
|
63
|
-
break;
|
|
64
|
-
default:
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
64
|
+
let output = input && typeof input === 'number' ? String(input) : String(input || '');
|
|
65
|
+
let digits = output;
|
|
66
|
+
digits = digits.replace(/\D/g, '');
|
|
67
|
+
|
|
68
|
+
switch (digits.length) {
|
|
69
|
+
case 7:
|
|
70
|
+
output = `${digits.slice(0, 3)}-${digits.slice(3)}`;
|
|
71
|
+
break;
|
|
72
|
+
case 10:
|
|
73
|
+
output = `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
74
|
+
break;
|
|
75
|
+
case 11:
|
|
76
|
+
output = `${digits.slice(0, 1)}-${digits.slice(1, 4)}-${digits.slice(4, 7)}-${digits.slice(7)}`;
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
output = digits;
|
|
80
|
+
break;
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
return output;
|
|
71
84
|
};
|
|
72
85
|
|
|
73
86
|
const formatPrice = (input: number | string): string => {
|
|
74
|
-
const output = formatNumber(input);
|
|
87
|
+
const output = input ? formatNumber(input) : String(input || '0');
|
|
88
|
+
return `$${output}`;
|
|
89
|
+
};
|
|
75
90
|
|
|
76
|
-
|
|
91
|
+
const formatQuotes = (value: string) => {
|
|
92
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
93
|
+
return value.slice(1, -1);
|
|
94
|
+
} else {
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
77
97
|
};
|
|
78
98
|
|
|
79
99
|
const formatSentenceCase = (input: string): string => {
|
|
@@ -112,6 +132,17 @@ const formatTitleCase = (input: string): string => {
|
|
|
112
132
|
: input;
|
|
113
133
|
};
|
|
114
134
|
|
|
135
|
+
const formatUrlFromRoot = (url: string) => {
|
|
136
|
+
const urlFormatted = url.split('.com/');
|
|
137
|
+
|
|
138
|
+
return urlFormatted.length > 1 ? `/${urlFormatted[1]}` : url;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const formatWeight = (input: number | string): string => {
|
|
142
|
+
const output = input ? formatNumber(input) : String(input || '0');
|
|
143
|
+
return `${output} lbs`;
|
|
144
|
+
};
|
|
145
|
+
|
|
115
146
|
const getArticle = (noun: string, isPlural = false, isDefinite = false) => {
|
|
116
147
|
const vowels = ['a', 'e', 'i', 'o', 'u'];
|
|
117
148
|
const isVowelLeading = vowels.includes(noun.charAt(0));
|
|
@@ -119,30 +150,35 @@ const getArticle = (noun: string, isPlural = false, isDefinite = false) => {
|
|
|
119
150
|
return isDefinite ? 'the' : isPlural ? 'some' : isVowelLeading ? 'an' : 'a';
|
|
120
151
|
};
|
|
121
152
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return
|
|
153
|
+
const priceToNumber = (value: string) => {
|
|
154
|
+
if (Number.isNaN(Number(value))) {
|
|
155
|
+
value = value.replace('$', '');
|
|
156
|
+
value = value.replace(/,/g, '');
|
|
157
|
+
}
|
|
158
|
+
return parseInt(value, 10);
|
|
128
159
|
};
|
|
129
160
|
|
|
130
|
-
const
|
|
131
|
-
|
|
161
|
+
const unformatPrice = (input: string): string => {
|
|
162
|
+
const output = input.replace(/\$/g, '').replace(/,/g, '');
|
|
163
|
+
return `${output}`;
|
|
132
164
|
};
|
|
133
165
|
|
|
134
166
|
export {
|
|
167
|
+
capitalizeFirst,
|
|
135
168
|
formatCamelCase,
|
|
136
169
|
formatKebabCase,
|
|
170
|
+
formatLabel,
|
|
137
171
|
formatNumber,
|
|
138
172
|
formatPascalCase,
|
|
139
173
|
formatPhone,
|
|
140
174
|
formatPrice,
|
|
175
|
+
formatQuotes,
|
|
141
176
|
formatSentenceCase,
|
|
142
177
|
formatSnakeCase,
|
|
143
178
|
formatTitleCase,
|
|
179
|
+
formatUrlFromRoot,
|
|
180
|
+
formatWeight,
|
|
144
181
|
getArticle,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
removeMarkup,
|
|
182
|
+
priceToNumber,
|
|
183
|
+
unformatPrice,
|
|
148
184
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ArgTypes } from '@storybook/vue3';
|
|
2
2
|
|
|
3
3
|
import { BOOLEAN_UNREQUIRED } from '@/types/Storybook';
|
|
4
|
+
import { CSS } from '@/types/Styles';
|
|
4
5
|
import { ELEMENT, ELEMENT_TEXT_AS_ICON } from '@/types/Element';
|
|
5
6
|
|
|
6
7
|
// Extensible object of key/value pairs
|
|
@@ -64,7 +65,7 @@ export const doSomething = () => {
|
|
|
64
65
|
alert('Did something.');
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
// Accept a KeyValue as the value of an object with a retrievable key as a Storybook argType
|
|
68
|
+
// Accept a KeyValue as the value of an object with a retrievable key as a Storybook argType.
|
|
68
69
|
export const formatArgType = (collection: KeyValueNamed) => {
|
|
69
70
|
const constant = getKey(collection);
|
|
70
71
|
const keyValues: KeyValue = collection[constant];
|
|
@@ -203,6 +204,39 @@ export const formatSnippetMinimal = (code: string) => {
|
|
|
203
204
|
return code.replace(/<[/]*template>/g, '');
|
|
204
205
|
};
|
|
205
206
|
|
|
207
|
+
export const getConstantByValue = (value: string) => {
|
|
208
|
+
const compareRecursively = (basis: string, shape: string | object, depth: number = 0): string | void => {
|
|
209
|
+
let output;
|
|
210
|
+
|
|
211
|
+
Object.entries(shape).forEach((entry: string[]) => {
|
|
212
|
+
const key = entry[0];
|
|
213
|
+
const value = entry[1];
|
|
214
|
+
const type = typeof value;
|
|
215
|
+
|
|
216
|
+
if (type === 'string' && basis === value) {
|
|
217
|
+
output = key;
|
|
218
|
+
return;
|
|
219
|
+
} else if (type === 'object') {
|
|
220
|
+
const match = compareRecursively(basis, value, depth + 1);
|
|
221
|
+
|
|
222
|
+
if (match) {
|
|
223
|
+
output = `${key}.${match}`;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return output;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const constant = compareRecursively(value, CSS);
|
|
233
|
+
|
|
234
|
+
return constant ? `CSS.${constant}` : undefined;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const getConstantsByValues = (classNames: string[]) =>
|
|
238
|
+
classNames.map((className) => getConstantByValue(className));
|
|
239
|
+
|
|
206
240
|
export const getKey = (input: any) => Object.keys(input)[0];
|
|
207
241
|
|
|
208
242
|
// Invert key/value pairs bc Storybook control option format is unintuitive.
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import type { Ref } from 'vue';
|
|
2
|
-
import type { StringField } from '@/types/Field';
|
|
3
|
-
import type { ValidationResult } from '@/types/Validation';
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import type { RangeData } from '@/types/FacetRange';
|
|
4
|
+
import type { SelectOption } from '@/types/Select';
|
|
5
|
+
import type { StringInput } from '@/types/Form';
|
|
6
|
+
import type { ValidationError, ValidationLength, ValidationResult, Validator } from '@/types/Validation';
|
|
7
|
+
|
|
8
|
+
import { priceToNumber } from '@/utilities/format';
|
|
9
|
+
|
|
10
|
+
export const errorMessageDefault = 'Please enter a valid value.';
|
|
11
|
+
|
|
12
|
+
export const noError = {
|
|
13
|
+
message: '',
|
|
14
|
+
valid: true,
|
|
15
|
+
} as Readonly<ValidationResult>;
|
|
16
|
+
|
|
17
|
+
export const checkFormat = (format: RegExp) => {
|
|
6
18
|
return (value: string): ValidationResult => {
|
|
7
|
-
let result =
|
|
8
|
-
message: '',
|
|
9
|
-
valid: true,
|
|
10
|
-
};
|
|
19
|
+
let result = noError;
|
|
11
20
|
|
|
12
21
|
if (!value.trim().match(format)) {
|
|
13
22
|
result = {
|
|
@@ -18,68 +27,164 @@ export function checkFormat(format: RegExp) {
|
|
|
18
27
|
|
|
19
28
|
return result;
|
|
20
29
|
};
|
|
21
|
-
}
|
|
30
|
+
};
|
|
22
31
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
maxlength,
|
|
27
|
-
minlength,
|
|
28
|
-
value,
|
|
29
|
-
});
|
|
32
|
+
export const getErrorMessage = (errorFromProps: ValidationError, errorFromRef: ValidationError) => {
|
|
33
|
+
// error in props takes precedence over validation error
|
|
34
|
+
if (typeof errorFromProps === 'string' && errorFromProps.length > 0) return errorFromProps;
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
return typeof errorFromRef === 'string' && errorFromRef.length > 0 ? errorFromRef : errorMessageDefault;
|
|
37
|
+
};
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
export const getFieldHasError = (errorFromProps: ValidationError, errorFromRef: ValidationError) =>
|
|
40
|
+
errorFromProps !== false || errorFromRef !== false;
|
|
41
|
+
|
|
42
|
+
export const getFieldLengthIsValid = ({ maxlength, minlength, value }: ValidationLength) => {
|
|
43
|
+
const tooShort = maxlength && value.length > maxlength;
|
|
44
|
+
const tooLong = minlength && value.length < minlength;
|
|
45
|
+
|
|
46
|
+
return !tooShort && !tooLong;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const getMaxRangeIsValid = ({ min }: Pick<RangeData, 'min'>, type?: 'price') => {
|
|
50
|
+
return (value: string): ValidationResult => {
|
|
51
|
+
let newMax: number | null = type === 'price' ? priceToNumber(value) : Number(value);
|
|
52
|
+
newMax = !isNaN(newMax) ? newMax : null;
|
|
53
|
+
if (min && newMax) {
|
|
54
|
+
if (newMax >= min) {
|
|
55
|
+
return {
|
|
56
|
+
message: '',
|
|
57
|
+
valid: true,
|
|
58
|
+
};
|
|
59
|
+
} else {
|
|
60
|
+
return {
|
|
61
|
+
message: `Must be greater than min`,
|
|
62
|
+
valid: false,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
return noError;
|
|
35
67
|
}
|
|
68
|
+
};
|
|
69
|
+
};
|
|
36
70
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
71
|
+
export const getMinRangeIsValid = ({ max }: Pick<RangeData, 'max'>, type?: 'price') => {
|
|
72
|
+
return (value: string): ValidationResult => {
|
|
73
|
+
let newMin: number | null = type === 'price' ? priceToNumber(value) : Number(value);
|
|
74
|
+
newMin = !isNaN(newMin) ? newMin : null;
|
|
75
|
+
if (max && newMin) {
|
|
76
|
+
if (newMin <= max) {
|
|
77
|
+
return {
|
|
78
|
+
message: '',
|
|
79
|
+
valid: true,
|
|
80
|
+
};
|
|
81
|
+
} else {
|
|
82
|
+
return {
|
|
83
|
+
message: `Must be less than max`,
|
|
84
|
+
valid: false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
return noError;
|
|
89
|
+
}
|
|
41
90
|
};
|
|
42
|
-
}
|
|
91
|
+
};
|
|
43
92
|
|
|
44
|
-
export const
|
|
93
|
+
export const getSelectOptionsFromStrings = (strings: string[]) =>
|
|
94
|
+
strings.map(
|
|
95
|
+
(option) =>
|
|
96
|
+
({
|
|
97
|
+
label: option,
|
|
98
|
+
value: option,
|
|
99
|
+
} as SelectOption)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
export const handleFieldValidation = ({
|
|
103
|
+
error,
|
|
104
|
+
errorFromProps,
|
|
45
105
|
maxlength,
|
|
46
106
|
minlength,
|
|
107
|
+
validators,
|
|
47
108
|
value,
|
|
48
109
|
}: {
|
|
110
|
+
error: Ref<ValidationError>;
|
|
111
|
+
errorFromProps: ValidationError;
|
|
49
112
|
maxlength?: number;
|
|
50
113
|
minlength?: number;
|
|
51
|
-
|
|
114
|
+
validators?: Validator[];
|
|
115
|
+
value: Ref<string>;
|
|
52
116
|
}) => {
|
|
53
|
-
|
|
54
|
-
const tooLong = minlength && value.length < minlength;
|
|
117
|
+
// error in props takes precedence over validation error
|
|
55
118
|
|
|
56
|
-
|
|
57
|
-
};
|
|
119
|
+
error.value = errorFromProps ? errorFromProps : false;
|
|
58
120
|
|
|
59
|
-
|
|
121
|
+
if (!error.value && validators) {
|
|
122
|
+
const validation = validateProperty(value.value, validators);
|
|
123
|
+
|
|
124
|
+
if (!validation.valid) {
|
|
125
|
+
error.value = validation.message;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!error.value && (maxlength || minlength)) {
|
|
130
|
+
const lengthvalidation = validateLength({
|
|
131
|
+
maxlength,
|
|
132
|
+
minlength,
|
|
133
|
+
value: value.value,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
if (!lengthvalidation.valid) {
|
|
137
|
+
error.value = lengthvalidation.message;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
60
141
|
|
|
61
|
-
export function validateFieldsFromRefs(fields: { [key: string]: Ref<
|
|
142
|
+
export function validateFieldsFromRefs(fields: { [key: string]: Ref<StringInput | null> }) {
|
|
62
143
|
let valid = true;
|
|
63
144
|
|
|
64
145
|
for (const key in fields) {
|
|
65
146
|
if (fields[key].value?.required) {
|
|
66
147
|
const value = fields[key].value?.value;
|
|
67
|
-
|
|
68
148
|
valid = valid && !!value && value.trim() !== '';
|
|
69
149
|
}
|
|
70
150
|
|
|
71
151
|
const error = fields[key].value?.error;
|
|
72
|
-
|
|
73
152
|
valid = valid && !error;
|
|
74
153
|
}
|
|
75
154
|
|
|
76
155
|
return valid;
|
|
77
156
|
}
|
|
78
157
|
|
|
158
|
+
export const validateLength = ({ maxlength, minlength, value }: ValidationLength): ValidationResult => {
|
|
159
|
+
const response = {
|
|
160
|
+
message: '',
|
|
161
|
+
valid: true,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
response.valid = getFieldLengthIsValid({
|
|
165
|
+
maxlength,
|
|
166
|
+
minlength,
|
|
167
|
+
value,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (response.valid) return response;
|
|
171
|
+
|
|
172
|
+
response.message = errorMessageDefault;
|
|
173
|
+
|
|
174
|
+
if (maxlength && minlength) {
|
|
175
|
+
response.message = `Please enter a value between ${minlength} and ${maxlength} characters in length.`;
|
|
176
|
+
} else if (maxlength) {
|
|
177
|
+
response.message = `Please enter a value no more than ${maxlength} characters in length.`;
|
|
178
|
+
} else if (minlength) {
|
|
179
|
+
response.message = `Please enter a value no less than ${minlength} characters in length.`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return response;
|
|
183
|
+
};
|
|
184
|
+
|
|
79
185
|
export function validateProperty(value: string, validators: ((value: string) => ValidationResult)[]): ValidationResult {
|
|
80
186
|
for (const validator of validators) {
|
|
81
187
|
const validation = validator(value);
|
|
82
|
-
|
|
83
188
|
if (!validation.valid) {
|
|
84
189
|
return validation;
|
|
85
190
|
}
|
package/package.json
CHANGED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
.block-field .field {
|
|
2
|
-
--input-outline-width: var(--border-w-1);
|
|
3
|
-
outline: var(--input-outline-width) solid var(--ti-surface-border-rest);
|
|
4
|
-
outline-offset: calc(var(--input-outline-width) * -1);
|
|
5
|
-
color: var(--ti-surface-foreground);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.block-field .field::placeholder {
|
|
9
|
-
color: var(--ti-surface-variant-foreground);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.block-field.error {
|
|
13
|
-
color: var(--error-on-surface);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.block-field.error .field {
|
|
17
|
-
outline-color: var(--error-border-rest);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.block-field.error:focus-within .field {
|
|
21
|
-
outline-color: var(--error-border-rest);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.block-field.error:hover {
|
|
25
|
-
color: var(--error-on-surface-variant);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.block-field.error:hover .field {
|
|
29
|
-
outline-color: var(--error-border-high);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.block-field.disabled {
|
|
33
|
-
opacity: 0.333;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.block-field:hover .field {
|
|
37
|
-
outline-color: var(--ti-surface-border-high);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.block-field:focus-within .field {
|
|
41
|
-
--input-outline-width: var(--border-w-2);
|
|
42
|
-
outline-color: var(--ti-surface-border-high);
|
|
43
|
-
}
|