UNPKG

react-dynamiq-ui

Version:

this is react dynamic ui help you to avoide repeating yourself. it's very easy to customize the style and access your data dynamically without mapping

1,414 lines (1,403 loc) 107 kB
'use strict'; var jsxRuntime = require('react/jsx-runtime'); var react = require('react'); const PaginationBase = ({ children, baseProps }) => { return (jsxRuntime.jsx("div", { ...(baseProps ? { ...baseProps, ...(baseProps.className ? { className: `flex flex-col md:flex-row justify-between items-start md:items-center space-y-3 md:space-y-0 p-4 bg-white dark:bg-dark ${baseProps.className}`, } : { className: `flex flex-col md:flex-row justify-between items-start md:items-center space-y-3 md:space-y-0 p-4 bg-white dark:bg-dark`, }), } : { className: `flex flex-col md:flex-row justify-between items-start md:items-center space-y-3 md:space-y-0 p-4 bg-white dark:bg-dark`, }), children: children })); }; const PaginationLeftBase = ({ children, leftBaseProps, }) => { return (jsxRuntime.jsx("div", { ...(leftBaseProps ? { ...leftBaseProps, ...(leftBaseProps.className ? { className: `flex items-center gap-x-3 ${leftBaseProps.className}`, } : { className: `flex items-center gap-x-3`, }), } : { className: `flex items-center gap-x-3`, }), children: children })); }; const PaginationRightBase = ({ children, rightBaseProps, }) => { return (jsxRuntime.jsx("ul", { ...(rightBaseProps ? { ...rightBaseProps, ...(rightBaseProps.className ? { className: `inline-flex items-stretch -space-x-px" ${rightBaseProps.className}`, } : { className: `inline-flex items-stretch -space-x-px"`, }), } : { className: `inline-flex items-stretch -space-x-px"`, }), children: children })); }; const PaginationController = ({ pagination }) => { return (jsxRuntime.jsxs(PaginationBase, { baseProps: pagination?.baseProps, children: [jsxRuntime.jsxs(PaginationLeftBase, { leftBaseProps: pagination?.leftBaseProps, children: [jsxRuntime.jsxs("span", { className: "text-sm font-normal text-gray-500 dark:text-white", children: ["Showing", jsxRuntime.jsxs("span", { className: "font-semibold text-gray-900 dark:text-white", children: [pagination?.page || 1, "-", pagination?.totalPages || 0] }), "of", jsxRuntime.jsx("span", { className: "font-semibold text-gray-900 dark:text-white", children: pagination?.totalPages })] }), pagination.per_pageComponent] }), jsxRuntime.jsxs(PaginationRightBase, { rightBaseProps: pagination?.rightBaseProps, children: [jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { onClick: () => { pagination.handlePageChange(pagination.page - 1); }, disabled: pagination?.page <= 1, className: "flex items-center justify-center h-full py-1.5 px-3 cursor-pointer disabled:cursor-not-allowed ml-0 text-gray-500 dark:text-white bg-white dark:bg-dark rounded-l-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700", children: [jsxRuntime.jsx("span", { className: "sr-only", children: "Previous" }), jsxRuntime.jsx("svg", { className: "w-5 h-5", "aria-hidden": "true", fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z", clipRule: "evenodd" }) })] }) }), pagination?.totalPages <= 5 ? (Array.from({ length: pagination?.totalPages }, (_, index) => (jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(index + 1); }, className: "cursor-pointer", children: jsxRuntime.jsx("span", { className: `flex items-center justify-center text-sm py-2 px-3 leading-tight ${index + 1 === pagination.page ? "bg-gray-300 dark:bg-gray-950" : "text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300 hover:bg-gray-100"}`, children: index + 1 }) }, index)))) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(1); }, className: "cursor-pointer", children: jsxRuntime.jsx("span", { className: `flex items-center justify-center text-sm py-2 px-3 leading-tight ${pagination?.page === 1 ? "bg-gray-300 dark:bg-gray-950" : "text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300 hover:bg-gray-100"}`, children: "1" }) }), pagination?.page > 3 && (jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(pagination.page - 1); }, className: "cursor-pointer", children: jsxRuntime.jsx("span", { className: "flex items-center justify-center text-sm py-2 px-3 leading-tight text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300", children: "..." }) })), Array.from({ length: 3 }, (_, i) => (jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(pagination?.page - 1 + i); }, className: "cursor-pointer", children: pagination?.page - 1 + i > 1 && pagination?.page - 1 + i < pagination?.totalPages && (jsxRuntime.jsx("span", { className: `flex items-center justify-center text-sm py-2 px-3 leading-tight ${pagination?.page === pagination?.page - 1 + i ? "bg-gray-300 dark:bg-gray-950" : "text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300 hover:bg-gray-100"}`, children: pagination?.page - 1 + i })) }, pagination?.page - 1 + i))), pagination?.page < pagination?.totalPages - 2 && (jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(pagination.page + 1); }, className: "cursor-pointer", children: jsxRuntime.jsx("span", { className: "flex items-center justify-center text-sm py-2 px-3 leading-tight text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300", children: "..." }) })), jsxRuntime.jsx("li", { onClick: () => { pagination.handlePageChange(pagination?.totalPages || 0); }, className: "cursor-pointer", children: jsxRuntime.jsx("span", { className: `flex items-center justify-center text-sm py-2 px-3 leading-tight ${pagination?.page === pagination?.totalPages ? "bg-gray-300 dark:bg-gray-950" : "text-gray-500 dark:text-white bg-white dark:bg-dark border border-gray-300 hover:bg-gray-100"}`, children: pagination?.totalPages }) })] })), jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("button", { onClick: () => { pagination.handlePageChange(pagination.page + 1); }, disabled: pagination?.page >= pagination?.totalPages, className: "flex items-center justify-center h-full py-1.5 px-3 cursor-pointer disabled:cursor-not-allowed leading-tight text-gray-500 dark:text-white bg-white dark:bg-dark rounded-r-lg border border-gray-300 hover:bg-gray-100 hover:text-gray-700", children: [jsxRuntime.jsx("span", { className: "sr-only", children: "Next" }), jsxRuntime.jsx("svg", { className: "w-5 h-5", "aria-hidden": "true", fill: "currentColor", viewBox: "0 0 20 20", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z", clipRule: "evenodd" }) })] }) })] })] })); }; function getNestedValue(obj, path) { const keys = path?.split("."); const resultValue = keys?.reduce((acc, key) => { return acc && acc[key] !== undefined ? acc[key] : undefined; }, obj); if (typeof resultValue === "number") { return Number(resultValue); } return resultValue?.toString(); } function handlePropsDynamic(props, item) { try { const resultObj = {}; Object.entries(props).forEach(([key, value]) => { if (typeof value === "string") { let newValue = value; const expressionRegex = /\{([^{}]+?)\}/g; let match; while ((match = expressionRegex.exec(newValue)) !== null) { const expression = match[1]; const evaluatedResult = evaluateTernaryExpression(expression, item); newValue = newValue.replace(match[0], evaluatedResult); } const pathRegex = /\[([^\]]+)\]/g; while ((match = pathRegex.exec(newValue)) !== null) { const path = match[1]; const evaluatedPath = getNestedValue(item, path); newValue = newValue.replace(match[0], evaluatedPath); } resultObj[key] = newValue; } else { resultObj[key] = value; } }); return resultObj; } catch (error) { return {}; } } function evaluateTernaryExpression(expression, item) { try { const dynamicPathRegex = /\[([^\]]+)\]/g; let evaluatedExpression = expression; let match; while ((match = dynamicPathRegex.exec(expression)) !== null) { const dynamicPath = match[1]; const dynamicValue = getNestedValue(item, dynamicPath); evaluatedExpression = evaluatedExpression.replace(match[0], JSON.stringify(dynamicValue)); } const result = new Function("item", ` with (item) { return ${evaluatedExpression}; // The ternary condition itself } `)(item); return result; } catch (error) { return expression; } } function generateDynamicLink(href, item) { const regex = /\[([^\]]+)\]/g; return href.replace(regex, (_, key) => { const keys = key.split("."); let value = item; for (let k of keys) { value = value && value[k]; } return value || ""; }); } function handleJoined(column, item) { const joinedValues = column?.join?.map((path) => { return getNestedValue(item, path) || ""; }); return joinedValues?.join(" ")?.trim(); } async function handleOptionChnage(value, apiLink, onRes, onCatch, data) { try { const bodyData = { item: data, value: value, }; const res = await fetch(apiLink, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(bodyData), }); if (res.ok) { if (onRes) { onRes([]); } } } catch (error) { if (onCatch) { onCatch(error); } } } function findTrueContion(column, item) { const findTrueColumn = column?.condtions?.find((condi) => { if (typeof condi.condtion === "boolean") { return condi.condtion === true; } if (Array.isArray(condi.condtion.compare)) { const [getFirstValue, getSecondValue] = condi.condtion.compare; let firstValue = getFirstValue; if (getFirstValue?.startsWith("[")) { firstValue = getFirstValue?.slice(1, -1); firstValue = getNestedValue(item, firstValue); } let secondValue = getSecondValue; if (getSecondValue?.startsWith("[")) { secondValue = getSecondValue?.slice(1, -1); secondValue = getNestedValue(item, secondValue); } if (secondValue !== undefined) { return firstValue === secondValue; } return (firstValue !== undefined && firstValue !== null && firstValue !== "" && firstValue !== "undefined"); } return false; }); return findTrueColumn; } const Chip = ({ className, item }) => { return (jsxRuntime.jsx("span", { ...(className ? { ...handlePropsDynamic({ className: `${className} inline-flex w-2 h-2 rounded-full`, }, item), ...(className ? {} : { className: `${className} inline-flex w-2 h-2 rounded-full text-red-700 bg-red-500`, }), } : { className: `${className} inline-flex w-2 h-2 rounded-full text-red-700 bg-red-500`, }) })); }; function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n} const CLASS_PART_SEPARATOR = '-'; const createClassGroupUtils = config => { const classMap = createClassMap(config); const { conflictingClassGroups, conflictingClassGroupModifiers } = config; const getClassGroupId = className => { const classParts = className.split(CLASS_PART_SEPARATOR); // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and remove it from classParts. if (classParts[0] === '' && classParts.length !== 1) { classParts.shift(); } return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className); }; const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => { const conflicts = conflictingClassGroups[classGroupId] || []; if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) { return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]]; } return conflicts; }; return { getClassGroupId, getConflictingClassGroupIds }; }; const getGroupRecursive = (classParts, classPartObject) => { if (classParts.length === 0) { return classPartObject.classGroupId; } const currentClassPart = classParts[0]; const nextClassPartObject = classPartObject.nextPart.get(currentClassPart); const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined; if (classGroupFromNextClassPart) { return classGroupFromNextClassPart; } if (classPartObject.validators.length === 0) { return undefined; } const classRest = classParts.join(CLASS_PART_SEPARATOR); return classPartObject.validators.find(({ validator }) => validator(classRest))?.classGroupId; }; const arbitraryPropertyRegex = /^\[(.+)\]$/; const getGroupIdForArbitraryProperty = className => { if (arbitraryPropertyRegex.test(className)) { const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1]; const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(':')); if (property) { // I use two dots here because one dot is used as prefix for class groups in plugins return 'arbitrary..' + property; } } }; /** * Exported for testing only */ const createClassMap = config => { const { theme, prefix } = config; const classMap = { nextPart: new Map(), validators: [] }; const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix); prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => { processClassesRecursively(classGroup, classMap, classGroupId, theme); }); return classMap; }; const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => { classGroup.forEach(classDefinition => { if (typeof classDefinition === 'string') { const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition); classPartObjectToEdit.classGroupId = classGroupId; return; } if (typeof classDefinition === 'function') { if (isThemeGetter(classDefinition)) { processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme); return; } classPartObject.validators.push({ validator: classDefinition, classGroupId }); return; } Object.entries(classDefinition).forEach(([key, classGroup]) => { processClassesRecursively(classGroup, getPart(classPartObject, key), classGroupId, theme); }); }); }; const getPart = (classPartObject, path) => { let currentClassPartObject = classPartObject; path.split(CLASS_PART_SEPARATOR).forEach(pathPart => { if (!currentClassPartObject.nextPart.has(pathPart)) { currentClassPartObject.nextPart.set(pathPart, { nextPart: new Map(), validators: [] }); } currentClassPartObject = currentClassPartObject.nextPart.get(pathPart); }); return currentClassPartObject; }; const isThemeGetter = func => func.isThemeGetter; const getPrefixedClassGroupEntries = (classGroupEntries, prefix) => { if (!prefix) { return classGroupEntries; } return classGroupEntries.map(([classGroupId, classGroup]) => { const prefixedClassGroup = classGroup.map(classDefinition => { if (typeof classDefinition === 'string') { return prefix + classDefinition; } if (typeof classDefinition === 'object') { return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value])); } return classDefinition; }); return [classGroupId, prefixedClassGroup]; }); }; // LRU cache inspired from hashlru (https://github.com/dominictarr/hashlru/blob/v1.0.4/index.js) but object replaced with Map to improve performance const createLruCache = maxCacheSize => { if (maxCacheSize < 1) { return { get: () => undefined, set: () => {} }; } let cacheSize = 0; let cache = new Map(); let previousCache = new Map(); const update = (key, value) => { cache.set(key, value); cacheSize++; if (cacheSize > maxCacheSize) { cacheSize = 0; previousCache = cache; cache = new Map(); } }; return { get(key) { let value = cache.get(key); if (value !== undefined) { return value; } if ((value = previousCache.get(key)) !== undefined) { update(key, value); return value; } }, set(key, value) { if (cache.has(key)) { cache.set(key, value); } else { update(key, value); } } }; }; const IMPORTANT_MODIFIER = '!'; const createParseClassName = config => { const { separator, experimentalParseClassName } = config; const isSeparatorSingleCharacter = separator.length === 1; const firstSeparatorCharacter = separator[0]; const separatorLength = separator.length; // parseClassName inspired by https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js const parseClassName = className => { const modifiers = []; let bracketDepth = 0; let modifierStart = 0; let postfixModifierPosition; for (let index = 0; index < className.length; index++) { let currentCharacter = className[index]; if (bracketDepth === 0) { if (currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || className.slice(index, index + separatorLength) === separator)) { modifiers.push(className.slice(modifierStart, index)); modifierStart = index + separatorLength; continue; } if (currentCharacter === '/') { postfixModifierPosition = index; continue; } } if (currentCharacter === '[') { bracketDepth++; } else if (currentCharacter === ']') { bracketDepth--; } } const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart); const hasImportantModifier = baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER); const baseClassName = hasImportantModifier ? baseClassNameWithImportantModifier.substring(1) : baseClassNameWithImportantModifier; const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined; return { modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition }; }; if (experimentalParseClassName) { return className => experimentalParseClassName({ className, parseClassName }); } return parseClassName; }; /** * Sorts modifiers according to following schema: * - Predefined modifiers are sorted alphabetically * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it */ const sortModifiers = modifiers => { if (modifiers.length <= 1) { return modifiers; } const sortedModifiers = []; let unsortedModifiers = []; modifiers.forEach(modifier => { const isArbitraryVariant = modifier[0] === '['; if (isArbitraryVariant) { sortedModifiers.push(...unsortedModifiers.sort(), modifier); unsortedModifiers = []; } else { unsortedModifiers.push(modifier); } }); sortedModifiers.push(...unsortedModifiers.sort()); return sortedModifiers; }; const createConfigUtils = config => ({ cache: createLruCache(config.cacheSize), parseClassName: createParseClassName(config), ...createClassGroupUtils(config) }); const SPLIT_CLASSES_REGEX = /\s+/; const mergeClassList = (classList, configUtils) => { const { parseClassName, getClassGroupId, getConflictingClassGroupIds } = configUtils; /** * Set of classGroupIds in following format: * `{importantModifier}{variantModifiers}{classGroupId}` * @example 'float' * @example 'hover:focus:bg-color' * @example 'md:!pr' */ const classGroupsInConflict = []; const classNames = classList.trim().split(SPLIT_CLASSES_REGEX); let result = ''; for (let index = classNames.length - 1; index >= 0; index -= 1) { const originalClassName = classNames[index]; const { modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition } = parseClassName(originalClassName); let hasPostfixModifier = Boolean(maybePostfixModifierPosition); let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName); if (!classGroupId) { if (!hasPostfixModifier) { // Not a Tailwind class result = originalClassName + (result.length > 0 ? ' ' + result : result); continue; } classGroupId = getClassGroupId(baseClassName); if (!classGroupId) { // Not a Tailwind class result = originalClassName + (result.length > 0 ? ' ' + result : result); continue; } hasPostfixModifier = false; } const variantModifier = sortModifiers(modifiers).join(':'); const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier; const classId = modifierId + classGroupId; if (classGroupsInConflict.includes(classId)) { // Tailwind class omitted due to conflict continue; } classGroupsInConflict.push(classId); const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier); for (let i = 0; i < conflictGroups.length; ++i) { const group = conflictGroups[i]; classGroupsInConflict.push(modifierId + group); } // Tailwind class not in conflict result = originalClassName + (result.length > 0 ? ' ' + result : result); } return result; }; /** * The code in this file is copied from https://github.com/lukeed/clsx and modified to suit the needs of tailwind-merge better. * * Specifically: * - Runtime code from https://github.com/lukeed/clsx/blob/v1.2.1/src/index.js * - TypeScript types from https://github.com/lukeed/clsx/blob/v1.2.1/clsx.d.ts * * Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com) */ function twJoin() { let index = 0; let argument; let resolvedValue; let string = ''; while (index < arguments.length) { if (argument = arguments[index++]) { if (resolvedValue = toValue(argument)) { string && (string += ' '); string += resolvedValue; } } } return string; } const toValue = mix => { if (typeof mix === 'string') { return mix; } let resolvedValue; let string = ''; for (let k = 0; k < mix.length; k++) { if (mix[k]) { if (resolvedValue = toValue(mix[k])) { string && (string += ' '); string += resolvedValue; } } } return string; }; function createTailwindMerge(createConfigFirst, ...createConfigRest) { let configUtils; let cacheGet; let cacheSet; let functionToCall = initTailwindMerge; function initTailwindMerge(classList) { const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst()); configUtils = createConfigUtils(config); cacheGet = configUtils.cache.get; cacheSet = configUtils.cache.set; functionToCall = tailwindMerge; return tailwindMerge(classList); } function tailwindMerge(classList) { const cachedResult = cacheGet(classList); if (cachedResult) { return cachedResult; } const result = mergeClassList(classList, configUtils); cacheSet(classList, result); return result; } return function callTailwindMerge() { return functionToCall(twJoin.apply(null, arguments)); }; } const fromTheme = key => { const themeGetter = theme => theme[key] || []; themeGetter.isThemeGetter = true; return themeGetter; }; const arbitraryValueRegex = /^\[(?:([a-z-]+):)?(.+)\]$/i; const fractionRegex = /^\d+\/\d+$/; const stringLengths = /*#__PURE__*/new Set(['px', 'full', 'screen']); const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/; const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/; const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/; // Shadow always begins with x and y offset separated by underscore optionally prepended by inset const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/; const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/; const isLength = value => isNumber(value) || stringLengths.has(value) || fractionRegex.test(value); const isArbitraryLength = value => getIsArbitraryValue(value, 'length', isLengthOnly); const isNumber = value => Boolean(value) && !Number.isNaN(Number(value)); const isArbitraryNumber = value => getIsArbitraryValue(value, 'number', isNumber); const isInteger = value => Boolean(value) && Number.isInteger(Number(value)); const isPercent = value => value.endsWith('%') && isNumber(value.slice(0, -1)); const isArbitraryValue = value => arbitraryValueRegex.test(value); const isTshirtSize = value => tshirtUnitRegex.test(value); const sizeLabels = /*#__PURE__*/new Set(['length', 'size', 'percentage']); const isArbitrarySize = value => getIsArbitraryValue(value, sizeLabels, isNever); const isArbitraryPosition = value => getIsArbitraryValue(value, 'position', isNever); const imageLabels = /*#__PURE__*/new Set(['image', 'url']); const isArbitraryImage = value => getIsArbitraryValue(value, imageLabels, isImage); const isArbitraryShadow = value => getIsArbitraryValue(value, '', isShadow); const isAny = () => true; const getIsArbitraryValue = (value, label, testValue) => { const result = arbitraryValueRegex.exec(value); if (result) { if (result[1]) { return typeof label === 'string' ? result[1] === label : label.has(result[1]); } return testValue(result[2]); } return false; }; const isLengthOnly = value => // `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths. // For example, `hsl(0 0% 0%)` would be classified as a length without this check. // I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough. lengthUnitRegex.test(value) && !colorFunctionRegex.test(value); const isNever = () => false; const isShadow = value => shadowRegex.test(value); const isImage = value => imageRegex.test(value); const getDefaultConfig = () => { const colors = fromTheme('colors'); const spacing = fromTheme('spacing'); const blur = fromTheme('blur'); const brightness = fromTheme('brightness'); const borderColor = fromTheme('borderColor'); const borderRadius = fromTheme('borderRadius'); const borderSpacing = fromTheme('borderSpacing'); const borderWidth = fromTheme('borderWidth'); const contrast = fromTheme('contrast'); const grayscale = fromTheme('grayscale'); const hueRotate = fromTheme('hueRotate'); const invert = fromTheme('invert'); const gap = fromTheme('gap'); const gradientColorStops = fromTheme('gradientColorStops'); const gradientColorStopPositions = fromTheme('gradientColorStopPositions'); const inset = fromTheme('inset'); const margin = fromTheme('margin'); const opacity = fromTheme('opacity'); const padding = fromTheme('padding'); const saturate = fromTheme('saturate'); const scale = fromTheme('scale'); const sepia = fromTheme('sepia'); const skew = fromTheme('skew'); const space = fromTheme('space'); const translate = fromTheme('translate'); const getOverscroll = () => ['auto', 'contain', 'none']; const getOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll']; const getSpacingWithAutoAndArbitrary = () => ['auto', isArbitraryValue, spacing]; const getSpacingWithArbitrary = () => [isArbitraryValue, spacing]; const getLengthWithEmptyAndArbitrary = () => ['', isLength, isArbitraryLength]; const getNumberWithAutoAndArbitrary = () => ['auto', isNumber, isArbitraryValue]; const getPositions = () => ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top']; const getLineStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none']; const getBlendModes = () => ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity']; const getAlign = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch']; const getZeroAndEmpty = () => ['', '0', isArbitraryValue]; const getBreaks = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column']; const getNumberAndArbitrary = () => [isNumber, isArbitraryValue]; return { cacheSize: 500, separator: ':', theme: { colors: [isAny], spacing: [isLength, isArbitraryLength], blur: ['none', '', isTshirtSize, isArbitraryValue], brightness: getNumberAndArbitrary(), borderColor: [colors], borderRadius: ['none', '', 'full', isTshirtSize, isArbitraryValue], borderSpacing: getSpacingWithArbitrary(), borderWidth: getLengthWithEmptyAndArbitrary(), contrast: getNumberAndArbitrary(), grayscale: getZeroAndEmpty(), hueRotate: getNumberAndArbitrary(), invert: getZeroAndEmpty(), gap: getSpacingWithArbitrary(), gradientColorStops: [colors], gradientColorStopPositions: [isPercent, isArbitraryLength], inset: getSpacingWithAutoAndArbitrary(), margin: getSpacingWithAutoAndArbitrary(), opacity: getNumberAndArbitrary(), padding: getSpacingWithArbitrary(), saturate: getNumberAndArbitrary(), scale: getNumberAndArbitrary(), sepia: getZeroAndEmpty(), skew: getNumberAndArbitrary(), space: getSpacingWithArbitrary(), translate: getSpacingWithArbitrary() }, classGroups: { // Layout /** * Aspect Ratio * @see https://tailwindcss.com/docs/aspect-ratio */ aspect: [{ aspect: ['auto', 'square', 'video', isArbitraryValue] }], /** * Container * @see https://tailwindcss.com/docs/container */ container: ['container'], /** * Columns * @see https://tailwindcss.com/docs/columns */ columns: [{ columns: [isTshirtSize] }], /** * Break After * @see https://tailwindcss.com/docs/break-after */ 'break-after': [{ 'break-after': getBreaks() }], /** * Break Before * @see https://tailwindcss.com/docs/break-before */ 'break-before': [{ 'break-before': getBreaks() }], /** * Break Inside * @see https://tailwindcss.com/docs/break-inside */ 'break-inside': [{ 'break-inside': ['auto', 'avoid', 'avoid-page', 'avoid-column'] }], /** * Box Decoration Break * @see https://tailwindcss.com/docs/box-decoration-break */ 'box-decoration': [{ 'box-decoration': ['slice', 'clone'] }], /** * Box Sizing * @see https://tailwindcss.com/docs/box-sizing */ box: [{ box: ['border', 'content'] }], /** * Display * @see https://tailwindcss.com/docs/display */ display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'table', 'inline-table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row-group', 'table-row', 'flow-root', 'grid', 'inline-grid', 'contents', 'list-item', 'hidden'], /** * Floats * @see https://tailwindcss.com/docs/float */ float: [{ float: ['right', 'left', 'none', 'start', 'end'] }], /** * Clear * @see https://tailwindcss.com/docs/clear */ clear: [{ clear: ['left', 'right', 'both', 'none', 'start', 'end'] }], /** * Isolation * @see https://tailwindcss.com/docs/isolation */ isolation: ['isolate', 'isolation-auto'], /** * Object Fit * @see https://tailwindcss.com/docs/object-fit */ 'object-fit': [{ object: ['contain', 'cover', 'fill', 'none', 'scale-down'] }], /** * Object Position * @see https://tailwindcss.com/docs/object-position */ 'object-position': [{ object: [...getPositions(), isArbitraryValue] }], /** * Overflow * @see https://tailwindcss.com/docs/overflow */ overflow: [{ overflow: getOverflow() }], /** * Overflow X * @see https://tailwindcss.com/docs/overflow */ 'overflow-x': [{ 'overflow-x': getOverflow() }], /** * Overflow Y * @see https://tailwindcss.com/docs/overflow */ 'overflow-y': [{ 'overflow-y': getOverflow() }], /** * Overscroll Behavior * @see https://tailwindcss.com/docs/overscroll-behavior */ overscroll: [{ overscroll: getOverscroll() }], /** * Overscroll Behavior X * @see https://tailwindcss.com/docs/overscroll-behavior */ 'overscroll-x': [{ 'overscroll-x': getOverscroll() }], /** * Overscroll Behavior Y * @see https://tailwindcss.com/docs/overscroll-behavior */ 'overscroll-y': [{ 'overscroll-y': getOverscroll() }], /** * Position * @see https://tailwindcss.com/docs/position */ position: ['static', 'fixed', 'absolute', 'relative', 'sticky'], /** * Top / Right / Bottom / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ inset: [{ inset: [inset] }], /** * Right / Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ 'inset-x': [{ 'inset-x': [inset] }], /** * Top / Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ 'inset-y': [{ 'inset-y': [inset] }], /** * Start * @see https://tailwindcss.com/docs/top-right-bottom-left */ start: [{ start: [inset] }], /** * End * @see https://tailwindcss.com/docs/top-right-bottom-left */ end: [{ end: [inset] }], /** * Top * @see https://tailwindcss.com/docs/top-right-bottom-left */ top: [{ top: [inset] }], /** * Right * @see https://tailwindcss.com/docs/top-right-bottom-left */ right: [{ right: [inset] }], /** * Bottom * @see https://tailwindcss.com/docs/top-right-bottom-left */ bottom: [{ bottom: [inset] }], /** * Left * @see https://tailwindcss.com/docs/top-right-bottom-left */ left: [{ left: [inset] }], /** * Visibility * @see https://tailwindcss.com/docs/visibility */ visibility: ['visible', 'invisible', 'collapse'], /** * Z-Index * @see https://tailwindcss.com/docs/z-index */ z: [{ z: ['auto', isInteger, isArbitraryValue] }], // Flexbox and Grid /** * Flex Basis * @see https://tailwindcss.com/docs/flex-basis */ basis: [{ basis: getSpacingWithAutoAndArbitrary() }], /** * Flex Direction * @see https://tailwindcss.com/docs/flex-direction */ 'flex-direction': [{ flex: ['row', 'row-reverse', 'col', 'col-reverse'] }], /** * Flex Wrap * @see https://tailwindcss.com/docs/flex-wrap */ 'flex-wrap': [{ flex: ['wrap', 'wrap-reverse', 'nowrap'] }], /** * Flex * @see https://tailwindcss.com/docs/flex */ flex: [{ flex: ['1', 'auto', 'initial', 'none', isArbitraryValue] }], /** * Flex Grow * @see https://tailwindcss.com/docs/flex-grow */ grow: [{ grow: getZeroAndEmpty() }], /** * Flex Shrink * @see https://tailwindcss.com/docs/flex-shrink */ shrink: [{ shrink: getZeroAndEmpty() }], /** * Order * @see https://tailwindcss.com/docs/order */ order: [{ order: ['first', 'last', 'none', isInteger, isArbitraryValue] }], /** * Grid Template Columns * @see https://tailwindcss.com/docs/grid-template-columns */ 'grid-cols': [{ 'grid-cols': [isAny] }], /** * Grid Column Start / End * @see https://tailwindcss.com/docs/grid-column */ 'col-start-end': [{ col: ['auto', { span: ['full', isInteger, isArbitraryValue] }, isArbitraryValue] }], /** * Grid Column Start * @see https://tailwindcss.com/docs/grid-column */ 'col-start': [{ 'col-start': getNumberWithAutoAndArbitrary() }], /** * Grid Column End * @see https://tailwindcss.com/docs/grid-column */ 'col-end': [{ 'col-end': getNumberWithAutoAndArbitrary() }], /** * Grid Template Rows * @see https://tailwindcss.com/docs/grid-template-rows */ 'grid-rows': [{ 'grid-rows': [isAny] }], /** * Grid Row Start / End * @see https://tailwindcss.com/docs/grid-row */ 'row-start-end': [{ row: ['auto', { span: [isInteger, isArbitraryValue] }, isArbitraryValue] }], /** * Grid Row Start * @see https://tailwindcss.com/docs/grid-row */ 'row-start': [{ 'row-start': getNumberWithAutoAndArbitrary() }], /** * Grid Row End * @see https://tailwindcss.com/docs/grid-row */ 'row-end': [{ 'row-end': getNumberWithAutoAndArbitrary() }], /** * Grid Auto Flow * @see https://tailwindcss.com/docs/grid-auto-flow */ 'grid-flow': [{ 'grid-flow': ['row', 'col', 'dense', 'row-dense', 'col-dense'] }], /** * Grid Auto Columns * @see https://tailwindcss.com/docs/grid-auto-columns */ 'auto-cols': [{ 'auto-cols': ['auto', 'min', 'max', 'fr', isArbitraryValue] }], /** * Grid Auto Rows * @see https://tailwindcss.com/docs/grid-auto-rows */ 'auto-rows': [{ 'auto-rows': ['auto', 'min', 'max', 'fr', isArbitraryValue] }], /** * Gap * @see https://tailwindcss.com/docs/gap */ gap: [{ gap: [gap] }], /** * Gap X * @see https://tailwindcss.com/docs/gap */ 'gap-x': [{ 'gap-x': [gap] }], /** * Gap Y * @see https://tailwindcss.com/docs/gap */ 'gap-y': [{ 'gap-y': [gap] }], /** * Justify Content * @see https://tailwindcss.com/docs/justify-content */ 'justify-content': [{ justify: ['normal', ...getAlign()] }], /** * Justify Items * @see https://tailwindcss.com/docs/justify-items */ 'justify-items': [{ 'justify-items': ['start', 'end', 'center', 'stretch'] }], /** * Justify Self * @see https://tailwindcss.com/docs/justify-self */ 'justify-self': [{ 'justify-self': ['auto', 'start', 'end', 'center', 'stretch'] }], /** * Align Content * @see https://tailwindcss.com/docs/align-content */ 'align-content': [{ content: ['normal', ...getAlign(), 'baseline'] }], /** * Align Items * @see https://tailwindcss.com/docs/align-items */ 'align-items': [{ items: ['start', 'end', 'center', 'baseline', 'stretch'] }], /** * Align Self * @see https://tailwindcss.com/docs/align-self */ 'align-self': [{ self: ['auto', 'start', 'end', 'center', 'stretch', 'baseline'] }], /** * Place Content * @see https://tailwindcss.com/docs/place-content */ 'place-content': [{ 'place-content': [...getAlign(), 'baseline'] }], /** * Place Items * @see https://tailwindcss.com/docs/place-items */ 'place-items': [{ 'place-items': ['start', 'end', 'center', 'baseline', 'stretch'] }], /** * Place Self * @see https://tailwindcss.com/docs/place-self */ 'place-self': [{ 'place-self': ['auto', 'start', 'end', 'center', 'stretch'] }], // Spacing /** * Padding * @see https://tailwindcss.com/docs/padding */ p: [{ p: [padding] }], /** * Padding X * @see https://tailwindcss.com/docs/padding */ px: [{ px: [padding] }], /** * Padding Y * @see https://tailwindcss.com/docs/padding */ py: [{ py: [padding] }], /** * Padding Start * @see https://tailwindcss.com/docs/padding */ ps: [{ ps: [padding] }], /** * Padding End * @see https://tailwindcss.com/docs/padding */ pe: [{ pe: [padding] }], /** * Padding Top * @see https://tailwindcss.com/docs/padding */ pt: [{ pt: [padding] }], /** * Padding Right * @see https://tailwindcss.com/docs/padding */ pr: [{ pr: [padding] }], /** * Padding Bottom * @see https://tailwindcss.com/docs/padding */ pb: [{ pb: [padding] }], /** * Padding Left * @see https://tailwindcss.com/docs/padding */ pl: [{ pl: [padding] }], /** * Margin * @see https://tailwindcss.com/docs/margin */ m: [{ m: [margin] }], /** * Margin X * @see https://tailwindcss.com/docs/margin */ mx: [{ mx: [margin] }], /** * Margin Y * @see https://tailwindcss.com/docs/margin */ my: [{ my: [margin] }], /** * Margin Start * @see https://tailwindcss.com/docs/margin */ ms: [{ ms: [margin] }], /** * Margin End * @see https://tailwindcss.com/docs/margin */ me: [{ me: [margin] }], /** * Margin Top * @see https://tailwindcss.com/docs/margin */ mt: [{ mt: [margin] }], /** * Margin Right * @see https://tailwindcss.com/docs/margin */ mr: [{ mr: [margin] }], /** * Margin Bottom * @see https://tailwindcss.com/docs/margin */ mb: [{ mb: [margin] }], /** * Margin Left * @see https://tailwindcss.com/docs/margin */ ml: [{ ml: [margin] }], /** * Space Between X * @see https://tailwindcss.com/docs/space */ 'space-x': [{ 'space-x': [space] }], /** * Space Between X Reverse * @see https://tailwindcss.com/docs/space */ 'space-x-reverse': ['space-x-reverse'], /** * Space Between Y * @see https://tailwindcss.com/docs/space */ 'space-y': [{ 'space-y': [space] }], /** * Space Between Y Reverse * @see https://tailwindcss.com/docs/space */ 'space-y-reverse': ['space-y-reverse'], // Sizing /** * Width * @see https://tailwindcss.com/docs/width */ w: [{ w: ['auto', 'min', 'max', 'fit', 'svw', 'lvw', 'dvw', isArbitraryValue, spacing] }], /** * Min-Width * @see https://tailwindcss.com/docs/min-width */ 'min-w': [{ 'min-w': [isArbitraryValue, spacing, 'min', 'max', 'fit'] }], /** * Max-Width * @see https://tailwindcss.com/docs/max-width */ 'max-w': [{ 'max-w': [isArbitraryValue, spacing, 'none', 'full', 'min', 'max', 'fit', 'prose', { screen: [isTshirtSize] }, isTshirtSize] }], /** * Height * @see https://tailwindcss.com/docs/height */ h: [{ h: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit', 'svh', 'lvh', 'dvh'] }], /** * Min-Height * @see https://tailwindcss.com/docs/min-height */ 'min-h': [{ 'min-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh'] }], /** * Max-Height * @see https://tailwindcss.com/docs/max-height */ 'max-h': [{ 'max-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh'] }], /** * Size * @see https://tailwindcss.com/docs/size */ size: [{ size: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit'] }], // Typography /** * Font Size * @see https://tailwindcss.com/docs/font-size */ 'font-size': [{ text: ['base', isTshirtSize, isArbitraryLength] }], /** * Font Smoothing * @see https://tailwindcss.com/docs/font-smoothing */ 'font-smoothing': ['antialiased', 'subpixel-antialiased'], /** * Font Style * @see https://tailwindcss.com/docs/font-style */ 'font-style': ['italic', 'not-italic'], /** * Font Weight * @see https://tailwindcss.com/docs/font-weight */ 'font-weight': [{ font: ['thin', 'extralight', 'light', 'normal', 'medium', 'semibold', 'bold', 'extrabold', 'black', isArbitraryNumber] }], /** * Font Family * @see https://tailwindcss.com/docs/font-family */ 'font-family': [{ font: [isAny] }], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric */ 'fvn-normal': ['normal-nums'], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric */ 'fvn-ordinal': ['ordinal'], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font-variant-numeric */ 'fvn-slashed-zero': ['slashed-zero'], /** * Font Variant Numeric * @see https://tailwindcss.com/docs/font