@timmo001/groundwork-ui 0.6.0 → 0.8.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.
@@ -629,7 +629,7 @@
629
629
  {
630
630
  "kind": "variable",
631
631
  "name": "fieldStyles",
632
- "default": "css` :where(gw-input, gw-select, gw-switch, gw-checkbox) { display: flex; flex-direction: column; gap: var(--gw-space-2); font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } :where(gw-input, gw-select) .gw-field-heading { display: flex; gap: var(--gw-space-1); align-items: center; } :where(gw-input, gw-select) .gw-field-heading > label { font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } /* The (i) button by the label that opens a field's longer help */ :where(gw-input, gw-select) .gw-info { display: inline-grid; place-items: center; width: 1.5rem; height: 1.5rem; padding: 0; color: var(--gw-color-text-secondary); cursor: pointer; background: none; border: 0; border-radius: var(--gw-radius-pill); transition: color var(--gw-motion-fast) var(--gw-motion-easing), background-color var(--gw-motion-fast) var(--gw-motion-easing); } :where(gw-input, gw-select) .gw-info:hover { color: var(--gw-color-text-strong); background: var(--gw-color-fill-neutral-hovered); } :where(gw-input, gw-select) .gw-info:focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :where(gw-input, gw-select) .gw-info[hidden] { display: none; } :where(gw-input, gw-select) .gw-info > .icon { width: 1rem; height: 1rem; fill: currentColor; } :where(gw-input, gw-select) :where(input, .gw-select-trigger) { width: 100%; min-height: 2.5rem; padding: 0 var(--gw-space-3); font: inherit; font-size: var(--gw-font-size-s); color: var(--gw-color-text-strong); background: var(--gw-color-surface-lower); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-control); transition: border-color var(--gw-motion-fast) var(--gw-motion-easing); } /* The trigger shows the chosen option, with its icon, and a chevron with room around it that turns over while the list is open */ gw-select .gw-select-trigger { display: flex; gap: var(--gw-space-2); align-items: center; padding-inline-end: var(--gw-space-3); text-align: start; cursor: pointer; } gw-select .gw-select-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* With an inline label the select sits among toolbar controls, so it's a pill that fits its content, like the toggles and buttons beside it */ gw-select[inline-label] { display: inline-flex; } gw-select[inline-label] .gw-select-trigger { width: auto; padding-inline: var(--gw-space-4) var(--gw-space-3); border-radius: var(--gw-radius-pill); } /* An inline label reads as a quiet prefix to the value */ gw-select .gw-select-inline-label { flex: none; color: var(--gw-color-text-secondary); } gw-select .gw-select-inline-label[hidden] { display: none; } gw-select .gw-select-value[data-placeholder] { color: var(--gw-color-text-secondary); } gw-select .gw-select-trigger > .icon { flex: none; width: var(--gw-icon-size, 1.25rem); height: var(--gw-icon-size, 1.25rem); fill: currentColor; } gw-select .gw-select-trigger > .icon:last-child { color: var(--gw-color-text-secondary); transition: rotate var(--gw-motion-normal) var(--gw-motion-easing); } gw-select[open] .gw-select-trigger > .icon:last-child { rotate: 180deg; } gw-select .gw-select-trigger > .icon[hidden] { display: none; } /* The list opens under the trigger, growing from it, or as a bottom sheet sliding up on phones */ gw-select .gw-select-popup { position: fixed; inset: unset; box-sizing: border-box; max-width: calc(100vw - 12px); padding: 0; margin: 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-panel); box-shadow: var(--gw-shadow-l); opacity: 0; scale: 1 0.96; transform-origin: top; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), scale var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } gw-select .gw-select-popup[data-placement=\"above\"] { transform-origin: bottom; } gw-select .gw-select-popup:popover-open { opacity: 1; scale: 1; } @starting-style { gw-select .gw-select-popup:popover-open { opacity: 0; scale: 1 0.96; } } gw-select .gw-select-popup[data-placement=\"sheet\"] { inset: auto 0 0; width: 100%; max-width: none; padding-block-end: env(safe-area-inset-bottom); border-end-start-radius: 0; border-end-end-radius: 0; scale: 1; translate: 0 100%; --gw-option-list-height: 60vh; } gw-select .gw-select-popup[data-placement=\"sheet\"]:popover-open { translate: 0 0; } @starting-style { gw-select .gw-select-popup[data-placement=\"sheet\"]:popover-open { translate: 0 100%; } } gw-select .gw-select-popup[data-placement=\"sheet\"]::backdrop { background: rgb(0 0 0 / 40%); } /* With multiple, a full-width Clear under the list empties the choice */ gw-select .gw-select-clear { display: block; width: 100%; min-height: 2.5rem; padding: 0 var(--gw-space-3); font: inherit; font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-secondary); cursor: pointer; background: none; border: 0; border-block-start: var(--gw-border-width) solid var(--gw-color-border-quiet); transition: color var(--gw-motion-fast) var(--gw-motion-easing), background-color var(--gw-motion-fast) var(--gw-motion-easing); } gw-select .gw-select-clear:hover { color: var(--gw-color-text-strong); background: var(--gw-color-fill-neutral-hovered); } gw-select .gw-select-clear:focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: calc(var(--gw-focus-width) * -1); } gw-select .gw-select-clear[hidden] { display: none; } :where(gw-input, gw-select) :where(input, .gw-select-trigger):hover { border-color: var(--gw-color-border-loud); } :where(gw-input, gw-select, gw-switch, gw-checkbox) :where(input, .gw-select-trigger):focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :where(gw-input, gw-select) [aria-invalid=\"true\"] { border-color: var(--gw-color-border-danger); } :where(gw-input, gw-select, gw-switch, gw-checkbox) :disabled { color: var(--gw-color-text-disabled); cursor: not-allowed; } :where(gw-input, gw-select, gw-switch, gw-checkbox) .gw-hint { margin: 0; font-size: var(--gw-font-size-xs); color: var(--gw-color-text-secondary); } :where(gw-input, gw-select, gw-switch, gw-checkbox) .gw-error { margin: 0; font-size: var(--gw-font-size-xs); color: var(--gw-color-danger); } :where(gw-switch, gw-checkbox) > label { display: inline-flex; gap: var(--gw-space-3); align-items: center; font-size: var(--gw-font-size-s); cursor: pointer; } :where(gw-switch, gw-checkbox, gw-select) .gw-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } gw-checkbox input { width: 1.125rem; height: 1.125rem; margin: 0; accent-color: var(--gw-color-fill-accent-resting); } gw-switch input { position: relative; flex: none; width: 2.5rem; height: 1.5rem; margin: 0; cursor: pointer; appearance: none; background: var(--gw-color-surface-lower); border: var(--gw-border-width) solid var(--gw-color-border-loud); border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), border-color var(--gw-motion-normal) var(--gw-motion-easing); } gw-switch input::after { position: absolute; inset-block-start: 0.1875rem; inset-inline-start: 0.1875rem; width: 1rem; height: 1rem; content: \"\"; background: var(--gw-color-text-secondary); border-radius: 50%; transition: translate var(--gw-motion-normal) var(--gw-motion-easing), background-color var(--gw-motion-normal) var(--gw-motion-easing); } gw-switch input:checked { background: var(--gw-color-fill-accent-resting); border-color: transparent; } gw-switch input:checked::after { translate: 1rem 0; background: var(--gw-color-on-accent); } gw-switch input:disabled { opacity: 0.5; } `",
632
+ "default": "css` :where(gw-input, gw-select, gw-switch, gw-checkbox) { display: flex; flex-direction: column; gap: var(--gw-space-2); font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } :where(gw-input, gw-select) .gw-field-heading { display: flex; gap: var(--gw-space-1); align-items: center; } :where(gw-input, gw-select) .gw-field-heading > label { font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } /* The (i) button by the label that opens a field's longer help */ :where(gw-input, gw-select) .gw-info { display: inline-grid; place-items: center; width: 1.5rem; height: 1.5rem; padding: 0; color: var(--gw-color-text-secondary); cursor: pointer; background: none; border: 0; border-radius: var(--gw-radius-pill); transition: color var(--gw-motion-fast) var(--gw-motion-easing), background-color var(--gw-motion-fast) var(--gw-motion-easing); } :where(gw-input, gw-select) .gw-info:hover { color: var(--gw-color-text-strong); background: var(--gw-color-fill-neutral-hovered); } :where(gw-input, gw-select) .gw-info:focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :where(gw-input, gw-select) .gw-info[hidden] { display: none; } :where(gw-input, gw-select) .gw-info > .icon { width: 1rem; height: 1rem; fill: currentColor; } /* Sizes run xs to xl through --gw-field-scale, around 1 for medium, and the control's height follows the theme's density too */ :where(gw-input, gw-select)[size=\"xs\"] { --gw-field-scale: 0.6; } :where(gw-input, gw-select)[size=\"small\"] { --gw-field-scale: 0.8; } :where(gw-input, gw-select)[size=\"large\"] { --gw-field-scale: 1.2; } :where(gw-input, gw-select)[size=\"xl\"] { --gw-field-scale: 1.4; } :where(gw-input, gw-select) :where(input, .gw-select-trigger) { --gw-field-size: var(--gw-field-scale, 1); --gw-icon-size: calc( 1.25rem * var(--gw-field-size) * var(--gw-control-scale, 1) ); width: 100%; min-height: calc( 2.5rem * var(--gw-field-size) * var(--gw-control-scale, 1) ); padding: 0 calc(var(--gw-space-3) * var(--gw-field-size)); font: inherit; font-size: calc(var(--gw-font-size-s) * var(--gw-field-size)); color: var(--gw-color-text-strong); background: var(--gw-color-surface-lower); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-control); transition: border-color var(--gw-motion-fast) var(--gw-motion-easing); } /* The trigger shows the chosen option, with its icon, and a chevron with room around it that turns over while the list is open */ gw-select .gw-select-trigger { display: flex; gap: calc(var(--gw-space-2) * var(--gw-field-size)); align-items: center; padding-inline-end: calc(var(--gw-space-3) * var(--gw-field-size)); text-align: start; cursor: pointer; } gw-select .gw-select-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* With an inline label the select sits among toolbar controls, so it's a pill that fits its content, like the toggles and buttons beside it */ gw-select[inline-label] { display: inline-flex; } gw-select[inline-label] .gw-select-trigger { width: auto; padding-inline: calc(var(--gw-space-4) * var(--gw-field-size)) calc(var(--gw-space-3) * var(--gw-field-size)); border-radius: var(--gw-radius-pill); } /* An inline label reads as a quiet prefix to the value */ gw-select .gw-select-inline-label { flex: none; color: var(--gw-color-text-secondary); } gw-select .gw-select-inline-label[hidden] { display: none; } gw-select .gw-select-value[data-placeholder] { color: var(--gw-color-text-secondary); } gw-select .gw-select-trigger > .icon { flex: none; width: var(--gw-icon-size, 1.25rem); height: var(--gw-icon-size, 1.25rem); fill: currentColor; } gw-select .gw-select-trigger > .icon:last-child { color: var(--gw-color-text-secondary); transition: rotate var(--gw-motion-normal) var(--gw-motion-easing); } gw-select[open] .gw-select-trigger > .icon:last-child { rotate: 180deg; } gw-select .gw-select-trigger > .icon[hidden] { display: none; } /* The list opens under the trigger, growing from it, or as a bottom sheet sliding up on phones */ gw-select .gw-select-popup { position: fixed; inset: unset; box-sizing: border-box; max-width: calc(100vw - 12px); padding: 0; margin: 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-panel); box-shadow: var(--gw-shadow-l); opacity: 0; scale: 1 0.96; transform-origin: top; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), scale var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } gw-select .gw-select-popup[data-placement=\"above\"] { transform-origin: bottom; } gw-select .gw-select-popup:popover-open { opacity: 1; scale: 1; } @starting-style { gw-select .gw-select-popup:popover-open { opacity: 0; scale: 1 0.96; } } gw-select .gw-select-popup[data-placement=\"sheet\"] { inset: auto 0 0; width: 100%; max-width: none; padding-block-end: env(safe-area-inset-bottom); border-end-start-radius: 0; border-end-end-radius: 0; scale: 1; translate: 0 100%; --gw-option-list-height: 60vh; } gw-select .gw-select-popup[data-placement=\"sheet\"]:popover-open { translate: 0 0; } @starting-style { gw-select .gw-select-popup[data-placement=\"sheet\"]:popover-open { translate: 0 100%; } } gw-select .gw-select-popup[data-placement=\"sheet\"]::backdrop { background: rgb(0 0 0 / 40%); } /* With multiple, a full-width Clear under the list empties the choice */ gw-select .gw-select-clear { display: block; width: 100%; min-height: 2.5rem; padding: 0 var(--gw-space-3); font: inherit; font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-secondary); cursor: pointer; background: none; border: 0; border-block-start: var(--gw-border-width) solid var(--gw-color-border-quiet); transition: color var(--gw-motion-fast) var(--gw-motion-easing), background-color var(--gw-motion-fast) var(--gw-motion-easing); } gw-select .gw-select-clear:hover { color: var(--gw-color-text-strong); background: var(--gw-color-fill-neutral-hovered); } gw-select .gw-select-clear:focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: calc(var(--gw-focus-width) * -1); } gw-select .gw-select-clear[hidden] { display: none; } :where(gw-input, gw-select) :where(input, .gw-select-trigger):hover { border-color: var(--gw-color-border-loud); } :where(gw-input, gw-select, gw-switch, gw-checkbox) :where(input, .gw-select-trigger):focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :where(gw-input, gw-select) [aria-invalid=\"true\"] { border-color: var(--gw-color-border-danger); } :where(gw-input, gw-select, gw-switch, gw-checkbox) :disabled { color: var(--gw-color-text-disabled); cursor: not-allowed; } :where(gw-input, gw-select, gw-switch, gw-checkbox) .gw-hint { margin: 0; font-size: var(--gw-font-size-xs); color: var(--gw-color-text-secondary); } :where(gw-input, gw-select, gw-switch, gw-checkbox) .gw-error { margin: 0; font-size: var(--gw-font-size-xs); color: var(--gw-color-danger); } :where(gw-switch, gw-checkbox) > label { display: inline-flex; gap: var(--gw-space-3); align-items: center; font-size: var(--gw-font-size-s); cursor: pointer; } :where(gw-switch, gw-checkbox, gw-select) .gw-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } gw-checkbox input { width: 1.125rem; height: 1.125rem; margin: 0; accent-color: var(--gw-color-fill-accent-resting); } gw-switch input { position: relative; flex: none; width: 2.5rem; height: 1.5rem; margin: 0; cursor: pointer; appearance: none; background: var(--gw-color-surface-lower); border: var(--gw-border-width) solid var(--gw-color-border-loud); border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-normal) var(--gw-motion-easing), border-color var(--gw-motion-normal) var(--gw-motion-easing); } gw-switch input::after { position: absolute; inset-block-start: 0.1875rem; inset-inline-start: 0.1875rem; width: 1rem; height: 1rem; content: \"\"; background: var(--gw-color-text-secondary); border-radius: 50%; transition: translate var(--gw-motion-normal) var(--gw-motion-easing), background-color var(--gw-motion-normal) var(--gw-motion-easing); } gw-switch input:checked { background: var(--gw-color-fill-accent-resting); border-color: transparent; } gw-switch input:checked::after { translate: 1rem 0; background: var(--gw-color-on-accent); } gw-switch input:disabled { opacity: 0.5; } `",
633
633
  "description": "Field components render their native control in light DOM, never in a\nshadow root: password managers and `<label for>` can't reach across one,\nand a form only submits controls it can see. Their styles are adopted into\nwhichever document or shadow root they sit in."
634
634
  },
