@oleksandr-94/aura-css 0.1.0

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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +593 -0
  3. package/dist/aura-flat.css +1611 -0
  4. package/dist/aura-flat.min.css +1 -0
  5. package/dist/aura-neu.css +1622 -0
  6. package/dist/aura-neu.min.css +1 -0
  7. package/dist/aura.css +1634 -0
  8. package/dist/aura.min.css +1 -0
  9. package/dist/interactions.d.ts +57 -0
  10. package/dist/interactions.global.min.js +1 -0
  11. package/dist/interactions.min.mjs +1 -0
  12. package/dist/interactions.mjs +208 -0
  13. package/package.json +72 -0
  14. package/src/_config.scss +72 -0
  15. package/src/_functions.scss +23 -0
  16. package/src/_layers.scss +4 -0
  17. package/src/_surface.scss +49 -0
  18. package/src/_tokens.scss +65 -0
  19. package/src/base/_a11y.scss +31 -0
  20. package/src/base/_reset.scss +7 -0
  21. package/src/components/_accordion.scss +62 -0
  22. package/src/components/_alert.scss +43 -0
  23. package/src/components/_avatar.scss +50 -0
  24. package/src/components/_badge.scss +61 -0
  25. package/src/components/_button.scss +79 -0
  26. package/src/components/_card.scss +58 -0
  27. package/src/components/_checkbox.scss +51 -0
  28. package/src/components/_dropdown.scss +73 -0
  29. package/src/components/_file.scss +42 -0
  30. package/src/components/_group.scss +51 -0
  31. package/src/components/_input.scss +85 -0
  32. package/src/components/_modal.scss +43 -0
  33. package/src/components/_pagination.scss +87 -0
  34. package/src/components/_progress.scss +44 -0
  35. package/src/components/_radio.scss +42 -0
  36. package/src/components/_range.scss +27 -0
  37. package/src/components/_rating.scss +43 -0
  38. package/src/components/_segmented.scss +60 -0
  39. package/src/components/_switch.scss +79 -0
  40. package/src/components/_table.scss +38 -0
  41. package/src/components/_tabs.scss +150 -0
  42. package/src/components/_toast.scss +59 -0
  43. package/src/components/_tooltip.scss +60 -0
  44. package/src/index.scss +32 -0
  45. package/src/js/global.js +7 -0
  46. package/src/js/interactions.auto.js +5 -0
  47. package/src/js/interactions.js +192 -0
  48. package/src/skins/_flat.scss +29 -0
  49. package/src/skins/_glass.scss +40 -0
  50. package/src/skins/_neu.scss +49 -0
