ngwr 12.2.0 → 13.0.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 +11 -1
- package/border-glow/border-glow.scss +1 -1
- package/border-glow/styles/_index.scss +15 -233
- package/border-glow/styles/_rules.scss +228 -0
- package/breadcrumbs/breadcrumbs.scss +1 -1
- package/breadcrumbs/styles/_index.scss +15 -78
- package/breadcrumbs/styles/_rules.scss +84 -0
- package/card/card.scss +1 -1
- package/card/styles/_index.scss +15 -96
- package/card/styles/_rules.scss +96 -0
- package/cascader/cascader.scss +1 -1
- package/cascader/styles/_index.scss +15 -244
- package/cascader/styles/_rules.scss +261 -0
- package/checkbox/styles/_index.scss +7 -0
- package/circular-text/circular-text.scss +1 -1
- package/circular-text/styles/_index.scss +15 -63
- package/circular-text/styles/_rules.scss +58 -0
- package/color-picker/styles/_index.scss +8 -0
- package/drag-drop/sortable-list.scss +1 -1
- package/drag-drop/styles/_index.scss +14 -143
- package/drag-drop/styles/_rules.scss +151 -0
- package/falling-text/falling-text.scss +1 -1
- package/falling-text/styles/_index.scss +15 -36
- package/falling-text/styles/_rules.scss +31 -0
- package/fesm2022/ngwr-border-glow.mjs +2 -2
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +2 -2
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +27 -9
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +86 -8
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +2 -2
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +57 -7
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +8 -0
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +2 -2
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +2 -2
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +29 -8
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +48 -1
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +2 -2
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +2 -2
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +41 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +17 -2
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +2 -2
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +2 -2
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +2 -2
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +2 -2
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +1 -1
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +63 -8
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +17 -2
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +22 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +46 -12
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +2 -2
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +21 -6
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +2 -2
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +2 -2
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +44 -4
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +1 -1
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +5 -2
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +41 -1
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +2 -2
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +38 -6
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +33 -7
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +2 -2
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +2 -2
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +2 -2
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/file-upload/styles/_index.scss +6 -0
- package/glitch-text/glitch-text.scss +1 -1
- package/glitch-text/styles/_index.scss +14 -164
- package/glitch-text/styles/_rules.scss +160 -0
- package/gradient-text/gradient-text.scss +1 -1
- package/gradient-text/styles/_index.scss +15 -118
- package/gradient-text/styles/_rules.scss +113 -0
- package/input/styles/_index.scss +13 -0
- package/input-otp/styles/_index.scss +8 -0
- package/lightbox/lightbox.scss +1 -1
- package/lightbox/styles/_index.scss +15 -191
- package/lightbox/styles/_rules.scss +198 -0
- package/list/list.scss +1 -1
- package/list/styles/_index.scss +15 -101
- package/list/styles/_rules.scss +108 -0
- package/llms-full.txt +3 -3
- package/loading-bar/loading-bar.scss +1 -1
- package/loading-bar/styles/_index.scss +15 -33
- package/loading-bar/styles/_rules.scss +28 -0
- package/marquee/marquee.scss +1 -1
- package/marquee/styles/_index.scss +15 -155
- package/marquee/styles/_rules.scss +150 -0
- package/package.json +1 -1
- package/segmented/styles/_index.scss +8 -0
- package/select/styles/_index.scss +17 -1
- package/shiny-text/shiny-text.scss +1 -1
- package/shiny-text/styles/_index.scss +14 -105
- package/shiny-text/styles/_rules.scss +101 -0
- package/slider/styles/_index.scss +8 -0
- package/spotlight-card/spotlight-card.scss +1 -1
- package/spotlight-card/styles/_index.scss +15 -52
- package/spotlight-card/styles/_rules.scss +47 -0
- package/star-border/star-border.scss +1 -1
- package/star-border/styles/_index.scss +15 -125
- package/star-border/styles/_rules.scss +120 -0
- package/switch/styles/_index.scss +7 -0
- package/theme/styles/_dark.scss +81 -4
- package/theme/styles/_index.scss +1 -0
- package/theme/styles/_motion.scss +94 -0
- package/tilt-card/styles/_index.scss +15 -45
- package/tilt-card/styles/_rules.scss +40 -0
- package/tilt-card/tilt-card.scss +1 -1
- package/tree/styles/_index.scss +15 -1
- package/types/ngwr-cascader.d.ts +17 -1
- package/types/ngwr-checkbox.d.ts +51 -3
- package/types/ngwr-color-picker.d.ts +19 -1
- package/types/ngwr-file-upload.d.ts +18 -1
- package/types/ngwr-form.d.ts +51 -2
- package/types/ngwr-input-otp.d.ts +23 -1
- package/types/ngwr-knob.d.ts +14 -0
- package/types/ngwr-radio.d.ts +37 -2
- package/types/ngwr-rating.d.ts +14 -0
- package/types/ngwr-segmented.d.ts +18 -1
- package/types/ngwr-select.d.ts +17 -1
- package/types/ngwr-slider.d.ts +14 -1
- package/types/ngwr-switch.d.ts +26 -2
- package/types/ngwr-textarea.d.ts +3 -0
- package/types/ngwr-theme.d.ts +24 -0
- package/types/ngwr-transfer.d.ts +17 -1
- package/types/ngwr-tree.d.ts +21 -1
- package/types/ngwr-version.d.ts +1 -1
- package/typewriter/styles/_index.scss +15 -38
- package/typewriter/styles/_rules.scss +33 -0
- package/typewriter/typewriter.scss +1 -1
- package/virtual-scroll/styles/_index.scss +15 -32
- package/virtual-scroll/styles/_rules.scss +27 -0
- package/virtual-scroll/virtual-scroll.scss +1 -1
- package/waves/styles/_index.scss +15 -50
- package/waves/styles/_rules.scss +45 -0
- package/waves/waves.scss +1 -1
|
@@ -85,6 +85,14 @@
|
|
|
85
85
|
font-variant-numeric: tabular-nums;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// A read-only slider still takes focus and still announces its value, so it
|
|
89
|
+
// keeps the visual and only stops inviting the drag — `grab` on something that
|
|
90
|
+
// cannot move is the part that looks broken. Matches `wr-knob--readonly`.
|
|
91
|
+
&--readonly &__track,
|
|
92
|
+
&--readonly &__thumb {
|
|
93
|
+
cursor: default;
|
|
94
|
+
}
|
|
95
|
+
|
|
88
96
|
&--disabled {
|
|
89
97
|
--wr-slider-thumb-border: var(--wr-color-on-surface-muted);
|
|
90
98
|
--wr-slider-fill: var(--wr-color-on-surface-muted);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@forward './styles';
|
|
1
|
+
@forward './styles/rules';
|
|
@@ -1,52 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// the theme
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), 0.15);
|
|
17
|
-
|
|
18
|
-
position: relative;
|
|
19
|
-
display: block;
|
|
20
|
-
border-radius: 1.5rem;
|
|
21
|
-
border: 1px solid var(--wr-color-outline);
|
|
22
|
-
background-color: var(--wr-color-surface);
|
|
23
|
-
padding: 2rem;
|
|
24
|
-
overflow: hidden;
|
|
25
|
-
color: var(--wr-color-on-surface);
|
|
26
|
-
|
|
27
|
-
&::before {
|
|
28
|
-
content: '';
|
|
29
|
-
position: absolute;
|
|
30
|
-
inset: 0;
|
|
31
|
-
background: radial-gradient(
|
|
32
|
-
circle at var(--wr-spotlight-x) var(--wr-spotlight-y),
|
|
33
|
-
var(--wr-spotlight-color),
|
|
34
|
-
transparent var(--wr-spotlight-radius, 80%)
|
|
35
|
-
);
|
|
36
|
-
opacity: 0;
|
|
37
|
-
transition: opacity 0.5s ease;
|
|
38
|
-
pointer-events: none;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
&:hover::before,
|
|
42
|
-
&:focus-within::before {
|
|
43
|
-
opacity: 0.6;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Dark mode: `--wr-color-on-surface-rgb` already flips to a light value, so the
|
|
48
|
-
// default tint above becomes a light beam on the navy surface — nudge the
|
|
49
|
-
// alpha up a touch so it reads as bright as the classic spotlight.
|
|
50
|
-
[data-theme='dark'] .wr-spotlight-card {
|
|
51
|
-
--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), 0.22);
|
|
52
|
-
}
|
|
1
|
+
// Public Sass entry for `@use 'ngwr/spotlight-card'`.
|
|
2
|
+
//
|
|
3
|
+
// Pulls the whole theme so a standalone import still brings in every design
|
|
4
|
+
// token these rules reference, then loads the rules themselves from `_rules`.
|
|
5
|
+
//
|
|
6
|
+
// The split is what keeps the token layer out of the JavaScript bundle.
|
|
7
|
+
// `spotlight-card.scss` is the component's `styleUrl`, and a component stylesheet is
|
|
8
|
+
// its OWN Sass compilation — `@use` only deduplicates within one. So while the
|
|
9
|
+
// umbrella sheet emits the theme once, forwarding it from here would inline a
|
|
10
|
+
// second, byte-identical copy of `:root`, `[data-theme='dark']` and the
|
|
11
|
+
// box-sizing reset into the compiled component styles, which ng-packagr then
|
|
12
|
+
// embeds in the FESM bundle as a string. `spotlight-card.scss` forwards `_rules`
|
|
13
|
+
// instead, so it carries this component's own CSS and nothing else.
|
|
14
|
+
@use '../../theme/styles';
|
|
15
|
+
@forward 'rules';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Cursor-tracked spotlight card (reactbits port). The `--wr-spotlight-x/y`
|
|
2
|
+
// vars come from the host's mousemove handler; `--wr-spotlight-color` is
|
|
3
|
+
// set inline from the `[spotlightColor]` input when provided — otherwise
|
|
4
|
+
// the theme picks the default below. `--wr-color-on-surface-rgb` flips between
|
|
5
|
+
// themes (dark on light surfaces, light on dark), so a single tint reads
|
|
6
|
+
// as a dark-ish glow in light mode and a light beam in dark mode.
|
|
7
|
+
|
|
8
|
+
.wr-spotlight-card {
|
|
9
|
+
--wr-spotlight-x: 50%;
|
|
10
|
+
--wr-spotlight-y: 50%;
|
|
11
|
+
--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), 0.15);
|
|
12
|
+
|
|
13
|
+
position: relative;
|
|
14
|
+
display: block;
|
|
15
|
+
border-radius: 1.5rem;
|
|
16
|
+
border: 1px solid var(--wr-color-outline);
|
|
17
|
+
background-color: var(--wr-color-surface);
|
|
18
|
+
padding: 2rem;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
color: var(--wr-color-on-surface);
|
|
21
|
+
|
|
22
|
+
&::before {
|
|
23
|
+
content: '';
|
|
24
|
+
position: absolute;
|
|
25
|
+
inset: 0;
|
|
26
|
+
background: radial-gradient(
|
|
27
|
+
circle at var(--wr-spotlight-x) var(--wr-spotlight-y),
|
|
28
|
+
var(--wr-spotlight-color),
|
|
29
|
+
transparent var(--wr-spotlight-radius, 80%)
|
|
30
|
+
);
|
|
31
|
+
opacity: 0;
|
|
32
|
+
transition: opacity 0.5s ease;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:hover::before,
|
|
37
|
+
&:focus-within::before {
|
|
38
|
+
opacity: 0.6;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Dark mode: `--wr-color-on-surface-rgb` already flips to a light value, so the
|
|
43
|
+
// default tint above becomes a light beam on the navy surface — nudge the
|
|
44
|
+
// alpha up a touch so it reads as bright as the classic spotlight.
|
|
45
|
+
[data-theme='dark'] .wr-spotlight-card {
|
|
46
|
+
--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), 0.22);
|
|
47
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@forward './styles';
|
|
1
|
+
@forward './styles/rules';
|
|
@@ -1,125 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
--wr-star-border-speed: 6s;
|
|
17
|
-
--wr-star-border-radius: 20px;
|
|
18
|
-
--wr-star-border-stop: 16%;
|
|
19
|
-
--wr-star-border-opacity: 1;
|
|
20
|
-
|
|
21
|
-
display: inline-block;
|
|
22
|
-
position: relative;
|
|
23
|
-
border: 0;
|
|
24
|
-
background: transparent;
|
|
25
|
-
border-radius: var(--wr-star-border-radius);
|
|
26
|
-
overflow: hidden;
|
|
27
|
-
cursor: inherit;
|
|
28
|
-
|
|
29
|
-
&__ray {
|
|
30
|
-
position: absolute;
|
|
31
|
-
display: block;
|
|
32
|
-
width: 300%;
|
|
33
|
-
height: 50%;
|
|
34
|
-
opacity: var(--wr-star-border-opacity);
|
|
35
|
-
border-radius: 50%;
|
|
36
|
-
background: radial-gradient(circle, var(--wr-star-border-color), transparent var(--wr-star-border-stop));
|
|
37
|
-
animation: wr-star-border-bottom var(--wr-star-border-speed) linear infinite alternate;
|
|
38
|
-
z-index: 0;
|
|
39
|
-
|
|
40
|
-
&--bottom {
|
|
41
|
-
bottom: -12px;
|
|
42
|
-
// rtl-ok: the comet's off-screen start mark — `wr-star-border-bottom` sweeps it by `translate(-100%, 0%)`
|
|
43
|
-
right: -250%;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
&--top {
|
|
47
|
-
top: -12px;
|
|
48
|
-
// rtl-ok: the comet's off-screen start mark — `wr-star-border-top` sweeps it by `translate(100%, 0%)`
|
|
49
|
-
left: -250%;
|
|
50
|
-
animation-name: wr-star-border-top;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Single-ray variant — drop the top comet.
|
|
55
|
-
&--single &__ray--top {
|
|
56
|
-
display: none;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Hover-only variant — rays sit hidden until the pointer is in. The
|
|
60
|
-
// idle state must drop the animation entirely (not pause it): a paused
|
|
61
|
-
// animation pins `opacity` at its 0% keyframe value, which beats the
|
|
62
|
-
// cascade and leaves a frozen comet visible.
|
|
63
|
-
&--hover &__ray {
|
|
64
|
-
opacity: 0;
|
|
65
|
-
animation: none;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
&--hover:hover &__ray {
|
|
69
|
-
animation: wr-star-border-bottom var(--wr-star-border-speed) linear infinite alternate;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
&--hover:hover &__ray--top {
|
|
73
|
-
animation-name: wr-star-border-top;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
&__inner {
|
|
77
|
-
position: relative;
|
|
78
|
-
display: block;
|
|
79
|
-
border: 1px solid var(--wr-color-outline);
|
|
80
|
-
background: var(--wr-color-surface);
|
|
81
|
-
color: var(--wr-color-on-surface);
|
|
82
|
-
font-size: 1rem;
|
|
83
|
-
text-align: center;
|
|
84
|
-
padding: 1rem 1.625rem;
|
|
85
|
-
border-radius: var(--wr-star-border-radius);
|
|
86
|
-
z-index: 1;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
[data-theme='dark'] .wr-star-border {
|
|
91
|
-
--wr-star-border-color: #ffffff;
|
|
92
|
-
--wr-star-border-stop: 10%;
|
|
93
|
-
--wr-star-border-opacity: 0.7;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
@keyframes wr-star-border-bottom {
|
|
97
|
-
0% {
|
|
98
|
-
transform: translate(0%, 0%);
|
|
99
|
-
opacity: 1;
|
|
100
|
-
}
|
|
101
|
-
100% {
|
|
102
|
-
transform: translate(-100%, 0%);
|
|
103
|
-
opacity: 0;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@keyframes wr-star-border-top {
|
|
108
|
-
0% {
|
|
109
|
-
transform: translate(0%, 0%);
|
|
110
|
-
opacity: 1;
|
|
111
|
-
}
|
|
112
|
-
100% {
|
|
113
|
-
transform: translate(100%, 0%);
|
|
114
|
-
opacity: 0;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Reduced motion: no sweeping comets — a frozen ray reads as a smudge,
|
|
119
|
-
// so hide them and keep the panel border as the resting look.
|
|
120
|
-
@media (prefers-reduced-motion: reduce) {
|
|
121
|
-
.wr-star-border__ray {
|
|
122
|
-
animation: none !important;
|
|
123
|
-
opacity: 0 !important;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
1
|
+
// Public Sass entry for `@use 'ngwr/star-border'`.
|
|
2
|
+
//
|
|
3
|
+
// Pulls the whole theme so a standalone import still brings in every design
|
|
4
|
+
// token these rules reference, then loads the rules themselves from `_rules`.
|
|
5
|
+
//
|
|
6
|
+
// The split is what keeps the token layer out of the JavaScript bundle.
|
|
7
|
+
// `star-border.scss` is the component's `styleUrl`, and a component stylesheet is
|
|
8
|
+
// its OWN Sass compilation — `@use` only deduplicates within one. So while the
|
|
9
|
+
// umbrella sheet emits the theme once, forwarding it from here would inline a
|
|
10
|
+
// second, byte-identical copy of `:root`, `[data-theme='dark']` and the
|
|
11
|
+
// box-sizing reset into the compiled component styles, which ng-packagr then
|
|
12
|
+
// embeds in the FESM bundle as a string. `star-border.scss` forwards `_rules`
|
|
13
|
+
// instead, so it carries this component's own CSS and nothing else.
|
|
14
|
+
@use '../../theme/styles';
|
|
15
|
+
@forward 'rules';
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Star border (reactbits port). Two oversized radial-gradient "comets"
|
|
2
|
+
// sweep along the top and bottom edges of the rounded container; the
|
|
3
|
+
// projected content sits on a token-themed inner panel above them.
|
|
4
|
+
|
|
5
|
+
.wr-star-border {
|
|
6
|
+
// Light surfaces get a primary comet; dark theme flips to the classic
|
|
7
|
+
// white (see block below). `[color]` overrides both inline. The light
|
|
8
|
+
// comet gets a wider core + full opacity — a thin 10% tail washes out
|
|
9
|
+
// to gray on white surfaces.
|
|
10
|
+
--wr-star-border-color: var(--wr-color-primary);
|
|
11
|
+
--wr-star-border-speed: 6s;
|
|
12
|
+
--wr-star-border-radius: 20px;
|
|
13
|
+
--wr-star-border-stop: 16%;
|
|
14
|
+
--wr-star-border-opacity: 1;
|
|
15
|
+
|
|
16
|
+
display: inline-block;
|
|
17
|
+
position: relative;
|
|
18
|
+
border: 0;
|
|
19
|
+
background: transparent;
|
|
20
|
+
border-radius: var(--wr-star-border-radius);
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
cursor: inherit;
|
|
23
|
+
|
|
24
|
+
&__ray {
|
|
25
|
+
position: absolute;
|
|
26
|
+
display: block;
|
|
27
|
+
width: 300%;
|
|
28
|
+
height: 50%;
|
|
29
|
+
opacity: var(--wr-star-border-opacity);
|
|
30
|
+
border-radius: 50%;
|
|
31
|
+
background: radial-gradient(circle, var(--wr-star-border-color), transparent var(--wr-star-border-stop));
|
|
32
|
+
animation: wr-star-border-bottom var(--wr-star-border-speed) linear infinite alternate;
|
|
33
|
+
z-index: 0;
|
|
34
|
+
|
|
35
|
+
&--bottom {
|
|
36
|
+
bottom: -12px;
|
|
37
|
+
// rtl-ok: the comet's off-screen start mark — `wr-star-border-bottom` sweeps it by `translate(-100%, 0%)`
|
|
38
|
+
right: -250%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&--top {
|
|
42
|
+
top: -12px;
|
|
43
|
+
// rtl-ok: the comet's off-screen start mark — `wr-star-border-top` sweeps it by `translate(100%, 0%)`
|
|
44
|
+
left: -250%;
|
|
45
|
+
animation-name: wr-star-border-top;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Single-ray variant — drop the top comet.
|
|
50
|
+
&--single &__ray--top {
|
|
51
|
+
display: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Hover-only variant — rays sit hidden until the pointer is in. The
|
|
55
|
+
// idle state must drop the animation entirely (not pause it): a paused
|
|
56
|
+
// animation pins `opacity` at its 0% keyframe value, which beats the
|
|
57
|
+
// cascade and leaves a frozen comet visible.
|
|
58
|
+
&--hover &__ray {
|
|
59
|
+
opacity: 0;
|
|
60
|
+
animation: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&--hover:hover &__ray {
|
|
64
|
+
animation: wr-star-border-bottom var(--wr-star-border-speed) linear infinite alternate;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&--hover:hover &__ray--top {
|
|
68
|
+
animation-name: wr-star-border-top;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&__inner {
|
|
72
|
+
position: relative;
|
|
73
|
+
display: block;
|
|
74
|
+
border: 1px solid var(--wr-color-outline);
|
|
75
|
+
background: var(--wr-color-surface);
|
|
76
|
+
color: var(--wr-color-on-surface);
|
|
77
|
+
font-size: 1rem;
|
|
78
|
+
text-align: center;
|
|
79
|
+
padding: 1rem 1.625rem;
|
|
80
|
+
border-radius: var(--wr-star-border-radius);
|
|
81
|
+
z-index: 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
[data-theme='dark'] .wr-star-border {
|
|
86
|
+
--wr-star-border-color: #ffffff;
|
|
87
|
+
--wr-star-border-stop: 10%;
|
|
88
|
+
--wr-star-border-opacity: 0.7;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@keyframes wr-star-border-bottom {
|
|
92
|
+
0% {
|
|
93
|
+
transform: translate(0%, 0%);
|
|
94
|
+
opacity: 1;
|
|
95
|
+
}
|
|
96
|
+
100% {
|
|
97
|
+
transform: translate(-100%, 0%);
|
|
98
|
+
opacity: 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@keyframes wr-star-border-top {
|
|
103
|
+
0% {
|
|
104
|
+
transform: translate(0%, 0%);
|
|
105
|
+
opacity: 1;
|
|
106
|
+
}
|
|
107
|
+
100% {
|
|
108
|
+
transform: translate(100%, 0%);
|
|
109
|
+
opacity: 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Reduced motion: no sweeping comets — a frozen ray reads as a smudge,
|
|
114
|
+
// so hide them and keep the panel border as the resting look.
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.wr-star-border__ray {
|
|
117
|
+
animation: none !important;
|
|
118
|
+
opacity: 0 !important;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -95,6 +95,13 @@
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// A read-only switch still takes focus and still submits its value, so it
|
|
99
|
+
// keeps the full visual and only stops inviting the click — dimming it would
|
|
100
|
+
// say "disabled", which is the other state.
|
|
101
|
+
&--readonly &__label {
|
|
102
|
+
cursor: default;
|
|
103
|
+
}
|
|
104
|
+
|
|
98
105
|
&--disabled {
|
|
99
106
|
--wr-switch-color: var(--wr-color-on-surface-muted);
|
|
100
107
|
pointer-events: none;
|
package/theme/styles/_dark.scss
CHANGED
|
@@ -3,13 +3,90 @@
|
|
|
3
3
|
@use 'colors';
|
|
4
4
|
@use 'variables';
|
|
5
5
|
|
|
6
|
-
// Dark theme overrides — opt-in via `[data-theme="dark"]` on <html
|
|
7
|
-
// Drive the toggle from
|
|
8
|
-
// `provideWrTheme(...)`).
|
|
6
|
+
// Dark theme overrides — opt-in via `[data-theme="dark"]` on <html>, or
|
|
7
|
+
// whatever `$theme-attribute` below is configured to. Drive the toggle from
|
|
8
|
+
// `WrTheme` (provided automatically with `provideWrTheme(...)`).
|
|
9
9
|
//
|
|
10
10
|
// Only semantic tokens flip — palette hues stay so brand-coloured
|
|
11
11
|
// elements look the same regardless of theme.
|
|
12
12
|
|
|
13
|
+
/// The attribute the dark block keys on. Must match the `attribute` passed to
|
|
14
|
+
/// `provideWrTheme(...)`, and that pairing is the whole reason this variable
|
|
15
|
+
/// exists: `WrThemeConfig.attribute` is a RUNTIME value, and no CSS selector can
|
|
16
|
+
/// read one. Until v13 the selector below was the literal `[data-theme='dark']`,
|
|
17
|
+
/// so an app that set `provideWrTheme({ attribute: 'data-color-mode' })` got a
|
|
18
|
+
/// service reporting `resolved() === 'dark'`, the attribute written correctly
|
|
19
|
+
/// onto `<html>`, and a page that stayed light forever — no error, no warning.
|
|
20
|
+
///
|
|
21
|
+
/// Configure the two together:
|
|
22
|
+
///
|
|
23
|
+
/// ```scss
|
|
24
|
+
/// // styles.scss
|
|
25
|
+
/// @use 'ngwr' with ($theme-attribute: 'data-color-mode');
|
|
26
|
+
/// ```
|
|
27
|
+
/// ```ts
|
|
28
|
+
/// provideWrTheme({ attribute: 'data-color-mode' })
|
|
29
|
+
/// ```
|
|
30
|
+
///
|
|
31
|
+
/// Only the configured attribute is emitted — the default is NOT kept as a
|
|
32
|
+
/// second selector. Renaming it is what decouples ngwr from another design
|
|
33
|
+
/// system that already owns `data-theme`, and emitting both would re-couple
|
|
34
|
+
/// them: that system's own `data-theme="dark"` would flip ngwr's tokens behind
|
|
35
|
+
/// the app's back, which is the exact collision the rename exists to avoid.
|
|
36
|
+
///
|
|
37
|
+
/// If the two disagree the page silently stays light, so `WrTheme` publishes a
|
|
38
|
+
/// dev-mode check for it: the light block below writes the configured name into
|
|
39
|
+
/// `--wr-theme-attribute`, and the service warns when what it reads there is not
|
|
40
|
+
/// what it was configured with. A stylesheet that is missing or predates v13
|
|
41
|
+
/// leaves the property empty and the check stays quiet — it can only fire on a
|
|
42
|
+
/// real disagreement.
|
|
43
|
+
$theme-attribute: 'data-theme' !default;
|
|
44
|
+
|
|
45
|
+
/// The dark-theme selector, for a stylesheet that has to build its own.
|
|
46
|
+
///
|
|
47
|
+
/// @example scss
|
|
48
|
+
/// #{dark.dark-selector()} .my-thing { ... }
|
|
49
|
+
@function dark-selector() {
|
|
50
|
+
@return '[#{$theme-attribute}=\'dark\']';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Wrap a declaration block so it only applies in dark mode, honouring
|
|
54
|
+
/// `$theme-attribute`. Prefer this over writing `[data-theme='dark']` by hand —
|
|
55
|
+
/// a hand-written literal is exactly what BUG-3 was.
|
|
56
|
+
///
|
|
57
|
+
/// @example scss
|
|
58
|
+
/// @use 'ngwr/theme' as theme;
|
|
59
|
+
///
|
|
60
|
+
/// .my-card {
|
|
61
|
+
/// background: #fff;
|
|
62
|
+
///
|
|
63
|
+
/// @include theme.dark {
|
|
64
|
+
/// background: #0b1120;
|
|
65
|
+
/// }
|
|
66
|
+
/// }
|
|
67
|
+
@mixin dark() {
|
|
68
|
+
@if & {
|
|
69
|
+
@at-root #{dark-selector()} #{&} {
|
|
70
|
+
@content;
|
|
71
|
+
}
|
|
72
|
+
} @else {
|
|
73
|
+
#{dark-selector()} {
|
|
74
|
+
@content;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
:root {
|
|
80
|
+
// The attribute this compiled stylesheet keys its dark block on, published so
|
|
81
|
+
// `WrTheme` can compare it against `WrThemeConfig.attribute` in dev mode and
|
|
82
|
+
// say so when the two were configured apart. Read with
|
|
83
|
+
// `getPropertyValue('--wr-theme-attribute')`, never with `var()`.
|
|
84
|
+
//
|
|
85
|
+
// unused-ok: read by `WrTheme` through the CSSOM rather than painted with —
|
|
86
|
+
// it carries a name, not a value, so no declaration can reference it.
|
|
87
|
+
--wr-theme-attribute: #{$theme-attribute};
|
|
88
|
+
}
|
|
89
|
+
|
|
13
90
|
// Intents re-tuned for the dark canvas. Looped (below) so each gets the
|
|
14
91
|
// FULL symmetric shade set — the hand blocks used to ship only base+rgb,
|
|
15
92
|
// leaving -light/-dark/-lighter/-darker baked from the LIGHT palette.
|
|
@@ -37,7 +114,7 @@ $_light: #262f44;
|
|
|
37
114
|
$_medium: #6d7682;
|
|
38
115
|
$_dark: #e6ebf3;
|
|
39
116
|
|
|
40
|
-
|
|
117
|
+
#{dark-selector()} {
|
|
41
118
|
// Canvas (was `--wr-color-white` in light mode)
|
|
42
119
|
// Deeper than slate-900 so an elevated surface in slate-800 reads
|
|
43
120
|
// as a real layer rather than vanishing into the background.
|
package/theme/styles/_index.scss
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// `prefers-reduced-motion` for the always-on chrome.
|
|
2
|
+
//
|
|
3
|
+
// Why this lives in the theme layer rather than in each component. The
|
|
4
|
+
// animation catalogue (`ngwr/glitch-text`, `ngwr/gradient-text`, …) guards
|
|
5
|
+
// itself, component by component — those are opt-in effects, and each one knows
|
|
6
|
+
// what its own stillness should look like. The ten blocks below are the
|
|
7
|
+
// opposite: chrome nobody opted into. A spinner and a skeleton animate on
|
|
8
|
+
// essentially every page of every app, and four of the animations here never
|
|
9
|
+
// stop at all (`wr-spinner-rotate`, `wr-spinner-dash`, `wr-skeleton-shimmer`,
|
|
10
|
+
// `wr-card-spin`, `wr-lightbox-shimmer`), which is the case vestibular guidance
|
|
11
|
+
// is most emphatic about. Collecting them in one place is what makes the set
|
|
12
|
+
// reviewable — the gap this closes existed because nine separate stylesheets
|
|
13
|
+
// each forgot, and nine separate stylesheets can each forget again.
|
|
14
|
+
//
|
|
15
|
+
// **Every declaration here is `!important`, and that is structural rather than
|
|
16
|
+
// lazy.** The theme layer is loaded first — `styles.scss` forwards it before any
|
|
17
|
+
// component, and a standalone `@use 'ngwr/spinner'` pulls it in ahead of the
|
|
18
|
+
// spinner's own rules — so at equal specificity the component always wins on
|
|
19
|
+
// source order. `!important` is the only lever a stylesheet that must come first
|
|
20
|
+
// has. `.wr-overlay-sheet` needs one more: its animation is itself `!important`
|
|
21
|
+
// (it has to beat four components' panel sizing), so the class is doubled here
|
|
22
|
+
// to out-specify it.
|
|
23
|
+
//
|
|
24
|
+
// What reduced motion MEANS is decided per animation, not globally:
|
|
25
|
+
//
|
|
26
|
+
// - An ENTER animation is removed. The panel still arrives, it just does not
|
|
27
|
+
// travel to get there. Every keyframe set below animates from a transparent,
|
|
28
|
+
// offset or scaled-down state TO the element's resting one, with no
|
|
29
|
+
// `forwards`, so removing it lands on exactly the frame the animation was
|
|
30
|
+
// heading for. Nothing in the library waits on `animationend`, so nothing
|
|
31
|
+
// is left un-dismissed.
|
|
32
|
+
// - A decorative INFINITE loop is removed outright — a skeleton's shimmer and
|
|
33
|
+
// a lightbox's shimmer say nothing the static placeholder does not.
|
|
34
|
+
// - A SPINNER is slowed, not stopped. Its rotation IS the message: a frozen
|
|
35
|
+
// spinner does not read as "reduced motion", it reads as "hung". So the
|
|
36
|
+
// rotation stays at half speed and the pulsing arc — the part that carries
|
|
37
|
+
// no information — is frozen at a fixed sweep. Same call Bootstrap makes,
|
|
38
|
+
// and the same reading as WCAG 2.3.3, which is about non-essential motion.
|
|
39
|
+
// - The TOAST progress bar is deliberately left alone. It is a countdown: it
|
|
40
|
+
// is the only thing on screen saying how long is left before the toast
|
|
41
|
+
// leaves, and freezing it would not remove information, it would state a
|
|
42
|
+
// falsehood — a full bar that never drains. It is also 2px tall and moves
|
|
43
|
+
// along one axis at constant speed, the mildest shape motion sensitivity
|
|
44
|
+
// takes. If that trade is ever revisited, revisit it here.
|
|
45
|
+
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
// Overlay enter choreography — dialog, dropdown, popconfirm, toast, lightbox
|
|
48
|
+
// viewer, and all four drawer edges.
|
|
49
|
+
.wr-dialog-panel,
|
|
50
|
+
.wr-dropdown-menu,
|
|
51
|
+
.wr-popconfirm-overlay > .wr-popconfirm,
|
|
52
|
+
.wr-toast,
|
|
53
|
+
.wr-lightbox-viewer,
|
|
54
|
+
.wr-drawer__panel--left,
|
|
55
|
+
.wr-drawer__panel--right,
|
|
56
|
+
.wr-drawer__panel--top,
|
|
57
|
+
.wr-drawer__panel--bottom {
|
|
58
|
+
animation: none !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The responsive bottom sheet, which slides a full panel height up the
|
|
62
|
+
// screen — the largest single translation the library performs. Doubled
|
|
63
|
+
// class: `overlay/styles/_index.scss` sets this animation `!important`, and it
|
|
64
|
+
// is loaded after this file.
|
|
65
|
+
.wr-overlay-sheet.wr-overlay-sheet {
|
|
66
|
+
animation: none !important;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Decorative loading shimmers. Both ride a pseudo-element whose resting
|
|
70
|
+
// position is off-screen or at its gradient origin, so stopping them leaves a
|
|
71
|
+
// plain tinted placeholder rather than a half-drawn band.
|
|
72
|
+
.wr-skeleton--animated::after,
|
|
73
|
+
.wr-lightbox--loading::after {
|
|
74
|
+
animation: none !important;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Spinners. The rotation survives at half speed; the arc stops pulsing and
|
|
78
|
+
// holds the sweep the dash animation spends most of its cycle at, so the
|
|
79
|
+
// shape stays a recognisable spinner instead of collapsing to the 1-unit dot
|
|
80
|
+
// its first keyframe starts from.
|
|
81
|
+
.wr-spinner svg {
|
|
82
|
+
animation-duration: 4s !important;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.wr-spinner__path {
|
|
86
|
+
animation: none !important;
|
|
87
|
+
stroke-dasharray: 90, 150 !important;
|
|
88
|
+
stroke-dashoffset: 0 !important;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.wr-card__spinner {
|
|
92
|
+
animation-duration: 1.4s !important;
|
|
93
|
+
}
|
|
94
|
+
}
|