635
635
  {
@@ -2097,6 +2097,14 @@
2097
2097
  {
2098
2098
  "description": "The icon's color, for a tone of your own. `tone` sets it.",
2099
2099
  "name": "--gw-tone"
2100
+ },
2101
+ {
2102
+ "description": "Scales the badge, around 1 for medium.",
2103
+ "name": "--gw-badge-scale"
2104
+ },
2105
+ {
2106
+ "description": "Scales its height and icon with the theme's density. The theme sets it.",
2107
+ "name": "--gw-control-scale"
2100
2108
  }
2101
2109
  ],
2102
2110
  "cssParts": [
@@ -2140,7 +2148,7 @@
2140
2148
  "text": "readonly CSSStyleSheet[]"
2141
2149
  },
2142
2150
  "static": true,
2143
- "default": "[ base, css` :host { display: inline-flex; max-width: 100%; vertical-align: middle; } /* 36px tall, 12px padding, 8px between the 18px icon and the text */ .badge { --gw-icon-size: 1.125rem; display: inline-flex; gap: var(--gw-space-2); align-items: center; box-sizing: border-box; max-width: 100%; height: 2.25rem; padding: 0 var(--gw-space-4) 0 var(--gw-space-3); vertical-align: middle; color: var(--gw-color-text-strong); background: var(--gw-color-surface-raised); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-pill); } :host([size=\"small\"]) .badge { --gw-icon-size: 1rem; gap: var(--gw-space-1); height: 1.75rem; padding: 0 var(--gw-space-3) 0 var(--gw-space-2); } .icon { color: var(--gw-tone, var(--gw-color-accent)); } .info { display: flex; flex-direction: column; min-width: 0; } .label { font-size: var(--gw-font-size-2xs); line-height: 1.1; color: var(--gw-color-text-secondary); } .content { font-size: var(--gw-font-size-xs); font-weight: var(--gw-font-weight-strong); line-height: 1.2; white-space: nowrap; } .value { display: inline-block; } `, ]",
2151
+ "default": "[ base, controlSizes(\"badge\"), css` :host { display: inline-flex; max-width: 100%; vertical-align: middle; } /* 36px tall at medium, 12px padding, 8px between the 18px icon and the text */ .badge { --gw-size: var(--gw-badge-scale, 1); --gw-scale: calc(var(--gw-size) * var(--gw-control-scale, 1)); --gw-icon-size: calc(1.125rem * var(--gw-scale)); display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-size)); align-items: center; box-sizing: border-box; max-width: 100%; height: calc(2.25rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-4) * var(--gw-size)) 0 calc(var(--gw-space-3) * var(--gw-size)); vertical-align: middle; color: var(--gw-color-text-strong); background: var(--gw-color-surface-raised); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-pill); } .icon { color: var(--gw-tone, var(--gw-color-accent)); } .info { display: flex; flex-direction: column; min-width: 0; } .label { font-size: max( var(--gw-font-size-2xs), calc(var(--gw-font-size-2xs) * var(--gw-size)) ); line-height: 1.1; color: var(--gw-color-text-secondary); } .content { font-size: max( var(--gw-font-size-2xs), calc(var(--gw-font-size-xs) * var(--gw-size)) ); font-weight: var(--gw-font-weight-strong); line-height: 1.2; white-space: nowrap; } .value { display: inline-block; } `, ]",
2144
2152
  "inheritedFrom": {
2145
2153
  "name": "GwElement",
2146
2154
  "module": "src/element.ts"
@@ -2174,7 +2182,7 @@
2174
2182
  "kind": "field",
2175
2183
  "name": "size",
2176
2184
  "type": {
2177
- "text": "\"small\" | \"medium\""
2185
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
2178
2186
  },
2179
2187
  "default": "\"medium\""
2180
2188
  },
@@ -2558,9 +2566,9 @@
2558
2566
  },
