Spaces:
Sleeping
Sleeping
Download bridge/src/Mapper.php from acecalisto3/UIKitV3-Automator: direct link, hf CLI and curl.
- Browser
- Download file 8.94 kB
-
https://huggingface.co/spaces/acecalisto3/UIKitV3-Automator/resolve/main/bridge/src/Mapper.php
- Command line
-
hf download hf://spaces/acecalisto3/UIKitV3-Automator/bridge/src/Mapper.php
-
curl -L -o Mapper.php https://huggingface.co/spaces/acecalisto3/UIKitV3-Automator/resolve/main/bridge/src/Mapper.php
8.94 kB
| /** | |
| * Token key -> semantic role -> YOOtheme/UIkit Less variables. | |
| * | |
| * This table is the product. Everything else is plumbing: it is what keeps an | |
| * imported design editable inside YOOtheme's style panel instead of a CSS dump. | |
| */ | |
| namespace Fyoo\FigmaBridge; | |
| class Mapper | |
| { | |
| /** role => [less variables it drives] */ | |
| public const ROLES = [ | |
| 'color.primary' => ['@global-primary-background'], | |
| 'color.secondary' => ['@global-secondary-background'], | |
| 'color.background' => ['@global-background'], | |
| 'color.muted' => ['@global-muted-background'], | |
| 'color.text' => ['@global-color'], | |
| 'color.emphasis' => ['@global-emphasis-color'], | |
| 'color.text-muted' => ['@global-muted-color'], | |
| 'color.inverse' => ['@global-inverse-color'], | |
| 'color.link' => ['@global-link-color'], | |
| 'color.danger' => ['@global-danger-background'], | |
| 'color.success' => ['@global-success-background'], | |
| 'color.warning' => ['@global-warning-background'], | |
| 'color.border' => ['@global-border'], | |
| 'type.body' => ['@global-font-family', '@global-font-size', '@global-line-height'], | |
| 'type.small' => ['@global-small-font-size'], | |
| 'type.lead' => ['@global-medium-font-size'], | |
| 'type.h1' => ['@base-h1-font-size'], | |
| 'type.h2' => ['@base-h2-font-size'], | |
| 'type.h3' => ['@base-h3-font-size'], | |
| 'type.h4' => ['@base-h4-font-size'], | |
| 'type.h5' => ['@base-h5-font-size'], | |
| 'type.h6' => ['@base-h6-font-size'], | |
| 'space.xsmall' => ['@global-small-margin'], | |
| 'space.small' => ['@global-margin'], | |
| 'space.medium' => ['@global-medium-margin'], | |
| 'space.large' => ['@global-large-margin'], | |
| 'space.xlarge' => ['@global-xlarge-margin'], | |
| 'space.gutter' => ['@global-gutter'], | |
| 'space.section' => ['@section-padding-vertical'], | |
| 'space.container' => ['@container-max-width'], | |
| 'radius.default' => ['@border-rounded-border-radius'], | |
| 'shadow.small' => ['@global-small-box-shadow'], | |
| 'shadow.medium' => ['@global-medium-box-shadow'], | |
| 'shadow.large' => ['@global-large-box-shadow'], | |
| 'shadow.xlarge' => ['@global-xlarge-box-shadow'], | |
| ]; | |
| /** | |
| * Ordered: first pattern that matches a token key wins. Order matters — | |
| * "text-muted" must be tested before "text", "muted" before "background". | |
| */ | |
| public const RULES = [ | |
| 'color' => [ | |
| '~(^|-)(on-primary|inverse|contrast)(-|$)~' => 'color.inverse', | |
| '~(^|-)(text|foreground|fg|ink|content)-(muted|secondary|subtle|tertiary)(-|$)~' => 'color.text-muted', | |
| '~(^|-)(muted|subtle)-(text|foreground|fg)(-|$)~' => 'color.text-muted', | |
| '~(^|-)(heading|title|emphasis|display)(-|$)~' => 'color.emphasis', | |
| '~(^|-)(text|foreground|fg|ink|body)(-|$)~' => 'color.text', | |
| '~(^|-)link(-|$)~' => 'color.link', | |
| '~(^|-)(danger|error|destructive|critical|negative)(-|$)~' => 'color.danger', | |
| '~(^|-)(success|positive|ok)(-|$)~' => 'color.success', | |
| '~(^|-)(warning|caution|alert)(-|$)~' => 'color.warning', | |
| '~(^|-)(border|divider|outline|stroke|separator)(-|$)~' => 'color.border', | |
| '~(^|-)(secondary|brand-2|accent-2)(-|$)~' => 'color.secondary', | |
| '~(^|-)(brand-)?(primary|accent|brand)(-|$)~' => 'color.primary', | |
| '~(^|-)(muted|subtle|surface-2|neutral-alt)(-|$)~' => 'color.muted', | |
| '~(^|-)(surface|background|bg|canvas|base|paper)(-|$)~' => 'color.background', | |
| ], | |
| 'typography' => [ | |
| '~(^|-)(h1|heading-(xl|1|hero|display))(-|$)~' => 'type.h1', | |
| '~(^|-)(h2|heading-(lg|2|large))(-|$)~' => 'type.h2', | |
| '~(^|-)(h3|heading-(md|3|medium))(-|$)~' => 'type.h3', | |
| '~(^|-)(h4|heading-(sm|4|small))(-|$)~' => 'type.h4', | |
| '~(^|-)(h5|heading-(xs|5))(-|$)~' => 'type.h5', | |
| '~(^|-)(h6|heading-(2xs|6)|overline|eyebrow)(-|$)~' => 'type.h6', | |
| '~(^|-)(lead|intro|subtitle|body-large)(-|$)~' => 'type.lead', | |
| '~(^|-)(small|caption|meta|footnote)(-|$)~' => 'type.small', | |
| '~(^|-)(body|base|paragraph|text|default)(-|$)~' => 'type.body', | |
| ], | |
| 'spacing' => [ | |
| '~(^|-)(container|max-width|content|content-width|wrapper|page-width)(-|$)~' => 'space.container', | |
| '~(^|-)(section|block|stack-xl)(-|$)~' => 'space.section', | |
| '~(^|-)(gutter|grid-gap|column-gap|gap)(-|$)~' => 'space.gutter', | |
| '~(^|-)(3xl|2xl|xxl|xlarge|xl)(-|$)~' => 'space.xlarge', | |
| '~(^|-)(large|lg)(-|$)~' => 'space.large', | |
| '~(^|-)(md|medium)(-|$)~' => 'space.medium', | |
| '~(^|-)(xs|xxs|2xs|xsmall)(-|$)~' => 'space.xsmall', | |
| '~(^|-)(sm|small|base|default)(-|$)~' => 'space.small', | |
| ], | |
| 'radius' => [ | |
| '~(^|-)(default|base|md|medium|card|button|control)(-|$)~' => 'radius.default', | |
| ], | |
| 'shadow' => [ | |
| '~(^|-)(3xl|2xl|xxl|xlarge|xl)(-|$)~' => 'shadow.xlarge', | |
| '~(^|-)(lg|large)(-|$)~' => 'shadow.large', | |
| '~(^|-)(md|medium|default|base|card)(-|$)~' => 'shadow.medium', | |
| '~(^|-)(sm|xs|small)(-|$)~' => 'shadow.small', | |
| ], | |
| ]; | |
| /** Figma component name -> semantic role -> YOOtheme element target. */ | |
| public const COMPONENTS = [ | |
| '~^button\s*/\s*primary~i' => ['action.primary', 'button-primary'], | |
| '~^button\s*/\s*secondary~i' => ['action.secondary', 'button-secondary'], | |
| '~^button~i' => ['action.default', 'button-default'], | |
| '~^card~i' => ['content.card', 'card-default'], | |
| '~^(nav|navbar|header)~i' => ['navigation.primary', 'navbar'], | |
| '~^(input|field|form)~i' => ['form.control', 'form'], | |
| '~^(alert|notice|banner)~i' => ['feedback.alert', 'alert'], | |
| '~^(section|hero)~i' => ['layout.section', 'section'], | |
| ]; | |
| private array $overrides; | |
| /** @param array $overrides token key => role, saved from the admin mapping table */ | |
| public function __construct(array $overrides = []) | |
| { | |
| $this->overrides = $overrides; | |
| } | |
| public function role(string $group, string $key): ?string | |
| { | |
| if (isset($this->overrides[$key])) { | |
| return $this->overrides[$key] === '-' ? null : $this->overrides[$key]; | |
| } | |
| foreach (self::RULES[$group] ?? [] as $pattern => $role) { | |
| if (preg_match($pattern, "-$key-")) { | |
| return $role; | |
| } | |
| } | |
| return null; | |
| } | |
| public function variables(string $role): array | |
| { | |
| return self::ROLES[$role] ?? []; | |
| } | |
| public function component(string $name): array | |
| { | |
| foreach (self::COMPONENTS as $pattern => $mapping) { | |
| if (preg_match($pattern, $name)) { | |
| return ['role' => $mapping[0], 'target' => $mapping[1]]; | |
| } | |
| } | |
| return ['role' => '', 'target' => '']; | |
| } | |
| /** | |
| * Full resolution table for one token graph: what maps where, and what did not | |
| * map at all (the admin UI shows these so a human can assign them). | |
| */ | |
| public function resolve(Tokens $tokens): array | |
| { | |
| $mapped = []; | |
| $unmapped = []; | |
| $claimed = []; | |
| foreach (Tokens::GROUPS as $group) { | |
| foreach ($tokens->group($group) as $key => $value) { | |
| $role = $this->role($group === 'typography' ? 'typography' : $group, $key); | |
| // First token to claim a role wins; later ones stay available as raw vars. | |
| if ($role === null || isset($claimed[$role])) { | |
| $unmapped[] = ['group' => $group, 'key' => $key, 'value' => $value, 'reason' => $role ? "role $role already taken" : 'no rule matched']; | |
| continue; | |
| } | |
| $claimed[$role] = $key; | |
| $mapped[] = [ | |
| 'group' => $group, | |
| 'key' => $key, | |
| 'value' => $value, | |
| 'role' => $role, | |
| 'variables' => $this->variables($role), | |
| ]; | |
| } | |
| } | |
| return ['mapped' => $mapped, 'unmapped' => $unmapped]; | |
| } | |
| } | |