diff --git a/apps/docs/.storybook/preview.tsx b/apps/docs/.storybook/preview.tsx index 8b2cf9d5a..98d9e8888 100644 --- a/apps/docs/.storybook/preview.tsx +++ b/apps/docs/.storybook/preview.tsx @@ -53,7 +53,7 @@ const preview: Preview = { defaultValue: 'one', toolbar: { icon: 'switchalt', - items: ['one', 'neo', 'side-by-side'], + items: ['one', 'neo', 'neov2', 'side-by-side'], }, }, app: { @@ -133,6 +133,7 @@ const preview: Preview = { <> + ); } @@ -142,6 +143,9 @@ const preview: Preview = { case 'neo': { return ; } + case 'neov2': { + return ; + } case 'default': { return ; } diff --git a/packages/bootstrap/src/abstracts/_icons.scss b/packages/bootstrap/src/abstracts/_icons.scss deleted file mode 100644 index 9cfef5711..000000000 --- a/packages/bootstrap/src/abstracts/_icons.scss +++ /dev/null @@ -1,559 +0,0 @@ -@use '../abstracts/colors' as *; - -$icons-applications: ( - 'account': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'actualites': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'admin-portal': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'admin': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'archive': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'attendance': ( - 'neo': $green, - 'one': $one-green, - ), - 'blog': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'cahier-de-texte': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'cahier-textes': ( - 'neo': $blue, - 'one': $one-green, - ), - 'calendar': ( - 'neo': $green, - 'one': $one-green, - ), - 'canal-numerique': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'cns': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'collaborative-wall': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'collaborativeeditor': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'community': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'competences': ( - 'neo': $green, - 'one': $one-green, - ), - 'conversation': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'crre': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'directory': ( - 'neo': $green, - 'one': $one-green, - ), - 'edt': ( - 'neo': $green, - 'one': $one-green, - ), - 'exercizer': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'qwant': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'forms': ( - 'neo': $green, - 'one': $one-green, - ), - 'forum': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'library': ( - 'neo': $purple, - 'one': $one-purple, - ), - 'magneto': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'mediacentre': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'mindmap': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'minibadge': ( - 'neo': $green, - 'one': $one-green, - ), - 'notebook': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'notes': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'pad': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'pages': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'parametrage': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'parcours': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'paths': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'poll': ( - 'neo': $green, - 'one': $one-green, - ), - 'polls': ( - 'neo': $green, - 'one': $one-green, - ), - 'presences': ( - 'neo': $green, - 'one': $one-green, - ), - 'rack': ( - 'neo': $green, - 'one': $one-green, - ), - 'rbs': ( - 'neo': $green, - 'one': $one-green, - ), - 'schoolbook': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'scrap-book': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'scrapbook': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'searchengine': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'settings-class': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'sharebigfiles': ( - 'neo': $green, - 'one': $one-green, - ), - 'statistics': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'stats': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'support': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'timeline': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'timelinegenerator': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'userbook': ( - 'neo': $green, - 'one': $one-green, - ), - 'userbook-mood': ( - 'neo': $green, - 'one': $one-green, - ), - 'userbook-moto': ( - 'neo': $green, - 'one': $one-green, - ), - 'video': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'visioconf': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'web-conference': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'website': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'wiki': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'workspace': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'placeholder': ( - 'neo': $secondary, - 'one': $primary, - ), - 'nabook': ( - 'neo': $nabook-color, - 'one': $nabook-color, - ), - 'votil': ( - 'neo': $yellow, - 'one': $yellow, - ), - 'appointments': ( - 'neo': $green, - 'one': $one-green, - ), - 'communities': ( - 'neo': $purple, - 'one': $one-purple, - ), - 'minetest': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'geogebra': ( - 'neo': $blue, - 'one': $one-blue, - ), -) !default; - -$icons-connectors: ( - 'absences': ( - 'neo': $red, - 'one': $one-red, - ), - 'admission-post-bac': ( - 'neo': $red, - 'one': $one-red, - ), - 'aide-devoirs': ( - 'neo': $green, - 'one': $one-green, - ), - 'agenda': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'assistance': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'assr': ( - 'neo': $red, - 'one': $one-red, - ), - 'award': ( - 'neo': $green, - 'one': $one-green, - ), - 'banquesavoir': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'bcdi': ( - 'neo': $purple, - 'one': $one-purple, - ), - 'biblionisep': ( - 'neo': $green, - 'one': $one-green, - ), - 'bookmark-empty': ( - 'neo': $green, - 'one': $one-green, - ), - 'canal-numerique': ( - 'neo': $red, - 'one': $one-red, - ), - 'ccn': ( - 'neo': $green, - 'one': $one-green, - ), - 'cerise': ( - 'neo': $red, - 'one': $one-red, - ), - 'cervoprint': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'charlemagne': ( - 'neo': $red, - 'one': $one-red, - ), - 'charte': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'chat': ( - 'neo': $red, - 'one': $one-red, - ), - 'cidj': ( - 'neo': $green, - 'one': $one-green, - ), - 'connecteur-generique1': ( - 'neo': $red, - 'one': $one-orange, - ), - 'connecteur-generique2': ( - 'neo': $red, - 'one': $one-orange, - ), - 'educagri': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'edumedia': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'edumoov': ( - 'neo': $red, - 'one': $one-red, - ), - 'edutheque': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'electron': ( - 'neo': $red, - 'one': $one-red, - ), - 'elyceepicardie': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'esidoc': ( - 'neo': $pink, - 'one': $one-indigo, - ), - 'europress': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'gepi': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'glpi': ( - 'neo': $red, - 'one': $one-red, - ), - 'hiboutheque': ( - 'neo': $green, - 'one': $one-green, - ), - 'itopstore': ( - 'neo': $green, - 'one': $one-green, - ), - 'kne': ( - 'neo': $purple, - 'one': $one-orange, - ), - 'le-site-tv': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'lemonde': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'lesechos': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'lsu': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'madmagz': ( - 'neo': $pink, - 'one': $one-red, - ), - 'matholycee': ( - 'neo': $red, - 'one': $one-red, - ), - 'maxicours': ( - 'neo': $indigo, - 'one': $one-yellow, - ), - 'mediacentre': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'monorientationenligne': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'monstageenligne': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'moodle': ( - 'neo': $orange, - 'one': $one-orange, - ), - 'museefrancaisphoto': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'my-network': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'netvibes': ( - 'neo': $green, - 'one': $one-green, - ), - 'note': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'onisep': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'onisep2': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'parametrage': ( - 'neo': $red, - 'one': $one-red, - ), - 'paraschool': ( - 'neo': $green, - 'one': $one-green, - ), - 'pearltress': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'picardie-cursus': ( - 'neo': $purple, - 'one': $one-purple, - ), - 'pro-eps': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'pronote': ( - 'neo': $purple, - 'one': $one-purple, - ), - 'public': ( - 'neo': $red, - 'one': $one-red, - ), - 'qwant-junior': ( - 'neo': $red, - 'one': $one-orange, - ), - 'residence-artiste': ( - 'neo': $green, - 'one': $one-green, - ), - 'ressourcesdepartementale91': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'sacoche': ( - 'neo': $indigo, - 'one': $one-indigo, - ), - 'scolinfo': ( - 'neo': $red, - 'one': $one-orange, - ), - 'suitcase': ( - 'neo': $red, - 'one': $one-red, - ), - 'turboself': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'universalis': ( - 'neo': $red, - 'one': $one-red, - ), - 'unstagepourtous': ( - 'neo': $pink, - 'one': $one-pink, - ), - 'vie-scolaire': ( - 'neo': $yellow, - 'one': $one-yellow, - ), - 'webclasseur': ( - 'neo': $blue, - 'one': $one-blue, - ), - 'lool': ( - 'neo': $blue, - 'one': $one-blue, - ), -) !default; diff --git a/packages/bootstrap/src/abstracts/_index.scss b/packages/bootstrap/src/abstracts/_index.scss index 641de4eab..92508aeef 100644 --- a/packages/bootstrap/src/abstracts/_index.scss +++ b/packages/bootstrap/src/abstracts/_index.scss @@ -1,5 +1,4 @@ @forward 'colors'; -@forward 'icons'; @forward 'type'; @forward 'variables'; @forward 'mixins'; diff --git a/packages/bootstrap/src/themes/_index.scss b/packages/bootstrap/src/themes/_index.scss index 3dd7c788c..a61f89f84 100644 --- a/packages/bootstrap/src/themes/_index.scss +++ b/packages/bootstrap/src/themes/_index.scss @@ -1,4 +1,5 @@ @forward 'neo'; @forward 'one'; +@forward 'neov2'; @forward 'overrides'; @forward 'skins'; diff --git a/packages/bootstrap/src/themes/_theme-api.scss b/packages/bootstrap/src/themes/_theme-api.scss new file mode 100644 index 000000000..77d39d67f --- /dev/null +++ b/packages/bootstrap/src/themes/_theme-api.scss @@ -0,0 +1,68 @@ +// ============================================================================= +// Theme API – Contrat pour les thèmes basés sur une map de configuration +// ============================================================================= +// Ce module fournit des mixins pour générer les variables CSS d'un thème +// à partir d'une map Sass. Utilisé par le thème neov2 (et futurs thèmes). +// Les thèmes "one" et "neo" utilisent encore l'ancienne mécanique. +// CONTRAT DE LA MAP DE THÈME +// -------------------------- +// La config doit fournir au minimum : +// $theme-: ( +// name: '', // identifiant data-product +// colors: ( // clés → valeurs (couleurs hex/rgb/var) +// primary: #..., +// primary-200: #..., +// secondary: #..., +// ... +// ), +// typography: ( ... ), // optionnel +// layout: ( ... ), // optionnel +// components: ( ... ), // optionnel +// ); +// ============================================================================= + +@use 'sass:map'; +@use '../abstracts/variables' as vars; + +@mixin theme-vars($product, $config) { + $colors: map.get($config, colors); + $typography: map.get($config, typography); + $layout: map.get($config, layout); + $components: map.get($config, components); + + [data-product="#{$product}"] { + @if $colors { + @each $key, $value in $colors { + --#{vars.$prefix}#{$key}: #{$value}; + } + } + + @if $typography { + @each $key, $value in $typography { + --#{vars.$prefix}#{$key}: #{$value}; + } + } + + @if $layout { + @each $key, $value in $layout { + --#{vars.$prefix}#{$key}: #{$value}; + } + } + + @if $components { + @each $component, $vars-map in $components { + @each $key, $value in $vars-map { + --#{vars.$prefix}#{$key}: #{$value}; + } + } + } + } +} + +@mixin theme-variant($product, $variant, $variant-config) { + [data-product="#{$product}"][data-theme="#{$variant}"] { + @each $key, $value in $variant-config { + --#{vars.$prefix}#{$key}: #{$value}; + } + } +} diff --git a/packages/bootstrap/src/themes/configs/_neov2.scss b/packages/bootstrap/src/themes/configs/_neov2.scss new file mode 100644 index 000000000..8d48c2950 --- /dev/null +++ b/packages/bootstrap/src/themes/configs/_neov2.scss @@ -0,0 +1,60 @@ +// Configuration du thème neov2. +// Valeurs initiales basées sur la palette par défaut (abstracts). + +@use '../../abstracts/' as *; + +$theme-neov2: ( + name: 'neov2', + colors: ( + primary: $primary, + 'primary-200': $primary-200, + 'primary-300': $primary-300, + 'primary-800': $primary-800, + secondary: $secondary, + 'secondary-200': $secondary-200, + 'secondary-300': $secondary-300, + 'secondary-800': $secondary-800, + tertiary: $tertiary, + 'white': $white, + 'black': $black, + 'gray-100': $gray-100, + 'gray-200': $gray-200, + 'gray-300': $gray-300, + 'gray-400': $gray-400, + 'gray-500': $gray-500, + 'gray-600': $gray-600, + 'gray-700': $gray-700, + 'gray-800': $gray-800, + 'gray-900': $gray-900, + success: $success, + 'success-200': $success-200, + 'success-300': $success-300, + 'success-800': $success-800, + info: $info, + 'info-200': $info-200, + 'info-300': $info-300, + 'info-800': $info-800, + warning: $warning, + 'warning-200': $warning-200, + 'warning-300': $warning-300, + 'warning-800': $warning-800, + danger: $danger, + 'danger-200': $danger-200, + 'danger-300': $danger-300, + 'danger-800': $danger-800, + 'blue-200': $blue-200, + 'blue-300': $blue-300, + 'blue-500': $blue-500, + 'blue-800': $blue-800, + 'orange-200': $orange-200, + 'orange-300': $orange-300, + 'orange-500': $orange-500, + 'orange-800': $orange-800, + ), + typography: ( + 'font-sans-serif': $font-family-sans-serif, + 'family-primary': $font-family-primary, + ), + layout: (), + components: (), +) !default; diff --git a/packages/bootstrap/src/themes/configs/_theme-config.schema.scss b/packages/bootstrap/src/themes/configs/_theme-config.schema.scss new file mode 100644 index 000000000..e45ef4678 --- /dev/null +++ b/packages/bootstrap/src/themes/configs/_theme-config.schema.scss @@ -0,0 +1,14 @@ +// ============================================================================= +// Schéma exhaustif des variables de thème (référence pour les configs) +// ============================================================================= +// Liste des variables CSS (--edifice-*) utilisées dans le package bootstrap. +// À utiliser comme checklist lors de la création ou mise à jour d'un thème. +// ============================================================================= + +// colors : primary, primary-200, primary-300, primary-800, secondary, secondary-200, +// secondary-300, secondary-800, tertiary, white, black, gray-100..900, +// success, info, warning, danger (+ -200, -300, -800), blue-*, orange-*, etc. +// typography : font-sans-serif, family-primary, btn-font-family +// layout : container-width, navbar-padding-*, navbar-brand-*, navbar-badge-* +// components : buttons (btn-*), form-label, form-control, alert, avatar, dropdown, +// dropzone, popover, workspace, badge, etc. diff --git a/packages/bootstrap/src/themes/neo/_icons.scss b/packages/bootstrap/src/themes/neo/_icons.scss new file mode 100644 index 000000000..76a769dcf --- /dev/null +++ b/packages/bootstrap/src/themes/neo/_icons.scss @@ -0,0 +1,146 @@ +@use '../../abstracts/colors' as *; + +$neo-icons: ( + 'applications': ( + 'account': $orange, + 'actualites': $orange, + 'admin-portal': $yellow, + 'admin': $yellow, + 'archive': $yellow, + 'attendance': $green, + 'blog': $orange, + 'cahier-de-texte': $blue, + 'cahier-textes': $blue, + 'calendar': $green, + 'canal-numerique': $pink, + 'cns': $pink, + 'collaborative-wall': $blue, + 'collaborativeeditor': $blue, + 'community': $blue, + 'competences': $green, + 'conversation': $orange, + 'crre': $pink, + 'directory': $green, + 'edt': $green, + 'exercizer': $blue, + 'qwant': $pink, + 'forms': $green, + 'forum': $orange, + 'library': $purple, + 'magneto': $blue, + 'mediacentre': $blue, + 'mindmap': $blue, + 'minibadge': $green, + 'notebook': $pink, + 'notes': $pink, + 'pad': $blue, + 'pages': $orange, + 'parametrage': $yellow, + 'parcours': $pink, + 'paths': $pink, + 'poll': $green, + 'polls': $green, + 'presences': $green, + 'rack': $green, + 'rbs': $green, + 'schoolbook': $orange, + 'scrap-book': $blue, + 'scrapbook': $blue, + 'searchengine': $pink, + 'settings-class': $yellow, + 'sharebigfiles': $green, + 'statistics': $yellow, + 'stats': $yellow, + 'support': $yellow, + 'timeline': $yellow, + 'timelinegenerator': $blue, + 'userbook': $green, + 'userbook-mood': $green, + 'userbook-moto': $green, + 'video': $pink, + 'visioconf': $orange, + 'web-conference': $orange, + 'website': $orange, + 'wiki': $blue, + 'workspace': $orange, + 'placeholder': $secondary, + 'nabook': $nabook-color, + 'votil': $yellow, + 'appointments': $green, + 'communities': $purple, + 'minetest': $blue, + 'geogebra': $blue, + ), + 'connectors': ( + 'absences': $red, + 'admission-post-bac': $red, + 'aide-devoirs': $green, + 'agenda': $yellow, + 'assistance': $blue, + 'assr': $red, + 'award': $green, + 'banquesavoir': $blue, + 'bcdi': $purple, + 'biblionisep': $green, + 'bookmark-empty': $green, + 'canal-numerique': $red, + 'ccn': $green, + 'cerise': $red, + 'cervoprint': $blue, + 'charlemagne': $red, + 'charte': $yellow, + 'chat': $red, + 'cidj': $green, + 'connecteur-generique1': $red, + 'connecteur-generique2': $red, + 'educagri': $indigo, + 'edumedia': $blue, + 'edumoov': $red, + 'edutheque': $yellow, + 'electron': $red, + 'elyceepicardie': $indigo, + 'esidoc': $pink, + 'europress': $blue, + 'gepi': $blue, + 'glpi': $red, + 'hiboutheque': $green, + 'itopstore': $green, + 'kne': $purple, + 'le-site-tv': $yellow, + 'lemonde': $indigo, + 'lesechos': $indigo, + 'lsu': $blue, + 'madmagz': $pink, + 'matholycee': $red, + 'maxicours': $indigo, + 'mediacentre': $blue, + 'monorientationenligne': $yellow, + 'monstageenligne': $blue, + 'moodle': $orange, + 'museefrancaisphoto': $indigo, + 'my-network': $indigo, + 'netvibes': $green, + 'note': $yellow, + 'onisep': $blue, + 'onisep2': $blue, + 'parametrage': $red, + 'paraschool': $green, + 'pearltress': $blue, + 'picardie-cursus': $purple, + 'pro-eps': $blue, + 'pronote': $purple, + 'public': $red, + 'qwant-junior': $red, + 'residence-artiste': $green, + 'ressourcesdepartementale91': $indigo, + 'sacoche': $indigo, + 'scolinfo': $red, + 'suitcase': $red, + 'turboself': $yellow, + 'universalis': $red, + 'unstagepourtous': $pink, + 'vie-scolaire': $yellow, + 'webclasseur': $blue, + 'lool': $blue, + ), +); \ No newline at end of file diff --git a/packages/bootstrap/src/themes/neov2/MIGRATION-STRATEGY.md b/packages/bootstrap/src/themes/neov2/MIGRATION-STRATEGY.md new file mode 100644 index 000000000..0578b4bcd --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/MIGRATION-STRATEGY.md @@ -0,0 +1,10 @@ +# Stratégie de migration vers neov2 + +- **Objectif** : migrer progressivement vers le thème neov2 (API map + overrides par composant) sans tout réécrire d’un coup. +- **Conserver** : les thèmes `one` et `neo` tels quels ; neov2 coexiste. +- **Étapes** : + 1. Activer neov2 côté app (`data-product="neov2"`). + 2. Ajuster les overrides dans `themes/neov2/overrides/` par composant. + 3. Utiliser les variables CSS `--edifice-*` issues de la config pour les personnalisations. +- **Référence** : `configs/_theme-config.schema.scss` liste les variables de thème utilisées dans le package. +- **Icônes** : pour tout nouveau thème, il est obligatoire de renseigner les couleurs des icônes (applications et connecteurs). Fichier de référence : `packages/bootstrap/src/abstracts/_icons.scss`. Le thème doit exposer `$-icons` (applications + connectors) pour que les classes `.color-app-*`, `.bg-app-*`, etc. soient générées. diff --git a/packages/bootstrap/src/themes/neov2/OVERRIDES-INVENTORY.md b/packages/bootstrap/src/themes/neov2/OVERRIDES-INVENTORY.md new file mode 100644 index 000000000..857566876 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/OVERRIDES-INVENTORY.md @@ -0,0 +1,11 @@ +# Inventaire des overrides neov2 + +| Composant | Fichier / dossier | Description | +|------------|------------------------|--------------------------------| +| Container | overrides/_container.scss | Layout / container (optionnel) | +| Treeview | overrides/_treeview.scss | Styles treeview (optionnel) | +| Header | overrides/header/ | Navbar, brand, dropdown | +| Buttons | overrides/buttons/ | Boutons (réutilise neo/mixins) | +| Variants | overrides/_variants.scss | Sous-thèmes data-theme | + +L’ordre de chargement est défini dans `overrides/_index.scss`. diff --git a/packages/bootstrap/src/themes/neov2/THEMING.md b/packages/bootstrap/src/themes/neov2/THEMING.md new file mode 100644 index 000000000..fc1265982 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/THEMING.md @@ -0,0 +1,33 @@ +# Thème neov2 + +Le thème **neov2** repose sur l’API de thème (maps + mixins) définie dans `_theme-api.scss`. Les variables CSS sont générées à partir de la configuration dans `configs/_neov2.scss`. + +## Structure + +- **configs/_neov2.scss** : map `$theme-neov2` (couleurs, typo, layout, components). +- **overrides/** : surcharges par composant (header, buttons, container, treeview, variants). +- **_icons.scss** : couleurs des icônes (applications et connecteurs) pour le thème. +- Les overrides utilisent `[data-product="neov2"]` pour cibler le thème. + +## Icônes (obligatoire pour tout nouveau thème) + +Les couleurs des icônes par application et par connecteur sont définies dans un fichier dédié, **obligatoire** pour la création d’un thème : + +- **Fichier de référence** : [packages/bootstrap/src/abstracts/_icons.scss](../../abstracts/_icons.scss) + Ce fichier centralise la liste des applications et connecteurs et leurs couleurs par thème. C’est le fichier à compléter ou à utiliser comme référence lorsque vous créez un nouveau thème. + +- **Structure attendue** : pour chaque thème, une variable `$-icons` (ex. `$neov2-icons`) contenant deux maps : + - **applications** : nom d’application → couleur (ex. `'blog': $orange`). + - **connectors** : nom de connecteur → couleur (ex. `'absences': $red`). + +- **Emplacement** : la définition peut vivre dans `abstracts/_icons.scss` (référence partagée) ou dans le dossier du thème (ex. `themes/neov2/_icons.scss`) qui exporte `$neov2-icons`. Le thème doit exposer sa variable d’icônes pour que [tokens/_icons.scss](../../tokens/_icons.scss) génère les classes `.color-app-*`, `.bg-app-*`, etc. + +Sans ce fichier (ou cette variable) rempli, les icônes d’applications et de connecteurs n’auront pas de couleurs pour le thème. + +## Utilisation + +Sur le conteneur racine de l’app, définir `data-product="neov2"` pour activer le thème. Les variantes (sous-thèmes) utilisent `data-theme=""` (voir `overrides/_variants.scss`). + +## Migration depuis neo/one + +Voir `MIGRATION-STRATEGY.md` et `PROMPT-MIGRATION.md` dans ce dossier. diff --git a/packages/bootstrap/src/themes/neov2/_icons.scss b/packages/bootstrap/src/themes/neov2/_icons.scss new file mode 100644 index 000000000..8758f3779 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/_icons.scss @@ -0,0 +1,4 @@ +@use '../../abstracts/colors' as *; +@use '../neo/_icons' as *; + +$neov2-icons: $neo-icons; \ No newline at end of file diff --git a/packages/bootstrap/src/themes/neov2/_index.scss b/packages/bootstrap/src/themes/neov2/_index.scss new file mode 100644 index 000000000..14c456b51 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/_index.scss @@ -0,0 +1,8 @@ +// Thème neov2 – basé sur l'API de thème (theme-api.scss). +// Les overrides spécifiques au thème sont organisés par composant dans le dossier overrides/. + +@use "../theme-api" as theme; +@use "../configs/neov2" as *; +@use "overrides"; + +@include theme.theme-vars("neov2", $theme-neov2); diff --git a/packages/bootstrap/src/themes/neov2/overrides/_container.scss b/packages/bootstrap/src/themes/neov2/overrides/_container.scss new file mode 100644 index 000000000..c9d385b8d --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/_container.scss @@ -0,0 +1,5 @@ +@use "../../../abstracts/" as *; + +[data-product="neov2"] { + // Overrides layout/container pour neov2 (optionnel). +} diff --git a/packages/bootstrap/src/themes/neov2/overrides/_index.scss b/packages/bootstrap/src/themes/neov2/overrides/_index.scss new file mode 100644 index 000000000..563786ab8 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/_index.scss @@ -0,0 +1,5 @@ +@use "container"; +@use "treeview"; +@use "header"; +@use "buttons"; +@use "variants"; diff --git a/packages/bootstrap/src/themes/neov2/overrides/_treeview.scss b/packages/bootstrap/src/themes/neov2/overrides/_treeview.scss new file mode 100644 index 000000000..614c0383a --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/_treeview.scss @@ -0,0 +1,5 @@ +@use "../../../abstracts/" as *; + +[data-product="neov2"] { + // .treeview { --#{$prefix}selected-background-color: var(--#{$prefix}secondary-200); } +} diff --git a/packages/bootstrap/src/themes/neov2/overrides/_variants.scss b/packages/bootstrap/src/themes/neov2/overrides/_variants.scss new file mode 100644 index 000000000..f032f1b45 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/_variants.scss @@ -0,0 +1,4 @@ +@use "../../../abstracts/" as *; + +// Variantes (sous-thèmes) pour neov2. +// Exemple : [data-product="neov2"][data-theme="brand1"] { --#{$prefix}primary: #004899; ... } diff --git a/packages/bootstrap/src/themes/neov2/overrides/buttons/_component.scss b/packages/bootstrap/src/themes/neov2/overrides/buttons/_component.scss new file mode 100644 index 000000000..39b9834bb --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/buttons/_component.scss @@ -0,0 +1,142 @@ +@use "sass:map"; +@use "../../../neo/buttons/mixins" as neo-mixins; +@use "../../../../abstracts/" as *; + +[data-product="neov2"] { + .btn { + &:hover, + &.hover, + &:focus-visible { + > span { + transform: translateY(-0.2rem); + } + } + + &:active, + &.active { + box-shadow: inset 0 0 0 var(--#{$prefix}btn-active-box-shadow-width) + var(--#{$prefix}btn-active-border-color); + + > span { + transform: translateY(0); + } + } + + &:focus-visible { + box-shadow: inset 0 0 0 var(--#{$prefix}btn-active-box-shadow-width) + var(--#{$prefix}btn-hover-border-color); + } + } + + @each $value, $key in $button-colors { + .btn-#{$value} { + @include neo-mixins.variant-button-filled( + map.get($key, "base"), + map.get($key, "dark"), + map.get($key, "light"), + map.get($key, "text"), + map.get($key, "box-shadow") + ); + } + + @if ($value == "tertiary") { + .btn-#{$value} { + &:disabled, + &.disabled { + --#{$prefix}btn-bg: var(--#{$prefix}gray-200); + --#{$prefix}btn-color: var(--#{$prefix}gray-600); + } + } + + &[data-state="selected"], + &.is-selected { + background-color: var(--#{$prefix}secondary-200); + } + } + } + + @each $value, $key in $button-colors { + @if ($value == "tertiary") { + .btn-outline-#{$value} { + --#{$prefix}btn-active-bg: var(--#{$prefix}gray-200); + --#{$prefix}btn-active-border-color: var(--#{$prefix}gray-600); + --#{$prefix}btn-active-box-shadow-color: transparent; + --#{$prefix}btn-active-color: var(--#{$prefix}gray-900); + --#{$prefix}btn-bg: transparent; + --#{$prefix}btn-border-color: var(--#{$prefix}gray-500); + --#{$prefix}btn-border-radius: 0.8rem; + --#{$prefix}btn-border-width: 0.1rem; + --#{$prefix}btn-color: var(--#{$prefix}gray-800); + --#{$prefix}btn-disabled-bg: transparent; + --#{$prefix}btn-disabled-border-color: var(--#{$prefix}gray-400); + --#{$prefix}btn-disabled-color: var(--#{$prefix}gray-500); + --#{$prefix}btn-disabled-opacity: 1; + --#{$prefix}btn-hover-bg: transparent; + --#{$prefix}btn-hover-border-color: var(--#{$prefix}gray-500); + --#{$prefix}btn-hover-color: var(--#{$prefix}gray-800); + + &:focus-visible { + --#{$prefix}btn-hover-bg: var(--#{$prefix}gray-200); + --#{$prefix}btn-hover-border-color: var(--#{$prefix}gray-600); + --#{$prefix}btn-focus-box-shadow-color: transparent; + --#{$prefix}btn-hover-color: var(--#{$prefix}gray-800); + } + } + } @else { + .btn-outline-#{$value} { + @include neo-mixins.variant-button-outlined( + map.get($key, "base"), + map.get($key, "dark"), + map.get($key, "pale"), + map.get($key, "light"), + map.get($key, "box-shadow") + ); + } + } + } + + @each $value, $key in $button-colors { + .btn-ghost-#{$value} { + &:hover, + &.hover, + &:focus-visible { + > span { + transform: translateY(0); + } + } + + @include neo-mixins.variant-button-ghost( + map.get($key, "base"), + map.get($key, "dark"), + map.get($key, "light"), + map.get($key, "box-shadow") + ); + + @if ($value == "tertiary") { + --#{$prefix}btn-color: #{$gray-800}; + --#{$prefix}btn-hover-color: #{$gray-800}; + + &:hover, + &.hover { + --#{$prefix}btn-hover-color: #{$gray-800}; + } + + &:first-child:active, + &:active, + &.active { + --#{$prefix}btn-active-color: #{$black}; + } + + &:disabled, + &.disabled { + --#{$prefix}btn-disabled-color: #{$gray-500}; + } + + &[data-state="selected"], + &.is-selected { + background-color: var(--#{$prefix}secondary-200); + } + } + } + } +} diff --git a/packages/bootstrap/src/themes/neov2/overrides/buttons/_index.scss b/packages/bootstrap/src/themes/neov2/overrides/buttons/_index.scss new file mode 100644 index 000000000..df136ce34 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/buttons/_index.scss @@ -0,0 +1 @@ +@forward "component"; diff --git a/packages/bootstrap/src/themes/neov2/overrides/header/_component.scss b/packages/bootstrap/src/themes/neov2/overrides/header/_component.scss new file mode 100644 index 000000000..a376e0706 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/header/_component.scss @@ -0,0 +1,209 @@ +@use "sass:color"; +@use "../../../../abstracts/" as *; +@use "../../../../vendors/bootstrap"; + +[data-product="neov2"] { + .header { + &.no-1d { + .collapse:not(.show) { + @include bootstrap.media-breakpoint-up(md) { + display: inline-flex; + } + } + } + + .container-fluid { + @include bootstrap.media-breakpoint-up(md) { + padding-inline: 0; + } + } + + .navbar { + --#{$prefix}navbar-padding-y: #{$navbar-padding-y}; + width: 100%; + background: linear-gradient(to bottom, $secondary, color.adjust($secondary, $lightness: -5%)); + box-shadow: $box-shadow; + + .container { + padding-top: 0; + padding-bottom: 0; + } + + .navbar-title { + font-size: 1.4rem; + font-weight: 700; + color: var(--#{$prefix}white); + } + + .navbar-nav { + display: inline-flex; + flex-direction: row; + align-items: center; + } + + .navbar-brand { + --#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y}; + --#{$prefix}navbar-brand-padding-x: #{$navbar-brand-padding-x}; + --#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end}; + + .logo { + height: 30px; + object-fit: contain; + object-position: left; + max-width: 100%; + width: auto; + } + + @include bootstrap.media-breakpoint-up(md) { + padding: 0; + margin-right: 0; + + .logo { + display: inline-block; + height: 52px; + } + } + } + + .nav-link { + display: inline-flex; + align-items: center; + align-self: self-end; + padding: $spacer-8; + align-items: center; + cursor: pointer; + border-bottom: 3px solid transparent; + border-radius: 0; + + &:hover { + border-bottom: 3px solid var(--#{$prefix}primary); + } + + &:not(.dropdown-item) { + .nav-text { + @include bootstrap.visually-hidden; + } + } + + .badge { + --#{$prefix}badge-padding-x: #{$navbar-badge-padding-x}; + --#{$prefix}badge-padding-y: #{$navbar-badge-padding-y}; + --#{$prefix}badge-font-size: #{$navbar-badge-font-size}; + right: 0; + top: $spacer-4; + + @include bootstrap.media-breakpoint-up(md) { + top: $spacer-12; + } + } + + @include bootstrap.media-breakpoint-up(md) { + padding: $spacer-16 $spacer-8; + > svg { + width: 3.2rem; + height: 3.2rem; + } + } + } + + .dropdown-menu { + position: absolute !important; + padding: $spacer-8; + background-color: $white; + display: none; + + .icon { + color: var(--#{$prefix}gray-800); + width: 1.6rem; + height: 1.6rem; + } + + .dropdown-item { + border-radius: $border-radius !important; + gap: $spacer-8; + font-size: 1.2rem; + width: 100%; + + @include bootstrap.media-breakpoint-up(md) { + border-radius: 0 !important; + + &.nav-link { + background-color: transparent; + &:hover { + background-color: transparent; + } + } + } + + @include bootstrap.media-breakpoint-down(md) { + &.nav-link { + border-bottom: 0; + &:hover { + border-bottom: 0; + } + } + } + } + + .dropdown-divider { + margin-block: $spacer-4; + } + + @include bootstrap.media-breakpoint-down(md) { + .avatar { + --#{$prefix}avatar-size: 2rem; + } + + &.show { + display: block !important; + } + } + + @include bootstrap.media-breakpoint-up(md) { + position: static !important; + display: flex; + background: transparent; + flex-direction: row; + padding: 0; + border-radius: 0; + border: 0; + box-shadow: none; + + .icon { + color: var(--#{$prefix}white); + + width: 3.2rem; + height: 3.2rem; + } + + .nav-text { + @include bootstrap.visually-hidden; + } + } + } + + .dropdown-menu-end { + right: 0; + } + + } + + i.ic-help::before { + content: ""; + display: block; + width: 2.4rem; + height: 2.4rem; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg' aria-hidden='true' color='%23fff'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 24c6.627 0 12-5.373 12-12S18.627 0 12 0 0 5.373 0 12s5.373 12 12 12ZM7.123 7.667C8.276 5.958 9.745 5 12.013 5 14.425 5 17 6.941 17 9.5c0 2.113-1.377 2.932-2.418 3.552-.633.376-1.142.68-1.142 1.154v.169a.693.693 0 0 1-.682.703h-2.06a.693.693 0 0 1-.681-.703v-.287c0-1.768 1.269-2.5 2.266-3.075l.073-.042c.863-.499 1.392-.838 1.392-1.499 0-.874-1.082-1.454-1.956-1.454-1.112 0-1.64.53-2.351 1.449a.668.668 0 0 1-.945.121L7.27 8.63a.718.718 0 0 1-.147-.963ZM9.76 17.97c0-1.12.883-2.03 1.969-2.03 1.085 0 1.968.91 1.968 2.03 0 1.119-.883 2.029-1.968 2.029-1.086 0-1.969-.91-1.969-2.03Z' fill='currentColor'%3E%3C/path%3E%3C/svg%3E"); + } + + @include bootstrap.media-breakpoint-up(md) { + i.ic-help::before { + width: 3.2rem; + height: 3.2rem; + } + } + } +} diff --git a/packages/bootstrap/src/themes/neov2/overrides/header/_index.scss b/packages/bootstrap/src/themes/neov2/overrides/header/_index.scss new file mode 100644 index 000000000..df136ce34 --- /dev/null +++ b/packages/bootstrap/src/themes/neov2/overrides/header/_index.scss @@ -0,0 +1 @@ +@forward "component"; diff --git a/packages/bootstrap/src/themes/one/_icons.scss b/packages/bootstrap/src/themes/one/_icons.scss new file mode 100644 index 000000000..a31913bef --- /dev/null +++ b/packages/bootstrap/src/themes/one/_icons.scss @@ -0,0 +1,146 @@ +@use '../../abstracts/colors' as *; + +$one-icons: ( + 'applications': ( + 'account': $one-orange, + 'actualites': $one-orange, + 'admin-portal': $one-yellow, + 'admin': $one-yellow, + 'archive': $one-yellow, + 'attendance': $one-green, + 'blog': $one-orange, + 'cahier-de-texte': $one-blue, + 'cahier-textes': $one-green, + 'calendar': $one-green, + 'canal-numerique': $one-pink, + 'cns': $one-pink, + 'collaborative-wall': $one-blue, + 'collaborativeeditor': $one-blue, + 'community': $one-blue, + 'competences': $one-green, + 'conversation': $one-orange, + 'crre': $one-pink, + 'directory': $one-green, + 'edt': $one-green, + 'exercizer': $one-blue, + 'qwant': $one-pink, + 'forms': $one-green, + 'forum': $one-orange, + 'library': $one-purple, + 'magneto': $one-blue, + 'mediacentre': $one-blue, + 'mindmap': $one-blue, + 'minibadge': $one-green, + 'notebook': $one-pink, + 'notes': $one-pink, + 'pad': $one-blue, + 'pages': $one-orange, + 'parametrage': $one-yellow, + 'parcours': $one-pink, + 'paths': $one-pink, + 'poll': $one-green, + 'polls': $one-green, + 'presences': $one-green, + 'rack': $one-green, + 'rbs': $one-green, + 'schoolbook': $one-orange, + 'scrap-book': $one-blue, + 'scrapbook': $one-blue, + 'searchengine': $one-pink, + 'settings-class': $one-yellow, + 'sharebigfiles': $one-green, + 'statistics': $one-yellow, + 'stats': $one-yellow, + 'support': $one-yellow, + 'timeline': $one-yellow, + 'timelinegenerator': $one-blue, + 'userbook': $one-green, + 'userbook-mood': $one-green, + 'userbook-moto': $one-green, + 'video': $one-pink, + 'visioconf': $one-orange, + 'web-conference': $one-orange, + 'website': $one-orange, + 'wiki': $one-blue, + 'workspace': $one-orange, + 'placeholder': $primary, + 'nabook': $nabook-color, + 'votil': $yellow, + 'appointments': $one-green, + 'communities': $one-purple, + 'minetest': $one-blue, + 'geogebra': $one-blue, + ), + 'connectors': ( + 'absences': $one-red, + 'admission-post-bac': $one-red, + 'aide-devoirs': $one-green, + 'agenda': $one-yellow, + 'assistance': $one-blue, + 'assr': $one-red, + 'award': $one-green, + 'banquesavoir': $one-blue, + 'bcdi': $one-purple, + 'biblionisep': $one-green, + 'bookmark-empty': $one-green, + 'canal-numerique': $one-red, + 'ccn': $one-green, + 'cerise': $one-red, + 'cervoprint': $one-blue, + 'charlemagne': $one-red, + 'charte': $one-yellow, + 'chat': $one-red, + 'cidj': $one-green, + 'connecteur-generique1': $one-orange, + 'connecteur-generique2': $one-orange, + 'educagri': $one-indigo, + 'edumedia': $one-blue, + 'edumoov': $one-red, + 'edutheque': $one-yellow, + 'electron': $one-red, + 'elyceepicardie': $one-indigo, + 'esidoc': $one-indigo, + 'europress': $one-blue, + 'gepi': $one-blue, + 'glpi': $one-red, + 'hiboutheque': $one-green, + 'itopstore': $one-green, + 'kne': $one-orange, + 'le-site-tv': $one-yellow, + 'lemonde': $one-indigo, + 'lesechos': $one-indigo, + 'lsu': $one-blue, + 'madmagz': $one-red, + 'matholycee': $one-red, + 'maxicours': $one-yellow, + 'mediacentre': $one-blue, + 'monorientationenligne': $one-yellow, + 'monstageenligne': $one-blue, + 'moodle': $one-orange, + 'museefrancaisphoto': $one-indigo, + 'my-network': $one-indigo, + 'netvibes': $one-green, + 'note': $one-yellow, + 'onisep': $one-blue, + 'onisep2': $one-blue, + 'parametrage': $one-red, + 'paraschool': $one-green, + 'pearltress': $one-blue, + 'picardie-cursus': $one-purple, + 'pro-eps': $one-blue, + 'pronote': $one-purple, + 'public': $one-red, + 'qwant-junior': $one-orange, + 'residence-artiste': $one-green, + 'ressourcesdepartementale91': $one-indigo, + 'sacoche': $one-indigo, + 'scolinfo': $one-orange, + 'suitcase': $one-red, + 'turboself': $one-yellow, + 'universalis': $one-red, + 'unstagepourtous': $one-pink, + 'vie-scolaire': $one-yellow, + 'webclasseur': $one-blue, + 'lool': $one-blue, + ), +); \ No newline at end of file diff --git a/packages/bootstrap/src/tokens/_icons.scss b/packages/bootstrap/src/tokens/_icons.scss index ee04680cf..d532127c6 100644 --- a/packages/bootstrap/src/tokens/_icons.scss +++ b/packages/bootstrap/src/tokens/_icons.scss @@ -1,146 +1,82 @@ @use 'sass:color'; @use 'sass:map'; @use '../abstracts/' as *; +@use '../themes/neo/icons' as *; +@use '../themes/one/icons' as *; +@use '../themes/neov2/icons' as *; -.color-app { - //applications - @each $app, $data in $icons-applications { - [data-product='neo'] & { - &-#{$app} { - color: map.get($data, 'neo'); - } - } +$theme-icons: ( + 'neo': $neo-icons, + 'one': $one-icons, + 'neov2': $neov2-icons, +); - [data-product='one'] & { - &-#{$app} { - color: map.get($data, 'one'); - } - } - } +@each $product, $config in $theme-icons { + $applications: map.get($config, 'applications'); + $connectors: map.get($config, 'connectors'); - //connectors - @each $app, $data in $icons-connectors { - [data-product='neo'] & { - &-#{$app} { - color: map.get($data, 'neo'); + [data-product='#{$product}'] { + .color-app { + @each $app, $color in $applications { + &-#{$app} { + color: $color; + } } - } - - [data-product='one'] & { - &-#{$app} { - color: map.get($data, 'one'); + + @each $app, $color in $connectors { + &-#{$app} { + color: $color; + } } } - } -} -.bg-app { - //applications - @each $app, $data in $icons-applications { - [data-product='neo'] & { - &-#{$app} { - background-color: map.get($data, 'neo'); + .bg-app { + @each $app, $color in $applications { + &-#{$app} { + background-color: $color; + } } - } - [data-product='one'] & { - &-#{$app} { - background-color: map.get($data, 'one'); + @each $app, $color in $connectors { + &-#{$app} { + background-color: $color; + } } } - } - //connectors - @each $app, $data in $icons-connectors { - [data-product='neo'] & { - &-#{$app} { - background-color: map.get($data, 'neo'); + .bg-light { + @each $app, $color in $applications { + &-#{$app} { + background-color: color.scale( + $color, + $lightness: 90%, + $saturation: 5% + ); + } } - } - [data-product='one'] & { - &-#{$app} { - background-color: map.get($data, 'one'); + @each $app, $color in $connectors { + &-#{$app} { + background-color: color.scale( + $color, + $lightness: 90%, + $saturation: 5% + ); + } } } - } -} -.bg-light { - // applications - @each $app, $data in $icons-applications { - [data-product='neo'] & { - &-#{$app} { - background-color: color.scale( - map.get($data, 'neo'), - $lightness: 90%, - $saturation: 5% - ); + .border-app { + @each $app, $color in $applications { + &-#{$app} { + border-color: $color; + } } - } - - [data-product='one'] & { - &-#{$app} { - background-color: color.scale( - map.get($data, 'one'), - $lightness: 90%, - $saturation: 5% - ); - } - } - } - - //connectors - @each $app, $data in $icons-connectors { - [data-product='neo'] & { - &-#{$app} { - background-color: color.scale( - map.get($data, 'neo'), - $lightness: 90%, - $saturation: 5% - ); - } - } - - [data-product='one'] & { - &-#{$app} { - background-color: color.scale( - map.get($data, 'one'), - $lightness: 90%, - $saturation: 5% - ); - } - } - } -} - -.border-app { - //applications - @each $app, $data in $icons-applications { - [data-product='neo'] & { - &-#{$app} { - border-color: map.get($data, 'neo'); - } - } - - [data-product='one'] & { - &-#{$app} { - border-color: map.get($data, 'one'); - } - } - } - - //connectors - @each $app, $data in $icons-connectors { - [data-product='neo'] & { - &-#{$app} { - border-color: map.get($data, 'neo'); - } - } - [data-product='one'] & { - &-#{$app} { - border-color: map.get($data, 'one'); + @each $app, $color in $connectors { + &-#{$app} { + border-color: $color; + } } } }