mtrl 0.2.6 → 0.2.7
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/index.ts +18 -0
- package/package.json +1 -1
- package/src/components/badge/_styles.scss +117 -109
- package/src/components/badge/api.ts +57 -59
- package/src/components/badge/badge.ts +16 -2
- package/src/components/badge/config.ts +65 -11
- package/src/components/badge/constants.ts +22 -12
- package/src/components/badge/features.ts +44 -40
- package/src/components/badge/types.ts +42 -30
- package/src/components/bottom-app-bar/_styles.scss +103 -0
- package/src/components/bottom-app-bar/bottom-app-bar.ts +196 -0
- package/src/components/bottom-app-bar/config.ts +73 -0
- package/src/components/bottom-app-bar/index.ts +11 -0
- package/src/components/bottom-app-bar/types.ts +108 -0
- package/src/components/button/_styles.scss +0 -10
- package/src/components/button/api.ts +5 -0
- package/src/components/button/config.ts +5 -0
- package/src/components/button/types.ts +6 -0
- package/src/components/card/card.ts +13 -25
- package/src/components/card/config.ts +67 -22
- package/src/components/card/features.ts +3 -0
- package/src/components/card/types.ts +28 -0
- package/src/components/checkbox/_styles.scss +0 -2
- package/src/components/datepicker/_styles.scss +358 -0
- package/src/components/datepicker/api.ts +272 -0
- package/src/components/datepicker/config.ts +144 -0
- package/src/components/datepicker/constants.ts +98 -0
- package/src/components/datepicker/datepicker.ts +346 -0
- package/src/components/datepicker/index.ts +9 -0
- package/src/components/datepicker/render.ts +452 -0
- package/src/components/datepicker/types.ts +268 -0
- package/src/components/datepicker/utils.ts +290 -0
- package/src/components/dialog/_styles.scss +174 -128
- package/src/components/dialog/api.ts +48 -13
- package/src/components/dialog/config.ts +9 -5
- package/src/components/dialog/dialog.ts +6 -3
- package/src/components/dialog/features.ts +290 -130
- package/src/components/dialog/types.ts +7 -4
- package/src/components/divider/_styles.scss +57 -0
- package/src/components/divider/config.ts +81 -0
- package/src/components/divider/divider.ts +37 -0
- package/src/components/divider/features.ts +207 -0
- package/src/components/divider/index.ts +5 -0
- package/src/components/divider/types.ts +55 -0
- package/src/components/extended-fab/_styles.scss +267 -0
- package/src/components/extended-fab/api.ts +141 -0
- package/src/components/extended-fab/config.ts +108 -0
- package/src/components/extended-fab/constants.ts +36 -0
- package/src/components/extended-fab/extended-fab.ts +125 -0
- package/src/components/extended-fab/index.ts +4 -0
- package/src/components/extended-fab/types.ts +287 -0
- package/src/components/fab/_styles.scss +225 -0
- package/src/components/fab/api.ts +97 -0
- package/src/components/fab/config.ts +94 -0
- package/src/components/fab/constants.ts +41 -0
- package/src/components/fab/fab.ts +67 -0
- package/src/components/fab/index.ts +4 -0
- package/src/components/fab/types.ts +234 -0
- package/src/components/navigation/_styles.scss +1 -0
- package/src/components/navigation/api.ts +78 -50
- package/src/components/navigation/features/items.ts +280 -0
- package/src/components/navigation/nav-item.ts +72 -23
- package/src/components/navigation/navigation.ts +54 -2
- package/src/components/navigation/types.ts +210 -188
- package/src/components/search/_styles.scss +306 -0
- package/src/components/search/api.ts +203 -0
- package/src/components/search/config.ts +87 -0
- package/src/components/search/constants.ts +21 -0
- package/src/components/search/features/index.ts +4 -0
- package/src/components/search/features/search.ts +718 -0
- package/src/components/search/features/states.ts +165 -0
- package/src/components/search/features/structure.ts +198 -0
- package/src/components/search/index.ts +10 -0
- package/src/components/search/search.ts +52 -0
- package/src/components/search/types.ts +163 -0
- package/src/components/segmented-button/_styles.scss +117 -0
- package/src/components/segmented-button/config.ts +67 -0
- package/src/components/segmented-button/constants.ts +42 -0
- package/src/components/segmented-button/index.ts +4 -0
- package/src/components/segmented-button/segment.ts +155 -0
- package/src/components/segmented-button/segmented-button.ts +250 -0
- package/src/components/segmented-button/types.ts +219 -0
- package/src/components/slider/_styles.scss +83 -24
- package/src/components/slider/accessibility.md +5 -5
- package/src/components/slider/api.ts +41 -120
- package/src/components/slider/config.ts +51 -47
- package/src/components/slider/features/handlers.ts +495 -0
- package/src/components/slider/features/index.ts +1 -2
- package/src/components/slider/features/slider.ts +66 -84
- package/src/components/slider/features/states.ts +195 -0
- package/src/components/slider/features/structure.ts +136 -206
- package/src/components/slider/features/ui.ts +145 -206
- package/src/components/slider/index.ts +2 -11
- package/src/components/slider/slider.ts +9 -12
- package/src/components/slider/types.ts +39 -24
- package/src/components/switch/_styles.scss +0 -2
- package/src/components/tabs/_styles.scss +94 -32
- package/src/components/tabs/features.ts +4 -2
- package/src/components/tabs/indicator.ts +73 -13
- package/src/components/tabs/types.ts +10 -2
- package/src/components/timepicker/README.md +277 -0
- package/src/components/timepicker/_styles.scss +451 -0
- package/src/components/timepicker/api.ts +632 -0
- package/src/components/timepicker/clockdial.ts +482 -0
- package/src/components/timepicker/config.ts +130 -0
- package/src/components/timepicker/constants.ts +138 -0
- package/src/components/timepicker/index.ts +8 -0
- package/src/components/timepicker/render.ts +613 -0
- package/src/components/timepicker/timepicker.ts +117 -0
- package/src/components/timepicker/types.ts +336 -0
- package/src/components/timepicker/utils.ts +241 -0
- package/src/components/top-app-bar/_styles.scss +225 -0
- package/src/components/top-app-bar/config.ts +83 -0
- package/src/components/top-app-bar/index.ts +11 -0
- package/src/components/top-app-bar/top-app-bar.ts +316 -0
- package/src/components/top-app-bar/types.ts +140 -0
- package/src/core/build/_ripple.scss +6 -6
- package/src/core/build/ripple.ts +72 -95
- package/src/core/compose/features/icon.ts +3 -1
- package/src/core/compose/features/ripple.ts +4 -1
- package/src/core/compose/features/textlabel.ts +26 -2
- package/src/core/dom/create.ts +5 -0
- package/src/index.ts +9 -0
- package/src/styles/abstract/_theme.scss +9 -1
- package/src/styles/themes/_autumn.scss +21 -0
- package/src/styles/themes/_base-theme.scss +61 -0
- package/src/styles/themes/_baseline.scss +58 -0
- package/src/styles/themes/_bluekhaki.scss +125 -0
- package/src/styles/themes/_brownbeige.scss +125 -0
- package/src/styles/themes/_browngreen.scss +125 -0
- package/src/styles/themes/_forest.scss +6 -0
- package/src/styles/themes/_greenbeige.scss +125 -0
- package/src/styles/themes/_material.scss +125 -0
- package/src/styles/themes/_ocean.scss +6 -0
- package/src/styles/themes/_sageivory.scss +125 -0
- package/src/styles/themes/_spring.scss +6 -0
- package/src/styles/themes/_summer.scss +5 -0
- package/src/styles/themes/_sunset.scss +5 -0
- package/src/styles/themes/_tealcaramel.scss +125 -0
- package/src/styles/themes/_winter.scss +6 -0
- package/src/components/navigation/features/items.js +0 -192
- package/src/components/slider/features/appearance.ts +0 -94
- package/src/components/slider/features/disabled.ts +0 -68
- package/src/components/slider/features/events.ts +0 -164
- package/src/components/slider/features/interactions.ts +0 -396
- package/src/components/slider/features/keyboard.ts +0 -233
- package/src/core/collection/adapters/mongodb.js +0 -232
package/index.ts
CHANGED
|
@@ -3,23 +3,32 @@ import {
|
|
|
3
3
|
createLayout,
|
|
4
4
|
createElement,
|
|
5
5
|
createBadge,
|
|
6
|
+
createBottomAppBar,
|
|
6
7
|
createButton,
|
|
8
|
+
createDatePicker,
|
|
9
|
+
createFab,
|
|
10
|
+
createExtendedFab,
|
|
11
|
+
createSegmentedButton,
|
|
7
12
|
createCard,
|
|
8
13
|
createCarousel,
|
|
9
14
|
createCheckbox,
|
|
10
15
|
createChip,
|
|
11
16
|
createDialog,
|
|
17
|
+
createDivider,
|
|
12
18
|
createList,
|
|
13
19
|
createMenu,
|
|
14
20
|
createNavigation,
|
|
15
21
|
createProgress,
|
|
16
22
|
createRadios,
|
|
23
|
+
createSearch,
|
|
17
24
|
createSheet,
|
|
18
25
|
createSlider,
|
|
19
26
|
createSnackbar,
|
|
20
27
|
createTabs,
|
|
21
28
|
createTextfield,
|
|
29
|
+
createTimePicker,
|
|
22
30
|
createTooltip,
|
|
31
|
+
createTopAppBar,
|
|
23
32
|
createSwitch
|
|
24
33
|
} from './src/index.js'
|
|
25
34
|
|
|
@@ -27,22 +36,31 @@ export {
|
|
|
27
36
|
createLayout,
|
|
28
37
|
createElement,
|
|
29
38
|
createBadge,
|
|
39
|
+
createBottomAppBar,
|
|
30
40
|
createButton,
|
|
41
|
+
createDatePicker,
|
|
42
|
+
createFab,
|
|
43
|
+
createExtendedFab,
|
|
44
|
+
createSegmentedButton,
|
|
31
45
|
createCard,
|
|
32
46
|
createCarousel,
|
|
33
47
|
createCheckbox,
|
|
34
48
|
createChip,
|
|
35
49
|
createDialog,
|
|
50
|
+
createDivider,
|
|
36
51
|
createList,
|
|
37
52
|
createMenu,
|
|
38
53
|
createNavigation,
|
|
39
54
|
createProgress,
|
|
40
55
|
createRadios,
|
|
56
|
+
createSearch,
|
|
41
57
|
createSheet,
|
|
42
58
|
createSlider,
|
|
43
59
|
createSnackbar,
|
|
44
60
|
createTabs,
|
|
45
61
|
createTextfield,
|
|
62
|
+
createTimePicker,
|
|
46
63
|
createTooltip,
|
|
64
|
+
createTopAppBar,
|
|
47
65
|
createSwitch
|
|
48
66
|
}
|
package/package.json
CHANGED
|
@@ -1,96 +1,130 @@
|
|
|
1
|
-
// src/components/badge/
|
|
1
|
+
// src/components/badge/_badge.scss
|
|
2
2
|
@use '../../styles/abstract/base' as base;
|
|
3
3
|
@use '../../styles/abstract/variables' as v;
|
|
4
4
|
@use '../../styles/abstract/functions' as f;
|
|
5
5
|
@use '../../styles/abstract/mixins' as m;
|
|
6
6
|
@use '../../styles/abstract/theme' as t;
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Badge component styles
|
|
10
|
+
*
|
|
11
|
+
* Badge specifications:
|
|
12
|
+
* - Small badge size: 6dp
|
|
13
|
+
* - Large badge height: 16dp
|
|
14
|
+
* - Small badge corner radius: 3dp
|
|
15
|
+
* - Large badge corner radius: 8dp
|
|
16
|
+
* - Small badge: positioned 6dp from container edge
|
|
17
|
+
* - Large badge: positioned 14dp (height) x 12dp (width) from container edge
|
|
18
|
+
*/
|
|
8
19
|
$component: '#{base.$prefix}-badge';
|
|
20
|
+
$wrapper: '#{base.$prefix}-badge-wrapper';
|
|
9
21
|
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
// Wrapper styles to establish positioning context
|
|
23
|
+
.#{$wrapper} {
|
|
12
24
|
position: relative;
|
|
13
25
|
display: inline-flex;
|
|
26
|
+
flex-shrink: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.#{$component} {
|
|
30
|
+
// Base badge styles
|
|
31
|
+
position: absolute;
|
|
32
|
+
display: flex;
|
|
14
33
|
align-items: center;
|
|
15
34
|
justify-content: center;
|
|
16
|
-
box-sizing: border-box;
|
|
17
|
-
min-width: 20px;
|
|
18
|
-
height: 20px;
|
|
19
|
-
padding: 0 6px;
|
|
20
|
-
border-radius: 10px;
|
|
21
|
-
background-color: t.color('error');
|
|
22
|
-
color: t.color('on-error');
|
|
23
|
-
font-size: 11px;
|
|
24
35
|
font-weight: 500;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
text-
|
|
29
|
-
|
|
30
|
-
// Badge parent wrapper
|
|
31
|
-
&-wrapper {
|
|
32
|
-
position: relative;
|
|
33
|
-
display: inline-flex;
|
|
34
|
-
}
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
transition: all 200ms ease;
|
|
39
|
+
text-overflow: ellipsis;
|
|
35
40
|
|
|
36
|
-
//
|
|
37
|
-
&--
|
|
38
|
-
|
|
39
|
-
top: -8px;
|
|
40
|
-
right: -8px;
|
|
41
|
-
transform: translate(50%, -50%);
|
|
41
|
+
// Hide for visibility: false
|
|
42
|
+
&--invisible {
|
|
43
|
+
display: none;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
//
|
|
45
|
-
&--
|
|
46
|
-
|
|
47
|
-
height:
|
|
46
|
+
// Small badge (dot)
|
|
47
|
+
&--small {
|
|
48
|
+
width: 6px;
|
|
49
|
+
height: 6px;
|
|
50
|
+
min-width: 6px;
|
|
51
|
+
border-radius: 3px; // 3dp corner radius
|
|
52
|
+
font-size: 0;
|
|
48
53
|
padding: 0;
|
|
49
|
-
border-radius: 50%;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
//
|
|
53
|
-
&--
|
|
54
|
-
min-width: 16px;
|
|
56
|
+
// Large badge
|
|
57
|
+
&--large {
|
|
55
58
|
height: 16px;
|
|
56
|
-
|
|
59
|
+
min-width: 16px;
|
|
60
|
+
border-radius: 8px; // 8dp corner radius
|
|
57
61
|
padding: 0 4px;
|
|
62
|
+
font-size: 11px;
|
|
63
|
+
line-height: 16px;
|
|
64
|
+
|
|
65
|
+
// Handle max character count container (16dp x 34dp)
|
|
66
|
+
&.#{$component}--overflow {
|
|
67
|
+
min-width: auto;
|
|
68
|
+
max-width: 34px; // max width is 34dp for overflow badges
|
|
69
|
+
padding: 0 4px;
|
|
70
|
+
}
|
|
58
71
|
}
|
|
59
72
|
|
|
60
|
-
//
|
|
61
|
-
&--
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
// Position specs
|
|
74
|
+
&--positioned {
|
|
75
|
+
// Small badge placement (6dp from container edge)
|
|
76
|
+
&.#{$component}--small {
|
|
77
|
+
&.#{$component}--top-right {
|
|
78
|
+
top: -3px;
|
|
79
|
+
right: -3px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&.#{$component}--top-left {
|
|
83
|
+
top: -3px;
|
|
84
|
+
left: -3px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&.#{$component}--bottom-right {
|
|
88
|
+
bottom: -3px;
|
|
89
|
+
right: -3px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&.#{$component}--bottom-left {
|
|
93
|
+
bottom: -3px;
|
|
94
|
+
left: -3px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Large badge placement (14dp x 12dp from container edge)
|
|
99
|
+
&.#{$component}--large {
|
|
100
|
+
&.#{$component}--top-right {
|
|
101
|
+
top: -8px;
|
|
102
|
+
right: -8px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&.#{$component}--top-left {
|
|
106
|
+
top: -8px;
|
|
107
|
+
left: -8px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&.#{$component}--bottom-right {
|
|
111
|
+
bottom: -8px;
|
|
112
|
+
right: -8px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&.#{$component}--bottom-left {
|
|
116
|
+
bottom: -8px;
|
|
117
|
+
left: -8px;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
85
120
|
}
|
|
86
121
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
122
|
+
// badge color system
|
|
123
|
+
&--error {
|
|
124
|
+
background-color: t.color('error');
|
|
125
|
+
color: t.color('on-error');
|
|
91
126
|
}
|
|
92
127
|
|
|
93
|
-
// Color variants
|
|
94
128
|
&--primary {
|
|
95
129
|
background-color: t.color('primary');
|
|
96
130
|
color: t.color('on-primary');
|
|
@@ -106,11 +140,6 @@ $component: '#{base.$prefix}-badge';
|
|
|
106
140
|
color: t.color('on-tertiary');
|
|
107
141
|
}
|
|
108
142
|
|
|
109
|
-
&--error {
|
|
110
|
-
background-color: t.color('error');
|
|
111
|
-
color: t.color('on-error');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
143
|
&--success {
|
|
115
144
|
background-color: t.color('success');
|
|
116
145
|
color: t.color('on-success');
|
|
@@ -125,50 +154,29 @@ $component: '#{base.$prefix}-badge';
|
|
|
125
154
|
background-color: t.color('info');
|
|
126
155
|
color: t.color('on-info');
|
|
127
156
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
&.#{$component}--secondary {
|
|
139
|
-
color: t.color('secondary');
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
&.#{$component}--tertiary {
|
|
143
|
-
color: t.color('tertiary');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
&.#{$component}--error {
|
|
147
|
-
color: t.color('error');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// RTL support
|
|
160
|
+
[dir="rtl"] {
|
|
161
|
+
.#{$component}--positioned {
|
|
162
|
+
&.#{$component}--top-right {
|
|
163
|
+
right: auto;
|
|
164
|
+
left: -8px;
|
|
148
165
|
}
|
|
149
166
|
|
|
150
|
-
&.#{$component}--
|
|
151
|
-
|
|
167
|
+
&.#{$component}--top-left {
|
|
168
|
+
left: auto;
|
|
169
|
+
right: -8px;
|
|
152
170
|
}
|
|
153
171
|
|
|
154
|
-
&.#{$component}--
|
|
155
|
-
|
|
172
|
+
&.#{$component}--bottom-right {
|
|
173
|
+
right: auto;
|
|
174
|
+
left: -8px;
|
|
156
175
|
}
|
|
157
176
|
|
|
158
|
-
&.#{$component}--
|
|
159
|
-
|
|
177
|
+
&.#{$component}--bottom-left {
|
|
178
|
+
left: auto;
|
|
179
|
+
right: -8px;
|
|
160
180
|
}
|
|
161
181
|
}
|
|
162
|
-
|
|
163
|
-
// Max value handling
|
|
164
|
-
&--max {
|
|
165
|
-
&::after {
|
|
166
|
-
content: '+';
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Invisible
|
|
171
|
-
&--invisible {
|
|
172
|
-
display: none;
|
|
173
|
-
}
|
|
174
182
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// src/components/badge/api.ts
|
|
2
2
|
import { BadgeComponent } from './types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
BADGE_VARIANTS,
|
|
5
|
+
BADGE_COLORS,
|
|
6
|
+
BADGE_POSITIONS
|
|
7
|
+
} from './constants';
|
|
8
|
+
import { formatBadgeLabel } from './config';
|
|
4
9
|
|
|
5
10
|
interface ApiOptions {
|
|
6
11
|
visibility: {
|
|
@@ -19,7 +24,8 @@ interface ComponentWithElements {
|
|
|
19
24
|
wrapper?: HTMLElement;
|
|
20
25
|
config: {
|
|
21
26
|
max?: number;
|
|
22
|
-
|
|
27
|
+
label?: string | number;
|
|
28
|
+
variant?: string;
|
|
23
29
|
};
|
|
24
30
|
getClass: (name: string) => string;
|
|
25
31
|
addClass: (...classes: string[]) => any;
|
|
@@ -39,27 +45,33 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
39
45
|
...component as any,
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
|
-
* Sets the badge
|
|
43
|
-
* @param {string|number}
|
|
48
|
+
* Sets the badge label
|
|
49
|
+
* @param {string|number} label - Label to display in the badge
|
|
44
50
|
* @returns {BadgeComponent} Badge component instance for chaining
|
|
45
51
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
component.config.content = content;
|
|
52
|
+
setLabel(label: string | number) {
|
|
53
|
+
component.config.label = label;
|
|
49
54
|
|
|
50
|
-
//
|
|
51
|
-
if (component.config.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
// Small badges (dot variant) don't have text
|
|
56
|
+
if (component.config.variant === BADGE_VARIANTS.SMALL) {
|
|
57
|
+
component.element.textContent = '';
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Format the label
|
|
62
|
+
const formattedLabel = formatBadgeLabel(label, component.config.max);
|
|
63
|
+
component.element.textContent = formattedLabel;
|
|
64
|
+
|
|
65
|
+
// Add overflow class if label was truncated
|
|
66
|
+
component.element.classList.remove(`${component.getClass('badge')}--overflow`);
|
|
67
|
+
if (typeof label === 'number' &&
|
|
68
|
+
component.config.max !== undefined &&
|
|
69
|
+
label > component.config.max) {
|
|
70
|
+
component.element.classList.add(`${component.getClass('badge')}--overflow`);
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
// Toggle
|
|
62
|
-
if (
|
|
73
|
+
// Toggle visibility based on whether label is empty
|
|
74
|
+
if (formattedLabel === '' || formattedLabel === '0') {
|
|
63
75
|
this.hide();
|
|
64
76
|
} else {
|
|
65
77
|
this.show();
|
|
@@ -69,10 +81,10 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
69
81
|
},
|
|
70
82
|
|
|
71
83
|
/**
|
|
72
|
-
* Gets the badge
|
|
73
|
-
* @returns {string} Current badge
|
|
84
|
+
* Gets the badge label
|
|
85
|
+
* @returns {string} Current badge label
|
|
74
86
|
*/
|
|
75
|
-
|
|
87
|
+
getLabel() {
|
|
76
88
|
return component.element.textContent || '';
|
|
77
89
|
},
|
|
78
90
|
|
|
@@ -114,19 +126,16 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
114
126
|
|
|
115
127
|
/**
|
|
116
128
|
* Sets maximum value (after which badge shows max+)
|
|
129
|
+
*
|
|
117
130
|
* @param {number} max - Maximum value to display
|
|
118
131
|
* @returns {BadgeComponent} Badge component instance for chaining
|
|
119
132
|
*/
|
|
120
133
|
setMax(max: number) {
|
|
121
134
|
component.config.max = max;
|
|
122
135
|
|
|
123
|
-
// Apply max formatting if current
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
component.element.textContent = String(max);
|
|
127
|
-
component.element.classList.add(`${component.getClass('badge')}--max`);
|
|
128
|
-
} else {
|
|
129
|
-
component.element.classList.remove(`${component.getClass('badge')}--max`);
|
|
136
|
+
// Apply max formatting if current label exceeds max
|
|
137
|
+
if (component.config.label !== undefined) {
|
|
138
|
+
this.setLabel(component.config.label);
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
return this;
|
|
@@ -137,7 +146,7 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
137
146
|
* @param {string} color - Color variant to apply
|
|
138
147
|
* @returns {BadgeComponent} Badge component instance for chaining
|
|
139
148
|
*/
|
|
140
|
-
setColor(color: keyof typeof BADGE_COLORS | BADGE_COLORS) {
|
|
149
|
+
setColor(color: keyof typeof BADGE_COLORS | (typeof BADGE_COLORS)[keyof typeof BADGE_COLORS]) {
|
|
141
150
|
// Remove existing color classes
|
|
142
151
|
Object.values(BADGE_COLORS).forEach(colorName => {
|
|
143
152
|
component.element.classList.remove(`${component.getClass('badge')}--${colorName}`);
|
|
@@ -150,44 +159,32 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
150
159
|
|
|
151
160
|
/**
|
|
152
161
|
* Sets badge variant
|
|
153
|
-
* @param {string} variant - Variant to apply
|
|
162
|
+
* @param {string} variant - Variant to apply (small or large)
|
|
154
163
|
* @returns {BadgeComponent} Badge component instance for chaining
|
|
155
164
|
*/
|
|
156
|
-
setVariant(variant: keyof typeof BADGE_VARIANTS | BADGE_VARIANTS) {
|
|
165
|
+
setVariant(variant: keyof typeof BADGE_VARIANTS | (typeof BADGE_VARIANTS)[keyof typeof BADGE_VARIANTS]) {
|
|
157
166
|
// Remove existing variant classes
|
|
158
167
|
Object.values(BADGE_VARIANTS).forEach(variantName => {
|
|
159
168
|
component.element.classList.remove(`${component.getClass('badge')}--${variantName}`);
|
|
160
169
|
});
|
|
161
170
|
|
|
162
|
-
// Add new variant class
|
|
163
|
-
|
|
164
|
-
component.element.classList.add(`${component.getClass('badge')}--${variant}`);
|
|
165
|
-
}
|
|
171
|
+
// Add new variant class
|
|
172
|
+
component.element.classList.add(`${component.getClass('badge')}--${variant}`);
|
|
166
173
|
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
component.element.textContent = '';
|
|
170
|
-
} else if (component.config.content !== undefined) {
|
|
171
|
-
this.setContent(component.config.content);
|
|
172
|
-
}
|
|
174
|
+
// Update component config
|
|
175
|
+
component.config.variant = variant;
|
|
173
176
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
component.element.classList.remove(`${component.getClass('badge')}--${sizeName}`);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Add new size class if not medium (default)
|
|
189
|
-
if (size !== BADGE_SIZES.MEDIUM) {
|
|
190
|
-
component.element.classList.add(`${component.getClass('badge')}--${size}`);
|
|
177
|
+
// Update accessibility attributes
|
|
178
|
+
if (variant === BADGE_VARIANTS.SMALL) {
|
|
179
|
+
component.element.textContent = '';
|
|
180
|
+
component.element.setAttribute('aria-hidden', 'true');
|
|
181
|
+
} else {
|
|
182
|
+
component.element.setAttribute('role', 'status');
|
|
183
|
+
|
|
184
|
+
// Restore label for large badges
|
|
185
|
+
if (component.config.label !== undefined) {
|
|
186
|
+
this.setLabel(component.config.label);
|
|
187
|
+
}
|
|
191
188
|
}
|
|
192
189
|
|
|
193
190
|
return this;
|
|
@@ -198,7 +195,7 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
198
195
|
* @param {string} position - Position variant to apply
|
|
199
196
|
* @returns {BadgeComponent} Badge component instance for chaining
|
|
200
197
|
*/
|
|
201
|
-
setPosition(position: keyof typeof BADGE_POSITIONS | BADGE_POSITIONS) {
|
|
198
|
+
setPosition(position: keyof typeof BADGE_POSITIONS | (typeof BADGE_POSITIONS)[keyof typeof BADGE_POSITIONS]) {
|
|
202
199
|
// Remove existing position classes
|
|
203
200
|
Object.values(BADGE_POSITIONS).forEach(posName => {
|
|
204
201
|
component.element.classList.remove(`${component.getClass('badge')}--${posName}`);
|
|
@@ -224,6 +221,7 @@ export const withAPI = ({ visibility, lifecycle }: ApiOptions) =>
|
|
|
224
221
|
// Create a new wrapper to hold the target and badge
|
|
225
222
|
const wrapper = document.createElement('div');
|
|
226
223
|
wrapper.classList.add(component.getClass('badge-wrapper'));
|
|
224
|
+
wrapper.style.position = 'relative';
|
|
227
225
|
|
|
228
226
|
// Replace the target with the wrapper
|
|
229
227
|
const parent = target.parentNode;
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
withVisibility,
|
|
10
10
|
withVariant,
|
|
11
11
|
withColor,
|
|
12
|
-
withSize,
|
|
13
12
|
withPosition,
|
|
14
13
|
withMax,
|
|
15
14
|
withAttachment
|
|
@@ -22,18 +21,33 @@ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
|
22
21
|
* Creates a new Badge component
|
|
23
22
|
* @param {BadgeConfig} config - Badge configuration object
|
|
24
23
|
* @returns {BadgeComponent} Badge component instance
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // Create a small dot badge
|
|
27
|
+
* const notificationBadge = createBadge({
|
|
28
|
+
* variant: BADGE_VARIANTS.SMALL,
|
|
29
|
+
* target: document.querySelector('.icon-button')
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Create a large badge with a count
|
|
34
|
+
* const countBadge = createBadge({
|
|
35
|
+
* variant: BADGE_VARIANTS.LARGE,
|
|
36
|
+
* label: 5,
|
|
37
|
+
* target: document.querySelector('.notification-icon')
|
|
38
|
+
* });
|
|
25
39
|
*/
|
|
26
40
|
const createBadge = (config: BadgeConfig = {}): BadgeComponent => {
|
|
27
41
|
const baseConfig = createBaseConfig(config);
|
|
28
42
|
|
|
29
43
|
try {
|
|
44
|
+
// Compose the badge component from multiple feature enhancers
|
|
30
45
|
const badge = pipe(
|
|
31
46
|
createBase,
|
|
32
47
|
withEvents(),
|
|
33
48
|
withElement(getElementConfig(baseConfig)),
|
|
34
49
|
withVariant(baseConfig),
|
|
35
50
|
withColor(baseConfig),
|
|
36
|
-
withSize(baseConfig),
|
|
37
51
|
withPosition(baseConfig),
|
|
38
52
|
withMax(baseConfig),
|
|
39
53
|
withVisibility(),
|