mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1496439 - Implement the flex item sizing outline in the flexbox panel. r=gl
Differential Revision: https://phabricator.services.mozilla.com/D7733 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
8eb10516b2
commit
87ac76f795
@ -181,7 +181,12 @@ BoxModel.prototype = {
|
||||
this._updateReasons = [];
|
||||
|
||||
return null;
|
||||
}).bind(this))().catch(console.error);
|
||||
}).bind(this))().catch(error => {
|
||||
// If we failed because we were being destroyed while waiting for a request, ignore.
|
||||
if (this.document) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
this._lastRequest = lastRequest;
|
||||
},
|
||||
|
@ -0,0 +1,147 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { colorUtils } = require("devtools/shared/css/color");
|
||||
|
||||
const Types = require("../types");
|
||||
|
||||
class FlexItemSizingOutline extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
color: PropTypes.string.isRequired,
|
||||
flexDirection: PropTypes.string.isRequired,
|
||||
flexItem: PropTypes.shape(Types.flexItem).isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
renderBasisOutline(mainBaseSize) {
|
||||
return (
|
||||
dom.div({
|
||||
className: "flex-outline-basis" + (!mainBaseSize ? " zero-basis" : ""),
|
||||
style: {
|
||||
color: colorUtils.setAlpha(this.props.color, 0.4),
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
renderDeltaOutline(mainDeltaSize) {
|
||||
if (!mainDeltaSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({
|
||||
className: "flex-outline-delta",
|
||||
style: {
|
||||
backgroundColor: colorUtils.setAlpha(this.props.color, 0.1)
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
renderFinalOutline(mainFinalSize, mainMaxSize, mainMinSize) {
|
||||
const isClamped = mainFinalSize === mainMaxSize ||
|
||||
mainFinalSize === mainMinSize;
|
||||
|
||||
return (
|
||||
dom.div({
|
||||
className: "flex-outline-final" + (isClamped ? " clamped" : "")
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
renderPoint(name) {
|
||||
return dom.div({ className: `flex-outline-point ${name}`, "data-label": name });
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
mainBaseSize,
|
||||
mainDeltaSize,
|
||||
mainMaxSize,
|
||||
mainMinSize,
|
||||
} = this.props.flexItem.flexItemSizing;
|
||||
const isRow = this.props.flexDirection.startsWith("row");
|
||||
|
||||
// Calculate the final size. This is base + delta, then clamped by min or max.
|
||||
let mainFinalSize = mainBaseSize + mainDeltaSize;
|
||||
mainFinalSize = Math.max(mainFinalSize, mainMinSize);
|
||||
mainFinalSize = Math.min(mainFinalSize, mainMaxSize);
|
||||
|
||||
// The max size is only interesting to show if it did clamp the item
|
||||
const showMax = mainMaxSize === mainFinalSize;
|
||||
|
||||
// The min size is only really interesting if it actually clamped the item.
|
||||
const showMin = mainMinSize === mainFinalSize;
|
||||
|
||||
// Sort all of the dimensions in order to come up with a grid track template.
|
||||
// Make mainDeltaSize start from the same point as the other ones so we can compare.
|
||||
let sizes = [
|
||||
{ name: "basis-end", size: mainBaseSize },
|
||||
{ name: "final-end", size: mainFinalSize }
|
||||
];
|
||||
|
||||
if (mainDeltaSize > 0) {
|
||||
sizes.push({ name: "delta-start", size: mainBaseSize });
|
||||
sizes.push({ name: "delta-end", size: mainBaseSize + mainDeltaSize });
|
||||
} else {
|
||||
sizes.push({ name: "delta-start", size: mainBaseSize + mainDeltaSize });
|
||||
sizes.push({ name: "delta-end", size: mainBaseSize });
|
||||
}
|
||||
|
||||
if (showMax) {
|
||||
sizes.push({ name: "max", size: mainMaxSize });
|
||||
}
|
||||
if (showMin) {
|
||||
sizes.push({ name: "min", size: mainMinSize });
|
||||
}
|
||||
|
||||
sizes = sizes.sort((a, b) => a.size - b.size);
|
||||
|
||||
let gridTemplateColumns = "[final-start basis-start";
|
||||
let accumulatedSize = 0;
|
||||
for (const { name, size } of sizes) {
|
||||
const breadth = Math.round(size - accumulatedSize);
|
||||
if (breadth === 0) {
|
||||
gridTemplateColumns += ` ${name}`;
|
||||
continue;
|
||||
}
|
||||
|
||||
gridTemplateColumns += `] ${breadth}fr [${name}`;
|
||||
accumulatedSize = size;
|
||||
}
|
||||
gridTemplateColumns += "]";
|
||||
|
||||
return (
|
||||
dom.div({ className: "flex-outline-container" },
|
||||
dom.div(
|
||||
{
|
||||
className: "flex-outline" +
|
||||
(isRow ? " row" : " column") +
|
||||
(mainDeltaSize > 0 ? " growing" : " shrinking"),
|
||||
style: {
|
||||
color: this.props.color,
|
||||
gridTemplateColumns
|
||||
}
|
||||
},
|
||||
this.renderPoint("basis"),
|
||||
this.renderPoint("final"),
|
||||
showMin ? this.renderPoint("min") : null,
|
||||
showMax ? this.renderPoint("max") : null,
|
||||
this.renderBasisOutline(mainBaseSize),
|
||||
this.renderDeltaOutline(mainDeltaSize),
|
||||
this.renderFinalOutline(mainFinalSize, mainMaxSize, mainMinSize)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FlexItemSizingOutline;
|
@ -4,7 +4,12 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createElement,
|
||||
createFactory,
|
||||
Fragment,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
|
||||
@ -15,6 +20,9 @@ loader.lazyGetter(this, "FlexContainerProperties", function() {
|
||||
loader.lazyGetter(this, "FlexItemList", function() {
|
||||
return createFactory(require("./FlexItemList"));
|
||||
});
|
||||
loader.lazyGetter(this, "FlexItemSizingOutline", function() {
|
||||
return createFactory(require("./FlexItemSizingOutline"));
|
||||
});
|
||||
loader.lazyGetter(this, "FlexItemSizingProperties", function() {
|
||||
return createFactory(require("./FlexItemSizingProperties"));
|
||||
});
|
||||
@ -27,6 +35,7 @@ const Types = require("../types");
|
||||
class Flexbox extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||
flexContainer: PropTypes.shape(Types.flexContainer).isRequired,
|
||||
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||
@ -60,6 +69,9 @@ class Flexbox extends PureComponent {
|
||||
}
|
||||
|
||||
renderFlexItemSizing() {
|
||||
const {
|
||||
color,
|
||||
} = this.props.flexbox;
|
||||
const {
|
||||
flexItems,
|
||||
flexItemShown,
|
||||
@ -71,10 +83,17 @@ class Flexbox extends PureComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
return FlexItemSizingProperties({
|
||||
flexDirection: properties["flex-direction"],
|
||||
flexItem,
|
||||
});
|
||||
return createElement(Fragment, null,
|
||||
FlexItemSizingOutline({
|
||||
color,
|
||||
flexDirection: properties["flex-direction"],
|
||||
flexItem,
|
||||
}),
|
||||
FlexItemSizingProperties({
|
||||
flexDirection: properties["flex-direction"],
|
||||
flexItem,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -11,6 +11,7 @@ DevToolsModules(
|
||||
'FlexItem.js',
|
||||
'FlexItemList.js',
|
||||
'FlexItemSelector.js',
|
||||
'FlexItemSizingOutline.js',
|
||||
'FlexItemSizingProperties.js',
|
||||
'Header.js',
|
||||
)
|
||||
|
@ -14,3 +14,5 @@ DevToolsModules(
|
||||
'flexbox.js',
|
||||
'types.js',
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
6
devtools/client/inspector/flexbox/test/.eslintrc.js
Normal file
6
devtools/client/inspector/flexbox/test/.eslintrc.js
Normal file
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../../.eslintrc.mochitests.js"
|
||||
};
|
13
devtools/client/inspector/flexbox/test/browser.ini
Normal file
13
devtools/client/inspector/flexbox/test/browser.ini
Normal file
@ -0,0 +1,13 @@
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
doc_flexbox_simple.html
|
||||
head.js
|
||||
!/devtools/client/inspector/test/head.js
|
||||
!/devtools/client/inspector/test/shared-head.js
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
|
||||
[browser_flexbox_item_outline_exists.js]
|
||||
[browser_flexbox_item_outline_rotates_for_column.js]
|
||||
[browser_flexbox_item_outline_has_correct_layout.js]
|
@ -0,0 +1,34 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the flex item outline exists when a flex item is selected.
|
||||
|
||||
const TEST_URI = URL_ROOT + "doc_flexbox_simple.html";
|
||||
|
||||
add_task(async function() {
|
||||
await addTab(TEST_URI);
|
||||
const { inspector, flexboxInspector } = await openLayoutView();
|
||||
const { document: doc } = flexboxInspector;
|
||||
|
||||
// Select a flex item in the test document and wait for the outline to be rendered.
|
||||
const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline-container");
|
||||
await selectNode(".item", inspector);
|
||||
const [flexOutlineContainer] = await onFlexItemOutlineRendered;
|
||||
|
||||
ok(flexOutlineContainer, "The flex outline exists in the DOM");
|
||||
|
||||
const [basis, final] = [...flexOutlineContainer.querySelectorAll(
|
||||
".flex-outline-basis, .flex-outline-final")];
|
||||
|
||||
ok(basis, "The basis outline exists");
|
||||
ok(final, "The final outline exists");
|
||||
|
||||
const [basisPoint, finalPoint] = [...flexOutlineContainer.querySelectorAll(
|
||||
".flex-outline-point.basis, .flex-outline-point.final")];
|
||||
|
||||
ok(basisPoint, "The basis point exists");
|
||||
ok(finalPoint, "The final point exists");
|
||||
});
|
@ -0,0 +1,52 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the flex item outline has a correct layout. This outline is built using css
|
||||
// grid under the hood to position everything. So we want to check that the template for
|
||||
// this grid has been correctly generated depending on the item that is currently
|
||||
// selected.
|
||||
|
||||
const TEST_URI = URL_ROOT + "doc_flexbox_simple.html";
|
||||
|
||||
const TEST_DATA = [{
|
||||
selector: ".shrinking .item",
|
||||
expectedGridTemplate: "[final-start basis-start] 300fr [final-end delta-start] " +
|
||||
"200fr [basis-end delta-end]"
|
||||
}, {
|
||||
selector: ".shrinking.is-clamped .item",
|
||||
expectedGridTemplate: "[final-start basis-start] 300fr [delta-start] " +
|
||||
"50fr [final-end min] 150fr [basis-end delta-end]"
|
||||
}, {
|
||||
selector: ".growing .item",
|
||||
expectedGridTemplate: "[final-start basis-start] 200fr [basis-end delta-start] " +
|
||||
"100fr [final-end delta-end]"
|
||||
}, {
|
||||
selector: ".growing.is-clamped .item",
|
||||
expectedGridTemplate: "[final-start basis-start] 200fr [basis-end delta-start] " +
|
||||
"50fr [final-end max] 50fr [delta-end]"
|
||||
}];
|
||||
|
||||
add_task(async function() {
|
||||
await addTab(TEST_URI);
|
||||
const { inspector, flexboxInspector } = await openLayoutView();
|
||||
const { document: doc } = flexboxInspector;
|
||||
|
||||
for (const {selector, expectedGridTemplate} of TEST_DATA) {
|
||||
info(`Checking the grid template for the flex item outline for ${selector}`);
|
||||
|
||||
const flexOutline = await selectNodeAndGetFlexOutline(selector, inspector, doc);
|
||||
|
||||
is(flexOutline.style.gridTemplateColumns, expectedGridTemplate,
|
||||
"Grid template is correct");
|
||||
}
|
||||
});
|
||||
|
||||
async function selectNodeAndGetFlexOutline(selector, inspector, doc) {
|
||||
const onFlexItemOutlineRendered = waitForDOM(doc, ".flex-outline");
|
||||
await selectNode(selector, inspector);
|
||||
const [flexOutlineContainer] = await onFlexItemOutlineRendered;
|
||||
return flexOutlineContainer;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the flex item outline is rotated for flex items in a column flexbox layout.
|
||||
|
||||
const TEST_URI = URL_ROOT + "doc_flexbox_simple.html";
|
||||
|
||||
add_task(async function() {
|
||||
await addTab(TEST_URI);
|
||||
const { inspector, flexboxInspector } = await openLayoutView();
|
||||
const { document: doc } = flexboxInspector;
|
||||
|
||||
// Select a flex item in the row flexbox layout.
|
||||
let onFlexItemOutlineRendered = waitForDOM(doc,
|
||||
".flex-outline-container .flex-outline");
|
||||
await selectNode(".container .item", inspector);
|
||||
let [flexOutline] = await onFlexItemOutlineRendered;
|
||||
|
||||
ok(flexOutline.classList.contains("row"), "The flex outline has the row class");
|
||||
|
||||
// Check that the outline is wider than it is tall in the configuration.
|
||||
let bounds = flexOutline.getBoxQuads()[0].getBounds();
|
||||
ok(bounds.width > bounds.height, "The outline looks like a row");
|
||||
|
||||
// Select a flex item in the column flexbox layout.
|
||||
onFlexItemOutlineRendered = waitForDOM(doc,
|
||||
".flex-outline-container .flex-outline");
|
||||
await selectNode(".container.column .item", inspector);
|
||||
([flexOutline] = await onFlexItemOutlineRendered);
|
||||
|
||||
ok(flexOutline.classList.contains("column"), "The flex outline has the column class");
|
||||
|
||||
// Check that the outline is taller than it is wide in the configuration.
|
||||
bounds = flexOutline.getBoxQuads()[0].getBounds();
|
||||
ok(bounds.height > bounds.width, "The outline looks like a column");
|
||||
});
|
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
.container {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
}
|
||||
.container.column {
|
||||
height: 300px;
|
||||
width: 150px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.item {
|
||||
background: #0004;
|
||||
}
|
||||
.shrinking .item {
|
||||
flex-basis: 500px;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.shrinking.is-clamped .item {
|
||||
min-width: 350px;
|
||||
}
|
||||
.growing .item {
|
||||
flex-basis: 200px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.growing.is-clamped .item {
|
||||
max-width: 250px;
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
<div class="item">flex item in a row flex container</div>
|
||||
</div>
|
||||
<div class="container column">
|
||||
<div class="item">flex item in a column flex container</div>
|
||||
</div>
|
||||
<div class="container shrinking">
|
||||
<div class="item">Shrinking flex item</div>
|
||||
</div>
|
||||
<div class="container shrinking is-clamped">
|
||||
<div class="item">Shrinking and clamped flex item</div>
|
||||
</div>
|
||||
<div class="container growing">
|
||||
<div class="item">Growing flex item</div>
|
||||
</div>
|
||||
<div class="container growing is-clamped">
|
||||
<div class="item">Growing and clamped flex item</div>
|
||||
</div>
|
21
devtools/client/inspector/flexbox/test/head.js
Normal file
21
devtools/client/inspector/flexbox/test/head.js
Normal file
@ -0,0 +1,21 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||
/* import-globals-from ../../test/head.js */
|
||||
"use strict";
|
||||
|
||||
// Import the inspector's head.js first (which itself imports shared-head.js).
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
|
||||
this);
|
||||
|
||||
// Make sure only the flexbox layout accordion is opened, and the others are closed.
|
||||
Services.prefs.setBoolPref("devtools.layout.flexbox.opened", true);
|
||||
Services.prefs.setBoolPref("devtools.layout.boxmodel.opened", false);
|
||||
Services.prefs.setBoolPref("devtools.layout.grid.opened", false);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.layout.flexbox.opened");
|
||||
Services.prefs.clearUserPref("devtools.layout.boxmodel.opened");
|
||||
Services.prefs.clearUserPref("devtools.layout.grid.opened");
|
||||
});
|
@ -146,6 +146,7 @@ function openLayoutView() {
|
||||
inspector: data.inspector,
|
||||
boxmodel: data.inspector.getPanel("boxmodel"),
|
||||
gridInspector: data.inspector.layoutview.gridInspector,
|
||||
flexboxInspector: data.inspector.layoutview.flexboxInspector,
|
||||
layoutView: data.inspector.layoutview,
|
||||
testActor: data.testActor
|
||||
};
|
||||
|
@ -107,6 +107,7 @@ devtools.jar:
|
||||
skin/images/accessibility.svg (themes/images/accessibility.svg)
|
||||
skin/images/add.svg (themes/images/add.svg)
|
||||
skin/images/arrowhead-left.svg (themes/images/arrowhead-left.svg)
|
||||
skin/images/arrowhead-right.svg (themes/images/arrowhead-right.svg)
|
||||
skin/images/arrowhead-down.svg (themes/images/arrowhead-down.svg)
|
||||
skin/images/arrowhead-up.svg (themes/images/arrowhead-up.svg)
|
||||
skin/images/breadcrumbs-divider.svg (themes/images/breadcrumbs-divider.svg)
|
||||
@ -278,6 +279,7 @@ devtools.jar:
|
||||
skin/images/reveal.svg (themes/images/reveal.svg)
|
||||
skin/images/select-arrow.svg (themes/images/select-arrow.svg)
|
||||
skin/images/settings.svg (themes/images/settings.svg)
|
||||
skin/images/lock.svg (themes/images/lock.svg)
|
||||
|
||||
# Debugger
|
||||
skin/images/debugger/angular.svg (themes/images/debugger/angular.svg)
|
||||
|
6
devtools/client/themes/images/arrowhead-right.svg
Normal file
6
devtools/client/themes/images/arrowhead-right.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="context-fill #0C0C0D" fill-rule="evenodd" clip-rule="evenodd" d="M8.293 4.293a1 1 0 0 1 1.414 0l7 7a1 1 0 0 1 0 1.414l-7 7a1 1 0 0 1-1.414-1.414L14.586 12 8.293 5.707a1 1 0 0 1 0-1.414z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 524 B |
6
devtools/client/themes/images/lock.svg
Normal file
6
devtools/client/themes/images/lock.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="context-fill">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 7a3 3 0 1 1 6 0v3H9V7zm-2 3V7a5 5 0 1 1 10 0v3h1a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h1z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 501 B |
@ -158,10 +158,187 @@
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flex Item Sizing Outline
|
||||
*/
|
||||
|
||||
.flex-outline-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-outline {
|
||||
display: grid;
|
||||
margin: 2em 0;
|
||||
grid-auto-rows: 35px;
|
||||
flex-basis: 80%;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.flex-outline.column {
|
||||
transform: translate(50%, -2em) rotate(.25turn);
|
||||
transform-origin: center left;
|
||||
flex-basis: 150px;
|
||||
margin-bottom: 120px;
|
||||
}
|
||||
|
||||
.flex-outline-final,
|
||||
.flex-outline-basis,
|
||||
.flex-outline-delta {
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.flex-outline-final {
|
||||
border: 1px solid currentColor;
|
||||
position: relative;
|
||||
grid-column: final-start / final-end;
|
||||
}
|
||||
|
||||
.flex-outline-final.clamped::after {
|
||||
content: "";
|
||||
background-color: var(--theme-body-background);
|
||||
background-image: url(chrome://devtools/skin/images/lock.svg);
|
||||
background-size: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 1px;
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.flex-outline.column .flex-outline-final.clamped::after {
|
||||
transform: rotate(-.25turn);
|
||||
}
|
||||
|
||||
.flex-outline-basis {
|
||||
border-style: dotted;
|
||||
border-width: 3px;
|
||||
margin: 1px 0;
|
||||
grid-column: basis-start / basis-end;
|
||||
}
|
||||
|
||||
.flex-outline-basis.zero-basis {
|
||||
border-width: 0 0 0 3px;
|
||||
}
|
||||
|
||||
.flex-outline-delta {
|
||||
background-repeat: round;
|
||||
fill: currentColor;
|
||||
-moz-context-properties: fill;
|
||||
grid-column: delta-start / delta-end;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.flex-outline.growing .flex-outline-delta {
|
||||
background-image: url(chrome://devtools/skin/images/arrowhead-right.svg);
|
||||
}
|
||||
|
||||
.flex-outline.shrinking .flex-outline-delta {
|
||||
background-image: url(chrome://devtools/skin/images/arrowhead-left.svg);
|
||||
}
|
||||
|
||||
.flex-outline-point {
|
||||
position: relative;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.flex-outline-point {
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.flex-outline-point.basis {
|
||||
grid-column-end: basis-end;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.flex-outline.shrinking .flex-outline-point.basis {
|
||||
grid-column-start: basis-end;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.flex-outline-point.final {
|
||||
grid-column-start: final-end;
|
||||
left: -1px;
|
||||
}
|
||||
|
||||
.flex-outline.shrinking .flex-outline-point.final {
|
||||
grid-column-end: final-end;
|
||||
grid-column-start: unset;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.flex-outline-point.min {
|
||||
grid-column: min;
|
||||
place-self: end;
|
||||
}
|
||||
|
||||
.flex-outline.shrinking .flex-outline-point.min {
|
||||
place-self: end start;
|
||||
}
|
||||
|
||||
.flex-outline-point.max {
|
||||
grid-column: max;
|
||||
align-self: end;
|
||||
left: -1px;
|
||||
}
|
||||
|
||||
.flex-outline-point::before {
|
||||
content: attr(data-label);
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 0 3px;
|
||||
height: 10px;
|
||||
border-color: currentColor;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.flex-outline.column .flex-outline-point::before {
|
||||
padding: 0;
|
||||
writing-mode: sideways-lr;
|
||||
}
|
||||
|
||||
.flex-outline-point.basis::before,
|
||||
.flex-outline-point.final::before {
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.flex-outline-point.min::before,
|
||||
.flex-outline-point.max::before {
|
||||
bottom: -12px;
|
||||
}
|
||||
|
||||
.flex-outline.column .flex-outline-point.min::before,
|
||||
.flex-outline.column .flex-outline-point.min::before {
|
||||
text-indent: -12px;
|
||||
}
|
||||
|
||||
.flex-outline-point.final::before,
|
||||
.flex-outline.shrinking .flex-outline-point.min::before,
|
||||
.flex-outline-point.max::before,
|
||||
.flex-outline.shrinking .flex-outline-point.basis::before {
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
|
||||
.flex-outline-point.basis::before,
|
||||
.flex-outline-point.min::before,
|
||||
.flex-outline.shrinking .flex-outline-point.final::before {
|
||||
border-width: 0 1px 0 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flex Item Sizing Properties
|
||||
*/
|
||||
|
||||
#flex-item-sizing-properties {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#flex-item-sizing-properties span {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user