2559
2567
  {
2560
2568
  "type": {
2561
- "text": "\"small\"|\"medium\""
2569
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
2562
2570
  },
2563
- "description": "The size. Defaults to `medium`.",
2571
+ "description": "The size, around 36px tall at medium. Defaults to `medium`.",
2564
2572
  "name": "size"
2565
2573
  },
2566
2574
  {
@@ -3058,6 +3066,10 @@
3058
3066
  "description": "Scales every dimension, around 1 for medium.",
3059
3067
  "name": "--gw-button-scale"
3060
3068
  },
3069
+ {
3070
+ "description": "Scales its height and icon with the theme's density. The theme sets it.",
3071
+ "name": "--gw-control-scale"
3072
+ },
3061
3073
  {
3062
3074
  "description": "The color, set by `variant`.",
3063
3075
  "name": "--gw-button-tone"
@@ -3091,7 +3103,7 @@
3091
3103
  "text": "Properties"
3092
3104
  },
3093
3105
  "static": true,
3094
- "default": "{ variant: { reflect: true }, appearance: { reflect: true }, size: { reflect: true }, type: {}, href: {}, label: {}, disabled: { type: \"boolean\", reflect: true }, loading: { type: \"boolean\", reflect: true }, icon: {}, labels: { reflect: true }, }",
3106
+ "default": "{ variant: { reflect: true }, appearance: { reflect: true }, size: { reflect: true }, type: {}, href: {}, label: {}, disabled: { type: \"boolean\", reflect: true }, loading: { type: \"boolean\", reflect: true }, icon: {}, swatch: {}, labels: { reflect: true }, }",
3095
3107
  "inheritedFrom": {
3096
3108
  "name": "GwElement",
3097
3109
  "module": "src/element.ts"
@@ -3118,7 +3130,7 @@
3118
3130
  "text": "readonly CSSStyleSheet[]"
3119
3131
  },
3120
3132
  "static": true,
3121
- "default": "[ base, css` :host { --gw-button-tone: var(--gw-color-accent); display: inline-block; } /* Everything scales from --gw-button-scale, around a 40px medium button: the presets give 24, 32, 48 and 56px, and an app can set any value for a size between or beyond them */ :host([size=\"xs\"]) { --gw-button-scale: 0.6; } :host([size=\"small\"]) { --gw-button-scale: 0.8; } :host([size=\"large\"]) { --gw-button-scale: 1.2; } :host([size=\"xl\"]) { --gw-button-scale: 1.4; } :host([variant=\"neutral\"]) { --gw-button-tone: var(--gw-color-text-secondary); --gw-button-ink: var(--gw-color-text-strong); } :host([variant=\"info\"]) { --gw-button-tone: var(--gw-color-info); } :host([variant=\"success\"]) { --gw-button-tone: var(--gw-color-success); } :host([variant=\"warning\"]) { --gw-button-tone: var(--gw-color-warning); } :host([variant=\"danger\"]) { --gw-button-tone: var(--gw-color-danger); } .button { --gw-scale: var(--gw-button-scale, 1); --gw-icon-size: calc(1.125rem * var(--gw-scale)); position: relative; display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-scale)); align-items: center; justify-content: center; min-height: calc(2.5rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-4) * var(--gw-scale)); font: inherit; font-size: calc(var(--gw-font-size-s) * var(--gw-scale)); font-weight: var(--gw-font-weight-strong); line-height: 1; color: var(--gw-button-ink, var(--gw-button-tone)); text-decoration: none; text-transform: var(--gw-label-transform); letter-spacing: var(--gw-label-tracking); white-space: nowrap; cursor: pointer; background: transparent; border: max(var(--gw-border-width), 1px) solid transparent; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing), border-color var(--gw-motion-fast) var(--gw-motion-easing), color var(--gw-motion-fast) var(--gw-motion-easing), scale var(--gw-motion-fast) var(--gw-motion-easing); } /* A slight press, so a click feels physical */ .button:active { scale: 0.97; } .button:hover { background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } .button:active { background: color-mix(in oklch, var(--gw-button-tone) 24%, transparent); } /* A solid fill, with text that flips between black and white by the fill's lightness so it reads on every theme's colors */ :host([appearance=\"accent\"]) .button { color: oklch( from var(--gw-button-tone) clamp(0, (0.66 - l) * 1000, 1) 0 0 ); background: var(--gw-button-tone); } :host([appearance=\"accent\"]) .button:hover { background: oklch( from var(--gw-button-tone) calc(l + (0.6 - l) * 0.2) c h ); } :host([appearance=\"accent\"]) .button:active { background: oklch( from var(--gw-button-tone) calc(l + (0.6 - l) * 0.35) c h ); } /* The tint lowers the tone's contrast, so the text leans toward the strongest text color to stay readable on it */ :host([appearance=\"filled\"]) .button { color: var( --gw-button-ink, color-mix( in oklch, var(--gw-button-tone) 70%, var(--gw-color-text-strong) ) ); background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } :host([appearance=\"filled\"]) .button:hover { background: color-mix(in oklch, var(--gw-button-tone) 24%, transparent); } :host([appearance=\"filled\"]) .button:active { background: color-mix(in oklch, var(--gw-button-tone) 32%, transparent); } :host([appearance=\"outlined\"]) .button { border-color: var(--gw-button-tone); } /* A slotted link carries the text; the pill draws its focus ring */ ::slotted(a) { color: inherit; text-decoration: none; outline: none; } .button.focused { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :host([appearance=\"plain\"]) .button.current, :host([appearance=\"outlined\"]) .button.current { background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } :host([appearance=\"filled\"]) .button.current { background: color-mix(in oklch, var(--gw-button-tone) 32%, transparent); } .button:disabled, .button[aria-disabled=\"true\"] { color: var(--gw-color-text-disabled); pointer-events: none; cursor: not-allowed; background: var(--gw-color-fill-neutral-disabled); border-color: transparent; } :host([appearance=\"plain\"]) .button:disabled, :host([appearance=\"plain\"]) .button[aria-disabled=\"true\"] { background: transparent; } ::slotted([slot=\"icon\"]), .icon { flex: none; width: var(--gw-icon-size); height: var(--gw-icon-size); fill: currentColor; } /* The icon and the ring share one cell and crossfade */ .lead { display: grid; place-items: center; } .lead > * { grid-area: 1 / 1; } .lead > *, .text, .ring { transition: opacity var(--gw-motion-normal) cubic-bezier(0.4, 0, 0.2, 1); } /* Sized to the icon's drawn area, which is inset in its 24px box */ .ring { width: calc(var(--gw-icon-size) * 0.8); height: calc(var(--gw-icon-size) * 0.8); border: calc(2px * var(--gw-scale)) solid color-mix(in oklch, currentColor 25%, transparent); border-top-color: currentColor; border-radius: 50%; opacity: 0; animation: spin 0.9s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Without an icon, the ring sits over the hidden text */ .ring.over { position: absolute; inset: 0; margin: auto; } :host([loading]) .button { cursor: progress; } :host([loading]) .lead > .ring, :host([loading]) .button:not(.has-icon) > .ring.over { opacity: 1; } :host([loading]) .lead > :not(.ring), :host([loading]) .button:not(.has-icon) > .text { opacity: 0; } .button:not(.has-icon) > .lead { display: none; } /* Icon only, to save space: square, with the text kept for assistive technology. auto does this on narrow screens */ :host([labels=\"hide\"]) .button.has-icon { min-width: calc(2.5rem * var(--gw-scale)); padding: 0; } :host([labels=\"hide\"]) .has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } @media (width < 40rem) { :host([labels=\"auto\"]) .button.has-icon { min-width: calc(2.5rem * var(--gw-scale)); padding: 0; } :host([labels=\"auto\"]) .has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } } `, ]",
3133
+ "default": "[ base, controlSizes(\"button\"), css` :host { --gw-button-tone: var(--gw-color-accent); display: inline-block; } :host([variant=\"neutral\"]) { --gw-button-tone: var(--gw-color-text-secondary); --gw-button-ink: var(--gw-color-text-strong); } :host([variant=\"info\"]) { --gw-button-tone: var(--gw-color-info); } :host([variant=\"success\"]) { --gw-button-tone: var(--gw-color-success); } :host([variant=\"warning\"]) { --gw-button-tone: var(--gw-color-warning); } :host([variant=\"danger\"]) { --gw-button-tone: var(--gw-color-danger); } .button { --gw-size: var(--gw-button-scale, 1); --gw-scale: calc(var(--gw-size) * var(--gw-control-scale, 1)); --gw-icon-size: calc(1.125rem * var(--gw-scale)); position: relative; display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-size)); align-items: center; justify-content: center; min-height: calc(2.5rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-4) * var(--gw-size)); font: inherit; font-size: calc(var(--gw-font-size-s) * var(--gw-size)); font-weight: var(--gw-font-weight-strong); line-height: 1; color: var(--gw-button-ink, var(--gw-button-tone)); text-decoration: none; text-transform: var(--gw-label-transform); letter-spacing: var(--gw-label-tracking); white-space: nowrap; cursor: pointer; background: transparent; border: max(var(--gw-border-width), 1px) solid transparent; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing), border-color var(--gw-motion-fast) var(--gw-motion-easing), color var(--gw-motion-fast) var(--gw-motion-easing), scale var(--gw-motion-fast) var(--gw-motion-easing); } /* A slight press, so a click feels physical */ .button:active { scale: 0.97; } .button:hover { background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } .button:active { background: color-mix(in oklch, var(--gw-button-tone) 24%, transparent); } /* A solid fill, with text that flips between black and white by the fill's lightness so it reads on every theme's colors */ :host([appearance=\"accent\"]) .button { color: oklch( from var(--gw-button-tone) clamp(0, (0.66 - l) * 1000, 1) 0 0 ); background: var(--gw-button-tone); } :host([appearance=\"accent\"]) .button:hover { background: oklch( from var(--gw-button-tone) calc(l + (0.6 - l) * 0.2) c h ); } :host([appearance=\"accent\"]) .button:active { background: oklch( from var(--gw-button-tone) calc(l + (0.6 - l) * 0.35) c h ); } /* The tint lowers the tone's contrast, so the text leans toward the strongest text color to stay readable on it */ :host([appearance=\"filled\"]) .button { color: var( --gw-button-ink, color-mix( in oklch, var(--gw-button-tone) 70%, var(--gw-color-text-strong) ) ); background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } :host([appearance=\"filled\"]) .button:hover { background: color-mix(in oklch, var(--gw-button-tone) 24%, transparent); } :host([appearance=\"filled\"]) .button:active { background: color-mix(in oklch, var(--gw-button-tone) 32%, transparent); } :host([appearance=\"outlined\"]) .button { border-color: var(--gw-button-tone); } /* A slotted link carries the text; the pill draws its focus ring */ ::slotted(a) { color: inherit; text-decoration: none; outline: none; } .button.focused { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } :host([appearance=\"plain\"]) .button.current, :host([appearance=\"outlined\"]) .button.current { background: color-mix(in oklch, var(--gw-button-tone) 16%, transparent); } :host([appearance=\"filled\"]) .button.current { background: color-mix(in oklch, var(--gw-button-tone) 32%, transparent); } .button:disabled, .button[aria-disabled=\"true\"] { color: var(--gw-color-text-disabled); pointer-events: none; cursor: not-allowed; background: var(--gw-color-fill-neutral-disabled); border-color: transparent; } :host([appearance=\"plain\"]) .button:disabled, :host([appearance=\"plain\"]) .button[aria-disabled=\"true\"] { background: transparent; } ::slotted([slot=\"icon\"]), .icon { flex: none; width: var(--gw-icon-size); height: var(--gw-icon-size); fill: currentColor; } /* The icon and the ring share one cell and crossfade */ .lead { display: grid; place-items: center; } /* The icon slot is display: contents, so its slotted icon is a grid item of its own and needs the shared cell too */ .lead > *, ::slotted([slot=\"icon\"]) { grid-area: 1 / 1; } /* A color dot in the icon's place */ .swatch { width: calc(var(--gw-icon-size) * 0.6); height: calc(var(--gw-icon-size) * 0.6); border: 1px solid color-mix(in oklab, var(--gw-color-text-primary) 20%, transparent); border-radius: 50%; } .lead > *, .text, .ring { transition: opacity var(--gw-motion-normal) cubic-bezier(0.4, 0, 0.2, 1); } /* Sized to the icon's drawn area, which is inset in its 24px box */ .ring { width: calc(var(--gw-icon-size) * 0.8); height: calc(var(--gw-icon-size) * 0.8); border: calc(2px * var(--gw-scale)) solid color-mix(in oklch, currentColor 25%, transparent); border-top-color: currentColor; border-radius: 50%; opacity: 0; animation: spin 0.9s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Without an icon, the ring sits over the hidden text */ .ring.over { position: absolute; inset: 0; margin: auto; } :host([loading]) .button { cursor: progress; } :host([loading]) .lead > .ring, :host([loading]) .button:not(.has-icon) > .ring.over { opacity: 1; } :host([loading]) .lead > :not(.ring), :host([loading]) .button:not(.has-icon) > .text { opacity: 0; } .button:not(.has-icon) > .lead { display: none; } /* Icon only, to save space: square, with the text kept for assistive technology. auto does this on narrow screens */ :host([labels=\"hide\"]) .button.has-icon { min-width: calc(2.5rem * var(--gw-scale)); padding: 0; } :host([labels=\"hide\"]) .has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } @media (width < 40rem) { :host([labels=\"auto\"]) .button.has-icon { min-width: calc(2.5rem * var(--gw-scale)); padding: 0; } :host([labels=\"auto\"]) .has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } } `, ]",
3122
3134
  "inheritedFrom": {
3123
3135
  "name": "GwElement",
3124
3136
  "module": "src/element.ts"
@@ -3198,6 +3210,15 @@
3198
3210
  "description": "SVG path data for an icon before the text.",
3199
3211
  "default": "\"\""
3200
3212
  },
