Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix rendering of inline code blocks for docs
Browse files Browse the repository at this point in the history
Styling of codeblocks:

- Uniform margins as other documentation elements.
- Add small margin for inline code-blocks.
- Use different background color for inline code-blocks.
- Introduce `inline-code` and `code-block` mixins for clarity in
  styling.

Overflowing of codeblocks:

- Improve flex layout of the tree component to be handle overflowing
  content and providing maximum available width. To be able to correctly
  provide maximum available width in card content, card expansion layout
  is changed so both close button and the content gets their full width.
- Other refactorings to support this:
  - Introduce separate Vue component for checkboxes of nodes for better
    separation of concerns and improved maintainability.
  - Refactor `LeafTreeNode` to make it simpler, separating layout concerns
    from other styling.
  - `ScriptsTree.vue`: Prefer `<div>`s instead of `<span>`s as they
    represent large content.
  - Remove unnecessary `<div>`s and use `<template>`s to reduce HTML
    complexity.
  - Update script documentation to not include unnecessary left padding
    on script code blocks.
undergroundwires committed Nov 25, 2023
1 parent 7c632f7 commit cfccefd
Showing 12 changed files with 280 additions and 166 deletions.
6 changes: 3 additions & 3 deletions src/application/collections/windows.yaml
Original file line number Diff line number Diff line change
@@ -7196,9 +7196,9 @@ actions:
To view all the scheduled tasks related to Windows Update, you can use the following PowerShell command:

