bootstrap-italia 2.9.1 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,6 @@ import EventHandler from 'bootstrap/js/src/dom/event-handler'
3
3
  import SelectorEngine from 'bootstrap/js/src/dom/selector-engine'
4
4
  import Manipulator from 'bootstrap/js/src/dom/manipulator'
5
5
 
6
- //import Input from './input'
7
6
  import InputLabel from './input-label'
8
7
 
9
8
  const NAME = 'inputpassword'
@@ -12,38 +11,45 @@ const EVENT_KEY = `.${DATA_KEY}`
12
11
  const DATA_API_KEY = '.data-api'
13
12
 
14
13
  const Default = {
15
- shortPass: 'Password molto debole',
16
- badPass: 'Password debole',
17
- goodPass: 'Password sicura',
18
- strongPass: 'Password molto sicura',
19
- enterPass: 'Inserisci almeno 8 caratteri e una lettera maiuscola',
20
- alertCaps: 'CAPS LOCK inserito',
21
- showText: true,
22
- minimumLength: 4,
14
+ shortPass: 'Password troppo breve',
15
+ badPass: 'Password debole.',
16
+ goodPass: 'Password abbastanza sicura.',
17
+ strongPass: 'Password sicura.',
18
+ minimumLength: 8,
19
+ suggestionsLabel: 'Suggerimenti per una buona password:',
20
+ suggestionFollowed: 'suggerimenti seguito',
21
+ suggestionFollowedPlural: 'suggerimenti seguiti',
22
+ suggestionOf: 'di',
23
+ suggestionMetLabel: 'Soddisfatto: ',
24
+ suggestionMetIconPath: `
25
+ M9.6 16.9 4 11.4l.8-.7 4.8 4.8 8.5-8.4.7.7-9.2 9.1z
26
+ `,
27
+ suggestionLength: 'Almeno {minLength} caratteri.',
28
+ suggestionUppercase: 'Una o più maiuscole.',
29
+ suggestionLowercase: 'Una o più minuscole.',
30
+ suggestionNumber: 'Uno o più numeri.',
31
+ suggestionSpecial: 'Uno o più caratteri speciali.',
23
32
  }
24
33
 
25
34
  const EVENT_CLICK = `click${EVENT_KEY}`
26
35
  const EVENT_KEYUP = `keyup${EVENT_KEY}`
27
- const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
28
- const EVENT_KEYPRESS = `keypress${EVENT_KEY}`
29
36
  const EVENT_SCORE = `score${EVENT_KEY}`
30
37
  const EVENT_TEXT = `text${EVENT_KEY}`
38
+ const EVENT_SUGGS = `suggs${EVENT_KEY}`
31
39
 
32
40
  const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
33
41
  const EVENT_MOUSEDOWN_DATA_API = `mousedown${EVENT_KEY}${DATA_API_KEY}`
