ng-hub-ui-ds
La base de design tokens compartida de la familia ng-hub-ui: las variables CSS --hub-ref-* (primitivas) y --hub-sys-* (semánticas), con claro/oscuro y 8 temas. Impórtala una vez y toda la familia lee la misma paleta.
¿Qué es y para qué sirve?
Su función es homogeneizar y cablear las variables de estilo a lo largo de todas las bibliotecas de la familia. Cada librería se tematiza con variables --hub-* pero no las define: las consume. Este paquete es la fuente de verdad única que las conecta, de modo que:
- Una sola paleta alimenta panels, forms, calendar, board… a la vez.
- Re-tematizas una vez (un token) y el cambio se propaga a toda la familia.
- Modo oscuro y 8 temas listos, conmutables con un atributo.
- La usas también en tu propio CSS, así tu UI casa con los componentes.
El cableado se está desplegando biblioteca a biblioteca: más abajo, en la familia, está el estado de integración de cada una. ¿Buscas el catálogo completo de tokens? Está en la referencia de tokens.
Primeros pasos
La ruta completa: qué instalar, qué importar y dónde, y qué mecanismo usar para cada modificación. El ds no tiene dependencias (CSS/SCSS puro) y nada se emite salvo que lo importes.
1 · Instalar
El ds es la base; añade las librerías de la familia que uses. Ninguna define la paleta — todas consumen los tokens del ds.
npm install ng-hub-ui-ds
npm install ng-hub-ui-panels ng-hub-ui-forms … # las que uses2 · Importar — una vez, en la raíz, y en este orden
/* styles.scss (raíz de la app) */
/* 1 · Tokens — SIEMPRE, una sola vez: la base que toda la familia consume */
@use 'ng-hub-ui-ds/styles/tokens/hub-tokens';
/* 2 · Reset de elementos nativos — solo si tu app no trae ya uno (Bootstrap Reboot…) */
@use 'ng-hub-ui-ds/styles/base/reset';
/* 3 · Utilidades — opt-in: importa solo las hojas que uses
(nombres Bootstrap-exactos: NO las cargues junto a Bootstrap global) */
@use 'ng-hub-ui-ds/styles/utilities/layout';
@use 'ng-hub-ui-ds/styles/utilities/text';
@use 'ng-hub-ui-ds/styles/utilities/surfaces';
/* 4 · Hojas propias de algunas librerías — una vez, la ruta la documenta su README */
@use 'ng-hub-ui-forms/src/lib/styles/index' as hub-forms; // chrome compartido de forms
@use 'ng-hub-ui-utils/styles/tooltip'; // tooltip de utils
/* 5 · Mixins — cuando construyas tus propios componentes con el mismo sistema */
@use 'ng-hub-ui-ds' as hub;
.page { @include hub.center($max: xl); } Sin Sass también funciona: cada hoja tiene su gemela .css compilada — @import 'ng-hub-ui-ds/styles/tokens/hub-tokens.css'; — o vía angular.json:
"styles": [
"node_modules/ng-hub-ui-ds/styles/tokens/hub-tokens.css",
"src/styles.scss"
]3 · Modificar — qué mecanismo según qué cambias
| Quiero… | Mecanismo | Dónde se explica |
|---|---|---|
| Cambiar un color global (p. ej. el primary) | :root { --hub-sys-color-primary: … } — re-tematiza toda la familia | Cómo modificarlo |
| Añadir un acento nuevo (brand, tertiary…) | CSS: --hub-sys-color-brand · Sass: $hub-accents-extra | Cómo modificarlo |
| Quitar variantes que no uso | Sass: sustituye el mapa — with ($hub-accents: (primary: …, danger: …)) — y solo se emiten esas familias | Funciones SCSS |
| Ajustar spacing / radios / grid | Sobrescribir los tokens estructurales --hub-ref-space-* / --hub-sys-radius-* / --hub-sys-grid-* | Capa estructural |
| Un tema completo (dark, corporate…) | [data-theme='…'] { tokens que difieran } + atributo en <html> | Crea tu tema |
| Construir MIS componentes con el mismo sistema | Mixins: @include hub.stack() · hub.text-bg(brand) · hub.radius(lg)… — o las clases de utilidad | Mixins y estilos |
| Convivir con Bootstrap / Material / Tailwind | Mixins puente: @include hub.bridge-bootstrap($mode: adopt | project) | Puentes |
| Afinar UN componente de UNA librería | Sus hooks propios --hub-<componente>-* (scoped o globales) | Referencia de tokens y la página de cada librería |
4 · Y el resto de bibliotecas
Con los tokens cargados, no hay nada más que configurar: cada ng-hub-ui-* lee --hub-sys-* y se re-tematiza sola con tus overrides. Además, cada componente expone hooks --hub-<componente>-* para el ajuste fino, y algunas librerías traen hojas propias que se importan una vez junto a los tokens — la ruta exacta la documenta el README de cada una (p. ej. el chrome compartido de forms o el tooltip/overlay de utils, como en el bloque del paso 2). El estado de integración de cada librería está en la familia.
Arquitectura: las dos capas
--hub-ref-*
Valores crudos sin contexto: rampas de color, espaciado, radios, tipografía.
--hub-ref-color-blue-500--hub-sys-*
Asignaciones con significado que consumen los componentes.
--hub-sys-color-primary Regla de oro: los componentes referencian solo tokens sys; los sys apuntan a los ref. Cambiar un sys re-tematiza; cambiar un ref ajusta la paleta base.
Colores semánticos · temas en vivo
El set es abierto: 9 variantes por defecto (5 cromáticas + 4 neutrales) y las que tú añadas. Cada acento expone una familia uniforme de roles — subtle, border-subtle, emphasis y el par de contraste on. Cambia el tema y observa cómo toda la paleta se re-colorea.
Crea tu tema · cambia solo los colores base
Define únicamente el color base de cada familia semántica. El resto (subtle, border-subtle, emphasis, on) se deriva automáticamente con color-mix / relative color — y los componentes de abajo se re-tematizan en vivo, demostrando el cableado compartido.
Componentes en vivo
.mi-tema {
/* define SOLO el color base de cada familia */
--hub-sys-color-primary: #6d28d9;
/* el resto se deriva en runtime con color-mix / relative color — nada que mantener */
--hub-sys-color-primary-subtle: color-mix(in oklch, var(--hub-sys-color-primary) 12%, var(--hub-sys-surface-page));
--hub-sys-color-primary-border-subtle: color-mix(in oklch, var(--hub-sys-color-primary) 35%, var(--hub-sys-surface-page));
--hub-sys-color-primary-emphasis: color-mix(in oklch, var(--hub-sys-color-primary) 80%, var(--hub-sys-color-ink));
--hub-sys-color-primary-on: oklch(from var(--hub-sys-color-primary) clamp(0, (0.62 - l) * 1000, 1) 0 h);
}La familia · estado de integración
Toda la familia lee estos tokens. El badge indica si la biblioteca ya está cableada a --hub-sys-* (se re-tematiza con el design-system) o está pendiente de cablear (la abordamos luego). Pulsa cualquiera para ver sus ejemplos.
Cómo modificarlo
1. Sobrescribir un token (CSS) — el camino principal
Cada valor es una variable CSS, así que re-tematizar es una línea y cascada a toda la familia:
:root {
--hub-sys-color-primary: #7c3aed;
--hub-sys-color-primary-subtle: #ede9fe;
--hub-sys-color-primary-emphasis: #5b21b6;
}2. Añadir tu propio acento
Define una familia --hub-sys-color-<nombre> y los componentes que aceptan una variante semántica la recogen sin cambios. Pruébalo aquí en vivo:
color-mix. :root {
--hub-sys-color-brand: #9333ea;
--hub-sys-color-brand-subtle: #f3e8ff;
--hub-sys-color-brand-border-subtle: #d8b4fe;
--hub-sys-color-brand-emphasis: #6b21a8;
}
<!-- en cualquier componente que acepte una variante semántica -->
<hub-panel appearance="alert" variant="brand">Aviso de marca</hub-panel> Con solo --hub-sys-color-brand ya funciona (los componentes derivan el resto con color-mix). Define la familia completa cuando quieras tintes exactos.
… o predefínelo en el mapa abierto (Sass)
Si usas Sass, amplía el mapa abierto de acentos antes de incluir el paquete con $hub-accents-extra. Solo se recompila el ds — nunca las librerías— y cada variante nueva obtiene su familia completa (subtle · border-subtle · emphasis · on):
// Añade tus propias variantes — solo recompila el ds, nunca las librerías.
@use 'ng-hub-ui-ds/styles/tokens/hub-tokens' with (
$hub-accents-extra: (
brand: #ff6b00,
accent: #00b8d9,
tertiary: #9c36b5
)
);
// brand · accent · tertiary obtienen subtle · border-subtle · emphasis · on automáticamente.3. Crear un tema propio
[data-theme='corporate'] {
--hub-sys-color-primary: #0033a0;
--hub-sys-surface-page: #fbfcff;
--hub-sys-text-primary: #0a1f44;
/* …el resto de tokens que difieran del base */
}4. …o todo junto con hub.theme() (Sass)
Un único mixin de tematización parcial: pásale solo los cambios como mapas y emite las variables con el nombre canónico. Todo lo que cuelga de cada token — alias sys, familias de rol, utilidades, componentes — se re-deriva solo por la cadena de var():
@use 'ng-hub-ui-ds' as hub;
/* cambia SOLO el paso 3 del spacing — gap-3, .p-3, sys-gap-3, componentes… se mueven con él */
:root { @include hub.theme($space: (3: 1.25rem)); }
/* o un tema completo, scopeable a [data-theme] o a un subárbol */
[data-theme='compact'] {
@include hub.theme(
$space: (3: 0.75rem, 4: 1rem),
$radius: (md: 0.25rem),
$accents: (primary: #0f766e, brand: #ff6b00)
);
}Funciones SCSS: cómo se genera por dentro
Las familias de color semántico no se escriben a mano: el set de acentos es un mapa abierto con !default y la familia se deriva con un @each sobre map.keys($hub-accents). Por eso añadir un color (o nueve) es uniforme y sin boilerplate: toda clave del mapa obtiene su familia automáticamente.
// El set de acentos es un mapa ABIERTO con !default — añade los que quieras.
$hub-accents: (
primary: …, secondary: …, success: …, danger: …, warning: …,
info: …, neutral: …, light: …, dark: …
) !default;
// La familia se deriva UNA vez en :root, iterando TODAS las claves del mapa,
// así que cualquier acento que añadas obtiene su familia gratis.
@mixin hub-color-derive() {
@each $name in map.keys($hub-accents) {
--hub-sys-color-#{$name}-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 12%, var(--hub-sys-surface-page));
--hub-sys-color-#{$name}-emphasis: color-mix(in oklch, var(--hub-sys-color-#{$name}) 80%, var(--hub-sys-color-ink));
--hub-sys-color-#{$name}-on: oklch(from var(--hub-sys-color-#{$name}) clamp(0, (0.62 - l) * 1000, 1) 0 h);
}
}Para la mayoría de casos no necesitas tocar el SCSS: la sobrescritura de variables CSS cubre re-tematizar y añadir acentos. El mapa + mixin es la mecánica interna, útil si contribuyes al paquete.
Capa estructural · tokens en vivo
Además del color, el ds define una capa estructural canónica: escala de spacing (--hub-ref-space-*), sizing y fracciones (--hub-sys-size-*), grid (--hub-sys-grid-columns, gutters) y una escala de gap semántica (--hub-sys-gap-*). Todo abajo se pinta consumiendo esas variables.
Escala de spacing · --hub-ref-space-0…7
Escala de gap · --hub-sys-gap-0…5
Fracciones de ancho · --hub-sys-size-*
Grid auto-fit + container widths
/* Tokens estructurales canónicos (ref → sys) */
gap: var(--hub-sys-gap-3); /* escala de spacing */
padding-inline: var(--hub-ref-space-4);
max-width: var(--hub-sys-container-max-width-lg);
grid-template-columns: repeat(var(--hub-sys-grid-columns), minmax(0, 1fr));
/* Mixins de layout */
@use 'ng-hub-ui-ds' as hub;
.page { @include hub.center($max: xl); }
.toolbar { @include hub.cluster($gap: 2); }
.cards { @include hub.grid($min: 16rem, $gap: 3); }
/* Utilidades opt-in (nomenclatura Bootstrap, 3 hojas) */
@use 'ng-hub-ui-ds/styles/utilities/layout'; // .d-flex .gap-3 .ms-auto .position-* .ratio-*
@use 'ng-hub-ui-ds/styles/utilities/text'; // .fs-3 .fw-bold .text-truncate .text-muted
@use 'ng-hub-ui-ds/styles/utilities/surfaces'; // .bg-* .border .rounded .shadow .opacity-*Mixins y estilos
La API Sass del ds: helpers que consumen los tokens canónicos — sin hornear spacing ni color. Se importan namespaced con @use 'ng-hub-ui-ds' as hub. Las hojas de utilidades se construyen desde estos mismos mixins, así que modificar o ampliar un comportamiento es acuñar tu propia clase con el mixin. Cada demo de abajo está construida desde el mixin real; al final tienes el catálogo completo.
Cada mixin tiene una utilidad equivalente; las demos de abajo consumen la clase real del ds (.cluster, .stack…) — esta página no re-aplica ningún mixin.
hub.cluster() · .cluster — fila que envuelve
hub.stack() · .stack — columna
hub.grid() · .grid-auto — grid auto-fit
hub.center() · .center — wrapper centrado
@use 'ng-hub-ui-ds' as hub;
.toolbar { @include hub.cluster($gap: 2); } // fila que envuelve
.feed { @include hub.stack($gap: 3); } // columna
.cards { @include hub.grid($min: 8rem, $gap: 2); } // grid auto-fit
.page { @include hub.center($max: sm); } // wrapper centradoCatálogo completo
| Mixin | Parámetros | Descripción |
|---|---|---|
| Tema | ||
hub.theme() | $accents, $space, $gap, $radius, $shadow, $font-*, $line-height, $tokens | Tematización parcial en una llamada: pásale solo los cambios como mapas y emite las variables canónicas; lo derivado se re-deriva solo. |
| Breakpoints | ||
hub.media-breakpoint-up() | $name, $breakpoints: $hub-breakpoints | Media query mobile-first desde el breakpoint (sm 576 · md 768 · lg 992 · xl 1200 · xxl 1400). |
hub.media-breakpoint-down() | $name, $breakpoints: $hub-breakpoints | Media query por debajo del breakpoint. |
| Layout | ||
hub.stack() | $gap: 3, $align: stretch | Columna flex con gap de token. |
hub.cluster() | $gap: 2, $align: center, $justify: flex-start | Fila flex que envuelve. |
hub.grid() | $min: 16rem, $gap: 4 | Grid auto-fit con ancho mínimo por celda. |
hub.grid-fixed() | $cols: 12, $gap: 4 | Grid de N columnas fijas. |
hub.row() | $gap: 3 | Fila de 12 tracks (--hub-sys-grid-columns). |
hub.col() | $span: 12 | Celda que abarca $span tracks de una row(). |
hub.offset() | $n: 0 | Arranca una col() en el track $n + 1 (offset de Bootstrap); 0 resetea. |
hub.center() | $max: xl, $pad: 3 | Wrapper centrado a un max-width de contenedor. |
| Tipografía | ||
hub.font-family() | $family: base | base | display | mono. |
hub.font-size() | $size: base | 1–6 (escala de headings) o xs | sm | base | lg. |
hub.font-weight() | $weight: base | light | base | medium | semibold | bold. |
hub.line-height() | $height: base | 1 | sm | base | lg. |
hub.text-color() | $variant: body | Acento del mapa abierto, body o muted; atenúa con --hub-text-opacity. |
hub.link-color() | $variant: primary | Enlace del acento con hover -emphasis y subrayado con opacidad (--hub-link-underline-opacity). |
hub.text-truncate() | — | Truncado a una línea con elipsis. |
hub.text-break() | — | Rompe palabras/URLs largas sin desbordar. |
| Superficies | ||
hub.bg() | $variant: body, $subtle: false | Fondo de acento (o su tinte subtle), body o transparent; atenúa con --hub-bg-opacity. |
hub.text-bg() | $variant: primary | Fondo de acento + color -on de contraste garantizado. |
hub.border() | $width: 1px, $color: … | Borde sólido con el token de borde por defecto. |
hub.border-color() | $variant: primary | Color de borde desde un acento del mapa abierto. |
hub.radius() | $size: md | none | sm | md | lg | xl | xxl | pill | circle. |
hub.shadow() | $size: md | none | sm | md | lg | inset. |
| Helpers | ||
hub.focus-ring() | — | Anillo de foco con los tokens --hub-sys-focus-ring-*. |
hub.visually-hidden() | — | Oculta visualmente manteniendo el acceso para lectores de pantalla. |
hub.stretched-link() | — | Extiende el área clicable del enlace a su ancestro posicionado. |
hub.ratio() | $x: 16, $y: 9 | Proporción fija con aspect-ratio nativo. |
hub.clearfix() | — | Limpia flotados (::after). |
| Puentes | ||
hub.bridge-bootstrap() | $mode: adopt | project | Adopta el tema de --bs-* o lo proyecta sobre él. |
hub.bridge-material() | $mode: adopt | project | Ídem con --mat-sys-* (Angular Material 3). |
hub.bridge-tailwind() | $mode: adopt | project | Ídem con --color-* (Tailwind v4 @theme). |
hub.bridge-open-props() | $mode: adopt | Alias de las rampas de Open Props. |
Utilidades
Clases opt-in que envuelven la misma capa, con nombres exactamente iguales a los de Bootstrap — drop-in replacement, pero no cargues las hojas Y Bootstrap globalmente en el mismo documento. Tres hojas: layout (display/flex, grid, spacing, sizing, position, helpers — estas secciones), text (sección «Texto») y surfaces (sección «Superficies»). La demo usa las clases reales:
.cluster .gap-2
.grid-auto .gap-2
Sizing · .w-50 · .w-25 · .w-auto
// tres hojas opt-in — importa solo las que uses
@use 'ng-hub-ui-ds/styles/utilities/layout'; // layout, spacing, position, helpers
@use 'ng-hub-ui-ds/styles/utilities/text'; // tipografía y texto
@use 'ng-hub-ui-ds/styles/utilities/surfaces'; // fondos, bordes, radios, sombras
<div class="cluster gap-2"> … </div>
<div class="grid-auto gap-2"> … </div>
<div class="w-50">mitad</div>
<div class="vh-100 min-vh-100">alto de viewport</div>Flexbox
Set completo de utilidades de display y flexbox, con la nomenclatura exacta de Bootstrap. Las demos usan las clases reales del ds.
justify-content · .justify-content-* — eje principal
.justify-content-startalign-items · .align-items-* — eje cruzado
.align-items-startflex-direction · .flex-column
flex-fill / flex-grow-0 — crecer y fijar
Responsive · .flex-md-row · .align-items-md-center
Toda la familia flex tiene variantes por breakpoint. Columna en móvil, fila centrada desde md — redimensiona la ventana:
Separador vertical · .vr
<!-- display + dirección / wrap -->
<div class="d-flex flex-wrap gap-2"> … </div>
<div class="d-flex flex-column"> … </div>
<!-- eje principal (justify) y cruzado (align) -->
<div class="d-flex justify-content-between align-items-center"> … </div>
<!-- crecer / fijar -->
<div class="d-flex gap-2">
<span class="flex-fill">crece</span>
<span class="flex-grow-0">fijo</span>
</div>
<!-- responsive: columna en móvil, fila alineada arriba desde md -->
<div class="d-flex flex-column flex-md-row align-items-md-start"> … </div>
<!-- separador vertical -->
<div class="d-flex gap-3">izq <span class="vr"></span> dcha</div>Columnas, anchos y spacing
Rejilla de 12 columnas (.row + .col-1…12 + .offset-1…11, driven por --hub-sys-grid-columns), anchos y padding/margin direccionales. Cada demo usa las utilidades reales.
Columnas · .row + .col-N
Offsets · .offset-N
La celda arranca en el track n + 1 de la misma rejilla (grid-column-start); con breakpoint, .offset-md-8, y .offset-md-0 resetea a colocación automática.
Anchos · .w-25 / 50 / 75 / 100 / auto
Padding · .p-1…5 (los 4 lados)
Padding por eje · .px-* / .py-*
Margin · .m-1…5 (dentro de un marco de referencia)
Margin por eje · .mx-* / .my-*
Responsive · .col-md-6 · .d-lg-none · .p-sm-3
Variantes mobile-first (sm 576 · md 768 · lg 992 · xl 1200 · xxl 1400) para display, columnas y offsets, spacing, gap y toda la familia flex (.flex-md-row, .justify-content-md-center, .align-items-md-start, .order-lg-*…). Redimensiona la ventana — estas celdas son .col-12 .col-md-6 .col-xl-3:
<!-- mobile-first: 1 columna → 2 en ≥768px → 4 en ≥1200px -->
<div class="row">
<div class="col-12 col-md-6 col-xl-3">…</div>
</div>
<div class="d-none d-lg-flex">solo escritorio</div>
<section class="p-2 p-md-4">padding que crece con el viewport</section>
// breakpoints como mixin — para cualquier otra utilidad o tu propio CSS
@use 'ng-hub-ui-ds' as hub;
@include hub.media-breakpoint-up(md) { .sidebar { width: 18rem; } }<!-- 12-column grid: cada fila suma 12 -->
<div class="row">
<div class="col-6">col-6</div>
<div class="col-6">col-6</div>
</div>
<div class="row">
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
</div>
<!-- offset: .col-4.offset-8 arranca en el track 9 (offset-{bp}-0 resetea) -->
<div class="row">
<div class="col-4 offset-md-8">col-4 offset-md-8</div>
</div>
<!-- anchos · padding · margin direccionales -->
<div class="w-50">w-50</div>
<div class="p-3">padding 1rem en los 4 lados</div>
<div class="px-4 py-2">padding-inline 1.5rem · padding-block .5rem</div>
<div class="mx-3">margin-inline 1rem</div>Texto
Utilidades de tipografía y texto con la nomenclatura exacta de Bootstrap, construidas sobre los mixins de tipografía (hub.font-size(), hub.font-weight(), hub.text-color()…): cada valor resuelve a tokens, así que sobrescribir el token re-tematiza las utilidades — y con los mixins puedes acuñar tus propias variantes.
Tamaño · .fs-1…6 · headings · .h1…6
.fs-* cambia solo el tamaño; .h1…6 aplica la tipografía completa de un heading (tamaño + negrita + interlineado compacto + margen) sin la semántica — un <div class="h5"> se lee como un <h5>:
Peso · .fw-* · estilo · .fst-italic
Alineación · .text-start / .text-center / .text-end
Transform · decoración · familia
Truncado · .text-truncate
Interlineado · .lh-1 / .lh-sm / .lh-base / .lh-lg
Colores · .text-primary … .text-muted
Opacidad de texto · .text-opacity-* · enlaces · .link-*
// importa la hoja una vez
@use 'ng-hub-ui-ds/styles/utilities/text';
<h2 class="fs-3 fw-semibold">Titular</h2>
<p class="text-muted lh-lg">Secundario con interlineado holgado</p>
<span class="text-uppercase fw-medium">etiqueta</span>
<td class="text-end font-monospace">1.234,56 €</td>
<p class="text-truncate" style="max-width: 16rem">Se trunca con elipsis…</p>
// …o acuña tus propias variantes con los mixins
@use 'ng-hub-ui-ds' as hub;
.card__title { @include hub.font-size(4); @include hub.font-weight(semibold); }
.card__meta { @include hub.text-color(muted); @include hub.text-truncate(); }Superficies
Fondos, bordes, radios, sombras y opacidad con la nomenclatura exacta de Bootstrap, construidos sobre los mixins de superficie (hub.bg(), hub.text-bg(), hub.radius(), hub.shadow()…) y los tokens --hub-sys-color-* / --hub-sys-radius-* / --hub-sys-shadow-*.
Fondos · .bg-* y .bg-*-subtle
Fondo + contraste garantizado · .text-bg-*
Bordes · .border · .border-{variant} · .border-1…5
Radios · .rounded-0…3 · .rounded-pill · .rounded-circle
Sombras · .shadow-sm / .shadow / .shadow-lg
Opacidad · .opacity-* (elemento) · .bg-opacity-* (solo fondo)
// importa la hoja una vez
@use 'ng-hub-ui-ds/styles/utilities/surfaces';
<span class="badge text-bg-success rounded-pill">activo</span>
<div class="bg-warning-subtle border border-warning rounded-3 p-3">aviso</div>
<div class="bg-body rounded shadow-lg p-4">tarjeta elevada</div>
// …o acuña tus propias variantes con los mixins
@use 'ng-hub-ui-ds' as hub;
.card { @include hub.bg(body); @include hub.radius(lg); @include hub.shadow(sm); }
.card--brand { @include hub.text-bg(brand); } // cualquier acento del mapa abiertoPosición y helpers
Position/inset, overflow, order, float, visibilidad, z-index, object-fit e interacciones — más los helpers de comportamiento (.visually-hidden, .stretched-link, .ratio-*, .clearfix). Todo con la nomenclatura exacta de Bootstrap.
Posición · .position-* + .top/.start/.translate-middle
Ratio · .ratio .ratio-16x9
Overflow · interacción · spacing lateral
Focus ring · .focus-ring
Anillo de foco dirigido por los tokens --hub-sys-focus-ring-* — haz clic o Tab:
Accesibilidad · .visually-hidden
Este párrafo contiene un texto oculto visualmente pero anunciado por lectores de pantalla: solo para tecnología de asistencia (inspecciona el DOM para verlo).
<!-- badge posicionado sobre la esquina del contenedor -->
<div class="position-relative">
…
<span class="position-absolute top-0 start-100 translate-middle text-bg-danger rounded-pill px-2">9+</span>
</div>
<!-- media a proporción fija -->
<div class="ratio ratio-16x9"><iframe src="…"></iframe></div>
<!-- tarjeta entera clicable + texto solo para lectores -->
<div class="position-relative">
<a href="…" class="stretched-link">Ver más<span class="visually-hidden"> sobre superficies</span></a>
</div>
<!-- empujar con auto-margins dentro de un flex -->
<nav class="d-flex gap-2"><span>logo</span><a class="ms-auto">login</a></nav>Puentes a otros sistemas
Mixins opt-in que conectan hub con el framework presente. Coste cero si no los llamas. Dos direcciones con $mode: adopt (hub toma el tema del host) y project (hub proyecta su tema sobre el host).
@use 'ng-hub-ui-ds' as hub;
/* "tengo Bootstrap y quiero que hub adopte su paleta" */
:root { @include hub.bridge-bootstrap($mode: adopt); }
/* "quiero teñir Material y Tailwind con MI tema hub" */
:root { @include hub.bridge-material($mode: project); }
:root { @include hub.bridge-tailwind($mode: project); }| Mixin | Sistema | adopt | project |
|---|---|---|---|
hub.bridge-bootstrap | Bootstrap 5.3+ | lee --bs-* | tiñe --bs-* + gutters/radius |
hub.bridge-material | Angular Material 3 | lee --mat-sys-* | tiñe --mat-sys-* (par color/on) |
hub.bridge-tailwind | Tailwind v4 | lee --color-* | emite --color-* para @theme |
hub.bridge-open-props | Open Props | alias de rampas | — |
Referencia rápida
| Quiero… | Cómo |
|---|---|
| Usar la paleta | @use '…/hub-tokens' |
| Cambiar un color global | :root { --hub-sys-color-primary: … } |
| Añadir variantes propias | with ($hub-accents-extra: (brand: …)) |
| Texto con contraste | color: var(--hub-sys-color-primary-on) |
| Layout (mixin / utilidad) | @include hub.center() · .stack |
| Texto (mixin / utilidad) | @include hub.font-size(3) · .fs-3 .fw-bold .text-muted |
| Superficies (mixin / utilidad) | @include hub.text-bg(brand) · .bg-primary-subtle .rounded .shadow |
| Posición / helpers | .position-absolute .top-0 · .ratio-16x9 · .visually-hidden |
| Responsive | .col-md-6 · .flex-md-row · .offset-md-8 · @include hub.media-breakpoint-up(md) |
| Puente a Bootstrap/Material | @include hub.bridge-bootstrap($mode: adopt) |
| Crear un tema | [data-theme='<nombre>'] { … } |
| Tematización parcial (Sass) | @include hub.theme($space: (3: 1.25rem), $accents: (primary: …)) |