ui: Fix code editor resizing and restyle (#11474)
Fixes an issue where the code editor would not resizing to the full extent of the browser window plus CodeEditor restyling/refactoring - :label named block - :tools named block - :content named block - code and CSS cleanup - CodeEditor.mdx Signed-off-by: Alessandro De Blasis <alex@deblasis.net> Co-authored-by: John Cowen <johncowen@users.noreply.github.com>
This commit is contained in:
parent
dadb7a7c33
commit
e0b46721c4
|
@ -0,0 +1,6 @@
|
|||
```release-note:bug
|
||||
ui: code editor styling (layout consistency + wide screen support)
|
||||
```
|
||||
```release-note:improvement
|
||||
ui: added copy to clipboard button in code editor toolbars
|
||||
```
|
|
@ -6,6 +6,49 @@ state: needs-love
|
|||
# CodeEditor
|
||||
|
||||
```hbs preview-template
|
||||
<CodeEditor />
|
||||
|
||||
<CodeEditor
|
||||
@readonly={{true}}
|
||||
@name={{concat name "[Rules]"}}
|
||||
@syntax="hcl"
|
||||
@oninput={{noop}}
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
<:content>
|
||||
<!-- Plain text or something that renders data like the following -->
|
||||
<Consul::ServiceIdentity::Template
|
||||
@nspace={{nspace}}
|
||||
@name={{item.Name}}
|
||||
/>
|
||||
</:content>
|
||||
</CodeEditor>
|
||||
```
|
||||
|
||||
A code-editor with syntax highlighting supporting multiple languages (JSON, HCL, YAML), validation and simple tools such as "Copy to clipboard"
|
||||
|
||||
|
||||
### Arguments
|
||||
|
||||
| Argument | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `readonly` | `Boolean` | false | If true, the content (value) of the CodeEditor cannot be changed by the user |
|
||||
| `name` | `String` | | The name attribute of the form element |
|
||||
| `syntax` | `String` | | Identifies the language used to validate/syntax highlight the code (possible values: hcl, json, yaml) |
|
||||
| `oninput` | `Action` | noop | Action/callback that is triggered when the user inputs data |
|
||||
|
||||
### Named Blocks
|
||||
|
||||
| Name | Description | Behaviour if empty |
|
||||
| --- | --- | --- |
|
||||
| `:label` | Used to define the title that's displayed on the left inside the toolbar above the CodeEditor | Nothing is displayed |
|
||||
| `:tools` | Used to define tools, buttons, widgets that will be displayed on the right inside the toolbar above the CodeEditor | By default it renders a `language selector` dropdown (if `readonly`== false and `syntax` is falsy) and a `CopyButton`
|
||||
| `:content` | Used to display specific content such as code templates inside the CodeEditor | if the block is defined, @value will be displayed instead |
|
||||
|
||||
|
||||
### See
|
||||
|
||||
- [Component Source Code](./index.js)
|
||||
- [Template Source Code](./index.hbs)
|
||||
|
||||
---
|
||||
|
|
|
@ -1,11 +1,28 @@
|
|||
<div class="toolbar-container">
|
||||
<div class="toolbar">
|
||||
<label class="title">
|
||||
{{#if (has-block "label")}}
|
||||
{{yield to="label"}}
|
||||
{{/if}}
|
||||
</label>
|
||||
<div class="tools">
|
||||
{{#if (has-block "tools")}}
|
||||
{{yield to="tools"}}
|
||||
{{else}}
|
||||
{{#if (and (not readonly) (not syntax))}}
|
||||
<PowerSelect
|
||||
@onChange={{action "change"}}
|
||||
@selected={{mode}}
|
||||
@searchEnabled={{false}}
|
||||
@options={{modes}} as |mode|>
|
||||
{{mode.name}}
|
||||
</PowerSelect>
|
||||
<div class="toolbar-separator"></div>
|
||||
<CopyButton @value={{value}} @name="value" />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<IvyCodemirror @value={{value}} @name={{name}} @class={{class}} @options={{options}} @valueUpdated={{action onkeyup}} />
|
||||
<pre><code>{{yield}}</code></pre>
|
||||
{{#if (and (not readonly) (not syntax))}}
|
||||
<PowerSelect
|
||||
@onChange={{action "change"}}
|
||||
@selected={{mode}}
|
||||
@searchEnabled={{false}}
|
||||
@options={{modes}} as |mode|>
|
||||
{{mode.name}}
|
||||
</PowerSelect>
|
||||
{{/if}}
|
||||
<pre><code>{{#if (has-block "content")}}{{yield to="content"}}{{else}}{{value}}{{/if}}</code></pre>
|
||||
|
|
|
@ -3,23 +3,9 @@
|
|||
border: 10px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
clear: both;
|
||||
}
|
||||
%code-editor .ember-power-select-trigger {
|
||||
@extend %code-editor-syntax-select;
|
||||
}
|
||||
%code-editor-syntax-select {
|
||||
width: 200px;
|
||||
float: right;
|
||||
z-index: 1;
|
||||
}
|
||||
%code-editor-syntax-select {
|
||||
margin-top: 1px;
|
||||
border: 0;
|
||||
background-color: rgb(var(--black));
|
||||
color: rgb(var(--white));
|
||||
border-left: 1px solid;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
%code-editor::after {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
|
@ -32,3 +18,51 @@
|
|||
%code-editor > pre {
|
||||
display: none;
|
||||
}
|
||||
|
||||
%code-editor {
|
||||
.toolbar-container,
|
||||
.toolbar-container .toolbar {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.toolbar-container {
|
||||
position: relative;
|
||||
margin-top: 4px;
|
||||
height: 44px;
|
||||
|
||||
.toolbar {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
|
||||
.title {
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.toolbar-separator {
|
||||
height: 32px;
|
||||
margin: 0 4px;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.tools {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0 10px;
|
||||
align-items: center;
|
||||
.copy-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ember-basic-dropdown-trigger {
|
||||
margin: 0 8px;
|
||||
width: 120px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ $syntax-dark-gray: #535f73;
|
|||
--syntax-yellow: rgb(var(--tone-yellow-500));
|
||||
}
|
||||
.CodeMirror {
|
||||
max-width: 1150px;
|
||||
max-width: 1260px;
|
||||
min-height: 300px;
|
||||
height: auto;
|
||||
/* adds some space at the bottom of the editor for when a horizonal-scroll has appeared */
|
||||
|
@ -186,3 +186,35 @@ $syntax-dark-gray: #535f73;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
%code-editor {
|
||||
.toolbar-container {
|
||||
background: rgb(var(--tone-gray-050));
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgb(var(--tone-gray-050)) 50%,
|
||||
rgb(var(--tone-gray-150)) 100%
|
||||
);
|
||||
border: 1px solid rgb(var(--tone-gray-150));
|
||||
border-bottom-color: rgb(var(--tone-gray-600));
|
||||
border-top-color: rgb(var(--tone-gray-400));
|
||||
|
||||
.toolbar {
|
||||
.title {
|
||||
color: rgb(var(--tone-gray-900));
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.toolbar-separator {
|
||||
border-right: 1px solid rgb(var(--tone-gray-300));
|
||||
}
|
||||
}
|
||||
.ember-power-select-trigger {
|
||||
background-color: rgb(var(--tone-gray-000));
|
||||
color: rgb(var(--tone-gray-999));
|
||||
border-radius: var(--decor-radius-100);
|
||||
border: var(--decor-border-100);
|
||||
border-color: rgb(var(--tone-gray-700));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,16 +38,19 @@
|
|||
<span>Code</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label for="" class="type-text{{if api.data.error.Value ' has-error'}}">
|
||||
<span>Value</span>
|
||||
{{#if json}}
|
||||
<CodeEditor
|
||||
@name="value"
|
||||
@readonly={{or disabld api.disabled}}
|
||||
@value={{atob api.data.Value}}
|
||||
@onkeyup={{action api.change "value"}}
|
||||
/>
|
||||
>
|
||||
<:label>Value</:label>
|
||||
</CodeEditor>
|
||||
{{else}}
|
||||
<span>Value</span>
|
||||
<textarea
|
||||
{{disabled (or disabld api.disabled)}}
|
||||
autofocus={{not api.isCreate}}
|
||||
|
|
|
@ -36,27 +36,40 @@
|
|||
<strong>{{item.error.Name.validation}}</strong>
|
||||
{{/if}}
|
||||
</label>
|
||||
<label class="type-text" data-test-rules>
|
||||
<span>Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a></span>
|
||||
<label for="" class="type-text" data-test-rules>
|
||||
{{#if (eq item.template 'service-identity')}}
|
||||
<CodeEditor
|
||||
@readonly={{true}}
|
||||
@name={{concat name "[Rules]"}}
|
||||
@syntax="hcl"
|
||||
@oninput={{action "change" (concat name "[Rules]")}}
|
||||
><Consul::ServiceIdentity::Template
|
||||
@nspace={{nspace}}
|
||||
@name={{item.Name}}
|
||||
/></CodeEditor>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
<:content>
|
||||
<Consul::ServiceIdentity::Template
|
||||
@nspace={{nspace}}
|
||||
@name={{item.Name}}
|
||||
/>
|
||||
</:content>
|
||||
</CodeEditor>
|
||||
{{else if (eq item.template 'node-identity')}}
|
||||
<CodeEditor
|
||||
@readonly={{true}}
|
||||
@name={{concat name "[Rules]"}}
|
||||
@syntax="hcl"
|
||||
@oninput={{action "change" (concat name "[Rules]")}}
|
||||
><Consul::NodeIdentity::Template
|
||||
@name={{item.Name}}
|
||||
/></CodeEditor>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
<:content>
|
||||
<Consul::NodeIdentity::Template
|
||||
@name={{item.Name}}
|
||||
/>
|
||||
</:content>
|
||||
</CodeEditor>
|
||||
{{else}}
|
||||
<CodeEditor
|
||||
@syntax="hcl"
|
||||
|
@ -64,7 +77,11 @@
|
|||
@name={{concat name "[Rules]"}}
|
||||
@value={{item.Rules}}
|
||||
@onkeyup={{action "change" (concat name "[Rules]")}}
|
||||
/>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
</CodeEditor>
|
||||
{{#if item.error.Rules}}
|
||||
<strong>{{item.error.Rules.validation}}</strong>
|
||||
{{/if}}
|
||||
|
|
|
@ -114,28 +114,45 @@
|
|||
</dl>
|
||||
{{/if}}
|
||||
<label class="type-text">
|
||||
<span>Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a></span>
|
||||
{{#if (eq item.template 'service-identity')}}
|
||||
<CodeEditor
|
||||
@syntax="hcl"
|
||||
@readonly={{true}}
|
||||
><Consul::ServiceIdentity::Template
|
||||
@nspace={{nspace}}
|
||||
@name={{item.Name}}
|
||||
/></CodeEditor>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
<:content>
|
||||
<Consul::ServiceIdentity::Template
|
||||
@nspace={{nspace}}
|
||||
@name={{item.Name}}
|
||||
/>
|
||||
</:content>
|
||||
</CodeEditor>
|
||||
{{else if (eq item.template 'node-identity')}}
|
||||
<CodeEditor
|
||||
@syntax="hcl"
|
||||
@readonly={{true}}
|
||||
><Consul::NodeIdentity::Template
|
||||
@name={{item.Name}}
|
||||
/></CodeEditor>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
<:content>
|
||||
<Consul::NodeIdentity::Template
|
||||
@name={{item.Name}}
|
||||
/>
|
||||
</:content>
|
||||
</CodeEditor>
|
||||
{{else}}
|
||||
<CodeEditor
|
||||
@syntax="hcl"
|
||||
@readonly={{true}}
|
||||
@value={{or loadedItem.Rules item.Rules}}
|
||||
/>
|
||||
>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
</CodeEditor>
|
||||
{{/if}}
|
||||
</label>
|
||||
{{#if (not disabled)}}
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
<label class="type-text">
|
||||
<span>Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a></span>
|
||||
<CodeEditor @class={{if item.error.Rules "error"}} @name="Rules" @syntax="hcl" @value={{item.Rules}} @onkeyup={{action "change" "Rules"}} />
|
||||
<CodeEditor
|
||||
@class={{if item.error.Rules "error"}} @name="Rules" @syntax="hcl" @value={{item.Rules}} @onkeyup={{action "change" "Rules"}}>
|
||||
<:label>
|
||||
Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a>
|
||||
</:label>
|
||||
</CodeEditor>
|
||||
</label>
|
||||
{{#if create }}
|
||||
<label class="type-text">
|
||||
|
|
Loading…
Reference in New Issue