@@ -23,8 +23,22 @@ function init() {
2323 const resetBtns = container . querySelectorAll ( "[data-taxation-reset]" ) ;
2424
2525 const ctx = { container, config, i18n, state } ;
26+ const mobileMq = window . matchMedia ( "(max-width: 992px)" ) ;
27+
28+ function scrollCalculatorToTopOnMobile ( ) {
29+ if ( ! mobileMq . matches ) return ;
30+ const MOBILE_HEADER_OFFSET = 88 ;
31+ const targetTop = window . scrollY + container . getBoundingClientRect ( ) . top ;
32+ window . scrollTo ( {
33+ top : Math . max ( 0 , targetTop - MOBILE_HEADER_OFFSET ) ,
34+ behavior : "smooth" ,
35+ } ) ;
36+ }
37+
38+ ctx . scrollCalculatorToTopOnMobile = scrollCalculatorToTopOnMobile ;
2639
2740 function rerenderAll ( ) {
41+ renderPersonLimitControlInput ( ctx , saveState ) ;
2842 operatorsWrapper . innerHTML = "" ;
2943 nationalWrapper . innerHTML = "" ;
3044 const otherWrapper = container . querySelector ( "[data-taxation-other]" ) ;
@@ -94,17 +108,72 @@ function init() {
94108 updateSummary ( container , config , i18n , state ) ;
95109 }
96110
111+ function onPersonLimitChange ( ) {
112+ for ( const op of config . operators ) {
113+ const opState = state . operators [ op . slug ] ;
114+ if ( ! hasActiveState ( opState ) ) continue ;
115+ const row = operatorsWrapper . querySelector (
116+ '[data-taxation-row="' + op . slug + '"]' ,
117+ ) ;
118+ if ( ! row ) continue ;
119+ updateRowState (
120+ row ,
121+ opState ,
122+ op . firstClass || 0 ,
123+ op . secondClass ,
124+ state . personLimit ,
125+ true ,
126+ op . singlePersonOnly || false ,
127+ ) ;
128+ updateRowMultipliers (
129+ row ,
130+ op . singlePersonOnly ? 1 : state . personLimit ,
131+ i18n ,
132+ ) ;
133+ updateRowWarning (
134+ row ,
135+ op . singleClassOnly || false ,
136+ op . singlePersonOnly || false ,
137+ state . personLimit ,
138+ i18n ,
139+ ) ;
140+ }
141+
142+ for ( const nat of config . national ) {
143+ const natState = state . national [ nat . key ] ;
144+ if ( ! hasActiveState ( natState ) ) continue ;
145+ const row = nationalWrapper . querySelector (
146+ '[data-taxation-row="' + nat . key + '"]' ,
147+ ) ;
148+ if ( ! row ) continue ;
149+ updateRowState (
150+ row ,
151+ natState ,
152+ nat . firstClass ,
153+ nat . secondClass ,
154+ state . personLimit ,
155+ false ,
156+ false ,
157+ ) ;
158+ }
159+
160+ runPlanning ( ctx ) ;
161+ updateSummary ( container , config , i18n , state ) ;
162+ }
163+
164+ ctx . onPersonLimitChange = onPersonLimitChange ;
165+
97166 ctx . rerenderAll = rerenderAll ;
98167 ctx . runOptimization = runOptimization ;
99168
100- renderPersonLimitControlInput ( ctx , saveState ) ;
101169 rerenderAll ( ) ;
102170
103171 if ( resetBtns . length > 0 && operatorsWrapper && nationalWrapper ) {
104172 const resetCalculator = function ( ) {
105173 state . operators = { } ;
106174 state . national = { } ;
107175 state . other = 0 ;
176+ state . personLimit = 1 ;
108177 state . planningAssignments = { } ;
109178 state . planningManualAssignments = { } ;
110179 state . planningMonthCount = 0 ;
@@ -130,35 +199,17 @@ function getI18n(container) {
130199 addOperator : container . dataset . i18nAddOperator ,
131200 addNational : container . dataset . i18nAddNational ,
132201 remove : container . dataset . i18nRemove ,
133- perField : container . dataset . i18nPerField ,
134- field : container . dataset . i18nField ,
135- fields : container . dataset . i18nFields ,
136202 increase : container . dataset . i18nIncrease ,
137203 decrease : container . dataset . i18nDecrease ,
138- sum : container . dataset . i18nSum ,
139- categoryInternational : container . dataset . i18nCategoryInternational ,
140- categoryNational : container . dataset . i18nCategoryNational ,
141204 categoryOther : container . dataset . i18nCategoryOther ,
142205 otherPlaceholder : container . dataset . i18nOtherPlaceholder ,
143- classMixedWarning : container . dataset . i18nClassMixedWarning ,
144- secondPersonHint : container . dataset . i18nSecondPersonHint ,
145206 highlightImportant : container . dataset . i18nHighlightImportant ,
146- highlightTip : container . dataset . i18nHighlightTip ,
147- thresholdAbove : container . dataset . i18nThresholdAbove ,
148- thresholdBelow : container . dataset . i18nThresholdBelow ,
149- thresholdExcess : container . dataset . i18nThresholdExcess ,
150- disclaimer : container . dataset . i18nDisclaimer ,
151- personsRequired : container . dataset . i18nPersonsRequired ,
152- personLimit : container . dataset . i18nPersonLimit ,
153207 noRelativesWarning : container . dataset . i18nNoRelativesWarning ,
154- reset : container . dataset . i18nReset ,
155208 planning : container . dataset . i18nPlanning ,
156209 optimize : container . dataset . i18nOptimize ,
157- manualMode : container . dataset . i18nManualMode ,
158- optimizationTitle : container . dataset . i18nOptimizationTitle ,
210+ addMonth : container . dataset . i18nAddMonth ,
159211 optimizationMonth : container . dataset . i18nOptimizationMonth ,
160- optimizationItems : container . dataset . i18nOptimizationItems ,
161- optimizationImpossible : container . dataset . i18nOptimizationImpossible ,
212+ personLimit : container . dataset . i18nPersonLimit ,
162213 unassigned : container . dataset . i18nUnassigned ,
163214 person : container . dataset . i18nPerson ,
164215 persons : container . dataset . i18nPersons ,
@@ -736,6 +787,7 @@ function createSearchSelect(options) {
736787 list . className = "o-taxation-calculator__search-list" ;
737788 list . setAttribute ( "role" , "listbox" ) ;
738789 list . setAttribute ( "aria-hidden" , "true" ) ;
790+ list . inert = true ;
739791
740792 const activeKeys = new Set ( ) ;
741793
@@ -755,6 +807,7 @@ function createSearchSelect(options) {
755807 const btn = document . createElement ( "button" ) ;
756808 btn . type = "button" ;
757809 btn . className = "o-taxation-calculator__search-item-btn" ;
810+ btn . setAttribute ( "aria-label" , item . label ) ;
758811
759812 const addIcon = createIcon ( "add_circle" ) ;
760813 addIcon . classList . add ( "o-taxation-calculator__search-add-icon" ) ;
@@ -813,6 +866,7 @@ function createSearchSelect(options) {
813866 function openList ( ) {
814867 const count = buildItems ( ) ;
815868 if ( count > 0 ) {
869+ list . inert = false ;
816870 list . setAttribute ( "aria-hidden" , "false" ) ;
817871 input . setAttribute ( "aria-expanded" , "true" ) ;
818872 wrapper . classList . add ( "o-taxation-calculator__search-select--open" ) ;
@@ -821,6 +875,10 @@ function createSearchSelect(options) {
821875 }
822876
823877 function closeList ( ) {
878+ if ( list . contains ( document . activeElement ) ) {
879+ input . focus ( { preventScroll : true } ) ;
880+ }
881+ list . inert = true ;
824882 list . setAttribute ( "aria-hidden" , "true" ) ;
825883 input . setAttribute ( "aria-expanded" , "false" ) ;
826884 wrapper . classList . remove ( "o-taxation-calculator__search-select--open" ) ;
@@ -998,6 +1056,7 @@ function renderOperators(ctx, wrapper) {
9981056 items : selectItems ,
9991057 onSelect ( item ) {
10001058 addOperatorCard ( ctx , wrapper , searchSelect , item . data ) ;
1059+ ctx . scrollCalculatorToTopOnMobile ( ) ;
10011060 } ,
10021061 } ) ;
10031062
@@ -1030,6 +1089,7 @@ function renderNational(ctx, wrapper) {
10301089 items : selectItems ,
10311090 onSelect ( item ) {
10321091 addNationalCard ( ctx , wrapper , searchSelect , item . data ) ;
1092+ ctx . scrollCalculatorToTopOnMobile ( ) ;
10331093 } ,
10341094 } ) ;
10351095
@@ -1138,18 +1198,6 @@ function updateSummary(container, config, i18n, state) {
11381198 summaryHint ,
11391199 ) ;
11401200
1141- updateSummaryBlock (
1142- container ,
1143- {
1144- totalEl : container . querySelector ( "[data-taxation-bottom-total]" ) ,
1145- personsEl : container . querySelector ( "[data-taxation-bottom-persons]" ) ,
1146- thresholdEl : container . querySelector ( "[data-taxation-bottom-threshold]" ) ,
1147- } ,
1148- total ,
1149- totalPersons ,
1150- summaryHint ,
1151- ) ;
1152-
11531201 updateThresholdBlock (
11541202 container . querySelector ( "[data-taxation-mobile-threshold-detail]" ) ,
11551203 summaryHint ,
@@ -1185,6 +1233,20 @@ function runPlanning(ctx) {
11851233 }
11861234}
11871235
1236+ function updateRowMultipliers ( row , effectivePersonLimit , i18n ) {
1237+ var multiplierEls = row . querySelectorAll (
1238+ ".o-taxation-calculator__multiplier" ,
1239+ ) ;
1240+ for ( const multiplierEl of multiplierEls ) {
1241+ if ( effectivePersonLimit === 1 ) {
1242+ multiplierEl . textContent = "x 1 " + i18n . person ;
1243+ } else {
1244+ multiplierEl . textContent =
1245+ "x " + effectivePersonLimit + " " + i18n . persons ;
1246+ }
1247+ }
1248+ }
1249+
11881250function updateSummaryBlock ( container , els , total , totalPersons , summaryHint ) {
11891251 if ( ! els . totalEl ) return ;
11901252
0 commit comments