ui: DisclosureCard component (#12541)

This commit is contained in:
John Cowen 2022-03-15 12:54:56 +00:00 committed by GitHub
parent dfefcabfbe
commit 7fbfab669c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 404 additions and 1 deletions

View File

@ -0,0 +1,125 @@
<!-- START component-docs:@tagName -->
# DisclosureCard
<!-- END component-docs:@tagName -->
```hbs preview-template
<figure>
<figcaption>
Use the component
</figcaption>
<DisclosureCard as |disclosure|>
<header>
<h4>api-service-1</h4>
</header>
<Consul::Bucket::List
@item={{hash
Namespace="different-nspace"
Partition="different-partition"
}}
@nspace={{'nspace'}}
@partition={{'partition'}}
/>
<DistributionMeter
type="linear"
as |meter|>
<meter.Meter class="warning" percentage="50" />
<meter.Meter class="critical" percentage="30" />
</DistributionMeter>
<disclosure.Details
as |details|>
<Consul::Bucket::List
@item={{hash
Namespace="different-nspace"
Partition="different-partition"
}}
@nspace={{'nspace'}}
@partition={{'partition'}}
/>
<DistributionMeter
type="linear"
as |meter|>
<meter.Meter class="warning" percentage="80" />
<meter.Meter class="critical" percentage="10" />
</DistributionMeter>
<Consul::Bucket::List
@item={{hash
Namespace="different-nspace"
Partition="different-partition"
}}
@nspace={{'nspace'}}
@partition={{'partition'}}
/>
<DistributionMeter
type="linear"
as |meter|>
<meter.Meter class="warning" percentage="10" />
<meter.Meter class="critical" percentage="40" />
</DistributionMeter>
<Consul::Bucket::List
@item={{hash
Namespace="different-nspace"
Partition="different-partition"
}}
@nspace={{'nspace'}}
@partition={{'partition'}}
/>
<DistributionMeter
type="linear"
as |meter|>
<meter.Meter class="warning" percentage="50" />
<meter.Meter class="critical" percentage="30" />
</DistributionMeter>
</disclosure.Details>
<disclosure.Action
slot="action"
{{on 'click' disclosure.toggle}}
>
{{if disclosure.expanded "View less" "View more"}}
</disclosure.Action>
</DisclosureCard>
</figure>
```
## Attributes
<!-- START component-docs:@attrs -->
<!-- END component-docs:@attrs -->
## Arguments
<!-- START component-docs:@args -->
<!-- END component-docs:@args -->
## Slots
<!-- START component-docs:@slots -->
<!-- END component-docs:@slots -->
## CSS Parts
<!-- START component-docs:@cssparts -->
<!-- END component-docs:@cssparts -->
## CSS Properties
<!-- START component-docs:@cssprops -->
<!-- END component-docs:@cssprops -->
## Contextual Components
<!-- START component-docs:@components -->
<!-- END component-docs:@components -->

View File

@ -0,0 +1,90 @@
<CustomElement
@element="disclosure-card"
@description="Block level component with extra disclosable content"
@attrs={{array
}}
as |custom element|>
<Disclosure as |disclosure|>
<disclosure-card
{{did-insert custom.connect}}
{{will-destroy custom.disconnect}}
expanded={{disclosure.expanded}}
>
<custom.Template
@styles={{css-map
(require '/styles/base/icons/base-keyframes.css' from='/components/disclosure-card')
(require '/styles/base/icons/icons/chevron-down/index.css' from='/components/disclosure-card')
(require '/components/panel/index.css' from='/components/disclosure-card')
(css "
:host {
display: block;
}
slot[name='action']::slotted(button) {
display: block;
cursor: pointer;
width: 100%;
background-color: rgb(var(--tone-gray-050));
color: rgb(var(--tone-gray-800));
padding-top: var(--padding-y);
padding-bottom: var(--padding-y);
}
slot[name='action']::slotted(button)::after {
transition-timing-function: linear;
transition-duration: 300ms;
transition-property: transform;
--icon-name: icon-chevron-down;
--icon-size: icon-000;
content: '';
}
:host([expanded]) slot[name='action']::slotted(button)::after {
transform: scaleY(-100%);
}
:host([expanded]) [style*='max-height'] {
transition-duration: 50ms;
}
[style*='max-height'] {
transition-timing-function: ease-out;
transition-property: max-height;
overflow: hidden;
}
.content {
padding: var(--padding-y) var(--padding-x);
}
")
}}
>
<div part="base"
class={{class-map
"panel"
}}
>
<div
{{on-resize (dom-position (array
(array 'height' 'max-height')
))}}
class={{class-map
'content'
}}
>
<slot>
</slot>
</div>
<hr
class={{class-map
'panel-separator'
}}
/>
<slot name="action">
</slot>
</div>
</custom.Template>
{{yield disclosure}}
</disclosure-card>
</Disclosure>
</CustomElement>

View File

@ -0,0 +1,31 @@
export default (css) => css`
.panel {
--padding-x: 14px;
--padding-y: 14px;
}
.panel {
position: relative;
}
.panel-separator {
margin: 0;
}
.panel {
--tone-border: var(--tone-gray-300);
border: var(--decor-border-100);
border-radius: var(--decor-radius-200);
box-shadow: var(--decor-elevation-600);
}
.panel-separator {
border: 0;
border-top: var(--decor-border-100);
}
.panel {
color: rgb(var(--tone-gray-900));
background-color: rgb(var(--tone-gray-000));
}
.panel,
.panel-separator {
border-color: rgb(var(--tone-border));
}
`;

View File

@ -24,6 +24,16 @@ export default class DomPosition extends Helper {
}
}
return target(rect);
} else {
// if we are using this as part of an on-resize
// provide and easy way to map coords to CSS props
const $el = e.target;
const rect = $el.getBoundingClientRect();
target.forEach(
([prop, value]) => {
$el.style[value] = `${rect[prop]}px`;
}
);
}
};
}

