feat(chip): adding ionic theme

This commit is contained in:
Maria Hutt
2025-12-17 18:15:04 -08:00
parent 7040091786
commit 098cba4096
12 changed files with 469 additions and 62 deletions

View File

@@ -890,10 +890,10 @@ export namespace Components {
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"medium"`.
* @default 'medium'
* Set to `"small"` for a chip with less height and padding. Defaults to `"small"`.
* @default 'large'
*/
"size"?: 'small' | 'medium' | 'large';
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/
@@ -6861,10 +6861,10 @@ declare namespace LocalJSX {
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"medium"`.
* @default 'medium'
* Set to `"small"` for a chip with less height and padding. Defaults to `"small"`.
* @default 'large'
*/
"size"?: 'small' | 'medium' | 'large';
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/

View File

@@ -1,6 +1,7 @@
@use "../../themes/mixins" as mixins;
@use "../../themes/functions.color" as colors;
@use "./chip.base.vars.scss" as vars;
@use "sass:meta";
// Chip: Common Styles
// --------------------------------------------------
@@ -20,6 +21,7 @@
@include mixins.border-radius(var(--border-radius));
@include mixins.margin(vars.$chip-margin);
@include mixins.padding(vars.$chip-padding-vertical, vars.$chip-padding-horizontal);
@include mixins.typography(vars.$chip-typography);
display: inline-flex;
position: relative;
@@ -49,12 +51,6 @@
font-size: vars.$chip-size-small-font-size;
}
:host(.chip-medium) {
min-height: vars.$chip-size-medium-height;
font-size: vars.$chip-size-medium-font-size;
}
:host(.chip-large) {
min-height: vars.$chip-size-large-height;
@@ -110,6 +106,8 @@
:host(.ion-color.chip-bold.chip-outline) {
border-color: vars.$chip-hue-bold-semantic-outline-border-color;
background: vars.$chip-outline-bold-semantic-bg; //native would be transparent, else it would be whatevers in ion-color.chip-bold
}
// Subtle
@@ -120,6 +118,8 @@
:host(.ion-color.chip-subtle.chip-outline) {
border-color: colors.current-color(shade, $subtle: true);
background: vars.$chip-outline-subtle-semantic-bg;
}
// Outline Chip
@@ -130,11 +130,6 @@
border-style: solid;
}
:host(.chip-outline),
:host(.chip-outline.ion-color) {
background: vars.$chip-outline-bg;
}
// Chip States
// ---------------------------------------------
@@ -210,10 +205,14 @@
// Avatar
::slotted(ion-avatar) {
// width: vars.$chip-avatar-size;
// height: vars.$chip-avatar-size;
// @error vars.$chip-avatar-size;
@if vars.$chip-avatar-size != "unset" {
width: vars.$chip-avatar-size;
height: vars.$chip-avatar-size;
}
flex-shrink: 0;
width: vars.$chip-avatar-size;
height: vars.$chip-avatar-size;
}
::slotted(ion-avatar:first-child) {

View File

@@ -76,8 +76,14 @@ $chip-hue-bold-semantic-outline-border-color: var(--ion-chip-hue-bold-semantic-o
/// @prop - Outline border width
$chip-outline-border-width: var(--ion-chip-variant-outline-border-width);
/// @prop - Outline chip background color
$chip-outline-bg: var(--ion-chip-variant-outline-bg);
/// @prop - Outline bold chip background color for semantic colors
$chip-outline-bold-semantic-bg: var(--ion-chip-hue-bold-semantic-outline-bg);
/// @prop - Subtle chip background color for semantic colors
$chip-hue-subtle-semantic-bg: var(--ion-chip-hue-subtle-semantic-bg);
/// @prop - Outline subtle chip background color for semantic colors
$chip-outline-subtle-semantic-bg: var(--ion-chip-hue-subtle-semantic-outline-bg);
/// @prop - Focus ring color
$chip-focus-ring-color: var(--ion-chip-state-focus-ring-color);
@@ -128,7 +134,7 @@ $chip-icon-last-child-margin: var(--ion-chip-icon-last-child-margin);
$chip-icon-last-child-margin-start: var(--ion-chip-icon-last-child-margin-start);
/// @prop - Avatar size
$chip-avatar-size: var(--ion-chip-avatar-size);
$chip-avatar-size: var(--ion-chip-avatar-size, revert-layer);
/// @prop - Avatar margin vertical for first child
$chip-avatar-first-child-margin-vertical: var(--ion-chip-avatar-first-child-margin-vertical);
@@ -147,3 +153,14 @@ $chip-avatar-last-child-margin-start: var(--ion-chip-avatar-last-child-margin-st
/// @prop - Avatar margin end for last child
$chip-avatar-last-child-margin-end: var(--ion-chip-avatar-last-child-margin-end);
/// @prop - Typography styles for the chip
$chip-typography: (
font-family: var(--ion-chip-typography-font-family),
font-size: var(--ion-chip-typography-font-size),
font-weight: var(--ion-chip-typography-font-weight),
letter-spacing: var(--ion-chip-typography-letter-spacing),
line-height: var(--ion-chip-typography-line-height),
text-decoration: var(--ion-chip-typography-text-decoration),
text-transform: var(--ion-chip-typography-text-transform),
);

View File

@@ -64,9 +64,9 @@ export class Chip implements ComponentInterface {
/**
* Set to `"small"` for a chip with less height and padding.
*
* Defaults to `"medium"`.
* Defaults to `"small"`.
*/
@Prop() size?: 'small' | 'medium' | 'large' = 'medium';
@Prop() size?: 'small' | 'large' = 'large';
render() {
const { hue, size } = this;

View File

@@ -1,9 +1,22 @@
import * as colorTokens from 'outsystems-design-tokens/tokens/color scheme.json';
import * as primitiveTokens from 'outsystems-design-tokens/tokens/primitives.json';
import * as lightTokens from 'outsystems-design-tokens/tokens/theme/light.json';
import * as typographyTokens from 'outsystems-design-tokens/tokens/typography.json';
import { currentColor, cachedResolveOsToken } from '../../utils/theme';
import { defaultTheme as baseDefaultTheme } from '../base/default.tokens';
import type { DefaultTheme } from '../themes.interfaces';
import { darkTheme } from './dark.tokens';
import { lightTheme } from './light.tokens';
const tokenMap = {
colorTokens,
primitiveTokens,
lightTokens,
typographyTokens,
};
export const defaultTheme: DefaultTheme = {
...baseDefaultTheme,
@@ -76,4 +89,102 @@ export const defaultTheme: DefaultTheme = {
xxxl: 'var(--ion-radii-1000)',
xxxxl: 'var(--ion-radii-full)',
},
components: {
IonChip: {
margin: '0px',
padding: {
vertical: primitiveTokens.scale['150'].$value,
horizontal: primitiveTokens.scale['200'].$value,
},
typography: cachedResolveOsToken(typographyTokens.body.sm.medium.$value, tokenMap),
lineHeight: primitiveTokens.font['line-height']['full'].$value,
// Sizes
size: {
small: {
height: primitiveTokens.scale['600'].$value,
fontSize: primitiveTokens.font['font-size']['300'].$value,
},
large: {
height: primitiveTokens.scale['800'].$value,
fontSize: primitiveTokens.font['font-size']['350'].$value,
},
},
// States
state: {
disabled: {
opacity: '0.4',
},
focus: {
ring: {
color: lightTokens.primitives.blue['400'].$value,
width: primitiveTokens.scale['050'].$value,
},
},
},
// Shapes
shape: {
soft: {
borderRadius: primitiveTokens.scale['100'].$value,
},
round: {
borderRadius: primitiveTokens.scale['400'].$value,
},
rectangular: {
borderRadius: primitiveTokens.scale['0'].$value,
},
},
// Hues
hue: {
bold: {
bg: cachedResolveOsToken(colorTokens.bg.neutral.bold.default, tokenMap),
color: lightTokens.primitives.base.white.$value,
outline: {
borderColor: lightTokens.primitives.neutral['1200'].$value,
},
// Any of the semantic colors like primary, secondary, etc.
semantic: {
color: currentColor('contrast'),
outline: {
borderColor: currentColor('shade'),
bg: currentColor('base'),
},
},
},
subtle: {
bg: cachedResolveOsToken(lightTokens.primitives.neutral['100'], tokenMap),
color: lightTokens.primitives.neutral['800'].$value,
outline: {
borderColor: lightTokens.primitives.neutral['300'].$value,
},
semantic: {
outline: {
borderColor: currentColor('shade', null, true),
bg: currentColor('base', null, true),
},
},
},
},
// Variants
variant: {
outline: {
borderWidth: primitiveTokens.scale['025'].$value,
},
},
icon: {
size: primitiveTokens.font['font-size']['400'].$value,
},
},
},
};

View File

@@ -1,9 +1,172 @@
import * as colorTokens from 'outsystems-design-tokens/tokens/color scheme.json';
import * as primitiveTokens from 'outsystems-design-tokens/tokens/primitives.json';
import * as lightTokens from 'outsystems-design-tokens/tokens/theme/light.json';
import * as typographyTokens from 'outsystems-design-tokens/tokens/typography.json';
import { cachedResolveOsToken } from '../../utils/theme';
import type { LightTheme } from '../themes.interfaces';
const tokenMap = {
colorTokens,
lightTokens,
primitiveTokens,
typographyTokens,
};
console.log(
'cachedResolveOsToken(colorTokens.bg.primary.base.default, tokenMap)',
cachedResolveOsToken(colorTokens.bg.primary.base.default, tokenMap)
);
export const lightTheme: LightTheme = {
backgroundColor: '#ffffff',
textColor: '#000000',
color: {
primary: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.primary.base.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.primary, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.primary.base.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.primary['600'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.primary.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.primary, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.primary, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.primary.subtle.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.primary['200'], tokenMap),
},
},
secondary: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.info.base.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.primary, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.info.base.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.info['700'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.info.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.info, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.info, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.info.subtle.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.info['200'], tokenMap),
},
},
tertiary: {
bold: {
base: cachedResolveOsToken(lightTokens.primitives.violet['700'], tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(lightTokens.primitives.violet['700'], tokenMap),
shade: cachedResolveOsToken(lightTokens.primitives.violet['800'], tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.primary['600'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(lightTokens.primitives.violet['100'], tokenMap),
contrast: cachedResolveOsToken(lightTokens.primitives.violet['700'], tokenMap),
foreground: cachedResolveOsToken(lightTokens.primitives.violet['700'], tokenMap),
shade: cachedResolveOsToken(lightTokens.primitives.violet['300'], tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.violet['200'], tokenMap),
},
},
success: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.success.base.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.success, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.success.base.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.success['800'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.success.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.success, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.success, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.success.subtle.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.success['200'], tokenMap),
},
},
warning: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.warning.base.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.warning, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.warning.base.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.warning['800'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.warning.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.warning, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.warning, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.warning.subtle.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.warning['200'], tokenMap),
},
},
danger: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.danger.base.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.danger, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.danger.base.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.danger['700'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.danger.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.danger, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.danger, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.danger.subtle.press, tokenMap),
tint: cachedResolveOsToken(colorTokens.semantics.danger['200'], tokenMap),
},
},
light: {
bold: {
base: cachedResolveOsToken(lightTokens.primitives.base.white, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.default, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(lightTokens.primitives.neutral['600'], tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['400'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.neutral.subtlest.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.default, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.neutral.subtlest.press, tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['100'], tokenMap),
},
},
medium: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.neutral.bold.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.neutral.bold.press, tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['900'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.neutral.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.subtlest, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.neutral.subtle.press, tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['100'], tokenMap),
},
},
dark: {
bold: {
base: cachedResolveOsToken(colorTokens.bg.neutral.boldest.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.inverse, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.neutral.boldest.press, tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['1100'], tokenMap),
},
subtle: {
base: cachedResolveOsToken(colorTokens.bg.neutral.subtle.default, tokenMap),
contrast: cachedResolveOsToken(colorTokens.text.subtle, tokenMap),
foreground: cachedResolveOsToken(colorTokens.text.default, tokenMap),
shade: cachedResolveOsToken(colorTokens.bg.neutral.subtle.press, tokenMap),
tint: cachedResolveOsToken(lightTokens.primitives.neutral['100'], tokenMap),
},
},
},
components: {
IonCard: {
background: '#ffffff',

View File

@@ -98,10 +98,6 @@ export const defaultTheme: DefaultTheme = {
height: '24px',
fontSize: clamp('12px', `${(fontSizes.chipBase - 2) / 16}rem`, '20px'),
},
medium: {
height: '32px',
fontSize: clamp('13px', `${fontSizes.chipBase / 16}rem`, '22px'),
},
large: {
height: '32px',
fontSize: clamp('14px', `${(fontSizes.chipBase + 2) / 16}rem`, '24px'),
@@ -159,6 +155,7 @@ export const defaultTheme: DefaultTheme = {
outline: {
borderColor: currentColor('base', 0.32),
bg: 'transparent',
},
},
},
@@ -169,6 +166,13 @@ export const defaultTheme: DefaultTheme = {
outline: {
borderColor: rgba(colors.textColorRgb, 0.32),
},
semantic: {
outline: {
borderColor: currentColor('shade'),
bg: 'transparent',
},
},
},
},
@@ -176,7 +180,6 @@ export const defaultTheme: DefaultTheme = {
variant: {
outline: {
borderWidth: '1px',
bg: 'transparent',
},
},

View File

@@ -103,10 +103,6 @@ export const defaultTheme: DefaultTheme = {
height: '24px',
fontSize: `${(fontSizes.chipBase - 2) / 16}rem`,
},
medium: {
height: '32px',
fontSize: `${fontSizes.chipBase / 16}rem`,
},
large: {
height: '32px',
fontSize: `${(fontSizes.chipBase + 2) / 16}rem`,
@@ -164,6 +160,7 @@ export const defaultTheme: DefaultTheme = {
outline: {
borderColor: currentColor('base', 0.32),
bg: 'transparent',
},
},
},
@@ -174,6 +171,13 @@ export const defaultTheme: DefaultTheme = {
outline: {
borderColor: rgba(colors.textColorRgb, 0.32),
},
semantic: {
outline: {
borderColor: currentColor('shade'),
bg: 'transparent',
},
},
},
},
@@ -181,7 +185,6 @@ export const defaultTheme: DefaultTheme = {
variant: {
outline: {
borderWidth: '1px',
bg: 'transparent',
},
},

View File

@@ -632,3 +632,20 @@
}
}
}
// Typography mixin to be used with typography scss variables (ionic.vars.scss)
//
// ex: @include typography($ion-heading-h3-medium);
//
// --------------------------------------------------
@mixin typography($properties) {
font-family: map-get($properties, font-family);
font-size: map-get($properties, font-size);
font-weight: map-get($properties, font-weight);
letter-spacing: map-get($properties, letter-spacing);
line-height: map-get($properties, line-height);
text-decoration: map-get($properties, text-decoration);
text-transform: map-get($properties, text-transform);
}