3213
+ {
3214
+ "kind": "field",
3215
+ "name": "swatch",
3216
+ "type": {
3217
+ "text": "string"
3218
+ },
3219
+ "description": "A CSS color, drawn as a small round dot in the icon's place.",
3220
+ "default": "\"\""
3221
+ },
3201
3222
  {
3202
3223
  "kind": "field",
3203
3224
  "name": "labels",
@@ -3219,6 +3240,12 @@
3219
3240
  "privacy": "private",
3220
3241
  "readonly": true
3221
3242
  },
3243
+ {
3244
+ "kind": "field",
3245
+ "name": "#swatch",
3246
+ "privacy": "private",
3247
+ "readonly": true
3248
+ },
3222
3249
  {
3223
3250
  "kind": "field",
3224
3251
  "name": "#lead",
@@ -3618,6 +3645,13 @@
3618
3645
  "description": "SVG path data for an icon before the text.",
3619
3646
  "name": "icon"
3620
3647
  },
3648
+ {
3649
+ "type": {
3650
+ "text": "string"
3651
+ },
3652
+ "description": "A CSS color, drawn as a small round dot in the icon's place, such as a tag's own color.",
3653
+ "name": "swatch"
3654
+ },
3621
3655
  {
3622
3656
  "type": {
3623
3657
  "text": "\"show\"|\"hide\"|\"auto\""
@@ -3652,7 +3686,7 @@
3652
3686
  "declarations": [
3653
3687
  {
3654
3688
  "kind": "class",
3655
- "description": "A surface for one group of content, with an optional heading and actions.\nWith `href` the whole card is a link. While `loading`, lines of skeleton\nstand in for the content, and for the heading until it's known. The card\nglides to its new height and the content fades in once it's loaded.",
3689
+ "description": "A surface for one group of content, with an optional heading and actions.\nWith `href` the whole card is a link. While `loading`, lines of skeleton\nstand in for the content, and for the heading until it's known. The card\nglides to its new height and the content fades in once it's loaded.\n\nFor a link the page's HTML has to carry, such as one with a `target` or\n`rel`, put an `<a>` in the `heading` slot instead of `href`. A click\nanywhere on the card that isn't on another control follows it, the card\nshows the link's hover and focus, and the link stays a real one in the\npage, so the rest of the card's content stays plain text.",
3656
3690
  "name": "GwCard",
3657
3691
  "cssParts": [
3658
3692
  {
@@ -3677,6 +3711,10 @@
3677
3711
  "description": "The content.",
3678
3712
  "name": ""
3679
3713
  },
3714
+ {
3715
+ "description": "The heading, in place of `heading`. An `<a>` here makes the whole card follow it.",
3716
+ "name": "heading"
3717
+ },
3680
3718
  {
3681
3719
  "description": "Buttons beside the heading.",
3682
3720
  "name": "actions"
@@ -3703,7 +3741,7 @@
3703
3741
  "text": "readonly CSSStyleSheet[]"
3704
3742
  },
3705
3743
  "static": true,
3706
- "default": "[ base, css` :host { display: block; } .card { display: flex; flex-direction: column; gap: var(--gw-space-3); height: 100%; padding: var(--gw-space-4); color: inherit; text-decoration: none; background: var(--gw-color-surface-raised); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-panel); box-shadow: var(--gw-shadow-s); } :host([flush]) .card { padding: 0; overflow: hidden; } a.card { transition: border-color var(--gw-motion-fast) var(--gw-motion-easing); } a.card:hover { border-color: var(--gw-color-border-accent); } header { display: flex; gap: var(--gw-space-2); align-items: center; } h2 { flex: 1; margin: 0; font-size: var(--gw-font-size-m); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .body:not([hidden]) { display: flex; flex-direction: column; gap: inherit; } `, ]",
3744
+ "default": "[ base, css` :host { display: block; } .card { display: flex; flex-direction: column; gap: var(--gw-space-3); height: 100%; padding: var(--gw-space-4); color: inherit; text-decoration: none; background: var(--gw-color-surface-raised); border: var(--gw-border-width) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-panel); box-shadow: var(--gw-shadow-s); } :host([flush]) .card { padding: 0; overflow: hidden; } a.card { transition: border-color var(--gw-motion-fast) var(--gw-motion-easing); } a.card:hover, .card.linked:hover { border-color: var(--gw-color-border-accent); } /* A card following a link in its heading slot */ .card.linked { cursor: pointer; transition: border-color var(--gw-motion-fast) var(--gw-motion-easing); } .card.focused { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } ::slotted([slot=\"heading\"]) { font: inherit; color: inherit; } ::slotted(a[slot=\"heading\"]) { text-decoration: none; outline: none; } header { display: flex; gap: var(--gw-space-2); align-items: center; } h2 { flex: 1; margin: 0; font-size: var(--gw-font-size-m); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .body:not([hidden]) { display: flex; flex-direction: column; gap: inherit; } `, ]",
3707
3745
  "inheritedFrom": {
3708
3746
  "name": "GwElement",
3709
3747
  "module": "src/element.ts"
@@ -3762,6 +3800,12 @@
3762
3800
  "privacy": "private",
3763
3801
  "readonly": true
3764
3802
  },
3803
+ {
3804
+ "kind": "field",
3805
+ "name": "#headingSlot",
3806
+ "privacy": "private",
3807
+ "readonly": true
3808
+ },
3765
3809
  {
3766
3810
  "kind": "field",
3767
3811
  "name": "#header",
@@ -3806,6 +3850,17 @@
3806
3850
  },
3807
3851
  "default": "false"
3808
3852
  },
3853
+ {
3854
+ "kind": "method",
3855
+ "name": "#link",
3856
+ "privacy": "private",
3857
+ "return": {
3858
+ "type": {
3859
+ "text": "HTMLAnchorElement | null"
3860
+ }
3861
+ },
3862
+ "description": "The `<a>` in the heading slot, or holding it, when there is one."
3863
+ },
3809
3864
  {
3810
3865
  "kind": "method",
3811
3866
  "name": "create",
@@ -5277,6 +5332,14 @@
5277
5332
  {
5278
5333
  "description": "The border. `tone` sets it.",
5279
5334
  "name": "--gw-tone-border"
5335
+ },
5336
+ {
5337
+ "description": "Scales the chip, around 1 for medium.",
5338
+ "name": "--gw-chip-scale"
5339
+ },
5340
+ {
5341
+ "description": "Scales its height and icon with the theme's density. The theme sets it.",
5342
+ "name": "--gw-control-scale"
5280
5343
  }
5281
5344
  ],
5282
5345
  "cssParts": [
@@ -5303,7 +5366,7 @@
5303
5366
  "text": "Properties"
5304
5367
  },
5305
5368
  "static": true,
5306
- "default": "{ tone: { reflect: true }, icon: {}, loading: { type: \"boolean\", reflect: true }, }",
5369
+ "default": "{ tone: { reflect: true }, icon: {}, swatch: {}, loading: { type: \"boolean\", reflect: true }, size: { reflect: true }, }",
5307
5370
  "inheritedFrom": {
5308
5371
  "name": "GwElement",
5309
5372
  "module": "src/element.ts"
@@ -5316,7 +5379,7 @@
5316
5379
  "text": "readonly CSSStyleSheet[]"
5317
5380
  },
5318
5381
  "static": true,
5319
- "default": "[ base, css` :host { display: inline-flex; } /* 32px, with 12px padding */ .chip { display: inline-flex; gap: var(--gw-space-2); align-items: center; box-sizing: border-box; height: 2rem; padding: 0 var(--gw-space-3); font-size: var(--gw-font-size-xs); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); background: var(--gw-tone-fill, var(--gw-color-fill-neutral-resting)); border: var(--gw-border-width) solid var(--gw-tone-border, var(--gw-color-border-quiet)); border-radius: var(--gw-radius-chip); --gw-icon-size: 1rem; } .content { display: inline-flex; gap: inherit; align-items: center; } `, ]",
5382
+ "default": "[ base, controlSizes(\"chip\"), css` :host { display: inline-flex; } /* 32px at medium, with 12px padding */ .chip { --gw-size: var(--gw-chip-scale, 1); --gw-scale: calc(var(--gw-size) * var(--gw-control-scale, 1)); --gw-icon-size: calc(1rem * var(--gw-scale)); display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-size)); align-items: center; box-sizing: border-box; height: calc(2rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-3) * var(--gw-size)); font-size: max( var(--gw-font-size-2xs), calc(var(--gw-font-size-xs) * var(--gw-size)) ); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); background: var(--gw-tone-fill, var(--gw-color-fill-neutral-resting)); border: var(--gw-border-width) solid var(--gw-tone-border, var(--gw-color-border-quiet)); border-radius: var(--gw-radius-chip); } .content { display: inline-flex; gap: inherit; align-items: center; } /* A color dot in the icon's place */ .swatch { flex: none; width: calc(var(--gw-icon-size) * 0.6); height: calc(var(--gw-icon-size) * 0.6); border: 1px solid color-mix(in oklab, var(--gw-color-text-primary) 20%, transparent); border-radius: 50%; } `, ]",
5320
5383
  "inheritedFrom": {
5321
5384
  "name": "GwElement",
5322
5385
  "module": "src/element.ts"
@@ -5339,6 +5402,15 @@
5339
5402
  "description": "SVG path data for an icon before the text, instead of the `icon` slot.",
5340
5403
  "default": "\"\""
5341
5404
  },
5405
+ {
5406
+ "kind": "field",
5407
+ "name": "swatch",
5408
+ "type": {
5409
+ "text": "string"
5410
+ },
5411
+ "description": "A CSS color, drawn as a small round dot in the icon's place.",
5412
+ "default": "\"\""
5413
+ },
5342
5414
  {
5343
5415
  "kind": "field",
5344
5416
  "name": "loading",
@@ -5347,12 +5419,26 @@
5347
5419
  },
5348
5420
  "default": "false"
5349
5421
  },
5422
+ {
5423
+ "kind": "field",
5424
+ "name": "size",
5425
+ "type": {
5426
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
5427
+ },
5428
+ "default": "\"medium\""
5429
+ },
5350
5430
  {
5351
5431
  "kind": "field",
5352
5432
  "name": "#icon",
5353
5433
  "privacy": "private",
5354
5434
  "readonly": true
5355
5435
  },
5436
+ {
5437
+ "kind": "field",
5438
+ "name": "#swatch",
5439
+ "privacy": "private",
5440
+ "readonly": true
5441
+ },
5356
5442
  {
5357
5443
  "kind": "field",
5358
5444
  "name": "#chip",
@@ -5698,12 +5784,26 @@
5698
5784
  "description": "SVG path data for an icon before the text.",
5699
5785
  "name": "icon"
5700
5786
  },
5787
+ {
5788
+ "type": {
5789
+ "text": "string"
5790
+ },
5791
+ "description": "A CSS color, drawn as a small round dot in the icon's place, such as a tag's own color.",
5792
+ "name": "swatch"
5793
+ },
5701
5794
  {
5702
5795
  "type": {
5703
5796
  "text": "boolean"
5704
5797
  },
5705
5798
  "description": "Shows a skeleton for the text.",
5706
5799
  "name": "loading"
5800
+ },
5801
+ {
5802
+ "type": {
5803
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
5804
+ },
5805
+ "description": "The size, around 32px tall at medium. Defaults to `medium`.",
5806
+ "name": "size"
5707
5807
  }
5708
5808
  ],
5709
5809
  "superclass": {
@@ -9617,6 +9717,16 @@
9617
9717
  "kind": "class",
9618
9718
  "description": "A labeled native `<input>`, with an optional hint and error.",
9619
9719
  "name": "GwInput",
9720
+ "cssProperties": [
9721
+ {
9722
+ "description": "Scales the field, around 1 for medium.",
9723
+ "name": "--gw-field-scale"
9724
+ },
9725
+ {
9726
+ "description": "Scales its height with the theme's density. The theme sets it.",
9727
+ "name": "--gw-control-scale"
9728
+ }
9729
+ ],
9620
9730
  "members": [
9621
9731
  {
9622
9732
  "kind": "field",
@@ -9625,7 +9735,7 @@
9625
9735
  "text": "Properties"
9626
9736
  },
9627
9737
  "static": true,
9628
- "default": "{ label: {}, name: {}, type: {}, value: {}, placeholder: {}, autocomplete: {}, hint: {}, info: {}, error: {}, required: { type: \"boolean\" }, disabled: { type: \"boolean\" }, }",
9738
+ "default": "{ label: {}, name: {}, type: {}, value: {}, placeholder: {}, autocomplete: {}, hint: {}, info: {}, error: {}, required: { type: \"boolean\" }, disabled: { type: \"boolean\" }, size: { reflect: true }, }",
9629
9739
  "inheritedFrom": {
9630
9740
  "name": "GwElement",
9631
9741
  "module": "src/element.ts"
@@ -9720,6 +9830,14 @@
9720
9830
  },
9721
9831
  "default": "false"
9722
9832
  },
9833
+ {
9834
+ "kind": "field",
9835
+ "name": "size",
9836
+ "type": {
9837
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
9838
+ },
9839
+ "default": "\"medium\""
9840
+ },
9723
9841
  {
9724
9842
  "kind": "field",
9725
9843
  "name": "#id",
@@ -10159,6 +10277,13 @@
10159
10277
  },
10160
10278
  "description": "Disables the field.",
10161
10279
  "name": "disabled"
10280
+ },
10281
+ {
10282
+ "type": {
10283
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
10284
+ },
10285
+ "description": "The field's size, 40px tall at medium. Defaults to `medium`.",
10286
+ "name": "size"
10162
10287
  }
10163
10288
  ],
10164
10289
  "superclass": {
@@ -10189,6 +10314,16 @@
10189
10314
  "kind": "class",
10190
10315
  "description": "A button that opens a menu on the Popover API, so it shows in the top\nlayer and closes on Esc or a click outside. Set `items`; arrow keys, Home\nand End move between them, and choosing one fires `select` with its\n`value` and closes the menu.\n\nContextual actions, such as \"Add a schedule\", go in `actions`: they stay\nbelow the items as the list scrolls, so they're found without scrolling to\nthe end, and with no items the menu says `empty` above them.\n\nItems render inside the component, so a page's own button styles can't\nreach them.",
10191
10316
  "name": "GwMenuButton",
10317
+ "cssProperties": [
10318
+ {
10319
+ "description": "Scales the trigger, around 1 for medium.",
10320
+ "name": "--gw-menu-button-scale"
10321
+ },
10322
+ {
10323
+ "description": "Scales its height and icon with the theme's density. The theme sets it.",
10324
+ "name": "--gw-control-scale"
10325
+ }
10326
+ ],
10192
10327
  "cssParts": [
10193
10328
  {
10194
10329
  "description": "The button that opens the menu.",
@@ -10203,7 +10338,7 @@
10203
10338
  "text": "Properties"
10204
10339
  },
10205
10340
  "static": true,
10206
- "default": "{ label: {}, icon: {}, empty: {}, items: { type: \"json\" }, actions: { type: \"json\" }, }",
10341
+ "default": "{ label: {}, icon: {}, empty: {}, items: { type: \"json\" }, actions: { type: \"json\" }, size: { reflect: true }, }",
10207
10342
  "inheritedFrom": {
10208
10343
  "name": "GwElement",
10209
10344
  "module": "src/element.ts"
@@ -10216,7 +10351,7 @@
10216
10351
  "text": "readonly CSSStyleSheet[]"
10217
10352
  },
10218
10353
  "static": true,
10219
- "default": "[ base, css` :host { position: relative; display: inline-block; anchor-scope: --gw-menu; } .trigger { display: inline-flex; gap: var(--gw-space-2); align-items: center; box-sizing: border-box; height: 2.5rem; padding: 0 var(--gw-space-4); font: inherit; font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); cursor: pointer; background: var(--gw-color-fill-neutral-resting); border: var(--gw-border-width) solid var(--gw-border-color); border-radius: var(--gw-radius-control); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); anchor-name: --gw-menu; } .trigger:hover { background: var(--gw-color-fill-neutral-hovered); } .chevron { width: 0.4rem; height: 0.4rem; margin-inline-start: var(--gw-space-1); border-inline-end: 1.5px solid currentColor; border-block-end: 1.5px solid currentColor; rotate: 45deg; translate: 0 -0.125rem; transition: rotate var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing); } .trigger[aria-expanded=\"true\"] .chevron { rotate: 225deg; translate: 0 0.125rem; } [popover] { position-anchor: --gw-menu; position-try-fallbacks: flip-block, flip-inline; inset: auto; top: anchor(bottom); left: anchor(left); box-sizing: border-box; min-width: 15rem; max-height: min(24rem, 60vh); padding: 0; margin: var(--gw-space-1) 0 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-l); box-shadow: var(--gw-shadow-m); opacity: 0; translate: 0 -0.25rem; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open { display: flex; flex-direction: column; opacity: 1; translate: 0 0; } @starting-style { [popover]:popover-open { opacity: 0; translate: 0 -0.25rem; } } /* The items scroll; the actions stay put below them, so \"Add\" is always in reach rather than at the end of a long list */ .items, .actions { display: flex; flex-direction: column; gap: var(--gw-space-0-5); padding: var(--gw-space-1); } .items { flex: 1; min-height: 0; overflow-y: auto; } .actions { border-block-start: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); } .empty { padding: var(--gw-space-3); margin: 0; font-size: var(--gw-font-size-s); color: var(--gw-color-text-secondary); } .item { display: flex; gap: var(--gw-space-3); align-items: center; box-sizing: border-box; min-height: 2.5rem; padding: var(--gw-space-2) var(--gw-space-3); font: inherit; font-size: var(--gw-font-size-s); color: var(--gw-color-text-primary); text-align: start; cursor: pointer; background: transparent; border: 0; border-radius: var(--gw-radius-m); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); --gw-icon-size: 1.125rem; } .item:hover, .item:focus-visible { background: var(--gw-color-fill-neutral-hovered); outline: none; } .item:focus-visible { box-shadow: inset 0 0 0 var(--gw-focus-width) var(--gw-color-focus); } .item:disabled { color: var(--gw-color-text-disabled); cursor: not-allowed; background: transparent; } .action { font-weight: var(--gw-font-weight-strong); color: var(--gw-color-accent); } .text { display: flex; flex-direction: column; gap: var(--gw-space-0-5); } .description { font-size: var(--gw-font-size-xs); color: var(--gw-color-text-secondary); } `, ]",
10354
+ "default": "[ base, controlSizes(\"menu-button\"), css` :host { position: relative; display: inline-block; anchor-scope: --gw-menu; } .trigger { --gw-size: var(--gw-menu-button-scale, 1); --gw-scale: calc(var(--gw-size) * var(--gw-control-scale, 1)); --gw-icon-size: calc(1.25rem * var(--gw-scale)); display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-size)); align-items: center; box-sizing: border-box; height: calc(2.5rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-4) * var(--gw-size)); font: inherit; font-size: calc(var(--gw-font-size-s) * var(--gw-size)); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); cursor: pointer; background: var(--gw-color-fill-neutral-resting); border: var(--gw-border-width) solid var(--gw-border-color); border-radius: var(--gw-radius-control); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); anchor-name: --gw-menu; } .trigger:hover { background: var(--gw-color-fill-neutral-hovered); } .chevron { width: 0.4rem; height: 0.4rem; margin-inline-start: var(--gw-space-1); border-inline-end: 1.5px solid currentColor; border-block-end: 1.5px solid currentColor; rotate: 45deg; translate: 0 -0.125rem; transition: rotate var(--gw-motion-normal) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing); } .trigger[aria-expanded=\"true\"] .chevron { rotate: 225deg; translate: 0 0.125rem; } [popover] { position-anchor: --gw-menu; position-try-fallbacks: flip-block, flip-inline; inset: auto; top: anchor(bottom); left: anchor(left); box-sizing: border-box; min-width: 15rem; max-height: min(24rem, 60vh); padding: 0; margin: var(--gw-space-1) 0 0; overflow: hidden; color: var(--gw-color-text-primary); background: var(--gw-color-surface-overlay); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-l); box-shadow: var(--gw-shadow-m); opacity: 0; translate: 0 -0.25rem; transition: opacity var(--gw-motion-fast) var(--gw-motion-easing), translate var(--gw-motion-normal) var(--gw-motion-easing), display var(--gw-motion-normal) allow-discrete, overlay var(--gw-motion-normal) allow-discrete; } [popover]:popover-open { display: flex; flex-direction: column; opacity: 1; translate: 0 0; } @starting-style { [popover]:popover-open { opacity: 0; translate: 0 -0.25rem; } } /* The items scroll; the actions stay put below them, so \"Add\" is always in reach rather than at the end of a long list */ .items, .actions { display: flex; flex-direction: column; gap: var(--gw-space-0-5); padding: var(--gw-space-1); } .items { flex: 1; min-height: 0; overflow-y: auto; } .actions { border-block-start: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); } .empty { padding: var(--gw-space-3); margin: 0; font-size: var(--gw-font-size-s); color: var(--gw-color-text-secondary); } .item { display: flex; gap: var(--gw-space-3); align-items: center; box-sizing: border-box; min-height: 2.5rem; padding: var(--gw-space-2) var(--gw-space-3); font: inherit; font-size: var(--gw-font-size-s); color: var(--gw-color-text-primary); text-align: start; cursor: pointer; background: transparent; border: 0; border-radius: var(--gw-radius-m); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); --gw-icon-size: 1.125rem; } .item:hover, .item:focus-visible { background: var(--gw-color-fill-neutral-hovered); outline: none; } .item:focus-visible { box-shadow: inset 0 0 0 var(--gw-focus-width) var(--gw-color-focus); } .item:disabled { color: var(--gw-color-text-disabled); cursor: not-allowed; background: transparent; } .action { font-weight: var(--gw-font-weight-strong); color: var(--gw-color-accent); } .text { display: flex; flex-direction: column; gap: var(--gw-space-0-5); } .description { font-size: var(--gw-font-size-xs); color: var(--gw-color-text-secondary); } `, ]",
10220
10355
  "inheritedFrom": {
10221
10356
  "name": "GwElement",
10222
10357
  "module": "src/element.ts"
@@ -10264,6 +10399,14 @@
10264
10399
  },
10265
10400
  "default": "[]"
10266
10401
  },
10402
+ {
10403
+ "kind": "field",
10404
+ "name": "size",
10405
+ "type": {
10406
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
10407
+ },
10408
+ "default": "\"medium\""
10409
+ },
10267
10410
  {
10268
10411
  "kind": "field",
10269
10412
  "name": "#trigger",
@@ -10707,6 +10850,13 @@
10707
10850
  },
10708
10851
  "description": "Actions pinned under the items, as JSON.",
10709
10852
  "name": "actions"
10853
+ },
10854
+ {
10855
+ "type": {
10856
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
10857
+ },
10858
+ "description": "The trigger's size, 24 to 56px tall. Defaults to `medium`.",
10859
+ "name": "size"
10710
10860
  }
10711
10861
  ],
