fix: 本地 patch MDUI 以解决 tabindex = 0 导致的一系列玄学问题
This commit is contained in:
39
client/mdui_patched/internal/colorScheme.d.ts
vendored
Normal file
39
client/mdui_patched/internal/colorScheme.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import '@mdui/jq/methods/addClass.js';
|
||||
import '@mdui/jq/methods/append.js';
|
||||
import '@mdui/jq/methods/get.js';
|
||||
import '@mdui/jq/methods/remove.js';
|
||||
import '@mdui/jq/methods/removeClass.js';
|
||||
import type { JQ } from '@mdui/jq/shared/core.js';
|
||||
export interface CustomColor {
|
||||
/**
|
||||
* 自定义颜色名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 自定义十六进制颜色值,如 `#f82506`
|
||||
*/
|
||||
value: string;
|
||||
}
|
||||
/**
|
||||
* 移除指定元素上的配色方案
|
||||
* @param target
|
||||
*/
|
||||
export declare const remove: (target: string | HTMLElement | JQ<HTMLElement>) => void;
|
||||
/**
|
||||
* 设置配色方案
|
||||
* 在 head 中插入一个 <style id="mdui-custom-color-scheme-${source}"> 元素,
|
||||
* 并在 target 元素上添加 class="mdui-custom-color-scheme-${source}"
|
||||
*
|
||||
* 自定义颜色的 css 变量
|
||||
* --mdui-color-red
|
||||
* --mdui-color-on-red
|
||||
* --mdui-color-red-container
|
||||
* --mdui-color-on-red-container
|
||||
*
|
||||
* @param source
|
||||
* @param options
|
||||
*/
|
||||
export declare const setFromSource: (source: number, options?: {
|
||||
target?: string | HTMLElement | JQ<HTMLElement>;
|
||||
customColors?: CustomColor[];
|
||||
}) => void;
|
||||
133
client/mdui_patched/internal/colorScheme.js
Normal file
133
client/mdui_patched/internal/colorScheme.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { blueFromArgb, greenFromArgb, redFromArgb, customColor, argbFromHex, Scheme, CorePalette, } from '@material/material-color-utilities';
|
||||
import { getDocument } from 'ssr-window';
|
||||
import { $ } from '@mdui/jq/$.js';
|
||||
import { unique } from '@mdui/jq/functions/unique.js';
|
||||
import '@mdui/jq/methods/addClass.js';
|
||||
import '@mdui/jq/methods/append.js';
|
||||
import '@mdui/jq/methods/get.js';
|
||||
import '@mdui/jq/methods/remove.js';
|
||||
import '@mdui/jq/methods/removeClass.js';
|
||||
import { toKebabCase } from '@mdui/jq/shared/helper.js';
|
||||
const themeArr = ['light', 'dark'];
|
||||
const prefix = 'mdui-custom-color-scheme-'; // 类名前缀
|
||||
let themeIndex = 0;
|
||||
const rgbFromArgb = (source) => {
|
||||
const red = redFromArgb(source);
|
||||
const green = greenFromArgb(source);
|
||||
const blue = blueFromArgb(source);
|
||||
return [red, green, blue].join(', ');
|
||||
};
|
||||
/**
|
||||
* 移除指定元素上的配色方案
|
||||
* @param target
|
||||
*/
|
||||
export const remove = (target) => {
|
||||
const $target = $(target);
|
||||
// 找出指定元素上所有的配色方案 CSS class
|
||||
let classNames = $target
|
||||
.get()
|
||||
.map((element) => Array.from(element.classList))
|
||||
.flat();
|
||||
classNames = unique(classNames).filter((className) => className.startsWith(prefix));
|
||||
// 移除 CSS class
|
||||
$target.removeClass(classNames.join(' '));
|
||||
// 找出没有被其他元素使用的 CSS class
|
||||
const unusedClassNames = classNames.filter((className) => $(`.${className}`).length === 0);
|
||||
// 移除对应的 <style> 元素
|
||||
$(unusedClassNames.map((i) => `#${i}`).join(',')).remove();
|
||||
};
|
||||
/**
|
||||
* 设置配色方案
|
||||
* 在 head 中插入一个 <style id="mdui-custom-color-scheme-${source}"> 元素,
|
||||
* 并在 target 元素上添加 class="mdui-custom-color-scheme-${source}"
|
||||
*
|
||||
* 自定义颜色的 css 变量
|
||||
* --mdui-color-red
|
||||
* --mdui-color-on-red
|
||||
* --mdui-color-red-container
|
||||
* --mdui-color-on-red-container
|
||||
*
|
||||
* @param source
|
||||
* @param options
|
||||
*/
|
||||
export const setFromSource = (source, options) => {
|
||||
const document = getDocument();
|
||||
const $target = $(options?.target || document.documentElement);
|
||||
// 生成配色方案
|
||||
const schemes = {
|
||||
light: Scheme.light(source).toJSON(),
|
||||
dark: Scheme.dark(source).toJSON(),
|
||||
};
|
||||
// todo 目前 @material/material-color-utilities 库缺失了 8 种颜色,等官方库加上后,可以删除这段代码
|
||||
// https://github.com/material-foundation/material-color-utilities/issues/98
|
||||
const palette = CorePalette.of(source);
|
||||
Object.assign(schemes.light, {
|
||||
'surface-dim': palette.n1.tone(87),
|
||||
'surface-bright': palette.n1.tone(98),
|
||||
'surface-container-lowest': palette.n1.tone(100),
|
||||
'surface-container-low': palette.n1.tone(96),
|
||||
'surface-container': palette.n1.tone(94),
|
||||
'surface-container-high': palette.n1.tone(92),
|
||||
'surface-container-highest': palette.n1.tone(90),
|
||||
'surface-tint-color': schemes.light.primary,
|
||||
});
|
||||
Object.assign(schemes.dark, {
|
||||
'surface-dim': palette.n1.tone(6),
|
||||
'surface-bright': palette.n1.tone(24),
|
||||
'surface-container-lowest': palette.n1.tone(4),
|
||||
'surface-container-low': palette.n1.tone(10),
|
||||
'surface-container': palette.n1.tone(12),
|
||||
'surface-container-high': palette.n1.tone(17),
|
||||
'surface-container-highest': palette.n1.tone(22),
|
||||
'surface-tint-color': schemes.dark.primary,
|
||||
});
|
||||
// 扩充自定义颜色
|
||||
(options?.customColors || []).map((color) => {
|
||||
const name = toKebabCase(color.name);
|
||||
const custom = customColor(source, {
|
||||
name,
|
||||
value: argbFromHex(color.value),
|
||||
blend: true,
|
||||
});
|
||||
themeArr.forEach((theme) => {
|
||||
schemes[theme][name] = custom[theme].color;
|
||||
schemes[theme][`on-${name}`] = custom[theme].onColor;
|
||||
schemes[theme][`${name}-container`] = custom[theme].colorContainer;
|
||||
schemes[theme][`on-${name}-container`] = custom[theme].onColorContainer;
|
||||
});
|
||||
});
|
||||
// 根据配色方案生成 css 变量
|
||||
const colorVar = (theme, callback) => {
|
||||
return Object.entries(schemes[theme])
|
||||
.map(([key, value]) => callback(toKebabCase(key), rgbFromArgb(value)))
|
||||
.join('');
|
||||
};
|
||||
const className = prefix + `${source}-${themeIndex++}`;
|
||||
// CSS 文本
|
||||
const cssText = `.${className} {
|
||||
${colorVar('light', (token, rgb) => `--mdui-color-${token}-light: ${rgb};`)}
|
||||
${colorVar('dark', (token, rgb) => `--mdui-color-${token}-dark: ${rgb};`)}
|
||||
${colorVar('light', (token) => `--mdui-color-${token}: var(--mdui-color-${token}-light);`)}
|
||||
|
||||
color: rgb(var(--mdui-color-on-background));
|
||||
background-color: rgb(var(--mdui-color-background));
|
||||
}
|
||||
|
||||
.mdui-theme-dark .${className},
|
||||
.mdui-theme-dark.${className} {
|
||||
${colorVar('dark', (token) => `--mdui-color-${token}: var(--mdui-color-${token}-dark);`)}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.mdui-theme-auto .${className},
|
||||
.mdui-theme-auto.${className} {
|
||||
${colorVar('dark', (token) => `--mdui-color-${token}: var(--mdui-color-${token}-dark);`)}
|
||||
}
|
||||
}`;
|
||||
// 移除旧的配色方案
|
||||
remove($target);
|
||||
// 创建 <style> 元素,添加到 head 中
|
||||
$(document.head).append(`<style id="${className}">${cssText}</style>`);
|
||||
// 添加新配色方案
|
||||
$target.addClass(className);
|
||||
};
|
||||
13
client/mdui_patched/internal/localeCodes.d.ts
vendored
Normal file
13
client/mdui_patched/internal/localeCodes.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* The locale code that templates in this source code are written in.
|
||||
*/
|
||||
export declare const sourceLocale = "en-us";
|
||||
/**
|
||||
* The other locale codes that this application is localized into. Sorted
|
||||
* lexicographically.
|
||||
*/
|
||||
export declare const targetLocales: readonly ["ar-eg", "az-az", "be-by", "bg-bg", "bn-bd", "ca-es", "cs-cz", "da-dk", "de-de", "el-gr", "en-gb", "es-es", "et-ee", "fa-ir", "fi-fi", "fr-be", "fr-ca", "fr-fr", "ga-ie", "gl-es", "he-il", "hi-in", "hr-hr", "hu-hu", "hy-am", "id-id", "is-is", "it-it", "ja-jp", "ka-ge", "kk-kz", "km-kh", "kmr-iq", "kn-in", "ko-kr", "lt-lt", "lv-lv", "mk-mk", "ml-in", "mn-mn", "ms-my", "nb-no", "ne-np", "nl-be", "nl-nl", "pl-pl", "pt-br", "pt-pt", "ro-ro", "ru-ru", "sk-sk", "sl-si", "sr-rs", "sv-se", "ta-in", "th-th", "tr-tr", "uk-ua", "ur-pk", "vi-vn", "zh-cn", "zh-hk", "zh-tw"];
|
||||
/**
|
||||
* All valid project locale codes. Sorted lexicographically.
|
||||
*/
|
||||
export declare const allLocales: readonly ["ar-eg", "az-az", "be-by", "bg-bg", "bn-bd", "ca-es", "cs-cz", "da-dk", "de-de", "el-gr", "en-gb", "en-us", "es-es", "et-ee", "fa-ir", "fi-fi", "fr-be", "fr-ca", "fr-fr", "ga-ie", "gl-es", "he-il", "hi-in", "hr-hr", "hu-hu", "hy-am", "id-id", "is-is", "it-it", "ja-jp", "ka-ge", "kk-kz", "km-kh", "kmr-iq", "kn-in", "ko-kr", "lt-lt", "lv-lv", "mk-mk", "ml-in", "mn-mn", "ms-my", "nb-no", "ne-np", "nl-be", "nl-nl", "pl-pl", "pt-br", "pt-pt", "ro-ro", "ru-ru", "sk-sk", "sl-si", "sr-rs", "sv-se", "ta-in", "th-th", "tr-tr", "uk-ua", "ur-pk", "vi-vn", "zh-cn", "zh-hk", "zh-tw"];
|
||||
144
client/mdui_patched/internal/localeCodes.js
Normal file
144
client/mdui_patched/internal/localeCodes.js
Normal file
@@ -0,0 +1,144 @@
|
||||
// Do not modify this file by hand!
|
||||
// Re-generate this file by running lit-localize.
|
||||
/**
|
||||
* The locale code that templates in this source code are written in.
|
||||
*/
|
||||
export const sourceLocale = `en-us`;
|
||||
/**
|
||||
* The other locale codes that this application is localized into. Sorted
|
||||
* lexicographically.
|
||||
*/
|
||||
export const targetLocales = [
|
||||
`ar-eg`,
|
||||
`az-az`,
|
||||
`be-by`,
|
||||
`bg-bg`,
|
||||
`bn-bd`,
|
||||
`ca-es`,
|
||||
`cs-cz`,
|
||||
`da-dk`,
|
||||
`de-de`,
|
||||
`el-gr`,
|
||||
`en-gb`,
|
||||
`es-es`,
|
||||
`et-ee`,
|
||||
`fa-ir`,
|
||||
`fi-fi`,
|
||||
`fr-be`,
|
||||
`fr-ca`,
|
||||
`fr-fr`,
|
||||
`ga-ie`,
|
||||
`gl-es`,
|
||||
`he-il`,
|
||||
`hi-in`,
|
||||
`hr-hr`,
|
||||
`hu-hu`,
|
||||
`hy-am`,
|
||||
`id-id`,
|
||||
`is-is`,
|
||||
`it-it`,
|
||||
`ja-jp`,
|
||||
`ka-ge`,
|
||||
`kk-kz`,
|
||||
`km-kh`,
|
||||
`kmr-iq`,
|
||||
`kn-in`,
|
||||
`ko-kr`,
|
||||
`lt-lt`,
|
||||
`lv-lv`,
|
||||
`mk-mk`,
|
||||
`ml-in`,
|
||||
`mn-mn`,
|
||||
`ms-my`,
|
||||
`nb-no`,
|
||||
`ne-np`,
|
||||
`nl-be`,
|
||||
`nl-nl`,
|
||||
`pl-pl`,
|
||||
`pt-br`,
|
||||
`pt-pt`,
|
||||
`ro-ro`,
|
||||
`ru-ru`,
|
||||
`sk-sk`,
|
||||
`sl-si`,
|
||||
`sr-rs`,
|
||||
`sv-se`,
|
||||
`ta-in`,
|
||||
`th-th`,
|
||||
`tr-tr`,
|
||||
`uk-ua`,
|
||||
`ur-pk`,
|
||||
`vi-vn`,
|
||||
`zh-cn`,
|
||||
`zh-hk`,
|
||||
`zh-tw`,
|
||||
];
|
||||
/**
|
||||
* All valid project locale codes. Sorted lexicographically.
|
||||
*/
|
||||
export const allLocales = [
|
||||
`ar-eg`,
|
||||
`az-az`,
|
||||
`be-by`,
|
||||
`bg-bg`,
|
||||
`bn-bd`,
|
||||
`ca-es`,
|
||||
`cs-cz`,
|
||||
`da-dk`,
|
||||
`de-de`,
|
||||
`el-gr`,
|
||||
`en-gb`,
|
||||
`en-us`,
|
||||
`es-es`,
|
||||
`et-ee`,
|
||||
`fa-ir`,
|
||||
`fi-fi`,
|
||||
`fr-be`,
|
||||
`fr-ca`,
|
||||
`fr-fr`,
|
||||
`ga-ie`,
|
||||
`gl-es`,
|
||||
`he-il`,
|
||||
`hi-in`,
|
||||
`hr-hr`,
|
||||
`hu-hu`,
|
||||
`hy-am`,
|
||||
`id-id`,
|
||||
`is-is`,
|
||||
`it-it`,
|
||||
`ja-jp`,
|
||||
`ka-ge`,
|
||||
`kk-kz`,
|
||||
`km-kh`,
|
||||
`kmr-iq`,
|
||||
`kn-in`,
|
||||
`ko-kr`,
|
||||
`lt-lt`,
|
||||
`lv-lv`,
|
||||
`mk-mk`,
|
||||
`ml-in`,
|
||||
`mn-mn`,
|
||||
`ms-my`,
|
||||
`nb-no`,
|
||||
`ne-np`,
|
||||
`nl-be`,
|
||||
`nl-nl`,
|
||||
`pl-pl`,
|
||||
`pt-br`,
|
||||
`pt-pt`,
|
||||
`ro-ro`,
|
||||
`ru-ru`,
|
||||
`sk-sk`,
|
||||
`sl-si`,
|
||||
`sr-rs`,
|
||||
`sv-se`,
|
||||
`ta-in`,
|
||||
`th-th`,
|
||||
`tr-tr`,
|
||||
`uk-ua`,
|
||||
`ur-pk`,
|
||||
`vi-vn`,
|
||||
`zh-cn`,
|
||||
`zh-hk`,
|
||||
`zh-tw`,
|
||||
];
|
||||
32
client/mdui_patched/internal/localize.d.ts
vendored
Normal file
32
client/mdui_patched/internal/localize.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import { targetLocales } from './localeCodes.js';
|
||||
import type { allLocales } from './localeCodes.js';
|
||||
import type { LocaleModule, LocaleStatusEventDetail } from '@lit/localize';
|
||||
export type LocaleTargetCode = (typeof targetLocales)[number];
|
||||
export type LocaleCode = (typeof allLocales)[number];
|
||||
export type LoadFunc = (locale: LocaleTargetCode) => Promise<LocaleModule>;
|
||||
export type GetLocal = () => LocaleCode;
|
||||
export type SetLocal = (locale: LocaleCode) => Promise<void>;
|
||||
declare global {
|
||||
interface WindowEventMap {
|
||||
'mdui-localize-status': CustomEvent<LocaleStatusEventDetail>;
|
||||
}
|
||||
}
|
||||
export declare const uninitializedError = "You must call `loadLocale` first to set up the localized template.";
|
||||
export declare let getLocale: GetLocal | undefined;
|
||||
export declare let setLocale: SetLocal | undefined;
|
||||
/**
|
||||
* 初始化 localization
|
||||
* @param loadFunc
|
||||
*/
|
||||
export declare const initializeLocalize: (loadFunc: LoadFunc) => void;
|
||||
/**
|
||||
* 监听 localize ready 事件
|
||||
* @param target
|
||||
* @param callback
|
||||
*/
|
||||
export declare const onLocaleReady: (target: HTMLElement, callback: () => void) => void;
|
||||
/**
|
||||
* 取消监听 localize ready 事件
|
||||
* @param target
|
||||
*/
|
||||
export declare const offLocaleReady: (target: HTMLElement) => void;
|
||||
55
client/mdui_patched/internal/localize.js
Normal file
55
client/mdui_patched/internal/localize.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import { configureLocalization, LOCALE_STATUS_EVENT } from '@lit/localize';
|
||||
import { getWindow } from 'ssr-window';
|
||||
import { sourceLocale, targetLocales } from './localeCodes.js';
|
||||
export const uninitializedError = 'You must call `loadLocale` first to set up the localized template.';
|
||||
export let getLocale;
|
||||
export let setLocale;
|
||||
/**
|
||||
* 初始化 localization
|
||||
* @param loadFunc
|
||||
*/
|
||||
export const initializeLocalize = (loadFunc) => {
|
||||
const window = getWindow();
|
||||
const result = configureLocalization({
|
||||
sourceLocale,
|
||||
targetLocales,
|
||||
loadLocale: loadFunc,
|
||||
});
|
||||
getLocale = result.getLocale;
|
||||
setLocale = result.setLocale;
|
||||
window.addEventListener(LOCALE_STATUS_EVENT, (event) => {
|
||||
window.dispatchEvent(new CustomEvent('mdui-localize-status', {
|
||||
detail: event.detail,
|
||||
}));
|
||||
});
|
||||
};
|
||||
let listeningLitLocalizeStatus = false;
|
||||
const localeReadyCallbacksMap = new Map();
|
||||
/**
|
||||
* 监听 localize ready 事件
|
||||
* @param target
|
||||
* @param callback
|
||||
*/
|
||||
export const onLocaleReady = (target, callback) => {
|
||||
if (!listeningLitLocalizeStatus) {
|
||||
listeningLitLocalizeStatus = true;
|
||||
const window = getWindow();
|
||||
window.addEventListener(LOCALE_STATUS_EVENT, (event) => {
|
||||
if (event.detail.status === 'ready') {
|
||||
localeReadyCallbacksMap.forEach((callbacks) => {
|
||||
callbacks.forEach((cb) => cb());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
const callbacks = localeReadyCallbacksMap.get(target) || [];
|
||||
callbacks.push(callback);
|
||||
localeReadyCallbacksMap.set(target, callbacks);
|
||||
};
|
||||
/**
|
||||
* 取消监听 localize ready 事件
|
||||
* @param target
|
||||
*/
|
||||
export const offLocaleReady = (target) => {
|
||||
localeReadyCallbacksMap.delete(target);
|
||||
};
|
||||
1
client/mdui_patched/internal/theme.d.ts
vendored
Normal file
1
client/mdui_patched/internal/theme.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export type Theme = 'light' | 'dark' | 'auto';
|
||||
1
client/mdui_patched/internal/theme.js
Normal file
1
client/mdui_patched/internal/theme.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Reference in New Issue
Block a user