@@ -0,0 +1,85 @@
1
+ // ============================================================
2
+ // Aura — Input / Select / Textarea (+ field wrapper)
3
+ // Controls render their "well" through the field() mixin, so they
4
+ // pick up the active skin (glass / flat / neu) automatically.
5
+ // ============================================================
6
+ @use "../config" as cfg;
7
+ @use "../surface" as s;
8
+ $p: cfg.$prefix;
9
+
10
+ @layer components {
11
+ // ---- labelled wrapper ----
12
+ .#{$p}field {
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: var(--space-2);
16
+ }
17
+ .#{$p}field__label {
18
+ font-size: var(--fs-xs);
19
+ font-weight: 600;
20
+ color: var(--on-surface);
21
+ }
22
+ .#{$p}field__label--required::after { content: " *"; color: var(--error); }
23
+ .#{$p}field__hint {
24
+ font-size: var(--fs-xs);
25
+ color: var(--on-surface-muted);
26
+ }
27
+ .#{$p}field__hint--error { color: var(--error); }
28
+ .#{$p}field__hint--success { color: var(--success); }
29
+
30
+ // ---- controls ----
31
+ .#{$p}input,
32
+ .#{$p}select,
33
+ .#{$p}textarea {
34
+ @include s.field;
35
+ font: inherit;
36
+ font-size: var(--fs-md);
37
+ color: var(--on-surface);
38
+ width: 100%;
39
+ padding: 10px 14px;
40
+ border-radius: var(--radius-md);
41
+ transition: border-color .15s ease;
42
+
43
+ &::placeholder { color: var(--on-surface-muted); }
44
+ &:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
45
+ &:disabled { opacity: .5; cursor: not-allowed; }
46
+ }
47
+
48
+ .#{$p}textarea {
49
+ min-height: 84px;
50
+ resize: vertical;
51
+ }
52
+
53
+ // native select: custom chevron, no OS arrow
54
+ .#{$p}select {
55
+ appearance: none;
56
+ -webkit-appearance: none;
57
+ padding-inline-end: 34px;
58
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5l3.5 3.5 3.5-3.5' fill='none' stroke='%238b93a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
59
+ background-repeat: no-repeat;
60
+ background-position: right 12px center;
61
+ }
62
+
63
+ // ---- validation states ----
64
+ .#{$p}input--error,
65
+ .#{$p}select--error,
66
+ .#{$p}textarea--error {
67
+ border-color: var(--error);
68
+ &:focus-visible { outline-color: var(--error); }
69
+ }
70
+ .#{$p}input--success,
71
+ .#{$p}select--success,
72
+ .#{$p}textarea--success {
73
+ border-color: var(--success);
74
+ &:focus-visible { outline-color: var(--success); }
75
+ }
76
+
77
+ // ---- sizes (input / select / textarea) ----
78
+ .#{$p}input--sm, .#{$p}select--sm, .#{$p}textarea--sm {
79
+ padding-block: 7px; padding-inline: 11px; font-size: var(--fs-sm); border-radius: var(--radius-sm);
80
+ }
81
+ .#{$p}input--lg, .#{$p}select--lg, .#{$p}textarea--lg {
82
+ padding-block: 13px; padding-inline: 16px; font-size: var(--fs-lg);
83
+ }
84
+ .#{$p}select--sm, .#{$p}select--lg { padding-inline-end: 34px; } // keep room for the chevron
85
+ }
@@ -0,0 +1,43 @@
1
+ // ============================================================
2
+ // Aura — Modal
3
+ // Driven by [data-state] on the overlay (mark it data-overlay so the
4
+ // JS applies scroll-lock + focus-trap + backdrop-close). The dialog
5
+ // is a solid surface for readability (not translucent).
6
+ // ============================================================
7
+ @use "../config" as cfg;
8
+ $p: cfg.$prefix;
9
+
10
+ @layer components {
11
+ .#{$p}modal-overlay {
12
+ position: fixed;
13
+ inset: 0;
14
+ z-index: var(--z-modal);
15
+ display: grid;
16
+ place-items: center;
17
+ padding: 20px;
18
+ background: rgba(4, 10, 20, .5);
19
+ -webkit-backdrop-filter: blur(4px);
20
+ backdrop-filter: blur(4px);
21
+ opacity: 0;
22
+ visibility: hidden;
23
+ transition: opacity .2s ease, visibility .2s ease;
24
+ }
25
+ .#{$p}modal-overlay[data-state="open"] { opacity: 1; visibility: visible; }
26
+
27
+ .#{$p}modal {
28
+ width: 100%;
29
+ max-width: 440px;
30
+ padding: 24px;
31
+ border-radius: var(--radius-lg);
32
+ background: var(--surface-1);
33
+ border: 1px solid var(--outline);
34
+ box-shadow: var(--shadow-2);
35
+ transform: translateY(10px) scale(.98);
36
+ transition: transform .2s ease;
37
+ }
38
+ .#{$p}modal-overlay[data-state="open"] .#{$p}modal { transform: none; }
39
+
40
+ .#{$p}modal__title { margin: 0 0 8px; font-size: var(--fs-xl); font-weight: 800; }
41
+ .#{$p}modal__body { margin: 0 0 20px; color: var(--on-surface-muted); font-size: var(--fs-md); line-height: 1.5; }
42
+ .#{$p}modal__actions { display: flex; gap: 10px; justify-content: flex-end; }
43
+ }
@@ -0,0 +1,87 @@
1
+ // ============================================================
2
+ // Aura — Pagination
3
+ // ============================================================
4
+ @use "../config" as cfg;
5
+ @use "../surface" as s;
6
+ $p: cfg.$prefix;
7
+
8
+ @layer components {
9
+ .#{$p}pagination {
10
+ display: inline-flex;
11
+ gap: 4px;
12
+ }
13
+
14
+ .#{$p}pagination__item {
15
+ min-width: 36px;
16
+ height: 36px;
17
+ padding: 0 8px;
18
+ display: inline-flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ border-radius: var(--radius-md);
22
+ border: 1px solid var(--outline);
23
+ background: var(--surface-1);
24
+ color: var(--on-surface);
25
+ font: inherit;
26
+ font-size: var(--fs-sm);
27
+ font-weight: 600;
28
+ text-decoration: none;
29
+ cursor: pointer;
30
+
31
+ &:hover:not(.#{$p}pagination__item--active):not(:disabled):not(.#{$p}pagination__item--disabled) {
32
+ background: color-mix(in srgb, var(--on-surface) 8%, transparent);
33
+ }
34
+ &:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
35
+ &:disabled,
36
+ &.#{$p}pagination__item--disabled { opacity: .5; cursor: not-allowed; }
37
+ }
38
+
39
+ .#{$p}pagination__item--active {
40
+ --_bg: var(--primary);
41
+ --_fg: var(--on-primary);
42
+ @include s.control;
43
+ border-color: transparent;
44
+ }
45
+
46
+ // ---- joined (button-group) style ----
47
+ .#{$p}pagination--joined {
48
+ gap: 0;
49
+
50
+ .#{$p}pagination__item {
51
+ position: relative;
52
+ border-radius: 0;
53
+ }
54
+ .#{$p}pagination__item:not(:first-child) { margin-inline-start: -1px; }
55
+ .#{$p}pagination__item:hover:not(:disabled):not(.#{$p}pagination__item--disabled),
56
+ .#{$p}pagination__item:focus-visible,
57
+ .#{$p}pagination__item--active { z-index: 1; }
58
+ .#{$p}pagination__item:first-child {
59
+ border-start-start-radius: var(--radius-md);
60
+ border-end-start-radius: var(--radius-md);
61
+ }
62
+ .#{$p}pagination__item:last-child {
63
+ border-start-end-radius: var(--radius-md);
64
+ border-end-end-radius: var(--radius-md);
65
+ }
66
+ }
67
+
68
+ // ---- small ----
69
+ .#{$p}pagination--sm .#{$p}pagination__item {
70
+ min-width: 30px;
71
+ height: 30px;
72
+ font-size: var(--fs-xs);
73
+ }
74
+
75
+ // ---- ellipsis (non-interactive gap marker) ----
76
+ .#{$p}pagination__ellipsis {
77
+ min-width: 24px;
78
+ height: 36px;
79
+ display: inline-flex;
80
+ align-items: flex-end;
81
+ justify-content: center;
82
+ padding-bottom: 6px;
83
+ color: var(--on-surface-muted);
84
+ user-select: none;
85
+ }
86
+ .#{$p}pagination--sm .#{$p}pagination__ellipsis { height: 30px; }
87
+ }
@@ -0,0 +1,44 @@
1
+ // ============================================================
2
+ // Aura — Progress (bar + spinner)
3
+ // Track is a skin-aware well; the fill uses the accent colour.
4
+ // ============================================================
5
+ @use "../config" as cfg;
6
+ @use "../surface" as s;
7
+ $p: cfg.$prefix;
8
+
9
+ @layer components {
10
+ .#{$p}progress {
11
+ --_c: var(--primary);
12
+ display: block;
13
+ width: 100%;
14
+ height: 8px;
15
+ border-radius: var(--radius-pill);
16
+ overflow: hidden;
17
+ @include s.field;
18
+ }
19
+ .#{$p}progress__bar {
20
+ display: block;
21
+ height: 100%;
22
+ border-radius: inherit;
23
+ background: var(--_c);
24
+ transition: width .3s ease;
25
+ }
26
+ .#{$p}progress--success { --_c: var(--success); }
27
+ .#{$p}progress--warning { --_c: var(--warning); }
28
+ .#{$p}progress--error { --_c: var(--error); }
29
+
30
+ // ---- spinner ----
31
+ .#{$p}spinner {
32
+ display: inline-block;
33
+ width: 28px;
34
+ height: 28px;
35
+ border: 3px solid var(--outline-strong);
36
+ border-top-color: var(--primary);
37
+ border-radius: 50%;
38
+ animation: #{$p}spin .8s linear infinite;
39
+ }
40
+ .#{$p}spinner--sm { width: 18px; height: 18px; border-width: 2px; }
41
+ .#{$p}spinner--lg { width: 40px; height: 40px; border-width: 4px; }
42
+
43
+ @keyframes #{$p}spin { to { transform: rotate(360deg); } }
44
+ }
@@ -0,0 +1,42 @@
1
+ // ============================================================
2
+ // Aura — Radio
3
+ // Custom control (appearance:none). Circle is a skin-aware well via
4
+ // field(); checked fills with --_c + white centre dot.
5
+ // ============================================================
6
+ @use "../config" as cfg;
7
+ @use "../surface" as s;
8
+ $p: cfg.$prefix;
9
+
10
+ @layer components {
11
+ .#{$p}radio {
12
+ --_c: var(--primary);
13
+ appearance: none;
14
+ -webkit-appearance: none;
15
+ margin: 0;
16
+ flex: none;
17
+ width: 18px;
18
+ height: 18px;
19
+ border-radius: 50%;
20
+ cursor: pointer;
21
+ position: relative;
22
+ vertical-align: middle;
23
+ transition: background .15s ease, border-color .15s ease;
24
+ @include s.field;
25
+
26
+ &:checked { --_bg: var(--_c); --_fg: #fff; @include s.control; }
27
+ &:checked::after {
28
+ content: "";
29
+ position: absolute;
30
+ inset: 4px;
31
+ border-radius: 50%;
32
+ background: #fff;
33
+ }
34
+
35
+ &:focus-visible { outline: 2px solid var(--_c); outline-offset: 2px; }
36
+ &:disabled { opacity: .5; cursor: not-allowed; }
37
+
38
+ &.#{$p}radio--success { --_c: var(--success); }
39
+ &.#{$p}radio--warning { --_c: var(--warning); }
40
+ &.#{$p}radio--error { --_c: var(--error); }
41
+ }
42
+ }
@@ -0,0 +1,27 @@
1
+ // ============================================================
2
+ // Aura — Range / slider
3
+ // Native <input type="range"> themed via accent-color: auto-fills,
4
+ // keyboard-accessible, zero JS. Colour follows --_c.
5
+ // ============================================================
6
+ @use "../config" as cfg;
7
+ $p: cfg.$prefix;
8
+
9
+ @layer components {
10
+ .#{$p}range {
11
+ --_c: var(--primary);
12
+ width: 100%;
13
+ height: 22px;
14
+ accent-color: var(--_c);
15
+ cursor: pointer;
16
+
17
+ &:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
18
+ &:disabled { opacity: .5; cursor: not-allowed; }
19
+
20
+ &.#{$p}range--success { --_c: var(--success); }
21
+ &.#{$p}range--warning { --_c: var(--warning); }
22
+ &.#{$p}range--error { --_c: var(--error); }
23
+
24
+ &.#{$p}range--sm { height: 16px; }
25
+ &.#{$p}range--lg { height: 28px; }
26
+ }
27
+ }
@@ -0,0 +1,43 @@
1
+ // ============================================================
2
+ // Aura — Rating (radio-powered stars)
3
+ // CSS-only, keyboard-accessible (arrow keys), form-submittable.
4
+ // Uses row-reverse so `:checked ~ label` fills the star and all
5
+ // lower ones. Hover previews.
6
+ // ============================================================
7
+ @use "../config" as cfg;
8
+ $p: cfg.$prefix;
9
+
10
+ @layer components {
11
+ .#{$p}rating {
12
+ --_c: var(--warning);
13
+ display: inline-flex;
14
+ flex-direction: row-reverse;
15
+ justify-content: flex-end;
16
+ gap: 2px;
17
+
18
+ input {
19
+ position: absolute;
20
+ width: 1px;
21
+ height: 1px;
22
+ opacity: 0;
23
+ margin: 0;
24
+ }
25
+ label {
26
+ font-size: 24px;
27
+ line-height: 1;
28
+ color: var(--outline-strong);
29
+ cursor: pointer;
30
+ transition: color .12s ease, transform .12s ease;
31
+ }
32
+ label:hover { transform: scale(1.1); }
33
+
34
+ // fill the checked star + every lower one (they follow in the reversed DOM)
35
+ input:checked ~ label,
36
+ label:hover,
37
+ label:hover ~ label { color: var(--_c); }
38
+
39
+ input:focus-visible + label { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }
40
+ &.#{$p}rating--sm label { font-size: 18px; }
41
+ &.#{$p}rating--lg label { font-size: 32px; }
42
+ }
43
+ }
@@ -0,0 +1,60 @@
1
+ // ============================================================
2
+ // Aura — Segmented control (radio-powered)
3
+ // A single-select group built on native radios: CSS-only, keyboard
4
+ // accessible (arrow keys) and form-submittable. The checked option
5
+ // becomes a skin-aware filled pill via control().
6
+ // ============================================================
7
+ @use "../config" as cfg;
8
+ @use "../surface" as s;
9
+ $p: cfg.$prefix;
10
+
11
+ @layer components {
12
+ .#{$p}segmented {
13
+ display: inline-flex;
14
+ gap: 4px;
15
+ padding: 4px;
16
+ border-radius: var(--radius-md);
17
+ @include s.field; // recessed well (like tabs)
18
+ }
19
+ .#{$p}segmented--block { display: flex; width: 100%; }
20
+ .#{$p}segmented--block .#{$p}segmented__option { flex: 1; }
21
+
22
+ .#{$p}segmented__option {
23
+ position: relative;
24
+ display: inline-flex;
25
+ flex: none;
26
+
27
+ input {
28
+ position: absolute;
29
+ inset: 0;
30
+ width: 100%;
31
+ margin: 0;
32
+ opacity: 0;
33
+ cursor: pointer;
34
+ }
35
+ span {
36
+ flex: 1;
37
+ text-align: center;
38
+ padding: 8px 14px;
39
+ border-radius: var(--radius-sm);
40
+ font-weight: 700;
41
+ font-size: var(--fs-sm);
42
+ color: var(--on-surface-muted);
43
+ white-space: nowrap;
44
+ user-select: none;
45
+ transition: color .15s ease;
46
+ }
47
+
48
+ input:checked + span {
49
+ --_c: var(--primary);
50
+ --_bg: var(--_c);
51
+ --_fg: var(--on-primary);
52
+ @include s.control; // active pill — glass glow / flat / neu
53
+ color: var(--_fg);
54
+ }
55
+ input:focus-visible + span {
56
+ outline: 2px solid var(--primary);
57
+ outline-offset: 2px;
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,79 @@
1
+ // ============================================================
2
+ // Aura — Switch (toggle)
3
+ // The track is a control well via field() (skin-aware); when
4
+ // checked it fills with the accent colour (--_c). White thumb on
5
+ // the coloured track — never colour-on-colour.
6
+ // ============================================================
7
+ @use "../config" as cfg;
8
+ @use "../surface" as s;
9
+ $p: cfg.$prefix;
10
+
11
+ @layer components {
12
+ .#{$p}switch {
13
+ --_c: var(--primary);
14
+ position: relative;
15
+ display: inline-flex;
16
+ flex: none;
17
+ width: 46px;
18
+ height: 26px;
19
+ vertical-align: middle;
20
+ cursor: pointer;
21
+ }
22
+
23
+ .#{$p}switch input {
24
+ position: absolute;
25
+ inset: 0;
26
+ opacity: 0;
27
+ margin: 0;
28
+ cursor: pointer;
29
+ }
30
+
31
+ .#{$p}switch__track {
32
+ position: absolute;
33
+ inset: 0;
34
+ border-radius: var(--radius-pill);
35
+ transition: background .2s ease, border-color .2s ease, box-shadow .2s ease;
36
+ @include s.field;
37
+ }
38
+
39
+ .#{$p}switch__thumb {
40
+ position: absolute;
41
+ top: 4px;
42
+ left: 4px;
43
+ width: 18px;
44
+ height: 18px;
45
+ border-radius: 50%;
46
+ background: var(--on-surface-muted);
47
+ transition: transform .2s ease, background .2s ease;
48
+ }
49
+
50
+ .#{$p}switch input:checked ~ .#{$p}switch__track {
51
+ --_bg: var(--_c);
52
+ --_fg: #fff;
53
+ @include s.control;
54
+ }
55
+ .#{$p}switch input:checked ~ .#{$p}switch__thumb {
56
+ transform: translateX(20px);
57
+ background: #fff;
58
+ }
59
+ .#{$p}switch input:focus-visible ~ .#{$p}switch__track {
60
+ outline: 2px solid var(--_c);
61
+ outline-offset: 2px;
62
+ }
63
+ .#{$p}switch input:disabled ~ .#{$p}switch__track,
64
+ .#{$p}switch input:disabled ~ .#{$p}switch__thumb { opacity: .5; }
65
+
66
+ // ---- colours ----
67
+ .#{$p}switch--success { --_c: var(--success); }
68
+ .#{$p}switch--warning { --_c: var(--warning); }
69
+ .#{$p}switch--error { --_c: var(--error); }
70
+
71
+ // ---- sizes ----
72
+ .#{$p}switch--sm { width: 38px; height: 22px; }
73
+ .#{$p}switch--sm .#{$p}switch__thumb { width: 14px; height: 14px; }
74
+ .#{$p}switch--sm input:checked ~ .#{$p}switch__thumb { transform: translateX(16px); }
75
+
76
+ .#{$p}switch--lg { width: 56px; height: 32px; }
77
+ .#{$p}switch--lg .#{$p}switch__thumb { width: 24px; height: 24px; }
78
+ .#{$p}switch--lg input:checked ~ .#{$p}switch__thumb { transform: translateX(24px); }
79
+ }
@@ -0,0 +1,38 @@
1
+ // ============================================================
2
+ // Aura — Table
3
+ // Transparent by design — place inside a .card for a surface.
4
+ // Uses outline tokens for rules; skin-independent.
5
+ // ============================================================
6
+ @use "../config" as cfg;
7
+ $p: cfg.$prefix;
8
+
9
+ @layer components {
10
+ .#{$p}table {
11
+ width: 100%;
12
+ border-collapse: collapse;
13
+ font-size: var(--fs-md);
14
+ color: var(--on-surface);
15
+
16
+ th, td {
17
+ text-align: left;
18
+ padding: 11px 14px;
19
+ border-bottom: 1px solid var(--outline);
20
+ }
21
+ th {
22
+ font-size: var(--fs-xs);
23
+ text-transform: uppercase;
24
+ letter-spacing: .05em;
25
+ font-weight: 700;
26
+ color: var(--on-surface-muted);
27
+ }
28
+ tbody tr:last-child td { border-bottom: none; }
29
+ tbody tr:hover { background: color-mix(in srgb, var(--on-surface) 5%, transparent); }
30
+ }
31
+
32
+ // ---- variants ----
33
+ .#{$p}table--zebra tbody tr:nth-child(even) {
34
+ background: color-mix(in srgb, var(--on-surface) 4%, transparent);
35
+ }
36
+ .#{$p}table--compact th,
37
+ .#{$p}table--compact td { padding: 7px 10px; }
38
+ }