10712
10862
  "superclass": {
@@ -14455,6 +14605,16 @@
14455
14605
  "kind": "class",
14456
14606
  "description": "Picks one of a few options, as a row of native radio buttons, so arrow\nkeys move between them and a form submits the choice. Fires `change`.\n\nOptions can carry icons, as Home Assistant's toggles do. `labels` decides\nwhether their text shows: `show` (the default), `hide` (icons only, with\nthe text as a tooltip and accessible name) or `auto`, which shows the text\non wide screens and only the icons on narrow ones.",
14457
14607
  "name": "GwSegmented",
14608
+ "cssProperties": [
14609
+ {
14610
+ "description": "Scales the control, around 1 for medium.",
14611
+ "name": "--gw-segmented-scale"
14612
+ },
14613
+ {
14614
+ "description": "Scales its height and icons with the theme's density. The theme sets it.",
14615
+ "name": "--gw-control-scale"
14616
+ }
14617
+ ],
14458
14618
  "cssParts": [
14459
14619
  {
14460
14620
  "description": "Each option.",
@@ -14473,7 +14633,7 @@
14473
14633
  "text": "Properties"
14474
14634
  },
14475
14635
  "static": true,
14476
- "default": "{ label: {}, name: {}, value: { reflect: true }, labels: { reflect: true }, options: { type: \"json\" }, }",
14636
+ "default": "{ label: {}, name: {}, value: { reflect: true }, labels: { reflect: true }, options: { type: \"json\" }, size: { reflect: true }, }",
14477
14637
  "inheritedFrom": {
14478
14638
  "name": "GwElement",
14479
14639
  "module": "src/element.ts"
@@ -14486,7 +14646,7 @@
14486
14646
  "text": "readonly CSSStyleSheet[]"
14487
14647
  },
14488
14648
  "static": true,
14489
- "default": "[ base, css` :host { display: inline-block; } /* A pill track with the picked option as a pill inside, as Home Assistant's toggles are */ fieldset { display: inline-flex; gap: 2px; padding: 3px; margin: 0; background: var(--gw-color-surface-lower); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-pill); } legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } label { position: relative; display: inline-flex; gap: var(--gw-space-2); align-items: center; box-sizing: border-box; /* 32px options in a 40px track, matching fields and buttons */ height: 2rem; padding: 0 var(--gw-space-3); font-size: var(--gw-font-size-s); color: var(--gw-color-text-primary); cursor: pointer; background: transparent; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); --gw-icon-size: 1.125rem; } :host([labels=\"hide\"]) label.has-icon { padding-inline: var(--gw-space-2); } :host([labels=\"hide\"]) label.has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } @media (width < 40rem) { :host([labels=\"auto\"]) label.has-icon { padding-inline: var(--gw-space-2); } :host([labels=\"auto\"]) label.has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } } label:hover { background: var(--gw-color-fill-neutral-hovered); } input { position: absolute; inset: 0; margin: 0; cursor: pointer; opacity: 0; } /* The picked pill is one element that slides between options, under their text, so the choice moves rather than jumps */ fieldset { position: relative; isolation: isolate; } .indicator { position: absolute; inset-block-start: 0; inset-inline-start: 0; z-index: -1; background: var(--gw-color-fill-accent-resting); border-radius: var(--gw-radius-pill); box-shadow: var(--gw-shadow-s); opacity: 0; } .indicator.placed { opacity: 1; } .indicator.moving { transition: translate var(--gw-motion-normal) var(--gw-motion-easing), width var(--gw-motion-normal) var(--gw-motion-easing), height var(--gw-motion-normal) var(--gw-motion-easing); } label { transition: background-color var(--gw-motion-fast) var(--gw-motion-easing), color var(--gw-motion-normal) var(--gw-motion-easing); } label:has(input:checked), label:has(input:checked):hover { color: var(--gw-color-on-accent); background: transparent; } label:has(input:focus-visible) { outline: var(--gw-focus-width) solid var(--gw-color-focus); /* Inset, so the ring sits inside the track rather than on its border */ outline-offset: calc(var(--gw-focus-width) * -1); } `, ]",
14649
+ "default": "[ base, controlSizes(\"segmented\"), css` :host { --gw-size: var(--gw-segmented-scale, 1); --gw-scale: calc(var(--gw-size) * var(--gw-control-scale, 1)); display: inline-block; } /* A pill track with the picked option as a pill inside, as Home Assistant's toggles are */ fieldset { display: inline-flex; gap: 2px; padding: 3px; margin: 0; background: var(--gw-color-surface-lower); border: max(var(--gw-border-width), 1px) solid var(--gw-color-border-normal); border-radius: var(--gw-radius-pill); } legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } label { position: relative; display: inline-flex; gap: calc(var(--gw-space-2) * var(--gw-size)); align-items: center; box-sizing: border-box; /* 32px options in a 40px track at medium, matching fields and buttons */ height: calc(2rem * var(--gw-scale)); padding: 0 calc(var(--gw-space-3) * var(--gw-size)); font-size: calc(var(--gw-font-size-s) * var(--gw-size)); color: var(--gw-color-text-primary); cursor: pointer; background: transparent; border-radius: var(--gw-radius-pill); transition: background-color var(--gw-motion-fast) var(--gw-motion-easing); --gw-icon-size: calc(1.125rem * var(--gw-scale)); } :host([labels=\"hide\"]) label.has-icon { padding-inline: var(--gw-space-2); } :host([labels=\"hide\"]) label.has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } @media (width < 40rem) { :host([labels=\"auto\"]) label.has-icon { padding-inline: var(--gw-space-2); } :host([labels=\"auto\"]) label.has-icon .text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } } label:hover { background: var(--gw-color-fill-neutral-hovered); } input { position: absolute; inset: 0; margin: 0; cursor: pointer; opacity: 0; } /* The picked pill is one element that slides between options, under their text, so the choice moves rather than jumps */ fieldset { position: relative; isolation: isolate; } .indicator { position: absolute; inset-block-start: 0; inset-inline-start: 0; z-index: -1; background: var(--gw-color-fill-accent-resting); border-radius: var(--gw-radius-pill); box-shadow: var(--gw-shadow-s); opacity: 0; } .indicator.placed { opacity: 1; } .indicator.moving { transition: translate var(--gw-motion-normal) var(--gw-motion-easing), width var(--gw-motion-normal) var(--gw-motion-easing), height var(--gw-motion-normal) var(--gw-motion-easing); } label { transition: background-color var(--gw-motion-fast) var(--gw-motion-easing), color var(--gw-motion-normal) var(--gw-motion-easing); } label:has(input:checked), label:has(input:checked):hover { color: var(--gw-color-on-accent); background: transparent; } label:has(input:focus-visible) { outline: var(--gw-focus-width) solid var(--gw-color-focus); /* Inset, so the ring sits inside the track rather than on its border */ outline-offset: calc(var(--gw-focus-width) * -1); } `, ]",
14490
14650
  "inheritedFrom": {
14491
14651
  "name": "GwElement",
14492
14652
  "module": "src/element.ts"
@@ -14532,6 +14692,14 @@
14532
14692
  },
14533
14693
  "default": "[]"
14534
14694
  },
14695
+ {
14696
+ "kind": "field",
14697
+ "name": "size",
14698
+ "type": {
14699
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
14700
+ },
14701
+ "default": "\"medium\""
14702
+ },
14535
14703
  {
14536
14704
  "kind": "field",
14537
14705
  "name": "#legend",
@@ -14949,6 +15117,13 @@
14949
15117
  },
14950
15118
  "description": "The options, as JSON.",
14951
15119
  "name": "options"
15120
+ },
15121
+ {
15122
+ "type": {
15123
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
15124
+ },
15125
+ "description": "The size, 40px tall at medium. Defaults to `medium`.",
15126
+ "name": "size"
14952
15127
  }
