@heroelc/fsociety 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heroelc/fsociety",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Angular component library with design system tokens, mixins and UI components",
5
5
  "author": "Heroel Carpinetti <heroeljcarpinetti@gmail.com>",
6
6
  "license": "MIT",
@@ -0,0 +1,473 @@
1
+ @use 'tokens' as t;
2
+
3
+ // =============================================================================
4
+ // fsociety · _mixins.scss
5
+ // Mixins reutilizables + clases utilitarias generadas automáticamente
6
+ //
7
+ // USO CON @include (en SCSS de componentes):
8
+ // @use '../styles/mixins' as m;
9
+ // .mi-componente { @include m.flex-center; @include m.pl(6); }
10
+ //
11
+ // USO CON CLASE (directo en HTML):
12
+ // <div class="flex-center pl-6 mt-4 truncate">
13
+ // =============================================================================
14
+
15
+
16
+ // -----------------------------------------------------------------------------
17
+ // 1. FLEXBOX / LAYOUT
18
+ // -----------------------------------------------------------------------------
19
+
20
+ @mixin flex-center {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ }
25
+
26
+ @mixin flex-between {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: space-between;
30
+ }
31
+
32
+ @mixin flex-around {
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: space-around;
36
+ }
37
+
38
+ @mixin flex-start {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: t.$fs-space-2;
42
+ }
43
+
44
+ @mixin flex-end {
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: flex-end;
48
+ }
49
+
50
+ @mixin flex-col {
51
+ display: flex;
52
+ flex-direction: column;
53
+ }
54
+
55
+ @mixin flex-col-center {
56
+ display: flex;
57
+ flex-direction: column;
58
+ align-items: center;
59
+ justify-content: center;
60
+ }
61
+
62
+ @mixin inline-flex-center {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ }
67
+
68
+ // stack — flex column con gap configurable
69
+ // @param $gap — valor de gap (default: $fs-space-4)
70
+ @mixin stack($gap: t.$fs-space-4) {
71
+ display: flex;
72
+ flex-direction: column;
73
+ gap: $gap;
74
+ }
75
+
76
+ // inline-stack — flex row con gap configurable
77
+ // @param $gap — valor de gap (default: $fs-space-2)
78
+ @mixin inline-stack($gap: t.$fs-space-2) {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: $gap;
82
+ }
83
+
84
+ // Clases utilitarias de flexbox
85
+ .flex-center { @include flex-center; }
86
+ .flex-between { @include flex-between; }
87
+ .flex-around { @include flex-around; }
88
+ .flex-start { @include flex-start; }
89
+ .flex-end { @include flex-end; }
90
+ .flex-col { @include flex-col; }
91
+ .flex-col-center { @include flex-col-center; }
92
+ .inline-flex-center{ @include inline-flex-center; }
93
+
94
+ // gap utilitario
95
+ $gap-scale: (
96
+ 1: t.$fs-space-1,
97
+ 2: t.$fs-space-2,
98
+ 3: t.$fs-space-3,
99
+ 4: t.$fs-space-4,
100
+ 5: t.$fs-space-5,
101
+ 6: t.$fs-space-6,
102
+ 8: t.$fs-space-8,
103
+ );
104
+
105
+ @each $key, $val in $gap-scale {
106
+ .gap-#{$key} { gap: $val; }
107
+ }
108
+
109
+
110
+ // -----------------------------------------------------------------------------
111
+ // 2. SPACING — padding y margin con lados individuales
112
+ // -----------------------------------------------------------------------------
113
+
114
+ // Escala de spacing mapeada a los tokens
115
+ $spacing-scale: (
116
+ 0: 0,
117
+ 1: t.$fs-space-1, // 4px
118
+ 2: t.$fs-space-2, // 8px
119
+ 3: t.$fs-space-3, // 12px
120
+ 4: t.$fs-space-4, // 16px
121
+ 5: t.$fs-space-5, // 20px
122
+ 6: t.$fs-space-6, // 24px
123
+ 8: t.$fs-space-8, // 32px
124
+ 10: t.$fs-space-10, // 40px
125
+ 12: t.$fs-space-12, // 48px
126
+ 16: t.$fs-space-16, // 64px
127
+ );
128
+
129
+ // ---------- Mixins de padding ----------
130
+
131
+ @mixin p($val) { padding: $val; }
132
+ @mixin px($key) { padding-left: map-get($spacing-scale, $key); padding-right: map-get($spacing-scale, $key); }
133
+ @mixin py($key) { padding-top: map-get($spacing-scale, $key); padding-bottom: map-get($spacing-scale, $key); }
134
+ @mixin pl($key) { padding-left: map-get($spacing-scale, $key); }
135
+ @mixin pr($key) { padding-right: map-get($spacing-scale, $key); }
136
+ @mixin pt($key) { padding-top: map-get($spacing-scale, $key); }
137
+ @mixin pb($key) { padding-bottom: map-get($spacing-scale, $key); }
138
+
139
+ // ---------- Mixins de margin ----------
140
+
141
+ @mixin m($val) { margin: $val; }
142
+ @mixin mx($key) {
143
+ @if $key == 'auto' {
144
+ margin-left: auto; margin-right: auto;
145
+ } @else {
146
+ margin-left: map-get($spacing-scale, $key); margin-right: map-get($spacing-scale, $key);
147
+ }
148
+ }
149
+ @mixin my($key) { margin-top: map-get($spacing-scale, $key); margin-bottom: map-get($spacing-scale, $key); }
150
+ @mixin ml($key) { margin-left: map-get($spacing-scale, $key); }
151
+ @mixin mr($key) { margin-right: map-get($spacing-scale, $key); }
152
+ @mixin mt($key) { margin-top: map-get($spacing-scale, $key); }
153
+ @mixin mb($key) { margin-bottom: map-get($spacing-scale, $key); }
154
+
155
+ // ---------- Clases utilitarias de padding ----------
156
+
157
+ @each $key, $val in $spacing-scale {
158
+ .p-#{$key} { padding: $val; }
159
+ .px-#{$key} { padding-left: $val; padding-right: $val; }
160
+ .py-#{$key} { padding-top: $val; padding-bottom: $val; }
161
+ .pl-#{$key} { padding-left: $val; }
162
+ .pr-#{$key} { padding-right: $val; }
163
+ .pt-#{$key} { padding-top: $val; }
164
+ .pb-#{$key} { padding-bottom: $val; }
165
+ }
166
+
167
+ // ---------- Clases utilitarias de margin ----------
168
+
169
+ @each $key, $val in $spacing-scale {
170
+ .m-#{$key} { margin: $val; }
171
+ .mx-#{$key} { margin-left: $val; margin-right: $val; }
172
+ .my-#{$key} { margin-top: $val; margin-bottom: $val; }
173
+ .ml-#{$key} { margin-left: $val; }
174
+ .mr-#{$key} { margin-right: $val; }
175
+ .mt-#{$key} { margin-top: $val; }
176
+ .mb-#{$key} { margin-bottom: $val; }
177
+ }
178
+
179
+ // margin auto
180
+ .mx-auto { margin-left: auto; margin-right: auto; }
181
+ .ml-auto { margin-left: auto; }
182
+ .mr-auto { margin-right: auto; }
183
+
184
+
185
+ // -----------------------------------------------------------------------------
186
+ // 3. TIPOGRAFÍA
187
+ // -----------------------------------------------------------------------------
188
+
189
+ // Corta el texto en una línea con ellipsis
190
+ @mixin truncate {
191
+ white-space: nowrap;
192
+ overflow: hidden;
193
+ text-overflow: ellipsis;
194
+ }
195
+
196
+ // Limita a N líneas con ellipsis (webkit)
197
+ // @param $lines — número de líneas
198
+ @mixin truncate-lines($lines: 2) {
199
+ display: -webkit-box;
200
+ -webkit-line-clamp: $lines;
201
+ -webkit-box-orient: vertical;
202
+ overflow: hidden;
203
+ }
204
+
205
+ // Estilo de label uppercase — usado en role, sección, etc.
206
+ @mixin uppercase-label {
207
+ font-size: t.$fs-text-xs;
208
+ font-weight: t.$fs-font-medium;
209
+ letter-spacing: 0.08em;
210
+ text-transform: uppercase;
211
+ font-family: t.$fs-font-sans;
212
+ }
213
+
214
+ // Fuente monospace
215
+ @mixin font-mono {
216
+ font-family: t.$fs-font-mono;
217
+ font-size: t.$fs-text-sm;
218
+ }
219
+
220
+ // Estilo de texto configurable
221
+ // @param $size — font-size token (ej: t.$fs-text-sm)
222
+ // @param $weight — font-weight token (ej: t.$fs-font-medium)
223
+ // @param $color — color CSS (default: inherit)
224
+ @mixin text-style($size: t.$fs-text-base, $weight: t.$fs-font-regular, $color: inherit) {
225
+ font-size: $size;
226
+ font-weight: $weight;
227
+ color: $color;
228
+ font-family: t.$fs-font-sans;
229
+ }
230
+
231
+ // Clases utilitarias de tipografía
232
+ .truncate { @include truncate; }
233
+ .truncate-2 { @include truncate-lines(2); }
234
+ .truncate-3 { @include truncate-lines(3); }
235
+ .uppercase-label { @include uppercase-label; }
236
+ .font-mono { @include font-mono; }
237
+
238
+ // text-align
239
+ .text-left { text-align: left; }
240
+ .text-center { text-align: center; }
241
+ .text-right { text-align: right; }
242
+
243
+ // font-weight
244
+ .font-regular { font-weight: t.$fs-font-regular; }
245
+ .font-medium { font-weight: t.$fs-font-medium; }
246
+ .font-semi { font-weight: t.$fs-font-semi; }
247
+ .font-bold { font-weight: t.$fs-font-bold; }
248
+
249
+ // font-size
250
+ .text-xs { font-size: t.$fs-text-xs; }
251
+ .text-sm { font-size: t.$fs-text-sm; }
252
+ .text-base { font-size: t.$fs-text-base; }
253
+ .text-lg { font-size: t.$fs-text-lg; }
254
+ .text-xl { font-size: t.$fs-text-xl; }
255
+ .text-2xl { font-size: t.$fs-text-2xl; }
256
+ .text-3xl { font-size: t.$fs-text-3xl; }
257
+
258
+
259
+ // -----------------------------------------------------------------------------
260
+ // 4. RESPONSIVE — breakpoints
261
+ // -----------------------------------------------------------------------------
262
+
263
+ $breakpoints: (
264
+ 'sm': 640px,
265
+ 'md': 768px,
266
+ 'lg': 1024px,
267
+ 'xl': 1280px,
268
+ '2xl': 1536px,
269
+ );
270
+
271
+ // respond-to — media query min-width
272
+ // @param $bp — nombre del breakpoint: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
273
+ // Ejemplo:
274
+ // .mi-componente {
275
+ // font-size: t.$fs-text-sm;
276
+ // @include respond-to('md') { font-size: t.$fs-text-base; }
277
+ // }
278
+ @mixin respond-to($bp) {
279
+ $val: map-get($breakpoints, $bp);
280
+ @if $val {
281
+ @media (min-width: $val) { @content; }
282
+ } @else {
283
+ @warn "respond-to(): breakpoint '#{$bp}' no existe. Usá: sm, md, lg, xl, 2xl";
284
+ }
285
+ }
286
+
287
+ // mobile-only — se aplica solo en pantallas menores a sm
288
+ @mixin mobile-only {
289
+ @media (max-width: #{map-get($breakpoints, 'sm') - 1px}) { @content; }
290
+ }
291
+
292
+ // container — ancho máximo centrado con padding lateral
293
+ @mixin container($max: 1200px) {
294
+ width: 100%;
295
+ max-width: $max;
296
+ margin-left: auto;
297
+ margin-right: auto;
298
+ padding-left: t.$fs-space-4;
299
+ padding-right: t.$fs-space-4;
300
+
301
+ @include respond-to('md') {
302
+ padding-left: t.$fs-space-6;
303
+ padding-right: t.$fs-space-6;
304
+ }
305
+ }
306
+
307
+ // Clases utilitarias responsive
308
+ .container { @include container; }
309
+
310
+ // display responsive
311
+ @each $bp, $val in $breakpoints {
312
+ @media (min-width: $val) {
313
+ .#{$bp}\:flex { display: flex; }
314
+ .#{$bp}\:flex-col { display: flex; flex-direction: column; }
315
+ .#{$bp}\:hidden { display: none; }
316
+ .#{$bp}\:block { display: block; }
317
+ .#{$bp}\:flex-center { @include flex-center; }
318
+ }
319
+ }
320
+
321
+
322
+ // -----------------------------------------------------------------------------
323
+ // 5. VISUAL / UI
324
+ // -----------------------------------------------------------------------------
325
+
326
+ // Focus ring accesible — ya definido en tokens, se re-exporta acá
327
+ // @param $color — color del ring (default: primary)
328
+ // @param $offset — separación del elemento (default: 2px)
329
+ @mixin focus-ring($color: var(--fs-primary-base), $offset: 2px) {
330
+ outline: none;
331
+ box-shadow: 0 0 0 $offset var(--fs-profile-avatar-border, #0d1117),
332
+ 0 0 0 ($offset + 2px) $color;
333
+ }
334
+
335
+ // Card con fondo navy y borde sutil — base de todos los componentes
336
+ @mixin card-surface($radius: t.$fs-radius-xl) {
337
+ background: #0d1117;
338
+ border: 0.5px solid rgba(255, 255, 255, 0.08);
339
+ border-radius: $radius;
340
+ transition: border-color t.$fs-duration-fast t.$fs-ease-default;
341
+
342
+ &:hover {
343
+ border-color: rgba(255, 255, 255, 0.14);
344
+ }
345
+ }
346
+
347
+ // Glass — fondo translúcido con blur
348
+ // @param $opacity — opacidad del fondo (default: 0.05)
349
+ @mixin glass($opacity: 0.05) {
350
+ background: rgba(255, 255, 255, $opacity);
351
+ backdrop-filter: blur(8px);
352
+ -webkit-backdrop-filter: blur(8px);
353
+ border: 0.5px solid rgba(255, 255, 255, 0.1);
354
+ }
355
+
356
+ // Visually hidden — oculto visualmente pero accesible para screen readers
357
+ @mixin visually-hidden {
358
+ position: absolute;
359
+ width: 1px;
360
+ height: 1px;
361
+ padding: 0;
362
+ margin: -1px;
363
+ overflow: hidden;
364
+ clip: rect(0, 0, 0, 0);
365
+ white-space: nowrap;
366
+ border: 0;
367
+ }
368
+
369
+ // Reset button — quita todos los estilos nativos del navegador
370
+ @mixin reset-button {
371
+ appearance: none;
372
+ background: none;
373
+ border: none;
374
+ padding: 0;
375
+ margin: 0;
376
+ cursor: pointer;
377
+ font-family: inherit;
378
+ font-size: inherit;
379
+ color: inherit;
380
+ line-height: inherit;
381
+ }
382
+
383
+ // Reset list — quita estilos de ul/ol
384
+ @mixin reset-list {
385
+ list-style: none;
386
+ padding: 0;
387
+ margin: 0;
388
+ }
389
+
390
+ // Divider — línea separadora horizontal
391
+ // @param $color — color del borde (default: sutil)
392
+ @mixin divider($color: rgba(255, 255, 255, 0.06)) {
393
+ height: 0.5px;
394
+ background: $color;
395
+ border: none;
396
+ margin: 0;
397
+ }
398
+
399
+ // Clases utilitarias visuales
400
+ .visually-hidden { @include visually-hidden; }
401
+ .card-surface { @include card-surface; }
402
+ .glass { @include glass; }
403
+ .divider { @include divider; }
404
+ .reset-list { @include reset-list; }
405
+
406
+ // display
407
+ .hidden { display: none; }
408
+ .block { display: block; }
409
+ .inline { display: inline; }
410
+ .inline-block { display: inline-block; }
411
+
412
+ // overflow
413
+ .overflow-hidden { overflow: hidden; }
414
+ .overflow-auto { overflow: auto; }
415
+
416
+ // position
417
+ .relative { position: relative; }
418
+ .absolute { position: absolute; }
419
+ .sticky { position: sticky; }
420
+
421
+ // width / height comunes
422
+ .w-full { width: 100%; }
423
+ .h-full { height: 100%; }
424
+ .w-auto { width: auto; }
425
+ .min-w-0 { min-width: 0; }
426
+
427
+ // border-radius
428
+ .rounded-sm { border-radius: t.$fs-radius-sm; }
429
+ .rounded-md { border-radius: t.$fs-radius-md; }
430
+ .rounded-lg { border-radius: t.$fs-radius-lg; }
431
+ .rounded-xl { border-radius: t.$fs-radius-xl; }
432
+ .rounded-2xl { border-radius: t.$fs-radius-2xl; }
433
+ .rounded-full { border-radius: t.$fs-radius-full; }
434
+
435
+
436
+ // -----------------------------------------------------------------------------
437
+ // 6. BADGE / COLOR HELPERS
438
+ // -----------------------------------------------------------------------------
439
+
440
+ // Genera el estilo filled de un badge a partir de un color base
441
+ // @param $base — color del texto y del dot
442
+ // @param $bg — fondo sutil
443
+ // @param $border — borde sutil
444
+ @mixin badge-variant($base, $bg, $border) {
445
+ background: $bg;
446
+ color: $base;
447
+ border-color: $border;
448
+ }
449
+
450
+ // Genera el estilo outline de un badge
451
+ // @param $base — color del borde y del texto
452
+ @mixin badge-outline($base) {
453
+ background: transparent;
454
+ color: $base;
455
+ border-color: $base;
456
+ }
457
+
458
+ // Dot indicador de estado
459
+ // @param $color — color del punto
460
+ // @param $size — tamaño (default: 6px)
461
+ @mixin dot-indicator($color, $size: 6px) {
462
+ width: $size;
463
+ height: $size;
464
+ border-radius: t.$fs-radius-full;
465
+ background: $color;
466
+ flex-shrink: 0;
467
+ }
468
+
469
+ // Degradé indicator — el mismo que usan los tabs de fsociety
470
+ @mixin gradient-indicator($from: var(--fs-primary-base), $to: var(--fs-tertiary-base)) {
471
+ background: linear-gradient(90deg, $from 0%, $to 100%);
472
+ box-shadow: 0 0 10px rgba(34, 211, 238, 0.45);
473
+ }