@eagami/ui 1.0.0 → 1.0.2

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": "1.0.0",
3
+ "version": "1.0.2",
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",
@@ -8,28 +8,28 @@
8
8
  // ---------------------------------------------------------------------------
9
9
 
10
10
  // Primary
11
- --color-primary-50: #eef4f8;
12
- --color-primary-100: #d5e5f0;
13
- --color-primary-200: #accfe2;
14
- --color-primary-300: #7db1ce;
15
- --color-primary-400: #628ead;
16
- --color-primary-500: #3c6c90;
17
- --color-primary-600: #2f567a;
18
- --color-primary-700: #285175;
19
- --color-primary-800: #11365c;
20
- --color-primary-900: #0d2533;
11
+ --color-primary-50: #ecf3f9;
12
+ --color-primary-100: #d1e3f0;
13
+ --color-primary-200: #abcbe3;
14
+ --color-primary-300: #7dafd4;
15
+ --color-primary-400: #4b91c3;
16
+ --color-primary-500: #3674a1;
17
+ --color-primary-600: #2a5b7e;
18
+ --color-primary-700: #204560;
19
+ --color-primary-800: #162f41;
20
+ --color-primary-900: #0d1c26;
21
21
 
22
22
  // Secondary
23
- --color-secondary-50: #f3f1f7;
24
- --color-secondary-100: #e3deed;
25
- --color-secondary-200: #c7bedb;
26
- --color-secondary-300: #a796c3;
27
- --color-secondary-400: #7d6a9c;
28
- --color-secondary-500: #594b6e;
29
- --color-secondary-600: #493d5c;
30
- --color-secondary-700: #40374f;
31
- --color-secondary-800: #2f2439;
32
- --color-secondary-900: #1e1528;
23
+ --color-secondary-50: #f2eff5;
24
+ --color-secondary-100: #dfd9e8;
25
+ --color-secondary-200: #c4b9d5;
26
+ --color-secondary-300: #a493be;
27
+ --color-secondary-400: #8169a5;
28
+ --color-secondary-500: #665086;
29
+ --color-secondary-600: #503f69;
30
+ --color-secondary-700: #3d3050;
31
+ --color-secondary-800: #292136;
32
+ --color-secondary-900: #181320;
33
33
 
34
34
  // Neutral (Gray)
35
35
  --color-neutral-0: #ffffff;
@@ -94,6 +94,7 @@
94
94
  --color-bg-base: var(--color-neutral-0);
95
95
  --color-bg-subtle: var(--color-neutral-50);
96
96
  --color-bg-muted: var(--color-neutral-100);
97
+ --color-bg-elevated: var(--color-neutral-0);
97
98
  --color-bg-overlay: rgba(0, 0, 0, 0.5);
98
99
 
99
100
  // Border
@@ -134,29 +135,58 @@
134
135
  }
135
136
 
136
137
  // ---------------------------------------------------------------------------
137
- // Dark mode overrides
138
+ // Dark mode overrides — applied when the OS prefers dark, unless the
139
+ // consumer has explicitly opted out via `<html data-theme="light">`. To
140
+ // force dark regardless of OS, set `<html data-theme="dark">`.
138
141
  // ---------------------------------------------------------------------------