14953
15128
  ],
14954
15129
  "superclass": {
@@ -14979,6 +15154,16 @@
14979
15154
  "kind": "class",
14980
15155
  "description": "A labeled select whose list opens under it, after Home Assistant's\npickers. Long lists get a search field, focused as the list opens, and\nonly the options in view are rendered. Move with the arrow keys and pick\nwith Enter. Below 600px wide the list is a bottom sheet.\n\nPass `options`, or write `<option>` children (in `<optgroup>`s for\ngroups, with `data-icon`, `data-swatch` and `data-description`), which it\nreads once when it first connects. A hidden input carries the value in\nforms, and it fires `change` when the value changes.\n\nWith `multiple` it picks several: each pick toggles an option in `values`\nand the list stays open, the trigger shows the first choice and how many\nmore, and a Clear button under the list empties it. A hidden input per\nvalue carries them in forms.",
14981
15156
  "name": "GwSelect",
15157
+ "cssProperties": [
15158
+ {
15159
+ "description": "Scales the field, around 1 for medium.",
15160
+ "name": "--gw-field-scale"
15161
+ },
15162
+ {
15163
+ "description": "Scales its height with the theme's density. The theme sets it.",
15164
+ "name": "--gw-control-scale"
15165
+ }
15166
+ ],
14982
15167
  "members": [
14983
15168
  {
14984
15169
  "kind": "field",
@@ -14987,7 +15172,7 @@
14987
15172
  "text": "Properties"
14988
15173
  },
14989
15174
  "static": true,
14990
- "default": "{ label: {}, name: {}, value: {}, multiple: { type: \"boolean\", reflect: true }, values: { type: \"json\" }, hint: {}, info: {}, placeholder: {}, search: {}, disabled: { type: \"boolean\" }, open: { type: \"boolean\", reflect: true }, options: { type: \"json\" }, labelHidden: { type: \"boolean\", attribute: \"label-hidden\" }, inlineLabel: { type: \"boolean\", attribute: \"inline-label\", reflect: true }, }",
15175
+ "default": "{ label: {}, name: {}, value: {}, multiple: { type: \"boolean\", reflect: true }, values: { type: \"json\" }, hint: {}, info: {}, placeholder: {}, search: {}, disabled: { type: \"boolean\" }, open: { type: \"boolean\", reflect: true }, options: { type: \"json\" }, labelHidden: { type: \"boolean\", attribute: \"label-hidden\" }, inlineLabel: { type: \"boolean\", attribute: \"inline-label\", reflect: true }, size: { reflect: true }, }",
14991
15176
  "inheritedFrom": {
14992
15177
  "name": "GwElement",
14993
15178
  "module": "src/element.ts"
@@ -15107,6 +15292,14 @@
15107
15292
  },
15108
15293
  "default": "false"
15109
15294
  },
15295
+ {
15296
+ "kind": "field",
15297
+ "name": "size",
15298
+ "type": {
15299
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
15300
+ },
15301
+ "default": "\"medium\""
15302
+ },
15110
15303
  {
15111
15304
  "kind": "field",
15112
15305
  "name": "#id",
@@ -15669,6 +15862,13 @@
15669
15862
  },
15670
15863
  "description": "Shows the label inside the trigger, before the value, for toolbars and filters.",
15671
15864
  "name": "inline-label"
15865
+ },
15866
+ {
15867
+ "type": {
15868
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
15869
+ },
15870
+ "description": "The field's size, 40px tall at medium. Defaults to `medium`.",
15871
+ "name": "size"
15672
15872
  }
