use-wc 1.0.0-pre.81 → 1.0.0-pre.83
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/custom-elements.json +1 -1
- package/dist/design-system.css +285 -22
- package/dist/docs/use-control-set.md +15 -1
- package/dist/tokens.css +26 -1
- package/package.json +1 -1
- package/vscode.html-custom-data.json +1 -1
package/custom-elements.json
CHANGED
|
@@ -843,7 +843,7 @@
|
|
|
843
843
|
"declarations": [
|
|
844
844
|
{
|
|
845
845
|
"kind": "class",
|
|
846
|
-
"description": "Groups adjacent controls — buttons and text-style inputs alike — into one visual unit: shared\nborders between touching children, rounded corners only on the two outer ends, and a hovered\nor focused child's border lifted above its neighbors so the whole border reads clearly.\n\n`use-control-set` renders no shadow DOM and no template of its own — it exists only as a\ndedicated tag for `theme/control-set.css` to style, the same way `use-layout` is a bare\nprimitive rather than a specific look. A classic split button is a text button followed by an\nicon-only trigger for a `use-menu`:\n\n```html\n<use-control-set>\n <button type=\"button\">Save</button>\n <button type=\"button\" popovertarget=\"save-options\" aria-label=\"More save options\">\n <use-caret></use-caret>\n </button>\n</use-control-set>\n<use-menu id=\"save-options\" aria-label=\"More save options\">\n <button role=\"menuitem\">Save as…</button>\n</use-menu>\n```\n\nA search box with an attached submit button follows the same shape, mixing a text input with a\nbutton:\n\n```html\n<use-control-set>\n <input type=\"search\" placeholder=\"Search\" />\n <button type=\"submit\">Go</button>\n</use-control-set>\n```\n\nA child is a `<button>`, anything wearing `.appearance-button`, an `<input>` (other than a\ncheckbox/radio/range/file), a `<select>`, a `<textarea>`, or anything wearing\n`.appearance-input` — see `theme/control-set.css` for exactly which selectors read which\nradius/border tokens.\n\nHow the touching sides render is themeable rather than fixed: `--usewc-layout-control-set-gap`\n(default: a negative overlap equal to the child's own border, for a seamless merged line) and\n`--usewc-effect-control-set-border-radius-sequential` (default: `0`, for square touching\ncorners) can both be overridden — a positive gap and a small radius reads as a looser, softer\nset instead of a fused one.",
|
|
846
|
+
"description": "Groups adjacent controls — buttons and text-style inputs alike — into one visual unit: shared\nborders between touching children, rounded corners only on the two outer ends, and a hovered\nor focused child's border lifted above its neighbors so the whole border reads clearly.\n\n`use-control-set` renders no shadow DOM and no template of its own — it exists only as a\ndedicated tag for `theme/control-set.css` to style, the same way `use-layout` is a bare\nprimitive rather than a specific look. A classic split button is a text button followed by an\nicon-only trigger for a `use-menu`:\n\n```html\n<use-control-set>\n <button type=\"button\">Save</button>\n <button type=\"button\" popovertarget=\"save-options\" aria-label=\"More save options\">\n <use-caret></use-caret>\n </button>\n</use-control-set>\n<use-menu id=\"save-options\" aria-label=\"More save options\">\n <button role=\"menuitem\">Save as…</button>\n</use-menu>\n```\n\nA search box with an attached submit button follows the same shape, mixing a text input with a\nbutton:\n\n```html\n<use-control-set>\n <input type=\"search\" placeholder=\"Search\" />\n <button type=\"submit\">Go</button>\n</use-control-set>\n```\n\nA child is a `<button>`, anything wearing `.appearance-button`, an `<input>` (other than a\ncheckbox/radio/range/file), a `<select>`, a `<textarea>`, or anything wearing\n`.appearance-input` — see `theme/control-set.css` for exactly which selectors read which\nradius/border tokens. A plain `span` renders as a static text cell between controls.\n\nPagination follows the same shape, with `a.appearance-button` links and `aria-current=\"page\"`\nholding the current page in its pressed look:\n\n```html\n<nav aria-label=\"Pagination\">\n <use-control-set>\n <a class=\"appearance-button\" href=\"?page=1\">1</a>\n <a class=\"appearance-button\" href=\"?page=2\" aria-current=\"page\">2</a>\n <span aria-hidden=\"true\">…</span>\n <a class=\"appearance-button\" href=\"?page=10\">10</a>\n </use-control-set>\n</nav>\n```\n\nHow the touching sides render is themeable rather than fixed: `--usewc-layout-control-set-gap`\n(default: a negative overlap equal to the child's own border, for a seamless merged line) and\n`--usewc-effect-control-set-border-radius-sequential` (default: `0`, for square touching\ncorners) can both be overridden — a positive gap and a small radius reads as a looser, softer\nset instead of a fused one.",
|
|
847
847
|
"name": "UseControlSet",
|
|
848
848
|
"slots": [
|
|
849
849
|
{
|
package/dist/design-system.css
CHANGED
|
@@ -370,22 +370,49 @@
|
|
|
370
370
|
text exactly here instead of staying a lighter tint of it. */
|
|
371
371
|
--usewc-local-link-decoration-opacity: 1;
|
|
372
372
|
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
373
375
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
376
|
+
/* `nav.breadcrumb` lays an `ol` of links out as a single wrapping trail. The separator is
|
|
377
|
+
generated content on every item after the first, reading its glyph from
|
|
378
|
+
`--usewc-effect-breadcrumb-separator` with empty alt text (`/ ""`), so assistive tech hears the
|
|
379
|
+
list structure rather than a run of slashes.
|
|
380
|
+
|
|
381
|
+
The current page is marked with `aria-current="page"` on its link. Rather than restyling
|
|
382
|
+
`color` directly, it swaps the link's own source tokens — the same approach `nav.sidebar` takes
|
|
383
|
+
in `link.css` — so every link state resolves to the document's ink instead of link blue. The
|
|
384
|
+
link's underline is already off here, since `link.css` treats every link inside a `nav` as
|
|
385
|
+
chrome. */
|
|
386
|
+
@layer use-theme.breadcrumb {
|
|
387
|
+
nav.breadcrumb > ol {
|
|
388
|
+
display: flex;
|
|
389
|
+
flex-wrap: wrap;
|
|
390
|
+
align-items: center;
|
|
391
|
+
gap: var(--usewc-layout-breadcrumb-gap);
|
|
392
|
+
margin: 0;
|
|
393
|
+
padding: 0;
|
|
394
|
+
list-style: none;
|
|
385
395
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
396
|
+
> li {
|
|
397
|
+
display: inline-flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
gap: var(--usewc-layout-breadcrumb-gap);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
> li + li::before {
|
|
403
|
+
content: var(--usewc-effect-breadcrumb-separator) / "";
|
|
404
|
+
color: var(--usewc-color-breadcrumb-separator);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
[aria-current="page"] {
|
|
408
|
+
--usewc-color-link-text-static: var(--usewc-color-breadcrumb-current-text);
|
|
409
|
+
--usewc-color-link-text-hover: var(--usewc-color-breadcrumb-current-text);
|
|
410
|
+
--usewc-color-link-text-active: var(--usewc-color-breadcrumb-current-text);
|
|
411
|
+
cursor: default;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
use-theme-escape & {
|
|
415
|
+
all: revert-layer;
|
|
389
416
|
}
|
|
390
417
|
}
|
|
391
418
|
}
|
|
@@ -509,12 +536,13 @@
|
|
|
509
536
|
}
|
|
510
537
|
}
|
|
511
538
|
|
|
512
|
-
&:not([type="file"]):is([aria-label], [aria-labelledby]):has(> use-caret:empty, > svg:only-child) {
|
|
539
|
+
&:not([type="file"]):is([aria-label], [aria-labelledby]):has(> use-caret:empty, > :is(svg, .icon):only-child) {
|
|
513
540
|
/*
|
|
514
541
|
* :empty on use-caret checks for no text nodes at all, not just "no element siblings" —
|
|
515
542
|
* that's what makes it safe to key square sizing off of: a caret with a label
|
|
516
|
-
* (<use-caret>Menu</use-caret>) never matches. svg
|
|
517
|
-
*
|
|
543
|
+
* (<use-caret>Menu</use-caret>) never matches. An `svg` — or an `.icon` wrapping a single
|
|
544
|
+
* standard character like `×` — as the only child has no such guarantee —
|
|
545
|
+
* a text node beside it (`<button><svg>…</svg> Show code</button>`) still passes it,
|
|
518
546
|
* since `:only-child` only counts sibling *elements* — so it's gated behind
|
|
519
547
|
* `[aria-label]`/`[aria-labelledby]` too: a real icon-only button needs one of those for
|
|
520
548
|
* accessibility regardless, while a button with its own visible text normally carries
|
|
@@ -654,6 +682,21 @@
|
|
|
654
682
|
--usewc-effect-button-box-shadow-active: none;
|
|
655
683
|
}
|
|
656
684
|
|
|
685
|
+
/* A current or pressed button holds its variant's own pressed look at rest and on hover — the
|
|
686
|
+
current page in a pagination `use-control-set`, or a toggle that's on. It comes after the
|
|
687
|
+
variant blocks so it re-points whichever `-active` values they set, rather than the base
|
|
688
|
+
ones. */
|
|
689
|
+
&:is([aria-current]:not([aria-current="false"]), [aria-pressed="true"]) {
|
|
690
|
+
--usewc-color-button-text-static: var(--usewc-color-button-text-active);
|
|
691
|
+
--usewc-color-button-background-static: var(--usewc-color-button-background-active);
|
|
692
|
+
--usewc-color-button-border-static: var(--usewc-color-button-border-active);
|
|
693
|
+
--usewc-color-button-text-hover: var(--usewc-color-button-text-active);
|
|
694
|
+
--usewc-color-button-background-hover: var(--usewc-color-button-background-active);
|
|
695
|
+
--usewc-color-button-border-hover: var(--usewc-color-button-border-active);
|
|
696
|
+
--usewc-effect-button-box-shadow-static: var(--usewc-effect-button-box-shadow-active);
|
|
697
|
+
--usewc-effect-button-box-shadow-hover: var(--usewc-effect-button-box-shadow-active);
|
|
698
|
+
}
|
|
699
|
+
|
|
657
700
|
&.extra-small {
|
|
658
701
|
--usewc-layout-button-padding-block: var(--usewc-layout-button-extra-small-padding-block);
|
|
659
702
|
--usewc-layout-button-padding-inline: var(--usewc-layout-button-extra-small-padding-inline);
|
|
@@ -751,6 +794,25 @@
|
|
|
751
794
|
all: revert-layer;
|
|
752
795
|
}
|
|
753
796
|
}
|
|
797
|
+
|
|
798
|
+
/* A plain `span` is a static text cell rather than a control — pagination's ellipsis, or a
|
|
799
|
+
unit beside an input. It borrows a base button's border, face, and inline padding so the
|
|
800
|
+
strip's outline stays unbroken through it, and stretches to its neighbors' height through
|
|
801
|
+
the container's default `align-items: stretch` instead of needing its own block padding. */
|
|
802
|
+
use-control-set > span:not([class*="appearance-"]) {
|
|
803
|
+
display: inline-flex;
|
|
804
|
+
align-items: center;
|
|
805
|
+
padding-inline: var(--usewc-layout-button-base-padding-inline);
|
|
806
|
+
font-size: var(--usewc-font-button-base-size);
|
|
807
|
+
color: var(--usewc-color-document-text-muted);
|
|
808
|
+
background: var(--usewc-color-button-base-background-static);
|
|
809
|
+
border: var(--usewc-layout-button-border) var(--usewc-effect-button-border-style)
|
|
810
|
+
var(--usewc-color-button-base-border-static);
|
|
811
|
+
|
|
812
|
+
use-theme-escape & {
|
|
813
|
+
all: revert-layer;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
754
816
|
}
|
|
755
817
|
|
|
756
818
|
@layer use-theme.code {
|
|
@@ -872,8 +934,8 @@
|
|
|
872
934
|
mask-position: center;
|
|
873
935
|
}
|
|
874
936
|
|
|
875
|
-
&:is([open], :open) summary:not([class*="appearance-"])::before,
|
|
876
|
-
&:is([open], :open) summary.appearance-button::before {
|
|
937
|
+
&:is([open], :open) > summary:not([class*="appearance-"])::before,
|
|
938
|
+
&:is([open], :open) > summary.appearance-button::before {
|
|
877
939
|
mask-image: var(--usewc-effect-dropdown-trigger-icon-mask-image, none);
|
|
878
940
|
}
|
|
879
941
|
|
|
@@ -895,6 +957,191 @@
|
|
|
895
957
|
}
|
|
896
958
|
}
|
|
897
959
|
|
|
960
|
+
/* `nav.sidebar` turns every link inside it, at any depth, into a padded row with a hover
|
|
961
|
+
background — a nested `a` would be invalid HTML anyway, so matching descendants can't reach
|
|
962
|
+
anything that isn't a nav item. It lives in its own layer after `link.css` and `details.css` so
|
|
963
|
+
its plain selectors outrank both without a specificity fight.
|
|
964
|
+
|
|
965
|
+
Links keep `link.css`'s own state machinery: this swaps the source tokens it reads through
|
|
966
|
+
(`--usewc-color-link-text-static`/`-hover`/`-active`) rather than setting `color` directly, so
|
|
967
|
+
every existing state recolors at once. `aria-current="page"` swaps the same tokens again for the
|
|
968
|
+
current page.
|
|
969
|
+
|
|
970
|
+
A `details` inside the sidebar is a collapsible group: its `summary` renders as the same kind of
|
|
971
|
+
row, keeping `details.css`'s caret. When the summary starts with an icon (`svg` or `.icon`), the
|
|
972
|
+
icon shows at rest and the caret takes its place on hover or keyboard focus — both share
|
|
973
|
+
`--usewc-layout-sidebar-item-icon-size`, so the swap never shifts the label.
|
|
974
|
+
|
|
975
|
+
Everything after the summary hangs off a guide line centered under the summary's icon column,
|
|
976
|
+
drawn once on the group's `::details-content` rather than on each row, so the rows' own rounded
|
|
977
|
+
corners never bend it, and nested rows get just enough inline padding to land their text under
|
|
978
|
+
the summary's text.
|
|
979
|
+
Rows below the top level all share one derived padding, which is why a group nested two deep
|
|
980
|
+
reads its offset from that padding instead of the top-level one.
|
|
981
|
+
|
|
982
|
+
Rows can sit directly in the nav or in `ul`/`ol` lists — lists are recommended, since assistive
|
|
983
|
+
tech announces their item count — and lists lose their bullets and indentation here so both
|
|
984
|
+
shapes render the same. That's also why a top-level group is found as a `details` with no
|
|
985
|
+
`details` ancestor rather than as a direct child of the nav.
|
|
986
|
+
|
|
987
|
+
Headings that are direct children of the nav are group labels. Only direct children count,
|
|
988
|
+
since a sidebar row can hold its own heading inside a nested `use-pattern`. */
|
|
989
|
+
@layer use-theme.sidebar {
|
|
990
|
+
nav.sidebar {
|
|
991
|
+
--usewc-local-sidebar-nested-padding-inline-start: calc(
|
|
992
|
+
var(--usewc-layout-sidebar-item-icon-size) / 2 + var(--usewc-layout-sidebar-item-gap) -
|
|
993
|
+
var(--usewc-layout-sidebar-nested-guide-width) / 2 - var(--usewc-layout-sidebar-nested-guide-gap)
|
|
994
|
+
);
|
|
995
|
+
|
|
996
|
+
:is(a, summary):not([class*="appearance-"]) {
|
|
997
|
+
display: flex;
|
|
998
|
+
align-items: center;
|
|
999
|
+
gap: var(--usewc-layout-sidebar-item-gap);
|
|
1000
|
+
padding: var(--usewc-layout-sidebar-item-padding-block) var(--usewc-layout-sidebar-item-padding-inline);
|
|
1001
|
+
border-radius: var(--usewc-effect-sidebar-item-border-radius);
|
|
1002
|
+
|
|
1003
|
+
&:is(:hover, :focus-visible) {
|
|
1004
|
+
background-color: var(--usewc-color-sidebar-item-background-hover);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
> :is(svg, .icon):first-child {
|
|
1008
|
+
display: inline-flex;
|
|
1009
|
+
align-items: center;
|
|
1010
|
+
justify-content: center;
|
|
1011
|
+
flex: none;
|
|
1012
|
+
inline-size: var(--usewc-layout-sidebar-item-icon-size);
|
|
1013
|
+
block-size: var(--usewc-layout-sidebar-item-icon-size);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
> :only-child:not(svg, .icon) {
|
|
1017
|
+
flex: auto;
|
|
1018
|
+
min-inline-size: 0;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
use-theme-escape & {
|
|
1022
|
+
all: revert-layer;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
a:not([class*="appearance-"]) {
|
|
1027
|
+
--usewc-color-link-text-static: var(--usewc-color-sidebar-item-text-static);
|
|
1028
|
+
--usewc-color-link-text-hover: var(--usewc-color-sidebar-item-text-hover);
|
|
1029
|
+
--usewc-color-link-text-active: var(--usewc-color-sidebar-item-text-active);
|
|
1030
|
+
|
|
1031
|
+
&[aria-current="page"] {
|
|
1032
|
+
--usewc-color-link-text-static: var(--usewc-color-sidebar-item-text-current);
|
|
1033
|
+
--usewc-color-link-text-hover: var(--usewc-color-sidebar-item-text-current);
|
|
1034
|
+
--usewc-color-link-text-active: var(--usewc-color-sidebar-item-text-current);
|
|
1035
|
+
background-color: var(--usewc-color-sidebar-item-background-current);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
summary:not([class*="appearance-"]) {
|
|
1040
|
+
color: var(--usewc-color-sidebar-item-text-static);
|
|
1041
|
+
cursor: pointer;
|
|
1042
|
+
outline-offset: var(--usewc-effect-outline-offset);
|
|
1043
|
+
|
|
1044
|
+
&:hover {
|
|
1045
|
+
color: var(--usewc-color-sidebar-item-text-hover);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
&:active {
|
|
1049
|
+
color: var(--usewc-color-sidebar-item-text-active);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
&:focus-visible {
|
|
1053
|
+
outline: var(--usewc-effect-outline-size) var(--usewc-effect-outline-style) var(--usewc-color-outline);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
&::before {
|
|
1057
|
+
flex: none;
|
|
1058
|
+
inline-size: var(--usewc-layout-sidebar-item-icon-size);
|
|
1059
|
+
block-size: var(--usewc-layout-sidebar-item-icon-size);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
&:has(> :is(svg, .icon):first-child) {
|
|
1063
|
+
&::before {
|
|
1064
|
+
display: none;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
&:is(:hover, :focus-visible) {
|
|
1068
|
+
&::before {
|
|
1069
|
+
display: inline-block;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
> :is(svg, .icon):first-child {
|
|
1073
|
+
display: none;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
use-theme-escape &,
|
|
1079
|
+
use-theme-escape &::before {
|
|
1080
|
+
all: revert-layer;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
:is(ul, ol) {
|
|
1085
|
+
margin: 0;
|
|
1086
|
+
padding: 0;
|
|
1087
|
+
list-style: none;
|
|
1088
|
+
|
|
1089
|
+
use-theme-escape & {
|
|
1090
|
+
all: revert-layer;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
details:has(a[aria-current="page"]) > summary:not([class*="appearance-"]) {
|
|
1095
|
+
color: var(--usewc-color-sidebar-item-text-current);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
details::details-content {
|
|
1099
|
+
padding-inline-start: var(--usewc-layout-sidebar-nested-guide-gap);
|
|
1100
|
+
border-inline-start: var(--usewc-layout-sidebar-nested-guide-width) solid var(--usewc-color-sidebar-nested-guide);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
details:not(details details)::details-content {
|
|
1104
|
+
margin-inline-start: calc(
|
|
1105
|
+
var(--usewc-layout-sidebar-item-padding-inline) + var(--usewc-layout-sidebar-item-icon-size) / 2 -
|
|
1106
|
+
var(--usewc-layout-sidebar-nested-guide-width) / 2
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
details details::details-content {
|
|
1111
|
+
margin-inline-start: calc(
|
|
1112
|
+
var(--usewc-local-sidebar-nested-padding-inline-start) + var(--usewc-layout-sidebar-item-icon-size) / 2 -
|
|
1113
|
+
var(--usewc-layout-sidebar-nested-guide-width) / 2
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
use-theme-escape & details::details-content {
|
|
1118
|
+
all: revert-layer;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
details > a:not([class*="appearance-"]),
|
|
1122
|
+
details > :not(summary) :is(a, summary):not([class*="appearance-"]) {
|
|
1123
|
+
padding-inline-start: var(--usewc-local-sidebar-nested-padding-inline-start);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
> :is(h1, h2, h3, h4, h5, h6) {
|
|
1127
|
+
margin: var(--usewc-layout-sidebar-group-label-spacing) 0 var(--usewc-space-4);
|
|
1128
|
+
padding-inline: var(--usewc-layout-sidebar-item-padding-inline);
|
|
1129
|
+
font-size: var(--usewc-font-sidebar-group-label-size);
|
|
1130
|
+
font-weight: var(--usewc-font-sidebar-group-label-weight);
|
|
1131
|
+
line-height: var(--usewc-layout-sidebar-group-label-line-height);
|
|
1132
|
+
color: var(--usewc-color-sidebar-group-label-text);
|
|
1133
|
+
|
|
1134
|
+
&:first-child {
|
|
1135
|
+
margin-block-start: 0;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
use-theme-escape & {
|
|
1139
|
+
all: revert-layer;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
898
1145
|
@layer use-theme.segment-input {
|
|
899
1146
|
:is(use-datetime-input, use-date-input, use-time-input, use-duration-input):not(.appearance-native) {
|
|
900
1147
|
display: inline-flex;
|
|
@@ -2722,9 +2969,9 @@
|
|
|
2722
2969
|
has room to render instead of being clipped at its edge. `header`/`main`/`footer` are style
|
|
2723
2970
|
hooks, not required elements. */
|
|
2724
2971
|
use-layout.page {
|
|
2725
|
-
--usewc-local-layout-default-spacing: var(--usewc-layout-page-
|
|
2726
|
-
--usewc-local-layout-default-
|
|
2727
|
-
--usewc-local-layout-default-
|
|
2972
|
+
--usewc-local-layout-default-spacing: var(--usewc-layout-page-spacing);
|
|
2973
|
+
--usewc-local-layout-default-padding-block: var(--usewc-layout-page-padding-block);
|
|
2974
|
+
--usewc-local-layout-default-gutter: var(--usewc-layout-page-padding-inline);
|
|
2728
2975
|
min-block-size: 0;
|
|
2729
2976
|
}
|
|
2730
2977
|
|
|
@@ -2874,6 +3121,22 @@
|
|
|
2874
3121
|
justify-content: space-between;
|
|
2875
3122
|
}
|
|
2876
3123
|
|
|
3124
|
+
/* A clear icon-only button closing out a header pulls its end edge into the gutter by the
|
|
3125
|
+
room between its own edge and its glyph, so the glyph — not an invisible box — lines up
|
|
3126
|
+
with the page's inset. A square button sheds its inline padding, so its glyph sits its
|
|
3127
|
+
block padding in instead. The button reads its own size's padding tokens, which is why
|
|
3128
|
+
this is a margin on it rather than less padding on the header. */
|
|
3129
|
+
& > header > button,
|
|
3130
|
+
& > header > section:last-child > button {
|
|
3131
|
+
&.clear:is([aria-label], [aria-labelledby]):last-child {
|
|
3132
|
+
margin-inline-end: calc(-1 * (var(--usewc-layout-button-padding-inline) + var(--usewc-layout-button-border)));
|
|
3133
|
+
}
|
|
3134
|
+
|
|
3135
|
+
&.clear:is([aria-label], [aria-labelledby]):last-child:has(> use-caret:empty, > :is(svg, .icon):only-child) {
|
|
3136
|
+
margin-inline-end: calc(-1 * (var(--usewc-layout-button-padding-block) + var(--usewc-layout-button-border)));
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
|
|
2877
3140
|
/* A `<figure>` inside the body is an attachment — it keeps the flow but sheds the UA margin. */
|
|
2878
3141
|
& > :is(main, use-layout[fill]) figure {
|
|
2879
3142
|
margin-inline: 0;
|
|
@@ -34,7 +34,21 @@ button:
|
|
|
34
34
|
A child is a `<button>`, anything wearing `.appearance-button`, an `<input>` (other than a
|
|
35
35
|
checkbox/radio/range/file), a `<select>`, a `<textarea>`, or anything wearing
|
|
36
36
|
`.appearance-input` — see `theme/control-set.css` for exactly which selectors read which
|
|
37
|
-
radius/border tokens.
|
|
37
|
+
radius/border tokens. A plain `span` renders as a static text cell between controls.
|
|
38
|
+
|
|
39
|
+
Pagination follows the same shape, with `a.appearance-button` links and `aria-current="page"`
|
|
40
|
+
holding the current page in its pressed look:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<nav aria-label="Pagination">
|
|
44
|
+
<use-control-set>
|
|
45
|
+
<a class="appearance-button" href="?page=1">1</a>
|
|
46
|
+
<a class="appearance-button" href="?page=2" aria-current="page">2</a>
|
|
47
|
+
<span aria-hidden="true">…</span>
|
|
48
|
+
<a class="appearance-button" href="?page=10">10</a>
|
|
49
|
+
</use-control-set>
|
|
50
|
+
</nav>
|
|
51
|
+
```
|
|
38
52
|
|
|
39
53
|
How the touching sides render is themeable rather than fixed: `--usewc-layout-control-set-gap`
|
|
40
54
|
(default: a negative overlap equal to the child's own border, for a seamless merged line) and
|
package/dist/tokens.css
CHANGED
|
@@ -222,6 +222,29 @@
|
|
|
222
222
|
--usewc-effect-sidebar-item-border-radius: var(--usewc-effect-border-radius-6);
|
|
223
223
|
--usewc-layout-sidebar-item-padding-block: var(--usewc-space-8);
|
|
224
224
|
--usewc-layout-sidebar-item-padding-inline: var(--usewc-space-12);
|
|
225
|
+
--usewc-color-sidebar-item-text-current: var(--usewc-color-brand-primary);
|
|
226
|
+
--usewc-color-sidebar-item-background-current: oklch(from var(--usewc-color-brand-primary) l c h / 0.1);
|
|
227
|
+
/* A leading icon and the group caret share one box, so the caret can stand in for the icon on
|
|
228
|
+
hover without shifting the label, and one indent lines nested text up under either. */
|
|
229
|
+
--usewc-layout-sidebar-item-icon-size: 1em;
|
|
230
|
+
--usewc-layout-sidebar-item-gap: var(--usewc-space-8);
|
|
231
|
+
/* The guide is a tint of the document's own ink rather than a fixed gray, so it stays equally
|
|
232
|
+
faint against either theme's background without a dark-mode override. */
|
|
233
|
+
--usewc-color-sidebar-nested-guide: oklch(from var(--usewc-color-document-text) l c h / 0.15);
|
|
234
|
+
--usewc-layout-sidebar-nested-guide-width: var(--usewc-space-1);
|
|
235
|
+
--usewc-layout-sidebar-nested-guide-gap: var(--usewc-space-4);
|
|
236
|
+
--usewc-color-sidebar-group-label-text: var(--usewc-color-document-text-muted);
|
|
237
|
+
--usewc-font-sidebar-group-label-size: var(--usewc-font-size-12);
|
|
238
|
+
--usewc-font-sidebar-group-label-weight: var(--usewc-font-weight-semibold);
|
|
239
|
+
--usewc-layout-sidebar-group-label-line-height: var(--usewc-line-height-18);
|
|
240
|
+
--usewc-layout-sidebar-group-label-spacing: var(--usewc-space-16);
|
|
241
|
+
/* - Breadcrumb */
|
|
242
|
+
/* The separator is decoration rather than meaning, the same way a link's underline is, so it
|
|
243
|
+
lives under `effect` — `breadcrumb.css` gives it empty alt text so it's never announced. */
|
|
244
|
+
--usewc-effect-breadcrumb-separator: "/";
|
|
245
|
+
--usewc-color-breadcrumb-separator: var(--usewc-color-document-text-muted);
|
|
246
|
+
--usewc-color-breadcrumb-current-text: var(--usewc-color-document-text);
|
|
247
|
+
--usewc-layout-breadcrumb-gap: var(--usewc-space-8);
|
|
225
248
|
|
|
226
249
|
/* Form */
|
|
227
250
|
/* - Color */
|
|
@@ -801,7 +824,9 @@
|
|
|
801
824
|
var(--usewc-layout-region-subtitle-line-height)
|
|
802
825
|
);
|
|
803
826
|
|
|
804
|
-
--usewc-layout-page-
|
|
827
|
+
--usewc-layout-page-spacing: var(--usewc-space-32);
|
|
828
|
+
--usewc-layout-page-padding-block: var(--usewc-space-16);
|
|
829
|
+
--usewc-layout-page-padding-inline: var(--usewc-space-24);
|
|
805
830
|
--usewc-layout-page-gap: var(--usewc-space-12);
|
|
806
831
|
--usewc-layout-page-avatar-size: var(--usewc-layout-region-title-block-size);
|
|
807
832
|
--usewc-font-page-title-size: var(--usewc-font-size-28);
|
package/package.json
CHANGED
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"name": "use-control-set",
|
|
80
|
-
"description": "Groups adjacent controls — buttons and text-style inputs alike — into one visual unit: shared\nborders between touching children, rounded corners only on the two outer ends, and a hovered\nor focused child's border lifted above its neighbors so the whole border reads clearly.\n\n`use-control-set` renders no shadow DOM and no template of its own — it exists only as a\ndedicated tag for `theme/control-set.css` to style, the same way `use-layout` is a bare\nprimitive rather than a specific look. A classic split button is a text button followed by an\nicon-only trigger for a `use-menu`:\n\n```html\n<use-control-set>\n <button type=\"button\">Save</button>\n <button type=\"button\" popovertarget=\"save-options\" aria-label=\"More save options\">\n <use-caret></use-caret>\n </button>\n</use-control-set>\n<use-menu id=\"save-options\" aria-label=\"More save options\">\n <button role=\"menuitem\">Save as…</button>\n</use-menu>\n```\n\nA search box with an attached submit button follows the same shape, mixing a text input with a\nbutton:\n\n```html\n<use-control-set>\n <input type=\"search\" placeholder=\"Search\" />\n <button type=\"submit\">Go</button>\n</use-control-set>\n```\n\nA child is a `<button>`, anything wearing `.appearance-button`, an `<input>` (other than a\ncheckbox/radio/range/file), a `<select>`, a `<textarea>`, or anything wearing\n`.appearance-input` — see `theme/control-set.css` for exactly which selectors read which\nradius/border tokens.\n\nHow the touching sides render is themeable rather than fixed: `--usewc-layout-control-set-gap`\n(default: a negative overlap equal to the child's own border, for a seamless merged line) and\n`--usewc-effect-control-set-border-radius-sequential` (default: `0`, for square touching\ncorners) can both be overridden — a positive gap and a small radius reads as a looser, softer\nset instead of a fused one.\n---\n\n\n### **Slots:**\n - _default_ - The grouped controls.",
|
|
80
|
+
"description": "Groups adjacent controls — buttons and text-style inputs alike — into one visual unit: shared\nborders between touching children, rounded corners only on the two outer ends, and a hovered\nor focused child's border lifted above its neighbors so the whole border reads clearly.\n\n`use-control-set` renders no shadow DOM and no template of its own — it exists only as a\ndedicated tag for `theme/control-set.css` to style, the same way `use-layout` is a bare\nprimitive rather than a specific look. A classic split button is a text button followed by an\nicon-only trigger for a `use-menu`:\n\n```html\n<use-control-set>\n <button type=\"button\">Save</button>\n <button type=\"button\" popovertarget=\"save-options\" aria-label=\"More save options\">\n <use-caret></use-caret>\n </button>\n</use-control-set>\n<use-menu id=\"save-options\" aria-label=\"More save options\">\n <button role=\"menuitem\">Save as…</button>\n</use-menu>\n```\n\nA search box with an attached submit button follows the same shape, mixing a text input with a\nbutton:\n\n```html\n<use-control-set>\n <input type=\"search\" placeholder=\"Search\" />\n <button type=\"submit\">Go</button>\n</use-control-set>\n```\n\nA child is a `<button>`, anything wearing `.appearance-button`, an `<input>` (other than a\ncheckbox/radio/range/file), a `<select>`, a `<textarea>`, or anything wearing\n`.appearance-input` — see `theme/control-set.css` for exactly which selectors read which\nradius/border tokens. A plain `span` renders as a static text cell between controls.\n\nPagination follows the same shape, with `a.appearance-button` links and `aria-current=\"page\"`\nholding the current page in its pressed look:\n\n```html\n<nav aria-label=\"Pagination\">\n <use-control-set>\n <a class=\"appearance-button\" href=\"?page=1\">1</a>\n <a class=\"appearance-button\" href=\"?page=2\" aria-current=\"page\">2</a>\n <span aria-hidden=\"true\">…</span>\n <a class=\"appearance-button\" href=\"?page=10\">10</a>\n </use-control-set>\n</nav>\n```\n\nHow the touching sides render is themeable rather than fixed: `--usewc-layout-control-set-gap`\n(default: a negative overlap equal to the child's own border, for a seamless merged line) and\n`--usewc-effect-control-set-border-radius-sequential` (default: `0`, for square touching\ncorners) can both be overridden — a positive gap and a small radius reads as a looser, softer\nset instead of a fused one.\n---\n\n\n### **Slots:**\n - _default_ - The grouped controls.",
|
|
81
81
|
"attributes": [],
|
|
82
82
|
"references": []
|
|
83
83
|
},
|