Our own Webpack Boilerplate for new projects.
- Pnpm
- Node v22+
To install, follow these instructions.
1: Add all of the files to your project.
2: Change the public
folder name to the correct name.
3: Open your terminal and go to your project:
cd /path/to/project
4: Use the correct nvm version:
nvm use 22
5: Run Pnpm to install all of the packages:
pnpm install
6: Run one of the commands:
pnpm watch
to watch any changes inside theassets
folderpnpm build
to compile thebuild
folder
To install the plugin with multiple themes, follow these instructions.
1: Add all of the files to your project.
2: Change the public
folder name to the correct name.
3: Open the packages.json
file and find these lines:
"scripts": {
"watch": "node webpack/pre-script.js && webpack -p --watch --config webpack/webpack.config.js",
"build": "node webpack/pre-script.js && webpack -p --config webpack/webpack.config.js"
},
4: Change the lines and add multiple themes. theme1
and theme2
should be renamed to your theme names:
"scripts": {
"theme1-watch": "node webpack/pre-script.js && NODE_THEME=theme1 webpack -p --watch --config webpack/webpack.config.js",
"theme1-build": "node webpack/pre-script.js && NODE_THEME=theme1 webpack -p --config webpack/webpack.config.js",
"theme2-watch": "node webpack/pre-script.js && NODE_THEME=theme2 webpack -p --watch --config webpack/webpack.config.js",
"theme2-build": "node webpack/pre-script.js && NODE_THEME=theme2 webpack -p --config webpack/webpack.config.js",
},
5: Create the theme folders inside the assets
folder (e.g. theme1
and theme2
).
6: Copy the css
, js
and svg
folders inside theme1
and theme2
.
7: Open your terminal and go to your project:
cd /path/to/project
8: Run Pnpm to install all of the packages:
pnpm install
9: Run one of the commands: Theme 1
pnpm theme1-watch
to watch any changes inside theassets/theme1
folderpnpm theme1-build
to compile thebuild/theme1
folder for development
Theme 2
pnpm theme2-watch
to watch any changes inside theassets/theme2
folderpnpm theme2-build
to compile thebuild/theme2
folder for development
10: Change the location of the CSS and JS file inside the index.html
:
Theme 1
<link rel="stylesheet" href="/build/theme1/css/css-main.build.css">
<script src="/build/theme1/js/js-app.build.js"></script>
Theme 2
<link rel="stylesheet" href="/build/theme2/css/css-main.build.css">
<script src="/build/theme2/js/js-app.build.js"></script>
We've add some basic accessibility features to the boilerplate. For all focusable elements, the focus-visible can be updated on it's own css declaration by updating the following elements
--outline-border-radius: 5px;
--outline-color: green;
--outline-offset: 5px;
--outline-width: 12px;
Two other classnames can be used out of the box;
.sr-only
and .sr-only-focusable
.
The first one is hidden for default screens. The second one is hidden for default screens, but visible when focused.
Use this markup for a hamburger menu trigger. The data element data-menu-is-active
will be added to the body when the hanburger is active. The state wil also be stored in the svelte store.
<div class="js-hamburger"></div>
There is a querySelector (.expanded-navigation) for the navigation that wil be targeted when the hamburger become to active. Make sure to change this to the correct class, id, data-attribute etc.
Use this markup as a start for a scrollable element. Make sure the items have a height and a width, and don't forget to set these dimensions in the javascript as well.
<div class="scrollable js-scrollable">
<div class="scrollable__slider dragscroll js-scrollable-items">
<div class="scrollable__inner js-scrollable-inner">
<div>1</div>
<div>2</div>
<div>3</div>
...
</div>
</div>
<div class="scrollable__controls">
<button class="scrollable__controls__button js-scrollable-left" aria-label="Scroll to left" type="button"><</button>
<button class="scrollable__controls__button js-scrollable-right" aria-label="Scroll to right" type="button">></button>
</div>
</div>
Use this markup as a start for a simple image slider.
When you import a new module in javascript, dont forget to also include the styles in css/2-vendor/_swiper.scss
.
<div class="image-slider swiper js-image-slider">
<div class="swiper-wrapper">
<div class="swiper-slide">1</div>
<div class="swiper-slide">2</div>
<div class="swiper-slide">3</div>
...
</div>
<div class="image-slider__pagination"></div>
<div class="image-slider__navigation">
<button class="image-slider__button image-slider__button--prev" aria-label="To left"><</button>
<button class="image-slider__button image-slider__button--next" aria-label="To right">></button>
</div>
</div>
Use this markup as a start for very simple accordion items
<div class="accordion">
<div class="accordion__item">
<input class="accordion__input" type="checkbox" name="accordion1" id="accordion1">
<label class="accordion__title" for="accordion1" aria-label="Show content of accordion item 1">Accordion item 1</label>
<div class="accordion__content">Content for accordion item 1</div>
</div>
<div class="accordion__item">
<input class="accordion__input" type="checkbox" name="accordion2" id="accordion2">
<label class="accordion__title" for="accordion2">Accordion item 2</label>
<div class="accordion__content">Content for accordion item 2</div>
</div>
</div>
Add data-popup-content="#popup-content"
on the trigger to open a popup with the contents of the element with id="popup-content"
.
By default this opens a fullscreen popup, but you can also specify a type with data-popup-type="small"
. This will add a modifier class: popup--small
to the popup. You can also add new types.
<button data-popup-content="#popup-content"></button>
<script type="text/x-template" id="popup-content">
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
</script>
Add data-scroll-to="#target"
on the trigger to scroll to element with id="target"
<button data-scroll-to="#target"></button>
Use this markup for the default form styling and validation:
<form class="form js-form-validate">
<!-- Single field -->
<div class="form__group">
<div class="form__item">
<label class="form__label" for="field1">field1*</label>
<input class="form__input" id="field1" name="field1" type="text" required="required">
</div>
</div>
<!-- Multiple fields -->
<div class="form__group">
<div class="form__item form__item--6">
<label class="form__label" for="field2">field2*</label>
<input class="form__input" id="field2" name="field2" type="text" required="required">
</div>
<div class="form__item form__item--6">
<label class="form__label" for="field3">field3*</label>
<input class="form__input" id="field3" name="field3" type="text" required="required">
</div>
</div>
<!-- Radio -->
<div class="form__group">
<div class="form__item">
<span class="form__label">field4*</span>
<label>
<input type="radio" value="1" name="radio">
<span>Radiobutton 1</span>
</label>
<label>
<input type="radio" value="2" name="radio">
<span>Radiobutton 2</span>
</label>
</div>
</div>
<!-- Checkbox -->
<div class="form__group">
<div class="form__item">
<span class="form__label">field5*</span>
<label>
<input type="checkbox" name="checkbox1">
<span>Checkbox 1</span>
</label>
<label>
<input type="checkbox" name="checkbox2">
<span>Checkbox 2</span>
</label>
<label>
<input type="checkbox" disabled>
<span>Checkbox 3 - disabled</span>
</label>
</div>
</div>
<!-- Submit button -->
<div class="form__group">
<div class="form__item">
<button class="btn" type="submit">Verzenden</button>
</div>
</div>
</form>
Use this markup for a date select. Make sure all classes prefixed with js-form-date-
are present.
The value from the selects will be placed in the hidden input with the format YYYY-MM-DD
.
Inside modules/formvalidation/init
, make sure the customValidation date
is enabled in the customValidations and formatDateField()
is enabled in the init()
function .
<!-- Date -->
<div class="form__group js-form-date">
<input class="js-form-date-result" type="hidden" name="birthDate" required="required" data-bouncer-target="#date-error">
<div class="form__item form__item--4">
<label class="form__label" for="field6">field6*</label>
<select class="form__input js-form-date-day" id="field6" name="field6">
<option value="" disabled selected></option>
<option value="1">1</option>
<option value="2">2</option>
...
</select>
<div id="date-error"></div>
</div>
<div class="form__item form__item--4">
<label class="form__label" for="field7">field7*</label>
<select class="form__input js-form-date-month" id="field7" name="field7">
<option value="" disabled selected></option>
<option value="1">Januari</option>
<option value="2">Februari</option>
...
</select>
</div>
<div class="form__item form__item--4">
<label class="form__label" for="field8">field8*</label>
<select class="form__input js-form-date-year" id="field8" name="field8">
<option value="" disabled selected></option>
<option value="2020">2020</option>
<option value="2019">2019</option>
...
</select>
</div>
</div>
Make sure isAtLeastOneCheckboxChecked
is enabled in the customValidations
inside modules/formvalidation/init
and use the following markup.
<div class="form__group" data-bouncer-at-least-one-checkbox>
<div class="form__item">
<span class="form__label">Field 9</span>
<label for="field9">
<input type="checkbox" value="1" id="field9" name="multipleCheckboxes[]" data-bouncer-target="#multipleCheckboxes">
<span>value 1</span>
</label>
<label for="field10">
<input type="checkbox" value="2" id="field10" name="multipleCheckboxes[]" data-bouncer-target="#multipleCheckboxes">
<span>value 2</span>
</label>
<label for="field11">
<input type="checkbox" value="2" id="field11" name="multipleCheckboxes[]" data-bouncer-target="#multipleCheckboxes">
<span>value 3</span>
</label>
<div id="multipleCheckboxes"></div>
</div>
</div>