mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
Initial Move from Azure DevOps to GitHub
This commit is contained in:
93
src/Explorer/Controls/CollapsiblePanel/CollapsiblePanel.tsx
Normal file
93
src/Explorer/Controls/CollapsiblePanel/CollapsiblePanel.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Collapsible React component
|
||||
* Note:
|
||||
* If onCollapsedChanged() is triggered, parent container is responsible for:
|
||||
* - updating isCollapsed property
|
||||
* - calling render()
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import LeftArrowIcon from "../../../../images/imgarrowlefticon.svg";
|
||||
import { AccessibleElement } from "../../Controls/AccessibleElement/AccessibleElement";
|
||||
|
||||
export interface CollapsiblePanelProps {
|
||||
collapsedTitle: string;
|
||||
expandedTitle: string;
|
||||
isCollapsed: boolean;
|
||||
onCollapsedChanged: (newValue: boolean) => void;
|
||||
collapseToLeft?: boolean;
|
||||
}
|
||||
|
||||
export class CollapsiblePanel extends React.Component<CollapsiblePanelProps> {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className={`collapsiblePanel ${this.props.isCollapsed ? "paneCollapsed" : ""}`}>
|
||||
{!this.props.isCollapsed ? this.getExpandedFragment() : this.getCollapsedFragment()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleCollapse(): void {
|
||||
this.props.onCollapsedChanged(!this.props.isCollapsed);
|
||||
}
|
||||
|
||||
private getCollapsedFragment(): JSX.Element {
|
||||
return (
|
||||
<div className="collapsibleNav nav">
|
||||
<ul className="nav">
|
||||
<li className="collapsedBtn collapseExpandButton">
|
||||
<AccessibleElement
|
||||
className="collapsedIconContainer"
|
||||
as="span"
|
||||
onActivated={() => this.toggleCollapse()}
|
||||
aria-label="Expand panel"
|
||||
>
|
||||
<img
|
||||
className={`collapsedIcon ${!this.props.isCollapsed ? "expanded" : ""} ${
|
||||
this.props.collapseToLeft ? "iconMirror" : ""
|
||||
}`}
|
||||
src={LeftArrowIcon}
|
||||
alt="Expand"
|
||||
/>
|
||||
</AccessibleElement>
|
||||
<AccessibleElement
|
||||
className="rotatedInner"
|
||||
as="span"
|
||||
onActivated={() => this.toggleCollapse()}
|
||||
aria-label="Expand panel"
|
||||
>
|
||||
<span>{this.props.collapsedTitle}</span>
|
||||
</AccessibleElement>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private getExpandedFragment(): JSX.Element {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="panelHeader">
|
||||
<AccessibleElement
|
||||
as="span"
|
||||
className={`collapsedIconContainer collapseExpandButton ${this.props.collapseToLeft ? "pull-right" : ""}`}
|
||||
onActivated={() => this.toggleCollapse()}
|
||||
aria-label="Collapse panel"
|
||||
>
|
||||
<img
|
||||
className={`collapsedIcon imgVerticalAlignment ${!this.props.isCollapsed ? "expanded" : ""} ${
|
||||
this.props.collapseToLeft ? "iconMirror" : ""
|
||||
}`}
|
||||
src={LeftArrowIcon}
|
||||
alt="Collapse"
|
||||
/>
|
||||
</AccessibleElement>
|
||||
<span className={`expandedTitle ${!this.props.collapseToLeft ? "iconSpacer" : ""}`}>
|
||||
{this.props.expandedTitle}
|
||||
</span>
|
||||
</div>
|
||||
<div className="panelContent">{this.props.children}</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
@import "../../../../less/Common/Constants";
|
||||
|
||||
.collapsiblePanel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.collapsiblePanel.paneCollapsed {
|
||||
width: 39px !important;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsedIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.collapsiblePanel .imgVerticalAlignment {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsedIcon.iconMirror:not(.expanded) {
|
||||
transform: rotate(-180deg);
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-ms-transform: rotate(-180deg);
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsedIcon.expanded:not(.iconMirror) {
|
||||
transform: rotate(-180deg);
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-ms-transform: rotate(-180deg);
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader {
|
||||
padding: 5px 0px 12px 0px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader .collapsedIconContainer {
|
||||
padding: 4px 0px 4px 6px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader .expandedTitle {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader .expandedTitle.iconSpacer {
|
||||
padding-left: 0px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelContent {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav .rotatedInner {
|
||||
color: black;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin: 3px 10px;
|
||||
transform: rotate(180deg);
|
||||
-webkit-transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
float: right;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav .collapsedBtn {
|
||||
padding: 5px 5px 0px 0px;
|
||||
cursor: pointer;
|
||||
margin: 0px 0px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader .collapseExpandButton:hover,
|
||||
.collapsiblePanel .collapsibleNav .collapseExpandButton:hover {
|
||||
background: @BaseLow;
|
||||
}
|
||||
|
||||
.collapsiblePanel .panelHeader .collapseExpandButton:active,
|
||||
.collapsiblePanel .collapsibleNav .collapseExpandButton:active {
|
||||
background-color: @AccentMediumLow;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav ul.nav {
|
||||
margin: 0 auto;
|
||||
margin-top: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav ul.nav li {
|
||||
float: right;
|
||||
line-height: 25px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav {
|
||||
width: 100vh;
|
||||
height: 45px;
|
||||
background: white;
|
||||
transform-origin: left top;
|
||||
-webkit-transform-origin: left top;
|
||||
-ms-transform-origin: left top;
|
||||
transform: rotate(-90deg) translateX(-100%);
|
||||
-webkit-transform: rotate(-90deg) translateX(-100%);
|
||||
-ms-transform: rotate(-90deg) translateX(-100%);
|
||||
}
|
||||
|
||||
.collapsiblePanel .collapsibleNav .collapsedIconContainer {
|
||||
transform: rotate(90deg);
|
||||
-webkit-transform: rotate(90deg);
|
||||
-ms-transform: rotate(90deg);
|
||||
float: right;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import * as ko from "knockout";
|
||||
import template from "./collapsible-panel-component.html";
|
||||
|
||||
/**
|
||||
* Helper class for ko component registration
|
||||
*/
|
||||
export class CollapsiblePanelComponent {
|
||||
constructor() {
|
||||
return {
|
||||
viewModel: CollapsiblePanelViewModel,
|
||||
template
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for this component
|
||||
*/
|
||||
interface CollapsiblePanelParams {
|
||||
collapsedTitle: ko.Observable<string>;
|
||||
expandedTitle: ko.Observable<string>;
|
||||
isCollapsed?: ko.Observable<boolean>;
|
||||
collapseToLeft?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapsible panel:
|
||||
* Contains a header with [>] button to collapse and an title ("expandedTitle").
|
||||
* Collapsing the panel:
|
||||
* - shrinks width to narrow amount
|
||||
* - hides children
|
||||
* - shows [<]
|
||||
* - shows vertical title ("collapsedTitle")
|
||||
* - the default behavior is to collapse to the right (ie, place this component on the right or use "collapseToLeft" parameter)
|
||||
*
|
||||
* How to use in your markup:
|
||||
* <collapsible-panel params="{ collapsedTitle:'Properties', expandedTitle:'Expanded properties' }">
|
||||
* <!-- add your markup here: the ko context is the same as outside of collapsible-panel (ie $data) -->
|
||||
* </collapsible-panel>
|
||||
*
|
||||
* Use the optional "isCollapsed" parameter to programmatically collapse/expand the pane from outside the component.
|
||||
* Use the optional "collapseToLeft" parameter to collapse to the left.
|
||||
*/
|
||||
class CollapsiblePanelViewModel {
|
||||
private params: CollapsiblePanelParams;
|
||||
private isCollapsed: ko.Observable<boolean>;
|
||||
|
||||
public constructor(params: CollapsiblePanelParams) {
|
||||
this.params = params;
|
||||
this.isCollapsed = params.isCollapsed || ko.observable(false);
|
||||
}
|
||||
|
||||
private toggleCollapse(): void {
|
||||
this.isCollapsed(!this.isCollapsed());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<div class="collapsiblePanel" data-bind="css: { paneCollapsed:isCollapsed() }">
|
||||
<div class="panelHeader" data-bind="visible: !isCollapsed()">
|
||||
<span
|
||||
class="collapsedIconContainer collapseExpandButton"
|
||||
data-bind="click:toggleCollapse, css: { 'pull-right':params.collapseToLeft }"
|
||||
>
|
||||
<img
|
||||
class="collapsedIcon imgVerticalAlignment"
|
||||
src="/imgarrowlefticon.svg"
|
||||
alt="Collapse"
|
||||
data-bind="css: { expanded:!isCollapsed(), iconMirror:params.collapseToLeft }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="expandedTitle"
|
||||
data-bind="text: params.expandedTitle, css:{ iconSpacer:!params.collapseToLeft }"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="collapsibleNav nav" data-bind="visible:isCollapsed">
|
||||
<ul class="nav">
|
||||
<li class="collapsedBtn collapseExpandButton">
|
||||
<span class="collapsedIconContainer" data-bind="click: toggleCollapse">
|
||||
<img
|
||||
class="collapsedIcon"
|
||||
src="/imgarrowlefticon.svg"
|
||||
data-bind="css: { expanded:!isCollapsed(), iconMirror:params.collapseToLeft }"
|
||||
alt="Expand"
|
||||
/>
|
||||
</span>
|
||||
<span class="rotatedInner" data-bind="click: toggleCollapse">
|
||||
<span data-bind="text: params.collapsedTitle"></span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="panelContent" data-bind="visible:!isCollapsed()">
|
||||
<!-- ko with:$parent -->
|
||||
<!-- ko template: { nodes: $componentTemplateNodes } -->
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user