@eagami/ui 2.2.0 → 2.4.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagami/ui",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Lightweight, accessible Angular UI component library built on CSS custom properties",
5
5
  "author": "Michal Wiraszka <michal@eagami.com>",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@ body {
22
22
  font-size: var(--font-size-md);
23
23
  line-height: var(--line-height-normal);
24
24
  color: var(--color-text-primary);
25
- background-color: var(--color-bg-base);
25
+ background-color: var(--color-bg-canvas);
26
26
  -webkit-font-smoothing: antialiased;
27
27
  -moz-osx-font-smoothing: grayscale;
28
28
  }
@@ -85,27 +85,47 @@
85
85
  --color-text-primary: var(--color-neutral-900);
86
86
  --color-text-secondary: var(--color-neutral-600);
87
87
  --color-text-tertiary: var(--color-neutral-400);
88
- --color-text-disabled: var(--color-neutral-300);
88
+ --color-text-disabled: var(--color-neutral-400);
89
89
  --color-text-inverse: var(--color-neutral-0);
90
90
  --color-text-link: var(--color-primary-600);
91
91
  --color-text-link-hover: var(--color-primary-800);
92
92
 
93
- // Background
93
+ // Two-tier surface model: `bg-canvas` is the page itself; `bg-base` is the
94
+ // surface of components on the page (inputs, cards, accordion items,
95
+ // popover panels). In dark mode bg-base lifts above bg-canvas so component
96
+ // surfaces don't disappear into the page.
97
+ --color-bg-canvas: var(--color-neutral-0);
94
98
  --color-bg-base: var(--color-neutral-0);
95
99
  --color-bg-subtle: var(--color-neutral-50);
100
+ --color-bg-stripe: var(--color-neutral-50);
96
101
  --color-bg-muted: var(--color-neutral-100);
97
102
  --color-bg-elevated: var(--color-neutral-0);
98
103
  --color-bg-overlay: rgba(0, 0, 0, 0.5);
99
104
 
100
- // Border
105
+ // Border. `subtle` is for low-contrast dividers (table rows, cell grids)
106
+ // where a full `default` border would feel heavy. `default` is the everyday
107
+ // form-component outline; `strong` is for prominent outlines (secondary
108
+ // buttons, etc.); `focus` is the keyboard-focus ring.
109
+ --color-border-subtle: var(--color-neutral-200);
101
110
  --color-border-default: var(--color-neutral-200);
102
111
  --color-border-strong: var(--color-neutral-400);
103
112
  --color-border-focus: var(--color-primary-500);
104
113
 
105
- // Brand semantic
114
+ // Brand semantic.
115
+ //
116
+ // Two roles split intentionally:
117
+ // - `--color-brand-default` (and `-hover` / `-active`) is the brand colour
118
+ // used as a **surface** — solid background under white text (primary
119
+ // button, badge bg). Needs ≥ 4.5:1 vs white text.
120
+ // - `--color-brand-text` is the brand colour used as a **foreground** on a
121
+ // non-brand surface (selected dropdown row, today marker, sorted column
122
+ // header, link, spinner). Needs ≥ 4.5:1 vs `--color-bg-base`. In dark
123
+ // mode the foreground role flips to a lighter shade so contrast against
124
+ // the dark surface still holds.
106
125
  --color-brand-default: var(--color-primary-600);
107
126
  --color-brand-hover: var(--color-primary-700);
108
127
  --color-brand-active: var(--color-primary-800);
128
+ --color-brand-text: var(--color-primary-700);
109
129
  --color-brand-subtle: var(--color-primary-50);
110
130
  --color-brand-muted: var(--color-primary-100);
111
131
 
@@ -154,29 +174,45 @@
154
174
  // ---------------------------------------------------------------------------