15673
15873
  ],
15674
15874
  "superclass": {
@@ -15703,6 +15903,10 @@
15703
15903
  {
15704
15904
  "description": "The padding above and below. Defaults to `--gw-space-2`.",
15705
15905
  "name": "--gw-row-padding"
15906
+ },
15907
+ {
15908
+ "description": "Scales the text and spacing, around 1 for medium.",
15909
+ "name": "--gw-setting-row-scale"
15706
15910
  }
15707
15911
  ],
15708
15912
  "cssParts": [
@@ -15725,7 +15929,7 @@
15725
15929
  "text": "Properties"
15726
15930
  },
15727
15931
  "static": true,
15728
- "default": "{ heading: {}, description: {}, loading: { type: \"boolean\", reflect: true }, }",
15932
+ "default": "{ heading: {}, description: {}, loading: { type: \"boolean\", reflect: true }, size: { reflect: true }, }",
15729
15933
  "inheritedFrom": {
15730
15934
  "name": "GwElement",
15731
15935
  "module": "src/element.ts"
@@ -15738,7 +15942,7 @@
15738
15942
  "text": "readonly CSSStyleSheet[]"
15739
15943
  },
15740
15944
  "static": true,
15741
- "default": "[ base, css` :host { display: block; } .row { display: flex; flex-wrap: wrap; gap: var(--gw-space-1) var(--gw-space-3); align-items: center; justify-content: space-between; padding: var(--gw-row-padding, var(--gw-space-2)) 0; } /* A full line even in themes without borders, since it separates rows */ :host(:not(:first-of-type)) .row { border-block-start: max(var(--gw-border-width), 1px) solid var(--gw-color-border-quiet); } .text { flex: 1 1 12rem; min-width: 0; } .heading { font-size: var(--gw-font-size-s); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .description { font-size: var(--gw-font-size-xs); color: var(--gw-color-text-secondary); } .control { max-width: 100%; } .control-skeleton { width: 3.25rem; min-height: 0; height: 2rem; --gw-skeleton-radius: var(--gw-radius-pill); } `, ]",
15945
+ "default": "[ base, controlSizes(\"setting-row\"), css` :host { --gw-size: var(--gw-setting-row-scale, 1); display: block; } .row { display: flex; flex-wrap: wrap; gap: calc(var(--gw-space-1) * var(--gw-size)) calc(var(--gw-space-3) * var(--gw-size)); align-items: center; justify-content: space-between; padding: var(--gw-row-padding, calc(var(--gw-space-2) * var(--gw-size))) 0; } /* A full line even in themes without borders, since it separates rows */ :host(:not(:first-of-type)) .row { border-block-start: max(var(--gw-border-width), 1px) solid var(--gw-color-border-quiet); } .text { flex: 1 1 12rem; min-width: 0; } .heading { font-size: max( var(--gw-font-size-xs), calc(var(--gw-font-size-s) * var(--gw-size)) ); font-weight: var(--gw-font-weight-strong); color: var(--gw-color-text-strong); } .description { font-size: max( var(--gw-font-size-2xs), calc(var(--gw-font-size-xs) * var(--gw-size)) ); color: var(--gw-color-text-secondary); } .control { max-width: 100%; } .control-skeleton { width: 3.25rem; min-height: 0; height: 2rem; --gw-skeleton-radius: var(--gw-radius-pill); } `, ]",
15742
15946
  "inheritedFrom": {
15743
15947
  "name": "GwElement",
15744
15948
  "module": "src/element.ts"
@@ -15768,6 +15972,14 @@
15768
15972
  },
