Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add modal and drawer components and examples #4229

Merged
merged 6 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@

"i18n-ally.localesPaths": [
"packages/locales/src/langs",
"playground/src/langs",
"playground/src/locales/langs",
"apps/*/src/locales/langs"
],
"i18n-ally.pathMatcher": "{locale}.json",
"i18n-ally.enabledParsers": ["json", "ts", "js", "yaml"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.displayLanguage": "zh-CN",
Expand Down
2 changes: 1 addition & 1 deletion apps/backend-mock/utils/jwt-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface UserPayload extends UserInfo {
}

export function generateAccessToken(user: UserInfo) {
return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '1d' });
return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '7d' });
}

export function generateRefreshToken(user: UserInfo) {
Expand Down
6 changes: 5 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"astro",
"ui-kit",
"styl",
"vnode",
"nocheck",
"prefixs",
"vitepress",
Expand All @@ -53,6 +54,9 @@
"**/*-dist/**",
"**/icons/**",
"pnpm-lock.yaml",
"**/*.log"
"**/*.log",
"**/*.test.ts",
"**/*.spec.ts",
"**/__tests__/**"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';

import { describe, expect, it } from 'vitest';

import { generatorContentHash } from './hash';
import { generatorContentHash } from '../hash';

describe('generatorContentHash', () => {
it('should generate an MD5 hash for the content', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { describe, expect, it } from 'vitest';

import { toPosixPath } from './path';
import { toPosixPath } from '../path';

describe('toPosixPath', () => {
// 测试 Windows 风格路径到 POSIX 风格路径的转换
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@
transition: all 0.6s ease-out;
}

.loading .dots {
display: flex;
align-items: center;
justify-content: center;
padding: 98px;
}

.loading .title {
margin-top: 36px;
font-size: 30px;
Expand Down Expand Up @@ -109,6 +102,6 @@
}
</style>
<div class="loading" id="__app-loading__">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
<span class="dot"><i></i><i></i><i></i><i></i></span>
<div class="title"><%= VITE_APP_TITLE %></div>
</div>
3 changes: 3 additions & 0 deletions packages/@core/base/icons/src/lucide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ export {
CornerDownLeft,
Disc as IconDefault,
Ellipsis,
Expand,
ExternalLink,
Eye,
EyeOff,
FoldHorizontal,
Fullscreen,
Github,
Info,
InspectionPanel,
Languages,
LoaderCircle,
Expand All @@ -46,6 +48,7 @@ export {
Search,
SearchX,
Settings,
Shrink,
Sun,
SunMoon,
SwatchBook,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { StorageManager } from './storage-manager';
import { StorageManager } from '../storage-manager';

describe('storageManager', () => {
let storageManager: StorageManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
convertToHslCssVar,
convertToRgb,
isValidColor,
} from './convert';
} from '../convert';

describe('color conversion functions', () => {
it('should correctly convert color to HSL format', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';

import { diff } from './diff';
import { diff } from '../diff';

describe('diff function', () => {
it('should return an empty object when comparing identical objects', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { getElementVisibleRect } from './dom'; // 假设函数位于 utils.ts 中
import { getElementVisibleRect } from '../dom'; // 假设函数位于 utils.ts 中

describe('getElementVisibleRect', () => {
// 设置浏览器视口尺寸的 mock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { describe, expect, it } from 'vitest';

import {
getFirstNonNullOrUndefined,
isEmpty,
isHttpUrl,
isObject,
isUndefined,
isWindow,
} from './inference';
} from '../inference';

describe('isHttpUrl', () => {
it("should return true when given 'http://example.com'", () => {
Expand Down Expand Up @@ -103,7 +104,6 @@ describe('isObject', () => {

it('should return false for non-objects', () => {
expect(isObject(null)).toBe(false);
expect(isObject()).toBe(false);
expect(isObject(42)).toBe(false);
expect(isObject('string')).toBe(false);
expect(isObject(true)).toBe(false);
Expand All @@ -112,3 +112,56 @@ describe('isObject', () => {
expect(isObject(/regex/)).toBe(true);
});
});

describe('getFirstNonNullOrUndefined', () => {
describe('getFirstNonNullOrUndefined', () => {
it('should return the first non-null and non-undefined value for a number array', () => {
expect(getFirstNonNullOrUndefined<number>(undefined, null, 0, 42)).toBe(
0,
);
expect(getFirstNonNullOrUndefined<number>(null, undefined, 42, 123)).toBe(
42,
);
});

it('should return the first non-null and non-undefined value for a string array', () => {
expect(
getFirstNonNullOrUndefined<string>(undefined, null, '', 'hello'),
).toBe('');
expect(
getFirstNonNullOrUndefined<string>(null, undefined, 'test', 'world'),
).toBe('test');
});

it('should return undefined if all values are null or undefined', () => {
expect(getFirstNonNullOrUndefined(undefined, null)).toBeUndefined();
expect(getFirstNonNullOrUndefined(null)).toBeUndefined();
});

it('should work with a single value', () => {
expect(getFirstNonNullOrUndefined(42)).toBe(42);
expect(getFirstNonNullOrUndefined()).toBeUndefined();
expect(getFirstNonNullOrUndefined(null)).toBeUndefined();
});

it('should handle mixed types correctly', () => {
expect(
getFirstNonNullOrUndefined<number | object | string>(
undefined,
null,
'test',
123,
{ key: 'value' },
),
).toBe('test');
expect(
getFirstNonNullOrUndefined<number | object | string>(
null,
undefined,
[1, 2, 3],
'string',
),
).toEqual([1, 2, 3]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { describe, expect, it } from 'vitest';

import {
capitalizeFirstLetter,
kebabToCamelCase,
toCamelCase,
toLowerCaseFirstLetter,
} from './letter';
} from '../letter';

// 编写测试用例
describe('capitalizeFirstLetter', () => {
Expand Down Expand Up @@ -76,3 +77,41 @@ describe('toCamelCase', () => {
expect(toCamelCase('Child', 'Parent')).toBe('ParentChild');
});
});

describe('kebabToCamelCase', () => {
it('should convert kebab-case to camelCase correctly', () => {
expect(kebabToCamelCase('my-component-name')).toBe('myComponentName');
});

it('should handle multiple consecutive hyphens', () => {
expect(kebabToCamelCase('my--component--name')).toBe('myComponentName');
});

it('should trim leading and trailing hyphens', () => {
expect(kebabToCamelCase('-my-component-name-')).toBe('myComponentName');
});

it('should preserve the case of the first word', () => {
expect(kebabToCamelCase('My-component-name')).toBe('MyComponentName');
});

it('should convert a single word correctly', () => {
expect(kebabToCamelCase('component')).toBe('component');
});

it('should return an empty string if input is empty', () => {
expect(kebabToCamelCase('')).toBe('');
});

it('should handle strings with no hyphens', () => {
expect(kebabToCamelCase('mycomponentname')).toBe('mycomponentname');
});

it('should handle strings with only hyphens', () => {
expect(kebabToCamelCase('---')).toBe('');
});

it('should handle mixed case inputs', () => {
expect(kebabToCamelCase('my-Component-Name')).toBe('myComponentName');
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';

import { filterTree, mapTree, traverseTreeValues } from './tree';
import { filterTree, mapTree, traverseTreeValues } from '../tree';

describe('traverseTreeValues', () => {
interface Node {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';

import { uniqueByField } from './unique';
import { uniqueByField } from '../unique';

describe('uniqueByField', () => {
it('should return an array with unique items based on id field', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, it } from 'vitest';

import { updateCSSVariables } from './update-css-variables';
import { updateCSSVariables } from '../update-css-variables';

it('updateCSSVariables should update CSS variables in :root selector', () => {
// 模拟初始的内联样式表内容
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { openWindow } from './window'; // 假设你的函数在 'openWindow' 文件中
import { openWindow } from '../window'; // 假设你的函数在 'openWindow' 文件中

describe('openWindow', () => {
// 保存原始的 window.open 函数
Expand Down
37 changes: 36 additions & 1 deletion packages/@core/base/shared/src/utils/inference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function isUndefined(value?: unknown): value is undefined {
* @param {T} value 要检查的值。
* @returns {boolean} 如果值为空,返回true,否则返回false。
*/
function isEmpty<T = unknown>(value: T): value is T {
function isEmpty<T = unknown>(value?: T): value is T {
if (value === null || value === undefined) {
return true;
}
Expand Down Expand Up @@ -105,7 +105,42 @@ function isNumber(value: any): value is number {
return typeof value === 'number' && Number.isFinite(value);
}

/**
* Returns the first value in the provided list that is neither `null` nor `undefined`.
*
* This function iterates over the input values and returns the first one that is
* not strictly equal to `null` or `undefined`. If all values are either `null` or
* `undefined`, it returns `undefined`.
*
* @template T - The type of the input values.
* @param {...(T | null | undefined)[]} values - A list of values to evaluate.
* @returns {T | undefined} - The first value that is not `null` or `undefined`, or `undefined` if none are found.
*
* @example
* // Returns 42 because it is the first non-null, non-undefined value.
* getFirstNonNullOrUndefined(undefined, null, 42, 'hello'); // 42
*
* @example
* // Returns 'hello' because it is the first non-null, non-undefined value.
* getFirstNonNullOrUndefined(null, undefined, 'hello', 123); // 'hello'
*
* @example
* // Returns undefined because all values are either null or undefined.
* getFirstNonNullOrUndefined(undefined, null); // undefined
*/
function getFirstNonNullOrUndefined<T>(
...values: (null | T | undefined)[]
): T | undefined {
for (const value of values) {
if (value !== undefined && value !== null) {
return value;
}
}
return undefined;
}

export {
getFirstNonNullOrUndefined,
isEmpty,
isFunction,
isHttpUrl,
Expand Down
17 changes: 16 additions & 1 deletion packages/@core/base/shared/src/utils/letter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,19 @@ function toCamelCase(key: string, parentKey: string): string {
return parentKey + key.charAt(0).toUpperCase() + key.slice(1);
}

export { capitalizeFirstLetter, toCamelCase, toLowerCaseFirstLetter };
function kebabToCamelCase(str: string): string {
return str
.split('-')
.filter(Boolean)
.map((word, index) =>
index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1),
)
.join('');
}

export {
capitalizeFirstLetter,
kebabToCamelCase,
toCamelCase,
toLowerCaseFirstLetter,
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { SortableOptions } from 'sortablejs';

import { beforeEach, describe, expect, it, vi } from 'vitest';

import { useSortable } from './use-sortable';
import { useSortable } from '../use-sortable';

describe('useSortable', () => {
beforeEach(() => {
Expand Down Expand Up @@ -30,7 +30,6 @@ describe('useSortable', () => {

// Import sortablejs to access the mocked create function
const Sortable = await import(
// @ts-expect-error - This is a dynamic import
'sortablejs/modular/sortable.complete.esm.js'
);

Expand Down
1 change: 1 addition & 0 deletions packages/@core/composables/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './use-content-style';
export * from './use-namespace';
export * from './use-priority-value';
export * from './use-sortable';
export {
useEmitAsProps,
Expand Down
Loading
Loading