@codeperate/cdp-ui-library
Version:
Codeperate UI Library
355 lines (351 loc) • 13.4 kB
JavaScript
import { r as registerInstance, h, H as Host, a as getElement } from './index-de893d6b.js';
import { d as deepAssign } from './deep-assign-b22cb0e3.js';
/**
* Tokenize input string.
*/
function lexer(str) {
var tokens = [];
var i = 0;
while (i < str.length) {
var char = str[i];
if (char === "*" || char === "+" || char === "?") {
tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
continue;
}
if (char === "\\") {
tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
continue;
}
if (char === "{") {
tokens.push({ type: "OPEN", index: i, value: str[i++] });
continue;
}
if (char === "}") {
tokens.push({ type: "CLOSE", index: i, value: str[i++] });
continue;
}
if (char === ":") {
var name = "";
var j = i + 1;
while (j < str.length) {
var code = str.charCodeAt(j);
if (
// `0-9`
(code >= 48 && code <= 57) ||
// `A-Z`
(code >= 65 && code <= 90) ||
// `a-z`
(code >= 97 && code <= 122) ||
// `_`
code === 95) {
name += str[j++];
continue;
}
break;
}
if (!name)
throw new TypeError("Missing parameter name at " + i);
tokens.push({ type: "NAME", index: i, value: name });
i = j;
continue;
}
if (char === "(") {
var count = 1;
var pattern = "";
var j = i + 1;
if (str[j] === "?") {
throw new TypeError("Pattern cannot start with \"?\" at " + j);
}
while (j < str.length) {
if (str[j] === "\\") {
pattern += str[j++] + str[j++];
continue;
}
if (str[j] === ")") {
count--;
if (count === 0) {
j++;
break;
}
}
else if (str[j] === "(") {
count++;
if (str[j + 1] !== "?") {
throw new TypeError("Capturing groups are not allowed at " + j);
}
}
pattern += str[j++];
}
if (count)
throw new TypeError("Unbalanced pattern at " + i);
if (!pattern)
throw new TypeError("Missing pattern at " + i);
tokens.push({ type: "PATTERN", index: i, value: pattern });
i = j;
continue;
}
tokens.push({ type: "CHAR", index: i, value: str[i++] });
}
tokens.push({ type: "END", index: i, value: "" });
return tokens;
}
/**
* Parse a string for the raw tokens.
*/
function parse(str, options) {
if (options === void 0) { options = {}; }
var tokens = lexer(str);
var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a;
var defaultPattern = "[^" + escapeString(options.delimiter || "/#?") + "]+?";
var result = [];
var key = 0;
var i = 0;
var path = "";
var tryConsume = function (type) {
if (i < tokens.length && tokens[i].type === type)
return tokens[i++].value;
};
var mustConsume = function (type) {
var value = tryConsume(type);
if (value !== undefined)
return value;
var _a = tokens[i], nextType = _a.type, index = _a.index;
throw new TypeError("Unexpected " + nextType + " at " + index + ", expected " + type);
};
var consumeText = function () {
var result = "";
var value;
// tslint:disable-next-line
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
result += value;
}
return result;
};
while (i < tokens.length) {
var char = tryConsume("CHAR");
var name = tryConsume("NAME");
var pattern = tryConsume("PATTERN");
if (name || pattern) {
var prefix = char || "";
if (prefixes.indexOf(prefix) === -1) {
path += prefix;
prefix = "";
}
if (path) {
result.push(path);
path = "";
}
result.push({
name: name || key++,
prefix: prefix,
suffix: "",
pattern: pattern || defaultPattern,
modifier: tryConsume("MODIFIER") || ""
});
continue;
}
var value = char || tryConsume("ESCAPED_CHAR");
if (value) {
path += value;
continue;
}
if (path) {
result.push(path);
path = "";
}
var open = tryConsume("OPEN");
if (open) {
var prefix = consumeText();
var name_1 = tryConsume("NAME") || "";
var pattern_1 = tryConsume("PATTERN") || "";
var suffix = consumeText();
mustConsume("CLOSE");
result.push({
name: name_1 || (pattern_1 ? key++ : ""),
pattern: name_1 && !pattern_1 ? defaultPattern : pattern_1,
prefix: prefix,
suffix: suffix,
modifier: tryConsume("MODIFIER") || ""
});
continue;
}
mustConsume("END");
}
return result;
}
/**
* Escape a regular expression string.
*/
function escapeString(str) {
return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
}
/**
* Get the flags for a regexp from the options.
*/
function flags(options) {
return options && options.sensitive ? "" : "i";
}
/**
* Pull out keys from a regexp.
*/
function regexpToRegexp(path, keys) {
if (!keys)
return path;
var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
var index = 0;
var execResult = groupsRegex.exec(path.source);
while (execResult) {
keys.push({
// Use parenthesized substring match if available, index otherwise
name: execResult[1] || index++,
prefix: "",
suffix: "",
modifier: "",
pattern: ""
});
execResult = groupsRegex.exec(path.source);
}
return path;
}
/**
* Transform an array into a regexp.
*/
function arrayToRegexp(paths, keys, options) {
var parts = paths.map(function (path) { return pathToRegexp(path, keys, options).source; });
return new RegExp("(?:" + parts.join("|") + ")", flags(options));
}
/**
* Create a path regexp from string input.
*/
function stringToRegexp(path, keys, options) {
return tokensToRegexp(parse(path, options), keys, options);
}
/**
* Expose a function for taking tokens and returning a RegExp.
*/
function tokensToRegexp(tokens, keys, options) {
if (options === void 0) { options = {}; }
var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d;
var endsWith = "[" + escapeString(options.endsWith || "") + "]|$";
var delimiter = "[" + escapeString(options.delimiter || "/#?") + "]";
var route = start ? "^" : "";
// Iterate over the tokens and create our regexp string.
for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
var token = tokens_1[_i];
if (typeof token === "string") {
route += escapeString(encode(token));
}
else {
var prefix = escapeString(encode(token.prefix));
var suffix = escapeString(encode(token.suffix));
if (token.pattern) {
if (keys)
keys.push(token);
if (prefix || suffix) {
if (token.modifier === "+" || token.modifier === "*") {
var mod = token.modifier === "*" ? "?" : "";
route += "(?:" + prefix + "((?:" + token.pattern + ")(?:" + suffix + prefix + "(?:" + token.pattern + "))*)" + suffix + ")" + mod;
}
else {
route += "(?:" + prefix + "(" + token.pattern + ")" + suffix + ")" + token.modifier;
}
}
else {
route += "(" + token.pattern + ")" + token.modifier;
}
}
else {
route += "(?:" + prefix + suffix + ")" + token.modifier;
}
}
}
if (end) {
if (!strict)
route += delimiter + "?";
route += !options.endsWith ? "$" : "(?=" + endsWith + ")";
}
else {
var endToken = tokens[tokens.length - 1];
var isEndDelimited = typeof endToken === "string"
? delimiter.indexOf(endToken[endToken.length - 1]) > -1
: // tslint:disable-next-line
endToken === undefined;
if (!strict) {
route += "(?:" + delimiter + "(?=" + endsWith + "))?";
}
if (!isEndDelimited) {
route += "(?=" + delimiter + "|" + endsWith + ")";
}
}
return new RegExp(route, flags(options));
}
/**
* Normalize the given path string, returning a regular expression.
*
* An empty array can be passed in for the keys, which will hold the
* placeholder key descriptions. For example, using `/user/:id`, `keys` will
* contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
*/
function pathToRegexp(path, keys, options) {
if (path instanceof RegExp)
return regexpToRegexp(path, keys);
if (Array.isArray(path))
return arrayToRegexp(path, keys, options);
return stringToRegexp(path, keys, options);
}
var __rest = (undefined && undefined.__rest) || function (s, e) {
var t = {};
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
const CdpMenuList = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.defaultConfig = {
menuItems: [],
anchorPropsFn: null,
classList: {
host: 'grid grid-cols-1 gap-y-2 auto-rows-min',
menuItem: 'py-2 px-4 hover:bg-light-blue-600 hover:text-white rounded-md grid grid-cols-[max-content,1fr,max-content] items-center gap-4 cursor-pointer',
menuItemActive: 'py-2 px-4 bg-light-blue-600 text-white rounded-md grid grid-cols-[max-content,1fr,max-content] items-center gap-4 cursor-pointer',
subMenuItem: 'py-1 px-4 hover:bg-light-blue-600 hover:text-white rounded-md grid grid-cols-[max-content,1fr,max-content] items-center gap-4',
subMenuItemActive: 'py-1 px-4 bg-light-blue-600 text-white rounded-md grid grid-cols-[max-content,1fr,max-content] items-center gap-4',
subMenuWrapper: 'grid grid-cols-1 gap-y-1 mt-2 pl-4',
},
};
}
componentWillLoad() {
this._config = deepAssign(this.config, this.defaultConfig);
}
isActive(href, activePath) {
const regex = pathToRegexp(href);
if (activePath.match(regex))
return true;
return false;
}
render() {
const { classList, anchorPropsFn, menuItems } = this._config;
const activePath = this.props.activePath;
return (h(Host, { class: classList.host }, menuItems.map((_a) => {
var { name, isActive, icon, indicator } = _a, props = __rest(_a, ["name", "isActive", "icon", "indicator"]);
let href = props['href'];
let expand = props['expand'];
let active = isActive ? isActive(activePath) : this.isActive(href, activePath);
if (props['nested'])
return (h("cdp-accordion", { props: { display: expand ? expand : active }, config: { toggle: !href } }, h("a", Object.assign({ slot: "accordion", class: active ? classList.menuItemActive : classList.menuItem }, (href ? anchorPropsFn(href) : {})), icon ? icon(active) : '', name, indicator ? indicator(active) : ''), h("div", { class: classList.subMenuWrapper }, props['nested'].map(({ name, href, indicator, icon, isActive }) => {
let active = isActive ? isActive(activePath) : this.isActive(href, activePath);
return (h("a", Object.assign({}, anchorPropsFn(href), { class: active ? classList.subMenuItemActive : classList.subMenuItem }), icon ? icon(active) : '', name, indicator ? indicator(active) : ''));
}))));
return (h("a", Object.assign({}, anchorPropsFn(href), { class: active ? classList.menuItemActive : classList.menuItem }), icon ? icon(active) : '', name, indicator ? indicator(active) : ''));
})));
}
get rootEl() { return getElement(this); }
};
export { CdpMenuList as cdp_menu_list };