142
+ @mixin dark-color-tokens {
143
+ --color-text-primary: var(--color-neutral-50);
144
+ --color-text-secondary: var(--color-neutral-400);
145
+ --color-text-tertiary: var(--color-neutral-500);
146
+ --color-text-disabled: var(--color-neutral-700);
147
+ --color-text-inverse: var(--color-neutral-900);
148
+ --color-text-link: var(--color-primary-300);
149
+ --color-text-link-hover: var(--color-primary-100);
150
+
151
+ --color-bg-base: var(--color-neutral-950);
152
+ --color-bg-subtle: var(--color-neutral-900);
153
+ --color-bg-muted: var(--color-neutral-800);
154
+ // Elevated surfaces (Card variant="elevated", Dialog, Drawer) need a
155
+ // background that's visibly lighter than the page bg, since black shadows
156
+ // disappear against a near-black page. Neutral-900 sits one step above
157
+ // bg-base and gives shadows something to fall against.
158
+ --color-bg-elevated: var(--color-neutral-900);
159
+
160
+ --color-border-default: var(--color-neutral-700);
161
+ --color-border-strong: var(--color-neutral-500);
162
+
163
+ --color-brand-default: var(--color-primary-400);
164
+ --color-brand-hover: var(--color-primary-300);
165
+ --color-brand-active: var(--color-primary-200);
166
+ --color-brand-subtle: rgba(75, 145, 195, 0.1);
167
+ --color-brand-muted: rgba(75, 145, 195, 0.2);
168
+
169
+ // Status `*-subtle` / `*-muted` — light pastels in light mode become
170
+ // unreadable behind light text in dark mode. Re-tint as a low-alpha wash of
171
+ // the saturated `*-500` hue so the surface darkens enough for `*-text-primary`
172
+ // (white) to read against it.
173
+ --color-success-subtle: rgba(34, 197, 94, 0.15);
174
+ --color-success-muted: rgba(34, 197, 94, 0.25);
175
+ --color-warning-subtle: rgba(245, 158, 11, 0.15);
176
+ --color-warning-muted: rgba(245, 158, 11, 0.25);
177
+ --color-error-subtle: rgba(239, 68, 68, 0.15);
178
+ --color-error-muted: rgba(239, 68, 68, 0.25);
179
+ --color-info-subtle: rgba(6, 182, 212, 0.15);
180
+ --color-info-muted: rgba(6, 182, 212, 0.25);
181
+ }
182
+
139
183
  @media (prefers-color-scheme: dark) {
140
- :root {
141
- --color-text-primary: var(--color-neutral-50);
142
- --color-text-secondary: var(--color-neutral-400);
143
- --color-text-tertiary: var(--color-neutral-500);
144
- --color-text-disabled: var(--color-neutral-700);
145
- --color-text-inverse: var(--color-neutral-900);
146
- --color-text-link: var(--color-primary-300);
147
- --color-text-link-hover: var(--color-primary-100);
148
-
149
- --color-bg-base: var(--color-neutral-950);
150
- --color-bg-subtle: var(--color-neutral-900);
151
- --color-bg-muted: var(--color-neutral-800);
152
-
153
- --color-border-default: var(--color-neutral-700);
154
- --color-border-strong: var(--color-neutral-500);
155
-
156
- --color-brand-default: var(--color-primary-400);
157
- --color-brand-hover: var(--color-primary-300);
158
- --color-brand-active: var(--color-primary-200);
159
- --color-brand-subtle: rgba(98, 142, 173, 0.1);
160
- --color-brand-muted: rgba(98, 142, 173, 0.2);
184
+ :root:not([data-theme='light']) {
185
+ @include dark-color-tokens;
161
186
  }
162
187
  }
188
+
189
+ :root[data-theme='dark'] {
190
+ @include dark-color-tokens;
191
+ color-scheme: dark;
192
+ }
@@ -33,3 +33,35 @@
33
33
  --z-index-toast: 600;
34
34
  --z-index-tooltip: 700;
35
35
  }