```powershell
@('\Microsoft\Windows\UpdateOrchestrator\*', '\Microsoft\Windows\WindowsUpdate\*', '\Microsoft\Windows\WaaSMedic\*', '\Microsoft\Windows\InstallService\*') `
| ForEach-Object { Get-ScheduledTask -TaskName '*' -TaskPath $_ -ErrorAction SilentlyContinue } `
| ForEach-Object { Write-Host "$($_.TaskPath)$($_.TaskName)" }
@('\Microsoft\Windows\UpdateOrchestrator\*', '\Microsoft\Windows\WindowsUpdate\*', '\Microsoft\Windows\WaaSMedic\*', '\Microsoft\Windows\InstallService\*') `
| ForEach-Object { Get-ScheduledTask -TaskName '*' -TaskPath $_ -ErrorAction SilentlyContinue } `
| ForEach-Object { Write-Host "$($_.TaskPath)$($_.TaskName)" }
```
children:
-
18 changes: 10 additions & 8 deletions src/presentation/components/Scripts/View/Cards/CardListItem.vue
Original file line number Diff line number Diff line change
@@ -30,15 +30,15 @@
/>
</div>
<div class="card__expander" @click.stop>
<div class="card__expander__content">
<ScriptsTree :category-id="categoryId" />
</div>
<div class="card__expander__close-button">
<AppIcon
icon="xmark"
@click="collapse()"
/>
</div>
<div class="card__expander__content">
<ScriptsTree :category-id="categoryId" />
</div>
</div>
</div>
</template>
@@ -184,20 +184,24 @@ $card-horizontal-gap : $card-gap;
position: relative;
background-color: $color-primary-darker;
color: $color-on-primary;
display: flex;
align-items: center;
flex-direction: column;
&__content {
flex: 1;
display: flex;
justify-content: center;
word-break: break-word;
margin-bottom: 1em;
margin-left: 0.5em;
margin-right: 0.5em;
max-width: 100%; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
&__close-button {
width: auto;
font-size: 1.5em;
align-self: flex-start;
align-self: flex-end;
margin-right: 0.25em;
@include clickable;
color: $color-primary-light;
@@ -242,8 +246,6 @@ $card-horizontal-gap : $card-gap;
.card__expander {
min-height: 200px;
// max-height: 1000px;
// overflow-y: auto;
margin-top: $expanded-margin-top;
opacity: 1;
}
8 changes: 4 additions & 4 deletions src/presentation/components/Scripts/View/TheScriptsView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="scripts">
<div v-if="!isSearching">
<template v-if="!isSearching">
<template v-if="currentView === ViewType.Cards">
<CardList />
</template>
@@ -9,8 +9,8 @@
<ScriptsTree />
</div>
</template>
</div>
<div v-else>
</template>
<template v-else>
<!-- Searching -->
<div class="search">
<div class="search__query">
@@ -33,7 +33,7 @@
<div v-if="searchHasMatches" class="tree tree--searching">
<ScriptsTree />
</div>
</div>
</template>
</div>
</template>

Original file line number Diff line number Diff line change
@@ -62,14 +62,16 @@ export default defineComponent({
.container {
display: flex;
flex-direction: column;
flex: 1; // Expands the container to fill available horizontal space, enabling alignment of child items.
max-width: 100%; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
*:not(:first-child) {
margin-left: 5px;
}
.header {
display: flex;
flex-direction: row;
.content {
flex: 1;
flex: 1; // Expands the content to fill available width, aligning the documentation button to the right.
}
}
.docs {
Original file line number Diff line number Diff line change
@@ -59,19 +59,50 @@ function renderAsMarkdownListItem(content: string): string {
$text-color: $color-on-primary;
$text-size: 0.75em; // Lower looks bad on Firefox
$base-spacing: $text-size;
@mixin code-block() {
pre {
// :has(> code) { @content; } would be better, but Firefox doesn't support it https://caniuse.com/css-has
@content;
}
}
@mixin inline-code() {
:not(pre) > code {
@content;
}
}
@mixin code() {
code {
@content;
}
}
.documentation-text {
color: $text-color;
font-size: $text-size;
font-family: $font-main;
code {
word-break: break-all; // Inline code should wrap with the line, or whole text overflows
@include code {
font-family: $font-normal;
font-weight: 600;
}
@include inline-code {
word-break: break-all; // Enables inline code to wrap with the text, even for long single words (like registry paths), thus preventing overflow.
}
@include code-block {
padding: $base-spacing;
background: $color-primary-darker;
overflow: auto; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
a {
&[href] {
word-break: break-word; // So URLs don't overflow
word-break: break-word; // Enables long URLs to wrap within the container, preventing horizontal overflow.
}
&[href^="http"]{
&:after {
@@ -116,47 +147,49 @@ $text-size: 0.75em; // Lower looks bad on Firefox
}
}
@mixin left-padding($selectors, $horizontal-gap) {
@mixin left-padding($selectors, $horizontal-spacing) {
#{$selectors} {
padding-inline-start: $horizontal-gap;
padding-inline-start: $horizontal-spacing;
}
}
@mixin bottom-margin($selectors, $vertical-gap) {
@mixin bottom-margin($selectors, $vertical-spacing) {
#{$selectors} {
&:not(:last-child) {
margin-bottom: $vertical-gap;
margin-bottom: $vertical-spacing;
}
}
}
@mixin apply-uniform-vertical-spacing($vertical-gap) {
@mixin apply-uniform-vertical-spacing($base-vertical-spacing) {
/* Reset default top/bottom margins added by browser. */
@include no-margin('p');
@include no-margin('h1, h2, h3, h4, h5, h6');
@include no-margin('blockquote');
@include no-margin('pre');
/* Add spacing between elements using `margin-bottom` only (bottom-out instead of top-down strategy). */
$small-gap: math.div($vertical-gap, 2);
@include bottom-margin('p', $vertical-gap);
@include bottom-margin('h1, h2, h3, h4, h5, h6', $vertical-gap);
@include bottom-margin('ul, ol', $vertical-gap);
@include bottom-margin('li', $small-gap);
@include bottom-margin('table', $vertical-gap);
@include bottom-margin('blockquote', $vertical-gap);
$small-vertical-spacing: math.div($base-vertical-spacing, 2);
@include bottom-margin('p', $base-vertical-spacing);
@include bottom-margin('h1, h2, h3, h4, h5, h6', $base-vertical-spacing);
@include bottom-margin('ul, ol', $base-vertical-spacing);
@include bottom-margin('li', $small-vertical-spacing);
@include bottom-margin('table', $base-vertical-spacing);
@include bottom-margin('blockquote', $base-vertical-spacing);
@include bottom-margin('pre', $base-vertical-spacing);
}
@mixin apply-uniform-horizontal-spacing($horizontal-gap) {
@mixin apply-uniform-horizontal-spacing($base-horizontal-spacing) {
/* Reset default left/right paddings added by browser. */
@include no-padding('ul, ol');
/* Add spacing for list items. */
$list-spacing: $horizontal-gap * 2;
@include left-padding('ul, ol', $list-spacing);
$large-horizontal-spacing: $base-horizontal-spacing * 2;
@include left-padding('ul, ol', $large-horizontal-spacing);
}
@include apply-uniform-vertical-spacing($text-size);
@include apply-uniform-horizontal-spacing($text-size);
@include apply-uniform-vertical-spacing($base-spacing);
@include apply-uniform-horizontal-spacing($base-spacing);
ul {
/*
@@ -167,7 +200,7 @@ $text-size: 0.75em; // Lower looks bad on Firefox
}
blockquote {
padding: 0 1em;
padding: 0 $base-spacing;
border-left: .25em solid $color-primary;
}
}
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ export default defineComponent({
display: flex;
flex-direction: row;
flex-wrap: wrap;
.text {
display: flex;
align-items: center;
19 changes: 14 additions & 5 deletions src/presentation/components/Scripts/View/Tree/ScriptsTree.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<span id="container">
<span v-if="initialNodes.length">
<div class="scripts-tree-container">
<template v-if="initialNodes.length">
<TreeView
:initial-nodes="initialNodes"
:selected-leaf-node-ids="selectedScriptNodeIds"
@@ -11,9 +11,11 @@
<NodeContent :node-metadata="nodeMetadata" />
</template>
</TreeView>
</span>
<span v-else>Nooo 😢</span>
</span>
</template>
<template v-else>
Nooo 😢
</template>
</div>
</template>

<script lang="ts">
@@ -58,3 +60,10 @@ export default defineComponent({
},
});
</script>

<style scoped lang="scss">
.scripts-tree-container {
display: flex; // We could provide `block`, but `flex` is more versatile.
overflow: auto; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
</style>
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
:style="{
'padding-left': `${currentNode.hierarchy.depthInTree * 24}px`,
}"
@click="toggleCheck"
>
<div
class="expand-collapse-arrow"
@@ -15,16 +14,17 @@
}"
@click.stop="toggleExpand"
/>
<LeafTreeNode
:node-id="nodeId"
:tree-root="treeRoot"
>
<template #node-content="slotProps">
<slot name="node-content" v-bind="slotProps" />
</template>
</LeafTreeNode>
<div class="leaf-node">
<LeafTreeNode
:node-id="nodeId"
:tree-root="treeRoot"
>
<template #node-content="slotProps">
<slot name="node-content" v-bind="slotProps" />
</template>
</LeafTreeNode>
</div>
</div>

<transition name="children-transition">
<ul
v-if="hasChildren && expanded"
@@ -132,6 +132,12 @@ export default defineComponent({
.expansible-node {
display: flex;
flex-direction: row;
.leaf-node {
flex: 1; // Expands the node horizontally, allowing its content to utilize full width for child item alignment, such as icons and text.
overflow: auto; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
flex-direction: row;
align-items: center;
@include hover-or-touch {
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
<template>
<li
class="wrapper"
class="node focusable"
tabindex="-1"
:class="{
'keyboard-focus': hasKeyboardFocus,
}"
@click.stop="toggleCheckState"
@focus="onNodeFocus"
>
<div
class="node focusable"
:class="{
'keyboard-focus': hasKeyboardFocus,
}"
tabindex="-1"
@focus="onNodeFocus"
>
<div
class="checkbox"
:class="{
checked: checked,
indeterminate: indeterminate,
}"
/>

<div class="content">
<div class="node__layout">
<div class="node__checkbox">
<NodeCheckbox
:node-id="nodeId"
:tree-root="treeRoot"
/>
</div>
<div class="node__content content">
<slot
name="node-content"
:node-metadata="currentNode.metadata"
@@ -36,10 +32,13 @@ import { useCurrentTreeNodes } from '../UseCurrentTreeNodes';
import { useNodeState } from './UseNodeState';
import { useKeyboardInteractionState } from './UseKeyboardInteractionState';
import { TreeNode } from './TreeNode';
import { TreeNodeCheckState } from './State/CheckState';
import NodeCheckbox from './NodeCheckbox.vue';
import type { PropType } from 'vue';
export default defineComponent({
components: {
NodeCheckbox,
},
props: {
nodeId: {
type: String,
@@ -53,22 +52,14 @@ export default defineComponent({
setup(props) {
const { isKeyboardBeingUsed } = useKeyboardInteractionState();
const { nodes } = useCurrentTreeNodes(toRef(props, 'treeRoot'));
const currentNode = computed<TreeNode>(
() => nodes.value.getNodeById(props.nodeId),
);
const currentNode = computed<TreeNode>(() => nodes.value.getNodeById(props.nodeId));
const { state } = useNodeState(currentNode);
const hasFocus = computed<boolean>(() => state.value.isFocused);
const checked = computed<boolean>(() => state.value.checkState === TreeNodeCheckState.Checked);
const indeterminate = computed<boolean>(
() => state.value.checkState === TreeNodeCheckState.Indeterminate,
);
const hasKeyboardFocus = computed<boolean>(() => {
if (!isKeyboardBeingUsed.value) {
return false;
}
return hasFocus.value;
return state.value.isFocused;
});
const onNodeFocus = () => {
@@ -82,8 +73,6 @@ export default defineComponent({
return {
onNodeFocus,
toggleCheckState,
indeterminate,
checked,
currentNode,
hasKeyboardFocus,
};
@@ -95,91 +84,59 @@ export default defineComponent({
@use "@/presentation/assets/styles/main" as *;
@use "./../tree-colors" as *;
.wrapper {
.node__layout {
display: flex;
align-items: center;
flex: 1;
padding-bottom: 3px;
padding-top: 3px;
.focusable {
outline: none; // We handle keyboard focus through own styling
}
.node {
display: flex;
align-items: center;
padding-bottom: 3px;
padding-top: 3px;
padding-right: 6px;
cursor: pointer;
width: 100%;
box-sizing: border-box;
&.keyboard-focus {
background: $color-node-highlight-bg;
}
@include hover-or-touch {
background: $color-node-highlight-bg;
}
.checkbox {
flex-shrink: 0;
position: relative;
width: 30px;
height: 30px;
box-sizing: border-box;
border: 1px solid $color-node-checkbox-border-unchecked;
border-radius: 2px;
transition: border-color .25s, background-color .25s;
background: $color-node-checkbox-bg-unchecked;
&:after {
position: absolute;
display: block;
content: "";
}
&.indeterminate {
border-color: $color-node-checkbox-border-unchecked;
.node__checkbox {
flex-shrink: 0; // Always render the checkbox properly on small screens
}
.node__content {
flex: 1; // Expands the node horizontally, allowing its content to utilize full width for child item alignment, such as icons and text.
overflow: auto; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
}
&:after {
background-color: $color-node-checkbox-border-indeterminate;
top: 50%;
left: 20%;
right: 20%;
height: 2px;
}
}
.focusable {
outline: none; // We handle keyboard focus through own styling
}
.node {
margin-bottom: 3px;
margin-top: 3px;
padding-bottom: 3px;
padding-top: 3px;
padding-right: 6px;
cursor: pointer;
box-sizing: border-box;
&.checked {
background: $color-node-checkbox-bg-checked;
border-color: $color-node-checkbox-border-checked;
&.keyboard-focus {
background: $color-node-highlight-bg;
}
&:after {
box-sizing: content-box;
border: 1.5px solid $color-node-checkbox-tick-checked;
/* probably width would be rounded in most cases */
border-left: 0;
border-top: 0;
left: 9px;
top: 3px;
height: 15px;
width: 8px;
transform: rotate(45deg) scaleY(1);
transition: transform .25s;
transform-origin: center;
}
}
}
@include hover-or-touch {
background: $color-node-highlight-bg;
}
.content {
padding-left: 9px;
padding-right: 6px;
flex-grow: 2;
text-decoration: none;
color: $color-node-fg;
line-height: 24px;
user-select: none;
font-size: 1.5em;
}
.content {
display: flex; // We could provide `block`, but `flex` is more versatile.
color: $color-node-fg;
padding-left: 9px;
padding-right: 6px;
text-decoration: none;
user-select: none;
font-size: 1.5em;
line-height: 24px;
/*
Following is a workaround fixing overflow-y caused by line height being smaller than font.
It should be removed once a proper line-height matching the font-size (not smaller than) is used.
*/
$line-height-compensation: calc((1.5em - 24px) / 4);
padding-top: $line-height-compensation;
padding-bottom: $line-height-compensation;
margin-top: calc(-1 * $line-height-compensation);
margin-bottom: calc(-1 * $line-height-compensation);
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<template>
<div
class="checkbox"
:class="{
checked: checked,
indeterminate: indeterminate,
}"
/>
</template>

<script lang="ts">
import { defineComponent, computed, toRef } from 'vue';
import { TreeRoot } from '../TreeRoot/TreeRoot';
import { useCurrentTreeNodes } from '../UseCurrentTreeNodes';
import { useNodeState } from './UseNodeState';
import { TreeNode } from './TreeNode';
import { TreeNodeCheckState } from './State/CheckState';
import type { PropType } from 'vue';
export default defineComponent({
props: {
nodeId: {
type: String,
required: true,
},
treeRoot: {
type: Object as PropType<TreeRoot>,
required: true,
},
},
setup(props) {
const { nodes } = useCurrentTreeNodes(toRef(props, 'treeRoot'));
const currentNode = computed<TreeNode>(
() => nodes.value.getNodeById(props.nodeId),
);
const { state } = useNodeState(currentNode);
const checked = computed<boolean>(() => state.value.checkState === TreeNodeCheckState.Checked);
const indeterminate = computed<boolean>(
() => state.value.checkState === TreeNodeCheckState.Indeterminate,
);
return {
indeterminate,
checked,
currentNode,
};
},
});
</script>

<style scoped lang="scss">
@use "@/presentation/assets/styles/main" as *;
@use "./../tree-colors" as *;
$sideSizeInPx: 30px;
.checkbox {
position: relative;
width: $sideSizeInPx;
height: $sideSizeInPx;
box-sizing: border-box;
border: 1px solid $color-node-checkbox-border-unchecked;
border-radius: 2px;
transition: border-color .25s, background-color .25s;
background: $color-node-checkbox-bg-unchecked;
&:after {
position: absolute;
display: block;
content: "";
}
&.indeterminate {
border-color: $color-node-checkbox-border-unchecked;
&:after {
background-color: $color-node-checkbox-border-indeterminate;
top: 50%;
left: 20%;
right: 20%;
height: 2px;
}
}
&.checked {
background: $color-node-checkbox-bg-checked;
border-color: $color-node-checkbox-border-checked;
&:after {
box-sizing: content-box;
border: 1.5px solid $color-node-checkbox-tick-checked;
border-left: 0;
border-top: 0;
left: 9px;
top: 3px;
height: 15px;
width: 8px;
transform: rotate(45deg) scaleY(1);
transition: transform .25s;
transform-origin: center;
}
}
}
</style>
Original file line number Diff line number Diff line change
@@ -63,8 +63,5 @@ export default defineComponent({
.tree-root {
@include reset-ul;
margin-block-start: 1em;
margin-block-end: 1em;
padding-inline-start: 3px;
}
</style>
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ export default defineComponent({
@use "./tree-colors" as *;
.tree {
overflow: auto;
background: $color-tree-bg;
overflow: auto; // Prevents horizontal expansion of inner content (e.g., when a code block is shown)
}
</style>

0 comments on commit cfccefd

Please sign in to comment.