@webority/theme 0.24.0 → 0.26.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 +16 -2
- package/dist/purge-safelist.json +199 -2
- package/dist/webority-brand-signal.css +1 -0
- package/dist/webority-theme.css +2 -2
- package/fonts/sans/OFL.txt +92 -0
- package/fonts/sans/WeboritySans-Bold.woff2 +0 -0
- package/fonts/sans/WeboritySans-BoldItalic.woff2 +0 -0
- package/fonts/sans/WeboritySans-Medium.woff2 +0 -0
- package/fonts/sans/WeboritySans-Regular.woff2 +0 -0
- package/fonts/sans/WeboritySans-RegularItalic.woff2 +0 -0
- package/fonts/sans/WeboritySans-SemiBold.woff2 +0 -0
- package/fonts/serif/WeboritySerif-Bold.woff2 +0 -0
- package/fonts/serif/WeboritySerif-BoldItalic.woff2 +0 -0
- package/fonts/serif/WeboritySerif-DemiBold.woff2 +0 -0
- package/fonts/serif/WeboritySerif-ExtraBold.woff2 +0 -0
- package/fonts/serif/WeboritySerif-Medium.woff2 +0 -0
- package/fonts/serif/WeboritySerif-Regular.woff2 +0 -0
- package/fonts/serif/WeboritySerif-RegularItalic.woff2 +0 -0
- package/index.scss +2 -1
- package/package.json +4 -2
- package/scss/_brand-signal.scss +202 -0
- package/scss/_fonts.scss +96 -0
- package/scss/_tokens.scss +55 -2
- package/scss/_variables.scss +2 -1
- package/scss/_wui-aliases.scss +21 -0
- package/scss/_wui-components.scss +12 -0
- package/scss/wui/_calendar.scss +256 -0
- package/scss/wui/_chart-card.scss +86 -0
- package/scss/wui/_chart.scss +524 -0
- package/scss/wui/_context-menu.scss +53 -0
- package/scss/wui/_data.scss +8 -6
- package/scss/wui/_display.scss +1 -1
- package/scss/wui/_image-crop.scss +146 -0
- package/scss/wui/_kanban.scss +434 -0
- package/scss/wui/_modal-remote.scss +55 -0
- package/scss/wui/_overlays.scss +39 -0
- package/scss/wui/_rich-text.scss +281 -0
- package/scss/wui/_shell-parts.scss +503 -0
- package/scss/wui/_shell.scss +11 -0
- package/scss/wui/_sortable.scss +135 -0
- package/scss/wui/_table-server.scss +40 -0
- package/scss/wui/_tree.scss +124 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
// Calendar: the <wui-calendar> element behind AppCalendar and <app-calendar>. The element is styled by its
|
|
2
|
+
// tag, since a framework that sets `class` on it would replace any class the element added to itself.
|
|
3
|
+
//
|
|
4
|
+
// Part of the wui-components layer; see _wui-components.scss for the load order. The calendar
|
|
5
|
+
// engine paints the grid from its own --fc-* custom properties, so the whole theme is those
|
|
6
|
+
// variables set from tokens below, which the dark remap in _wui-aliases.scss flips with the rest
|
|
7
|
+
// of the portal: there is no theme watcher and no engine selector here. The toolbar, view switch
|
|
8
|
+
// and status line are the element's own markup.
|
|
9
|
+
|
|
10
|
+
wui-calendar {
|
|
11
|
+
--fc-small-font-size: 12px;
|
|
12
|
+
--fc-page-bg-color: var(--color-surface);
|
|
13
|
+
--fc-neutral-bg-color: var(--color-bg-muted);
|
|
14
|
+
--fc-neutral-text-color: var(--color-text-muted);
|
|
15
|
+
--fc-border-color: var(--color-border);
|
|
16
|
+
--fc-today-bg-color: var(--color-primary-soft);
|
|
17
|
+
--fc-now-indicator-color: var(--color-danger);
|
|
18
|
+
--fc-highlight-color: var(--color-primary-soft);
|
|
19
|
+
--fc-non-business-color: var(--color-bg-muted);
|
|
20
|
+
--fc-more-link-bg-color: var(--color-bg-muted);
|
|
21
|
+
--fc-more-link-text-color: var(--color-text-body);
|
|
22
|
+
--fc-list-event-hover-bg-color: var(--color-bg-muted);
|
|
23
|
+
--fc-event-bg-color: var(--color-bg-muted);
|
|
24
|
+
--fc-event-border-color: var(--color-border-strong);
|
|
25
|
+
--fc-event-text-color: var(--color-text);
|
|
26
|
+
|
|
27
|
+
display: block;
|
|
28
|
+
min-width: 0;
|
|
29
|
+
font-size: 13px;
|
|
30
|
+
color: var(--color-text-body);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.wui-calendar-toolbar {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: wrap;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: 8px 12px;
|
|
38
|
+
margin-bottom: 12px;
|
|
39
|
+
}
|
|
40
|
+
.wui-calendar-nav {
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
gap: 6px;
|
|
44
|
+
}
|
|
45
|
+
.wui-calendar-today-btn,
|
|
46
|
+
.wui-calendar-nav-btn {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
min-width: 36px;
|
|
51
|
+
height: 36px;
|
|
52
|
+
padding: 0 12px;
|
|
53
|
+
border: 1px solid var(--color-border);
|
|
54
|
+
border-radius: 999px;
|
|
55
|
+
background: var(--color-surface);
|
|
56
|
+
color: var(--color-text);
|
|
57
|
+
font: inherit;
|
|
58
|
+
font-weight: 600;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
transition:
|
|
61
|
+
background 0.12s,
|
|
62
|
+
color 0.12s,
|
|
63
|
+
border-color 0.12s;
|
|
64
|
+
}
|
|
65
|
+
.wui-calendar-nav-btn {
|
|
66
|
+
padding: 0;
|
|
67
|
+
color: var(--color-text-muted);
|
|
68
|
+
}
|
|
69
|
+
.wui-calendar-today-btn:hover,
|
|
70
|
+
.wui-calendar-nav-btn:hover {
|
|
71
|
+
background: var(--color-primary-soft);
|
|
72
|
+
border-color: var(--color-primary);
|
|
73
|
+
color: var(--color-primary);
|
|
74
|
+
}
|
|
75
|
+
.wui-calendar-today-btn:focus-visible,
|
|
76
|
+
.wui-calendar-nav-btn:focus-visible,
|
|
77
|
+
.wui-calendar-view-btn:focus-visible {
|
|
78
|
+
outline: 2px solid var(--color-primary);
|
|
79
|
+
outline-offset: 2px;
|
|
80
|
+
}
|
|
81
|
+
.wui-calendar-title {
|
|
82
|
+
flex: 1 1 auto;
|
|
83
|
+
min-width: 0;
|
|
84
|
+
margin: 0;
|
|
85
|
+
font-size: 16px;
|
|
86
|
+
font-weight: 600;
|
|
87
|
+
line-height: 1.3;
|
|
88
|
+
color: var(--color-text);
|
|
89
|
+
text-align: center;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// The same outlined-pill selected state as the segmented control, on plain buttons: a view switch
|
|
93
|
+
// is pressed state, not a form value.
|
|
94
|
+
.wui-calendar-views {
|
|
95
|
+
display: inline-flex;
|
|
96
|
+
gap: 2px;
|
|
97
|
+
padding: 3px;
|
|
98
|
+
border: 1px solid var(--color-border);
|
|
99
|
+
border-radius: 999px;
|
|
100
|
+
background: var(--color-surface);
|
|
101
|
+
}
|
|
102
|
+
.wui-calendar-view-btn {
|
|
103
|
+
min-height: 28px;
|
|
104
|
+
padding: 0 12px;
|
|
105
|
+
border: 0;
|
|
106
|
+
border-radius: 999px;
|
|
107
|
+
background: transparent;
|
|
108
|
+
color: var(--color-text);
|
|
109
|
+
font: inherit;
|
|
110
|
+
font-size: 12px;
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
white-space: nowrap;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
transition:
|
|
115
|
+
background 0.14s ease,
|
|
116
|
+
color 0.14s ease;
|
|
117
|
+
}
|
|
118
|
+
.wui-calendar-view-btn:hover {
|
|
119
|
+
color: var(--color-primary);
|
|
120
|
+
}
|
|
121
|
+
.wui-calendar-view-btn[aria-pressed="true"] {
|
|
122
|
+
background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
|
|
123
|
+
box-shadow: inset 0 0 0 2px var(--color-primary);
|
|
124
|
+
color: var(--color-primary);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// On a phone the title takes a row of its own between the two controls, and every control is a
|
|
128
|
+
// full-size touch target.
|
|
129
|
+
@media (max-width: 575.98px) {
|
|
130
|
+
.wui-calendar-toolbar {
|
|
131
|
+
gap: 8px;
|
|
132
|
+
}
|
|
133
|
+
.wui-calendar-nav {
|
|
134
|
+
order: 1;
|
|
135
|
+
}
|
|
136
|
+
.wui-calendar-views {
|
|
137
|
+
order: 2;
|
|
138
|
+
margin-left: auto;
|
|
139
|
+
}
|
|
140
|
+
.wui-calendar-title {
|
|
141
|
+
order: 3;
|
|
142
|
+
flex-basis: 100%;
|
|
143
|
+
text-align: start;
|
|
144
|
+
}
|
|
145
|
+
.wui-calendar-today-btn,
|
|
146
|
+
.wui-calendar-nav-btn {
|
|
147
|
+
min-width: 44px;
|
|
148
|
+
height: 44px;
|
|
149
|
+
}
|
|
150
|
+
.wui-calendar-view-btn {
|
|
151
|
+
min-height: 38px;
|
|
152
|
+
padding: 0 10px;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.wui-calendar-status {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex-wrap: wrap;
|
|
159
|
+
align-items: center;
|
|
160
|
+
gap: 8px 12px;
|
|
161
|
+
margin-bottom: 12px;
|
|
162
|
+
padding: 10px 12px;
|
|
163
|
+
border: 1px solid var(--color-danger);
|
|
164
|
+
border-radius: 8px;
|
|
165
|
+
background: var(--color-danger-soft);
|
|
166
|
+
color: var(--color-danger-text);
|
|
167
|
+
}
|
|
168
|
+
.wui-calendar-status[hidden] {
|
|
169
|
+
display: none;
|
|
170
|
+
}
|
|
171
|
+
.wui-calendar-status-text {
|
|
172
|
+
flex: 1 1 auto;
|
|
173
|
+
margin: 0;
|
|
174
|
+
color: var(--color-text-muted);
|
|
175
|
+
}
|
|
176
|
+
.wui-calendar-status .wui-calendar-status-text {
|
|
177
|
+
color: inherit;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// A day cell, a week or day heading and an event are reached by keyboard; the ring is the same
|
|
181
|
+
// primary outline every other control in the library draws. The engine marks days with data-date.
|
|
182
|
+
wui-calendar [data-date]:focus-visible {
|
|
183
|
+
outline: 2px solid var(--color-primary);
|
|
184
|
+
outline-offset: -2px;
|
|
185
|
+
}
|
|
186
|
+
wui-calendar a:focus-visible {
|
|
187
|
+
outline: 2px solid var(--color-primary);
|
|
188
|
+
outline-offset: 1px;
|
|
189
|
+
}
|
|
190
|
+
// The engine draws day numbers, headings and event titles as bare anchors, which the page's link
|
|
191
|
+
// colour would turn into a field of links.
|
|
192
|
+
wui-calendar a {
|
|
193
|
+
color: inherit;
|
|
194
|
+
text-decoration: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.wui-calendar-surface {
|
|
198
|
+
min-width: 0;
|
|
199
|
+
overflow-x: auto;
|
|
200
|
+
transition: opacity 0.15s ease;
|
|
201
|
+
}
|
|
202
|
+
wui-calendar[aria-busy="true"] .wui-calendar-surface {
|
|
203
|
+
opacity: 0.6;
|
|
204
|
+
}
|
|
205
|
+
// Seven columns of times do not fit a phone: the week scrolls sideways inside the calendar.
|
|
206
|
+
wui-calendar[data-view="week"] .wui-calendar-surface > * {
|
|
207
|
+
min-width: 560px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// An event takes its tone from the engine's event variables: a soft fill, a tone-coloured edge
|
|
211
|
+
// (and dot, in the month and the list) and text that clears AA on the fill in both themes.
|
|
212
|
+
.wui-calendar-event-neutral {
|
|
213
|
+
--fc-event-bg-color: var(--color-bg-muted);
|
|
214
|
+
--fc-event-border-color: var(--color-border-strong);
|
|
215
|
+
--fc-event-text-color: var(--color-text);
|
|
216
|
+
}
|
|
217
|
+
.wui-calendar-event-primary {
|
|
218
|
+
--fc-event-bg-color: var(--color-primary-soft);
|
|
219
|
+
--fc-event-border-color: var(--color-primary);
|
|
220
|
+
--fc-event-text-color: var(--color-primary);
|
|
221
|
+
}
|
|
222
|
+
.wui-calendar-event-success {
|
|
223
|
+
--fc-event-bg-color: var(--color-success-soft);
|
|
224
|
+
--fc-event-border-color: var(--color-success);
|
|
225
|
+
--fc-event-text-color: var(--color-success-text);
|
|
226
|
+
}
|
|
227
|
+
.wui-calendar-event-warning {
|
|
228
|
+
--fc-event-bg-color: var(--color-warning-soft);
|
|
229
|
+
--fc-event-border-color: var(--color-warning);
|
|
230
|
+
--fc-event-text-color: var(--color-warning-text);
|
|
231
|
+
}
|
|
232
|
+
.wui-calendar-event-danger {
|
|
233
|
+
--fc-event-bg-color: var(--color-danger-soft);
|
|
234
|
+
--fc-event-border-color: var(--color-danger);
|
|
235
|
+
--fc-event-text-color: var(--color-danger-text);
|
|
236
|
+
}
|
|
237
|
+
.wui-calendar-event-info {
|
|
238
|
+
--fc-event-bg-color: var(--color-info-soft);
|
|
239
|
+
--fc-event-border-color: var(--color-info);
|
|
240
|
+
--fc-event-text-color: var(--color-info-text);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// What a page with no script shows until the element's script replaces it.
|
|
244
|
+
.wui-calendar-fallback {
|
|
245
|
+
margin: 0;
|
|
246
|
+
padding-left: 18px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@media (prefers-reduced-motion: reduce) {
|
|
250
|
+
.wui-calendar-today-btn,
|
|
251
|
+
.wui-calendar-nav-btn,
|
|
252
|
+
.wui-calendar-view-btn,
|
|
253
|
+
.wui-calendar-surface {
|
|
254
|
+
transition: none;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Chart surfaces: the sparkline, the chart card and the dashboard grid.
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// The sparkline is plain SVG (AppSparkline, <app-sparkline>) and never loads the chart engine.
|
|
4
|
+
// The card (AppChartCard, <app-chart-card>) is a normal .card whose header carries the view
|
|
5
|
+
// controls; the grid (AppDashboardGrid, <app-dashboard-grid>) lays cards and tiles on 12 columns.
|
|
6
|
+
|
|
7
|
+
:where(.wui-sparkline) {
|
|
8
|
+
display: inline-block;
|
|
9
|
+
vertical-align: middle;
|
|
10
|
+
color: var(--color-primary);
|
|
11
|
+
}
|
|
12
|
+
.wui-sparkline polyline {
|
|
13
|
+
stroke-width: 1.5;
|
|
14
|
+
stroke-linecap: round;
|
|
15
|
+
stroke-linejoin: round;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ── Chart card ──────────────────────────────────────────────────────────────
|
|
19
|
+
.wui-chart-card > .card-header {
|
|
20
|
+
flex-wrap: wrap;
|
|
21
|
+
}
|
|
22
|
+
.wui-chart-card .card-header-titles {
|
|
23
|
+
min-width: 0;
|
|
24
|
+
}
|
|
25
|
+
.wui-chart-card .card-header-actions {
|
|
26
|
+
gap: 4px;
|
|
27
|
+
}
|
|
28
|
+
.wui-chart-card-tool[aria-pressed="true"] {
|
|
29
|
+
background: var(--color-primary-soft);
|
|
30
|
+
color: var(--color-primary);
|
|
31
|
+
}
|
|
32
|
+
// The legend toggle is useful only while the chart shows a legend: two or more series, in the
|
|
33
|
+
// chart view. Before the element has drawn there is none, so the button waits for it.
|
|
34
|
+
.wui-chart-card:not(:has(wui-chart .wui-chart-legend:not([hidden]))) .wui-chart-card-legend-tool {
|
|
35
|
+
display: none;
|
|
36
|
+
}
|
|
37
|
+
.wui-chart-card-legend-off wui-chart .wui-chart-legend {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
// The card owns retry; the element only says what went wrong.
|
|
41
|
+
.wui-chart-card-retry {
|
|
42
|
+
display: none;
|
|
43
|
+
justify-content: center;
|
|
44
|
+
padding-top: 8px;
|
|
45
|
+
}
|
|
46
|
+
.wui-chart-card:has(wui-chart[data-state="error"]) .wui-chart-card-retry {
|
|
47
|
+
display: flex;
|
|
48
|
+
}
|
|
49
|
+
// Until the element's script has run, the server-rendered table is all there is: keep a long one
|
|
50
|
+
// from pushing the page about before it is swapped for the picture.
|
|
51
|
+
wui-chart:not(:defined) .wui-chart-table-wrap {
|
|
52
|
+
max-height: 20rem;
|
|
53
|
+
overflow: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ── Dashboard grid ──────────────────────────────────────────────────────────
|
|
57
|
+
// One column on a phone; from 576px a cell spans 3, 4, 6 or 12 of 12 columns.
|
|
58
|
+
.wui-dashboard-grid {
|
|
59
|
+
display: grid;
|
|
60
|
+
grid-template-columns: minmax(0, 1fr);
|
|
61
|
+
gap: 16px;
|
|
62
|
+
}
|
|
63
|
+
.wui-dashboard-cell {
|
|
64
|
+
min-width: 0;
|
|
65
|
+
}
|
|
66
|
+
.wui-dashboard-cell > .card,
|
|
67
|
+
.wui-dashboard-cell > .kpi {
|
|
68
|
+
height: 100%;
|
|
69
|
+
}
|
|
70
|
+
@media (min-width: 576px) {
|
|
71
|
+
.wui-dashboard-grid {
|
|
72
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
73
|
+
}
|
|
74
|
+
.wui-dashboard-cell {
|
|
75
|
+
grid-column: span 12;
|
|
76
|
+
}
|
|
77
|
+
.wui-dashboard-cell-3 {
|
|
78
|
+
grid-column: span 3;
|
|
79
|
+
}
|
|
80
|
+
.wui-dashboard-cell-4 {
|
|
81
|
+
grid-column: span 4;
|
|
82
|
+
}
|
|
83
|
+
.wui-dashboard-cell-6 {
|
|
84
|
+
grid-column: span 6;
|
|
85
|
+
}
|
|
86
|
+
}
|