@slyxup/ui 2.0.0 → 2.3.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/README.md +99 -3
- package/dist/components/PasswordField.d.ts +14 -0
- package/dist/components/PasswordField.d.ts.map +1 -0
- package/dist/components/PasswordField.js +9 -0
- package/dist/components/PasswordField.js.map +1 -0
- package/dist/components/PricingTable/PricingTable.js +1 -1
- package/dist/components/PricingTable/PricingTable.js.map +1 -1
- package/dist/components/ResetPassword/ResetPassword.d.ts.map +1 -1
- package/dist/components/ResetPassword/ResetPassword.js +2 -1
- package/dist/components/ResetPassword/ResetPassword.js.map +1 -1
- package/dist/components/SignIn/SignIn.d.ts +10 -1
- package/dist/components/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/SignIn/SignIn.js +7 -6
- package/dist/components/SignIn/SignIn.js.map +1 -1
- package/dist/components/SignUp/SignUp.d.ts +10 -1
- package/dist/components/SignUp/SignUp.d.ts.map +1 -1
- package/dist/components/SignUp/SignUp.js +4 -3
- package/dist/components/SignUp/SignUp.js.map +1 -1
- package/dist/components/SocialButtons/SocialButtons.js +1 -1
- package/dist/components/SocialButtons/SocialButtons.js.map +1 -1
- package/dist/components/UserButton/UserButton.js +1 -1
- package/dist/components/UserButton/UserButton.js.map +1 -1
- package/dist/components/UserProfile/UserProfile.js +2 -2
- package/dist/components/UserProfile/UserProfile.js.map +1 -1
- package/dist/icons.d.ts +2 -0
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +6 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/react/hooks/useBilling.d.ts.map +1 -1
- package/dist/react/hooks/useBilling.js.map +1 -1
- package/dist/styles.d.ts +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +237 -12
- package/dist/styles.js.map +1 -1
- package/dist/theme.d.ts +74 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +238 -0
- package/dist/theme.js.map +1 -0
- package/package.json +1 -1
package/dist/styles.js
CHANGED
|
@@ -10,6 +10,7 @@ export const CSS = `
|
|
|
10
10
|
--slx-accent: #5b5bd6;
|
|
11
11
|
--slx-accent-hover: #4c4cc4;
|
|
12
12
|
--slx-accent-soft: rgba(91, 91, 214, 0.12);
|
|
13
|
+
--slx-accent-2: #8b5cf6;
|
|
13
14
|
--slx-bg: #ffffff;
|
|
14
15
|
--slx-bg-subtle: #f7f7fb;
|
|
15
16
|
--slx-bg-page: #e9eaf6;
|
|
@@ -41,7 +42,7 @@ export const CSS = `
|
|
|
41
42
|
font-feature-settings: "cv11", "ss01";
|
|
42
43
|
}
|
|
43
44
|
@media (prefers-color-scheme: dark) {
|
|
44
|
-
.slyxup-root:not(.slyxup-light) {
|
|
45
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']):not([data-slyxup-theme='light']) {
|
|
45
46
|
--slx-accent: #8484f2;
|
|
46
47
|
--slx-accent-hover: #9696f5;
|
|
47
48
|
--slx-accent-soft: rgba(132, 132, 242, 0.16);
|
|
@@ -97,7 +98,7 @@ export const CSS = `
|
|
|
97
98
|
box-sizing: border-box;
|
|
98
99
|
animation: slx-rise .38s cubic-bezier(.22,.9,.32,1) both;
|
|
99
100
|
}
|
|
100
|
-
.slyxup-root:not(.slyxup-light) .slx-card,
|
|
101
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-card,
|
|
101
102
|
.slx-card { color: var(--slx-ink); }
|
|
102
103
|
.slx-card-error { animation: slx-shake .45s cubic-bezier(.36,.07,.19,.97) both; }
|
|
103
104
|
|
|
@@ -105,7 +106,7 @@ export const CSS = `
|
|
|
105
106
|
.slx-mark {
|
|
106
107
|
width: 46px; height: 46px; border-radius: 13px;
|
|
107
108
|
display: flex; align-items: center; justify-content: center;
|
|
108
|
-
background: linear-gradient(140deg, var(--slx-accent) 0%,
|
|
109
|
+
background: linear-gradient(140deg, var(--slx-accent) 0%, var(--slx-accent-2) 100%);
|
|
109
110
|
box-shadow:
|
|
110
111
|
inset 0 1px 0 rgba(255,255,255,.28),
|
|
111
112
|
0 6px 16px -6px rgba(91,91,214,.55);
|
|
@@ -165,14 +166,14 @@ export const CSS = `
|
|
|
165
166
|
border-radius: var(--slx-radius-sm);
|
|
166
167
|
padding: 9px 11px; margin: 0 0 16px;
|
|
167
168
|
}
|
|
168
|
-
.slyxup-root:not(.slyxup-light) .slx-setup-note {
|
|
169
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-setup-note {
|
|
169
170
|
color: #f5d878; background: rgba(250,204,21,.07); border-color: rgba(250,204,21,.25);
|
|
170
171
|
}
|
|
171
172
|
.slx-setup-note code {
|
|
172
173
|
font-family: var(--slx-mono); font-size: 11px;
|
|
173
174
|
background: rgba(0,0,0,.05); border-radius: 4px; padding: 1px 4px;
|
|
174
175
|
}
|
|
175
|
-
.slyxup-root:not(.slyxup-light) .slx-setup-note code { background: rgba(255,255,255,.08); }
|
|
176
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-setup-note code { background: rgba(255,255,255,.08); }
|
|
176
177
|
|
|
177
178
|
/* ── Primary button ── */
|
|
178
179
|
.slx-btn {
|
|
@@ -190,19 +191,19 @@ export const CSS = `
|
|
|
190
191
|
.slx-btn:focus-visible { outline: none; box-shadow: 0 0 0 3.5px rgba(10,10,15,.16), 0 0 0 1.5px #0a0a0f; }
|
|
191
192
|
.slx-btn[disabled] { opacity: .55; cursor: not-allowed; }
|
|
192
193
|
@media (prefers-color-scheme: dark) {
|
|
193
|
-
.slyxup-root:not(.slyxup-light) .slx-btn {
|
|
194
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-btn {
|
|
194
195
|
background: linear-gradient(180deg, #ffffff 0%, #ececf1 100%);
|
|
195
196
|
color: #0a0a0f; border-color: #ececf1;
|
|
196
197
|
box-shadow: 0 1px 2px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.9);
|
|
197
198
|
}
|
|
198
|
-
.slyxup-root:not(.slyxup-light) .slx-btn:hover { filter: brightness(.94); }
|
|
199
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-btn:hover { filter: brightness(.94); }
|
|
199
200
|
}
|
|
200
201
|
.slx-spinner {
|
|
201
202
|
width: 15px; height: 15px; flex: none;
|
|
202
203
|
border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
|
|
203
204
|
border-radius: 50%; animation: slx-spin .7s linear infinite;
|
|
204
205
|
}
|
|
205
|
-
.slyxup-root:not(.slyxup-light) .slx-spinner { border-color: rgba(10,10,15,.25); border-top-color: #0a0a0f; }
|
|
206
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-spinner { border-color: rgba(10,10,15,.25); border-top-color: #0a0a0f; }
|
|
206
207
|
|
|
207
208
|
/* ── Social ── */
|
|
208
209
|
.slx-social { display: grid; gap: 9px; margin-bottom: 4px; }
|
|
@@ -263,7 +264,7 @@ export const CSS = `
|
|
|
263
264
|
border: 1px solid var(--slx-border); cursor: pointer;
|
|
264
265
|
display: flex; align-items: center; justify-content: center;
|
|
265
266
|
font-size: 14px; font-weight: 650; color: #fff;
|
|
266
|
-
background: linear-gradient(135deg, var(--slx-accent),
|
|
267
|
+
background: linear-gradient(135deg, var(--slx-accent), var(--slx-accent-2));
|
|
267
268
|
padding: 0; overflow: hidden;
|
|
268
269
|
transition: box-shadow .15s, transform .06s;
|
|
269
270
|
}
|
|
@@ -307,7 +308,7 @@ export const CSS = `
|
|
|
307
308
|
.slx-badge-ok { color: var(--slx-success); background: color-mix(in srgb, var(--slx-success) 9%, transparent); border-color: color-mix(in srgb, var(--slx-success) 30%, transparent); }
|
|
308
309
|
.slx-badge-warn { color: #b45309; background: color-mix(in srgb, #f59e0b 10%, transparent); border-color: color-mix(in srgb, #f59e0b 30%, transparent); }
|
|
309
310
|
.slx-badge-accent { color: var(--slx-accent); background: var(--slx-accent-soft); border-color: color-mix(in srgb, var(--slx-accent) 30%, transparent); }
|
|
310
|
-
.slyxup-root:not(.slyxup-light) .slx-badge-warn { color: #fbbf24; }
|
|
311
|
+
.slyxup-root:not(.slyxup-light):not([data-slyxup-theme='light']) .slx-badge-warn { color: #fbbf24; }
|
|
311
312
|
|
|
312
313
|
/* ── Modal overlay ── */
|
|
313
314
|
.slx-overlay {
|
|
@@ -415,7 +416,7 @@ export const CSS = `
|
|
|
415
416
|
flex-shrink: 0;
|
|
416
417
|
display: flex; align-items: center; justify-content: center;
|
|
417
418
|
font-size: 24px; font-weight: 700; color: #fff;
|
|
418
|
-
background: linear-gradient(135deg, var(--slx-accent),
|
|
419
|
+
background: linear-gradient(135deg, var(--slx-accent), var(--slx-accent-2));
|
|
419
420
|
overflow: hidden;
|
|
420
421
|
box-shadow: 0 2px 8px rgba(91,91,214,.3);
|
|
421
422
|
}
|
|
@@ -522,7 +523,7 @@ export const CSS = `
|
|
|
522
523
|
.slx-plan-badge {
|
|
523
524
|
position: absolute; top: -10px; right: 12px;
|
|
524
525
|
font-size: 10px; font-weight: 700; letter-spacing: .05em;
|
|
525
|
-
color: #fff; background: linear-gradient(135deg, var(--slx-accent),
|
|
526
|
+
color: #fff; background: linear-gradient(135deg, var(--slx-accent), var(--slx-accent-2));
|
|
526
527
|
padding: 3px 8px; border-radius: 999px;
|
|
527
528
|
}
|
|
528
529
|
.slx-plan-name { font-size: 14px; font-weight: 600; color: var(--slx-ink-strong); margin: 0 0 6px; }
|
|
@@ -578,6 +579,230 @@ export const CSS = `
|
|
|
578
579
|
.slx-pagination .slx-btn-secondary { font-size: 12px; padding: 4px 10px; }
|
|
579
580
|
.slx-invoice-row { flex-wrap: wrap; gap: 6px; }
|
|
580
581
|
}
|
|
582
|
+
/* ── Explicit theme mode (wins over OS preference) ── */
|
|
583
|
+
.slyxup-root[data-slyxup-theme='dark'] {
|
|
584
|
+
--slx-accent: #8484f2;
|
|
585
|
+
--slx-accent-hover: #9696f5;
|
|
586
|
+
--slx-accent-soft: rgba(132, 132, 242, 0.16);
|
|
587
|
+
--slx-bg: #17171f;
|
|
588
|
+
--slx-bg-subtle: #1e1e28;
|
|
589
|
+
--slx-bg-page: #101016;
|
|
590
|
+
--slx-ink: #f0f0f4;
|
|
591
|
+
--slx-ink-strong: #ffffff;
|
|
592
|
+
--slx-muted: #9a9aa6;
|
|
593
|
+
--slx-border: #292935;
|
|
594
|
+
--slx-border-strong: #343442;
|
|
595
|
+
--slx-danger: #f0737d;
|
|
596
|
+
--slx-success: #4ade80;
|
|
597
|
+
--slx-shadow-card:
|
|
598
|
+
0 1px 2px rgba(0,0,0,.25),
|
|
599
|
+
0 12px 32px -8px rgba(0,0,0,.5),
|
|
600
|
+
0 32px 72px -20px rgba(0,0,0,.55);
|
|
601
|
+
--slx-shadow-pop:
|
|
602
|
+
0 4px 12px rgba(0,0,0,.4),
|
|
603
|
+
0 24px 56px -12px rgba(0,0,0,.6);
|
|
604
|
+
}
|
|
605
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-btn {
|
|
606
|
+
background: linear-gradient(180deg, #ffffff 0%, #ececf1 100%);
|
|
607
|
+
color: #0a0a0f; border-color: #ececf1;
|
|
608
|
+
box-shadow: 0 1px 2px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.9);
|
|
609
|
+
}
|
|
610
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-btn:hover { filter: brightness(.94); }
|
|
611
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-spinner { border-color: rgba(10,10,15,.25); border-top-color: #0a0a0f; }
|
|
612
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-setup-note {
|
|
613
|
+
color: #f5d878; background: rgba(250,204,21,.07); border-color: rgba(250,204,21,.25);
|
|
614
|
+
}
|
|
615
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-setup-note code { background: rgba(255,255,255,.08); }
|
|
616
|
+
.slyxup-root[data-slyxup-theme='dark'] .slx-badge-warn { color: #fbbf24; }
|
|
617
|
+
.slyxup-root[data-slyxup-theme='light'] {
|
|
618
|
+
--slx-bg: #ffffff;
|
|
619
|
+
--slx-bg-subtle: #f7f7fb;
|
|
620
|
+
--slx-bg-page: #e9eaf6;
|
|
621
|
+
--slx-ink: #16161d;
|
|
622
|
+
--slx-ink-strong: #0c0c12;
|
|
623
|
+
--slx-muted: #6f6f7b;
|
|
624
|
+
--slx-border: #e3e3ee;
|
|
625
|
+
--slx-border-strong: #d3d3e2;
|
|
626
|
+
--slx-danger: #d64550;
|
|
627
|
+
--slx-success: #1f9d55;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/* ── Accent presets (applyTheme or data-slyxup-accent) ── */
|
|
631
|
+
.slyxup-root[data-slyxup-accent='violet'] { --slx-accent: #5b5bd6; --slx-accent-hover: #4c4cc4; --slx-accent-soft: rgba(91,91,214,.12); --slx-accent-2: #8b5cf6; }
|
|
632
|
+
.slyxup-root[data-slyxup-accent='blue'] { --slx-accent: #2563eb; --slx-accent-hover: #1d4ed8; --slx-accent-soft: rgba(37,99,235,.12); --slx-accent-2: #60a5fa; }
|
|
633
|
+
.slyxup-root[data-slyxup-accent='emerald'] { --slx-accent: #059669; --slx-accent-hover: #047857; --slx-accent-soft: rgba(5,150,105,.12); --slx-accent-2: #34d399; }
|
|
634
|
+
.slyxup-root[data-slyxup-accent='amber'] { --slx-accent: #d97706; --slx-accent-hover: #b45309; --slx-accent-soft: rgba(217,119,6,.14); --slx-accent-2: #fbbf24; }
|
|
635
|
+
.slyxup-root[data-slyxup-accent='rose'] { --slx-accent: #e11d48; --slx-accent-hover: #be123c; --slx-accent-soft: rgba(225,29,72,.12); --slx-accent-2: #fb7185; }
|
|
636
|
+
.slyxup-root[data-slyxup-accent='cyan'] { --slx-accent: #0891b2; --slx-accent-hover: #0e7490; --slx-accent-soft: rgba(8,145,178,.12); --slx-accent-2: #22d3ee; }
|
|
637
|
+
|
|
638
|
+
/* ── Accent primary button (alternative to the default ink button) ── */
|
|
639
|
+
.slx-btn-accent {
|
|
640
|
+
background: linear-gradient(180deg, var(--slx-accent-hover) 0%, var(--slx-accent) 100%);
|
|
641
|
+
border-color: var(--slx-accent);
|
|
642
|
+
color: #fff;
|
|
643
|
+
box-shadow: 0 1px 2px rgba(18,18,28,.3), inset 0 1px 0 rgba(255,255,255,.18);
|
|
644
|
+
}
|
|
645
|
+
.slx-btn-accent:hover { filter: brightness(1.07); }
|
|
646
|
+
.slx-btn-accent:active { transform: scale(.985); filter: brightness(.95); }
|
|
647
|
+
.slx-btn-accent:focus-visible { outline: none; box-shadow: 0 0 0 3.5px var(--slx-accent-soft); }
|
|
648
|
+
.slx-btn-accent .slx-spinner { border-color: rgba(255,255,255,.35); border-top-color: #fff; }
|
|
649
|
+
|
|
650
|
+
/* ── Primary buttons in brand accent (opt-in via data-slyxup-primary='accent') ── */
|
|
651
|
+
.slyxup-root[data-slyxup-primary='accent'] .slx-btn {
|
|
652
|
+
background: linear-gradient(180deg, var(--slx-accent-hover) 0%, var(--slx-accent) 100%);
|
|
653
|
+
border-color: var(--slx-accent);
|
|
654
|
+
color: #fff;
|
|
655
|
+
box-shadow: 0 1px 2px rgba(18, 18, 28, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.18);
|
|
656
|
+
}
|
|
657
|
+
.slyxup-root[data-slyxup-primary='accent'] .slx-btn:hover { filter: brightness(1.07); }
|
|
658
|
+
.slyxup-root[data-slyxup-primary='accent'] .slx-btn:active { filter: brightness(0.95); }
|
|
659
|
+
.slyxup-root[data-slyxup-primary='accent'] .slx-btn:focus-visible {
|
|
660
|
+
outline: none;
|
|
661
|
+
box-shadow: 0 0 0 3.5px var(--slx-accent-soft);
|
|
662
|
+
}
|
|
663
|
+
.slyxup-root[data-slyxup-primary='accent'] .slx-btn .slx-spinner {
|
|
664
|
+
border-color: rgba(255, 255, 255, 0.35);
|
|
665
|
+
border-top-color: #fff;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/* ── Auth layouts: centered (default) / split / minimal ── */
|
|
669
|
+
.slx-form-full { display: contents; }
|
|
670
|
+
.slx-card.slx-layout-split {
|
|
671
|
+
max-width: 780px;
|
|
672
|
+
padding: 0;
|
|
673
|
+
display: grid;
|
|
674
|
+
grid-template-columns: 1fr 1.05fr;
|
|
675
|
+
overflow: hidden;
|
|
676
|
+
}
|
|
677
|
+
.slx-split-brand {
|
|
678
|
+
background: linear-gradient(150deg, var(--slx-accent) 0%, var(--slx-accent-2) 130%);
|
|
679
|
+
color: #fff;
|
|
680
|
+
padding: 40px 36px;
|
|
681
|
+
display: flex;
|
|
682
|
+
flex-direction: column;
|
|
683
|
+
justify-content: center;
|
|
684
|
+
gap: 0;
|
|
685
|
+
position: relative;
|
|
686
|
+
overflow: hidden;
|
|
687
|
+
}
|
|
688
|
+
.slx-split-brand::after {
|
|
689
|
+
content: '';
|
|
690
|
+
position: absolute;
|
|
691
|
+
width: 280px;
|
|
692
|
+
height: 280px;
|
|
693
|
+
right: -90px;
|
|
694
|
+
bottom: -90px;
|
|
695
|
+
border-radius: 50%;
|
|
696
|
+
background: rgba(255, 255, 255, 0.09);
|
|
697
|
+
pointer-events: none;
|
|
698
|
+
}
|
|
699
|
+
.slx-split-mark {
|
|
700
|
+
width: 44px;
|
|
701
|
+
height: 44px;
|
|
702
|
+
border-radius: 12px;
|
|
703
|
+
background: rgba(255, 255, 255, 0.16);
|
|
704
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
705
|
+
display: flex;
|
|
706
|
+
align-items: center;
|
|
707
|
+
justify-content: center;
|
|
708
|
+
margin-bottom: 22px;
|
|
709
|
+
}
|
|
710
|
+
.slx-split-title {
|
|
711
|
+
font-family: var(--slx-display);
|
|
712
|
+
font-size: 26px;
|
|
713
|
+
font-weight: 700;
|
|
714
|
+
letter-spacing: -0.025em;
|
|
715
|
+
line-height: 1.15;
|
|
716
|
+
margin: 0 0 10px;
|
|
717
|
+
}
|
|
718
|
+
.slx-split-sub { font-size: 14px; line-height: 1.6; opacity: 0.85; margin: 0 0 24px; }
|
|
719
|
+
.slx-split-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
|
|
720
|
+
.slx-split-points li {
|
|
721
|
+
font-size: 13.5px;
|
|
722
|
+
font-weight: 500;
|
|
723
|
+
padding-left: 28px;
|
|
724
|
+
position: relative;
|
|
725
|
+
line-height: 1.45;
|
|
726
|
+
}
|
|
727
|
+
.slx-split-points li::before {
|
|
728
|
+
content: '✓';
|
|
729
|
+
position: absolute;
|
|
730
|
+
left: 0;
|
|
731
|
+
top: 0;
|
|
732
|
+
width: 19px;
|
|
733
|
+
height: 19px;
|
|
734
|
+
border-radius: 50%;
|
|
735
|
+
background: rgba(255, 255, 255, 0.18);
|
|
736
|
+
font-size: 11px;
|
|
737
|
+
font-weight: 800;
|
|
738
|
+
display: flex;
|
|
739
|
+
align-items: center;
|
|
740
|
+
justify-content: center;
|
|
741
|
+
}
|
|
742
|
+
.slx-split-form { padding: 36px 36px 32px; min-width: 0; }
|
|
743
|
+
.slx-card.slx-layout-minimal {
|
|
744
|
+
background: transparent;
|
|
745
|
+
border: none;
|
|
746
|
+
box-shadow: none;
|
|
747
|
+
padding: 10px 6px;
|
|
748
|
+
max-width: 380px;
|
|
749
|
+
animation: none;
|
|
750
|
+
}
|
|
751
|
+
.slx-card.slx-layout-minimal .slx-mark { width: 40px; height: 40px; border-radius: 11px; margin-bottom: 16px; }
|
|
752
|
+
.slx-card.slx-layout-minimal .slx-subtitle { margin-bottom: 20px; }
|
|
753
|
+
.slx-card.slx-layout-minimal .slx-input { background: var(--slx-bg); }
|
|
754
|
+
@media (max-width: 680px) {
|
|
755
|
+
.slx-card.slx-layout-split { grid-template-columns: 1fr; max-width: 440px; }
|
|
756
|
+
.slx-split-brand { padding: 26px 24px; }
|
|
757
|
+
.slx-split-brand::after { display: none; }
|
|
758
|
+
.slx-split-title { font-size: 21px; }
|
|
759
|
+
.slx-split-sub { margin-bottom: 0; }
|
|
760
|
+
.slx-split-points { display: none; }
|
|
761
|
+
.slx-split-form { padding: 26px 22px 24px; }
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* ── Password field with reveal toggle ── */
|
|
765
|
+
.slx-input-wrap { position: relative; }
|
|
766
|
+
.slx-input-wrap .slx-input { padding-right: 42px; }
|
|
767
|
+
.slx-pw-toggle {
|
|
768
|
+
position: absolute;
|
|
769
|
+
right: 6px;
|
|
770
|
+
top: 50%;
|
|
771
|
+
transform: translateY(-50%);
|
|
772
|
+
width: 30px;
|
|
773
|
+
height: 30px;
|
|
774
|
+
border-radius: 8px;
|
|
775
|
+
display: flex;
|
|
776
|
+
align-items: center;
|
|
777
|
+
justify-content: center;
|
|
778
|
+
background: none;
|
|
779
|
+
border: none;
|
|
780
|
+
color: var(--slx-muted);
|
|
781
|
+
cursor: pointer;
|
|
782
|
+
transition: background 0.12s, color 0.12s;
|
|
783
|
+
}
|
|
784
|
+
.slx-pw-toggle:hover { color: var(--slx-ink); background: color-mix(in srgb, var(--slx-ink) 5%, transparent); }
|
|
785
|
+
.slx-pw-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--slx-accent-soft); }
|
|
786
|
+
|
|
787
|
+
/* ── Compact density (opt-in via data-slyxup-density='compact') ── */
|
|
788
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-card { padding: 24px 24px 20px; }
|
|
789
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-mark { width: 38px; height: 38px; margin-bottom: 14px; }
|
|
790
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-title { font-size: 19px; }
|
|
791
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-subtitle { margin-bottom: 16px; }
|
|
792
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-field { margin-bottom: 10px; }
|
|
793
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-input { padding: 8px 11px; font-size: 13.5px; }
|
|
794
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-btn { padding: 9px 14px; }
|
|
795
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-divider { margin: 14px 0; }
|
|
796
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-footer { margin-top: 16px; }
|
|
797
|
+
.slyxup-root[data-slyxup-density='compact'] .slx-split-form { padding: 24px; }
|
|
798
|
+
|
|
799
|
+
/* ── Small-screen polish for auth cards & menus ── */
|
|
800
|
+
@media (max-width: 460px) {
|
|
801
|
+
.slx-card { padding: 26px 22px 24px; border-radius: var(--slx-radius-lg); }
|
|
802
|
+
.slx-title { font-size: 19px; }
|
|
803
|
+
.slx-menu { min-width: 210px; max-width: calc(100vw - 32px); }
|
|
804
|
+
.slx-social-btn { font-size: 13px; padding: 11px 12px; }
|
|
805
|
+
}
|
|
581
806
|
@media (max-width: 380px) {
|
|
582
807
|
.slx-profile-content { padding: 12px; }
|
|
583
808
|
.slx-profile-head { padding: 12px 12px 10px; }
|
package/dist/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAE5B,MAAM,CAAC,MAAM,GAAG,GAAG
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAE5B,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoyBlB,CAAC;AAEF,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,qFAAqF;AACrF,MAAM,UAAU,YAAY;IAC1B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,oEAAoE;IACpE,6DAA6D;IAC7D,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,6BAA6B,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,uBAAuB,CAAC,EAAE,CAAC;YACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAChD,QAAQ,CAAC,GAAG,GAAG,YAAY,CAAC;YAC5B,QAAQ,CAAC,IAAI;gBACX,+KAA+K,CAAC;YAClL,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC5C,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjC,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;AACH,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlyxUp UI — runtime theme system.
|
|
3
|
+
*
|
|
4
|
+
* Three ways to theme, in order of precedence:
|
|
5
|
+
* 1. `applyTheme({...})` — sets data attributes + CSS variables (JS API).
|
|
6
|
+
* 2. Data attributes directly: `data-slyxup-theme`, `data-slyxup-accent`.
|
|
7
|
+
* 3. Raw CSS variables (`--slx-*`) — always win, set them yourself.
|
|
8
|
+
*
|
|
9
|
+
* Scoping: pass a container element to style one subtree (e.g. a preview
|
|
10
|
+
* panel) instead of the whole document. The container must carry the
|
|
11
|
+
* `slyxup-root` class (added automatically).
|
|
12
|
+
*/
|
|
13
|
+
export type ThemeMode = 'light' | 'dark' | 'auto';
|
|
14
|
+
/** Auth page layouts — 3 professional variants, same logic underneath. */
|
|
15
|
+
export type AuthLayout = 'centered' | 'split' | 'minimal';
|
|
16
|
+
/** Primary button treatment. 'ink' (default) = near-black/white button, 'accent' = brand gradient. */
|
|
17
|
+
export type PrimaryStyle = 'ink' | 'accent';
|
|
18
|
+
/** Spacing density. 'comfortable' (default) or 'compact' for dense dialogs. */
|
|
19
|
+
export type Density = 'comfortable' | 'compact';
|
|
20
|
+
export type AccentName = 'violet' | 'blue' | 'emerald' | 'amber' | 'rose' | 'cyan';
|
|
21
|
+
export interface AccentDef {
|
|
22
|
+
label: string;
|
|
23
|
+
/** Primary accent (links, focus rings, badges, avatar gradients). */
|
|
24
|
+
accent: string;
|
|
25
|
+
/** Hover state for accent text/links. */
|
|
26
|
+
accentHover: string;
|
|
27
|
+
/** Soft tint for focus rings + highlighted surfaces. */
|
|
28
|
+
accentSoft: string;
|
|
29
|
+
/** Second stop of accent gradients (marks, avatars, popular badges). */
|
|
30
|
+
gradientTo: string;
|
|
31
|
+
}
|
|
32
|
+
export declare const ACCENTS: Record<AccentName, AccentDef>;
|
|
33
|
+
export interface FontDef {
|
|
34
|
+
label: string;
|
|
35
|
+
body: string;
|
|
36
|
+
display: string;
|
|
37
|
+
mono?: string;
|
|
38
|
+
/** Google Fonts stylesheet to load (skipped when absent). */
|
|
39
|
+
href?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare const FONTS: Record<string, FontDef>;
|
|
42
|
+
export interface CustomFont {
|
|
43
|
+
body?: string;
|
|
44
|
+
display?: string;
|
|
45
|
+
mono?: string;
|
|
46
|
+
/** Optional stylesheet URL for a custom webfont. */
|
|
47
|
+
href?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface SlyxUpTheme {
|
|
50
|
+
/** 'auto' follows the OS (default). 'light'/'dark' force a mode. */
|
|
51
|
+
mode?: ThemeMode;
|
|
52
|
+
/** Preset name or any custom CSS color for full control. */
|
|
53
|
+
accent?: AccentName | (string & {});
|
|
54
|
+
/** Font preset name or a custom stack. Default: inherit the host app. */
|
|
55
|
+
font?: keyof typeof FONTS | CustomFont;
|
|
56
|
+
/** Base corner radius in px — sm/lg scale from it. Default 10. */
|
|
57
|
+
radius?: number;
|
|
58
|
+
/** Primary buttons: 'ink' (default, near-black/white) or 'accent' (brand gradient). */
|
|
59
|
+
primary?: PrimaryStyle;
|
|
60
|
+
/** Spacing density: 'comfortable' (default) or 'compact'. */
|
|
61
|
+
density?: Density;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Apply a theme. Targets `document.documentElement` by default — pass a
|
|
65
|
+
* container to scope the theme to one subtree (it gets `slyxup-root` added).
|
|
66
|
+
* Returns a cleanup function restoring previous values.
|
|
67
|
+
*/
|
|
68
|
+
export declare function applyTheme(theme: SlyxUpTheme, root?: HTMLElement): () => void;
|
|
69
|
+
/** Read the currently applied theme from an element (default: document root). */
|
|
70
|
+
export declare function getTheme(root?: HTMLElement): Required<Omit<SlyxUpTheme, 'font' | 'radius'>> & {
|
|
71
|
+
font: string;
|
|
72
|
+
radius: string;
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,0EAA0E;AAC1E,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,sGAAsG;AACtG,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE5C,+EAA+E;AAC/E,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,SAAS,CAAC;AAEhD,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,MAAM,GACN,SAAS,GACT,OAAO,GACP,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,CA2CjD,CAAC;AAEF,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAmBzC,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACpC,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,OAAO,KAAK,GAAG,UAAU,CAAC;IACvC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAwBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI,CAmG7E;AAED,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,QAAQ,CACpD,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAAC,CACrC,GAAG;IACF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAwBA"}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlyxUp UI — runtime theme system.
|
|
3
|
+
*
|
|
4
|
+
* Three ways to theme, in order of precedence:
|
|
5
|
+
* 1. `applyTheme({...})` — sets data attributes + CSS variables (JS API).
|
|
6
|
+
* 2. Data attributes directly: `data-slyxup-theme`, `data-slyxup-accent`.
|
|
7
|
+
* 3. Raw CSS variables (`--slx-*`) — always win, set them yourself.
|
|
8
|
+
*
|
|
9
|
+
* Scoping: pass a container element to style one subtree (e.g. a preview
|
|
10
|
+
* panel) instead of the whole document. The container must carry the
|
|
11
|
+
* `slyxup-root` class (added automatically).
|
|
12
|
+
*/
|
|
13
|
+
import { injectStyles } from './styles';
|
|
14
|
+
export const ACCENTS = {
|
|
15
|
+
violet: {
|
|
16
|
+
label: 'Violet',
|
|
17
|
+
accent: '#5b5bd6',
|
|
18
|
+
accentHover: '#4c4cc4',
|
|
19
|
+
accentSoft: 'rgba(91, 91, 214, 0.12)',
|
|
20
|
+
gradientTo: '#8b5cf6',
|
|
21
|
+
},
|
|
22
|
+
blue: {
|
|
23
|
+
label: 'Blue',
|
|
24
|
+
accent: '#2563eb',
|
|
25
|
+
accentHover: '#1d4ed8',
|
|
26
|
+
accentSoft: 'rgba(37, 99, 235, 0.12)',
|
|
27
|
+
gradientTo: '#60a5fa',
|
|
28
|
+
},
|
|
29
|
+
emerald: {
|
|
30
|
+
label: 'Emerald',
|
|
31
|
+
accent: '#059669',
|
|
32
|
+
accentHover: '#047857',
|
|
33
|
+
accentSoft: 'rgba(5, 150, 105, 0.12)',
|
|
34
|
+
gradientTo: '#34d399',
|
|
35
|
+
},
|
|
36
|
+
amber: {
|
|
37
|
+
label: 'Amber',
|
|
38
|
+
accent: '#d97706',
|
|
39
|
+
accentHover: '#b45309',
|
|
40
|
+
accentSoft: 'rgba(217, 119, 6, 0.14)',
|
|
41
|
+
gradientTo: '#fbbf24',
|
|
42
|
+
},
|
|
43
|
+
rose: {
|
|
44
|
+
label: 'Rose',
|
|
45
|
+
accent: '#e11d48',
|
|
46
|
+
accentHover: '#be123c',
|
|
47
|
+
accentSoft: 'rgba(225, 29, 72, 0.12)',
|
|
48
|
+
gradientTo: '#fb7185',
|
|
49
|
+
},
|
|
50
|
+
cyan: {
|
|
51
|
+
label: 'Cyan',
|
|
52
|
+
accent: '#0891b2',
|
|
53
|
+
accentHover: '#0e7490',
|
|
54
|
+
accentSoft: 'rgba(8, 145, 178, 0.12)',
|
|
55
|
+
gradientTo: '#22d3ee',
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const SYSTEM_STACK = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
59
|
+
export const FONTS = {
|
|
60
|
+
default: {
|
|
61
|
+
label: 'Default (inherit host)',
|
|
62
|
+
body: 'inherit',
|
|
63
|
+
display: 'inherit',
|
|
64
|
+
},
|
|
65
|
+
system: { label: 'System', body: SYSTEM_STACK, display: SYSTEM_STACK },
|
|
66
|
+
dm: {
|
|
67
|
+
label: 'DM Sans + Space Grotesk',
|
|
68
|
+
body: "'DM Sans', sans-serif",
|
|
69
|
+
display: "'Space Grotesk', sans-serif",
|
|
70
|
+
href: 'https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600;9..40,700;9..40,800&family=Space+Grotesk:wght@400;500;600;700&display=swap',
|
|
71
|
+
},
|
|
72
|
+
inter: {
|
|
73
|
+
label: 'Inter',
|
|
74
|
+
body: "'Inter', sans-serif",
|
|
75
|
+
display: "'Inter', sans-serif",
|
|
76
|
+
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const VAR_ACCENT = '--slx-accent';
|
|
80
|
+
const VAR_ACCENT_HOVER = '--slx-accent-hover';
|
|
81
|
+
const VAR_ACCENT_SOFT = '--slx-accent-soft';
|
|
82
|
+
const VAR_ACCENT_2 = '--slx-accent-2';
|
|
83
|
+
function isBrowser() {
|
|
84
|
+
return typeof document !== 'undefined';
|
|
85
|
+
}
|
|
86
|
+
function loadFontHref(href) {
|
|
87
|
+
if (!isBrowser() || !href)
|
|
88
|
+
return;
|
|
89
|
+
if (document.querySelector(`link[href="${href}"]`))
|
|
90
|
+
return;
|
|
91
|
+
const link = document.createElement('link');
|
|
92
|
+
link.rel = 'stylesheet';
|
|
93
|
+
link.href = href;
|
|
94
|
+
document.head.appendChild(link);
|
|
95
|
+
}
|
|
96
|
+
function isAccentName(a) {
|
|
97
|
+
return typeof a === 'string' && a in ACCENTS;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Apply a theme. Targets `document.documentElement` by default — pass a
|
|
101
|
+
* container to scope the theme to one subtree (it gets `slyxup-root` added).
|
|
102
|
+
* Returns a cleanup function restoring previous values.
|
|
103
|
+
*/
|
|
104
|
+
export function applyTheme(theme, root) {
|
|
105
|
+
if (!isBrowser())
|
|
106
|
+
return () => { };
|
|
107
|
+
injectStyles();
|
|
108
|
+
const el = root ?? document.documentElement;
|
|
109
|
+
el.classList.add('slyxup-root');
|
|
110
|
+
const prev = {
|
|
111
|
+
mode: el.getAttribute('data-slyxup-theme'),
|
|
112
|
+
accent: el.getAttribute('data-slyxup-accent'),
|
|
113
|
+
primary: el.getAttribute('data-slyxup-primary'),
|
|
114
|
+
density: el.getAttribute('data-slyxup-density'),
|
|
115
|
+
vars: [
|
|
116
|
+
VAR_ACCENT,
|
|
117
|
+
VAR_ACCENT_HOVER,
|
|
118
|
+
VAR_ACCENT_SOFT,
|
|
119
|
+
VAR_ACCENT_2,
|
|
120
|
+
'--slx-font',
|
|
121
|
+
'--slx-display',
|
|
122
|
+
'--slx-mono',
|
|
123
|
+
'--slx-radius',
|
|
124
|
+
'--slx-radius-sm',
|
|
125
|
+
'--slx-radius-lg',
|
|
126
|
+
].map((v) => [v, el.style.getPropertyValue(v)]),
|
|
127
|
+
};
|
|
128
|
+
// ── Mode ──
|
|
129
|
+
if (theme.mode && theme.mode !== 'auto') {
|
|
130
|
+
el.setAttribute('data-slyxup-theme', theme.mode);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
el.removeAttribute('data-slyxup-theme');
|
|
134
|
+
}
|
|
135
|
+
// ── Accent ──
|
|
136
|
+
if (theme.accent !== undefined) {
|
|
137
|
+
if (isAccentName(theme.accent)) {
|
|
138
|
+
el.setAttribute('data-slyxup-accent', theme.accent);
|
|
139
|
+
el.style.removeProperty(VAR_ACCENT);
|
|
140
|
+
el.style.removeProperty(VAR_ACCENT_HOVER);
|
|
141
|
+
el.style.removeProperty(VAR_ACCENT_SOFT);
|
|
142
|
+
el.style.removeProperty(VAR_ACCENT_2);
|
|
143
|
+
}
|
|
144
|
+
else if (typeof theme.accent === 'string' && theme.accent.trim()) {
|
|
145
|
+
const hex = theme.accent.trim();
|
|
146
|
+
el.removeAttribute('data-slyxup-accent');
|
|
147
|
+
el.style.setProperty(VAR_ACCENT, hex);
|
|
148
|
+
el.style.setProperty(VAR_ACCENT_HOVER, hex);
|
|
149
|
+
el.style.setProperty(VAR_ACCENT_SOFT, `color-mix(in srgb, ${hex} 12%, transparent)`);
|
|
150
|
+
el.style.setProperty(VAR_ACCENT_2, hex);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ── Primary button style ──
|
|
154
|
+
if (theme.primary !== undefined) {
|
|
155
|
+
if (theme.primary === 'accent')
|
|
156
|
+
el.setAttribute('data-slyxup-primary', 'accent');
|
|
157
|
+
else
|
|
158
|
+
el.removeAttribute('data-slyxup-primary');
|
|
159
|
+
}
|
|
160
|
+
// ── Density ──
|
|
161
|
+
if (theme.density !== undefined) {
|
|
162
|
+
if (theme.density === 'compact')
|
|
163
|
+
el.setAttribute('data-slyxup-density', 'compact');
|
|
164
|
+
else
|
|
165
|
+
el.removeAttribute('data-slyxup-density');
|
|
166
|
+
}
|
|
167
|
+
// ── Font ──
|
|
168
|
+
if (theme.font !== undefined) {
|
|
169
|
+
const def = typeof theme.font === 'string'
|
|
170
|
+
? (FONTS[theme.font] ?? FONTS.default)
|
|
171
|
+
: theme.font;
|
|
172
|
+
if (def.href)
|
|
173
|
+
loadFontHref(def.href);
|
|
174
|
+
if (def.body)
|
|
175
|
+
el.style.setProperty('--slx-font', def.body);
|
|
176
|
+
if (def.display)
|
|
177
|
+
el.style.setProperty('--slx-display', def.display);
|
|
178
|
+
if (def.mono)
|
|
179
|
+
el.style.setProperty('--slx-mono', def.mono);
|
|
180
|
+
}
|
|
181
|
+
// ── Radius ──
|
|
182
|
+
if (typeof theme.radius === 'number' && Number.isFinite(theme.radius)) {
|
|
183
|
+
const r = Math.max(0, Math.min(24, theme.radius));
|
|
184
|
+
el.style.setProperty('--slx-radius', `${r}px`);
|
|
185
|
+
el.style.setProperty('--slx-radius-sm', `${Math.max(2, r - 2)}px`);
|
|
186
|
+
el.style.setProperty('--slx-radius-lg', `${r + 4}px`);
|
|
187
|
+
}
|
|
188
|
+
return () => {
|
|
189
|
+
if (prev.mode === null)
|
|
190
|
+
el.removeAttribute('data-slyxup-theme');
|
|
191
|
+
else
|
|
192
|
+
el.setAttribute('data-slyxup-theme', prev.mode);
|
|
193
|
+
if (prev.accent === null)
|
|
194
|
+
el.removeAttribute('data-slyxup-accent');
|
|
195
|
+
else
|
|
196
|
+
el.setAttribute('data-slyxup-accent', prev.accent);
|
|
197
|
+
if (prev.primary === null)
|
|
198
|
+
el.removeAttribute('data-slyxup-primary');
|
|
199
|
+
else
|
|
200
|
+
el.setAttribute('data-slyxup-primary', prev.primary);
|
|
201
|
+
if (prev.density === null)
|
|
202
|
+
el.removeAttribute('data-slyxup-density');
|
|
203
|
+
else
|
|
204
|
+
el.setAttribute('data-slyxup-density', prev.density);
|
|
205
|
+
for (const [v, val] of prev.vars) {
|
|
206
|
+
if (!val)
|
|
207
|
+
el.style.removeProperty(v);
|
|
208
|
+
else
|
|
209
|
+
el.style.setProperty(v, val);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/** Read the currently applied theme from an element (default: document root). */
|
|
214
|
+
export function getTheme(root) {
|
|
215
|
+
const fallback = {
|
|
216
|
+
mode: 'auto',
|
|
217
|
+
accent: 'violet',
|
|
218
|
+
primary: 'ink',
|
|
219
|
+
density: 'comfortable',
|
|
220
|
+
font: '',
|
|
221
|
+
radius: '',
|
|
222
|
+
};
|
|
223
|
+
if (!isBrowser())
|
|
224
|
+
return fallback;
|
|
225
|
+
const el = root ?? document.documentElement;
|
|
226
|
+
const cs = window.getComputedStyle(el);
|
|
227
|
+
return {
|
|
228
|
+
mode: el.getAttribute('data-slyxup-theme') || 'auto',
|
|
229
|
+
accent: el.getAttribute('data-slyxup-accent') ||
|
|
230
|
+
cs.getPropertyValue(VAR_ACCENT).trim() ||
|
|
231
|
+
'violet',
|
|
232
|
+
primary: el.getAttribute('data-slyxup-primary') || 'ink',
|
|
233
|
+
density: el.getAttribute('data-slyxup-density') || 'comfortable',
|
|
234
|
+
font: cs.getPropertyValue('--slx-font').trim(),
|
|
235
|
+
radius: cs.getPropertyValue('--slx-radius').trim(),
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=theme.js.map
|