View File

@@ -269,6 +269,9 @@ type Components = {
gap?: string | number;
lineHeight?: string | number;
typography?: {
[key: string]: string | number;
};
// Sizes
size: {
@@ -276,10 +279,6 @@ type Components = {
height: string | number;
fontSize: string | number;
};
medium: {
height: string | number;
fontSize?: string | number;
};
large: {
height: string | number;
fontSize: string | number;
@@ -292,17 +291,19 @@ type Components = {
opacity: string | number;
};
focus: {
ringColor?: string;
ringWidth?: string | number;
bg: string;
semanticBg: string;
outlineBg: string;
ring?: {
color: string;
width?: string | number;
};
bg?: string;
semanticBg?: string;
outlineBg?: string;
};
activated: {
activated?: {
bg: string;
semanticBg: string;
};
hover: {
hover?: {
bg: string;
semanticBg: string;
outlineBg: string;
@@ -334,11 +335,12 @@ type Components = {
// Any of the semantic colors like primary, secondary, etc.
semantic: {
bgAlpha: string;
bgAlpha?: string;
color: string;
outline: {
borderColor: string;
bg?: string;
};
};
};
@@ -348,6 +350,14 @@ type Components = {
outline: {
borderColor: string;
bg?: string;
};
semantic: {
outline: {
borderColor: string;
bg?: string;
};
};
};
};
@@ -356,27 +366,26 @@ type Components = {
variant: {
outline: {
borderWidth: string | number;
bg: string;
};
};
icon: {
size: string | number;
color: string;
firstChildMargin: string | number;
firstChildMarginEnd: string | number;
lastChildMargin: string | number;
lastChildMarginStart: string | number;
color?: string;
firstChildMargin?: string | number;
firstChildMarginEnd?: string | number;
lastChildMargin?: string | number;
lastChildMarginStart?: string | number;
};
avatar: {
size: string | number;
firstChildMarginVertical: string | number;
firstChildMarginStart: string | number;
firstChildMarginEnd: string | number;
lastChildMarginVertical: string | number;
lastChildMarginStart: string | number;
lastChildMarginEnd: string | number;
avatar?: {
size: string | number | null;
firstChildMarginVertical?: string | number;
firstChildMarginStart?: string | number;
firstChildMarginEnd?: string | number;
lastChildMarginVertical?: string | number;
lastChildMarginStart?: string | number;
lastChildMarginEnd?: string | number;
};
};

View File

@@ -589,3 +589,87 @@ export function currentColor(variation: string, alpha: number | string | null =
export function clamp(min: number | string, val: number | string, max: number | string): string {
return `clamp(${min}, ${val}, ${max})`;
}
// Create a cache to store results
const cache = new Map<any, any>();
export const cachedResolveOsToken = (tokenPath: any, tokenMap: Record<string, any>): any => {
// Use the path/object as the key
// (Note: For objects, this caches by reference)
if (cache.has(tokenPath)) {
return cache.get(tokenPath);
}
// Use your existing resolveOsToken function with the global tokenMap
const result = resolveOsToken(tokenPath, tokenMap);
cache.set(tokenPath, result);
return result;
};
export const resolveOsToken = (tokenPath: any, tokenMap: Record<string, any>): any => {
// 1. Handle Objects (like Typography maps)
if (typeof tokenPath === 'object' && tokenPath !== null) {
// If it's a leaf-node token object, unwrap the $value immediately
if ('$value' in tokenPath) {
return resolveOsToken(tokenPath.$value, tokenMap);
}
// Otherwise, it's a map of multiple tokens, resolve each key
const resolvedObject: Record<string, any> = {};
for (const [key, val] of Object.entries(tokenPath)) {
resolvedObject[key] = resolveOsToken(val, tokenMap);
}
return resolvedObject;
}
// 2. Handle Reference Strings: "{category.path.item}"
let lookupPath = tokenPath;
let isPath = false;
if (typeof tokenPath === 'string' && tokenPath.startsWith('{') && tokenPath.endsWith('}')) {
const reference = tokenPath.slice(1, -1).trim();
const [refCategory, ...refPath] = reference.split('.');
let rootKey: string | null = null;
switch (refCategory) {
case 'semantics':
rootKey = 'colorTokens';
break;
case 'font':
rootKey = 'primitiveTokens';
break;
case 'primitives':
rootKey = 'lightTokens';
break;
case 'typography':
rootKey = 'typographyTokens';
break;
case 'scale':
rootKey = 'primitiveTokens';
break; // Added 'scale' based on your example
}
if (!rootKey) return tokenPath;
// As requested, keeping refCategory in the path
lookupPath = `${rootKey}.${refCategory}.${refPath.join('.')}`;
isPath = true;
}
// 3. ONLY run the reduce if we have confirmed this is a path to be searched
if (isPath) {
const value = lookupPath.split('.').reduce((acc: any, key: string) => {
if (acc && typeof acc === 'object' && key in acc) {
return acc[key];
}
return undefined;
}, tokenMap);
// Recursively resolve the result of the lookup
return resolveOsToken(value, tokenMap);
}
// 4. If it's not a path or a reference, it's a Literal Value (Hex, Font-stack, etc.)
return tokenPath;
};

View File

@@ -34,7 +34,8 @@
"@utils/*": ["src/utils/*"],
"@utils/test": ["src/utils/test/utils"],
"@global/*": ["src/global/*"]
}
},
"resolveJsonModule": true,
},
"include": [
"src",