ngwr 12.0.0 → 12.2.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 +79 -20
- package/alert/styles/_index.scss +11 -4
- package/badge/styles/_index.scss +30 -0
- package/badge/styles/_tag.scss +15 -1
- package/descriptions/styles/_index.scss +13 -3
- package/drawer/styles/_index.scss +95 -1
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs +3 -3
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-badge.mjs +6 -6
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs +3 -3
- package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-button.mjs +6 -6
- package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-cascader.mjs +3 -3
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-circular-text.mjs +3 -3
- package/fesm2022/ngwr-click-spark.mjs +3 -3
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-picker.mjs +18 -18
- package/fesm2022/ngwr-date.mjs +3 -3
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-donut-chart.mjs +3 -3
- package/fesm2022/ngwr-drag-drop.mjs +6 -6
- package/fesm2022/ngwr-drawer.mjs +24 -18
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-dropdown.mjs +9 -9
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-falling-text.mjs +3 -3
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-form.mjs +9 -9
- package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input.mjs +15 -15
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-lightbox.mjs +3 -3
- package/fesm2022/ngwr-line-chart.mjs +3 -3
- package/fesm2022/ngwr-list.mjs +6 -6
- package/fesm2022/ngwr-loading-bar.mjs +6 -6
- package/fesm2022/ngwr-markdown.mjs +6 -6
- package/fesm2022/ngwr-marquee.mjs +3 -3
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs +72 -9
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popover.mjs +6 -6
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs +3 -3
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-rating.mjs +3 -3
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-segmented-testing.mjs +71 -0
- package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +98 -8
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +22 -12
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +6 -6
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs +3 -3
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-spotlight-card.mjs +6 -6
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-star-border.mjs +3 -3
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-storage.mjs +3 -3
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-textarea.mjs +3 -3
- package/fesm2022/ngwr-theme.mjs +3 -3
- package/fesm2022/ngwr-tilt-card.mjs +6 -6
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-toast.mjs +9 -9
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs +3 -3
- package/fesm2022/ngwr-typewriter.mjs +3 -3
- package/fesm2022/ngwr-typography.mjs +3 -3
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs +3 -3
- package/fesm2022/ngwr-window.mjs +12 -12
- package/llms-full.txt +1 -1
- package/llms.txt +24 -2
- package/overlay/styles/_arrow.scss +243 -0
- package/package.json +1 -1
- package/popconfirm/styles/_index.scss +17 -0
- package/popover/styles/_index.scss +49 -207
- package/select/styles/_index.scss +30 -4
- package/sidebar/styles/_index.scss +4 -1
- package/stepper/styles/_index.scss +44 -5
- package/theme/styles/_mixins.scss +10 -0
- package/tree/styles/_index.scss +10 -2
- package/types/ngwr-pagination.d.ts +11 -0
- package/types/ngwr-segmented-testing.d.ts +44 -0
- package/types/ngwr-segmented.d.ts +86 -4
- package/types/ngwr-select.d.ts +12 -2
- package/types/ngwr-version.d.ts +1 -1
|
@@ -1,196 +1,27 @@
|
|
|
1
|
-
@use 'sass:list';
|
|
2
|
-
|
|
3
1
|
@use '../../theme/styles' as theme;
|
|
4
2
|
@use '../../overlay/styles'; // shared .wr-overlay-sheet / .wr-overlay-backdrop for responsive mode
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
top-start: (
|
|
28
|
-
bottom,
|
|
29
|
-
start,
|
|
30
|
-
),
|
|
31
|
-
top-end: (
|
|
32
|
-
bottom,
|
|
33
|
-
end,
|
|
34
|
-
),
|
|
35
|
-
bottom: (
|
|
36
|
-
top,
|
|
37
|
-
center,
|
|
38
|
-
),
|
|
39
|
-
bottom-start: (
|
|
40
|
-
top,
|
|
41
|
-
start,
|
|
42
|
-
),
|
|
43
|
-
bottom-end: (
|
|
44
|
-
top,
|
|
45
|
-
end,
|
|
46
|
-
),
|
|
47
|
-
left: (
|
|
48
|
-
right,
|
|
49
|
-
center,
|
|
50
|
-
),
|
|
51
|
-
left-start: (
|
|
52
|
-
right,
|
|
53
|
-
start,
|
|
54
|
-
),
|
|
55
|
-
left-end: (
|
|
56
|
-
right,
|
|
57
|
-
end,
|
|
58
|
-
),
|
|
59
|
-
right: (
|
|
60
|
-
left,
|
|
61
|
-
center,
|
|
62
|
-
),
|
|
63
|
-
right-start: (
|
|
64
|
-
left,
|
|
65
|
-
start,
|
|
66
|
-
),
|
|
67
|
-
right-end: (
|
|
68
|
-
left,
|
|
69
|
-
end,
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
/// Positions the arrow against `$edge`, offset outwards by `$pull`.
|
|
74
|
-
///
|
|
75
|
-
/// `left` / `right` name the panel edge in LTR terms only. Every side-anchored
|
|
76
|
-
/// and `-start` / `-end` entry in `WR_POPOVER_POSITIONS` is expressed as CDK
|
|
77
|
-
/// `originX: start | end` — plain `top` / `bottom` use `center`, which mirrors
|
|
78
|
-
/// to itself — and CDK resolves start / end against `Directionality`. So under
|
|
79
|
-
/// `dir="rtl"` the panel lands on the mirrored side of the trigger while the
|
|
80
|
-
/// modifier class keeps its LTR name, and the arrow has to travel with the
|
|
81
|
-
/// panel. Same for the `-start` / `-end` alignment along a horizontal edge.
|
|
82
|
-
///
|
|
83
|
-
/// The class names the placement the panel ACTUALLY took, not the requested one:
|
|
84
|
-
/// each entry in `WR_POPOVER_FALLBACKS` carries its own `panelClass`, so a flip
|
|
85
|
-
/// swaps the modifier and this loop moves the arrow with it.
|
|
86
|
-
@mixin _arrow-at($edge, $align, $pull) {
|
|
87
|
-
@if $edge == left {
|
|
88
|
-
inset-inline-start: -$pull;
|
|
89
|
-
} @else if $edge == right {
|
|
90
|
-
inset-inline-end: -$pull;
|
|
91
|
-
} @else {
|
|
92
|
-
#{$edge}: -$pull;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@if $edge == bottom or $edge == top {
|
|
96
|
-
@if $align == center {
|
|
97
|
-
// Both halves of the centring pair go logical together, so the arrow
|
|
98
|
-
// stays on the midpoint whichever way the axis runs.
|
|
99
|
-
inset-inline-start: 50%;
|
|
100
|
-
margin-inline-start: -$_arrow-half;
|
|
101
|
-
} @else if $align == start {
|
|
102
|
-
inset-inline-start: $_arrow-inset;
|
|
103
|
-
} @else {
|
|
104
|
-
inset-inline-end: $_arrow-inset;
|
|
105
|
-
}
|
|
106
|
-
} @else {
|
|
107
|
-
@if $align == center {
|
|
108
|
-
top: 50%;
|
|
109
|
-
margin-top: -$_arrow-half;
|
|
110
|
-
} @else if $align == start {
|
|
111
|
-
top: $_arrow-inset;
|
|
112
|
-
} @else {
|
|
113
|
-
bottom: $_arrow-inset;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/// The two faces of the rotated square that stay visible outside the panel.
|
|
119
|
-
///
|
|
120
|
-
/// These stay physical, and it is not an oversight. Which two borders paint is
|
|
121
|
-
/// decided by `transform: rotate(45deg)`, not by reading order: the rotation
|
|
122
|
-
/// turns the right border into the down-right face and the bottom one into the
|
|
123
|
-
/// down-left face, so `right + bottom` is what outlines a tip pointing DOWN.
|
|
124
|
-
/// Swapping only the inline half would paint two faces that are tucked under
|
|
125
|
-
/// the panel. A mirrored arrow needs the rotation mirrored as well — more than
|
|
126
|
-
/// a property rewrite, so it is left for the RTL pass that owns the TS side.
|
|
127
|
-
@mixin _arrow-border($edge) {
|
|
128
|
-
@if $edge == bottom {
|
|
129
|
-
// rtl-ok: down-right face of a 45°-rotated square — fixed by the rotation
|
|
130
|
-
border-right: 1px solid var(--wr-color-outline);
|
|
131
|
-
border-bottom: 1px solid var(--wr-color-outline);
|
|
132
|
-
} @else if $edge == top {
|
|
133
|
-
// rtl-ok: up-left face of a 45°-rotated square — fixed by the rotation
|
|
134
|
-
border-left: 1px solid var(--wr-color-outline);
|
|
135
|
-
border-top: 1px solid var(--wr-color-outline);
|
|
136
|
-
} @else if $edge == right {
|
|
137
|
-
border-top: 1px solid var(--wr-color-outline);
|
|
138
|
-
// rtl-ok: down-right face of a 45°-rotated square — fixed by the rotation
|
|
139
|
-
border-right: 1px solid var(--wr-color-outline);
|
|
140
|
-
} @else {
|
|
141
|
-
border-bottom: 1px solid var(--wr-color-outline);
|
|
142
|
-
// rtl-ok: up-left face of a 45°-rotated square — fixed by the rotation
|
|
143
|
-
border-left: 1px solid var(--wr-color-outline);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.wr-popover-overlay {
|
|
148
|
-
> * {
|
|
149
|
-
// Containing block for the arrow below.
|
|
150
|
-
position: relative;
|
|
151
|
-
display: block;
|
|
152
|
-
min-width: 8rem;
|
|
153
|
-
max-width: 22rem;
|
|
154
|
-
background: var(--wr-color-surface);
|
|
155
|
-
border: 1px solid var(--wr-color-outline);
|
|
156
|
-
@include theme.smooth-br(var(--wr-border-radius-base));
|
|
157
|
-
box-shadow: var(--wr-shadow-overlay);
|
|
158
|
-
font-family: var(--wr-font-family-base);
|
|
159
|
-
color: var(--wr-color-on-surface);
|
|
160
|
-
animation: wr-overlay-in var(--wr-overlay-duration) var(--wr-overlay-ease);
|
|
161
|
-
// rtl-ok: scale-in growth corner — `transform-origin` takes no logical keywords
|
|
162
|
-
transform-origin: top left;
|
|
163
|
-
|
|
164
|
-
&::after {
|
|
165
|
-
content: '';
|
|
166
|
-
position: absolute;
|
|
167
|
-
width: $_arrow;
|
|
168
|
-
height: $_arrow;
|
|
169
|
-
background: var(--wr-color-surface);
|
|
170
|
-
transform: rotate(45deg);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Responsive bottom-sheet mode has no anchor to point at, so no arrow.
|
|
175
|
-
&.wr-overlay-sheet > *::after {
|
|
176
|
-
content: none;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
@each $position, $spec in $_arrow-placement {
|
|
181
|
-
$edge: list.nth($spec, 1);
|
|
182
|
-
$align: list.nth($spec, 2);
|
|
183
|
-
|
|
184
|
-
// Pulled one extra pixel so the square's own border lines up flush with the
|
|
185
|
-
// panel's, instead of leaving the panel border showing across the arrow's base.
|
|
186
|
-
.wr-popover-overlay--#{$position} > *::after {
|
|
187
|
-
@include _arrow-at($edge, $align, $_arrow-half + 1px);
|
|
188
|
-
@include _arrow-border($edge);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.wr-tooltip-overlay--#{$position} .wr-tooltip::after {
|
|
192
|
-
@include _arrow-at($edge, $align, $_arrow-half);
|
|
193
|
-
}
|
|
3
|
+
@use '../../overlay/styles/arrow';
|
|
4
|
+
|
|
5
|
+
// The arrow — a rotated square tucked half under the panel — used to be written
|
|
6
|
+
// out here: geometry, a twelve-placement map and two mixins. `wr-popconfirm` is
|
|
7
|
+
// the same kind of anchored panel and had none of it, so rather than a second
|
|
8
|
+
// copy the whole thing moved to `overlay/styles/_arrow.scss` and both components
|
|
9
|
+
// call `arrow.anchored-arrow()`. The two calls at the foot of this file emit the
|
|
10
|
+
// rules that were here, for the same twelve placements.
|
|
11
|
+
|
|
12
|
+
.wr-popover-overlay > * {
|
|
13
|
+
display: block;
|
|
14
|
+
min-width: 8rem;
|
|
15
|
+
max-width: 22rem;
|
|
16
|
+
background: var(--wr-color-surface);
|
|
17
|
+
border: 1px solid var(--wr-color-outline);
|
|
18
|
+
@include theme.smooth-br(var(--wr-border-radius-base));
|
|
19
|
+
box-shadow: var(--wr-shadow-overlay);
|
|
20
|
+
font-family: var(--wr-font-family-base);
|
|
21
|
+
color: var(--wr-color-on-surface);
|
|
22
|
+
animation: wr-overlay-in var(--wr-overlay-duration) var(--wr-overlay-ease);
|
|
23
|
+
// rtl-ok: scale-in growth corner — `transform-origin` takes no logical keywords
|
|
24
|
+
transform-origin: top left;
|
|
194
25
|
}
|
|
195
26
|
|
|
196
27
|
//
|
|
@@ -235,24 +66,35 @@ $_arrow-placement: (
|
|
|
235
66
|
// rtl-ok: scale-in growth corner — `transform-origin` takes no logical keywords
|
|
236
67
|
transform-origin: top left;
|
|
237
68
|
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
width: $_arrow;
|
|
243
|
-
height: $_arrow;
|
|
244
|
-
background: var(--wr-tooltip-bg);
|
|
245
|
-
transform: rotate(45deg);
|
|
246
|
-
// The one piece that stays inert: the arrow points AT the trigger and
|
|
247
|
-
// overlaps it, so a hittable arrow would eat clicks meant for the control
|
|
248
|
-
// the tooltip describes.
|
|
249
|
-
pointer-events: none;
|
|
250
|
-
}
|
|
69
|
+
// The arrow itself comes from `arrow.anchored-arrow()` below. `position:
|
|
70
|
+
// relative` is restated by that call and kept here too, so the class still
|
|
71
|
+
// stands on its own for anyone styling `.wr-tooltip` directly — it is public
|
|
72
|
+
// API, and the arrow is the pane's business rather than the chip's.
|
|
251
73
|
}
|
|
252
74
|
|
|
253
|
-
// Arrow
|
|
254
|
-
//
|
|
255
|
-
//
|
|
75
|
+
// Arrow for both modes.
|
|
76
|
+
//
|
|
77
|
+
// Popover: the pane wraps whatever the author projected, so the panel selector
|
|
78
|
+
// is `> *`, and the square carries the panel's border on its two outward faces
|
|
79
|
+
// so the outline reads as continuous.
|
|
80
|
+
@include arrow.anchored-arrow(
|
|
81
|
+
$pane: '.wr-popover-overlay',
|
|
82
|
+
$panel: '> *',
|
|
83
|
+
$background: var(--wr-color-surface),
|
|
84
|
+
$border: var(--wr-color-outline)
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Tooltip: a known child, and no border faces — the chip's own border colour is
|
|
88
|
+
// overridable per instance through `--wr-tooltip-border`, so painting the faces
|
|
89
|
+
// from the token here would desync the moment anyone retints one. The arrow
|
|
90
|
+
// points AT the trigger and overlaps it, so it is the one inert piece: a
|
|
91
|
+
// hittable arrow would eat clicks meant for the control the tooltip describes.
|
|
92
|
+
@include arrow.anchored-arrow(
|
|
93
|
+
$pane: '.wr-tooltip-overlay',
|
|
94
|
+
$panel: '.wr-tooltip',
|
|
95
|
+
$background: var(--wr-tooltip-bg),
|
|
96
|
+
$inert: true
|
|
97
|
+
);
|
|
256
98
|
|
|
257
99
|
@media (prefers-reduced-motion: reduce) {
|
|
258
100
|
.wr-tooltip {
|
|
@@ -36,7 +36,15 @@
|
|
|
36
36
|
&--rounded {
|
|
37
37
|
--wr-select-radius: var(--wr-border-radius-pill);
|
|
38
38
|
--wr-select-padding-x: 1rem;
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
// The squircle reset has to land on the element `smooth-br` ran on, and
|
|
41
|
+
// that is the trigger, not the host: `corner-shape` does not inherit, so a
|
|
42
|
+
// declaration here left the trigger drawing the inset curve the mixin's own
|
|
43
|
+
// gotcha warns about instead of a stadium. `wr-btn` / `wr-input` put their
|
|
44
|
+
// modifier and their `smooth-br` on one element, which is why they paint.
|
|
45
|
+
.wr-select__trigger {
|
|
46
|
+
corner-shape: round;
|
|
47
|
+
}
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
&--disabled {
|
|
@@ -128,7 +136,15 @@
|
|
|
128
136
|
// Search-mode trigger: inline text input + chevron + clear
|
|
129
137
|
&__trigger--search {
|
|
130
138
|
cursor: text;
|
|
131
|
-
padding
|
|
139
|
+
// The FIELD owns the padding here — it is the click target and has to be
|
|
140
|
+
// typable edge to edge — but the chevron and the × are siblings of it, not
|
|
141
|
+
// children, so a flat `padding: 0` left the chevron sitting on the border.
|
|
142
|
+
// Hand the TRAILING inset back to the trigger: the chevron is now inset by
|
|
143
|
+
// the same amount the placeholder is, and the field keeps the leading edge.
|
|
144
|
+
// Logical properties, so the inset moves to the left in `dir="rtl"` on its
|
|
145
|
+
// own — no physical side is named.
|
|
146
|
+
padding-block: 0;
|
|
147
|
+
padding-inline: 0 calc(var(--wr-select-padding-x) * var(--wr-density-x, 1));
|
|
132
148
|
|
|
133
149
|
&:focus-within {
|
|
134
150
|
border-color: var(--wr-color-primary);
|
|
@@ -218,7 +234,12 @@
|
|
|
218
234
|
// Roomier on the label side, tighter where the remove (×) sits.
|
|
219
235
|
padding-block: 0.125rem;
|
|
220
236
|
padding-inline: 0.5rem 0.25rem;
|
|
221
|
-
|
|
237
|
+
// Not a pill: a chip is a shape nested INSIDE the trigger, so it repeats the
|
|
238
|
+
// trigger's own corner and scales with `size` along with it (5 / 6 / 7px for
|
|
239
|
+
// sm / md / lg). `--rounded` sets `--wr-select-radius` to the pill token, so
|
|
240
|
+
// a pill select still gets pill chips — the shape follows the control rather
|
|
241
|
+
// than being decided twice.
|
|
242
|
+
border-radius: var(--wr-select-radius);
|
|
222
243
|
background: var(--wr-color-primary-soft);
|
|
223
244
|
// `-ink`, not the raw intent: the chip paints the hue on its own soft tint,
|
|
224
245
|
// where the base lands at 4.17:1.
|
|
@@ -241,7 +262,12 @@
|
|
|
241
262
|
justify-content: center;
|
|
242
263
|
width: 1rem;
|
|
243
264
|
height: 1rem;
|
|
244
|
-
|
|
265
|
+
// Concentric with the chip: the remove is inset from the chip's edge by the
|
|
266
|
+
// chip's 2px block padding, and an inner corner only nests cleanly when it
|
|
267
|
+
// is the outer corner minus that inset. `max()` keeps the value legal for a
|
|
268
|
+
// consumer who sets `--wr-select-radius: 0` — a negative radius would
|
|
269
|
+
// invalidate the declaration outright.
|
|
270
|
+
border-radius: max(0px, calc(var(--wr-select-radius) - 2px));
|
|
245
271
|
cursor: pointer;
|
|
246
272
|
transition: background 0.12s ease;
|
|
247
273
|
|
|
@@ -224,7 +224,10 @@
|
|
|
224
224
|
&__badge {
|
|
225
225
|
flex: 0 0 auto;
|
|
226
226
|
padding: 0.0625rem 0.375rem;
|
|
227
|
-
|
|
227
|
+
// The row's corner, not a pill: the badge sits inside `__entry` / `__item`,
|
|
228
|
+
// which both read `--wr-border-radius-sm`, and a stadium nested in a 6px row
|
|
229
|
+
// reads as a foreign shape rather than a part of it.
|
|
230
|
+
border-radius: var(--wr-border-radius-sm);
|
|
228
231
|
background: var(--wr-color-fill-strong);
|
|
229
232
|
color: var(--wr-color-on-surface-muted);
|
|
230
233
|
font-size: var(--wr-text-xs);
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
@use '../../theme/styles' as theme;
|
|
2
2
|
|
|
3
|
+
// The label's own line box, and the header button's block padding. Both are
|
|
4
|
+
// declared once below and read back by the alignment arithmetic — the indicator
|
|
5
|
+
// centres on the label's FIRST LINE, and the connector centres on the indicator,
|
|
6
|
+
// so a literal repeated in three places is a defect waiting for someone to
|
|
7
|
+
// change one of them.
|
|
8
|
+
$label-line-height: 1.25rem;
|
|
9
|
+
$header-padding-block: 0.25rem;
|
|
10
|
+
|
|
3
11
|
.wr-stepper {
|
|
4
12
|
--wr-stepper-indicator-size: 1.75rem;
|
|
5
13
|
--wr-stepper-connector: var(--wr-color-outline);
|
|
@@ -33,9 +41,19 @@
|
|
|
33
41
|
flex-direction: column;
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
// `flex-start`, not `center`: a step that carries a hint line
|
|
45
|
+
// (`description` / `optional`) is TALLER than its neighbours, and centring
|
|
46
|
+
// every button in the row it defines drops the short steps' circles by half
|
|
47
|
+
// the difference — the whole row reads as misaligned because of one step.
|
|
48
|
+
// Anchored at the block start, every button's first line sits at the same y,
|
|
49
|
+
// and the connector places itself against the indicator (see `&__connector`)
|
|
50
|
+
// instead of riding the row's centre.
|
|
51
|
+
//
|
|
52
|
+
// A row of same-height steps is unaffected: with equal heights `center` and
|
|
53
|
+
// `flex-start` resolve identically.
|
|
36
54
|
&__header {
|
|
37
55
|
display: flex;
|
|
38
|
-
align-items:
|
|
56
|
+
align-items: flex-start;
|
|
39
57
|
flex: 1 1 auto;
|
|
40
58
|
gap: 0.75rem;
|
|
41
59
|
min-width: 0;
|
|
@@ -59,13 +77,20 @@
|
|
|
59
77
|
flex: 0 0 auto;
|
|
60
78
|
}
|
|
61
79
|
|
|
80
|
+
// `flex-start` here for the same reason, one level in: the indicator is a
|
|
81
|
+
// fixed-size circle and the label is a column that grows a line whenever the
|
|
82
|
+
// step has a `description` or is `optional`. Centred against the whole block,
|
|
83
|
+
// the circle slides down as the label grows and stops belonging to the step's
|
|
84
|
+
// NAME. The label carries the compensating offset (see `&__label`) rather
|
|
85
|
+
// than the indicator carrying a negative one, so the circle stays inside the
|
|
86
|
+
// button's own box.
|
|
62
87
|
&__header-button {
|
|
63
88
|
appearance: none;
|
|
64
89
|
background: transparent;
|
|
65
90
|
border: 0;
|
|
66
|
-
padding:
|
|
91
|
+
padding: $header-padding-block 0;
|
|
67
92
|
display: inline-flex;
|
|
68
|
-
align-items:
|
|
93
|
+
align-items: flex-start;
|
|
69
94
|
gap: 0.625rem;
|
|
70
95
|
color: var(--wr-color-on-surface);
|
|
71
96
|
cursor: pointer;
|
|
@@ -119,7 +144,15 @@
|
|
|
119
144
|
gap: 0.0625rem;
|
|
120
145
|
font-size: var(--wr-text-sm);
|
|
121
146
|
font-weight: 500;
|
|
122
|
-
line-height:
|
|
147
|
+
line-height: $label-line-height;
|
|
148
|
+
// Centre the label's FIRST LINE on the indicator, now that both are anchored
|
|
149
|
+
// to the button's block start. Half the difference between the circle and one
|
|
150
|
+
// line box — derived, not typed, because `--wr-stepper-indicator-size` is a
|
|
151
|
+
// public custom property a consumer can retune. At the shipped 1.75rem this
|
|
152
|
+
// is 0.25rem, which is exactly where `align-items: center` used to put a
|
|
153
|
+
// single-line label: the one-line step renders pixel-for-pixel as before and
|
|
154
|
+
// only the multi-line one moves.
|
|
155
|
+
margin-block-start: calc((var(--wr-stepper-indicator-size) - #{$label-line-height}) / 2);
|
|
123
156
|
}
|
|
124
157
|
|
|
125
158
|
&__header--active &__label {
|
|
@@ -145,7 +178,13 @@
|
|
|
145
178
|
height: 1.5px;
|
|
146
179
|
background: var(--wr-stepper-connector);
|
|
147
180
|
min-width: 1rem;
|
|
148
|
-
|
|
181
|
+
// The row aligns its children to the block start now, so the line has to
|
|
182
|
+
// place itself on the indicator's centre instead of inheriting the row's.
|
|
183
|
+
// Button padding, plus half a circle, less half the line's own thickness.
|
|
184
|
+
// Same y the centred version produced for a row of equal-height steps — and
|
|
185
|
+
// unlike it, the same y when one step grows a hint line.
|
|
186
|
+
margin-block-start: calc(#{$header-padding-block} + var(--wr-stepper-indicator-size) / 2 - 0.75px);
|
|
187
|
+
margin-inline: 0.5rem;
|
|
149
188
|
}
|
|
150
189
|
|
|
151
190
|
&--vertical &__connector {
|
|
@@ -43,6 +43,16 @@
|
|
|
43
43
|
/// }
|
|
44
44
|
/// ```
|
|
45
45
|
///
|
|
46
|
+
/// The reset has to sit on the element the mixin ran on. `corner-shape`
|
|
47
|
+
/// does not inherit, so a component whose modifier is on the HOST while
|
|
48
|
+
/// `smooth-br` is on a child needs to target that child — otherwise the
|
|
49
|
+
/// declaration lands on an element that never had a squircle to undo,
|
|
50
|
+
/// and, since `round` is the property's initial value, changes nothing
|
|
51
|
+
/// at all. `wr-select` shipped that way: `.wr-select--rounded` set it on
|
|
52
|
+
/// the host, the trigger kept `squircle` at the pill radius, and the
|
|
53
|
+
/// control painted a near-rectangle — 2px of corner where a stadium
|
|
54
|
+
/// wants 18.
|
|
55
|
+
///
|
|
46
56
|
/// @example scss
|
|
47
57
|
/// .thing {
|
|
48
58
|
/// @include smooth-br(0.625rem);
|
package/tree/styles/_index.scss
CHANGED
|
@@ -270,7 +270,10 @@
|
|
|
270
270
|
// Roomier on the label side, tighter where the remove (×) sits.
|
|
271
271
|
padding-block: 0.125rem;
|
|
272
272
|
padding-inline: 0.5rem 0.25rem;
|
|
273
|
-
|
|
273
|
+
// Not a pill: a chip is a shape nested INSIDE the trigger, so it repeats the
|
|
274
|
+
// trigger's own corner instead of deciding one for itself — and an override
|
|
275
|
+
// of `--wr-tree-trigger-radius` carries the chips with it.
|
|
276
|
+
border-radius: var(--wr-tree-trigger-radius);
|
|
274
277
|
background: var(--wr-color-primary-soft);
|
|
275
278
|
// The chip wraps a label, so this paints text on the chip's own tint.
|
|
276
279
|
color: var(--wr-color-primary-ink);
|
|
@@ -292,7 +295,12 @@
|
|
|
292
295
|
justify-content: center;
|
|
293
296
|
width: 1rem;
|
|
294
297
|
height: 1rem;
|
|
295
|
-
|
|
298
|
+
// Concentric with the chip: inset from the chip's edge by its 2px block
|
|
299
|
+
// padding, and an inner corner only nests cleanly when it is the outer
|
|
300
|
+
// corner minus that inset. `max()` keeps the value legal for a consumer who
|
|
301
|
+
// sets `--wr-tree-trigger-radius: 0` — a negative radius invalidates the
|
|
302
|
+
// whole declaration.
|
|
303
|
+
border-radius: max(0px, calc(var(--wr-tree-trigger-radius) - 2px));
|
|
296
304
|
cursor: pointer;
|
|
297
305
|
transition: background 0.12s ease;
|
|
298
306
|
|
|
@@ -111,6 +111,17 @@ declare class WrPagination {
|
|
|
111
111
|
protected readonly navLabel: _angular_core.Signal<string>;
|
|
112
112
|
/** Internal: total page count. */
|
|
113
113
|
protected readonly totalPages: _angular_core.Signal<number>;
|
|
114
|
+
/**
|
|
115
|
+
* Internal: where the previous arrow goes. Clamped to the end of the valid
|
|
116
|
+
* range rather than being a plain `currentPage() - 1`, because the page can
|
|
117
|
+
* legitimately sit past that end while `total` is 0 (see the guard effect).
|
|
118
|
+
* From page 5 of one page, `goTo(4)` is refused as out of range, so the arrow
|
|
119
|
+
* was enabled and did nothing — and under `responsive` on a narrow box the
|
|
120
|
+
* numbered cells are hidden by a container query, which left no way back at
|
|
121
|
+
* all. `Math.min` only ever moves the target INWARD, so `goTo`'s own
|
|
122
|
+
* past-the-end refusal keeps working as the backstop it is.
|
|
123
|
+
*/
|
|
124
|
+
protected readonly prevPage: _angular_core.Signal<number>;
|
|
114
125
|
/** Internal: "X–Y of Z" string. */
|
|
115
126
|
protected readonly rangeLabel: _angular_core.Signal<string>;
|
|
116
127
|
/**
|
|
@@ -194,6 +194,17 @@ declare class WrSegmentedOptionHarness extends ComponentHarness {
|
|
|
194
194
|
* - Activation is the browser's own default action on a button, which jsdom does not
|
|
195
195
|
* implement, so {@link select} clicks — see {@link WrSegmentedOptionHarness.select}.
|
|
196
196
|
*
|
|
197
|
+
* **It is a signal-forms control**, which adds two things to read here and one that
|
|
198
|
+
* cannot be read at all. `[formField]` binds the component's own `value` model, and a
|
|
199
|
+
* surrounding `<wr-form-field>` publishes its state onto the GROUP —
|
|
200
|
+
* {@link isInvalid} and {@link getDescriptionText} answer that, on the host rather
|
|
201
|
+
* than per segment, because the strip is one field and a description repeated on
|
|
202
|
+
* every segment would be announced once per Tab. What is NOT here is the field's
|
|
203
|
+
* `touched` flag: the component only emits `touch`, and whether anything listened is
|
|
204
|
+
* a fact about the form, not about this DOM — assert it on the field.
|
|
205
|
+
* {@link blur} is how a spec gets there, and it is the ONLY route: a click does not
|
|
206
|
+
* mark a field touched, and neither does moving from one segment to the next.
|
|
207
|
+
*
|
|
197
208
|
* **There is deliberately no `getValue()` and no selection by value.** `options` is
|
|
198
209
|
* a bound array of `{ value, label, … }` and the value is a generic `T` the component
|
|
199
210
|
* writes nowhere — not on the host, not on a segment. The single exception is an
|
|
@@ -339,6 +350,39 @@ declare class WrSegmentedHarness extends ComponentHarness {
|
|
|
339
350
|
* {@link getTabStopLabels} gives.
|
|
340
351
|
*/
|
|
341
352
|
getFocusedLabel(): Promise<string | null>;
|
|
353
|
+
/**
|
|
354
|
+
* Whether the surrounding `<wr-form-field>` is reporting this control invalid, from
|
|
355
|
+
* `aria-invalid` on the host.
|
|
356
|
+
*
|
|
357
|
+
* `false` for a control with no field around it, and `false` for a field that is
|
|
358
|
+
* invalid but has not shown its copy yet: the component keys the attribute on the
|
|
359
|
+
* MESSAGE existing rather than on the error, because announcing "invalid" while
|
|
360
|
+
* pointing at nothing is worse than staying quiet. So this and
|
|
361
|
+
* {@link getDescriptionText} move together, and a `true` with no description would
|
|
362
|
+
* be the finding.
|
|
363
|
+
*/
|
|
364
|
+
isInvalid(): Promise<boolean>;
|
|
365
|
+
/**
|
|
366
|
+
* The text `aria-describedby` points at — the validation copy a screen reader is
|
|
367
|
+
* given for this control — or `null` when the host describes nothing.
|
|
368
|
+
*
|
|
369
|
+
* Resolved from the document root, because the element named may sit anywhere on
|
|
370
|
+
* the page, and THROWS when the reference resolves to no element: a dangling
|
|
371
|
+
* `aria-describedby` renders exactly like a working one and is announced as
|
|
372
|
+
* nothing, so returning `null` for it would report the bug as the healthy state.
|
|
373
|
+
*/
|
|
374
|
+
getDescriptionText(): Promise<string | null>;
|
|
375
|
+
/**
|
|
376
|
+
* Take focus off the strip entirely — what marks a bound field touched, and the
|
|
377
|
+
* only thing that does.
|
|
378
|
+
*
|
|
379
|
+
* The component emits `touch` from a `focusout` that leaves the host, so a click
|
|
380
|
+
* does not reach it and neither does Tab from one segment to the next: a strip a
|
|
381
|
+
* user tabbed straight past has to end up untouched, which is the case `touched`
|
|
382
|
+
* exists for. Resolves quietly when nothing inside was focused, since that is
|
|
383
|
+
* already the state this asks for.
|
|
384
|
+
*/
|
|
385
|
+
blur(): Promise<void>;
|
|
342
386
|
/**
|
|
343
387
|
* The index the component publishes for the thumb, from the
|
|
344
388
|
* `--wr-segmented-thumb-index` custom property it sets inline.
|