@newlogic-digital/ui 3.3.0 → 3.5.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.
Files changed (151) hide show
  1. package/README.md +10 -14
  2. package/package.json +23 -23
  3. package/src/data/main.json +2 -8
  4. package/src/emails/{templates/Content.twig → templates.test/Content.latte} +10 -2
  5. package/src/emails/{templates/Header.twig → templates.test/Header.latte} +1 -1
  6. package/src/emails/{templates/Layout.twig → templates.test/Layout.latte} +2 -2
  7. package/src/icons.svg +34 -28
  8. package/src/scripts/Components/CookieConsent.js +22 -28
  9. package/src/scripts/Layout/Header.js +25 -11
  10. package/src/scripts/Layout/Main.js +25 -55
  11. package/src/scripts/Libraries/+.js +4 -5
  12. package/src/scripts/Libraries/Dialog.js +37 -72
  13. package/src/scripts/Libraries/Drawer.js +22 -21
  14. package/src/scripts/Libraries/Form.js +8 -13
  15. package/src/scripts/Libraries/Naja.js +33 -0
  16. package/src/scripts/Libraries/ReCaptcha.js +14 -4
  17. package/src/scripts/Libraries/Ripple.js +6 -22
  18. package/src/scripts/Libraries/Script.js +1 -2
  19. package/src/scripts/Libraries/Slider.js +160 -0
  20. package/src/scripts/Libraries/Stimulus.js +0 -1
  21. package/src/scripts/Libraries/Swup.js +54 -38
  22. package/src/scripts/Libraries/Tippy.js +17 -20
  23. package/src/scripts/Ui/+.js +3 -3
  24. package/src/scripts/Ui/Check.js +8 -0
  25. package/src/scripts/Ui/Control.js +186 -0
  26. package/src/scripts/Ui/ControlSelect.js +24 -0
  27. package/src/scripts/Ui/Text.js +8 -10
  28. package/src/scripts/Utils/Functions/+.js +3 -3
  29. package/src/scripts/Utils/Functions/importScript.js +1 -1
  30. package/src/scripts/Utils/Functions/importStyle.js +1 -1
  31. package/src/scripts/Utils/Functions/inputStep.js +9 -0
  32. package/src/scripts/Utils/Functions/inputValidity.js +57 -0
  33. package/src/scripts/Utils/Functions/loadStimulus.js +12 -9
  34. package/src/scripts/Utils/Functions/replaceScript.js +4 -0
  35. package/src/scripts/Utils/Functions/replaceTag.js +1 -5
  36. package/src/scripts/Utils/cdn.js +2 -3
  37. package/src/scripts/Utils/global.js +1 -1
  38. package/src/styles/Components/+.css +1 -1
  39. package/src/styles/Components/CookieConsent.css +22 -25
  40. package/src/styles/Components/Dialog/Default.css +10 -62
  41. package/src/styles/Components/Dropdown/Default.css +6 -3
  42. package/src/styles/Components/Field.css +1 -0
  43. package/src/styles/Layout/Header.css +13 -17
  44. package/src/styles/Layout/Main.css +8 -91
  45. package/src/styles/Layout/Nav.css +31 -27
  46. package/src/styles/Libraries/+.css +1 -2
  47. package/src/styles/Libraries/Datepicker.css +38 -229
  48. package/src/styles/Libraries/Dialog.css +1 -19
  49. package/src/styles/Libraries/Drawer.css +17 -29
  50. package/src/styles/Libraries/Hint.css +86 -101
  51. package/src/styles/Libraries/Pickr.css +13 -0
  52. package/src/styles/Libraries/Ripple.css +1 -29
  53. package/src/styles/Libraries/Tippy.css +25 -39
  54. package/src/styles/Ui/+.css +6 -5
  55. package/src/styles/Ui/Badge.css +7 -82
  56. package/src/styles/Ui/Btn.css +13 -226
  57. package/src/styles/Ui/Check.css +1 -0
  58. package/src/styles/Ui/Control.css +47 -0
  59. package/src/styles/Ui/ControlSelect.css +66 -0
  60. package/src/styles/Ui/Dot.css +22 -0
  61. package/src/styles/Ui/Group.css +1 -0
  62. package/src/styles/Ui/Heading.css +3 -22
  63. package/src/styles/Ui/Image.css +1 -17
  64. package/src/styles/Ui/Info.css +1 -0
  65. package/src/styles/Ui/Label.css +1 -14
  66. package/src/styles/Ui/Link.css +2 -41
  67. package/src/styles/Ui/Notice.css +1 -47
  68. package/src/styles/Ui/Progress.css +1 -56
  69. package/src/styles/Ui/Switch.css +1 -70
  70. package/src/styles/Ui/Text.css +4 -245
  71. package/src/styles/Ui/Title.css +5 -13
  72. package/src/styles/Utils/+.css +3 -4
  73. package/src/styles/Utils/breakpoints.css +1 -0
  74. package/src/styles/Utils/config.css +5 -0
  75. package/src/styles/Utils/default.css +8 -122
  76. package/src/styles/Utils/icons.css +3 -7
  77. package/src/styles/Utils/keyframes.css +1 -182
  78. package/src/styles/Utils/{tailwind/base.css → tailwind.css} +31 -21
  79. package/src/styles/Utils/theme/+.css +1 -1
  80. package/src/styles/Utils/theme/main.css +14 -23
  81. package/src/styles/main.css +19 -15
  82. package/src/styles/tinymce.css +34 -0
  83. package/src/templates/Components/CookieConsent.latte +28 -0
  84. package/src/templates/Components/Dialogs/Basic.latte +22 -0
  85. package/src/templates/Layout/{Header.twig → Header.latte} +15 -17
  86. package/src/templates/Layout/Main.latte +62 -0
  87. package/src/templates/Sections/Gdpr.latte +127 -0
  88. package/src/templates/Sections/Site.latte +141 -0
  89. package/src/templates/Sections/Ui/Docs/@intro.html +13 -62
  90. package/src/templates/Sections/Ui/Docs/@nav.html +41 -92
  91. package/src/templates/Sections/Ui/Docs/@styles.html +2 -6
  92. package/src/templates/Sections/Ui/Docs/Default.latte +1059 -0
  93. package/src/templates/Sections/Ui/Icons.html +11 -9
  94. package/src/templates/Sections/Ui/Intro.html +66 -37
  95. package/src/templates/Sections/Ui.latte +8 -0
  96. package/src/templates/Ui/+.latte +5 -0
  97. package/src/templates/Ui/Check.latte +7 -0
  98. package/src/templates/Ui/Control.latte +9 -0
  99. package/src/templates/Ui/ControlDate.latte +14 -0
  100. package/src/templates/Ui/ControlSelect.latte +9 -0
  101. package/src/templates/Ui/ControlTime.latte +14 -0
  102. package/src/templates/Utils/sections.latte +3 -0
  103. package/src/views/dialog/basic.json.latte +5 -0
  104. package/src/views/dropdown/{tippy.json.twig → tippy.json.latte} +7 -4
  105. package/src/views/email/email.latte +6 -0
  106. package/src/views/email/email.test.latte +6 -0
  107. package/src/views/gdpr.json +1 -1
  108. package/src/views/index.json +1 -1
  109. package/src/views/site.json +11 -0
  110. package/src/views/ui-icons.json +1 -1
  111. package/src/views/ui.json +1 -1
  112. package/vite.config.js +16 -6
  113. package/.eslintrc +0 -13
  114. package/.stylelintrc +0 -18
  115. package/public/sw.js +0 -30
  116. package/src/emails/email.prod.html +0 -6
  117. package/src/emails/email.twig.html +0 -6
  118. package/src/scripts/Libraries/Anchor.js +0 -35
  119. package/src/scripts/Libraries/NativeSlider.js +0 -138
  120. package/src/scripts/Libraries/Tabs.js +0 -16
  121. package/src/scripts/Ui/Checkbox.js +0 -10
  122. package/src/scripts/Ui/Input.js +0 -259
  123. package/src/scripts/Ui/Select.js +0 -53
  124. package/src/scripts/Utils/Functions/checkValidity.js +0 -44
  125. package/src/scripts/Utils/Functions/dataValue.js +0 -52
  126. package/src/scripts/Utils/Functions/inView.js +0 -24
  127. package/src/styles/Components/Form/+.css +0 -1
  128. package/src/styles/Components/Form/CookieConsent.css +0 -31
  129. package/src/styles/Libraries/NativeSlider.css +0 -60
  130. package/src/styles/Libraries/Tabs.css +0 -19
  131. package/src/styles/Ui/Checkbox.css +0 -151
  132. package/src/styles/Ui/Icon.css +0 -33
  133. package/src/styles/Ui/Input.css +0 -467
  134. package/src/styles/Ui/Radio.css +0 -4
  135. package/src/styles/Ui/Select.css +0 -137
  136. package/src/styles/Utils/normalize.css +0 -223
  137. package/src/styles/Utils/tailwind/+.css +0 -2
  138. package/src/styles/Utils/tailwind/gutters.css +0 -346
  139. package/src/styles/Utils/vars.css +0 -126
  140. package/src/styles/Utils/vendor.css +0 -1
  141. package/src/templates/Components/CookieConsent.twig +0 -30
  142. package/src/templates/Components/Dialogs/Basic.twig +0 -24
  143. package/src/templates/Layout/Main.twig +0 -49
  144. package/src/templates/Sections/Gdpr.twig +0 -64
  145. package/src/templates/Sections/Ui/Docs/Default.twig +0 -1600
  146. package/src/templates/Sections/Ui.twig +0 -8
  147. package/src/templates/Utils/sections.twig +0 -3
  148. package/src/views/dialog/basic.json.twig +0 -3
  149. package/tailwind.config.cjs +0 -69
  150. /package/src/emails/{templates.prod → templates}/.gitkeep +0 -0
  151. /package/src/templates/Layout/{Footer.twig → Footer.latte} +0 -0