155
175
  @mixin dark-color-tokens {
156
176
  --color-text-primary: var(--color-neutral-50);
157
- --color-text-secondary: var(--color-neutral-400);
177
+ --color-text-secondary: var(--color-neutral-300);
158
178
  --color-text-tertiary: var(--color-neutral-500);
159
- --color-text-disabled: var(--color-neutral-700);
179
+ --color-text-disabled: var(--color-neutral-500);
160
180
  --color-text-inverse: var(--color-neutral-900);
161
181
  --color-text-link: var(--color-primary-300);
162
182
  --color-text-link-hover: var(--color-primary-100);
163
183
 
164
- // Dark-mode background hierarchy steps from darkest (page) to lightest (hover),
165
- // since elevation in dark mode is conveyed by surface lightness rather than shadow:
166
- // bg-base (950) bg-subtle (900) bg-elevated (800) bg-muted (700)
167
- // bg-muted sits *above* bg-elevated so hover states inside elevated surfaces
168
- // (dropdowns on a card, menu items in a drawer) still read as a step up.
169
- --color-bg-base: var(--color-neutral-950);
170
- --color-bg-subtle: var(--color-neutral-900);
171
- --color-bg-elevated: var(--color-neutral-800);
172
- --color-bg-muted: var(--color-neutral-700);
173
-
174
- --color-border-default: var(--color-neutral-700);
175
- --color-border-strong: var(--color-neutral-500);
176
-
177
- --color-brand-default: var(--color-primary-400);
178
- --color-brand-hover: var(--color-primary-300);
179
- --color-brand-active: var(--color-primary-200);
184
+ // Dark-mode surface hierarchy. Canvas is the page itself (deepest).
185
+ // bg-base lifts above it so component surfaces (inputs, cards, accordion
186
+ // items, popover panels) read above the page instead of disappearing into
187
+ // it. Subtle / elevated / muted continue the lift for striped rows, floating
188
+ // surfaces, and hover states.
189
+ --color-bg-canvas: var(--color-neutral-950);
190
+ --color-bg-base: var(--color-neutral-800);
191
+ --color-bg-subtle: var(--color-neutral-700);
192
+ --color-bg-stripe: var(--color-neutral-900);
193
+ --color-bg-elevated: var(--color-neutral-700);
194
+ --color-bg-muted: var(--color-neutral-600);
195
+
196
+ // Borders sit clear of every bg-* shade so they stay visible on any surface.
197
+ // `subtle` mixes between neutral-700 and -800 so it's distinct from the
198
+ // card surface (neutral-700) while staying close to cell bgs (-800/-900).
199
+ // `default` is the form-component outline; anything darker collides with
200
+ // bg-subtle / bg-elevated (both neutral-700) and disappears.
201
+ --color-border-subtle: color-mix(
202
+ in srgb,
203
+ var(--color-neutral-700),
204
+ var(--color-neutral-800)
205
+ );
206
+ --color-border-default: var(--color-neutral-400);
207
+ --color-border-strong: var(--color-neutral-300);
208
+
209
+ // Brand surface roles step one shade lighter than light mode so the button
210
+ // clears WCAG 1.4.11 (3:1) against the near-black canvas while still
211
+ // carrying its white label above 4.5:1.
212
+ --color-brand-default: var(--color-primary-500);
213
+ --color-brand-hover: var(--color-primary-600);
214
+ --color-brand-active: var(--color-primary-700);
215
+ --color-brand-text: var(--color-primary-300);
180
216
  --color-brand-subtle: rgba(75, 145, 195, 0.1);
181
217
  --color-brand-muted: rgba(75, 145, 195, 0.2);
182
218
 
@@ -15,6 +15,23 @@
15
15
  --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
16
16
  --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);
17
17
 
18
+ // Bevel — paired inset highlight (top) + inset shadow (bottom) for surfaces
19
+ // that should read as raised/3D (chips, ring rims, keyboard keys, mechanical
20
+ // toggles). Compose with `--shadow-*` for an ambient drop:
21
+ // `box-shadow: var(--shadow-bevel), var(--shadow-sm);`
22
+ --shadow-bevel:
23
+ inset 0 1px 1px rgba(255, 255, 255, 0.85), inset 0 -1px 1.5px rgba(0, 0, 0, 0.25);
24
+ --shadow-bevel-strong:
25
+ inset 0 1.5px 2px rgba(255, 255, 255, 0.9), inset 0 -2px 3px rgba(0, 0, 0, 0.3);
26
+
27
+ // Well — paired inset shadow (top) + inset highlight (bottom) for surfaces
28
+ // that should read as recessed/sunken (cavity in a ring, depressed switch,
29
+ // inset panel). Inverse lighting of `--shadow-bevel`.
30
+ --shadow-well:
31
+ inset 0 1px 1.5px rgba(0, 0, 0, 0.3), inset 0 -1px 0.5px rgba(255, 255, 255, 0.5);
32
+ --shadow-well-strong:
33
+ inset 0 2px 3px rgba(0, 0, 0, 0.4), inset 0 -1.5px 1px rgba(255, 255, 255, 0.55);
34
+
18
35
  // Focus ring — used for keyboard accessibility across all interactive elements
