@wovenui/components 0.0.0-stage → 1.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/LICENSE +21 -0
- package/README.md +284 -2
- package/dist/components.json +4204 -0
- package/dist/llms-full.txt +2839 -0
- package/dist/wovenui-kit.css +5002 -0
- package/dist/wovenui-kit.css.map +1 -0
- package/dist/wovenui-kit.iife.js +532 -0
- package/dist/wovenui-kit.js +529 -0
- package/dist/wovenui-kit.min.css +2 -0
- package/dist/wovenui-kit.min.css.map +1 -0
- package/package.json +268 -4
- package/src/_close.scss +45 -0
- package/src/_helpers.scss +11 -0
- package/src/_kit.scss +124 -0
- package/src/_shared.scss +10 -0
- package/src/components/_accordion.scss +132 -0
- package/src/components/_alert.scss +161 -0
- package/src/components/_autocomplete.scss +129 -0
- package/src/components/_avatar-group.scss +80 -0
- package/src/components/_avatar.scss +134 -0
- package/src/components/_badge.scss +91 -0
- package/src/components/_breadcrumb.scss +115 -0
- package/src/components/_btn-group.scss +113 -0
- package/src/components/_button.scss +301 -0
- package/src/components/_card.scss +120 -0
- package/src/components/_checkbox.scss +168 -0
- package/src/components/_code-block.scss +78 -0
- package/src/components/_confirm-modal.scss +75 -0
- package/src/components/_data-table.scss +79 -0
- package/src/components/_desc-list.scss +180 -0
- package/src/components/_divider.scss +66 -0
- package/src/components/_dot.scss +115 -0
- package/src/components/_drawer.scss +200 -0
- package/src/components/_dropdown.scss +182 -0
- package/src/components/_empty-state.scss +146 -0
- package/src/components/_field-group.scss +68 -0
- package/src/components/_field-message.scss +75 -0
- package/src/components/_field.scss +127 -0
- package/src/components/_form-actions.scss +58 -0
- package/src/components/_info-row.scss +69 -0
- package/src/components/_input-group.scss +87 -0
- package/src/components/_input.scss +278 -0
- package/src/components/_list.scss +76 -0
- package/src/components/_modal.scss +168 -0
- package/src/components/_page-header.scss +85 -0
- package/src/components/_pagination.scss +138 -0
- package/src/components/_panel.scss +69 -0
- package/src/components/_popover.scss +154 -0
- package/src/components/_progress-circle.scss +123 -0
- package/src/components/_progress.scss +122 -0
- package/src/components/_radio.scss +162 -0
- package/src/components/_segmented.scss +183 -0
- package/src/components/_select.scss +154 -0
- package/src/components/_sidebar.scss +300 -0
- package/src/components/_skeleton.scss +90 -0
- package/src/components/_spinner.scss +84 -0
- package/src/components/_stat.scss +92 -0
- package/src/components/_table.scss +460 -0
- package/src/components/_tabs.scss +327 -0
- package/src/components/_tag.scss +143 -0
- package/src/components/_text.scss +42 -0
- package/src/components/_textarea.scss +57 -0
- package/src/components/_timeline.scss +196 -0
- package/src/components/_title.scss +41 -0
- package/src/components/_toast.scss +221 -0
- package/src/components/_toggle.scss +171 -0
- package/src/components/_toolbar.scss +74 -0
- package/src/components/_topbar.scss +204 -0
- package/src/entries/accordion.scss +4 -0
- package/src/entries/alert.scss +4 -0
- package/src/entries/autocomplete.scss +4 -0
- package/src/entries/avatar-group.scss +4 -0
- package/src/entries/avatar.scss +4 -0
- package/src/entries/badge.scss +4 -0
- package/src/entries/breadcrumb.scss +4 -0
- package/src/entries/btn-group.scss +4 -0
- package/src/entries/button.scss +4 -0
- package/src/entries/card.scss +4 -0
- package/src/entries/checkbox.scss +4 -0
- package/src/entries/code-block.scss +4 -0
- package/src/entries/confirm-modal.scss +4 -0
- package/src/entries/data-table.scss +4 -0
- package/src/entries/desc-list.scss +4 -0
- package/src/entries/divider.scss +4 -0
- package/src/entries/dot.scss +4 -0
- package/src/entries/drawer.scss +4 -0
- package/src/entries/dropdown.scss +4 -0
- package/src/entries/empty-state.scss +4 -0
- package/src/entries/field-group.scss +4 -0
- package/src/entries/field-message.scss +4 -0
- package/src/entries/field.scss +4 -0
- package/src/entries/form-actions.scss +4 -0
- package/src/entries/info-row.scss +4 -0
- package/src/entries/input-group.scss +4 -0
- package/src/entries/input.scss +4 -0
- package/src/entries/list.scss +4 -0
- package/src/entries/modal.scss +4 -0
- package/src/entries/page-header.scss +4 -0
- package/src/entries/pagination.scss +4 -0
- package/src/entries/panel.scss +4 -0
- package/src/entries/popover.scss +4 -0
- package/src/entries/progress-circle.scss +4 -0
- package/src/entries/progress.scss +4 -0
- package/src/entries/radio.scss +4 -0
- package/src/entries/segmented.scss +4 -0
- package/src/entries/select.scss +4 -0
- package/src/entries/sidebar.scss +4 -0
- package/src/entries/skeleton.scss +4 -0
- package/src/entries/spinner.scss +4 -0
- package/src/entries/stat.scss +4 -0
- package/src/entries/table.scss +4 -0
- package/src/entries/tabs.scss +4 -0
- package/src/entries/tag.scss +4 -0
- package/src/entries/text.scss +4 -0
- package/src/entries/textarea.scss +4 -0
- package/src/entries/timeline.scss +4 -0
- package/src/entries/title.scss +4 -0
- package/src/entries/toast.scss +4 -0
- package/src/entries/toggle.scss +4 -0
- package/src/entries/toolbar.scss +4 -0
- package/src/entries/topbar.scss +4 -0
- package/src/index.scss +7 -0
- package/src/js/autocomplete.js +86 -0
- package/src/js/data-table.js +141 -0
- package/src/js/index.js +34 -0
- package/src/js/input-clear.js +25 -0
- package/src/js/package.json +3 -0
- package/src/js/tabs.js +73 -0
- package/src/js/toast.js +161 -0
- package/src/js/util.js +21 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-checkbox
|
|
3
|
+
//// Custom checkbox with a label, a check mark and an indeterminate dash.
|
|
4
|
+
////
|
|
5
|
+
//// The box is 1em, so it follows the root type size. The `wu-checkbox-input` part also works alone with an `aria-label`.
|
|
6
|
+
////
|
|
7
|
+
//// Inside a `wu-field-group sm` or `lg`, a checkbox without its own size takes the group size.
|
|
8
|
+
////
|
|
9
|
+
//// @since 1.0.0
|
|
10
|
+
//// @needs none
|
|
11
|
+
//// @js none
|
|
12
|
+
//// @example html
|
|
13
|
+
//// <label class="wu-checkbox">
|
|
14
|
+
//// <input type="checkbox" class="wu-checkbox-input" name="terms" checked>
|
|
15
|
+
//// <span class="wu-checkbox-label">I accept the terms</span>
|
|
16
|
+
//// </label>
|
|
17
|
+
//// @example html
|
|
18
|
+
//// <label class="wu-checkbox sm">
|
|
19
|
+
//// <input type="checkbox" class="wu-checkbox-input" name="news" disabled>
|
|
20
|
+
//// <span class="wu-checkbox-label">Send the newsletter</span>
|
|
21
|
+
//// </label>
|
|
22
|
+
//// <input type="checkbox" class="wu-checkbox-input" name="all" aria-label="Select all">
|
|
23
|
+
//// @modifier sm | lg - Small or large font size, and so box size @since 1.0.0
|
|
24
|
+
//// @part wu-checkbox-input - The `input` drawn as a box @since 1.0.0
|
|
25
|
+
//// @part wu-checkbox-label - Label text next to the box @since 1.0.0
|
|
26
|
+
//// @state checked - Brand fill with a check mark @since 1.0.0
|
|
27
|
+
//// @state indeterminate - Brand fill with a dash @since 1.0.0
|
|
28
|
+
//// @state disabled - Half opacity and a not-allowed cursor @since 1.0.0
|
|
29
|
+
//// @state aria-invalid="true" - Danger edge that stays on hover and when checked @since 1.0.0
|
|
30
|
+
////
|
|
31
|
+
|
|
32
|
+
@use "@wovenui/core/mixins" as woven;
|
|
33
|
+
|
|
34
|
+
.wu-checkbox {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: flex-start;
|
|
37
|
+
gap: woven.token(space-2);
|
|
38
|
+
color: woven.token(text-regular);
|
|
39
|
+
font-size: woven.token(font-size-md);
|
|
40
|
+
line-height: woven.token(line-height-normal);
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
|
|
43
|
+
&:has(.wu-checkbox-input:disabled) {
|
|
44
|
+
opacity: woven.token(opacity-50);
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.wu-checkbox-input {
|
|
50
|
+
display: inline-grid;
|
|
51
|
+
flex: none;
|
|
52
|
+
place-content: center;
|
|
53
|
+
width: 1em;
|
|
54
|
+
height: 1em;
|
|
55
|
+
margin: 0;
|
|
56
|
+
margin-block-start: calc((1lh - 1em) / 2);
|
|
57
|
+
border: woven.token(border-width-1) solid woven.token(border-control);
|
|
58
|
+
border-radius: woven.token(radius-xs);
|
|
59
|
+
background: woven.token(bg-surface);
|
|
60
|
+
font-size: inherit;
|
|
61
|
+
line-height: inherit;
|
|
62
|
+
vertical-align: middle;
|
|
63
|
+
appearance: none;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
transition-property: background-color, border-color;
|
|
66
|
+
transition-duration: woven.token(duration-150);
|
|
67
|
+
transition-timing-function: woven.token(ease-out);
|
|
68
|
+
|
|
69
|
+
// Check mark, drawn with clip-path
|
|
70
|
+
&::before {
|
|
71
|
+
content: "";
|
|
72
|
+
width: 0.75em;
|
|
73
|
+
height: 0.75em;
|
|
74
|
+
background: woven.token(text-on-brand);
|
|
75
|
+
clip-path: var(--wu-kit-marker-check);
|
|
76
|
+
visibility: hidden;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&:hover:not(:disabled, :checked, :indeterminate) {
|
|
80
|
+
border-color: woven.token(border-control-hover);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
&:focus-visible {
|
|
84
|
+
outline: woven.token(border-focus-width) solid woven.token(border-focus);
|
|
85
|
+
outline-offset: woven.token(border-focus-offset);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&:is(:checked, :indeterminate) {
|
|
89
|
+
border-color: woven.token(brand);
|
|
90
|
+
background: woven.token(brand);
|
|
91
|
+
|
|
92
|
+
&::before {
|
|
93
|
+
visibility: visible;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&:hover:not(:disabled) {
|
|
97
|
+
border-color: woven.token(brand-hover);
|
|
98
|
+
background: woven.token(brand-hover);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Invalid: a 2px danger edge that stays on hover and when checked
|
|
103
|
+
&:is([aria-invalid="true"], :user-invalid),
|
|
104
|
+
&:is([aria-invalid="true"], :user-invalid):is(:hover, :checked, :indeterminate) {
|
|
105
|
+
border-color: woven.token(danger);
|
|
106
|
+
box-shadow: 0 0 0 woven.token(border-width-1) woven.token(danger);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Indeterminate dash
|
|
110
|
+
&:indeterminate::before {
|
|
111
|
+
clip-path: inset(40% 10%);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&:disabled {
|
|
115
|
+
opacity: woven.token(opacity-50);
|
|
116
|
+
cursor: not-allowed;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.wu-checkbox > &:disabled {
|
|
120
|
+
opacity: 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.wu-checkbox-label {
|
|
125
|
+
min-width: 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.wu-checkbox.sm {
|
|
129
|
+
font-size: woven.token(font-size-sm);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.wu-checkbox.lg {
|
|
133
|
+
font-size: woven.token(font-size-lg);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@media (forced-colors: active) {
|
|
137
|
+
.wu-checkbox-input {
|
|
138
|
+
border-color: CanvasText;
|
|
139
|
+
background: Canvas;
|
|
140
|
+
forced-color-adjust: none;
|
|
141
|
+
|
|
142
|
+
&::before {
|
|
143
|
+
background: HighlightText;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&:is(:checked, :indeterminate) {
|
|
147
|
+
border-color: Highlight;
|
|
148
|
+
background: Highlight;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&:disabled {
|
|
152
|
+
border-color: GrayText;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&:disabled:is(:checked, :indeterminate) {
|
|
156
|
+
background: GrayText;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Size from a wu-field-group sm or lg
|
|
162
|
+
:where(.wu-field-group.sm) .wu-checkbox:not(.sm, .lg) {
|
|
163
|
+
font-size: woven.token(font-size-sm);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
:where(.wu-field-group.lg) .wu-checkbox:not(.sm, .lg) {
|
|
167
|
+
font-size: woven.token(font-size-lg);
|
|
168
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-code-block
|
|
3
|
+
//// Scrollable block for code, with edge shadows when the content overflows.
|
|
4
|
+
////
|
|
5
|
+
//// Use `pre` with `code` inside, and add `tabindex="0"` and an `aria-label` so keyboard users can scroll it.
|
|
6
|
+
////
|
|
7
|
+
//// For line numbers, wrap each line in a `wu-code-block-line` span. The numbers are not copied or read aloud.
|
|
8
|
+
////
|
|
9
|
+
//// @since 1.0.0
|
|
10
|
+
//// @needs none
|
|
11
|
+
//// @js none
|
|
12
|
+
//// @example html
|
|
13
|
+
//// <pre class="wu-code-block" tabindex="0" aria-label="Install command"><code>pnpm add @wovenui/components</code></pre>
|
|
14
|
+
//// @example html
|
|
15
|
+
//// <pre class="wu-code-block" tabindex="0" aria-label="Example"><code><span class="wu-code-block-line">const a = 1;</span>
|
|
16
|
+
//// <span class="wu-code-block-line">const b = 2;</span></code></pre>
|
|
17
|
+
//// @part wu-code-block-line - Inline span for one line, with an optional line number @since 1.0.0
|
|
18
|
+
//// @variable --wu-code-block--Background [var(--wu-bg-alternate)] - Background of the block and of its scroll shadow covers @since 1.0.0
|
|
19
|
+
//// @variable --wu-code-block--FontFamily [ui-monospace] - Font family; the default is a system monospace stack @since 1.0.0
|
|
20
|
+
//// @state :focus-visible - Focus ring, for the scrollable block @since 1.0.0
|
|
21
|
+
////
|
|
22
|
+
|
|
23
|
+
@use "@wovenui/core/mixins" as woven;
|
|
24
|
+
|
|
25
|
+
$bg: var(--wu-code-block--Background, #{woven.token(bg-alternate)});
|
|
26
|
+
$shadow: color-mix(in srgb, #{woven.token(text-regular)} 15%, transparent);
|
|
27
|
+
|
|
28
|
+
.wu-code-block {
|
|
29
|
+
margin: 0;
|
|
30
|
+
padding: woven.token(space-4);
|
|
31
|
+
overflow: auto;
|
|
32
|
+
border: woven.token(border-width-1) solid woven.token(border-regular);
|
|
33
|
+
border-radius: woven.token(radius-md);
|
|
34
|
+
background:
|
|
35
|
+
linear-gradient(to right, #{$bg} 50%, transparent) left / #{woven.token(space-8)} 100% no-repeat local,
|
|
36
|
+
linear-gradient(to left, #{$bg} 50%, transparent) right / #{woven.token(space-8)} 100% no-repeat local,
|
|
37
|
+
linear-gradient(to right, #{$shadow}, transparent) left / #{woven.token(space-3)} 100% no-repeat scroll,
|
|
38
|
+
linear-gradient(to left, #{$shadow}, transparent) right / #{woven.token(space-3)} 100% no-repeat scroll,
|
|
39
|
+
#{$bg};
|
|
40
|
+
color: woven.token(text-regular);
|
|
41
|
+
font-family: var(--wu-code-block--FontFamily, ui-monospace, "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", monospace);
|
|
42
|
+
font-size: woven.token(font-size-sm);
|
|
43
|
+
line-height: woven.token(line-height-relaxed);
|
|
44
|
+
white-space: pre;
|
|
45
|
+
tab-size: 4;
|
|
46
|
+
counter-reset: wu-code-line;
|
|
47
|
+
|
|
48
|
+
// Undo core's inline code look
|
|
49
|
+
> code {
|
|
50
|
+
padding: 0;
|
|
51
|
+
border-radius: 0;
|
|
52
|
+
background: none;
|
|
53
|
+
color: inherit;
|
|
54
|
+
font: inherit;
|
|
55
|
+
white-space: inherit;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:focus-visible {
|
|
59
|
+
outline: woven.token(border-focus-width) solid woven.token(border-focus);
|
|
60
|
+
outline-offset: woven.token(border-focus-offset);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Optional line numbers: wrap each line in an inline span. Numbers are not copied or read aloud.
|
|
65
|
+
.wu-code-block-line {
|
|
66
|
+
counter-increment: wu-code-line;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.wu-code-block-line::before {
|
|
70
|
+
content: counter(wu-code-line);
|
|
71
|
+
content: counter(wu-code-line) / "";
|
|
72
|
+
display: inline-block;
|
|
73
|
+
min-width: 3ch;
|
|
74
|
+
margin-inline-end: woven.token(space-4);
|
|
75
|
+
color: woven.token(text-muted);
|
|
76
|
+
text-align: end;
|
|
77
|
+
user-select: none;
|
|
78
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-confirm-modal
|
|
3
|
+
//// Dialog that asks the user to confirm or cancel an action, with a title, a message and two buttons.
|
|
4
|
+
////
|
|
5
|
+
//// Builds on `wu-modal` for open, close, backdrop and motion, and on `wu-btn` for the actions. Use `role="alertdialog"`.
|
|
6
|
+
////
|
|
7
|
+
//// The subject is optional and names the object. `danger` gives the message full weight; the confirming button takes `wu-btn danger`. `dialog.returnValue` holds the value of the button that closed it.
|
|
8
|
+
////
|
|
9
|
+
//// @since 1.0.0
|
|
10
|
+
//// @needs modal, button
|
|
11
|
+
//// @js none
|
|
12
|
+
//// @example html
|
|
13
|
+
//// <button class="wu-btn" type="button" commandfor="c1" command="show-modal">Delete</button>
|
|
14
|
+
//// <dialog class="wu-modal wu-confirm-modal danger" id="c1" role="alertdialog" aria-labelledby="c1-title" aria-describedby="c1-subject c1-message">
|
|
15
|
+
//// <h2 class="wu-confirm-modal-title" id="c1-title">Delete project?</h2>
|
|
16
|
+
//// <p class="wu-confirm-modal-subject" id="c1-subject">Website redesign</p>
|
|
17
|
+
//// <p class="wu-confirm-modal-message" id="c1-message">This cannot be undone.</p>
|
|
18
|
+
//// <form class="wu-confirm-modal-actions" method="dialog">
|
|
19
|
+
//// <button class="wu-btn" value="cancel" autofocus>Cancel</button>
|
|
20
|
+
//// <button class="wu-btn danger" value="confirm">Delete</button>
|
|
21
|
+
//// </form>
|
|
22
|
+
//// </dialog>
|
|
23
|
+
//// @modifier danger - Message at full contrast and body size, for destructive actions @since 1.0.0
|
|
24
|
+
//// @part wu-confirm-modal-title - Heading that names the question @since 1.0.0
|
|
25
|
+
//// @part wu-confirm-modal-subject - Optional line that names the object the action applies to @since 1.0.0
|
|
26
|
+
//// @part wu-confirm-modal-message - Supporting text about the consequence @since 1.0.0
|
|
27
|
+
//// @part wu-confirm-modal-actions - Form that holds the buttons, aligned to the end @since 1.0.0
|
|
28
|
+
//// @variable --wu-confirm-modal--Width [26rem] - Width of the dialog @since 1.0.0
|
|
29
|
+
////
|
|
30
|
+
|
|
31
|
+
@use "@wovenui/core/mixins" as woven;
|
|
32
|
+
|
|
33
|
+
.wu-confirm-modal {
|
|
34
|
+
gap: woven.token(space-2);
|
|
35
|
+
inline-size: var(--wu-confirm-modal--Width, 26rem);
|
|
36
|
+
padding: woven.token(space-6);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.wu-confirm-modal-title {
|
|
40
|
+
margin: 0;
|
|
41
|
+
font-size: woven.token(font-size-lg);
|
|
42
|
+
font-weight: woven.token(font-weight-semibold);
|
|
43
|
+
line-height: woven.token(line-height-tight);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Names the object the action applies to
|
|
47
|
+
.wu-confirm-modal-subject {
|
|
48
|
+
margin: 0;
|
|
49
|
+
color: woven.token(text-regular);
|
|
50
|
+
font-weight: woven.token(font-weight-semibold);
|
|
51
|
+
overflow-wrap: anywhere;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.wu-confirm-modal-message {
|
|
55
|
+
margin: 0;
|
|
56
|
+
color: woven.token(text-muted);
|
|
57
|
+
font-size: woven.token(font-size-sm);
|
|
58
|
+
line-height: woven.token(line-height-normal);
|
|
59
|
+
text-wrap: pretty;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.wu-confirm-modal-actions {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-wrap: wrap;
|
|
65
|
+
justify-content: flex-end;
|
|
66
|
+
gap: woven.token(space-2);
|
|
67
|
+
margin: 0;
|
|
68
|
+
margin-block-start: woven.token(space-4);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Destructive confirm: the stakes read at full contrast and body size
|
|
72
|
+
.wu-confirm-modal.danger .wu-confirm-modal-message {
|
|
73
|
+
color: woven.token(text-regular);
|
|
74
|
+
font-size: woven.token(font-size-md);
|
|
75
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-data-table
|
|
3
|
+
//// Sortable table: click a header to sort rows by text or number.
|
|
4
|
+
////
|
|
5
|
+
//// Add it to a `wu-table`; the sort button and arrows come from the table component, and the kit script sorts the first `tbody` and sets `aria-sort`. A `data-sort-value` on a cell wins over its text.
|
|
6
|
+
////
|
|
7
|
+
//// The script adds a `wu-data-table-status` live region after the table and announces each sort there.
|
|
8
|
+
////
|
|
9
|
+
//// @since 1.0.0
|
|
10
|
+
//// @needs table
|
|
11
|
+
//// @js required initDataTable
|
|
12
|
+
//// @example html
|
|
13
|
+
//// <table class="wu-table wu-data-table">
|
|
14
|
+
//// <thead>
|
|
15
|
+
//// <tr>
|
|
16
|
+
//// <th scope="col" aria-sort="ascending"><button class="wu-table-sort" type="button">Name</button></th>
|
|
17
|
+
//// <th scope="col" class="wu-table-num"><button class="wu-table-sort" type="button">Amount</button></th>
|
|
18
|
+
//// </tr>
|
|
19
|
+
//// </thead>
|
|
20
|
+
//// <tbody>
|
|
21
|
+
//// <tr><td>Ada</td><td class="wu-table-num" data-sort-value="1200">$1,200</td></tr>
|
|
22
|
+
//// <tr><td>Grace</td><td class="wu-table-num" data-sort-value="950">$950</td></tr>
|
|
23
|
+
//// </tbody>
|
|
24
|
+
//// </table>
|
|
25
|
+
//// @modifier animated - Rows glide to their new place when the user allows motion; `wu-animated` on an ancestor does the same @since 1.0.0
|
|
26
|
+
//// @part wu-data-table-status - Visually hidden live region added by the script to announce each sort @since 1.0.0
|
|
27
|
+
//// @part wu-data-table-row - View transition class, not an HTML class, set on body rows while they move; target `::view-transition-group(*.wu-data-table-row)` to restyle the glide @since 1.0.0
|
|
28
|
+
//// @state aria-sort="ascending" - Header cell sorted ascending, set by the script @since 1.0.0
|
|
29
|
+
//// @state aria-sort="descending" - Header cell sorted descending, set by the script @since 1.0.0
|
|
30
|
+
//// @state aria-busy="true" - Set while rows move: progress cursor, and the row animation runs @since 1.0.0
|
|
31
|
+
////
|
|
32
|
+
|
|
33
|
+
@use "@wovenui/core/mixins" as woven;
|
|
34
|
+
|
|
35
|
+
.wu-data-table[aria-busy="true"] {
|
|
36
|
+
cursor: progress;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Larger sort arrows than the plain table's, drawn at 1.25 times its paths
|
|
40
|
+
.wu-data-table .wu-table-sort::after {
|
|
41
|
+
width: 10px;
|
|
42
|
+
height: 15px;
|
|
43
|
+
clip-path: path("M5 0L10 6.25H0Z M0 8.75H10L5 15Z");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.wu-data-table th[aria-sort="ascending"] > .wu-table-sort::after {
|
|
47
|
+
clip-path: path("M5 4.375L10 10.625H0Z");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.wu-data-table th[aria-sort="descending"] > .wu-table-sort::after {
|
|
51
|
+
clip-path: path("M0 4.375H10L5 10.625Z");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Visually hidden live region for the sort announcement
|
|
55
|
+
.wu-data-table-status {
|
|
56
|
+
position: absolute;
|
|
57
|
+
inline-size: 1px;
|
|
58
|
+
block-size: 1px;
|
|
59
|
+
margin: -1px;
|
|
60
|
+
padding: 0;
|
|
61
|
+
border: 0;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
clip-path: inset(50%);
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Opt-in motion: rows glide to their new place (view transition, started by the script)
|
|
68
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
69
|
+
.wu-data-table.animated[aria-busy="true"] > tbody > tr,
|
|
70
|
+
.wu-animated .wu-data-table[aria-busy="true"] > tbody > tr {
|
|
71
|
+
view-transition-class: wu-data-table-row;
|
|
72
|
+
view-transition-name: match-element;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
::view-transition-group(*.wu-data-table-row) {
|
|
76
|
+
animation-duration: woven.token(duration-300);
|
|
77
|
+
animation-timing-function: woven.token(ease-out);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-desc-list
|
|
3
|
+
//// Description list of terms and values, plain, divided, bordered or in columns.
|
|
4
|
+
////
|
|
5
|
+
//// Use a `dl`; wrap each pair in a `div` for divided, bordered and column layouts.
|
|
6
|
+
////
|
|
7
|
+
//// @since 1.0.0
|
|
8
|
+
//// @needs none
|
|
9
|
+
//// @js none
|
|
10
|
+
//// @example html
|
|
11
|
+
//// <dl class="wu-desc-list horizontal divided">
|
|
12
|
+
//// <div><dt>Name</dt><dd>Ada Lovelace</dd></div>
|
|
13
|
+
//// <div><dt>Role</dt><dd>Engineer</dd></div>
|
|
14
|
+
//// </dl>
|
|
15
|
+
//// @example html
|
|
16
|
+
//// <dl class="wu-desc-list bordered">
|
|
17
|
+
//// <div><dt>Plan</dt><dd>Team</dd></div>
|
|
18
|
+
//// <div><dt>Seats</dt><dd>12</dd></div>
|
|
19
|
+
//// </dl>
|
|
20
|
+
//// @example html
|
|
21
|
+
//// <dl class="wu-desc-list columns">
|
|
22
|
+
//// <div><dt>City</dt><dd>Berlin</dd></div>
|
|
23
|
+
//// <div><dt>Country</dt><dd>Germany</dd></div>
|
|
24
|
+
//// <div><dt>Timezone</dt><dd>CET</dd></div>
|
|
25
|
+
//// </dl>
|
|
26
|
+
//// @modifier horizontal - Terms in a column beside their descriptions @since 1.0.0
|
|
27
|
+
//// @modifier divided - Lines between the `div` pairs @since 1.0.0
|
|
28
|
+
//// @modifier bordered - Table look: lines around every cell, terms on the alternate background @since 1.0.0
|
|
29
|
+
//// @modifier columns - Several pairs per row; with `bordered`, each pair is a term cell beside its description @since 1.0.0
|
|
30
|
+
//// @variable --wu-desc-list--TermWidth [fit-content(40%)] - Width of the term column in `horizontal` and `bordered` @since 1.0.0
|
|
31
|
+
//// @variable --wu-desc-list--Columns [3] - Most pairs per row in `columns` @since 1.0.0
|
|
32
|
+
//// @variable --wu-desc-list--ColumnWidth [10rem] - Narrowest a pair gets in `columns` before a row holds fewer @since 1.0.0
|
|
33
|
+
////
|
|
34
|
+
|
|
35
|
+
@use "@wovenui/core/mixins" as woven;
|
|
36
|
+
|
|
37
|
+
.wu-desc-list {
|
|
38
|
+
margin: 0;
|
|
39
|
+
color: woven.token(text-regular);
|
|
40
|
+
font-size: woven.token(font-size-sm);
|
|
41
|
+
line-height: woven.token(line-height-normal);
|
|
42
|
+
|
|
43
|
+
> dt,
|
|
44
|
+
> div > dt {
|
|
45
|
+
color: woven.token(text-muted);
|
|
46
|
+
font-weight: woven.token(font-weight-medium);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
> dd,
|
|
50
|
+
> div > dd {
|
|
51
|
+
margin: 0;
|
|
52
|
+
text-wrap: pretty;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
> dt + dd,
|
|
56
|
+
> dd + dd,
|
|
57
|
+
> div > dt + dd,
|
|
58
|
+
> div > dd + dd {
|
|
59
|
+
margin-block-start: woven.token(space-1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
> dd + dt,
|
|
63
|
+
> div + div {
|
|
64
|
+
margin-block-start: woven.token(space-4);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Terms in a column beside their descriptions; --wu-desc-list--TermWidth sets the column
|
|
69
|
+
.wu-desc-list.horizontal {
|
|
70
|
+
display: grid;
|
|
71
|
+
grid-template-columns: var(--wu-desc-list--TermWidth, fit-content(40%)) minmax(0, 1fr);
|
|
72
|
+
gap: woven.token(space-3) woven.token(space-6);
|
|
73
|
+
|
|
74
|
+
> div {
|
|
75
|
+
display: grid;
|
|
76
|
+
grid-column: 1 / -1;
|
|
77
|
+
grid-template-columns: subgrid;
|
|
78
|
+
row-gap: woven.token(space-1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
> dt,
|
|
82
|
+
> div > dt {
|
|
83
|
+
grid-column: 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
> dd,
|
|
87
|
+
> div > dd {
|
|
88
|
+
grid-column: 2;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// The grid gaps space the rows
|
|
92
|
+
> *,
|
|
93
|
+
> div > * {
|
|
94
|
+
margin-block-start: 0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Lines between <div> groups
|
|
99
|
+
.wu-desc-list.divided > div + div {
|
|
100
|
+
padding-block-start: woven.token(space-3);
|
|
101
|
+
border-block-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Bordered: term and description cells with lines between them, terms on the alternate background.
|
|
105
|
+
// Each cell draws its top and start line 1px outside itself; the root clips the outer ones behind its own border.
|
|
106
|
+
.wu-desc-list.bordered {
|
|
107
|
+
display: grid;
|
|
108
|
+
grid-template-columns: var(--wu-desc-list--TermWidth, fit-content(40%)) minmax(0, 1fr);
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
border: woven.token(border-width-1) solid woven.token(border-regular);
|
|
111
|
+
border-radius: woven.token(radius-md);
|
|
112
|
+
background: woven.token(bg-surface);
|
|
113
|
+
|
|
114
|
+
> div {
|
|
115
|
+
display: grid;
|
|
116
|
+
grid-column: 1 / -1;
|
|
117
|
+
grid-template-columns: subgrid;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
> dt,
|
|
121
|
+
> dd,
|
|
122
|
+
> div > dt,
|
|
123
|
+
> div > dd {
|
|
124
|
+
margin-block-start: calc(-1 * #{woven.token(border-width-1)});
|
|
125
|
+
margin-inline-start: calc(-1 * #{woven.token(border-width-1)});
|
|
126
|
+
padding-block: woven.token(space-2);
|
|
127
|
+
padding-inline: woven.token(space-3);
|
|
128
|
+
border-block-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
129
|
+
border-inline-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
> dt,
|
|
133
|
+
> div > dt {
|
|
134
|
+
grid-column: 1;
|
|
135
|
+
background: woven.token(bg-alternate);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
> dd,
|
|
139
|
+
> div > dd {
|
|
140
|
+
grid-column: 2;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
> div + div {
|
|
144
|
+
margin-block-start: 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Columns: pairs side by side, at most --wu-desc-list--Columns per row (3), fewer when a pair would be narrower
|
|
149
|
+
// than --wu-desc-list--ColumnWidth (10rem)
|
|
150
|
+
@mixin -columns($gap: null) {
|
|
151
|
+
$count: var(--wu-desc-list--Columns, 3);
|
|
152
|
+
$share: "100% / #{$count}";
|
|
153
|
+
|
|
154
|
+
@if $gap {
|
|
155
|
+
$share: "(100% - (#{$count} - 1) * #{$gap}) / #{$count}";
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
grid-template-columns: repeat(auto-fill, minmax(min(100%, max(var(--wu-desc-list--ColumnWidth, 10rem), #{$share})), 1fr));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.wu-desc-list.columns {
|
|
162
|
+
display: grid;
|
|
163
|
+
gap: woven.token(space-4) woven.token(space-6);
|
|
164
|
+
@include -columns(woven.token(space-6));
|
|
165
|
+
|
|
166
|
+
> div + div {
|
|
167
|
+
margin-block-start: 0;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Bordered columns: each pair is a term cell beside its description cell
|
|
172
|
+
.wu-desc-list.bordered.columns {
|
|
173
|
+
gap: 0;
|
|
174
|
+
@include -columns;
|
|
175
|
+
|
|
176
|
+
> div {
|
|
177
|
+
grid-column: auto;
|
|
178
|
+
grid-template-columns: var(--wu-desc-list--TermWidth, 40%) minmax(0, 1fr);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
////
|
|
2
|
+
//// @component wu-divider
|
|
3
|
+
//// Horizontal or vertical separator line, optionally with a text label between two lines.
|
|
4
|
+
////
|
|
5
|
+
//// Use an `hr` element. `aria-orientation="vertical"` turns it into a vertical line between inline items. With content, the text is read and the lines are decoration.
|
|
6
|
+
////
|
|
7
|
+
//// @since 1.0.0
|
|
8
|
+
//// @needs none
|
|
9
|
+
//// @js none
|
|
10
|
+
//// @example html
|
|
11
|
+
//// <hr class="wu-divider">
|
|
12
|
+
//// <hr class="wu-divider dashed">
|
|
13
|
+
//// @example html
|
|
14
|
+
//// <div class="wu-divider">or</div>
|
|
15
|
+
//// @example html
|
|
16
|
+
//// <span>Edit</span><hr class="wu-divider" aria-orientation="vertical"><span>Share</span>
|
|
17
|
+
//// @modifier dashed - Dashed line, also on the lines beside a label @since 1.0.0
|
|
18
|
+
//// @state aria-orientation="vertical" - Vertical line that stretches to the row height @since 1.0.0
|
|
19
|
+
//// @state :not(:empty) - With content: the text sits between two lines @since 1.0.0
|
|
20
|
+
////
|
|
21
|
+
|
|
22
|
+
@use "@wovenui/core/mixins" as woven;
|
|
23
|
+
|
|
24
|
+
.wu-divider {
|
|
25
|
+
height: 0;
|
|
26
|
+
margin-block: woven.token(space-4);
|
|
27
|
+
margin-inline: 0;
|
|
28
|
+
border: 0;
|
|
29
|
+
border-block-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.wu-divider[aria-orientation="vertical"] {
|
|
33
|
+
display: inline-block;
|
|
34
|
+
align-self: stretch;
|
|
35
|
+
width: 0;
|
|
36
|
+
height: auto;
|
|
37
|
+
min-height: 1em;
|
|
38
|
+
margin-block: 0;
|
|
39
|
+
margin-inline: woven.token(space-2);
|
|
40
|
+
border-block-start: 0;
|
|
41
|
+
border-inline-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
42
|
+
vertical-align: middle;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.wu-divider:not(:empty) {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: woven.token(space-3);
|
|
49
|
+
height: auto;
|
|
50
|
+
border-block-start: 0;
|
|
51
|
+
color: woven.token(text-muted);
|
|
52
|
+
font-size: woven.token(font-size-xs);
|
|
53
|
+
|
|
54
|
+
&::before,
|
|
55
|
+
&::after {
|
|
56
|
+
content: "";
|
|
57
|
+
flex: 1;
|
|
58
|
+
border-block-start: woven.token(border-width-1) solid woven.token(border-regular);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.wu-divider.dashed,
|
|
63
|
+
.wu-divider.dashed::before,
|
|
64
|
+
.wu-divider.dashed::after {
|
|
65
|
+
border-style: dashed;
|
|
66
|
+
}
|