36
+
37
+ // Dark mode — black drop shadows are nearly invisible against a near-black
38
+ // page, so flip the shadow color to white at low alpha. The soft fade is what
39
+ // reads as a cast shadow; against a dark page, white-at-low-alpha blends to a
40
+ // muted dark gray that mirrors the role black-at-low-alpha plays in light mode.
41
+ // xl and 2xl have tighter offset/blur than light mode so the lighter fade
42
+ // doesn't sprawl into a halo. The `:not([data-theme='light'])` clause lets
43
+ // consumers force light mode via `<html data-theme="light">` even when the OS
44
+ // prefers dark, and the matching `[data-theme='dark']` block forces dark mode
45
+ // regardless of OS.
46
+ @mixin dark-elevation-tokens {
47
+ --shadow-xs: 0 1px 2px 0 rgba(255, 255, 255, 0.04);
48
+ --shadow-sm:
49
+ 0 1px 3px 0 rgba(255, 255, 255, 0.05), 0 1px 2px -1px rgba(255, 255, 255, 0.04);
50
+ --shadow-md:
51
+ 0 4px 6px -1px rgba(255, 255, 255, 0.06), 0 2px 4px -2px rgba(255, 255, 255, 0.04);
52
+ --shadow-lg:
53
+ 0 8px 12px -2px rgba(255, 255, 255, 0.08), 0 3px 5px -3px rgba(255, 255, 255, 0.05);
54
+ --shadow-xl:
55
+ 0 12px 18px -4px rgba(255, 255, 255, 0.1), 0 5px 8px -4px rgba(255, 255, 255, 0.06);
56
+ --shadow-2xl: 0 16px 28px -8px rgba(255, 255, 255, 0.12);
57
+ }
58
+
59
+ @media (prefers-color-scheme: dark) {
60
+ :root:not([data-theme='light']) {
61
+ @include dark-elevation-tokens;
62
+ }
63
+ }
64
+
65
+ :root[data-theme='dark'] {
66
+ @include dark-elevation-tokens;
67
+ }
@@ -188,6 +188,8 @@ declare class AvatarEditorComponent implements OnDestroy {
188
188
  readonly isLoading: _angular_core.Signal<boolean>;
189
189
  readonly zoom: _angular_core.WritableSignal<number>;
190
190
  readonly canRevert: _angular_core.Signal<boolean>;
191
+ /** True when the visible crop is darker than mid-grey; drives the `--on-light` class on the overlay so the "Change photo" affordance stays readable. */
192
+ readonly isImageDark: _angular_core.WritableSignal<boolean>;
191
193
  private image;
192
194
  private offsetX;
193
195
  private offsetY;
@@ -248,6 +250,17 @@ declare class AvatarEditorComponent implements OnDestroy {
248
250
  private getDrawParams;
249
251
  private clampOffset;
250
252
  private draw;
253
+ /**
254
+ * Samples the visible crop region and stores whether it's darker than
255
+ * mid-grey, so the hover overlay can flip its label and icon between
256
+ * white (on dark photos) and black (on light photos).
257
+ *
258
+ * Restricts sampling to the inscribed circle for circle crops to ignore
259
+ * the soon-to-be-masked corners. Uses Rec. 601 perceptual luminance
260
+ * weights; transparent pixels and CORS-tainted canvases default to a
261
+ * "dark" assumption (white ink).
262
+ */
263
+ private updateImageDarkness;
251
264
  private emitCropStateChange;
252
265
  private clearCanvas;
253
266
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AvatarEditorComponent, never>;
@@ -839,8 +852,9 @@ declare class AlertTriangleIconComponent {
839
852
  }
840
853
 
841
854
  declare class AppleIconComponent {
855
+ readonly brand: _angular_core.InputSignal<boolean>;
842
856
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppleIconComponent, never>;
843
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppleIconComponent, "ea-icon-apple", never, {}, {}, never, never, true, never>;
857
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppleIconComponent, "ea-icon-apple", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
844
858
  }
845
859
 
846
860
  declare class ArrowDownIconComponent {
@@ -949,8 +963,9 @@ declare class EyeIconComponent {
949
963
  }
950
964
 
951
965
  declare class FacebookIconComponent {
966
+ readonly brand: _angular_core.InputSignal<boolean>;
952
967
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FacebookIconComponent, never>;
953
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<FacebookIconComponent, "ea-icon-facebook", never, {}, {}, never, never, true, never>;
968
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FacebookIconComponent, "ea-icon-facebook", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
954
969
  }
955
970
 
956
971
  declare class FileIconComponent {
@@ -964,8 +979,9 @@ declare class FilterIconComponent {
964
979
  }
965
980
 
966
981
  declare class GithubIconComponent {
982
+ readonly brand: _angular_core.InputSignal<boolean>;
967
983
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GithubIconComponent, never>;
968
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<GithubIconComponent, "ea-icon-github", never, {}, {}, never, never, true, never>;
984
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GithubIconComponent, "ea-icon-github", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
969
985
  }
970
986
 
971
987
  declare class GoogleIconComponent {
@@ -1079,8 +1095,9 @@ declare class XCircleIconComponent {
1079
1095
  }
1080
1096
 
1081
1097
  declare class XTwitterIconComponent {
1098
+ readonly brand: _angular_core.InputSignal<boolean>;
1082
1099
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<XTwitterIconComponent, never>;
1083
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<XTwitterIconComponent, "ea-icon-x-twitter", never, {}, {}, never, never, true, never>;
1100
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<XTwitterIconComponent, "ea-icon-x-twitter", never, { "brand": { "alias": "brand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1084
1101
  }
1085
1102
 
1086
1103
  declare class XIconComponent {