View File

@ -4,16 +4,23 @@ import { css } from '@lit/reactive-element';
import resolve from 'consul-ui/utils/path/resolve';
import panel from 'consul-ui/components/panel/index.css';
import distributionMeter from 'consul-ui/components/distribution-meter/index.css';
import distributionMeterMeter from 'consul-ui/components/distribution-meter/meter/index.css';
import distributionMeterMeterElement from 'consul-ui/components/distribution-meter/meter/element';
import visuallyHidden from 'consul-ui/styles/base/decoration/visually-hidden.css';
import baseKeyframes from 'consul-ui/styles/base/icons/base-keyframes.css';
import chevronDown from 'consul-ui/styles/base/icons/icons/chevron-down/index.css';
const fs = {
['/components/panel/index.css']: panel,
['/components/distribution-meter/index.css']: distributionMeter,
['/components/distribution-meter/meter/index.css']: distributionMeterMeter,
['/components/distribution-meter/meter/element']: distributionMeterMeterElement,
['/styles/base/decoration/visually-hidden.css']: visuallyHidden
['/styles/base/decoration/visually-hidden.css']: visuallyHidden,
['/styles/base/icons/base-keyframes.css']: baseKeyframes,
['/styles/base/icons/icons/chevron-down/index.css']: chevronDown
};
const container = new Map();

View File

@ -0,0 +1,91 @@
export default css => css`
*::before, *::after {
display: inline-block;
animation-play-state: paused;
animation-fill-mode: forwards;
animation-iteration-count: var(--icon-resolution, 1);
vertical-align: text-top;
}
*::before {
animation-name: var(--icon-name-start, var(--icon-name)),
var(--icon-size-start, var(--icon-size, icon-000));
background-color: var(--icon-color-start, var(--icon-color));
}
*::after {
animation-name: var(--icon-name-end, var(--icon-name)),
var(--icon-size-end, var(--icon-size, icon-000));
background-color: var(--icon-color-end, var(--icon-color));
}
[style*='--icon-color-start']::before {
color: var(--icon-color-start);
}
[style*='--icon-color-end']::after {
color: var(--icon-color-end);
}
[style*='--icon-name-start']::before,
[style*='--icon-name-end']::after {
content: '';
}
@keyframes icon-000 {
100% {
width: 1.2em;
height: 1.2em;
}
}
@keyframes icon-100 {
100% {
width: 0.625rem; /* 10px */
height: 0.625rem; /* 10px */
}
}
@keyframes icon-200 {
100% {
width: 0.75rem; /* 12px */
height: 0.75rem; /* 12px */
}
}
@keyframes icon-300 {
100% {
width: 1rem; /* 16px */
height: 1rem; /* 16px */
}
}
@keyframes icon-400 {
100% {
width: 1.125rem; /* 18px */
height: 1.125rem; /* 18px */
}
}
@keyframes icon-500 {
100% {
width: 1.250rem; /* 20px */
height: 1.250rem; /* 20px */
}
}
@keyframes icon-600 {
100% {
width: 1.375rem; /* 22px */
height: 1.375rem; /* 22px */
}
}
@keyframes icon-700 {
100% {
width: 1.500rem; /* 24px */
height: 1.500rem; /* 24px */
}
}
@keyframes icon-800 {
100% {
width: 1.625rem; /* 26px */
height: 1.625rem; /* 26px */
}
}
@keyframes icon-900 {
100% {
width: 1.750rem; /* 28px */
height: 1.750rem; /* 28px */
}
}
`;

View File

@ -0,0 +1,16 @@
export default css => css `
@keyframes icon-chevron-down {
50% {
background-color: var(--icon-color, var(--color-chevron-down-500, currentColor));
-webkit-mask-image: var(--icon-chevron-down-24);
mask-image: var(--icon-chevron-down-24);
}
100% {
background-color: var(--icon-color, var(--color-chevron-down-500, currentColor));
-webkit-mask-image: var(--icon-chevron-down-16);
mask-image: var(--icon-chevron-down-16);
}
}`;

View File

@ -0,0 +1,16 @@
export default css => css `
@keyframes icon-chevron-up {
50% {
background-color: var(--icon-color, var(--color-chevron-up-500, currentColor));
-webkit-mask-image: var(--icon-chevron-up-24);
mask-image: var(--icon-chevron-up-24);
}
100% {
background-color: var(--icon-color, var(--color-chevron-up-500, currentColor));
-webkit-mask-image: var(--icon-chevron-up-16);
mask-image: var(--icon-chevron-up-16);
}
}`;

View File

@ -0,0 +1,17 @@
export default css => css `
@keyframes icon-chevrons-down {
50% {
background-color: var(--icon-color, var(--color-chevrons-down-500, currentColor));
-webkit-mask-image: var(--icon-chevrons-down-24);
mask-image: var(--icon-chevrons-down-24);
}
100% {
background-color: var(--icon-color, var(--color-chevrons-down-500, currentColor));
-webkit-mask-image: var(--icon-chevrons-down-16);
mask-image: var(--icon-chevrons-down-16);
}
}
`;