feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
This commit is contained in:
1
f_scripts/shared/swiper/modules/navigation/navigation-element.min.css
vendored
Normal file
1
f_scripts/shared/swiper/modules/navigation/navigation-element.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:initial;line-height:1}.swiper-button-prev,:host(.swiper-rtl) .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-prev:after,:host(.swiper-rtl) .swiper-button-next:after{content:'prev'}.swiper-button-next,:host(.swiper-rtl) .swiper-button-prev{right:var(--swiper-navigation-sides-offset,10px);left:auto}.swiper-button-next:after,:host(.swiper-rtl) .swiper-button-prev:after{content:'next'}.swiper-button-lock{display:none}
|
||||
186
f_scripts/shared/swiper/modules/navigation/navigation.js
Normal file
186
f_scripts/shared/swiper/modules/navigation/navigation.js
Normal file
@@ -0,0 +1,186 @@
|
||||
import createElementIfNotDefined from '../../shared/create-element-if-not-defined.js';
|
||||
export default function Navigation({
|
||||
swiper,
|
||||
extendParams,
|
||||
on,
|
||||
emit
|
||||
}) {
|
||||
extendParams({
|
||||
navigation: {
|
||||
nextEl: null,
|
||||
prevEl: null,
|
||||
hideOnClick: false,
|
||||
disabledClass: 'swiper-button-disabled',
|
||||
hiddenClass: 'swiper-button-hidden',
|
||||
lockClass: 'swiper-button-lock',
|
||||
navigationDisabledClass: 'swiper-navigation-disabled'
|
||||
}
|
||||
});
|
||||
swiper.navigation = {
|
||||
nextEl: null,
|
||||
prevEl: null
|
||||
};
|
||||
const makeElementsArray = el => {
|
||||
if (!Array.isArray(el)) el = [el].filter(e => !!e);
|
||||
return el;
|
||||
};
|
||||
function getEl(el) {
|
||||
let res;
|
||||
if (el && typeof el === 'string' && swiper.isElement) {
|
||||
res = swiper.el.shadowRoot.querySelector(el);
|
||||
if (res) return res;
|
||||
}
|
||||
if (el) {
|
||||
if (typeof el === 'string') res = [...document.querySelectorAll(el)];
|
||||
if (swiper.params.uniqueNavElements && typeof el === 'string' && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
|
||||
res = swiper.el.querySelector(el);
|
||||
}
|
||||
}
|
||||
if (el && !res) return el;
|
||||
// if (Array.isArray(res) && res.length === 1) res = res[0];
|
||||
return res;
|
||||
}
|
||||
function toggleEl(el, disabled) {
|
||||
const params = swiper.params.navigation;
|
||||
el = makeElementsArray(el);
|
||||
el.forEach(subEl => {
|
||||
if (subEl) {
|
||||
subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
|
||||
if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
|
||||
if (swiper.params.watchOverflow && swiper.enabled) {
|
||||
subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function update() {
|
||||
// Update Navigation Buttons
|
||||
const {
|
||||
nextEl,
|
||||
prevEl
|
||||
} = swiper.navigation;
|
||||
if (swiper.params.loop) {
|
||||
toggleEl(prevEl, false);
|
||||
toggleEl(nextEl, false);
|
||||
return;
|
||||
}
|
||||
toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
|
||||
toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
|
||||
}
|
||||
function onPrevClick(e) {
|
||||
e.preventDefault();
|
||||
if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
|
||||
swiper.slidePrev();
|
||||
emit('navigationPrev');
|
||||
}
|
||||
function onNextClick(e) {
|
||||
e.preventDefault();
|
||||
if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
|
||||
swiper.slideNext();
|
||||
emit('navigationNext');
|
||||
}
|
||||
function init() {
|
||||
const params = swiper.params.navigation;
|
||||
swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
|
||||
nextEl: 'swiper-button-next',
|
||||
prevEl: 'swiper-button-prev'
|
||||
});
|
||||
if (!(params.nextEl || params.prevEl)) return;
|
||||
let nextEl = getEl(params.nextEl);
|
||||
let prevEl = getEl(params.prevEl);
|
||||
Object.assign(swiper.navigation, {
|
||||
nextEl,
|
||||
prevEl
|
||||
});
|
||||
nextEl = makeElementsArray(nextEl);
|
||||
prevEl = makeElementsArray(prevEl);
|
||||
const initButton = (el, dir) => {
|
||||
if (el) {
|
||||
el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
|
||||
}
|
||||
if (!swiper.enabled && el) {
|
||||
el.classList.add(...params.lockClass.split(' '));
|
||||
}
|
||||
};
|
||||
nextEl.forEach(el => initButton(el, 'next'));
|
||||
prevEl.forEach(el => initButton(el, 'prev'));
|
||||
}
|
||||
function destroy() {
|
||||
let {
|
||||
nextEl,
|
||||
prevEl
|
||||
} = swiper.navigation;
|
||||
nextEl = makeElementsArray(nextEl);
|
||||
prevEl = makeElementsArray(prevEl);
|
||||
const destroyButton = (el, dir) => {
|
||||
el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
|
||||
el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
|
||||
};
|
||||
nextEl.forEach(el => destroyButton(el, 'next'));
|
||||
prevEl.forEach(el => destroyButton(el, 'prev'));
|
||||
}
|
||||
on('init', () => {
|
||||
if (swiper.params.navigation.enabled === false) {
|
||||
// eslint-disable-next-line
|
||||
disable();
|
||||
} else {
|
||||
init();
|
||||
update();
|
||||
}
|
||||
});
|
||||
on('toEdge fromEdge lock unlock', () => {
|
||||
update();
|
||||
});
|
||||
on('destroy', () => {
|
||||
destroy();
|
||||
});
|
||||
on('enable disable', () => {
|
||||
let {
|
||||
nextEl,
|
||||
prevEl
|
||||
} = swiper.navigation;
|
||||
nextEl = makeElementsArray(nextEl);
|
||||
prevEl = makeElementsArray(prevEl);
|
||||
[...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.navigation.lockClass));
|
||||
});
|
||||
on('click', (_s, e) => {
|
||||
let {
|
||||
nextEl,
|
||||
prevEl
|
||||
} = swiper.navigation;
|
||||
nextEl = makeElementsArray(nextEl);
|
||||
prevEl = makeElementsArray(prevEl);
|
||||
const targetEl = e.target;
|
||||
if (swiper.params.navigation.hideOnClick && !prevEl.includes(targetEl) && !nextEl.includes(targetEl)) {
|
||||
if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
|
||||
let isHidden;
|
||||
if (nextEl.length) {
|
||||
isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
|
||||
} else if (prevEl.length) {
|
||||
isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
|
||||
}
|
||||
if (isHidden === true) {
|
||||
emit('navigationShow');
|
||||
} else {
|
||||
emit('navigationHide');
|
||||
}
|
||||
[...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
|
||||
}
|
||||
});
|
||||
const enable = () => {
|
||||
swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
|
||||
init();
|
||||
update();
|
||||
};
|
||||
const disable = () => {
|
||||
swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
|
||||
destroy();
|
||||
};
|
||||
Object.assign(swiper.navigation, {
|
||||
enable,
|
||||
disable,
|
||||
update,
|
||||
init,
|
||||
destroy
|
||||
});
|
||||
}
|
||||
64
f_scripts/shared/swiper/modules/navigation/navigation.less
Normal file
64
f_scripts/shared/swiper/modules/navigation/navigation.less
Normal file
@@ -0,0 +1,64 @@
|
||||
@import url('../../swiper-vars.less');
|
||||
|
||||
:root {
|
||||
--swiper-navigation-size: 44px;
|
||||
/*
|
||||
--swiper-navigation-top-offset: 50%;
|
||||
--swiper-navigation-sides-offset: 10px;
|
||||
--swiper-navigation-color: var(--swiper-theme-color);
|
||||
*/
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
position: absolute;
|
||||
top: var(--swiper-navigation-top-offset, 50%);
|
||||
width: calc(var(--swiper-navigation-size) / 44 * 27);
|
||||
height: var(--swiper-navigation-size);
|
||||
margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
|
||||
z-index: 10;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--swiper-navigation-color, var(--swiper-theme-color));
|
||||
&.swiper-button-disabled {
|
||||
opacity: 0.35;
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
&.swiper-button-hidden {
|
||||
opacity: 0;
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
.swiper-navigation-disabled & {
|
||||
display: none !important;
|
||||
}
|
||||
&:after {
|
||||
font-family: swiper-icons;
|
||||
font-size: var(--swiper-navigation-size);
|
||||
text-transform: none !important;
|
||||
letter-spacing: 0;
|
||||
font-variant: initial;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-rtl .swiper-button-next {
|
||||
&:after {
|
||||
content: 'prev';
|
||||
}
|
||||
left: var(--swiper-navigation-sides-offset, 10px);
|
||||
right: auto;
|
||||
}
|
||||
.swiper-button-next,
|
||||
.swiper-rtl .swiper-button-prev {
|
||||
&:after {
|
||||
content: 'next';
|
||||
}
|
||||
right: var(--swiper-navigation-sides-offset, 10px);
|
||||
left: auto;
|
||||
}
|
||||
.swiper-button-lock {
|
||||
display: none;
|
||||
}
|
||||
1
f_scripts/shared/swiper/modules/navigation/navigation.min.css
vendored
Normal file
1
f_scripts/shared/swiper/modules/navigation/navigation.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{position:absolute;top:var(--swiper-navigation-top-offset,50%);width:calc(var(--swiper-navigation-size)/ 44 * 27);height:var(--swiper-navigation-size);margin-top:calc(0px - (var(--swiper-navigation-size)/ 2));z-index:10;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--swiper-navigation-color,var(--swiper-theme-color))}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{opacity:0;cursor:auto;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);text-transform:none!important;letter-spacing:0;font-variant:initial;line-height:1}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:var(--swiper-navigation-sides-offset,10px);right:auto}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:'prev'}.swiper-button-next,.swiper-rtl .swiper-button-prev{right:var(--swiper-navigation-sides-offset,10px);left:auto}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:'next'}.swiper-button-lock{display:none}
|
||||
65
f_scripts/shared/swiper/modules/navigation/navigation.scss
Normal file
65
f_scripts/shared/swiper/modules/navigation/navigation.scss
Normal file
@@ -0,0 +1,65 @@
|
||||
@import '../../swiper-vars.scss';
|
||||
@at-root {
|
||||
:root {
|
||||
--swiper-navigation-size: 44px;
|
||||
/*
|
||||
--swiper-navigation-top-offset: 50%;
|
||||
--swiper-navigation-sides-offset: 10px;
|
||||
--swiper-navigation-color: var(--swiper-theme-color);
|
||||
*/
|
||||
}
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-button-next {
|
||||
position: absolute;
|
||||
top: var(--swiper-navigation-top-offset, 50%);
|
||||
width: calc(var(--swiper-navigation-size) / 44 * 27);
|
||||
height: var(--swiper-navigation-size);
|
||||
margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
|
||||
z-index: 10;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--swiper-navigation-color, var(--swiper-theme-color));
|
||||
&.swiper-button-disabled {
|
||||
opacity: 0.35;
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
&.swiper-button-hidden {
|
||||
opacity: 0;
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
.swiper-navigation-disabled & {
|
||||
display: none !important;
|
||||
}
|
||||
&:after {
|
||||
font-family: swiper-icons;
|
||||
font-size: var(--swiper-navigation-size);
|
||||
text-transform: none !important;
|
||||
letter-spacing: 0;
|
||||
font-variant: initial;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
.swiper-button-prev,
|
||||
.swiper-rtl .swiper-button-next {
|
||||
&:after {
|
||||
content: 'prev';
|
||||
}
|
||||
left: var(--swiper-navigation-sides-offset, 10px);
|
||||
right: auto;
|
||||
}
|
||||
.swiper-button-next,
|
||||
.swiper-rtl .swiper-button-prev {
|
||||
&:after {
|
||||
content: 'next';
|
||||
}
|
||||
right: var(--swiper-navigation-sides-offset, 10px);
|
||||
left: auto;
|
||||
}
|
||||
.swiper-button-lock {
|
||||
display: none;
|
||||
}
|
||||
Reference in New Issue
Block a user