Skip to content

Commit 746c5f0

Browse files
committed
refactor(utils): move openUrl to helpers
1 parent cca089f commit 746c5f0

File tree

2 files changed

+0
-213
lines changed

2 files changed

+0
-213
lines changed

core/src/utils/helpers.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -456,22 +456,3 @@ export const openURL = async (
456456
}
457457
return false;
458458
};
459-
460-
/**
461-
* Deep merges two objects, with source properties overriding target properties
462-
* @param target The target object to merge into
463-
* @param source The source object to merge from
464-
* @returns The merged object
465-
*/
466-
export const deepMerge = (target: any, source: any): any => {
467-
const result = { ...target };
468-
469-
for (const key in source) {
470-
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
471-
result[key] = deepMerge(result[key] ?? {}, source[key]);
472-
} else {
473-
result[key] = source[key];
474-
}
475-
}
476-
return result;
477-
};

core/src/utils/theme.ts

Lines changed: 0 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import type { Color, CssClassMap } from '../interface';
22

3-
import { deepMerge } from './helpers';
4-
5-
export const CSS_PROPS_PREFIX = '--ion-';
6-
export const CSS_ROOT_SELECTOR = ':root';
7-
83
export const hostContext = (selector: string, el: HTMLElement): boolean => {
94
return el.closest(selector) !== null;
105
};
@@ -38,192 +33,3 @@ export const getClassMap = (classes: string | string[] | undefined): CssClassMap
3833
getClassList(classes).forEach((c) => (map[c] = true));
3934
return map;
4035
};
41-
42-
/**
43-
* Flattens the theme object into CSS custom properties
44-
* @param theme The theme object to flatten
45-
* @param prefix The CSS prefix to use (e.g., '--ion-')
46-
* @returns CSS string with custom properties
47-
*/
48-
export const generateCSSVars = (theme: any, prefix: string = CSS_PROPS_PREFIX): string => {
49-
const cssProps = Object.entries(theme)
50-
.flatMap(([key, val]) => {
51-
// Skip invalid keys or values
52-
if (!key || typeof key !== 'string' || val === null || val === undefined) {
53-
return [];
54-
}
55-
56-
// if key is camelCase, convert to kebab-case
57-
if (key.match(/([a-z])([A-Z])/g)) {
58-
key = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
59-
}
60-
61-
// Special handling for 'base' property - don't add suffix
62-
if (key === 'base') {
63-
return [`${prefix.slice(0, -1)}: ${val};`];
64-
}
65-
66-
// If it's a font-sizes key, create rem version
67-
// This is necessary to support the dynamic font size feature
68-
if (key === 'font-sizes' && typeof val === 'object' && val !== null) {
69-
// Access the root font size from the global theme context
70-
const fontSizeBase = parseFloat((window as any).Ionic?.config?.get?.('theme')?.fontSizes?.root ?? '16');
71-
return Object.entries(val).flatMap(([sizeKey, sizeValue]) => {
72-
if (!sizeKey || sizeValue == null) return [];
73-
const remValue = `${parseFloat(sizeValue) / fontSizeBase}rem`;
74-
// Return both px and rem values as separate array items
75-
return [
76-
`${prefix}${key}-${sizeKey}: ${sizeValue};`, // original px value
77-
`${prefix}${key}-${sizeKey}-rem: ${remValue};`, // rem value
78-
];
79-
});
80-
}
81-
82-
return typeof val === 'object' && val !== null
83-
? generateCSSVars(val, `${prefix}${key}-`)
84-
: [`${prefix}${key}: ${val};`];
85-
})
86-
.filter(Boolean);
87-
88-
return cssProps.join('\n');
89-
};
90-
91-
/**
92-
* Creates a style element and injects its CSS into a target element
93-
* @param css The CSS string to inject
94-
* @param target The target element to inject into
95-
*/
96-
export const injectCSS = (css: string, target: Element | ShadowRoot = document.head) => {
97-
const style = document.createElement('style');
98-
style.innerHTML = css;
99-
target.appendChild(style);
100-
};
101-
102-
/**
103-
* Generates global CSS variables from a theme object
104-
* @param theme The theme object to generate CSS for
105-
* @returns The generated CSS string
106-
*/
107-
export const generateGlobalThemeCSS = (theme: any): string => {
108-
if (typeof theme !== 'object' || Array.isArray(theme)) {
109-
console.warn('generateGlobalThemeCSS: Invalid theme object provided', theme);
110-
return '';
111-
}
112-
113-
if (Object.keys(theme).length === 0) {
114-
console.warn('generateGlobalThemeCSS: Empty theme object provided');
115-
return '';
116-
}
117-
118-
// Exclude components and palette from the default tokens
119-
const { palette, components, ...defaultTokens } = theme;
120-
121-
// Generate CSS variables for the default design tokens
122-
const defaultTokensCSS = generateCSSVars(defaultTokens);
123-
124-
// Generate CSS variables for the light color palette
125-
const lightTokensCSS = generateCSSVars(palette.light);
126-
127-
let css = `
128-
${CSS_ROOT_SELECTOR} {
129-
${defaultTokensCSS}
130-
${lightTokensCSS}
131-
}
132-
`;
133-
134-
// Generate CSS variables for the dark color palette if it
135-
// is enabled for system preference
136-
if (palette.dark.enabled === 'system') {
137-
const darkTokensCSS = generateCSSVars(palette.dark);
138-
if (darkTokensCSS.length > 0) {
139-
css += `
140-
@media (prefers-color-scheme: dark) {
141-
${CSS_ROOT_SELECTOR} {
142-
${darkTokensCSS}
143-
}
144-
}
145-
`;
146-
}
147-
}
148-
149-
return css;
150-
};
151-
152-
/**
153-
* Applies the global theme from the provided base theme and user theme
154-
* @param baseTheme The default theme
155-
* @param userTheme The user's custom theme (optional)
156-
* @returns The combined theme object (or base theme if no user theme was provided)
157-
*/
158-
export const applyGlobalTheme = (baseTheme: any, userTheme?: any): any => {
159-
// If no base theme provided, error
160-
if (typeof baseTheme !== 'object' || Array.isArray(baseTheme)) {
161-
console.error('applyGlobalTheme: Valid base theme object is required', baseTheme);
162-
return {};
163-
}
164-
165-
// If no user theme provided or it is invalid, apply base theme
166-
if (!userTheme || typeof userTheme !== 'object' || Array.isArray(userTheme)) {
167-
if (userTheme) {
168-
console.error('applyGlobalTheme: Invalid user theme provided', userTheme);
169-
}
170-
injectCSS(generateGlobalThemeCSS(baseTheme));
171-
return baseTheme;
172-
}
173-
174-
// Merge themes and apply
175-
const mergedTheme = deepMerge(baseTheme, userTheme);
176-
injectCSS(generateGlobalThemeCSS(mergedTheme));
177-
return mergedTheme;
178-
};
179-
180-
/**
181-
* Generates component's themed CSS class with CSS variables
182-
* from its theme object
183-
* @param componentTheme The component's object to generate CSS for (e.g., IonChip { })
184-
* @param componentName The component name without any prefixes (e.g., 'chip')
185-
* @returns string containing the component's themed CSS variables
186-
*/
187-
export const generateComponentThemeCSS = (componentTheme: any, componentName: string): string => {
188-
const cssProps = generateCSSVars(componentTheme, `${CSS_PROPS_PREFIX}${componentName}-`);
189-
190-
return `
191-
:host(.${componentName}-themed) {
192-
${cssProps}
193-
}
194-
`;
195-
};
196-
197-
/**
198-
* Applies a component theme to an element if it exists in the custom theme
199-
* @param element The element to apply the theme to
200-
* @returns true if theme was applied, false otherwise
201-
*/
202-
export const applyComponentTheme = (element: HTMLElement): void => {
203-
const customTheme = (window as any).Ionic?.config?.get?.('customTheme');
204-
205-
// Convert 'ION-CHIP' to 'ion-chip' and split into parts
206-
const parts = element.tagName.toLowerCase().split('-');
207-
208-
// Get the component name 'chip' from the second part
209-
const componentName = parts[1];
210-
211-
// Convert to 'IonChip' by capitalizing each part
212-
const themeLookupName = parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('');
213-
214-
if (customTheme?.components?.[themeLookupName]) {
215-
const componentTheme = customTheme.components[themeLookupName];
216-
217-
// Add the theme class to the element (e.g., 'chip-themed')
218-
const themeClass = `${componentName}-themed`;
219-
element.classList.add(themeClass);
220-
221-
// Generate CSS custom properties inside a theme class selector
222-
const css = generateComponentThemeCSS(componentTheme, componentName);
223-
224-
// Inject styles into shadow root if available,
225-
// otherwise into the element itself
226-
const root = element.shadowRoot ?? element;
227-
injectCSS(css, root);
228-
}
229-
};

0 commit comments

Comments
 (0)