19
36
  --shadow-focus-ring: 0 0 0 3px rgba(59, 130, 246, 0.45);
20
37
  --shadow-focus-ring-error: 0 0 0 3px var(--color-error-200);
@@ -55,6 +72,18 @@
55
72
  --shadow-xl:
56
73
  0 12px 18px -4px rgba(255, 255, 255, 0.05), 0 5px 8px -4px rgba(255, 255, 255, 0.03);
57
74
  --shadow-2xl: 0 16px 28px -8px rgba(255, 255, 255, 0.06);
75
+
76
+ // Bevel / well: against a dark surface a bright white highlight reads as a
77
+ // halo. Drop the highlight alpha and crank the shadow alpha so the relief
78
+ // still reads as 3D on the lifted bg-base (neutral-800) without glowing.
79
+ --shadow-bevel:
80
+ inset 0 1px 1px rgba(255, 255, 255, 0.18), inset 0 -1px 1.5px rgba(0, 0, 0, 0.6);
81
+ --shadow-bevel-strong:
82
+ inset 0 1.5px 2px rgba(255, 255, 255, 0.22), inset 0 -2px 3px rgba(0, 0, 0, 0.7);
83
+ --shadow-well:
84
+ inset 0 1px 1.5px rgba(0, 0, 0, 0.55), inset 0 -1px 0.5px rgba(255, 255, 255, 0.08);
85
+ --shadow-well-strong:
86
+ inset 0 2px 3px rgba(0, 0, 0, 0.7), inset 0 -1.5px 1px rgba(255, 255, 255, 0.12);
58
87
  }
59
88
 
60
89
  @media (prefers-color-scheme: dark) {
@@ -81,6 +81,17 @@
81
81
  --text-h4-weight: var(--font-weight-semibold);
82
82
  --text-h4-lh: var(--line-height-snug);
83
83
 
84
+ // Section heading — page-level subsection title (e.g. an `<h2>` under an
85
+ // `<h1>` page title on a docs or marketing page). Same size/weight/lh as
86
+ // `--text-h4-*` but routes through the brand family so the heading reads
87
+ // as part of the brand wordmark rather than the body type. The only
88
+ // composite that pins a font-family; consumers who want to recolour or
89
+ // resize without re-specifying the family can still override per-piece.
90
+ --text-section-heading-size: var(--font-size-xl);
91
+ --text-section-heading-weight: var(--font-weight-semibold);
92
+ --text-section-heading-lh: var(--line-height-snug);
93
+ --text-section-heading-family: var(--font-family-brand);
94
+
84
95
  // Body
85
96
  --text-body-lg-size: var(--font-size-lg);
86
97
  --text-body-lg-weight: var(--font-weight-regular);
@@ -107,10 +118,16 @@
107
118
  --text-label-sm-weight: var(--font-weight-medium);
108
119
  --text-label-sm-lh: var(--line-height-tight);
109
120
 
110
- // Helper / caption — used for field-level hint and error messages. Sits
111
- // between `--font-size-xs` (12px) and `--font-size-sm` (14px) at 13px so
112
- // it stays visually subordinate to the field's label without dropping into
113
- // the "barely readable" zone that 12px hits on dense forms.
121
+ // Helper / caption — small subordinate text that sits visually below the
122
+ // primary content of a component. Sits between `--font-size-xs` (12px) and
123
+ // `--font-size-sm` (14px) at 13px so it stays subordinate without dropping
124
+ // into the "barely readable" zone that 12px hits.
125
+ //
126
+ // Primary role: field-level hint and error messages on form-like components
127
+ // (see STANDARD below). Secondary role: short subordinate metadata text
128
+ // inside a component, e.g. `<ea-file-uploader>`'s constraints disclosure
129
+ // ("PNG or JPG up to 5MB") and per-file size label ("245 KB"). For any
130
+ // role bigger than these, reach for a body-* composite instead.
114
131
  //
115
132
  // STANDARD — every form-like component (anything exposing `errorMsg` and/or
116
133
  // `hint`) must render its messages identically. Mirror `<ea-input>` exactly: