@veltra/styles 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- /* empty css */
2
- /* empty css */
3
- /* empty css */
4
- /* empty css */
5
- /* empty css */
1
+ import "./normalize.css";
2
+ import "./anime/fade.css";
3
+ import "./anime/slide.css";
4
+ import "./anime/spring.css";
5
+ import "./anime/zoom-in.css";
@@ -4,7 +4,6 @@ import { Theme } from "./type.js";
4
4
  type RecursivePartial<T> = { [P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P] };
5
5
  declare class UITheme {
6
6
  static themeID: string;
7
- private static legacyDeprecationWarned;
8
7
  private static adoptedSheet;
9
8
  readonly theme: Theme;
10
9
  private readonly reactiveEnabled;
@@ -18,10 +17,8 @@ declare class UITheme {
18
17
  private renderShadow;
19
18
  private renderBGColorAlpha;
20
19
  private renderBGFilter;
21
- /** 主题变量声明(不含 legacy 副本) */
20
+ /** 主题变量声明列表,均为 `--u-` 前缀的 CSS 自定义属性 */
22
21
  themeToDeclarationList(theme: Theme): string[];
23
- private static withLegacyDuplicates;
24
- private static warnLegacyOnce;
25
22
  private static declarationBlock;
26
23
  private static removeExistingStyleTag;
27
24
  private static applyGlobalCSS;
@@ -4,18 +4,8 @@ import { isObj, o, str } from "@cat-kit/core";
4
4
  import { withUnit } from "@veltra/utils";
5
5
  import { reactive, toRaw, watch } from "vue";
6
6
  //#region src/theme/ui-theme.ts
7
- function isDevEnv() {
8
- try {
9
- if (typeof import.meta !== "undefined") {
10
- if (import.meta.env?.DEV === true) return true;
11
- }
12
- } catch {}
13
- const proc = globalThis.process;
14
- return typeof proc !== "undefined" && proc.env?.NODE_ENV !== "production";
15
- }
16
7
  var UITheme = class UITheme {
17
8
  static themeID = "ultra-ui-theme";
18
- static legacyDeprecationWarned = false;
19
9
  static adoptedSheet = null;
20
10
  theme;
21
11
  reactiveEnabled;
@@ -79,7 +69,7 @@ var UITheme = class UITheme {
79
69
  const { filter } = theme.bg;
80
70
  return `--u-bg-filter: ${filter.blur} ${filter.saturate}`;
81
71
  }
82
- /** 主题变量声明(不含 legacy 副本) */
72
+ /** 主题变量声明列表,均为 `--u-` 前缀的 CSS 自定义属性 */
83
73
  themeToDeclarationList(theme) {
84
74
  const raw = theme;
85
75
  const lines = [...this.renderBase(raw)];
@@ -93,26 +83,8 @@ var UITheme = class UITheme {
93
83
  for (const c of chunks) lines.push(...c.split(";").map((s) => s.trim()).filter(Boolean));
94
84
  return lines;
95
85
  }
96
- static withLegacyDuplicates(decls) {
97
- const legacy = [];
98
- for (const decl of decls) {
99
- const idx = decl.indexOf(":");
100
- if (idx === -1) continue;
101
- const name = decl.slice(0, idx).trim();
102
- const value = decl.slice(idx + 1).trim();
103
- if (name.startsWith("--u-")) legacy.push(`--${name.slice(4)}: ${value}`);
104
- }
105
- return [...decls, ...legacy].join(";");
106
- }
107
- static warnLegacyOnce() {
108
- if (!isDevEnv() || UITheme.legacyDeprecationWarned) return;
109
- UITheme.legacyDeprecationWarned = true;
110
- console.warn("[@veltra/styles] Theme CSS variables now prefer the `--u-` namespace. Unprefixed aliases (e.g. `--color-primary`) are deprecated and will be removed in a future major version.");
111
- }
112
86
  static declarationBlock(decls) {
113
- const merged = UITheme.withLegacyDuplicates(decls);
114
- UITheme.warnLegacyOnce();
115
- return merged;
87
+ return decls.join(";");
116
88
  }
117
89
  static removeExistingStyleTag(doc) {
118
90
  const el = doc.getElementById(UITheme.themeID);
@@ -1 +1 @@
1
- {"version":3,"file":"ui-theme.js","names":[],"sources":["../../src/theme/ui-theme.ts"],"sourcesContent":["import { isObj, o, str } from '@cat-kit/core'\nimport { withUnit } from '@veltra/utils'\nimport { reactive, toRaw, watch } from 'vue'\n\nimport { componentCssVarsDarkDecls, componentCssVarsLightDecls } from './component-css-vars'\nimport { mixColor } from './helper'\nimport type { Theme } from './type'\n\ntype RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P]\n}\n\nfunction isDevEnv(): boolean {\n try {\n if (typeof import.meta !== 'undefined') {\n const env = (import.meta as { env?: { DEV?: boolean } }).env\n if (env?.DEV === true) return true\n }\n } catch {\n /* ignore */\n }\n const proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process\n return typeof proc !== 'undefined' && proc.env?.NODE_ENV !== 'production'\n}\n\nexport class UITheme {\n static themeID = 'ultra-ui-theme'\n\n private static legacyDeprecationWarned = false\n\n private static adoptedSheet: CSSStyleSheet | null = null\n\n readonly theme: Theme\n\n private readonly reactiveEnabled: boolean\n\n constructor(theme: Theme, options?: { reactive?: boolean }) {\n this.reactiveEnabled = options?.reactive !== false\n this.theme = reactive(theme) as Theme\n if (this.reactiveEnabled) {\n watch(this.theme, () => this.render(), { deep: true })\n }\n }\n\n static setTheme(mode: 'light' | 'dark' | 'auto'): void {\n if (typeof document === 'undefined') return\n const el = document.documentElement\n if (mode === 'auto') {\n delete el.dataset.theme\n } else {\n el.dataset.theme = mode\n }\n }\n\n private renderBase(\n theme: Record<string, unknown>,\n themeRules: string[] = [],\n parentKey = '--u'\n ): string[] {\n Object.keys(theme).forEach((key) => {\n const value = theme[key]\n const varKey = `${parentKey.startsWith('-') ? parentKey : str(parentKey).kebabCase()}-${str(key).kebabCase()}`\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n this.renderBase(value as Record<string, unknown>, themeRules, varKey)\n } else {\n if (value || value === 0) {\n const v = withUnit(value as number | string, 'px')\n if (v !== undefined) {\n themeRules.push(`${varKey}: ${v}`)\n }\n }\n }\n })\n\n return themeRules\n }\n\n private renderBorder(theme: Theme): string {\n const border = Object.keys(theme.border)\n .map((key) => `var(--u-border-${key})`)\n .join(' ')\n\n return `--u-border: ${border}`\n }\n\n private renderTypeColor(theme: Theme): string {\n const { color } = theme\n\n const types = Object.keys(color)\n const rates = [1, 3, 5, 7, 9]\n\n return types\n .map((type) => {\n const colorValue = color[type as keyof typeof color]! as `#${string}`\n\n return rates\n .map((rate) => {\n const light = `--u-color-${type}-light-${rate}: ${mixColor(\n colorValue,\n '#fff',\n rate / 10\n )}`\n const dark = `--u-color-${type}-dark-${rate}: ${mixColor(\n colorValue,\n '#000',\n rate / 10\n )}`\n return `${light};${dark}`\n })\n .join(';')\n })\n .join(';')\n }\n\n private renderShadow(_theme: Theme): string {\n const shadow = ['x', 'y', 'blur', 'spread', 'color']\n .map((k) => `var(--u-shadow-${k})`)\n .join(' ')\n\n return `--u-shadow: ${shadow}`\n }\n\n private renderBGColorAlpha(theme: Theme): string {\n const { color } = theme.bg\n return Object.keys(color)\n .map((type) => `--u-bg-color-${type}-alpha: ${color[type as keyof typeof color]}aa`)\n .join(';')\n }\n\n private renderBGFilter(theme: Theme): string {\n const { filter } = theme.bg\n return `--u-bg-filter: ${filter.blur} ${filter.saturate}`\n }\n\n /** 主题变量声明(不含 legacy 副本) */\n themeToDeclarationList(theme: Theme): string[] {\n const raw = theme as unknown as Record<string, unknown>\n const lines: string[] = [...this.renderBase(raw)]\n const chunks = [\n this.renderTypeColor(theme),\n this.renderShadow(theme),\n this.renderBGColorAlpha(theme),\n this.renderBGFilter(theme),\n this.renderBorder(theme)\n ]\n for (const c of chunks) {\n lines.push(\n ...c\n .split(';')\n .map((s) => s.trim())\n .filter(Boolean)\n )\n }\n return lines\n }\n\n private static withLegacyDuplicates(decls: string[]): string {\n const legacy: string[] = []\n for (const decl of decls) {\n const idx = decl.indexOf(':')\n if (idx === -1) continue\n const name = decl.slice(0, idx).trim()\n const value = decl.slice(idx + 1).trim()\n if (name.startsWith('--u-')) {\n legacy.push(`--${name.slice(4)}: ${value}`)\n }\n }\n return [...decls, ...legacy].join(';')\n }\n\n private static warnLegacyOnce(): void {\n if (!isDevEnv() || UITheme.legacyDeprecationWarned) return\n UITheme.legacyDeprecationWarned = true\n console.warn(\n '[@veltra/styles] Theme CSS variables now prefer the `--u-` namespace. ' +\n 'Unprefixed aliases (e.g. `--color-primary`) are deprecated and will be removed in a future major version.'\n )\n }\n\n private static declarationBlock(decls: string[]): string {\n const merged = UITheme.withLegacyDuplicates(decls)\n UITheme.warnLegacyOnce()\n return merged\n }\n\n private static removeExistingStyleTag(doc: Document): void {\n const el = doc.getElementById(UITheme.themeID)\n if (el?.parentNode) {\n el.parentNode.removeChild(el)\n }\n }\n\n private static applyGlobalCSS(css: string): void {\n const doc = typeof document !== 'undefined' ? document : undefined\n if (!doc) return\n\n const canAdopt =\n typeof CSSStyleSheet !== 'undefined' && 'adoptedStyleSheets' in Document.prototype\n\n if (canAdopt) {\n UITheme.removeExistingStyleTag(doc)\n if (!UITheme.adoptedSheet) {\n UITheme.adoptedSheet = new CSSStyleSheet()\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, UITheme.adoptedSheet]\n }\n UITheme.adoptedSheet.replaceSync(css)\n } else {\n if (UITheme.adoptedSheet) {\n UITheme.adoptedSheet = null\n }\n let style = doc.getElementById(UITheme.themeID)\n if (!style) {\n style = doc.createElement('style')\n style.id = UITheme.themeID\n doc.head.appendChild(style)\n }\n style.textContent = css\n }\n }\n\n /** 内置 light/dark:支持 data-theme 与 prefers-color-scheme */\n static injectBuiltInThemes(light: UITheme, dark: UITheme): void {\n const lightDecls = [\n ...light.themeToDeclarationList(toRaw(light.theme)),\n ...componentCssVarsLightDecls\n ]\n const darkDecls = [\n ...dark.themeToDeclarationList(toRaw(dark.theme)),\n ...componentCssVarsDarkDecls\n ]\n const lightBlock = UITheme.declarationBlock(lightDecls)\n const darkBlock = UITheme.declarationBlock(darkDecls)\n\n const css = [\n `html { ${lightBlock} }`,\n `@media (prefers-color-scheme: dark) {`,\n ` html:not([data-theme=\"light\"]) { ${darkBlock} }`,\n `}`,\n `html[data-theme=\"light\"] { ${lightBlock} }`,\n `html[data-theme=\"dark\"] { ${darkBlock} }`\n ].join('\\n')\n\n UITheme.applyGlobalCSS(css)\n }\n\n render(): void {\n const decls = [...this.themeToDeclarationList(toRaw(this.theme)), ...componentCssVarsLightDecls]\n const block = UITheme.declarationBlock(decls)\n const css = `html { ${block} }`\n UITheme.applyGlobalCSS(css)\n }\n\n new(customTheme: RecursivePartial<Theme> = {}): UITheme {\n function delEmpty(obj: Record<string, unknown>) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key]\n if (isObj(value)) {\n return delEmpty(value as Record<string, unknown>)\n }\n if (!value && value !== 0) {\n delete obj[key]\n }\n })\n }\n\n delEmpty(customTheme as Record<string, unknown>)\n\n const base = JSON.parse(JSON.stringify(toRaw(this.theme))) as Record<string, any>\n o(base).deepExtend(customTheme as Record<string, any>)\n return new UITheme(base as Theme, { reactive: this.reactiveEnabled })\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ui-theme.js","names":[],"sources":["../../src/theme/ui-theme.ts"],"sourcesContent":["import { isObj, o, str } from '@cat-kit/core'\nimport { withUnit } from '@veltra/utils'\nimport { reactive, toRaw, watch } from 'vue'\n\nimport { componentCssVarsDarkDecls, componentCssVarsLightDecls } from './component-css-vars'\nimport { mixColor } from './helper'\nimport type { Theme } from './type'\n\ntype RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P]\n}\n\nexport class UITheme {\n static themeID = 'ultra-ui-theme'\n\n private static adoptedSheet: CSSStyleSheet | null = null\n\n readonly theme: Theme\n\n private readonly reactiveEnabled: boolean\n\n constructor(theme: Theme, options?: { reactive?: boolean }) {\n this.reactiveEnabled = options?.reactive !== false\n this.theme = reactive(theme) as Theme\n if (this.reactiveEnabled) {\n watch(this.theme, () => this.render(), { deep: true })\n }\n }\n\n static setTheme(mode: 'light' | 'dark' | 'auto'): void {\n if (typeof document === 'undefined') return\n const el = document.documentElement\n if (mode === 'auto') {\n delete el.dataset.theme\n } else {\n el.dataset.theme = mode\n }\n }\n\n private renderBase(\n theme: Record<string, unknown>,\n themeRules: string[] = [],\n parentKey = '--u'\n ): string[] {\n Object.keys(theme).forEach((key) => {\n const value = theme[key]\n const varKey = `${parentKey.startsWith('-') ? parentKey : str(parentKey).kebabCase()}-${str(key).kebabCase()}`\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n this.renderBase(value as Record<string, unknown>, themeRules, varKey)\n } else {\n if (value || value === 0) {\n const v = withUnit(value as number | string, 'px')\n if (v !== undefined) {\n themeRules.push(`${varKey}: ${v}`)\n }\n }\n }\n })\n\n return themeRules\n }\n\n private renderBorder(theme: Theme): string {\n const border = Object.keys(theme.border)\n .map((key) => `var(--u-border-${key})`)\n .join(' ')\n\n return `--u-border: ${border}`\n }\n\n private renderTypeColor(theme: Theme): string {\n const { color } = theme\n\n const types = Object.keys(color)\n const rates = [1, 3, 5, 7, 9]\n\n return types\n .map((type) => {\n const colorValue = color[type as keyof typeof color]! as `#${string}`\n\n return rates\n .map((rate) => {\n const light = `--u-color-${type}-light-${rate}: ${mixColor(\n colorValue,\n '#fff',\n rate / 10\n )}`\n const dark = `--u-color-${type}-dark-${rate}: ${mixColor(\n colorValue,\n '#000',\n rate / 10\n )}`\n return `${light};${dark}`\n })\n .join(';')\n })\n .join(';')\n }\n\n private renderShadow(_theme: Theme): string {\n const shadow = ['x', 'y', 'blur', 'spread', 'color']\n .map((k) => `var(--u-shadow-${k})`)\n .join(' ')\n\n return `--u-shadow: ${shadow}`\n }\n\n private renderBGColorAlpha(theme: Theme): string {\n const { color } = theme.bg\n return Object.keys(color)\n .map((type) => `--u-bg-color-${type}-alpha: ${color[type as keyof typeof color]}aa`)\n .join(';')\n }\n\n private renderBGFilter(theme: Theme): string {\n const { filter } = theme.bg\n return `--u-bg-filter: ${filter.blur} ${filter.saturate}`\n }\n\n /** 主题变量声明列表,均为 `--u-` 前缀的 CSS 自定义属性 */\n themeToDeclarationList(theme: Theme): string[] {\n const raw = theme as unknown as Record<string, unknown>\n const lines: string[] = [...this.renderBase(raw)]\n const chunks = [\n this.renderTypeColor(theme),\n this.renderShadow(theme),\n this.renderBGColorAlpha(theme),\n this.renderBGFilter(theme),\n this.renderBorder(theme)\n ]\n for (const c of chunks) {\n lines.push(\n ...c\n .split(';')\n .map((s) => s.trim())\n .filter(Boolean)\n )\n }\n return lines\n }\n\n private static declarationBlock(decls: string[]): string {\n return decls.join(';')\n }\n\n private static removeExistingStyleTag(doc: Document): void {\n const el = doc.getElementById(UITheme.themeID)\n if (el?.parentNode) {\n el.parentNode.removeChild(el)\n }\n }\n\n private static applyGlobalCSS(css: string): void {\n const doc = typeof document !== 'undefined' ? document : undefined\n if (!doc) return\n\n const canAdopt =\n typeof CSSStyleSheet !== 'undefined' && 'adoptedStyleSheets' in Document.prototype\n\n if (canAdopt) {\n UITheme.removeExistingStyleTag(doc)\n if (!UITheme.adoptedSheet) {\n UITheme.adoptedSheet = new CSSStyleSheet()\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, UITheme.adoptedSheet]\n }\n UITheme.adoptedSheet.replaceSync(css)\n } else {\n if (UITheme.adoptedSheet) {\n UITheme.adoptedSheet = null\n }\n let style = doc.getElementById(UITheme.themeID)\n if (!style) {\n style = doc.createElement('style')\n style.id = UITheme.themeID\n doc.head.appendChild(style)\n }\n style.textContent = css\n }\n }\n\n /** 内置 light/dark:支持 data-theme 与 prefers-color-scheme */\n static injectBuiltInThemes(light: UITheme, dark: UITheme): void {\n const lightDecls = [\n ...light.themeToDeclarationList(toRaw(light.theme)),\n ...componentCssVarsLightDecls\n ]\n const darkDecls = [\n ...dark.themeToDeclarationList(toRaw(dark.theme)),\n ...componentCssVarsDarkDecls\n ]\n const lightBlock = UITheme.declarationBlock(lightDecls)\n const darkBlock = UITheme.declarationBlock(darkDecls)\n\n const css = [\n `html { ${lightBlock} }`,\n `@media (prefers-color-scheme: dark) {`,\n ` html:not([data-theme=\"light\"]) { ${darkBlock} }`,\n `}`,\n `html[data-theme=\"light\"] { ${lightBlock} }`,\n `html[data-theme=\"dark\"] { ${darkBlock} }`\n ].join('\\n')\n\n UITheme.applyGlobalCSS(css)\n }\n\n render(): void {\n const decls = [...this.themeToDeclarationList(toRaw(this.theme)), ...componentCssVarsLightDecls]\n const block = UITheme.declarationBlock(decls)\n const css = `html { ${block} }`\n UITheme.applyGlobalCSS(css)\n }\n\n new(customTheme: RecursivePartial<Theme> = {}): UITheme {\n function delEmpty(obj: Record<string, unknown>) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key]\n if (isObj(value)) {\n return delEmpty(value as Record<string, unknown>)\n }\n if (!value && value !== 0) {\n delete obj[key]\n }\n })\n }\n\n delEmpty(customTheme as Record<string, unknown>)\n\n const base = JSON.parse(JSON.stringify(toRaw(this.theme))) as Record<string, any>\n o(base).deepExtend(customTheme as Record<string, any>)\n return new UITheme(base as Theme, { reactive: this.reactiveEnabled })\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltra/styles",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -55,13 +55,13 @@
55
55
  }
56
56
  },
57
57
  "scripts": {
58
- "build": "tsdown && bun scripts/copy-scss.ts",
58
+ "build": "tsdown",
59
59
  "check-types": "tsc -p tsconfig.json --noEmit"
60
60
  },
61
61
  "dependencies": {
62
62
  "@cat-kit/core": "^1.1.1",
63
- "@veltra/compositions": "1.0.9",
64
- "@veltra/utils": "1.0.9"
63
+ "@veltra/compositions": "1.0.10",
64
+ "@veltra/utils": "1.0.10"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "vue": "^3.5.33"
@@ -10,24 +10,9 @@ type RecursivePartial<T> = {
10
10
  [P in keyof T]?: T[P] extends object ? RecursivePartial<T[P]> : T[P]
11
11
  }
12
12
 
13
- function isDevEnv(): boolean {
14
- try {
15
- if (typeof import.meta !== 'undefined') {
16
- const env = (import.meta as { env?: { DEV?: boolean } }).env
17
- if (env?.DEV === true) return true
18
- }
19
- } catch {
20
- /* ignore */
21
- }
22
- const proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process
23
- return typeof proc !== 'undefined' && proc.env?.NODE_ENV !== 'production'
24
- }
25
-
26
13
  export class UITheme {
27
14
  static themeID = 'ultra-ui-theme'
28
15
 
29
- private static legacyDeprecationWarned = false
30
-
31
16
  private static adoptedSheet: CSSStyleSheet | null = null
32
17
 
33
18
  readonly theme: Theme
@@ -132,7 +117,7 @@ export class UITheme {
132
117
  return `--u-bg-filter: ${filter.blur} ${filter.saturate}`
133
118
  }
134
119
 
135
- /** 主题变量声明(不含 legacy 副本) */
120
+ /** 主题变量声明列表,均为 `--u-` 前缀的 CSS 自定义属性 */
136
121
  themeToDeclarationList(theme: Theme): string[] {
137
122
  const raw = theme as unknown as Record<string, unknown>
138
123
  const lines: string[] = [...this.renderBase(raw)]
@@ -154,33 +139,8 @@ export class UITheme {
154
139
  return lines
155
140
  }
156
141
 
157
- private static withLegacyDuplicates(decls: string[]): string {
158
- const legacy: string[] = []
159
- for (const decl of decls) {
160
- const idx = decl.indexOf(':')
161
- if (idx === -1) continue
162
- const name = decl.slice(0, idx).trim()
163
- const value = decl.slice(idx + 1).trim()
164
- if (name.startsWith('--u-')) {
165
- legacy.push(`--${name.slice(4)}: ${value}`)
166
- }
167
- }
168
- return [...decls, ...legacy].join(';')
169
- }
170
-
171
- private static warnLegacyOnce(): void {
172
- if (!isDevEnv() || UITheme.legacyDeprecationWarned) return
173
- UITheme.legacyDeprecationWarned = true
174
- console.warn(
175
- '[@veltra/styles] Theme CSS variables now prefer the `--u-` namespace. ' +
176
- 'Unprefixed aliases (e.g. `--color-primary`) are deprecated and will be removed in a future major version.'
177
- )
178
- }
179
-
180
142
  private static declarationBlock(decls: string[]): string {
181
- const merged = UITheme.withLegacyDuplicates(decls)
182
- UITheme.warnLegacyOnce()
183
- return merged
143
+ return decls.join(';')
184
144
  }
185
145
 
186
146
  private static removeExistingStyleTag(doc: Document): void {