34
42
  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`
35
43
 
36
44
  const CLASS_NAME_PASSWORD = 'input-password'
37
- //const CLASS_NAME_METER = 'input-password-strength-meter'
38
- const CLASS_NAME_SHOW = 'show'
39
45
 
40
46
  const SELECTOR_PASSWORD = 'input[data-bs-input][type="password"]'
41
47
  const SELECTOR_BTN_SHOW_PWD = '.password-icon'
42
48
  const SELECTOR_METER = '.password-strength-meter'
43
49
  const SELECTOR_METER_GRAYBAR = '.password-meter'
44
50
  const SELECTOR_METER_COLBAR = '.progress-bar'
45
- const SELECTOR_CAPS = '.password-caps'
46
- const SELECTOR_TEXT = '.form-text'
51
+ const SELECTOR_METER_TEXT = '.strength-meter-info'
52
+ const SELECTOR_METER_SUGGS = '.strenght-meter-suggestions'
47
53
 
48
54
  class InputPassword extends BaseComponent {
49
55
  constructor(element, config) {
@@ -52,31 +58,54 @@ class InputPassword extends BaseComponent {
52
58
  this._config = this._getConfig(config)
53
59
  this._isCustom = this._element.classList.contains(CLASS_NAME_PASSWORD)
54
60
  this._meter = this._element.parentNode.querySelector(SELECTOR_METER)
55
- this._isShiftPressed = false
56
- this._isCapsOn = false
57
61
 
58
62
  this._grayBarElement = null
59
63
  this._colorBarElement = null
60
64
  this._textElement = null
61
- this._capsElement = null
65
+ this._suggsElement = null
62
66
  this._showPwdElement = null
63
67
 
64
68
  this._text = {}
65
69
 
66
70
  this._label = new InputLabel(element)
67
71
 
72
+ this._suggestions = [
73
+ {
74
+ key: 'length',
75
+ text: (config) => config.suggestionLength.replace('{minLength}', config.minimumLength.toString()),
76
+ test: (password, config) => password.length >= config.minimumLength,
77
+ },
78
+ {
79
+ key: 'uppercase',
80
+ text: (config) => config.suggestionUppercase,
81
+ test: (password) => /[A-Z]/.test(password),
82
+ },
83
+ {
84
+ key: 'lowercase',
85
+ text: (config) => config.suggestionLowercase,
86
+ test: (password) => /[a-z]/.test(password),
87
+ },
88
+ {
89
+ key: 'number',
90
+ text: (config) => config.suggestionNumber,
91
+ test: (password) => /[0-9]/.test(password),
92
+ },
93
+ {
94
+ key: 'special',
95
+ text: (config) => config.suggestionSpecial,
96
+ test: (password) => /[^A-Za-z0-9]/.test(password),
97
+ },
98
+ ]
99
+
68
100
  this._init()
69
101
  this._bindEvents()
70
102
  }
71
103
 
72
104
  // Getters
73
-
74
105
  static get NAME() {
75
106
  return NAME
76
107
  }
77
108
 
78
- // Public
79
-
80
109
  // Private
81
110
  _getConfig(config) {
82
111
  config = {
@@ -88,118 +117,174 @@ class InputPassword extends BaseComponent {
88
117
  }
89
118
 
90
119
  _init() {
91
- if (this._meter) {
92
- this._grayBarElement = this._meter.querySelector(SELECTOR_METER_GRAYBAR)
93
- this._colorBarElement = this._meter.querySelector(SELECTOR_METER_COLBAR)
94
- this._textElement = this._meter.querySelector(SELECTOR_TEXT)
95
-
96
- if (this._textElement) {
97
- this._config = Object.assign({}, this._config, { ...Manipulator.getDataAttributes(this._textElement) }, { enterPass: this._textElement.innerText })
98
- }
99
- }
100
120
  if (this._isCustom) {
101
- this._capsElement = this._element.parentNode.querySelector(SELECTOR_CAPS)
121
+ this._handleAutofill()
122
+ this._showPwdElement = SelectorEngine.findOne(SELECTOR_BTN_SHOW_PWD, this._element.parentNode)
123
+ if (this._meter) {
124
+ this._grayBarElement = this._meter.querySelector(SELECTOR_METER_GRAYBAR)
125
+ this._colorBarElement = this._meter.querySelector(SELECTOR_METER_COLBAR)
126
+ this._textElement = this._meter.querySelector(SELECTOR_METER_TEXT)
127
+ this._suggsElement = this._meter.querySelector(SELECTOR_METER_SUGGS)
128
+ if (this._textElement) {
129
+ this._config = Object.assign({}, this._config, { ...Manipulator.getDataAttributes(this._textElement) })
130
+ }
131
+ if (this._suggsElement) {
132
+ this._createsuggestionsList()
133
+ }
134
+ }
102
135
  }
103
-
104
- this._showPwdElement = SelectorEngine.findOne(SELECTOR_BTN_SHOW_PWD, this._element.parentNode)
105
136
  }
106
137
 
107
138
  _bindEvents() {
108
- if (this._meter) {
109
- EventHandler.on(this._element, EVENT_KEYUP, () => this._checkPassword())
110
- }
111
-
112
139
  if (this._isCustom) {
113
- EventHandler.on(this._element, EVENT_KEYDOWN, (evt) => {
114
- if (evt.key === 'Shift') {
115
- this._isShiftPressed = true
116
- }
117
- })
118
- EventHandler.on(this._element, EVENT_KEYUP, (evt) => {
119
- if (evt.key === 'Shift') {
120
- this._isShiftPressed = false
121
- }
122
- if (evt.key === 'CapsLock') {
123
- this._isCapsOn = !this._isCapsOn
124
- if (this._isCapsOn) {
125
- this._showCapsMsg()
126
- } else {
127
- this._hideCapsMsg()
128
- }
129
- }
130
- })
131
- EventHandler.on(this._element, EVENT_KEYPRESS, (evt) => {
132
- const matches = evt.key.match(/[A-Z]$/) || []
133
- if (matches.length > 0 && !this._isShiftPressed) {
134
- this._isCapsOn = true
135
- this._showCapsMsg()
136
- } else if (this._isCapsOn) {
137
- this._isCapsOn = false
138
- this._hideCapsMsg()
139
- }
140
- })
141
- }
142
-
143
- if (this._showPwdElement) {
144
- EventHandler.on(this._showPwdElement, EVENT_CLICK, () => this._toggleShowPassword())
140
+ if (this._showPwdElement) {
141
+ EventHandler.on(this._showPwdElement, EVENT_CLICK, () => this._toggleShowPassword())
142
+ }
143
+ if (this._meter) {
144
+ EventHandler.on(this._element, EVENT_KEYUP, () => this._checkPassword())
145
+ EventHandler.on(this._element, 'input', () => this._checkPassword())
146
+ }
145
147
  }
146
148
  }
147
149
 
148
- _showCapsMsg() {
149
- if (this._capsElement) {
150
- this._capsElement.classList.add(CLASS_NAME_SHOW)
151
- }
152
- }
153
- _hideCapsMsg() {
154
- if (this._capsElement) {
155
- this._capsElement.classList.remove(CLASS_NAME_SHOW)
150
+ _handleAutofill() {
151
+ const checkAndActivate = () => {
152
+ if (this._element.value !== '') {
153
+ this._label._labelOut()
154
+ this._checkPassword()
155
+ }
156
156
  }
157
+ checkAndActivate()
158
+ setTimeout(checkAndActivate, 100)
159
+ EventHandler.on(this._element, 'animationstart', (event) => {
160
+ if (event.animationName === 'onAutoFillStart') {
161
+ checkAndActivate()
162
+ }
163
+ })
157
164
  }
158
165
 
159
166
  _toggleShowPassword() {
160
167
  const toShow = this._element.getAttribute('type') === 'password'
161
168
  SelectorEngine.find('[class^="password-icon"]', this._showPwdElement).forEach((icon) => icon.classList.toggle('d-none'))
162
- if (toShow) {
163
- this._element.setAttribute('type', 'text')
164
- } else {
165
- this._element.setAttribute('type', 'password')
166
- }
169
+ this._element.setAttribute('type', toShow ? 'text' : 'password')
170
+ this._showPwdElement.setAttribute('aria-checked', toShow.toString())
167
171
  }
168
172
 
169
173
  _checkPassword() {
170
- const score = this._calculateScore(this._element.value)
171
- const perc = score < 0 ? 0 : score
172
-
173
- this._colorBarElement.classList.forEach((className) => {
174
- if (className.match(/(^|\s)bg-\S+/g)) {
175
- this._colorBarElement.classList.remove(className)
176
- }
177
- })
178
- this._colorBarElement.classList.add('bg-' + this._scoreColor(score))
179
- this._colorBarElement.style.width = perc + '%'
180
- this._colorBarElement.setAttribute('aria-valuenow', perc)
174
+ const password = this._element.value
175
+ const score = this._calculateScore(password)
176
+ this._updateMeter(score)
177
+ this._updateText(score, password)
178
+ this._updateSuggestions(password)
179
+ }
181
180
 
181
+ _updateMeter(score) {
182
+ const perc = score < 0 ? 0 : score
183
+ if (this._colorBarElement) {
184
+ this._colorBarElement.classList.forEach((className) => {
185
+ if (className.match(/(^|\s)bg-\S+/g)) {
186
+ this._colorBarElement.classList.remove(className)
187
+ }
188
+ })
189
+ this._colorBarElement.classList.add(`bg-${this._scoreColor(score)}`)
190
+ this._colorBarElement.style.width = `${perc}%`
191
+ this._colorBarElement.setAttribute('aria-valuenow', perc)
192
+ }
182
193
  EventHandler.trigger(this._element, EVENT_SCORE)
194
+ }
183
195
 
196
+ _updateText(score, password) {
184
197
  if (this._textElement) {
185
198
  let text = this._scoreText(score)
186
- if (this._element.value.length === 0 && score <= 0) {
187
- text = this._config.enterPass
199
+ if (this._suggsElement) {
200
+ const { completedCount, totalCount } = this._getCompletedSuggestions(password)
201
+ const suggestionText = completedCount === 1 ? this._config.suggestionFollowed : this._config.suggestionFollowedPlural
202
+ text += ` ${completedCount} ${this._config.suggestionOf} ${totalCount} ${suggestionText}.`
188
203
  }
189
-
190
- if (this._textElement.innerHTML.search(text) === -1) {
191
- this._textElement.innerHTML = text
204
+ if (this._textElement.textContent !== text) {
205
+ this._textElement.textContent = text
192
206
  this._textElement.classList.forEach((className) => {
193
207
  if (className.match(/(^|\s)text-\S+/g)) {
194
208
  this._textElement.classList.remove(className)
195
209
  }
196
210
  })
197
- this._textElement.classList.add('text-' + this._scoreColor(score))
211
+ this._textElement.classList.add(`text-${this._scoreColor(score)}`)
198
212
  EventHandler.trigger(this._element, EVENT_TEXT)
199
213
  }
200
214
  }
201
215
  }
202
216
 
217
+ _updateSuggestions(password) {
218
+ if (this._suggsElement) {
219
+ this._updateSuggestionsList(password)
220
+ EventHandler.trigger(this._element, EVENT_SUGGS)
221
+ }
222
+ }
223
+
224
+ _getCompletedSuggestions(password) {
225
+ let completedCount = 0
226
+ const totalCount = this._suggestions.length
227
+ this._suggestions.forEach((sugg) => {
228
+ if (sugg.test(password, this._config)) completedCount++
229
+ })
230
+ return { completedCount, totalCount }
231
+ }
232
+
233
+ _createsuggestionsList() {
234
+ if (this._suggsElement.querySelector('.password-suggestions')) {
235
+ return
236
+ }
237
+ const suggLabel = document.createElement('label')
238
+ suggLabel.className = 'visually-hidden'
239
+ suggLabel.htmlFor = 'suggestions'
240
+ suggLabel.textContent = Default.suggestionsLabel
241
+ const suggContainer = document.createElement('div')
242
+ suggContainer.id = 'suggestions'
243
+ suggContainer.className = 'password-suggestions'
244
+
245
+ this._suggestions.forEach((sugg) => {
246
+ const suggElement = document.createElement('div')
247
+ suggElement.className = 'suggestion'
248
+ suggElement.dataset.suggestion = sugg.key
249
+ const checkIcon = this._createIconCheck()
250
+ const textSpan = document.createElement('span')
251
+ textSpan.textContent = sugg.text(this._config)
252
+ suggElement.appendChild(checkIcon)
253
+ suggElement.appendChild(textSpan)
254
+ suggContainer.appendChild(suggElement)
255
+ })
256
+
257
+ this._suggsElement.appendChild(suggLabel)
258
+ this._suggsElement.appendChild(suggContainer)
259
+ }
260
+
261
+ _createIconCheck() {
262
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
263
+ svg.setAttribute('class', `icon icon-xs me-1 d-none`)
264
+ svg.setAttribute('aria-label', this._config.suggestionMetLabel)
265
+ svg.setAttribute('viewBox', '0 0 24 24')
266
+ svg.style.width = '1em'
267
+ svg.style.height = '1em'
268
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
269
+ path.setAttribute('d', this._config.suggestionMetIconPath.trim())
270
+ svg.appendChild(path)
271
+ return svg
272
+ }
273
+
274
+ _updateSuggestionsList(password) {
275
+ if (!this._suggsElement) return
276
+ this._suggestions.forEach((sugg) => {
277
+ const suggElement = this._suggsElement.querySelector(`[data-suggestion="${sugg.key}"]`)
278
+ if (suggElement) {
279
+ const isMet = sugg.test(password, this._config)
280
+ const checkIcon = suggElement.querySelector('.icon')
281
+ if (checkIcon) {
282
+ checkIcon.classList.toggle('d-none', !isMet)
283
+ }
284
+ }
285
+ })
286
+ }
287
+
203
288
  /**
204
289
  * Returns strings based on the score given.
205
290
  *
@@ -211,10 +296,14 @@ class InputPassword extends BaseComponent {
211
296
  return this._config.shortPass
212
297
  }
213
298
 
299
+ if (score === -2) {
300
+ return ''
301
+ }
302
+
214
303
  score = score < 0 ? 0 : score
215
304
 
216
305
  if (score < 26) {
217
- return this._config.shortPass
306
+ return this._config.badPass
218
307
  }
219
308
  if (score < 51) {
220
309
  return this._config.badPass
@@ -227,16 +316,7 @@ class InputPassword extends BaseComponent {
227
316
  }
228
317
 
229
318
  _scoreColor(score) {
230
- if (score === -1) {
231
- return 'danger'
232
- }
233
- if (score === -2) {
234
- return 'muted'
235
- }
236
-
237
- score = score < 0 ? 0 : score
238
-
239
- if (score < 26) {
319
+ if (score === -1 || score === -2 || score < 26) {
240
320
  return 'danger'
241
321
  }
242
322
  if (score < 51) {
@@ -245,7 +325,6 @@ class InputPassword extends BaseComponent {
245
325
  if (score < 76) {
246
326
  return 'success'
247
327
  }
248
-
249
328
  return 'success'
250
329
  }
251
330
 
@@ -281,7 +360,7 @@ class InputPassword extends BaseComponent {
281
360
  score += 5
282
361
  }
283
362
 
284
- // password has at least 2 sybols
363
+ // password has at least 2 symbols
285
364
  var symbols = '.*[!,@,#,$,%,^,&,*,?,_,~]'
286
365
  symbols = new RegExp('(' + symbols + symbols + ')')
287
366
  if (password.match(symbols)) {
@@ -360,11 +439,6 @@ class InputPassword extends BaseComponent {
360
439
  * ------------------------------------------------------------------------
361
440
  */
362
441
 
363
- /*const inputs = SelectorEngine.find(SELECTOR_PASSWORD)
364
- inputs.forEach((input) => {
365
- InputPassword.getOrCreateInstance(input)
366
- })*/
367
-
368
442
  const createInput = (element) => {
369
443
  if (element && element.matches(SELECTOR_PASSWORD)) {
370
444
  return InputPassword.getOrCreateInstance(element)
@@ -372,6 +446,19 @@ const createInput = (element) => {
372
446
  return null
373
447
  }
374
448
 
449
+ const initInputPassword = () => {
450
+ const element = SelectorEngine.findOne(SELECTOR_PASSWORD)
451
+ if (element) {
452
+ InputPassword.getOrCreateInstance(element)
453
+ }
454
+ }
455
+
456
+ if (document.readyState !== 'loading') {
457
+ initInputPassword()
458
+ } else {
459
+ document.addEventListener('DOMContentLoaded', initInputPassword)
460
+ }
461
+
375
462
  EventHandler.on(document, EVENT_MOUSEDOWN_DATA_API, SELECTOR_PASSWORD + ', label', function () {
376
463
  const target = InputLabel.getInputFromLabel(this) || this
377
464
  createInput(target)
package/src/js/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // bootstrap italia version variable
2
2
  // useful to check for the current version
3
3
  // eslint-disable-next-line no-unused-vars
4
- const BOOTSTRAP_ITALIA_VERSION = '2.9.1'
4
+ const BOOTSTRAP_ITALIA_VERSION = '2.10.0'
5
5
  export default BOOTSTRAP_ITALIA_VERSION
@@ -12,7 +12,7 @@
12
12
  }
13
13
  .password-meter {
14
14
  height: 4px;
15
- left: 10px;
15
+ left: 7px;
16
16
  bottom: -6px;
17
17
  width: 100%;
18
18
  max-width: 180px;
@@ -103,19 +103,22 @@ input[type='url'],
103
103
  textarea {
104
104
  border: none;
105
105
  border-bottom: 1px solid $input-border;
106
- border-radius: 0;
107
106
  padding: $input-spacing-y $input-spacing-x;
108
107
  outline: 0;
109
- width: 100%;
110
108
  box-shadow: none;
111
109
  transition: none;
112
110
  -webkit-appearance: none;
113
- -webkit-border-radius: 0;
114
111
  &::placeholder {
115
112
  color: $input-color-placeholder;
116
113
  }
117
114
  }
118
115
 
116
+ input[type='date'],
117
+ input[type='datetime-local'],
118
+ input[type='time'] {
119
+ display: flex;
120
+ }
121
+
119
122
  textarea {
120
123
  border: 1px solid $input-border;
121
124
  height: auto;
@@ -142,12 +145,12 @@ textarea {
142
145
  }
143
146
  .was-validated &:valid,
144
147
  &.is-valid {
145
- background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2300cc85' viewBox='0 0 192 512'%3E%3Cpath d='M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z'/%3E%3C/svg%3E");
148
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2300cc85' viewBox='0 0 192 512'%3E%3Cpath d='M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z'/%3E%3C/svg%3E");
146
149
  }
147
150
 
148
151
  .was-validated &:invalid,
149
152
  &.is-invalid {
150
- background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f73e5a' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E");
153
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f73e5a' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E");
151
154
  }
152
155
 
153
156
  &.warning {
@@ -33,6 +33,7 @@ button:has(~ .is-invalid),
33
33
  padding-right: calc(1.5em + 0.75rem) !important;
34
34
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2300cc85' viewBox='0 0 192 512'%3E%3Cpath d='M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z'/%3E%3C/svg%3E");
35
35
  }
36
+
36
37
  .input-group-text:has(~ .just-validate-success-field),
37
38
  .just-validate-success-field ~ .input-group-text,
38
39
  button:has(~ .just-validate-success-field),
@@ -70,13 +71,7 @@ textarea {
70
71
  border-bottom-width: 1px;
71
72
  }
72
73
  }
73
- input[type='date'] {
74
- &.is-invalid {
75
- border-bottom: 1px solid #d9364f;
76
- padding-right: calc(1.5em + 0.75rem) !important;
77
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f73e5a' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E");
78
- }
79
- }
74
+
80
75
  input[type='checkbox'],
81
76
  input[type='radio'] {
82
77
  &.just-validate-success-field {
@@ -85,6 +80,7 @@ input[type='radio'] {
85
80
  }
86
81
  }
87
82
  }
83
+
88
84
  select {
89
85
  &.is-invalid {
90
86
  border-bottom: 1px solid #d9364f;
@@ -1,3 +1,3 @@
1
1
  :root {
2
- --bootstrap-italia-version: '2.9.1';
2
+ --bootstrap-italia-version: '2.10.0';
3
3
  }
@@ -1,9 +1,3 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
- <svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
- viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
5
- <g>
6
- <path d="M17.7,5.3C16,2.2,12,1.1,8.9,2.8s-4.3,5.7-2.5,8.8L12,22l5.7-10.4c0.5-1,0.8-2,0.8-3.1S18.2,6.3,17.7,5.3z M16.8,11.1
7
- L12,19.9l-4.8-8.8c-0.5-0.8-0.7-1.7-0.7-2.7C6.5,5.4,9,3,12,3s5.5,2.5,5.5,5.5C17.5,9.4,17.3,10.3,16.8,11.1z"/>
8
- </g>
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12 22L6.31001 11.63C4.99676 9.25198 5.30085 6.30809 7.07246 4.24872C8.84407 2.18935 11.7095 1.4489 14.257 2.39217C16.8045 3.33544 18.4968 5.76346 18.5 8.48C18.4997 9.57513 18.2209 10.6522 17.69 11.61L12 22ZM12 3C10.0517 2.99538 8.24688 4.02372 7.25751 5.70214C6.26815 7.38057 6.24246 9.45762 7.19 11.16L12 19.94L16.82 11.13C17.2627 10.3166 17.4963 9.40602 17.5 8.48C17.4835 5.45253 15.0275 3.00545 12 3ZM8.5 9V8H15.5V9H8.5Z" />
9
3
  </svg>