15769
15973
  "default": "false"
15770
15974
  },
15975
+ {
15976
+ "kind": "field",
15977
+ "name": "size",
15978
+ "type": {
15979
+ "text": "\"xs\" | \"small\" | \"medium\" | \"large\" | \"xl\""
15980
+ },
15981
+ "default": "\"medium\""
15982
+ },
15771
15983
  {
15772
15984
  "kind": "field",
15773
15985
  "name": "#row",
@@ -16158,6 +16370,13 @@
16158
16370
  },
16159
16371
  "description": "Shows skeletons for the control and any unknown text.",
16160
16372
  "name": "loading"
16373
+ },
16374
+ {
16375
+ "type": {
16376
+ "text": "\"xs\"|\"small\"|\"medium\"|\"large\"|\"xl\""
16377
+ },
16378
+ "description": "The text and spacing size. Defaults to `medium`.",
16379
+ "name": "size"
16161
16380
  }
16162
16381
  ],
16163
16382
  "superclass": {
@@ -20074,7 +20293,7 @@
20074
20293
  "text": "readonly CSSStyleSheet[]"
20075
20294
  },
20076
20295
  "static": true,
20077
- "default": "[ base, css` :host { display: block; } .page { display: flex; flex-direction: column; gap: var(--gw-space-6); width: 100%; max-width: var(--gw-content-width); margin-inline: auto; } :host([narrow]) .page { max-width: var(--gw-content-width-narrow); } `, ]",
20296
+ "default": "[ base, css` :host { display: block; } .page { display: flex; flex-direction: column; gap: var(--gw-space-6); /* The same box as gw-app-bar's content, so the two line up */ width: min(100% - 2 * var(--gw-space-3), var(--gw-content-width)); margin-inline: auto; } :host([narrow]) .page { width: min( 100% - 2 * var(--gw-space-3), var(--gw-content-width-narrow) ); } `, ]",
20078
20297
  "inheritedFrom": {
20079
20298
  "name": "GwElement",
20080
20299
  "module": "src/element.ts"
@@ -21797,10 +22016,23 @@
21797
22016
  "kind": "javascript-module",
21798
22017
  "path": "src/styles.ts",
21799
22018
  "declarations": [
22019
+ {
22020
+ "kind": "function",
22021
+ "name": "controlSizes",
22022
+ "parameters": [
22023
+ {
22024
+ "name": "name",
22025
+ "type": {
22026
+ "text": "string"
22027
+ }
22028
+ }
22029
+ ],
22030
+ "description": "The `xs` to `xl` presets on a `size` attribute, as `--gw-<name>-scale`\naround 1 for medium, so an app can also set any size between or beyond\nthem. A control multiplies its height and icon by `--gw-control-scale`\ntoo, which follows the theme's density, and its text only by its own\nscale, since spacing and type already follow density on their own."
22031
+ },
21800
22032
  {
21801
22033
  "kind": "variable",
21802
22034
  "name": "base",
21803
- "default": "css` :host { font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } *, *::before, *::after { box-sizing: border-box; } [hidden] { display: none !important; } :focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } .icon { flex: none; width: var(--gw-icon-size, 1.25rem); height: var(--gw-icon-size, 1.25rem); fill: currentColor; } :host([tone=\"accent\"]) { --gw-tone: var(--gw-color-accent); --gw-tone-fill: var(--gw-color-fill-accent-quiet); --gw-tone-border: var(--gw-color-border-accent); } :host([tone=\"info\"]) { --gw-tone: var(--gw-color-info); --gw-tone-fill: var(--gw-color-fill-info-quiet); --gw-tone-border: var(--gw-color-border-info); } :host([tone=\"success\"]) { --gw-tone: var(--gw-color-success); --gw-tone-fill: var(--gw-color-fill-success-quiet); --gw-tone-border: var(--gw-color-border-success); } :host([tone=\"warning\"]) { --gw-tone: var(--gw-color-warning); --gw-tone-fill: var(--gw-color-fill-warning-quiet); --gw-tone-border: var(--gw-color-border-warning); } :host([tone=\"danger\"]) { --gw-tone: var(--gw-color-danger); --gw-tone-fill: var(--gw-color-fill-danger-quiet); --gw-tone-border: var(--gw-color-border-danger); } :host([tone=\"important\"]) { --gw-tone: var(--gw-color-important); --gw-tone-fill: var(--gw-color-fill-important-quiet); --gw-tone-border: var(--gw-color-border-important); } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important; } } `",
22035
+ "default": "css` :host { font-family: var(--gw-font-sans); color: var(--gw-color-text-primary); } *, *::before, *::after { box-sizing: border-box; } :host([hidden]), [hidden] { display: none !important; } :focus-visible { outline: var(--gw-focus-width) solid var(--gw-color-focus); outline-offset: var(--gw-focus-offset); } .icon { flex: none; width: var(--gw-icon-size, 1.25rem); height: var(--gw-icon-size, 1.25rem); fill: currentColor; } :host([tone=\"accent\"]) { --gw-tone: var(--gw-color-accent); --gw-tone-fill: var(--gw-color-fill-accent-quiet); --gw-tone-border: var(--gw-color-border-accent); } :host([tone=\"info\"]) { --gw-tone: var(--gw-color-info); --gw-tone-fill: var(--gw-color-fill-info-quiet); --gw-tone-border: var(--gw-color-border-info); } :host([tone=\"success\"]) { --gw-tone: var(--gw-color-success); --gw-tone-fill: var(--gw-color-fill-success-quiet); --gw-tone-border: var(--gw-color-border-success); } :host([tone=\"warning\"]) { --gw-tone: var(--gw-color-warning); --gw-tone-fill: var(--gw-color-fill-warning-quiet); --gw-tone-border: var(--gw-color-border-warning); } :host([tone=\"danger\"]) { --gw-tone: var(--gw-color-danger); --gw-tone-fill: var(--gw-color-fill-danger-quiet); --gw-tone-border: var(--gw-color-border-danger); } :host([tone=\"important\"]) { --gw-tone: var(--gw-color-important); --gw-tone-fill: var(--gw-color-fill-important-quiet); --gw-tone-border: var(--gw-color-border-important); } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important; } } `",
21804
22036
  "description": "What every component shares: box sizing, the focus ring, icons and the\ntones that set `--gw-tone` from a `tone` attribute."
21805
22037
  },
21806
22038
  {
@@ -21844,6 +22076,14 @@
21844
22076
  }
21845
22077
  ],
21846
22078
  "exports": [
22079
+ {
22080
+ "kind": "js",
22081
+ "name": "controlSizes",
22082
+ "declaration": {
22083
+ "name": "controlSizes",
22084
+ "module": "src/styles.ts"
22085
+ }
22086
+ },
21847
22087
  {
21848
22088
  "kind": "js",
21849
22089
  "name": "base",