Skip to content

Commit

Permalink
refactor(admin/core/theme): 重构了 breakpoints 相关功能
Browse files Browse the repository at this point in the history
- 添加了 breakpointsMedia 对象;
- 在 taildwind 的配置中添加了 min-width 和 max-width 中与 breakpoint 相关的 CSS 类;
  • Loading branch information
caixw committed Sep 10, 2024
1 parent c490024 commit cbafab5
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 73 deletions.
2 changes: 1 addition & 1 deletion admin/src/components/button/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}

.c--button.c--button-fill {
@apply text-[var(--fg)] bg-[var(--bg)] border-[var(--bg)];
@apply text-[var(--fg)] bg-palette-bg border-[var(--bg)];
}

.c--button.c--button-fill:enabled:hover,
Expand Down
13 changes: 8 additions & 5 deletions admin/src/core/theme/breakpoints.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
// SPDX-License-Identifier: MIT

import { expect, test } from 'vitest';
import { Breakpoints } from './breakpoints';
import { Breakpoints, breakpoints, breakpointsMedia } from './breakpoints';

test('breakpoints.compare', () => {
test('Breakpoints.compare', () => {
expect(Breakpoints.compare('xs', 'sm')).toEqual(-1);
expect(Breakpoints.compare('sm', 'sm')).toEqual(0);
expect(Breakpoints.compare('sm', 'xs')).toEqual(1);
expect(Breakpoints.compare('sm', 'lg')).toEqual(-2);

const bp = new Breakpoints();
bp.onChange(() => {
// TODO
});
bp.onChange(() => {});
});

test('breakpointsMedia', () => {
expect(breakpointsMedia.xs).toEqual(`(width >= ${breakpoints.xs}px)`);
expect(breakpointsMedia.lg).toEqual('(width >= 1024px)');
});
41 changes: 24 additions & 17 deletions admin/src/core/theme/breakpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,32 @@
// NOTE: 此文件可能被包括非源码目录下的多个文件引用,
// 不要在此文件中引用项目专用的一些功能,比如 vite.config.ts 中的 resolve.alias 的定义等。

const breakpointsOrder = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const;

export type Breakpoint = typeof breakpointsOrder[number];

/**
* 定义了常用的屏幕尺寸
*
* JS 和 CSS 都会用到。
*/
export const breakpoints: Record<Breakpoint, string> = {
// NOTE: 当屏幕从大到小变化,比如从 sm 向 xs 变化,会触发 sm 事件,且其 matches 为 false,
// 但是不会触发 xs,因为 sm 本身也是符合 xs 的条件。

xs: '(width >= 475px)',
sm: '(width >= 640px)',
md: '(width >= 768px)',
lg: '(width >= 1024px)',
xl: '(width >= 1280px)',
xxl: '(width >= 1536px)',
//xxxl: '(width >= 1600px)'
} as const;
export const breakpoints: Readonly<Record<Breakpoint, string>> = {
xs: '475px',
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
xxl: '1536px',
//xxxl: '1600px'
};

const breakpointsOrder = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const;
type BreakpointsMedia = Record<Breakpoint, string>;

export type Breakpoint = typeof breakpointsOrder[number];
/**
* 根据 {@link breakpoints} 生成的媒体查询样式
*/
export const breakpointsMedia: Readonly<BreakpointsMedia> = Object.entries(breakpoints).reduce<BreakpointsMedia>((obj, [key, val])=>{
obj[key as Breakpoint] = `(width >= ${val})`;
return obj;
}, {} as BreakpointsMedia);

export interface BreakpointChange {
(val: Breakpoint, old?: Breakpoint): void;
Expand All @@ -41,10 +46,12 @@ export class Breakpoints {
constructor() {
this.#events = [];

Object.entries(breakpoints).forEach((item) => {
Object.entries(breakpointsMedia).forEach((item) => {
const key = item[0] as Breakpoint;
const mql = window.matchMedia(item[1]);

// 当屏幕从大到小变化,比如从 sm 向 xs 变化,会触发 sm 事件,且其 matches 为 false,
// 但是不会触发 xs,因为 sm 本身也是符合 xs 的条件。
const event = (ev: {matches: boolean}) => {
if (ev.matches) {
this.#change(key);
Expand Down
2 changes: 1 addition & 1 deletion admin/src/core/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type { Contrast } from './contrast';
export { changeScheme, genScheme, getScheme } from './scheme';
export type { Scheme } from './scheme';

export { Breakpoints, breakpoints } from './breakpoints';
export { Breakpoints, breakpoints, breakpointsMedia } from './breakpoints';
export type { Breakpoint, BreakpointChange } from './breakpoints';

export { init as initTheme } from './theme';
74 changes: 26 additions & 48 deletions admin/tailwind.preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//
// SPDX-License-Identifier: MIT

import type { PluginUtils, PresetsConfig, ScreensConfig } from 'tailwindcss/types/config';
import { breakpoints } from './src/core/theme/breakpoints';
import type { PresetsConfig, ScreensConfig } from 'tailwindcss/types/config';
import { breakpoints, breakpointsMedia } from './src/core/theme/breakpoints';

const colors = {
'primary-bg': 'var(--primary-bg)',
Expand Down Expand Up @@ -49,61 +49,39 @@ const colors = {
'palette-fg-high': 'var(--fg-high)',
} as const;

function applyColors(f: PluginUtils['theme']) {
return {
...colors,
...f('colors')
};
}

const config: PresetsConfig = {
darkMode: 'selector',

theme: {
// 自定义颜色,方便直接在 HTML 中使用

backgroundColor: ({theme})=>({
...applyColors(theme)
}),

textColor: ({theme})=>({
...applyColors(theme)
}),
placeholderColor: ({theme})=>({
...applyColors(theme)
}),
caretColor: ({theme})=>({
...applyColors(theme)
}),
textDecorationColor: ({theme})=>({
...applyColors(theme)
}),

accentColor: ({theme})=>({
...applyColors(theme)
}),

borderColor: ({theme})=>({
...applyColors(theme)
}),
outlineColor: ({theme})=>({
...applyColors(theme)
}),
ringColor: ({theme})=>({
...applyColors(theme)
}),

divideColor: ({theme})=>({
...applyColors(theme)
}),

screens: buildScreens()
// 重定义 screens 属性,而不是扩展。
screens: buildScreens(),

extend: {
backgroundColor: colors,

textColor: colors,
placeholderColor: colors,
caretColor: colors,
textDecorationColor: colors,

accentColor: colors,

borderColor: colors,
outlineColor: colors,
ringColor: colors,
divideColor: colors,

minWidth: breakpoints,
maxWidth: breakpoints,
}
}
};

function buildScreens() {
const screens: ScreensConfig = {};
Object.entries(breakpoints).forEach((item) => {
Object.entries(breakpointsMedia).forEach((item) => {
// NOTE: 当屏幕从大到小变化,比如从 sm 向 xs 变化,会触发 sm 事件,且其 matches 为 false,
// 但是不会触发 xs,因为 sm 本身也是符合 xs 的条件。
screens[item[0]] = { 'raw': item[1]};
});
return screens;
Expand Down
2 changes: 1 addition & 1 deletion cmd/admin/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ const o: Options = {
menus: menus
};

await createApp('app', o);
createApp('app', o);

0 comments on commit cbafab5

Please sign in to comment.