yugrid
Version:
yugrid 现代化响应式 Grid 布局系统,支持 ES Module 和 CommonJS
505 lines (491 loc) • 14.6 kB
JavaScript
/**
* YuGrid v1.0.3
* 现代化响应式 Grid 布局系统
* (c) 2024 广州迅羽软件科技有限公司
* Released under the CC BY-NC-SA 4.0 License.
*/
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var n = 0,
F = function () {};
return {
s: F,
n: function () {
return n >= r.length ? {
done: !0
} : {
done: !1,
value: r[n++]
};
},
e: function (r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function () {
t = t.call(r);
},
n: function () {
var r = t.next();
return a = r.done, r;
},
e: function (r) {
u = !0, o = r;
},
f: function () {
try {
a || null == t.return || t.return();
} finally {
if (u) throw o;
}
}
};
}
function _defineProperty(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) return;
f = !1;
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
/**
* YuGrid - 响应式 Grid 布局系统
* 支持 12 列栅格系统,响应式断点,灵活的间距配置
*/
// 默认断点配置
var DEFAULT_BREAKPOINTS = {
xs: 0,
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1400
};
// 默认容器最大宽度
var DEFAULT_CONTAINER_MAX_WIDTHS = {
sm: 540,
md: 720,
lg: 960,
xl: 1140,
xxl: 1320
};
/**
* 获取当前屏幕断点
*/
function getCurrentBreakpoint() {
var breakpoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_BREAKPOINTS;
var width = window.innerWidth;
var sortedBreakpoints = Object.entries(breakpoints).sort(function (_ref, _ref2) {
var _ref3 = _slicedToArray(_ref, 2),
a = _ref3[1];
var _ref4 = _slicedToArray(_ref2, 2),
b = _ref4[1];
return b - a;
});
var _iterator = _createForOfIteratorHelper(sortedBreakpoints),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _slicedToArray(_step.value, 2),
name = _step$value[0],
minWidth = _step$value[1];
if (width >= minWidth) {
return name;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return 'xs';
}
/**
* Container 组件
*/
var YuContainer = /*#__PURE__*/function () {
function YuContainer(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, YuContainer);
this.element = typeof element === 'string' ? document.querySelector(element) : element;
this.options = _objectSpread2({
fluid: false,
maxWidths: DEFAULT_CONTAINER_MAX_WIDTHS,
breakpoints: DEFAULT_BREAKPOINTS
}, options);
this.init();
}
return _createClass(YuContainer, [{
key: "init",
value: function init() {
this.element.classList.add('yu-container');
if (this.options.fluid) {
this.element.classList.add('yu-container-fluid');
}
this.updateStyles();
this.bindEvents();
}
}, {
key: "updateStyles",
value: function updateStyles() {
if (!this.options.fluid) {
var currentBreakpoint = getCurrentBreakpoint(this.options.breakpoints);
var maxWidth = this.options.maxWidths[currentBreakpoint];
if (maxWidth) {
this.element.style.maxWidth = "".concat(maxWidth, "px");
} else {
this.element.style.maxWidth = '100%';
}
}
}
}, {
key: "bindEvents",
value: function bindEvents() {
var _this = this;
window.addEventListener('resize', function () {
_this.updateStyles();
});
}
}]);
}();
/**
* Row 组件
*/
var YuRow = /*#__PURE__*/function () {
function YuRow(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, YuRow);
this.element = typeof element === 'string' ? document.querySelector(element) : element;
this.options = _objectSpread2({
gutter: 0,
justify: 'start',
align: 'top',
wrap: true
}, options);
this.init();
}
return _createClass(YuRow, [{
key: "init",
value: function init() {
this.element.classList.add('yu-row');
// 设置对齐方式
if (this.options.justify !== 'start') {
this.element.classList.add("yu-row-justify-".concat(this.options.justify));
}
if (this.options.align !== 'top') {
this.element.classList.add("yu-row-align-".concat(this.options.align));
}
if (!this.options.wrap) {
this.element.classList.add('yu-row-nowrap');
}
this.updateGutter();
}
}, {
key: "updateGutter",
value: function updateGutter() {
if (this.options.gutter > 0) {
var halfGutter = this.options.gutter / 2;
this.element.style.marginLeft = "-".concat(halfGutter, "px");
this.element.style.marginRight = "-".concat(halfGutter, "px");
// 为所有子列设置 padding
var cols = this.element.querySelectorAll('.yu-col');
cols.forEach(function (col) {
col.style.paddingLeft = "".concat(halfGutter, "px");
col.style.paddingRight = "".concat(halfGutter, "px");
});
}
}
}, {
key: "setGutter",
value: function setGutter(gutter) {
this.options.gutter = gutter;
this.updateGutter();
}
}]);
}();
/**
* Col 组件
*/
var YuCol = /*#__PURE__*/function () {
function YuCol(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, YuCol);
this.element = typeof element === 'string' ? document.querySelector(element) : element;
this.options = _objectSpread2({
span: 24,
offset: 0,
push: 0,
pull: 0,
order: 0,
flex: null,
breakpoints: DEFAULT_BREAKPOINTS,
responsive: {}
}, options);
this.init();
}
return _createClass(YuCol, [{
key: "init",
value: function init() {
this.element.classList.add('yu-col');
this.updateClasses();
this.bindEvents();
}
}, {
key: "updateClasses",
value: function updateClasses() {
// 清除旧的类名
var classList = this.element.classList;
var oldClasses = Array.from(classList).filter(function (cls) {
return cls.startsWith('yu-col-');
});
oldClasses.forEach(function (cls) {
return classList.remove(cls);
});
var currentBreakpoint = getCurrentBreakpoint(this.options.breakpoints);
var config = this.getConfigForBreakpoint(currentBreakpoint);
// 设置基础类名
if (config.span !== undefined) {
classList.add("yu-col-".concat(config.span));
}
if (config.offset > 0) {
classList.add("yu-col-offset-".concat(config.offset));
}
if (config.push > 0) {
classList.add("yu-col-push-".concat(config.push));
}
if (config.pull > 0) {
classList.add("yu-col-pull-".concat(config.pull));
}
if (config.order !== 0) {
this.element.style.order = config.order;
}
if (config.flex) {
this.element.style.flex = config.flex;
}
}
}, {
key: "getConfigForBreakpoint",
value: function getConfigForBreakpoint(breakpoint) {
var breakpointOrder = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
var currentIndex = breakpointOrder.indexOf(breakpoint);
// 从当前断点开始向下查找配置
for (var i = currentIndex; i < breakpointOrder.length; i++) {
var bp = breakpointOrder[i];
if (this.options.responsive[bp]) {
return _objectSpread2(_objectSpread2({}, this.options), this.options.responsive[bp]);
}
}
return this.options;
}
}, {
key: "bindEvents",
value: function bindEvents() {
var _this2 = this;
window.addEventListener('resize', function () {
_this2.updateClasses();
});
}
}, {
key: "setSpan",
value: function setSpan(span) {
var breakpoint = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (breakpoint) {
this.options.responsive[breakpoint] = _objectSpread2(_objectSpread2({}, this.options.responsive[breakpoint]), {}, {
span: span
});
} else {
this.options.span = span;
}
this.updateClasses();
}
}]);
}();
/**
* 工厂函数
*/
function createContainer(element, options) {
return new YuContainer(element, options);
}
function createRow(element, options) {
return new YuRow(element, options);
}
function createCol(element, options) {
return new YuCol(element, options);
}
/**
* 批量初始化
*/
function initGrid() {
var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '[data-yu-grid]';
var elements = document.querySelectorAll(selector);
var instances = [];
elements.forEach(function (element) {
var type = element.dataset.yuGrid;
var options = element.dataset.yuOptions ? JSON.parse(element.dataset.yuOptions) : {};
var instance;
switch (type) {
case 'container':
instance = new YuContainer(element, options);
break;
case 'row':
instance = new YuRow(element, options);
break;
case 'col':
instance = new YuCol(element, options);
break;
}
if (instance) {
instances.push(instance);
}
});
return instances;
}
// 导出
var YuGrid = {
Container: YuContainer,
Row: YuRow,
Col: YuCol,
createContainer: createContainer,
createRow: createRow,
createCol: createCol,
initGrid: initGrid,
DEFAULT_BREAKPOINTS: DEFAULT_BREAKPOINTS,
DEFAULT_CONTAINER_MAX_WIDTHS: DEFAULT_CONTAINER_MAX_WIDTHS,
getCurrentBreakpoint: getCurrentBreakpoint
};
// 导出处理
if (typeof module !== 'undefined' && module.exports) {
// CommonJS 环境
module.exports = YuGrid;
module.exports["default"] = YuGrid;
} else if (typeof window !== 'undefined') {
// 浏览器环境
window.YuGrid = YuGrid;
}
// ES Module 导出(仅在支持的环境中)
if (typeof exports !== 'undefined') {
try {
exports["default"] = YuGrid;
exports.YuContainer = YuContainer;
exports.YuRow = YuRow;
exports.YuCol = YuCol;
exports.createContainer = createContainer;
exports.createRow = createRow;
exports.createCol = createCol;
exports.initGrid = initGrid;
exports.DEFAULT_BREAKPOINTS = DEFAULT_BREAKPOINTS;
exports.DEFAULT_CONTAINER_MAX_WIDTHS = DEFAULT_CONTAINER_MAX_WIDTHS;
exports.getCurrentBreakpoint = getCurrentBreakpoint;
} catch (e) {
// 忽略导出错误
}
}