@@ -2,7 +2,7 @@ import { loadStimulus, importStyle } from '../Utils/Functions/+.js'
2
2
  import cdn from '../Utils/cdn.js'
3
3
 
4
4
  export default class LibTippy {
5
- async init(element, options, template) {
5
+ async init (element, options, template) {
6
6
  const tippy = (await import('tippy.js')).default
7
7
  const { roundArrow } = await import('tippy.js')
8
8
 
@@ -14,7 +14,6 @@ export default class LibTippy {
14
14
 
15
15
  if (this.type.includes('dropdown')) {
16
16
  this.options.placement = 'bottom-end'
17
- this.options.arrow = false
18
17
  this.options.maxWidth = 'none'
19
18
  }
20
19
 
@@ -28,7 +27,7 @@ export default class LibTippy {
28
27
  } else {
29
28
  options.content = `
30
29
  <div class="c-dropdown">
31
- <div class="wrp_dropdown_body">
30
+ <div class="c_dropdown_body">
32
31
  ${element.getAttribute('aria-label')}
33
32
  </div>
34
33
  </div>
@@ -36,16 +35,16 @@ export default class LibTippy {
36
35
  }
37
36
  }
38
37
 
39
- if (typeof element.dataset.libTippySlot !== 'undefined') {
38
+ if (element.dataset.libTippySlot) {
40
39
  for (const [key, value] of Object.entries(JSON.parse(element.dataset.libTippySlot))) {
41
- options.content = options.content.replaceAll(`{${key}}`, value).replaceAll(`%7B${key}%7B`, value)
40
+ options.content = options.content.replaceAll(`{${key}}`, value.toString()).replaceAll(`%7B${key}%7B`, value.toString())
42
41
  }
43
42
  }
44
43
 
45
44
  tippy(element, options)
46
45
  }
47
46
 
48
- constructor(element, attributes = ['tooltip', '']) {
47
+ constructor (element, attributes = ['tooltip', '']) {
49
48
  const self = this
50
49
 
51
50
  this.options = {
@@ -55,29 +54,22 @@ export default class LibTippy {
55
54
  interactive: true,
56
55
  appendTo: 'parent',
57
56
  arrow: false,
58
- theme: 'light-border',
59
57
  animation: 'scale',
60
58
  inertia: true,
61
59
  allowHTML: true,
62
60
  onShow: (instance) => {
63
- let name = this.template
64
-
65
61
  if (this.type.includes('-full')) {
66
62
  instance.popper.classList.add('is-full')
67
- document.documentElement.classList.add('m:is-body-overlay')
68
- }
69
-
70
- if (typeof name === 'undefined') {
71
- name = this.type
63
+ document.documentElement.classList.add('max-md:is-body-overlay')
72
64
  }
73
65
 
74
- instance.popper.querySelector('.tippy-box').setAttribute('data-name', name)
66
+ instance.popper.querySelector('.tippy-box').setAttribute('data-name', this.template ?? this.type)
75
67
 
76
68
  loadStimulus(instance.popper.querySelector('.tippy-content'))
77
69
  },
78
70
  onHide: () => {
79
71
  if (this.type.includes('-full')) {
80
- setTimeout(() => document.documentElement.classList.remove('m:is-body-overlay'), 50)
72
+ setTimeout(() => document.documentElement.classList.remove('max-md:is-body-overlay'), 50)
81
73
  }
82
74
  }
83
75
  }
@@ -96,17 +88,18 @@ export default class LibTippy {
96
88
  this.options.showOnCreate = true
97
89
 
98
90
  this.options.trigger !== 'manual' && this.options.trigger.split(' ').forEach(event => {
99
- element.addEventListener(event, async function e() {
91
+ element.addEventListener(event, async function e () {
100
92
  if (self.template.startsWith('/') && self.options.content === '') {
101
93
  element.style.cursor = 'wait'
102
- element._addDataValue('state', 'loading')
94
+ element.classList.add('loading')
103
95
 
104
96
  fetch(self.template, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }).then(response => {
105
97
  return response.json()
106
- }).then(async(data) => {
98
+ }).then(async data => {
107
99
  self.options.content = data.content
108
100
  element.style.cursor = ''
109
- element._removeDataValue('state', 'loading')
101
+ element.classList.remove('loading')
102
+
110
103
  await self.init(element, self.options, self.template)
111
104
  element.removeEventListener(event, e)
112
105
  })
@@ -118,3 +111,7 @@ export default class LibTippy {
118
111
  })
119
112
  }
120
113
  }
114
+
115
+ export function hideTippy () {
116
+ document.querySelectorAll('[data-controller~="lib-tippy"][aria-expanded="true"]').forEach(element => element?._tippy?.hide())
117
+ }
@@ -1,4 +1,4 @@
1
- import './Checkbox.js'
2
- import './Input.js'
3
- import './Select.js'
1
+ import './Check.js'
2
+ import './Control.js'
3
+ import './ControlSelect.js'
4
4
  import './Text.js'
@@ -0,0 +1,8 @@
1
+ import { LibStimulus, Controller } from '../Libraries/Stimulus.js'
2
+ import { inputValidity } from '../Utils/Functions/+.js'
3
+
4
+ LibStimulus.register('ui-check', class extends Controller {
5
+ validity ({ currentTarget }) {
6
+ inputValidity(currentTarget)
7
+ }
8
+ })
@@ -0,0 +1,186 @@
1
+ import cdn from '../Utils/cdn.js'
2
+ import { LibStimulus, Controller } from '../Libraries/Stimulus.js'
3
+ import { importStyle, inputStep, inputValidity } from '../Utils/Functions/+.js'
4
+
5
+ LibStimulus.register('ui-control', class extends Controller {
6
+ static targets = ['number']
7
+
8
+ static values = {
9
+ dateOptions: {
10
+ default: {},
11
+ type: Object
12
+ },
13
+ dateDisabled: {
14
+ default: [],
15
+ type: Array
16
+ }
17
+ }
18
+
19
+ async connect () {
20
+ inputValidity(this.element, { validate: false })
21
+
22
+ this.element.addEventListener('change', () => inputValidity(this.element))
23
+
24
+ if (this.element.querySelector('select')) {
25
+ return
26
+ }
27
+
28
+ this.typeNumber()
29
+
30
+ await this.typeDate()
31
+
32
+ await this.typeColor()
33
+ }
34
+
35
+ async typeDate () {
36
+ const input = this.element.querySelector('[type^="date"], [type="month"]')
37
+
38
+ if (input) {
39
+ const AirDatepicker = (await import('air-datepicker')).default
40
+ const localeUrl = cdn.datepickerLang
41
+ const locale = (await import(/* @vite-ignore */ localeUrl)).default.default
42
+ const minDate = input.min ?? ''
43
+ const maxDate = input.max ?? ''
44
+ const timepicker = input.type === 'datetime-local'
45
+ const monthView = input.type === 'month'
46
+ ? {
47
+ view: 'months',
48
+ minView: 'months',
49
+ dateFormat: 'MMMM yyyy',
50
+ altFieldDateFormat: 'yyyy-MM'
51
+ }
52
+ : {}
53
+ const attributes = [...input.attributes].filter(({ name }) => name !== 'type').map(({ name, value }) => `${name}="${value}"`).join(' ')
54
+
55
+ input.setAttribute('type', 'hidden')
56
+
57
+ input.insertAdjacentHTML('afterend', `<input type="text" inputmode="none" ${attributes}>`)
58
+
59
+ const inputText = this.element.querySelector('[type="text"]')
60
+
61
+ inputText.addEventListener('keydown', e => {
62
+ const key = e.key.toLowerCase()
63
+
64
+ if (key !== 'backspace' && key !== 'tab') {
65
+ e.preventDefault()
66
+ } else if (key === 'backspace') {
67
+ this.datepicker.clear()
68
+ inputText.dispatchEvent(new Event('change', { bubbles: true }))
69
+ }
70
+ })
71
+
72
+ this.datepicker = new AirDatepicker(inputText, {
73
+ locale,
74
+ timepicker,
75
+ minDate,
76
+ maxDate,
77
+ startDate: input.value,
78
+ selectedDates: input.value,
79
+ altField: input,
80
+ autoClose: true,
81
+ container: this.element,
82
+ minutesStep: 5,
83
+ altFieldDateFormat: 'yyyy-MM-dd',
84
+ buttons: ['today', 'clear'],
85
+ ...monthView,
86
+ ...this.dateOptionsValue,
87
+ onRenderCell: ({ date, cellType }) => {
88
+ if (cellType === 'day' && this.dateDisabledValue.includes(this.datepicker.formatDate(date, 'yyyy-MM-dd'))) {
89
+ return {
90
+ disabled: true
91
+ }
92
+ }
93
+ },
94
+ onShow: () => {
95
+ this.datepicker.$datepicker.querySelectorAll('.air-datepicker-button').forEach(element => {
96
+ element.setAttribute('type', 'button')
97
+ element.setAttribute('tabindex', '-1')
98
+ })
99
+ },
100
+ onSelect: ({ date }) => {
101
+ inputText.dispatchEvent(new Event('change', { bubbles: true }))
102
+ }
103
+ })
104
+ }
105
+ }
106
+
107
+ async typeColor () {
108
+ if (this.element.querySelector('[type="color"]') !== null) {
109
+ const Pickr = (await import('@simonwep/pickr')).default
110
+ const input = this.element.querySelector('input')
111
+
112
+ await importStyle(cdn.pickrCss)
113
+
114
+ input.setAttribute('inputmode', 'none')
115
+ input.setAttribute('type', 'text')
116
+ input.setAttribute('maxlength', '9')
117
+ input.setAttribute('pattern', '^#?([a-fA-F0-9]{8}|[a-fA-F0-9]{6}|[a-fA-F0-9]{3})$')
118
+
119
+ this.element.insertAdjacentHTML('afterbegin', '<div class="icon-l"><div class="color"></div></div>')
120
+
121
+ const pickr = new Pickr({
122
+ el: input,
123
+ useAsButton: true,
124
+ theme: 'nano',
125
+ position: 'bottom-start',
126
+ components: {
127
+ preview: true,
128
+ opacity: true,
129
+ hue: true,
130
+ interaction: {
131
+ hex: true,
132
+ rgba: true,
133
+ input: true
134
+ }
135
+ }
136
+ }).on('init', pickr => {
137
+ pickr.setColor(input.value)
138
+ }).on('change', color => {
139
+ input.value = color.toHEXA().toString()
140
+ this.element.querySelector('.color').style['background-color'] = color.toHEXA().toString()
141
+ }).on('hide', pickr => {
142
+ pickr.applyColor()
143
+ input.dispatchEvent(new Event('change', { bubbles: true }))
144
+ })
145
+
146
+ input.addEventListener('change', ({ target }) => {
147
+ pickr.setColor(target.value)
148
+ })
149
+ }
150
+ }
151
+
152
+ typeNumber () {
153
+ if (this.element.querySelector('[type="number"]') && !this.hasNumberTarget) {
154
+ if (!this.element.querySelector('.icon-r')) {
155
+ this.element.insertAdjacentHTML('beforeend', '<div class="icon-r"></div>')
156
+ }
157
+
158
+ this.element.querySelector('.icon-r').insertAdjacentHTML('beforeend', `
159
+ <div class="flex flex-col gap-0 justify-center -space-y-1" data-ui-control-target="number">
160
+ <button class="focus-visible:text-accent" type="button" data-action="click->ui-control#increase">
161
+ <svg class="sq-4"><use href="#icon-angle-up"></use></svg>
162
+ </button>
163
+ <button class="focus-visible:text-accent" type="button" data-action="click->ui-control#decrease">
164
+ <svg class="sq-4"><use href="#icon-angle-down"></use></svg>
165
+ </button>
166
+ </div>
167
+ `)
168
+ }
169
+ }
170
+
171
+ increase () {
172
+ inputStep(this.element.querySelector('input[type="number"]'), true)
173
+ }
174
+
175
+ decrease () {
176
+ inputStep(this.element.querySelector('input[type="number"]'), false)
177
+ }
178
+
179
+ showPicker () {
180
+ this.element.querySelector('input:not([hidden])').showPicker()
181
+ }
182
+
183
+ showDatepicker () {
184
+ this.datepicker.$el.focus()
185
+ }
186
+ })
@@ -0,0 +1,24 @@
1
+ import { LibStimulus, Controller } from '../Libraries/Stimulus.js'
2
+
3
+ LibStimulus.register('ui-control-select', class extends Controller {
4
+ connect () {
5
+ this.select = this.element.querySelector('select')
6
+ const option = this.element.querySelectorAll('[data-option]')
7
+
8
+ if (option[0] !== null) {
9
+ option.forEach(option => {
10
+ if (option.dataset.disabled) {
11
+ return
12
+ }
13
+
14
+ option.setAttribute('data-action', 'click->ui-control-select#choose keydown.enter->ui-control-select#choose')
15
+ })
16
+ }
17
+ }
18
+
19
+ choose ({ currentTarget }) {
20
+ this.select.value = currentTarget.dataset.option
21
+ this.select.dispatchEvent(new Event('change', { bubbles: true }))
22
+ document.activeElement.blur()
23
+ }
24
+ })
@@ -1,23 +1,21 @@
1
1
  import { LibStimulus, Controller } from '../Libraries/Stimulus.js'
2
2
 
3
3
  LibStimulus.register('ui-text', class extends Controller {
4
- connect() {
4
+ connect () {
5
+ function wrap (element, wrapper) {
6
+ element.parentNode.insertBefore(wrapper, element)
7
+ wrapper.appendChild(element)
8
+ }
9
+
5
10
  this.element.querySelectorAll('table').forEach(table => {
6
- this.wrap(table, new DOMParser().parseFromString('<div class="elm_text_table"></div>', 'text/html').body.firstChild)
11
+ wrap(table, new DOMParser().parseFromString('<div class="c_text_table"></div>', 'text/html').body.firstChild)
7
12
  })
8
13
 
9
14
  this.element.querySelectorAll('iframe').forEach(iframe => {
10
- if (iframe.src.match(/youtube\.com/i)) {
11
- this.wrap(iframe, new DOMParser().parseFromString(`<div class="elm_text_video" style="max-width: ${iframe.width.includes('%') ? iframe.width : iframe.width + 'px'}"></div>`, 'text/html').body.firstChild)
12
- } else if (iframe.width && iframe.style.aspectRatio !== 'undefined') {
15
+ if (iframe.width && iframe.style.aspectRatio !== 'undefined') {
13
16
  iframe.style.aspectRatio = iframe.width + '/' + iframe.height
14
17
  iframe.style.height = 'auto'
15
18
  }
16
19
  })
17
20
  }
18
-
19
- wrap(el, wrapper) {
20
- el.parentNode.insertBefore(wrapper, el)
21
- wrapper.appendChild(el)
22
- }
23
21
  })
@@ -1,7 +1,7 @@
1
- export { default as checkValidity } from './checkValidity.js'
2
- import './dataValue.js'
3
1
  export { default as importScript } from './importScript.js'
4
2
  export { default as importStyle } from './importStyle.js'
5
- export { default as inView } from './inView.js'
3
+ export { default as inputStep } from './inputStep.js'
4
+ export { default as inputValidity } from './inputValidity.js'
6
5
  export { default as loadStimulus } from './loadStimulus.js'
6
+ export { default as replaceScript } from './replaceScript.js'
7
7
  export { default as replaceTag } from './replaceTag.js'
@@ -1,4 +1,4 @@
1
- export default function importScript(url) {
1
+ export default function importScript (url) {
2
2
  return new Promise((resolve, reject) => {
3
3
  if (document.querySelector(`script[src="${url}"]`) === null) {
4
4
  const script = document.createElement('script')
@@ -1,4 +1,4 @@
1
- export default function importStyle(url) {
1
+ export default function importStyle (url) {
2
2
  return new Promise((resolve, reject) => {
3
3
  if (document.querySelector(`link[href="${url}"]`) === null) {
4
4
  const style = document.createElement('link')
@@ -0,0 +1,9 @@
1
+ export default function inputStep (input, increase, callback) {
2
+ const value = parseInt(input.value === '' ? 0 : input.value)
3
+
4
+ if ((increase && (value < input.max || input.max === '')) || (!increase && (value > input.min || input.min === ''))) {
5
+ input.value = increase ? (value + 1).toString() : (value - 1).toString()
6
+ callback && callback()
7
+ input.dispatchEvent(new Event('change', { bubbles: true }))
8
+ }
9
+ }
@@ -0,0 +1,57 @@
1
+ export default function inputValidity (element, options = {}) {
2
+ const { validate, message, iconElements } = {
3
+ validate: true,
4
+ message: false,
5
+ iconElements: '.ui-control',
6
+ ...options
7
+ }
8
+
9
+ const selectors = element.querySelectorAll('input, textarea, select')
10
+
11
+ selectors.forEach(selector => {
12
+ if (selector.closest('.air-datepicker')) {
13
+ return
14
+ }
15
+
16
+ const validationMessage = selector.dataset.validationMessage ?? selector.validationMessage
17
+ const validityElement = element?.closest('.c-field')?.querySelector('.ui-info.validity')
18
+
19
+ if (!selector.outerHTML.match(/(data-novalidate|readonly|hidden)/) && validate) {
20
+ element.classList.remove('valid', 'invalid', 'active')
21
+
22
+ if (element.closest(iconElements) && element.querySelector('[class^="icon"] [class*="valid"]') !== null) {
23
+ element.querySelector('[class^="icon"] [class*="valid"]').remove()
24
+ }
25
+
26
+ if (selector.checkValidity()) {
27
+ element.classList.add('valid')
28
+
29
+ if (validityElement) {
30
+ validityElement.remove()
31
+ }
32
+ } else {
33
+ element.classList.add('invalid')
34
+
35
+ if (!validityElement && message) {
36
+ element?.closest('.c-field')?.insertAdjacentHTML('beforeend', `<div class="ui-info validity text-error">${validationMessage}</div>`)
37
+ }
38
+
39
+ if (element.closest(iconElements) && element.querySelector('[class^="icon"] [class*="valid"]') === null) {
40
+ if (!element.querySelector('.icon-r')) {
41
+ element.insertAdjacentHTML('beforeend', '<div class="icon-r"></div>')
42
+ }
43
+
44
+ element.querySelector('.icon-r').insertAdjacentHTML('afterbegin', `
45
+ <div class="invalid lib-hint-top" tabindex="0" aria-label="${validationMessage}">
46
+ <svg class="text-error"><use href="#icon-exclamation-circle"></use></svg>
47
+ </div>
48
+ `)
49
+ }
50
+ }
51
+ }
52
+
53
+ if (selector.value !== '') {
54
+ element.classList.add('active')
55
+ }
56
+ })
57
+ }
@@ -1,23 +1,25 @@
1
- const dynamicControllers = ['ui-input', 'ui-select', 'ui-text', 'ui-checkbox', 'ui-radio', 'c-cookieconsent', 'c-form-cookieconsent']
2
- const dynamicActions = [['.ui-btn', 'click->lib#ripple']]
1
+ import naja from 'naja'
3
2
 
4
- if (!('scrollBehavior' in document.documentElement.style)) {
5
- dynamicActions.push(['a[href^="#"]', 'click->lib#anchor'])
6
- }
3
+ const dynamicControllers = ['ui-control', 'ui-text', 'ui-check']
4
+ const dynamicActions = [['.ui-btn', 'click->lib-ripple#show'], ['.ui-check', 'change->ui-check#validity']]
7
5
 
8
- function loadControllers(parent, selectors) {
6
+ function loadControllers (parent, selectors) {
9
7
  if (parent !== null) {
10
8
  selectors.forEach(selector => {
11
9
  [...parent.getElementsByClassName(selector)].forEach(element => {
12
- if (element.getAttribute('data-controller') === null) {
10
+ const attribute = element.getAttribute('data-controller')
11
+
12
+ if (attribute === null) {
13
13
  element.setAttribute('data-controller', selector)
14
+ } else {
15
+ element.setAttribute('data-controller', `${attribute} ${selector}`)
14
16
  }
15
17
  })
16
18
  })
17
19
  }
18
20
  }
19
21
 
20
- function loadActions(parent, selectors) {
22
+ function loadActions (parent, selectors) {
21
23
  if (parent !== null) {
22
24
  selectors.forEach(selector => {
23
25
  parent.querySelectorAll(selector[0]).forEach(element => {
@@ -33,7 +35,8 @@ function loadActions(parent, selectors) {
33
35
  }
34
36
  }
35
37
 
36
- export default function loadStimulus(selector) {
38
+ export default function loadStimulus (selector, najaLoad = true) {
37
39
  loadControllers(selector, dynamicControllers)
38
40
  loadActions(selector, dynamicActions)
41
+ najaLoad && naja.uiHandler.bindUI(selector)
39
42
  }
@@ -0,0 +1,4 @@
1
+ export default function replaceScript (selector) {
2
+ selector.querySelectorAll('script:not([data-lib-cookieconsent])').forEach(script =>
3
+ script.setAttribute('data-controller', 'lib-script'))
4
+ }
@@ -1,12 +1,8 @@
1
- export default function replaceTag(documentElement) {
1
+ export default function replaceTag (documentElement) {
2
2
  documentElement.querySelectorAll('[data-lib-replace-tag]').forEach(element => {
3
3
  const replaceTag = document.querySelector(`[data-lib-replace-tag=${element.dataset.libReplaceTag}]`)
4
4
  const placement = element.closest('head') ? document.head : replaceTag.parentElement
5
5
 
6
6
  replaceTag ? (replaceTag.outerHTML = element.outerHTML) : placement.insertAdjacentHTML('beforeend', element.outerHTML)
7
-
8
- if (element.tagName === 'SCRIPT') {
9
- document.querySelector(`[data-lib-replace-tag=${element.dataset.libReplaceTag}]`)._addDataValue('controller', 'lib-script')
10
- }
11
7
  })
12
8
  }
@@ -1,7 +1,6 @@
1
1
  export default {
2
2
  recaptcha: 'https://www.google.com/recaptcha/enterprise.js?render={apikey}',
3
- seamless: 'https://cdn.jsdelivr.net/npm/seamless-scroll-polyfill@2.1.6/lib/bundle.min.js',
4
- pickrCss: 'https://cdn.jsdelivr.net/npm/@simonwep/pickr@1.8.0/dist/themes/nano.min.css',
3
+ pickrCss: 'https://cdn.jsdelivr.net/npm/@simonwep/pickr@1.8.2/dist/themes/nano.min.css',
5
4
  tippy: 'https://cdn.jsdelivr.net/combine/npm/tippy.js@6.3.7/dist/tippy.css,npm/tippy.js@6.3.1/dist/svg-arrow.css,npm/tippy.js@6.3.7/themes/light-border.css,npm/tippy.js@6.3.7/animations/scale.css',
6
- datepicker: 'https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.2.0/dist/css/datepicker.min.css'
5
+ datepickerLang: `https://cdn.jsdelivr.net/npm/air-datepicker@3.3.5/locale/${document.documentElement.lang}.js/+esm`
7
6
  }
@@ -1,4 +1,4 @@
1
- !CSS.supports('selector(:has(*))') && (async() => (await import('css-has-pseudo/browser')).default(document))()
1
+ !CSS.supports('selector(:has(*))') && (async () => (await import('css-has-pseudo/browser')).default(document))()
2
2
 
3
3
  if ('serviceWorker' in navigator && location.protocol === 'https:') {
4
4
  window.addEventListener('load', () => {
@@ -1,4 +1,4 @@
1
1
  @import "CookieConsent.css";
2
2
  @import "Dialog/+.css";
3
3
  @import "Dropdown/+.css";
4
- @import "Form/+.css";
4
+ @import "Field.css";
@@ -3,7 +3,7 @@
3
3
  inset: 0;
4
4
  display: none;
5
5
  z-index: var(--z-50);
6
- background-color: rgb(var(--color-dark) / 0.75);
6
+ background-color: rgb(var(--color-dark-rgb) / 75%);
7
7
  justify-content: center;
8
8
  align-items: center;
9
9
  flex-direction: column;
@@ -20,51 +20,48 @@
20
20
  animation: 0.5s ease 0s backwards 1 fade-in;
21
21
  }
22
22
 
23
- &:--state-active {
23
+ &.active {
24
24
  display: flex;
25
25
  }
26
26
 
27
- & .wrp {
27
+ > .c {
28
28
  max-width: 32rem;
29
29
  width: calc(100% - 2rem);
30
- border-radius: var(--radius);
31
- padding: 2rem;
30
+ border-radius: var(--rounded-2xl);
31
+ padding: 1rem;
32
+ background-color: var(--color-body-primary);
32
33
 
33
- @nest :--type-center& {
34
- max-width: 26rem;
35
- text-align: center;
36
-
37
- & .ui-image {
38
- margin-left: auto;
39
- margin-right: auto;
40
- }
34
+ @media (--media-md) {
35
+ padding: 2rem;
41
36
  }
42
37
 
43
- & .wrp_c_head {
38
+ > .c_head {
44
39
  margin-bottom: 1rem;
45
40
 
46
- @media (--media-t) {
41
+ @media (--media-md) {
47
42
  margin-bottom: 1.5rem;
48
43
  }
49
44
  }
50
45
 
51
- & .wrp_c_body {
52
- & .ui-text {
53
- --ui-text-size: 0.875rem;
54
- }
55
- }
56
-
57
- & .wrp_c_foot {
46
+ > .c_foot {
58
47
  display: flex;
59
48
  align-items: center;
60
49
  margin-top: 1.5rem;
61
50
 
62
- @media (--media-t) {
51
+ @media (--media-md) {
63
52
  margin-top: 2rem;
64
53
  }
54
+ }
55
+ }
56
+
57
+ &.is-center {
58
+ > .c {
59
+ max-width: 27rem;
60
+ text-align: center;
65
61
 
66
- & .ui-link {
67
- font-weight: var(--font-normal);
62
+ & .ui-image {
63
+ margin-left: auto;
64
+ margin-right: auto;
68
65
  }
69
66
  }
70
67
  }