features/rewrite/modal1 #10
@ -15,4 +15,11 @@
|
||||
<ProjectReference Include="..\Connected.Components.Showcase\Connected.Components.Showcase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Watch Include="..\..\src\**" />
|
||||
<Watch Remove="..\..\src\**\obj\**" />
|
||||
<Watch Remove="..\..\src\**\bin\**" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,5 +1,7 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<ModalDialog/>
|
||||
|
||||
<main>
|
||||
@Body
|
||||
</main>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
using Connected.Components.Showcase.Runner;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Connected.Services;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
@ -12,6 +13,8 @@ internal class Program
|
||||
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||
|
||||
builder.Services.AddModalDialogService();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Connected.Components.Showcase.Runner</title>
|
||||
<base href="/" />
|
||||
<link href="css/app.css" rel="stylesheet" />
|
||||
@ -27,4 +28,4 @@
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
@ -1,44 +1,9 @@
|
||||
<button
|
||||
type="button"
|
||||
href="#"
|
||||
@onclick="@OnClick"
|
||||
disabled=@Disabled
|
||||
style="@Style"
|
||||
class="@ClassList">
|
||||
<button type="button"
|
||||
@onclick="@OnClick"
|
||||
disabled=@Disabled
|
||||
style="@StyleList"
|
||||
class="@ClassList">
|
||||
<div class="@ContentClassList">
|
||||
@if (!string.IsNullOrEmpty(Glyph))
|
||||
{
|
||||
@if (GlyphPosition == Position.Top || GlyphPosition == Position.Bottom)
|
||||
{
|
||||
<div style="align-items:center">
|
||||
@if (GlyphPosition == Position.Top)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor"/>
|
||||
}
|
||||
@ChildContent
|
||||
@if (GlyphPosition == Position.Bottom)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor"/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (GlyphPosition == Position.Left || GlyphPosition == Position.Right)
|
||||
{
|
||||
<div style="display:flex; align-items:center">
|
||||
@if (GlyphPosition == Position.Left)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" Class="m-1" />
|
||||
}
|
||||
@ChildContent
|
||||
@if (GlyphPosition == Position.Right)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" Class="m-1" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
} else
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
</div>
|
||||
</button>
|
||||
|
@ -1,8 +1,6 @@
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using static Connected.Colors;
|
||||
using System;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class Button
|
||||
@ -28,10 +26,10 @@ public partial class Button
|
||||
/// <summary>
|
||||
/// Size of the button.
|
||||
/// Options: Size.[Small,Medium,Large,FullWidth]
|
||||
/// Default: Size.Large
|
||||
/// Default: Size.Medium
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Size Size { get; set; } = Size.Large;
|
||||
public Size Size { get; set; } = Size.Medium;
|
||||
|
||||
/// <summary>
|
||||
/// Text shown inside the button
|
||||
@ -48,29 +46,6 @@ public partial class Button
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Glyph (Icon) inside the button.
|
||||
/// Options: SVG string --> Icons
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Glyph { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the glyph relative to button Text parameter. If Glyph parameter == string.Empty this parameter is ignored
|
||||
/// Options: Position.[left,top,right,bottom]
|
||||
/// Default: Position.left
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Position GlyphPosition { get; set; } = Position.Left;
|
||||
|
||||
/// <summary>
|
||||
/// HEX string of the color for the glyph. If Glyph parameter is empty this parameter is ignored
|
||||
/// Options: any HEX color string
|
||||
/// Default: Black (#000000)
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string GlyphColor { get; set; } = "#000000";
|
||||
|
||||
/// <summary>
|
||||
/// User defined custom class added on top of default generated classes
|
||||
@ -90,7 +65,7 @@ public partial class Button
|
||||
|
||||
/// <summary>
|
||||
/// User defined custom style
|
||||
/// Options: any user defined string with valid CSS style
|
||||
/// Options: any valid CSS style
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
@ -115,10 +90,21 @@ public partial class Button
|
||||
|
||||
#region Styling
|
||||
|
||||
public string StyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Generated class list for button based on user parameters
|
||||
/// </summary>
|
||||
private string ClassList
|
||||
public string ClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -134,7 +120,7 @@ public partial class Button
|
||||
/// <summary>
|
||||
/// Generated class list for button based on user parameters
|
||||
/// </summary>
|
||||
private string ContentClassList
|
||||
public string ContentClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -2,12 +2,22 @@
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<div class="checkbox-group">
|
||||
@if (Checked)
|
||||
{
|
||||
<input id="@Id" name="checkbox" type="checkbox" @onchange="OnChange" @attributes=@InputAttributes checked>
|
||||
} else {
|
||||
<input id="@Id" name="checkbox" type="checkbox" @onchange="OnChange" @attributes=@InputAttributes>
|
||||
}
|
||||
<label for="@Id" class="checkbox-label">@Label</label>
|
||||
</div>
|
||||
<label class="checkbox-group"
|
||||
for="@Id">
|
||||
<input class="@ClassList"
|
||||
style="@StyleList"
|
||||
id="@Id"
|
||||
type="checkbox"
|
||||
@attributes=@InputAttributes
|
||||
checked="@Checked"
|
||||
readonly="@Readonly"
|
||||
disabled="@Disabled">
|
||||
<div class="checkbox-fill"></div>
|
||||
<label for="@Id"
|
||||
class="@LabelClassList"
|
||||
style="@LabelStyleList">
|
||||
@Label
|
||||
</label>
|
||||
</label>
|
||||
|
||||
|
||||
|
@ -1,21 +1,100 @@
|
||||
using Connected.Models;
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class CheckBox: InputBase
|
||||
public partial class CheckBox : InputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// State of the CheckBox
|
||||
/// Options: true, false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool Checked { get; set; } = false;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ID for the CheckBox
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event when the checked is changed
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<bool> CheckedChange { get; set; }
|
||||
public async Task OnChange(ChangeEventArgs args)
|
||||
public EventCallback<bool> CheckedChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OPTIONAL - Style for the input
|
||||
/// Options: any valid CSS style
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Style { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// OPTIONAL - Class for the label of input
|
||||
/// Options: any valid Class name or multiple separated with space
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string LabelClass { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// OPTIONAL - Style for the label of input
|
||||
/// Options: any valid CSS style
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string LabelStyle { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// OnChange event when checked is changed
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task OnChange()
|
||||
{
|
||||
Checked = (bool)args.Value;
|
||||
CheckedChange.InvokeAsync(Checked);
|
||||
Checked = !Checked;
|
||||
await CheckedChanged.InvokeAsync(Checked);
|
||||
}
|
||||
|
||||
private string ClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder("checkbox-input")
|
||||
.AddClass(base.Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
private string StyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
private string LabelClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder("checkbox-label")
|
||||
.AddClass(LabelClass)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
private string LabelStyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(LabelStyle)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
@using Connected.Models;
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<div>
|
||||
<div class="container">
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
@ -1,11 +0,0 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class CheckBoxGroup
|
||||
{
|
||||
[Parameter, EditorRequired]
|
||||
public string Id { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
|
||||
<div style="width:@WidthString; height:@HeightString; overflow:hidden">
|
||||
<svg viewBox="0 0 24 24" style="fill:@Color;" class="@GlyphClassList" @onclick="@OnClick">
|
||||
<div style="@GlyphStyleList">
|
||||
<svg viewBox="0 0 24 24" class="@GlyphClassList" @onclick="@OnClick">
|
||||
@((MarkupString)SVG)
|
||||
</svg>
|
||||
</div>
|
@ -2,59 +2,87 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace Connected.Components
|
||||
namespace Connected.Components;
|
||||
|
||||
public partial class Glyph
|
||||
{
|
||||
public partial class Glyph
|
||||
{
|
||||
[Parameter]
|
||||
public string SVG { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// SVG markup string for glyph
|
||||
/// Options: any valid SVG markup string
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string SVG { get; set; } = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Color { get; set; } = "#000000";
|
||||
/// <summary>
|
||||
/// Color of the glyph
|
||||
/// Options: Color.[Core,Primary,Secondary,Success,Info,Warning,Danger,White,Light,Dark]
|
||||
/// Default: Color.Dark
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color Color { get; set; } = Color.Dark;
|
||||
|
||||
[Parameter]
|
||||
public int Width { get; set; } = 24;
|
||||
[Parameter]
|
||||
public int Height { get; set; } = 24;
|
||||
/// <summary>
|
||||
/// Width of the glyph in px
|
||||
/// Options: Any positive integer number
|
||||
/// Default: 24
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Width { get; set; } = 24;
|
||||
|
||||
private string WidthString
|
||||
{
|
||||
get
|
||||
{
|
||||
return Width.ToString() + "px";
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Height of the glyph in px
|
||||
/// Options: Any positive integer number
|
||||
/// Default: 24
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Height { get; set; } = 24;
|
||||
|
||||
private string HeightString
|
||||
/// <summary>
|
||||
/// Class name or multiple classes separated by space
|
||||
/// Options: Any valid class name or names separated by space
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
|
||||
private string GlyphClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
return Width.ToString() + "px";
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
|
||||
private string GlyphClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder()
|
||||
.AddClass(Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
/// <summary>
|
||||
/// Glyph click event.
|
||||
/// </summary>
|
||||
public EventCallback<MouseEventArgs> Click { get; set; }
|
||||
protected async Task OnClick(MouseEventArgs e)
|
||||
{
|
||||
await Click.InvokeAsync(e);
|
||||
|
||||
return new CssBuilder()
|
||||
.AddClass("color-"+Helper.GetEnumDescription<Color>(Color))
|
||||
.AddClass(Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User defined style for the glyph
|
||||
/// Options: Any valid CSS style
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Style { get; set; } = string.Empty;
|
||||
|
||||
private string GlyphStyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle("width: "+Width.ToString()+"px; height:"+Height.ToString()+"px; overflow: hidden")
|
||||
.AddStyle(Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
/// <summary>
|
||||
/// Glyph click event.
|
||||
/// </summary>
|
||||
public EventCallback<MouseEventArgs> Click { get; set; }
|
||||
protected async Task OnClick(MouseEventArgs e)
|
||||
{
|
||||
await Click.InvokeAsync(e);
|
||||
}
|
||||
}
|
46
src/Connected.Components/Components/GlyphButton.razor
Normal file
46
src/Connected.Components/Components/GlyphButton.razor
Normal file
@ -0,0 +1,46 @@
|
||||
@inherits Button
|
||||
|
||||
<button type="button"
|
||||
href="#"
|
||||
@onclick="@OnClick"
|
||||
disabled=@Disabled
|
||||
style="@StyleList"
|
||||
class="@ClassList">
|
||||
<div class="@ContentClassList">
|
||||
@if (!string.IsNullOrEmpty(Glyph))
|
||||
{
|
||||
@if (GlyphPosition == Position.Top || GlyphPosition == Position.Bottom)
|
||||
{
|
||||
<div style="align-items:center">
|
||||
@if (GlyphPosition == Position.Top)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" />
|
||||
}
|
||||
@ChildContent
|
||||
@if (GlyphPosition == Position.Bottom)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@if (GlyphPosition == Position.Left || GlyphPosition == Position.Right)
|
||||
{
|
||||
<div style="display:flex; align-items:center">
|
||||
@if (GlyphPosition == Position.Left)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" Class="m-1" />
|
||||
}
|
||||
@ChildContent
|
||||
@if (GlyphPosition == Position.Right)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" Class="m-1" />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
</div>
|
||||
</button>
|
34
src/Connected.Components/Components/GlyphButton.razor.cs
Normal file
34
src/Connected.Components/Components/GlyphButton.razor.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class GlyphButton : Button
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Glyph (Icon) inside the button.
|
||||
/// Options: SVG string --> Icons
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string Glyph { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the glyph relative to button Text parameter. If Glyph parameter == string.Empty this parameter is ignored
|
||||
/// Options: Position.[left,top,right,bottom]
|
||||
/// Default: Position.left
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Position GlyphPosition { get; set; } = Position.Left;
|
||||
|
||||
/// <summary>
|
||||
/// Color for the glyph. If Glyph parameter is empty this parameter is ignored
|
||||
/// Options: Color.[Core,Primary,Secondary,Success,Info,Warning,Danger,White,Light,Dark]
|
||||
/// Default: Color.Dark
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color GlyphColor { get; set; } = Color.Dark;
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
<a
|
||||
class="@LinkClassList"
|
||||
style="@LinkStyleList"
|
||||
href="@Url"
|
||||
target="@Target" >
|
||||
<a class="@LinkClassList"
|
||||
style="@LinkStyleList"
|
||||
href="@Url"
|
||||
target="@_target">
|
||||
@Text
|
||||
</a>
|
||||
|
@ -1,49 +1,86 @@
|
||||
using Connected.Utilities;
|
||||
using Connected.Enums;
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class Link
|
||||
{
|
||||
[Parameter, EditorRequired]
|
||||
public string Url { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// URL of the link
|
||||
/// Options: Any valid web page adress
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string Url { get; set; } = string.Empty;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// Text shown for the link. If this is not provided URL is used
|
||||
/// Options: Any valid string
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public string Target { get; set; } = "_self";
|
||||
/// <summary>
|
||||
/// Target where the link shall open
|
||||
/// Options: Target.[Self,Parent,Top,Blank]
|
||||
/// Default: Target.Self
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Target Target { get; set; } = Target.Self;
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
private string _target
|
||||
{
|
||||
get
|
||||
{
|
||||
return Helper.GetEnumDescription<Target>(Target);
|
||||
}
|
||||
}
|
||||
|
||||
private string LinkClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder()
|
||||
.AddClass(Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Class name or multiple classes separated by space
|
||||
/// Options: Any valid class name or names separated by space
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Class { get; set; } = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Style { get; set; } = string.Empty;
|
||||
private string LinkClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder()
|
||||
.AddClass(Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
private string LinkStyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Style string for the link
|
||||
/// Options: Any valid CSS style
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Style { get; set; } = string.Empty;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Text)) Text = Url;
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
private string LinkStyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
//if Text parameter is not provided we set it to match URL
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
Text = Url;
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
25
src/Connected.Components/Components/ModalDialog.razor
Normal file
25
src/Connected.Components/Components/ModalDialog.razor
Normal file
@ -0,0 +1,25 @@
|
||||
@using Connected.Models.Modal;
|
||||
@if (IsVisible)
|
||||
{
|
||||
<div class="modal fade show" @onclick="@CloseIfEnabled" @onkeydown="@(e => CheckEscape(e))" tabindex="-1" @ref="@root">
|
||||
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
|
||||
<div class="modal-content" @onclick="PreventClose">
|
||||
@if (!ModalOptions.NoHeader)
|
||||
{
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">@Title</h3>
|
||||
</div>
|
||||
}
|
||||
<div class="modal-body">
|
||||
@Content
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@foreach (ModalButton button in buttons)
|
||||
{
|
||||
<button type="button" class="btn @button.GetButtonClass" @onclick="@(()=>CloseModal(button))">@button.ButtonText</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
108
src/Connected.Components/Components/ModalDialog.razor.cs
Normal file
108
src/Connected.Components/Components/ModalDialog.razor.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using Connected.Models.Modal;
|
||||
using Connected.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class ModalDialog : IDisposable
|
||||
{
|
||||
[Inject] ModalDialogService? ModalService { get; set; }
|
||||
|
||||
protected ElementReference root;
|
||||
protected bool IsVisible { get; set; }
|
||||
protected string? Title { get; set; }
|
||||
protected RenderFragment? Content { get; set; }
|
||||
protected bool OverlayClickToClose { get; set; } = true;
|
||||
|
||||
protected List<ModalButton> buttons { get; set; } = new();
|
||||
|
||||
protected ModalOptions? ModalOptions { get; set; }
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
ModalService.OnShow += ShowModal;
|
||||
ModalService.OnClose += CloseModal;
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (IsVisible)
|
||||
await root.FocusAsync();
|
||||
}
|
||||
|
||||
|
||||
public void ShowModal(string title, RenderFragment content, List<ModalButton> buttons, ModalOptions options)
|
||||
{
|
||||
Title = title;
|
||||
Content = content;
|
||||
IsVisible = true;
|
||||
|
||||
ModalOptions = options;
|
||||
this.buttons = buttons;
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void CloseModal(ModalButton? button)
|
||||
{
|
||||
if (button is not null)
|
||||
{
|
||||
if (button.CloseDialogOnClick)
|
||||
{
|
||||
CloseModal();
|
||||
}
|
||||
button.OnClickEvent.Delegate.DynamicInvoke(button.OnClickEvent.args);
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void CloseModal()
|
||||
{
|
||||
IsVisible = false;
|
||||
Title = "";
|
||||
Content = null;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (ModalService is not null)
|
||||
{
|
||||
ModalService.OnShow -= ShowModal;
|
||||
ModalService.OnClose -= CloseModal;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckEscape(KeyboardEventArgs args)
|
||||
{
|
||||
if (!ModalOptions.DisableEscKey)
|
||||
{
|
||||
var key = args.Key.ToLower();
|
||||
if (key.Equals("escape"))
|
||||
{
|
||||
CloseModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseIfEnabled(MouseEventArgs args)
|
||||
{
|
||||
if (!ModalOptions.DisableBackdropClick)
|
||||
{
|
||||
if (OverlayClickToClose)
|
||||
{
|
||||
CloseModal();
|
||||
}
|
||||
}
|
||||
OverlayClickToClose = true;
|
||||
}
|
||||
|
||||
public void PreventClose(MouseEventArgs args)
|
||||
{
|
||||
OverlayClickToClose = false;
|
||||
}
|
||||
|
||||
}
|
45
src/Connected.Components/Components/MultilineInput.razor
Normal file
45
src/Connected.Components/Components/MultilineInput.razor
Normal file
@ -0,0 +1,45 @@
|
||||
@using Connected.Models;
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<div class="@InputFieldClassList">
|
||||
<textarea value="@Value"
|
||||
placeholder="@Placeholder"
|
||||
disabled="@Disabled"
|
||||
readonly="@Readonly"
|
||||
required="@Required"
|
||||
style="overflow-x: hidden; overflow-y: hidden;"
|
||||
@oninput=@ChangeValueAsync
|
||||
@attributes="@InputAttributes" />
|
||||
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
@if (IsLabel)
|
||||
{
|
||||
<label class="label-animated">@Label</label>
|
||||
}
|
||||
@if (IsHelperText && !IsError)
|
||||
{
|
||||
<div class="input-helper-text">@HelperText</div>
|
||||
}
|
||||
@if (IsError)
|
||||
{
|
||||
<div class="input-error-text">@ErrorText</div>
|
||||
}
|
||||
<span class="input-glyph-wraper">
|
||||
<span class="input-glyph">
|
||||
@if (Clearable && !string.IsNullOrEmpty(Value))
|
||||
{
|
||||
<span class="input-glyph button" @onclick="Clear">
|
||||
<Glyph SVG="@Icons.Material.Rounded.Dangerous" />
|
||||
</span>
|
||||
}
|
||||
@if (IsError)
|
||||
{
|
||||
<span class="input-glyph error">
|
||||
<Glyph SVG="@Icons.Material.Outlined.Error" />
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
119
src/Connected.Components/Components/MultilineInput.razor.cs
Normal file
119
src/Connected.Components/Components/MultilineInput.razor.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using Connected.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class MultilineInput : InputBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
private int MinRows { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Number of rows
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Rows
|
||||
{
|
||||
get
|
||||
{
|
||||
return _numRows;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value >= MinRows) _numRows= value;
|
||||
else _numRows = MinRows;
|
||||
}
|
||||
}
|
||||
|
||||
private int _numRows = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Value of the TextInput. Used for @bind-Value
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events, Methods
|
||||
|
||||
/// <summary>
|
||||
/// Event triggered when value changes
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method that triggers oninput -> when value inside the component changes
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
private async Task ChangeValueAsync(ChangeEventArgs args)
|
||||
{
|
||||
int oldRows = Rows;
|
||||
await ValueChanged.InvokeAsync(args?.Value?.ToString());
|
||||
|
||||
int newRows = GetNumberOfLines(args.Value.ToString());
|
||||
|
||||
if (newRows == MinRows)
|
||||
{
|
||||
Rows = MinRows;
|
||||
ChangeAttribute("rows", Rows);
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
Rows = Math.Max(MinRows, newRows);
|
||||
if (oldRows < Rows)
|
||||
{
|
||||
ChangeAttribute("rows", Rows);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetNumberOfLines(string s)
|
||||
{
|
||||
int result = Math.Max(s.Split("\r\n").Length, 1);
|
||||
result = Math.Max(s.Split("\r").Length, result);
|
||||
result = Math.Max(s.Split("\n").Length, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the value of the TextInput
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task Clear()
|
||||
{
|
||||
await ValueChanged.InvokeAsync(string.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
private void AddAttribute(string key, object value)
|
||||
{
|
||||
if (!InputAttributes.ContainsKey(key))
|
||||
InputAttributes.Add(key, value);
|
||||
}
|
||||
|
||||
private void ChangeAttribute(string key, object value)
|
||||
{
|
||||
if (InputAttributes.ContainsKey(key)) InputAttributes.Remove(key);
|
||||
InputAttributes.Add(key, value);
|
||||
}
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
MinRows = Rows;
|
||||
AddAttribute("rows", MinRows);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -7,13 +7,14 @@
|
||||
<div class="@InputFieldClassList">
|
||||
<input type="text"
|
||||
placeholder="@Placeholder"
|
||||
step="@_step"
|
||||
step="@Step"
|
||||
disabled="@Disabled"
|
||||
readonly="@Readonly"
|
||||
required="@Required"
|
||||
value="@_value"
|
||||
@onkeydown=@(args => ChangeValue(args))
|
||||
@onkeydown:preventDefault="@_preventDefaultAction"
|
||||
@oninput=@GetValueAsync
|
||||
@oninput=@SetValueAsync
|
||||
@onmousewheel=@OnMouseWheel
|
||||
@onchange="@Change"
|
||||
@onwheel="OnMouseWheel"
|
||||
@ -39,18 +40,16 @@
|
||||
<Glyph Width=16 Height=16 SVG="@Icons.Material.Outlined.KeyboardArrowUp" Click="StepUp" />
|
||||
<Glyph Width=16 Height=16 SVG="@Icons.Material.Outlined.KeyboardArrowDown" Click="StepDown"></Glyph>
|
||||
</span>
|
||||
@if (Clearable && Value.ToString().Length > 0)
|
||||
@if (Clearable && !string.IsNullOrEmpty(Value?.ToString()))
|
||||
{
|
||||
<span class="input-glyph button" @onclick="Clear">
|
||||
<Glyph SVG="@Icons.Material.Rounded.Dangerous" />
|
||||
<!--<i class='bx bx-x-circle'></i>-->
|
||||
</span>
|
||||
}
|
||||
@if (IsError)
|
||||
{
|
||||
<span class="input-glyph error">
|
||||
<Glyph SVG="@Icons.Material.Outlined.Error" Color="#D10000" />
|
||||
<!--<i class='bx bx-error-circle'></i>-->
|
||||
<Glyph SVG="@Icons.Material.Outlined.Error" />
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
|
@ -5,142 +5,189 @@ using Microsoft.AspNetCore.Components.Web;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class NumberInput<NumberType>:InputBase where NumberType : INumber<NumberType>
|
||||
public partial class NumberInput<NumberType> : InputBase where NumberType : INumber<NumberType>
|
||||
{
|
||||
|
||||
private double _step =1;
|
||||
/// <summary>
|
||||
/// Step for up and down on numeric field
|
||||
/// Options: Any double number
|
||||
/// Default: 1
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public double Step {
|
||||
get
|
||||
{
|
||||
return _step;
|
||||
}
|
||||
set
|
||||
{
|
||||
_step=value;
|
||||
}
|
||||
}
|
||||
public double Step { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Mouse wheel disable to prevent StepUp/StepDown on number filed
|
||||
/// Options: true, false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool DisableMouseWheel
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = false;
|
||||
public bool DisableMouseWheel { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Increase 'Value' for the 'Step'
|
||||
/// </summary>
|
||||
/// <returns>'Value' increased for the 'Step' parameter</returns>
|
||||
private async Task StepUp()
|
||||
{
|
||||
try
|
||||
{
|
||||
double num = (double)Convert.ChangeType(Value, typeof(double));
|
||||
num += _step;
|
||||
var num = Helper.ConvertToType<double>(Value);
|
||||
|
||||
num += Step;
|
||||
|
||||
if (DecimalPlaces > 0)
|
||||
num = Math.Round(num, DecimalPlaces);
|
||||
Value = (NumberType)Convert.ChangeType(num, typeof(NumberType));
|
||||
if (IsError) ErrorText = string.Empty;
|
||||
Value = Helper.ConvertToType<NumberType>(num);
|
||||
|
||||
|
||||
if (IsError)
|
||||
ErrorText = string.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
ErrorText = "Error with step up!";
|
||||
Value = default(NumberType);
|
||||
Value = default;
|
||||
}
|
||||
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrease 'Value' for the 'Step'
|
||||
/// </summary>
|
||||
/// <returns>'Value' decreased for the 'Step' parameter</returns>
|
||||
private async Task StepDown()
|
||||
{
|
||||
try
|
||||
{
|
||||
double num = (double)Convert.ChangeType(Value, typeof(double));
|
||||
|
||||
num -= _step;
|
||||
var num = Helper.ConvertToType<double>(Value);
|
||||
|
||||
num -= Step;
|
||||
|
||||
if (DecimalPlaces > 0)
|
||||
num = Math.Round(num, DecimalPlaces);
|
||||
Value = (NumberType)Convert.ChangeType(num, typeof(NumberType));
|
||||
if (IsError) ErrorText = string.Empty;
|
||||
} catch
|
||||
|
||||
Value = Helper.ConvertToType<NumberType>(num);
|
||||
|
||||
if (IsError)
|
||||
ErrorText = string.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
ErrorText = "Error with step down!";
|
||||
Value = default(NumberType);
|
||||
Value = default;
|
||||
}
|
||||
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event triggered when mouse wheel is activated inside component
|
||||
/// </summary>
|
||||
/// <param name="args">WheelEventArgs argument</param>
|
||||
/// <returns>Doesnt return values just increasing/decreasing values</returns>
|
||||
protected async Task OnMouseWheel(WheelEventArgs args)
|
||||
{
|
||||
if (DisableMouseWheel == false)
|
||||
{
|
||||
if (args.ShiftKey || Disabled || Readonly)
|
||||
return;
|
||||
if (args.DeltaY >= 0)
|
||||
{
|
||||
await StepDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
await StepUp();
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (DisableMouseWheel)
|
||||
return;
|
||||
|
||||
if (args.ShiftKey || Disabled || Readonly)
|
||||
return;
|
||||
|
||||
if (args.DeltaY >= 0)
|
||||
{
|
||||
await StepDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
await StepUp();
|
||||
}
|
||||
}
|
||||
|
||||
private string _value;
|
||||
private string? _value;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Value of any numeric type
|
||||
/// Options: any numeric type variable
|
||||
/// Default: null
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
public NumberType? Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_value)) return default(NumberType);
|
||||
return (NumberType)Convert.ChangeType(_value, typeof(NumberType));
|
||||
if (string.IsNullOrEmpty(_value))
|
||||
return default;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return Helper.ConvertToType<NumberType>(_value);
|
||||
} catch
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_value = value.ToString();
|
||||
_value = value?.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of decimal places for Value. If set, Value is corrected when input looses focus
|
||||
/// Options: any integer number greater or equal 0
|
||||
/// Default: 0
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int DecimalPlaces { get; set; } =0;
|
||||
public int DecimalPlaces { get; set; } = 0;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Value change event
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<NumberType> ValueChanged { get; set; }
|
||||
public EventCallback<NumberType> ValueChanged { get; set; }
|
||||
|
||||
public async Task GetValueAsync(ChangeEventArgs args)
|
||||
{
|
||||
public async Task SetValueAsync(ChangeEventArgs args)
|
||||
{
|
||||
if (args.Value is not null)
|
||||
{
|
||||
string newVal = args.Value.ToString();
|
||||
var newVal = args.Value.ToString()!;
|
||||
|
||||
if (!newVal.Equals("0"))
|
||||
{
|
||||
if (newVal.ToString().Contains("-"))
|
||||
newVal = "-" + newVal.ToString().Replace("-", "");
|
||||
|
||||
if (newVal.ToString().ToLower().Contains("e"))
|
||||
newVal = "e" + newVal.ToString().Replace("e", "");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newVal))
|
||||
{
|
||||
await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType((NumberType)Convert.ChangeType(null, typeof(NumberType)), typeof(NumberType)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!newVal.Equals(_value))
|
||||
await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType((NumberType)Convert.ChangeType(newVal, typeof(NumberType)), typeof(NumberType)));
|
||||
}
|
||||
await ValueChanged.InvokeAsync(default);
|
||||
|
||||
if (!newVal.Equals(_value))
|
||||
await ValueChanged.InvokeAsync(Helper.ConvertToType<NumberType>(newVal));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Change(ChangeEventArgs args)
|
||||
{
|
||||
if (args.Value is not null)
|
||||
{
|
||||
Value = AdjustDecimalPlaces((NumberType)Convert.ChangeType(args.Value, typeof(NumberType)));
|
||||
}
|
||||
ValueChanged.InvokeAsync(Value);
|
||||
Value = AdjustDecimalPlaces(Helper.ConvertToType<NumberType>(args.Value));
|
||||
|
||||
await ValueChanged.InvokeAsync(Value);
|
||||
}
|
||||
|
||||
[Parameter] public EventCallback<KeyboardEventArgs> OnKeyDown { get; set; }
|
||||
/// <summary>
|
||||
/// On keyboard key press event
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<KeyboardEventArgs> OnKeyDown { get; set; }
|
||||
|
||||
private bool CheckKey(string key)
|
||||
{
|
||||
@ -159,7 +206,7 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
@ -172,49 +219,48 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe
|
||||
private bool _preventDefaultAction = true;
|
||||
public async Task ChangeValue(KeyboardEventArgs args)
|
||||
{
|
||||
_preventDefaultAction= true;
|
||||
_preventDefaultAction = true;
|
||||
if (args is not null)
|
||||
{
|
||||
var key = args.Key.ToString().ToLower();
|
||||
|
||||
if (CheckKey(key))
|
||||
{
|
||||
_preventDefaultAction = false;
|
||||
|
||||
await OnKeyDown.InvokeAsync(args);
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Key = null;
|
||||
}
|
||||
}
|
||||
|
||||
private NumberType AdjustDecimalPlaces(NumberType value)
|
||||
/// <summary>
|
||||
/// Method for adjusting decimal places provided with parameter
|
||||
/// </summary>
|
||||
/// <param name="value">Value whose decimal places we want to change</param>
|
||||
/// <returns>NumberType result with adjusted decimal places</returns>
|
||||
private NumberType? AdjustDecimalPlaces(NumberType? value)
|
||||
{
|
||||
var result = value;
|
||||
if (DecimalPlaces > 0)
|
||||
{
|
||||
double converted = Math.Round((double)Convert.ChangeType(result, typeof(double)), DecimalPlaces);
|
||||
return (NumberType)Convert.ChangeType(converted, typeof(NumberType));
|
||||
double converted = Math.Round(Helper.ConvertToType<double>(result), DecimalPlaces);
|
||||
return Helper.ConvertToType<NumberType>(converted);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clear event for user clear icon click. It clears the Value and set it to
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task Clear()
|
||||
{
|
||||
_value = string.Empty;
|
||||
await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType)));
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
if (!DecimalPlaces.Equals(Helper.GetDecimalPlaces(Value)))
|
||||
{
|
||||
Value = AdjustDecimalPlaces(Value);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
var val = Helper.ConvertToType<NumberType>(null);
|
||||
await ValueChanged.InvokeAsync(val);
|
||||
}
|
||||
|
||||
#region Lifecycle
|
||||
@ -222,18 +268,26 @@ public partial class NumberInput<NumberType>:InputBase where NumberType : INumbe
|
||||
{
|
||||
if (typeof(NumberType).Name.ToLower().Contains("int"))
|
||||
{
|
||||
if (Step - (int)Step > 0) Step = (int)Step;
|
||||
if (Step < 1) Step = 1;
|
||||
if (Step - (int)Step > 0)
|
||||
Step = (int)Step;
|
||||
if (Step < 1)
|
||||
Step = 1;
|
||||
}
|
||||
await base.OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
if (Required)
|
||||
if (firstRender)
|
||||
{
|
||||
if (!InputAttributes.ContainsKey("required")) InputAttributes.Add("required", true);
|
||||
if (Value is not null)
|
||||
{
|
||||
if (!DecimalPlaces.Equals(Helper.GetDecimalPlaces(Value)))
|
||||
{
|
||||
Value = AdjustDecimalPlaces(Value);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,20 @@
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<div class="radio-group">
|
||||
<input id="@Id" name="@ParentRadioGroup.Name" type="radio" @onchange="OnChange" @attributes=@InputAttributes>
|
||||
<label for="@Id" class="radio-label">@Label</label>
|
||||
</div>
|
||||
<label class="radio-group"
|
||||
for="@Id">
|
||||
<input class="@ClassNameList"
|
||||
id="@Id"
|
||||
name="@ParentRadioGroup?.Name"
|
||||
type="radio"
|
||||
@onchange="OnChange"
|
||||
@attributes=@InputAttributes
|
||||
disabled="@Disabled"
|
||||
readonly="@Readonly"
|
||||
checked="@Checked">
|
||||
|
||||
<div class="radio-fill"></div>
|
||||
|
||||
<label for="@Id"
|
||||
class="@LabelClassNameList">@Label</label>
|
||||
</label>
|
@ -1,9 +1,11 @@
|
||||
using Connected.Models;
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class Radio: InputBase
|
||||
public partial class Radio : InputBase
|
||||
{
|
||||
#region Parameters
|
||||
[CascadingParameter]
|
||||
public RadioGroup? ParentRadioGroup { get; set; }
|
||||
|
||||
@ -11,21 +13,51 @@ public partial class Radio: InputBase
|
||||
public bool Checked { get; set; } = false;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public string Id { get; set; }
|
||||
public string? Id { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> CheckedChange { get; set; }
|
||||
public async Task OnChange(ChangeEventArgs args)
|
||||
public EventCallback<bool> CheckedChanged { get; set; }
|
||||
|
||||
public async Task OnChange()
|
||||
{
|
||||
Checked = (bool)args.Value;
|
||||
CheckedChange.InvokeAsync(Checked);
|
||||
Checked = !Checked;
|
||||
await CheckedChanged.InvokeAsync(Checked);
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
#endregion
|
||||
|
||||
#region Style
|
||||
|
||||
[Parameter]
|
||||
public string ClassName { get; set; } = string.Empty;
|
||||
|
||||
private string ClassNameList
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
if (ParentRadioGroup.Disabled) Disabled = true;
|
||||
if (!InputAttributes.ContainsKey("disabled"))
|
||||
InputAttributes.Add("disabled", Disabled);
|
||||
get
|
||||
{
|
||||
return new CssBuilder("radio-input")
|
||||
.AddClass(ClassName)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public string LabelClassName { get; set; } = string.Empty;
|
||||
|
||||
private string LabelClassNameList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder("radio-label")
|
||||
.AddClass(LabelClassName)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
@using Connected.Models;
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<div>
|
||||
@if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
<h5>@Name</h5>
|
||||
}
|
||||
<div class="container">
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
<h5>@Name</h5>
|
||||
}
|
||||
<div class="container">
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
</CascadingValue>
|
@ -3,10 +3,32 @@
|
||||
namespace Connected.Components;
|
||||
public partial class RadioGroup
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Radio group name. Mandatory! Used for proper radio button grouping
|
||||
/// Options: any string will do
|
||||
/// Default: 'radiogroup'
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; } = "radiogroup";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used for globaly disabling radio button group and all the radios within
|
||||
/// Options: true or false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
public bool Disabled { get; set; } = false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// All the radiobuttons and other components inside radio group
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public RenderFragment? ChildContent { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
@ -4,19 +4,23 @@
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
@if (Items is not null)
|
||||
@if (component_loaded)
|
||||
{
|
||||
<div class="@InputFieldClassList">
|
||||
<select type="textarea" style="height:0px;" @attributes=@InputAttributes>
|
||||
</select>
|
||||
@if (Items is not null)
|
||||
{
|
||||
<div class="@InputFieldClassList">
|
||||
<select type="textarea"
|
||||
style="height:0px;"
|
||||
@attributes=@InputAttributes></select>
|
||||
@if (IsLabel)
|
||||
{
|
||||
<label class="label-animated">@Label</label>
|
||||
}
|
||||
|
||||
<span class="highlight"></span>
|
||||
<span class="bar">
|
||||
</span>
|
||||
|
||||
<span class="bar"></span>
|
||||
|
||||
<span class="input-glyph-wraper">
|
||||
@if (Clearable)
|
||||
{
|
||||
@ -24,9 +28,9 @@
|
||||
<i class='bx bx-x-circle'></i>
|
||||
</span>
|
||||
}
|
||||
<span class="input-glyph">
|
||||
<i class='bx bx-caret-down'></i>
|
||||
</span>
|
||||
<span class="input-glyph">
|
||||
<i class='bx bx-caret-down'></i>
|
||||
</span>
|
||||
@if (IsError)
|
||||
{
|
||||
<span class="input-glyph error">
|
||||
@ -35,22 +39,27 @@
|
||||
}
|
||||
</span>
|
||||
<div class="drop-down">
|
||||
<div class="dropdown-menu p-2" aria-labelledby="dropdownMenuButton">
|
||||
<div class="dropdown-menu p-2"
|
||||
aria-labelledby="dropdownMenuButton">
|
||||
@if (EnableSearch)
|
||||
{
|
||||
<input type="text"
|
||||
placeholder="Enter search string..."
|
||||
class="dropdown-item"
|
||||
@bind-value="@SearchText" />
|
||||
placeholder="Enter search string..."
|
||||
class="dropdown-item"
|
||||
@bind-value="@SearchText" />
|
||||
}
|
||||
@foreach (ValueType item in Items)
|
||||
@foreach (ValueType item in FilteredItems)
|
||||
{
|
||||
@if (item is not null)
|
||||
{
|
||||
<div class="dropdown-item" @onclick=@(()=>SetSelectedItem(@item))>@item.ToString()</div>
|
||||
<div class="dropdown-item"
|
||||
@onclick=@(()=>SetSelectedItem(@item))>
|
||||
@item.ToString()
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
@ -1,21 +1,46 @@
|
||||
using Connected.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class SimpleSelect<ValueType> : InputBase
|
||||
{
|
||||
private bool component_loaded = false;
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Value that is currently selected in the dropdown. Used for @bind-Value
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ValueType Value { get; set; }
|
||||
public ValueType? Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<ValueType> Items { get; set; }
|
||||
/// <summary>
|
||||
/// Collection of Items to work on (Filter). Filtered result is then shown in dropdown. If no filter is aplied, all the items are shown
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public ObservableCollection<ValueType>? Items { get; set; }
|
||||
|
||||
public IEnumerable<ValueType> OriginalItems { get; set; }
|
||||
/// <summary>
|
||||
/// Collection of items from 'Items' filtered with 'SearchText'
|
||||
/// </summary>
|
||||
private List<ValueType>? FilteredItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable edit text search box for item filtering
|
||||
/// Options: true or false
|
||||
/// Default: true
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool EnableSearch { get; set; } = true;
|
||||
|
||||
private string _searchText { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Search string provided by user
|
||||
/// Options: any string
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
public string SearchText
|
||||
{
|
||||
get
|
||||
@ -29,48 +54,92 @@ public partial class SimpleSelect<ValueType> : InputBase
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events, Methods
|
||||
|
||||
/// <summary>
|
||||
/// Method for setting the item on select
|
||||
/// </summary>
|
||||
/// <param name="item">item that will be set as selected</param>
|
||||
/// <returns>Methot returns nothing</returns>
|
||||
private async Task SetSelectedItem(ValueType item)
|
||||
{
|
||||
//DropDownClassToggle();
|
||||
await ValueChanged.InvokeAsync(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method for filtering items using 'SearchText' as filter
|
||||
/// </summary>
|
||||
private void FilterItems()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_searchText))
|
||||
if (Items is not null)
|
||||
{
|
||||
Items = OriginalItems;
|
||||
if (string.IsNullOrEmpty(_searchText))
|
||||
{
|
||||
SetItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
FilteredItems = Items.Where(item => item.ToString().ToLower().Contains(_searchText.ToLower())).ToList();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
Items = Items.Where(item => item.ToString().ToLower().Contains(_searchText.ToLower()));
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event triggered when value changes
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<ValueType> ValueChanged { get; set; }
|
||||
|
||||
private async Task ChangeValueAsync(ChangeEventArgs args)
|
||||
|
||||
/// <summary>
|
||||
/// Method for setting the FilteredItems collection keeping the original Item collection
|
||||
/// </summary>
|
||||
private void SetItems()
|
||||
{
|
||||
await ValueChanged.InvokeAsync((ValueType)Convert.ChangeType(args.Value, typeof(ValueType)));
|
||||
if (Items is not null)
|
||||
{
|
||||
FilteredItems = Items.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
/// <summary>
|
||||
/// Event triggered when the provided Items collection changes
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OriginalItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
|
||||
OriginalItems = Items;
|
||||
if (_searchText.Length>0) FilterItems();
|
||||
await base.OnParametersSetAsync();
|
||||
SetItems();
|
||||
FilterItems();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
/// <summary>
|
||||
/// Initializing Collections and aplying Filters if provided
|
||||
/// </summary>
|
||||
/// <returns>Nothing gets returned</returns>
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
if (Required)
|
||||
if (Items is null)
|
||||
{
|
||||
if (InputAttributes.ContainsKey("required")) InputAttributes.Add("required", true);
|
||||
Items= new ObservableCollection<ValueType>();
|
||||
}
|
||||
SetItems();
|
||||
if (_searchText.Length > 0)
|
||||
FilterItems();
|
||||
Items.CollectionChanged += OriginalItems_CollectionChanged;
|
||||
|
||||
component_loaded = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
@ -3,27 +3,15 @@
|
||||
@inherits InputBase;
|
||||
|
||||
<div class="@InputFieldClassList">
|
||||
@if (NumOfRows==1)
|
||||
{
|
||||
<input type="@inputType"
|
||||
value="@Value"
|
||||
placeholder="@Placeholder"
|
||||
disabled="@Disabled"
|
||||
readonly="@Readonly"
|
||||
@oninput=@ChangeValueAsync
|
||||
@attributes="@InputAttributes" />
|
||||
|
||||
} else
|
||||
{
|
||||
<textarea type="textarea"
|
||||
rows="@NumOfRows"
|
||||
<input type="@InputType"
|
||||
value="@Value"
|
||||
placeholder="@Placeholder"
|
||||
disabled="@Disabled"
|
||||
readonly="@Readonly"
|
||||
required="@Required"
|
||||
@oninput=@ChangeValueAsync
|
||||
@attributes="@InputAttributes" />
|
||||
}
|
||||
|
||||
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
@ -45,16 +33,15 @@
|
||||
{
|
||||
<span class="input-glyph button" @onclick="Clear">
|
||||
<Glyph SVG="@Icons.Material.Rounded.Dangerous" />
|
||||
<!--<i class='bx bx-x-circle'></i>-->
|
||||
</span>
|
||||
}
|
||||
@if (IsError)
|
||||
{
|
||||
<span class="input-glyph error">
|
||||
<Glyph SVG="@Icons.Material.Outlined.Error" Color="#D10000" />
|
||||
<!--<i class='bx bx-error-circle'></i>-->
|
||||
<Glyph SVG="@Icons.Material.Outlined.Error" />
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,67 +2,74 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class TextInput: InputBase
|
||||
public partial class TextInput : InputBase
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Setter for the TextInput if input is password field (for hiding characters)
|
||||
/// Options: true or false
|
||||
/// Default: false;
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool IsPassword { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public int NumOfRows
|
||||
{
|
||||
/// <summary>
|
||||
/// String for the component to use if TextInput is password field
|
||||
/// </summary>
|
||||
private string InputType => IsPassword ? "password" : "text";
|
||||
|
||||
/// <summary>
|
||||
/// Number of rows
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int NumOfRows
|
||||
{
|
||||
get
|
||||
{
|
||||
return _numberOfLines;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 1)
|
||||
{
|
||||
_numberOfLines = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_numberOfLines = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
private int _numberOfLines = 1;
|
||||
|
||||
{
|
||||
return _numberOfLines;
|
||||
}
|
||||
set
|
||||
{
|
||||
_numberOfLines = Math.Max(1, value);
|
||||
}
|
||||
}
|
||||
private int _numberOfLines = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Value of the TextInput. Used for @bind-Value
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
||||
private string inputType
|
||||
#endregion
|
||||
|
||||
#region Events, Methods
|
||||
|
||||
/// <summary>
|
||||
/// Event triggered when value changes
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method that triggers oninput -> when value inside the component changes
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
private async Task ChangeValueAsync(ChangeEventArgs args)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsPassword) return "password";
|
||||
return "text";
|
||||
}
|
||||
await ValueChanged.InvokeAsync(args?.Value?.ToString());
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
private async Task ChangeValueAsync(ChangeEventArgs args)
|
||||
{
|
||||
await ValueChanged.InvokeAsync(args.Value.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the value of the TextInput
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task Clear()
|
||||
{
|
||||
await ValueChanged.InvokeAsync(string.Empty);
|
||||
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
if (Required)
|
||||
{
|
||||
if (!InputAttributes.ContainsKey("required")) InputAttributes.Add("required", true);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
21
src/Connected.Components/Components/ToggleGlyphButton.razor
Normal file
21
src/Connected.Components/Components/ToggleGlyphButton.razor
Normal file
@ -0,0 +1,21 @@
|
||||
@inherits Button
|
||||
|
||||
<button type="button"
|
||||
@onclick="@Clicked"
|
||||
disabled=@Disabled
|
||||
style="@StyleList"
|
||||
class="@ClassList">
|
||||
<div class="@ContentClassList">
|
||||
<div style="align-items:center">
|
||||
@if (GlyphPosition == Position.Top)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" />
|
||||
}
|
||||
@ChildContent
|
||||
@if (GlyphPosition == Position.Bottom)
|
||||
{
|
||||
<Glyph SVG="@Glyph" Color="@GlyphColor" />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
120
src/Connected.Components/Components/ToggleGlyphButton.razor.cs
Normal file
120
src/Connected.Components/Components/ToggleGlyphButton.razor.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class ToggleGlyphButton: Button
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
/// <summary>
|
||||
/// Outline type of the button.
|
||||
/// Options: true, false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool Toggled { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Glyph (Icon) inside the button.
|
||||
/// Options: SVG string --> Icons
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string Glyph { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Glyph (Icon) inside the button when tge .
|
||||
/// Options: SVG string --> Icons
|
||||
/// Default: string.Empty
|
||||
/// </summary>
|
||||
[Parameter, EditorRequired]
|
||||
public string ToggledGlyph { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the glyph relative to button Text parameter. If Glyph parameter == string.Empty this parameter is ignored
|
||||
/// Options: Position.[left,top,right,bottom]
|
||||
/// Default: Position.left
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Position GlyphPosition { get; set; } = Position.Left;
|
||||
|
||||
/// <summary>
|
||||
/// Color for the glyph. If Glyph parameter is empty this parameter is ignored
|
||||
/// Options: Color.[Core,Primary,Secondary,Success,Info,Warning,Danger,White,Light,Dark]
|
||||
/// Default: Color.Dark
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color GlyphColor { get; set; } = Color.Dark;
|
||||
|
||||
/// <summary>
|
||||
/// Color for the glyph. If Glyph parameter is empty this parameter is ignored
|
||||
/// Options: Color.[Core,Primary,Secondary,Success,Info,Warning,Danger,White,Light,Dark]
|
||||
/// Default: Color.Dark
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Color ToggledGlyphColor { get; set; } = Color.Dark;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Button click event.
|
||||
/// Options: any MouseEventCallback event
|
||||
/// Default: empty
|
||||
[Parameter]
|
||||
public EventCallback<bool> ToggledChanged { get; set; }
|
||||
|
||||
protected async Task Clicked(MouseEventArgs e)
|
||||
{
|
||||
Toggled = !Toggled;
|
||||
await ToggledChanged.InvokeAsync(Toggled);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Styling
|
||||
|
||||
public string StyleList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StyleBuilder()
|
||||
.AddStyle(base.Style)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Generated class list for button based on user parameters
|
||||
/// </summary>
|
||||
public string ClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder("btn")
|
||||
.AddClass("btn-" + Helper.GetEnumDescription<Size>(base.Size))
|
||||
.AddClass("btn-" + Helper.GetEnumDescription<Color>(base.Color),!base.Outlined)
|
||||
.AddClass("btn-outline-" + Helper.GetEnumDescription<Color>(base.Color), base.Outlined)
|
||||
.AddClass(base.Class)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generated class list for button based on user parameters
|
||||
/// </summary>
|
||||
public string ContentClassList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new CssBuilder("")
|
||||
.AddClass(base.ContentClass)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
17
src/Connected.Components/Components/ToggleInput.razor
Normal file
17
src/Connected.Components/Components/ToggleInput.razor
Normal file
@ -0,0 +1,17 @@
|
||||
@using Connected.Models;
|
||||
|
||||
@inherits InputBase;
|
||||
|
||||
<label class="toggle-group" for="@Id">
|
||||
<input class="toggle-input"
|
||||
type="checkbox"
|
||||
name="toggle"
|
||||
disabled="@Disabled"
|
||||
id="@Id"
|
||||
checked="@Checked"
|
||||
@onchange="@OnChange"
|
||||
@attributes=@InputAttributes>
|
||||
|
||||
<div class="toggle-fill"></div>
|
||||
<label for="@Id" class="toggle-label">@Label</label>
|
||||
</label>
|
27
src/Connected.Components/Components/ToggleInput.razor.cs
Normal file
27
src/Connected.Components/Components/ToggleInput.razor.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using Connected.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Components;
|
||||
public partial class ToggleInput: InputBase
|
||||
{
|
||||
private bool _checked { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool? Checked
|
||||
{
|
||||
get => _checked;
|
||||
set => _checked= (bool)value;
|
||||
}
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public string Id { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> CheckedChanged { get; set; }
|
||||
|
||||
public async Task OnChange()
|
||||
{
|
||||
Checked = !Checked;
|
||||
await CheckedChanged.InvokeAsync((bool)Checked);
|
||||
}
|
||||
}
|
13
src/Connected.Components/Enums/ModalButtonType.cs
Normal file
13
src/Connected.Components/Enums/ModalButtonType.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Connected.Enums;
|
||||
public enum ModalButtonType
|
||||
{
|
||||
OkButton,
|
||||
CancelButton,
|
||||
RegularButton
|
||||
}
|
18
src/Connected.Components/Enums/Target.cs
Normal file
18
src/Connected.Components/Enums/Target.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Connected.Enums;
|
||||
public enum Target
|
||||
{
|
||||
[Description("_top")]
|
||||
Top,
|
||||
|
||||
[Description("_parent")]
|
||||
Parent,
|
||||
|
||||
[Description("_blank")]
|
||||
Blank,
|
||||
|
||||
[Description("_self")]
|
||||
Self,
|
||||
|
||||
}
|
@ -30,16 +30,20 @@ public class InputBase : ComponentBase
|
||||
[Parameter]
|
||||
public bool Required { get; set; } = false;
|
||||
|
||||
public Dictionary<string, object> InputAttributes { get; set; }
|
||||
public Dictionary<string, object> InputAttributes { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Show clear button.
|
||||
/// Disable input component
|
||||
/// Options: true or false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Show clear button.
|
||||
/// Make input component readonly
|
||||
/// Options: true or false
|
||||
/// Default: false
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool Readonly { get; set; } = false;
|
||||
@ -50,18 +54,11 @@ public class InputBase : ComponentBase
|
||||
[Parameter]
|
||||
public bool ShowCharacterCounter { get; set; }
|
||||
|
||||
private string _errorText = string.Empty;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string ErrorText {
|
||||
get
|
||||
{
|
||||
return _errorText;
|
||||
}
|
||||
set
|
||||
{
|
||||
_errorText = value;
|
||||
}
|
||||
}
|
||||
public string ErrorText { get; set; } = string.Empty;
|
||||
|
||||
public bool IsError
|
||||
{
|
||||
@ -79,15 +76,16 @@ public class InputBase : ComponentBase
|
||||
|
||||
protected virtual async Task SetTextAsync(string text)
|
||||
{
|
||||
if (Text != text)
|
||||
{
|
||||
Text = text;
|
||||
await TextChanged.InvokeAsync(text);
|
||||
}
|
||||
if (Text == text)
|
||||
return;
|
||||
|
||||
Text = text;
|
||||
await TextChanged.InvokeAsync(text);
|
||||
}
|
||||
|
||||
|
||||
private string _helperText = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string HelperText
|
||||
{
|
||||
@ -123,7 +121,7 @@ public class InputBase : ComponentBase
|
||||
[Parameter]
|
||||
public string Placeholder { get; set; } = string.Empty;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (InputAttributes is null) InputAttributes = new();
|
||||
}
|
||||
|
36
src/Connected.Components/Models/Modal/ModalButton.cs
Normal file
36
src/Connected.Components/Models/Modal/ModalButton.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using Connected.Enums;
|
||||
using Connected.Services;
|
||||
|
||||
namespace Connected.Models.Modal;
|
||||
public class ModalButton
|
||||
{
|
||||
public Event OnClickEvent { get; set; }
|
||||
public ModalButtonType ModalButtonType { get; set; } = ModalButtonType.RegularButton;
|
||||
public string ButtonText { get; set; }
|
||||
|
||||
public bool CloseDialogOnClick { get; set; } = true;
|
||||
|
||||
public ModalButton(Event OnClickEvent, string ButtonText, ModalButtonType ModalButtonType = ModalButtonType.RegularButton, bool CloseDialogOnClick = true)
|
||||
{
|
||||
this.OnClickEvent = OnClickEvent;
|
||||
this.ButtonText = ButtonText;
|
||||
this.ModalButtonType= ModalButtonType;
|
||||
this.CloseDialogOnClick = CloseDialogOnClick;
|
||||
}
|
||||
|
||||
public string GetButtonClass
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (this.ModalButtonType)
|
||||
{
|
||||
case ModalButtonType.CancelButton:
|
||||
return "btn-sm btn-core";
|
||||
case ModalButtonType.OkButton:
|
||||
return "btn-sm btn-info";
|
||||
default:
|
||||
return "btn-sm btn-secondary";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
src/Connected.Components/Models/Modal/ModalEvent.cs
Normal file
12
src/Connected.Components/Models/Modal/ModalEvent.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Connected.Models.Modal;
|
||||
public class Event
|
||||
{
|
||||
public Delegate Delegate;
|
||||
public object[] args;
|
||||
|
||||
public Event(Delegate Delegate, object[] Args)
|
||||
{
|
||||
this.Delegate = Delegate;
|
||||
args = Args;
|
||||
}
|
||||
}
|
10
src/Connected.Components/Models/Modal/ModalOptions.cs
Normal file
10
src/Connected.Components/Models/Modal/ModalOptions.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Connected.Models.Modal;
|
||||
public class ModalOptions
|
||||
{
|
||||
public bool DisableEscKey { get; set; } = false;
|
||||
public bool DisableBackdropClick { get; set; } = false;
|
||||
public bool NoHeader { get; set; } = false;
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Connected.Enums;
|
||||
using Connected.Utilities;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Connected;
|
||||
@ -24,8 +26,9 @@ internal class Navigation
|
||||
/// Navigates to the specified url.
|
||||
/// </summary>
|
||||
/// <param name="url">The destination url (relative or absolute).</param>
|
||||
public async Task NavigateTo(string url, Target target=Target._self)
|
||||
public async Task NavigateTo(string url, Target t=Target.Self)
|
||||
{
|
||||
string target = Helper.GetEnumDescription<Target>(t);
|
||||
if (!target.Equals("_self"))
|
||||
{
|
||||
if (!url.Equals(_navigationManager.Uri))
|
||||
@ -110,10 +113,4 @@ internal class Navigation
|
||||
}
|
||||
}
|
||||
|
||||
enum Target
|
||||
{
|
||||
_self,
|
||||
_blank,
|
||||
_parent,
|
||||
_top
|
||||
}
|
||||
|
||||
|
28
src/Connected.Components/Services/ModalDialogService.cs
Normal file
28
src/Connected.Components/Services/ModalDialogService.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Connected.Components;
|
||||
using Connected.Models.Modal;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Connected.Services;
|
||||
public class ModalDialogService
|
||||
{
|
||||
public event Action<string, RenderFragment, List<ModalButton>, ModalOptions> OnShow;
|
||||
public event Action OnClose;
|
||||
|
||||
public void ShowDialog(string title, RenderFragment content, List<ModalButton> buttons, ModalOptions options)
|
||||
{
|
||||
OnShow?.Invoke(title, content, buttons, options);
|
||||
}
|
||||
|
||||
public void ShowDialog(string title, MarkupString contentMarkup, List<ModalButton> buttons, ModalOptions options)
|
||||
{
|
||||
var content = new RenderFragment(x => x.AddContent(1, contentMarkup));
|
||||
OnShow?.Invoke(title, content, buttons, options);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
OnClose?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Connected.Services;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddModalDialogService(this IServiceCollection services)
|
||||
=> services.AddScoped<ModalDialogService>();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
@import 'globals/_index';
|
||||
@import 'layout/_index';
|
||||
@import 'components/_index';
|
||||
@import 'util/_index';
|
||||
@forward 'globals';
|
||||
@forward 'layout';
|
||||
@forward 'components';
|
||||
@forward 'util';
|
@ -12,12 +12,12 @@
|
||||
user-select: none;
|
||||
background-color: $bg-color;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.375rem 1rem;
|
||||
padding: 0.3rem 1.35rem;
|
||||
font-size: $base-font-size;
|
||||
text-transform: uppercase;
|
||||
line-height: $base-font-size * 1.5;
|
||||
text-decoration: none;
|
||||
border-radius: $base-border-radius * 20;
|
||||
border-radius: $border-radius-pill;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
@ -46,12 +46,12 @@
|
||||
}
|
||||
.btn-outline-#{$key} {
|
||||
// @include btn();
|
||||
color: $val;
|
||||
color: darken($val, 10);
|
||||
background-color: transparent;
|
||||
border: 1px solid $val;
|
||||
border: 1px solid darken($val, 10);
|
||||
&:hover {
|
||||
color: darken($val, 10);
|
||||
border: 1px solid darken($val, 10);
|
||||
color: darken($val, 30);
|
||||
border: 1px solid darken($val, 30);
|
||||
}
|
||||
&:focus-visible,
|
||||
&.focus {
|
||||
@ -67,24 +67,24 @@
|
||||
}
|
||||
|
||||
.btn.btn-sm {
|
||||
font-size: $font-size-sm;
|
||||
line-height: $font-size-sm * 1.5;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: $base-border-radius;
|
||||
font-size: .75rem;
|
||||
line-height: $font-size-sm * 1.25;
|
||||
padding: 0.4rem 1rem;
|
||||
//border-radius: $base-border-radius;
|
||||
}
|
||||
|
||||
.btn.btn-lg {
|
||||
font-size: $font-size-md;
|
||||
line-height: $font-size-md * 1.5;
|
||||
padding: 0.5rem 1.25rem;
|
||||
border-radius: $base-border-radius * 2.5;
|
||||
padding: 0.5rem 1.65rem;
|
||||
//border-radius: $base-border-radius * 2.5;
|
||||
}
|
||||
|
||||
.btn.btn-block {
|
||||
font-size: $font-size-md;
|
||||
line-height: $font-size-md * 1.5;
|
||||
padding: 0.5rem 1.25rem;
|
||||
border-radius: $base-border-radius * 2.5;
|
||||
padding: 0.5rem 1.5rem;
|
||||
//border-radius: $base-border-radius * 2.5;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
@ -114,12 +114,12 @@
|
||||
}
|
||||
|
||||
.btn-outline-core {
|
||||
color: var(--bg-core-primary) !important;
|
||||
color: var(--bg-core-primary-darken) !important;
|
||||
background-color: transparent !important;
|
||||
border: 1px solid var(--bg-core-primary) !important;
|
||||
border: 1px solid var(--bg-core-primary-darken) !important;
|
||||
&:hover {
|
||||
color: var(--bg-core-primary-darken) !important;
|
||||
border: 1px solid var(--bg-core-primary-darken) !important;
|
||||
color: var(--bg-core-primary-dark) !important;
|
||||
border: 1px solid var(--bg-core-primary-dark) !important;
|
||||
}
|
||||
&:focus-visible,
|
||||
&.focus {
|
||||
|
@ -1,102 +1,188 @@
|
||||
$color3: #f4f4f4;
|
||||
$color4: var(--bg-core-primary-darken);
|
||||
$checkbox-primary-color: var(--bg-core-primary-darken);
|
||||
$checkbox-secondary-color: #f4f4f4;
|
||||
$checkbox-disabled-color: darken($checkbox-secondary-color, 25%);
|
||||
|
||||
.checkbox-group {
|
||||
margin: 0.5rem;
|
||||
position:relative;
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
+ .checkbox-label {
|
||||
&:before {
|
||||
content: "";
|
||||
background: transparent;
|
||||
border-radius: 0%;
|
||||
border: 2px solid $color4;
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
position: relative;
|
||||
top: .15rem;
|
||||
margin-right: .75em;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
transition: all 250ms ease;
|
||||
}
|
||||
}
|
||||
&:checked {
|
||||
+ .checkbox-label {
|
||||
&:before {
|
||||
background-color: $color4;
|
||||
box-shadow: inset 0 0 0 2px $color3;
|
||||
--width: 1.25rem;
|
||||
--height: var(--width);
|
||||
--inset: calc(var(--width) / 10);
|
||||
|
||||
|
||||
margin: 0.75rem 0;
|
||||
width: max-content;
|
||||
cursor: pointer;
|
||||
position:relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap:.75rem;
|
||||
z-index: 1;
|
||||
|
||||
&.reversed{
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
& :nth-child(1) {order:2;}
|
||||
& :nth-child(2) {order:1;}
|
||||
}
|
||||
|
||||
&.column{
|
||||
flex-direction: column;
|
||||
gap:.25rem;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
// &:checked {
|
||||
// + .checkbox-label {
|
||||
// &:after {
|
||||
// background: $color3;
|
||||
// z-index: 1;
|
||||
// opacity: 1;
|
||||
// scale: 0.25;
|
||||
// clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
&:focus {
|
||||
+ .checkbox-label {
|
||||
&:before {
|
||||
outline: none;
|
||||
border-color: $color4;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:disabled {
|
||||
+ .checkbox-label {
|
||||
color: darken($color3, 25%);
|
||||
pointer-events: none;
|
||||
&:before {
|
||||
box-shadow: inset 0 0 0 2px $color3;
|
||||
border-color: darken($color3, 25%);
|
||||
background: darken($color3, 25%);
|
||||
}
|
||||
}
|
||||
}
|
||||
+ .checkbox-label {
|
||||
&:empty {
|
||||
&:before {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.checkbox-label:after {
|
||||
content: "";
|
||||
.checkbox-fill {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -6px;
|
||||
scale: .75;
|
||||
transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
background: transperent;
|
||||
border: 2px solid $checkbox-primary-color;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.checkbox-input:checked ~ .checkbox-fill {
|
||||
background: var(--bg-core-primary-darken);
|
||||
box-shadow: inset 0 0 0 var(--inset) $checkbox-secondary-color;
|
||||
|
||||
}
|
||||
|
||||
.checkbox-input:focus-within ~ .checkbox-fill {
|
||||
outline: 1px solid $checkbox-primary-color;
|
||||
|
||||
}
|
||||
|
||||
.checkbox-input:disabled ~ .checkbox-fill {
|
||||
box-shadow: inset 0 0 0 var(--inset) $checkbox-secondary-color;
|
||||
border-color: $checkbox-disabled-color;
|
||||
background: $checkbox-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.checkbox-input:disabled ~ .checkbox-label {
|
||||
color: $checkbox-disabled-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.checkbox-label:hover:after {
|
||||
background: var(--bg-core-primary-lighten);
|
||||
scale: 1;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.checkbox-fill::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: calc(var(--width) * 1.8);
|
||||
height: calc(var(--width) * 1.8);
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
scale: .75;
|
||||
transform-origin: left top;
|
||||
transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25), transform 0.2s;
|
||||
}
|
||||
|
||||
.checkbox-fill:hover::before {
|
||||
background: var(--bg-core-primary-lighten);
|
||||
scale: 1;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// $checkbox-primary-color: var(--bg-core-primary-darken);
|
||||
// $checkbox-secondary-color: #f4f4f4;
|
||||
// $checkbox-disabled-color: darken($checkbox-secondary-color, 25%);
|
||||
|
||||
// .checkbox-group {
|
||||
// margin: 0.5rem;
|
||||
// position:relative;
|
||||
|
||||
// input[type="checkbox"] {
|
||||
// position: absolute;
|
||||
// opacity: 0;
|
||||
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// content: "";
|
||||
// background: transparent;
|
||||
// border: 2px solid $checkbox-primary-color;
|
||||
// display: inline-block;
|
||||
// width: 1.25em;
|
||||
// height: 1.25em;
|
||||
// position: relative;
|
||||
// top: .15rem;
|
||||
// margin-right: .75em;
|
||||
// vertical-align: top;
|
||||
// cursor: pointer;
|
||||
// text-align: center;
|
||||
// z-index: 1;
|
||||
// transition: all 250ms ease;
|
||||
// }
|
||||
// }
|
||||
// &:checked {
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// background-color: $checkbox-primary-color;
|
||||
// box-shadow: inset 0 0 0 2px $checkbox-secondary-color;
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:focus {
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// outline: 1px solid $checkbox-primary-color;
|
||||
// border-color: $checkbox-primary-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:disabled {
|
||||
// + .checkbox-label {
|
||||
// color: darken($checkbox-secondary-color, 25%);
|
||||
// pointer-events: none;
|
||||
// &:before {
|
||||
// box-shadow: inset 0 0 0 2px $checkbox-secondary-color;
|
||||
// border-color: $checkbox-disabled-color;
|
||||
// background: $checkbox-disabled-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// + .checkbox-label {
|
||||
// &:empty {
|
||||
// &:before {
|
||||
// margin-right: 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// .checkbox-label:after {
|
||||
// content: "";
|
||||
// display: inline-block;
|
||||
// width: 35px;
|
||||
// height: 35px;
|
||||
// border-radius: 50%;
|
||||
// background-color: transparent;
|
||||
// position: absolute;
|
||||
// left: -8px;
|
||||
// top: -6px;
|
||||
// scale: .75;
|
||||
// transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
// }
|
||||
|
||||
// .checkbox-label:hover:after {
|
||||
// background: var(--bg-core-primary-lighten);
|
||||
// scale: 1;
|
||||
// opacity: .5;
|
||||
// }
|
218
src/Connected.Components/Styles/components/_chip.scss
Normal file
218
src/Connected.Components/Styles/components/_chip.scss
Normal file
@ -0,0 +1,218 @@
|
||||
@use "../util" as *;
|
||||
@use "../globals" as *;
|
||||
|
||||
/*CHIP*/
|
||||
/* scroll container */
|
||||
.horizontal-scroll-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-wrap: nowrap;
|
||||
gap: .5rem;
|
||||
overflow: auto;
|
||||
scroll-snap-type: both mandatory;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.horizontal-scroll-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.horizontal-scroll-container {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
|
||||
|
||||
.chip-icon {
|
||||
--height: 2.5rem;
|
||||
height: var(--height);
|
||||
aspect-ratio: 1 / 1;
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background-color: var(--bg-core-primary-darken);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: all 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
}
|
||||
|
||||
.chip-icon:hover,
|
||||
.chip-icon:active,
|
||||
.chip-icon:active {
|
||||
background-color: var(--bg-core-primary-dark);
|
||||
|
||||
}
|
||||
|
||||
.chip-icon.float-left {
|
||||
float: left;
|
||||
margin: .05rem .5rem .15rem 0;
|
||||
margin-top: -.25rem;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.chip-group {
|
||||
--height: 1.5rem;
|
||||
|
||||
border: 1px solid var(--bg-core-primary);
|
||||
padding: .15rem;
|
||||
min-width: max-content;
|
||||
color: var(--text-core);
|
||||
border-radius: $border-radius-pill;
|
||||
background-color: var(--bg-core-primary-light);
|
||||
display: inline-block;
|
||||
position:relative;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.chip-group-content{
|
||||
height: var(--height);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.chip-leading-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: $border-radius-pill;
|
||||
background-color: var(--bg-core-primary-light);
|
||||
height: var(--height);
|
||||
aspect-ratio: 1 / 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chip-leading-icon img{
|
||||
object-fit: cover;
|
||||
height: var(--height);
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.chip-cta-icon{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: $border-radius-pill;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
height: var(--height);
|
||||
aspect-ratio: 1 / 1;
|
||||
transition: all 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
}
|
||||
|
||||
.chip-label{
|
||||
font-size: $font-size-sm;
|
||||
margin:0 .85rem;
|
||||
}
|
||||
|
||||
.chip-cta-icon:hover{
|
||||
background-color: var(--bg-core-primary-lighten);
|
||||
}
|
||||
|
||||
|
||||
/*filter*/
|
||||
.chip-group.filter {
|
||||
border: 1px solid var(--bg-core-primary);
|
||||
background-color: var(--bg-core-primary-light);
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
&:hover{
|
||||
background-color: var(--bg-core-primary-lighten);
|
||||
}
|
||||
&:active,
|
||||
&.active{
|
||||
border: 1px solid var(--bg-core-primary);
|
||||
background-color: var(--bg-core-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.chip-group.filter .chip-leading-icon{
|
||||
//display: none;
|
||||
max-width: 0;
|
||||
transform: translateX(calc(var(--height) * -1.25));
|
||||
transition: all 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
}
|
||||
|
||||
.chip-group.filter.active .chip-leading-icon{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: $border-radius-pill;
|
||||
background-color: var(--bg-core-primary-light);
|
||||
height: var(--height);
|
||||
aspect-ratio: 1 / 1;
|
||||
transform: translateX(0);
|
||||
max-width: var(--height);
|
||||
}
|
||||
|
||||
.chip-group.select .chip-cta-icon{
|
||||
display: none;
|
||||
}
|
||||
/*end select*/
|
||||
|
||||
/*drop-down*/
|
||||
/* The container must be positioned relative: */
|
||||
.custom-select {
|
||||
position: relative;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.custom-select select {
|
||||
display: none; /*hide original SELECT element: */
|
||||
}
|
||||
|
||||
.select-selected {
|
||||
background-color: DodgerBlue;
|
||||
}
|
||||
|
||||
/* Style the arrow inside the select element: */
|
||||
.select-selected:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 14px;
|
||||
right: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
|
||||
/* Point the arrow upwards when the select box is open (active): */
|
||||
.select-selected.select-arrow-active:after {
|
||||
border-color: transparent transparent #fff transparent;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
/* style the items (options), including the selected item: */
|
||||
.select-items div,.select-selected {
|
||||
color: #ffffff;
|
||||
padding: 8px 16px;
|
||||
border: 1px solid transparent;
|
||||
border-color: transparent transparent rgba(0, 0, 0, 0.1) transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Style items (options): */
|
||||
.select-items {
|
||||
position: absolute;
|
||||
background-color: DodgerBlue;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
/* Hide the items when the select box is closed: */
|
||||
.select-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select-items div:hover, .same-as-selected {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
/*end-down*/
|
||||
|
||||
/*END CHIP*/
|
@ -1,3 +1,5 @@
|
||||
@use "sass:math";
|
||||
|
||||
@use "../util" as *;
|
||||
@use "../globals" as *;
|
||||
|
||||
@ -102,3 +104,250 @@ $colspan: ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*DATA GRID*/
|
||||
$columns: 12;
|
||||
|
||||
@mixin create-selectors($breakpoint: null) {
|
||||
$infix: if($breakpoint == null, '', '-#{$breakpoint}');
|
||||
|
||||
@for $i from 1 through $columns {
|
||||
.col#{$infix}-#{$i} {
|
||||
grid-column-end: span $i;
|
||||
padding: $base-padding;
|
||||
}
|
||||
.col-offset#{$infix}-#{$i} {
|
||||
grid-column-start: $i + 1;
|
||||
}
|
||||
.row#{$infix}-#{$i} {
|
||||
grid-row-end: span $i;
|
||||
}
|
||||
.row-offset#{$infix}-#{$i} {
|
||||
grid-row-start: $i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row{
|
||||
display: grid;
|
||||
grid-template-columns: repeat($columns, 1fr);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@include create-selectors;
|
||||
|
||||
@each $breakpoint, $width in $breakpoints-up {
|
||||
@media (min-width: $width) {
|
||||
@include create-selectors($breakpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.data-grid-row-content{
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
.data-grid:not(.data-grid.dense) .data-grid-row-content {
|
||||
background-color: var(--element-bg-core);
|
||||
border: 1px solid var(--border-core);
|
||||
border-radius: $border-radius-lg;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*ACTIVE*/
|
||||
.data-grid:not(.data-grid.dense) .data-grid-row-content:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
inset:0;
|
||||
background: var(--bg-core-primary-lighten);
|
||||
transition: width 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.data-grid:not(.data-grid.dense) .data-grid-row-content.active:before {
|
||||
width: calc(100% + 1.25rem * 2);
|
||||
}
|
||||
/*END ACTIVE*/
|
||||
|
||||
.data-grid.dense {
|
||||
background-color: var(--element-bg-core);
|
||||
border: 1px solid var(--border-core);
|
||||
border-radius: $border-radius-lg;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
overflow: hidden;
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*DENSE*/
|
||||
.data-grid.dense .data-grid-row-content {
|
||||
border-bottom: 1px solid var(--border-core);
|
||||
padding-bottom: .5rem;
|
||||
margin-bottom: .5rem;
|
||||
position: relative;
|
||||
&:last-child{
|
||||
border-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0
|
||||
}
|
||||
}
|
||||
/*END DENSE*/
|
||||
|
||||
/*DENSE ACTIVE*/
|
||||
.data-grid.dense .data-grid-row-content:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
inset: -.55rem -1.25rem -1px;
|
||||
background: var(--bg-core-primary-lighten);
|
||||
transition: width 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.data-grid.dense .data-grid-row-content.active:before {
|
||||
width: calc(100% + 1.25rem * 2);
|
||||
}
|
||||
|
||||
.data-grid.dense .data-grid-row-content:first-child:before {
|
||||
top: -1rem;
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
.data-grid.dense .data-grid-row-content:last-child:before {
|
||||
top: -10px;
|
||||
bottom: -1rem;
|
||||
}
|
||||
|
||||
.data-grid.dense .data-grid-row-content:only-child:before {
|
||||
inset: -1rem -1.25rem ;
|
||||
}
|
||||
/*END DENSE ACTIVE*/
|
||||
|
||||
.data-grid.select .data-grid-select {
|
||||
display: block;
|
||||
margin-top: .5rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.data-grid .data-grid-select,
|
||||
.data-grid .data-grid-collapse-cta{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.data-grid label {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-core-lc;
|
||||
}
|
||||
|
||||
/*COLLAPSE*/
|
||||
.data-grid.collapse .data-grid-collapse-cta {
|
||||
display: block;
|
||||
margin-top: .5rem;
|
||||
margin-left: .5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.collapsed{
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
padding-top: 0!important;
|
||||
padding-bottom: 0!important;
|
||||
border-top: 0px solid transparent;
|
||||
//opacity: 0;
|
||||
transition: all 0.5s ease-out;
|
||||
}
|
||||
|
||||
.collapsed.show {
|
||||
max-height: 25vh;
|
||||
overflow: auto;
|
||||
padding-top: initial;
|
||||
padding-bottom: initial;
|
||||
border-top: 1px solid var(--bg-core-primary-light);
|
||||
//opacity: 1;
|
||||
transition: all 0.5s ease-in;
|
||||
}
|
||||
|
||||
.data-grid .data-grid-collapse-cta i {
|
||||
transform: rotate(0);
|
||||
transition: all 0.5s ease-in;
|
||||
}
|
||||
.data-grid.show .data-grid-collapse-cta i {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
/*form-wizard*/
|
||||
|
||||
.form-wizard {
|
||||
background-color: var(--element-bg-core);
|
||||
border: 1px solid var(--border-core);
|
||||
border-radius: 0.6rem;
|
||||
padding: 1rem 1.25rem;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.form-outer {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-step {
|
||||
width: 100%;
|
||||
flex: 1 0 auto;
|
||||
transition: all 0.5s ease-out;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.form-step.next{
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.form-step.previous{
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
|
||||
.dots {
|
||||
--width: .75rem;
|
||||
--height: var(--width);
|
||||
|
||||
position: absolute;
|
||||
bottom: calc(var(--width) / -2);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
|
||||
.dot {
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
border-radius: 50%;
|
||||
background-color: var(--bg-core-primary-lighten);
|
||||
display: inline-block;
|
||||
outline: 1px solid #fff;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.dot.active,
|
||||
.dot.next {
|
||||
background-color: var(--bg-core-primary);
|
||||
outline: 2px solid var(--bg-core-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.dot.completed {
|
||||
background-color: $success;
|
||||
}
|
||||
}
|
||||
|
||||
/*end form-wizard*/
|
@ -3,4 +3,7 @@
|
||||
@forward "sidebar";
|
||||
@forward "radio";
|
||||
@forward "inputs";
|
||||
@forward "checkbox";
|
||||
@forward "checkbox";
|
||||
@forward "toggle";
|
||||
@forward "chip";
|
||||
@forward "modal";
|
@ -10,7 +10,7 @@ $width: 100%;
|
||||
|
||||
form{
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
//padding-top: 1rem;
|
||||
}
|
||||
|
||||
.form-group{
|
||||
@ -36,12 +36,13 @@ form{
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid $border-core;
|
||||
border-bottom: 1px solid var(--border-core);
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
&:focus ~ label.label-animated,
|
||||
&:valid ~ label.label-animated {
|
||||
&:valid ~ label.label-animated,
|
||||
&:disabled ~ label.label-animated {
|
||||
top: -12px;
|
||||
font-size: $font-size-sm;
|
||||
color: var(--bg-core-primary-darken);
|
||||
@ -204,29 +205,69 @@ select {
|
||||
height: auto;
|
||||
max-height: max-content;
|
||||
opacity: 1;
|
||||
transition: all $trans-time ease-in-out;
|
||||
pointer-events: initial;
|
||||
|
||||
}
|
||||
&:focus-within ~ .backdrop {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.drop-down{
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
min-width: 80%;
|
||||
width: 80%;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
z-index: 1500;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
box-shadow: $base-box-shadow;
|
||||
border-radius: $border-radius-lg;
|
||||
transition: all $trans-time ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
.backdrop{
|
||||
display: none;
|
||||
opacity: 0;
|
||||
z-index: 1499;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
overflow: hidden;
|
||||
background-color: rgba(0,0,0,.5);
|
||||
transition: all $trans-time ease-in-out;
|
||||
}
|
||||
|
||||
@include breakpoint(sm) {
|
||||
.drop-down{
|
||||
position: absolute;
|
||||
top: 46px;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
transform: none;
|
||||
border-radius: 0 0 $border-radius-lg $border-radius-lg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.drop-down{
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 46px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
height: 0;
|
||||
max-height: 0;
|
||||
//padding: $base-padding;
|
||||
z-index: 1500;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
box-shadow: $base-box-shadow;
|
||||
border-radius: 0 0 $border-radius-lg $border-radius-lg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.dropdown-header {
|
||||
@ -253,12 +294,12 @@ select {
|
||||
.dropdown-item:focus, .dropdown-item:hover {
|
||||
color: var(--text-core-hc);
|
||||
text-decoration: none;
|
||||
background-color: var(--bg-core-primary-lighten);
|
||||
background-color: var(--bg-core-primary-light);
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
height: 0;
|
||||
margin: 0.5rem 0;
|
||||
overflow: hidden;
|
||||
border-top: 1px solid $border-core;
|
||||
border-top: 1px solid var(--bg-core-primary-light);
|
||||
}
|
229
src/Connected.Components/Styles/components/_modal.scss
Normal file
229
src/Connected.Components/Styles/components/_modal.scss
Normal file
@ -0,0 +1,229 @@
|
||||
@use "../util" as *;
|
||||
@use "../globals" as *;
|
||||
|
||||
// stylelint-disable function-disallowed-list
|
||||
|
||||
// .modal-open - body class for killing the scroll
|
||||
.scroll-disabled{
|
||||
overflow: hidden;
|
||||
padding-right: 0;
|
||||
}
|
||||
// .modal - container to scroll within
|
||||
// .modal-dialog - positioning shell for the actual modal
|
||||
// .modal-content - actual modal w/ bg and corners and stuff
|
||||
|
||||
|
||||
// Container that the modal scrolls within
|
||||
|
||||
|
||||
.modal {
|
||||
--modal-zindex: #{$modal-zindex};
|
||||
--modal-width: 60vw;
|
||||
--modal-height: 50vh;
|
||||
--modal-padding: 1.5rem;
|
||||
--modal-margin: 1.5rem;
|
||||
--modal-color: var(--text-core);
|
||||
--modal-bg: var(--bg-core-primary-light);
|
||||
--modal-border-color: var(--bg-core-primary-light);
|
||||
--modal-border-width: 1px;
|
||||
--modal-border-radius: 1rem;
|
||||
--modal-box-shadow: 0 0.5rem 1rem rgba(var(--bg-core-primary), 0.15);
|
||||
|
||||
--modal-header-padding-x: 1.5rem; //close button
|
||||
--modal-header-padding-y: 1.5rem; //close button
|
||||
--modal-header-bg: var(--modal-bg);
|
||||
--modal-header-padding: 1.5rem;
|
||||
--modal-header-border-color: var(--bg-core-primary-light);
|
||||
--modal-header-border-width: 1px;
|
||||
|
||||
--modal-footer-bg: var(--modal-bg);
|
||||
--modal-footer-padding: 1.5rem;
|
||||
--modal-footer-border-color: var(--bg-core-primary-light);
|
||||
--modal-footer-border-width: 1px;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0,0,0,.65);
|
||||
z-index: var(--modal-zindex);
|
||||
display: none;
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
transition: opacity .15s linear;
|
||||
// Prevent Chrome on Windows from adding a focus outline. For details, see
|
||||
// https://github.com/twbs/bootstrap/pull/10951.
|
||||
outline: 0;
|
||||
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
|
||||
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
|
||||
// See also https://github.com/twbs/bootstrap/issues/17695
|
||||
}
|
||||
|
||||
|
||||
|
||||
// When fading in the modal, animate it to slide down
|
||||
.modal.fade {
|
||||
opacity: 1;
|
||||
transition: opacity .15s linear;
|
||||
}
|
||||
.modal.show{
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
// When trying to close, animate focus to scale
|
||||
.modal.modal-static {
|
||||
transform:scale(1.1);
|
||||
}
|
||||
|
||||
|
||||
// Shell div to position the modal with bottom padding
|
||||
.modal-dialog {
|
||||
position: relative;
|
||||
width: auto;
|
||||
margin: var(--modal-margin);
|
||||
// allow clicks to pass through for custom click handling to close modal
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.modal-dialog-scrollable {
|
||||
height: calc(100% - var(--modal-margin) * 2);
|
||||
|
||||
|
||||
.modal-content {
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog-centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: calc(100% - var(--modal-margin) * 2);
|
||||
|
||||
}
|
||||
|
||||
// Actual modal
|
||||
.modal-content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
|
||||
// counteract the pointer-events: none; in the .modal-dialog
|
||||
color: var(--modal-color);
|
||||
pointer-events: auto;
|
||||
background-color: var(--modal-bg);
|
||||
background-clip: padding-box;
|
||||
border: var(--modal-border-width) solid var(--modal-border-color);
|
||||
border-radius: var(--modal-border-radius);
|
||||
box-shadow: var(--modal-box-shadow);
|
||||
// Remove focus outline from opened modal
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Modal header
|
||||
// Top section of the modal w/ title and dismiss
|
||||
.modal-header {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
|
||||
padding: var(--modal-header-padding);
|
||||
background-color: var(--modal-header-bg);
|
||||
border-bottom: var(--modal-header-border-width) solid var(--modal-header-border-color);
|
||||
|
||||
|
||||
.btn-close {
|
||||
padding: calc(var(--modal-header-padding-y) * .5) calc(var(--modal-header-padding-x) * .5);
|
||||
margin: calc(-.5 * var(--modal-header-padding-y)) calc(-.5 * var(--modal-header-padding-x)) calc(-.5 * var(--modal-header-padding-y)) auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Title text within header
|
||||
.modal-title {
|
||||
margin-bottom: 0;
|
||||
|
||||
}
|
||||
|
||||
// Modal body
|
||||
// Where all modal content resides (sibling of .modal-header and .modal-footer)
|
||||
.modal-body {
|
||||
position: relative;
|
||||
// Enable `flex-grow: 1` so that the body take up as much space as possible
|
||||
// when there should be a fixed height on `.modal-dialog`.
|
||||
flex: 1 1 auto;
|
||||
padding: var(--modal-padding);
|
||||
}
|
||||
|
||||
// Footer (for actions)
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
align-items: center; // vertically center
|
||||
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
|
||||
padding: var(--modal-footer-padding);
|
||||
background-color: var(--modal-footer-bg);
|
||||
border-radius: var(--modal-border-radius);
|
||||
gap: .5rem;
|
||||
|
||||
}
|
||||
// Automatically set modal's width for larger viewports
|
||||
|
||||
|
||||
|
||||
.modal-dialog {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
padding: 0;
|
||||
|
||||
|
||||
@include breakpoint(sm) {
|
||||
max-width: 75vw;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding: var(--modal-padding);
|
||||
|
||||
}
|
||||
|
||||
@include breakpoint(lg) {
|
||||
max-width: var(--modal-width);
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // Modal background
|
||||
// .modal-backdrop {
|
||||
// opacity: 0;
|
||||
// display: none;
|
||||
// position: fixed;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// z-index: #{$backdrop-zindex};
|
||||
// width: 100vw;
|
||||
// height: 100vh;
|
||||
// background-color: #000;
|
||||
// transition: opacity .15s linear;
|
||||
// }
|
||||
|
||||
// .modal-backdrop.fade {
|
||||
// opacity: .5;
|
||||
// transition: opacity .15s linear;
|
||||
// }
|
||||
|
||||
// .modal-backdrop.show {
|
||||
// display: block;
|
||||
// }
|
||||
|
@ -1,86 +1,276 @@
|
||||
$color1: #f4f4f4;
|
||||
$color2: var(--bg-core-primary-darken);
|
||||
$radio-primary-color: var(--bg-core-primary-darken);
|
||||
$radio-secondary-color: #f4f4f4;
|
||||
$radio-disabled-color: darken($radio-secondary-color, 25%);
|
||||
|
||||
.radio-group {
|
||||
margin: 0.5rem;
|
||||
position:relative;
|
||||
input[type="radio"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
+ .radio-label {
|
||||
&:before {
|
||||
content: "";
|
||||
background: $color1;
|
||||
border-radius: 100%;
|
||||
border: 2px solid $color2;
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
position: relative;
|
||||
top: .15rem;
|
||||
margin-right: .75em;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
transition: all 250ms ease;
|
||||
}
|
||||
}
|
||||
&:checked {
|
||||
+ .radio-label {
|
||||
&:before {
|
||||
background-color: $color2;
|
||||
box-shadow: inset 0 0 0 2px $color1;
|
||||
--width: 1.25rem;
|
||||
--height: var(--width);
|
||||
--inset: calc(var(--width) / 10);
|
||||
|
||||
margin: 0.75rem 0;
|
||||
width: max-content;
|
||||
cursor: pointer;
|
||||
position:relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap:.75rem;
|
||||
z-index: 1;
|
||||
|
||||
&.reversed{
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
& :nth-child(1) {order:2;}
|
||||
& :nth-child(2) {order:1;}
|
||||
}
|
||||
|
||||
&.column{
|
||||
flex-direction: column;
|
||||
gap:.25rem;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
+ .radio-label {
|
||||
&:before {
|
||||
outline: none;
|
||||
border-color: $color2;
|
||||
|
||||
input[type="radio"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:disabled {
|
||||
+ .radio-label {
|
||||
color: darken($color1, 25%);
|
||||
pointer-events: none;
|
||||
&:before {
|
||||
box-shadow: inset 0 0 0 2px $color1;
|
||||
border-color: darken($color1, 25%);
|
||||
background: darken($color1, 25%);
|
||||
}
|
||||
}
|
||||
}
|
||||
+ .radio-label {
|
||||
&:empty {
|
||||
&:before {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.radio-label:after {
|
||||
content: "";
|
||||
|
||||
.radio-fill {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -6px;
|
||||
scale: .75;
|
||||
transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
background: transperent;
|
||||
border: 2px solid $radio-primary-color;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.radio-input:checked ~ .radio-fill {
|
||||
background: var(--bg-core-primary-darken);
|
||||
box-shadow: inset 0 0 0 var(--inset) $radio-secondary-color;
|
||||
|
||||
}
|
||||
|
||||
.radio-label:hover:after {
|
||||
background: var(--bg-core-primary-lighten);
|
||||
scale: 1;
|
||||
opacity: .5;
|
||||
}
|
||||
.radio-input:focus-within ~ .radio-fill {
|
||||
outline: 1px solid $radio-primary-color;
|
||||
|
||||
}
|
||||
|
||||
.radio-input:disabled ~ .radio-fill {
|
||||
box-shadow: inset 0 0 0 var(--inset) $radio-secondary-color;
|
||||
border-color: $radio-disabled-color;
|
||||
background: $radio-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.radio-input:disabled ~ .radio-label {
|
||||
color: $radio-disabled-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.radio-fill::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: calc(var(--width) * 1.8);
|
||||
height: calc(var(--width) * 1.8);
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
scale: .75;
|
||||
transform-origin: left top;
|
||||
transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25), transform 0.2s;
|
||||
}
|
||||
|
||||
.radio-fill:hover::before {
|
||||
background: var(--bg-core-primary-lighten);
|
||||
scale: 1;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// $checkbox-primary-color: var(--bg-core-primary-darken);
|
||||
// $checkbox-secondary-color: #f4f4f4;
|
||||
// $checkbox-disabled-color: darken($checkbox-secondary-color, 25%);
|
||||
|
||||
// .checkbox-group {
|
||||
// margin: 0.5rem;
|
||||
// position:relative;
|
||||
|
||||
// input[type="checkbox"] {
|
||||
// position: absolute;
|
||||
// opacity: 0;
|
||||
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// content: "";
|
||||
// background: transparent;
|
||||
// border: 2px solid $checkbox-primary-color;
|
||||
// display: inline-block;
|
||||
// width: 1.25em;
|
||||
// height: 1.25em;
|
||||
// position: relative;
|
||||
// top: .15rem;
|
||||
// margin-right: .75em;
|
||||
// vertical-align: top;
|
||||
// cursor: pointer;
|
||||
// text-align: center;
|
||||
// z-index: 1;
|
||||
// transition: all 250ms ease;
|
||||
// }
|
||||
// }
|
||||
// &:checked {
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// background-color: $checkbox-primary-color;
|
||||
// box-shadow: inset 0 0 0 2px $checkbox-secondary-color;
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:focus {
|
||||
// + .checkbox-label {
|
||||
// &:before {
|
||||
// outline: 1px solid $checkbox-primary-color;
|
||||
// border-color: $checkbox-primary-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:disabled {
|
||||
// + .checkbox-label {
|
||||
// color: darken($checkbox-secondary-color, 25%);
|
||||
// pointer-events: none;
|
||||
// &:before {
|
||||
// box-shadow: inset 0 0 0 2px $checkbox-secondary-color;
|
||||
// border-color: $checkbox-disabled-color;
|
||||
// background: $checkbox-disabled-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// + .checkbox-label {
|
||||
// &:empty {
|
||||
// &:before {
|
||||
// margin-right: 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// .checkbox-label:after {
|
||||
// content: "";
|
||||
// display: inline-block;
|
||||
// width: 35px;
|
||||
// height: 35px;
|
||||
// border-radius: 50%;
|
||||
// background-color: transparent;
|
||||
// position: absolute;
|
||||
// left: -8px;
|
||||
// top: -6px;
|
||||
// scale: .75;
|
||||
// transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
// }
|
||||
|
||||
// .checkbox-label:hover:after {
|
||||
// background: var(--bg-core-primary-lighten);
|
||||
// scale: 1;
|
||||
// opacity: .5;
|
||||
// }
|
||||
|
||||
|
||||
// $radio-primary-color: var(--bg-core-primary-darken);
|
||||
// $radio-secondary-color: #f4f4f4;
|
||||
// $radio-disabled-color: darken($radio-secondary-color, 25%);
|
||||
|
||||
// .radio-group {
|
||||
// margin: 0.5rem;
|
||||
// position:relative;
|
||||
|
||||
// input[type="radio"] {
|
||||
// position: absolute;
|
||||
// opacity: 0;
|
||||
|
||||
// + .radio-label {
|
||||
// &:before {
|
||||
// content: "";
|
||||
// background: transparent;
|
||||
// border-radius: 50%;
|
||||
// border: 2px solid $radio-primary-color;
|
||||
// display: inline-block;
|
||||
// width: 1.25em;
|
||||
// height: 1.25em;
|
||||
// position: relative;
|
||||
// top: .15rem;
|
||||
// margin-right: .75em;
|
||||
// vertical-align: top;
|
||||
// cursor: pointer;
|
||||
// text-align: center;
|
||||
// z-index: 1;
|
||||
// transition: all 250ms ease;
|
||||
// }
|
||||
// }
|
||||
// &:checked {
|
||||
// + .radio-label {
|
||||
// &:before {
|
||||
// background-color: $radio-primary-color;
|
||||
// box-shadow: inset 0 0 0 2px $radio-secondary-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:focus {
|
||||
// + .radio-label {
|
||||
// &:before {
|
||||
// outline: 1px solid $radio-primary-color;
|
||||
// border-color: $radio-primary-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// &:disabled {
|
||||
// + .radio-label {
|
||||
// color: darken($radio-secondary-color, 25%);
|
||||
// pointer-events: none;
|
||||
// &:before {
|
||||
// box-shadow: inset 0 0 0 2px $radio-secondary-color;
|
||||
// border-color: $radio-disabled-color;
|
||||
// background: $radio-disabled-color;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// + .radio-label {
|
||||
// &:empty {
|
||||
// &:before {
|
||||
// margin-right: 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// .radio-label:after {
|
||||
// content: "";
|
||||
// display: inline-block;
|
||||
// width: 35px;
|
||||
// height: 35px;
|
||||
// border-radius: 50%;
|
||||
// background-color: transparent;
|
||||
// position: absolute;
|
||||
// left: -8px;
|
||||
// top: -6px;
|
||||
// scale: .75;
|
||||
// transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25);
|
||||
// }
|
||||
|
||||
// .radio-label:hover:after {
|
||||
// background: var(--bg-core-primary-lighten);
|
||||
// scale: 1;
|
||||
// opacity: .5;
|
||||
// }
|
||||
|
||||
|
@ -2,28 +2,35 @@
|
||||
@use '../util/' as *;
|
||||
|
||||
|
||||
$sidebar-width-open:300px;
|
||||
$sidebar-width-closed:75px;
|
||||
$sidebar-right-width-open:300px;
|
||||
$sidebar-right-width-closed:0px;
|
||||
|
||||
.sidebar{
|
||||
position: fixed;
|
||||
padding-inline: 0.75rem;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
color: $text-core;
|
||||
background: var(--bg-core-primary);
|
||||
//margin: -2rem 2rem -2rem -2rem;
|
||||
z-index: 100;
|
||||
background: var(--bg-core-primary-light);
|
||||
border-right: 1px solid rgba(0,0,0,.025);
|
||||
border-radius: $border-radius-lg 0 0 $border-radius-lg;
|
||||
z-index: $sidebar-zindex;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@include breakpoint(sm) {
|
||||
height: calc(100% + 4rem);
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 300px;
|
||||
width: $sidebar-width-open;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar.close{
|
||||
width: 0;
|
||||
transform: translateX(-75px);
|
||||
transform: translateX($sidebar-width-closed);
|
||||
@include breakpoint(sm) {
|
||||
width: 75px;
|
||||
width: $sidebar-width-closed;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
@ -31,59 +38,80 @@
|
||||
.main {
|
||||
width: calc(100% - 1.5rem) ;
|
||||
margin-inline:auto;
|
||||
transition: all 0.3s ease;
|
||||
@include breakpoint (sm) {
|
||||
width: calc(100% - 300px);;
|
||||
width: calc(100% - $sidebar-width-open - $sidebar-right-width-open);
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.main.close{
|
||||
@include breakpoint (sm) {
|
||||
width: calc(100% - 75px);
|
||||
width: calc(100% - $sidebar-width-closed - $sidebar-width-open);
|
||||
}
|
||||
}
|
||||
|
||||
.main.close-r{
|
||||
@include breakpoint (sm) {
|
||||
width: calc(100% - $sidebar-right-width-open);
|
||||
}
|
||||
}
|
||||
|
||||
.main.close.close-r{
|
||||
@include breakpoint (sm) {
|
||||
width: calc(100% - $sidebar-right-width-closed - $sidebar-width-closed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//profile
|
||||
.sidebar .profile-details{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
background-color: rgba(0,0,0,.6);
|
||||
}
|
||||
padding-top: 0;
|
||||
//color: #fff;
|
||||
//background-color: var(--bg-core-primary);
|
||||
border-radius: $border-radius-lg 0 0 0;
|
||||
transition: all 0.3s ease;
|
||||
@include breakpoint (sm) {
|
||||
padding-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar .profile-details .avatar{
|
||||
min-width: calc(70px - 1rem);
|
||||
min-width: 50px;
|
||||
text-align: center;
|
||||
margin: 1rem 0 1rem 1rem;
|
||||
|
||||
}
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.sidebar .profile-details img{
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
object-fit: cover;
|
||||
border-radius: 50%;
|
||||
//transition: all 0.5s ease;
|
||||
}
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.sidebar .profile-details .name-job{
|
||||
margin-right: auto;
|
||||
|
||||
.sidebar .profile-details .profile-description {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.sidebar .profile-details .profile-name{
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
color:var(--text-core-hc)
|
||||
}
|
||||
|
||||
.sidebar .profile-details .profile-job{
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color:var(--text-core-lc)
|
||||
}
|
||||
|
||||
.sidebar .profile-details i{
|
||||
height: 50px;
|
||||
min-width: 70px;
|
||||
min-width: 50px;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
font-size: 20px;
|
||||
@ -94,137 +122,359 @@
|
||||
.sidebar.close .profile-details .profile-name,
|
||||
.sidebar.close .profile-details .profile-job{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
//links
|
||||
.sidebar .nav-links{
|
||||
height: 100%;
|
||||
/*NAV*/
|
||||
.sidebar nav{
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.sidebar .navbar{
|
||||
height: auto;
|
||||
//padding: 12px;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.sidebar.close .nav-links{
|
||||
|
||||
.sidebar.close .navbar{
|
||||
overflow: visible;
|
||||
}
|
||||
.sidebar .nav-links::-webkit-scrollbar{
|
||||
|
||||
.sidebar .navbar::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
.sidebar .nav-links li{
|
||||
|
||||
.sidebar .navbar .navbar-header{
|
||||
display: block;
|
||||
padding: 0.5rem 0;
|
||||
margin-bottom: 0;
|
||||
font-size: $font-size-sm;
|
||||
color: var(--text-core-lc);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
.sidebar .navbar .navbar-item{
|
||||
position: relative;
|
||||
list-style: none;
|
||||
transition: all 0.4s ease;
|
||||
margin-bottom: 12px;
|
||||
line-height: 50px;
|
||||
border-radius: $border-radius-pill;
|
||||
}
|
||||
.sidebar .nav-links li:hover{
|
||||
|
||||
.sidebar .navbar .navbar-item:hover,
|
||||
.sidebar .navbar .navbar-item:active,
|
||||
.sidebar .navbar .navbar-item.active{
|
||||
background: var(--bg-core-primary-lighten);
|
||||
}
|
||||
.sidebar .nav-links li .iocn-link{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.sidebar.close .navbar .navbar-item{
|
||||
border-radius: 50%;
|
||||
}
|
||||
.sidebar.close .nav-links li .iocn-link{
|
||||
display: block
|
||||
|
||||
.sidebar .navbar .navbar-item.fab{
|
||||
background-color:#ffdad9;
|
||||
border-radius: $border-radius-lg;
|
||||
margin-bottom: 36px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.sidebar .nav-links li i{
|
||||
|
||||
.sidebar .navbar .navbar-item.fab:hover,
|
||||
.sidebar .navbar .navbar-item.fab:active,
|
||||
.sidebar .navbar .navbar-item.fab.active{
|
||||
background-color: #fbc5c3;
|
||||
}
|
||||
|
||||
.sidebar .navbar .navbar-item i{
|
||||
height: 50px;
|
||||
min-width: 70px;
|
||||
min-width: 50px;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
color: var(--text-core-vc);
|
||||
font-size: 20px;
|
||||
color: var(--text-core-lc);
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.sidebar .nav-links li.showMenu i.arrow{
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
.sidebar.close .nav-links i.arrow{
|
||||
display: none;
|
||||
}
|
||||
.sidebar .nav-links li a{
|
||||
|
||||
.sidebar .navbar .navbar-item a{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
.sidebar .nav-links li a .link_name{
|
||||
|
||||
.sidebar .navbar .navbar-item a .navbar-link{
|
||||
flex: 1 0 auto;
|
||||
font-weight: 400;
|
||||
font-weight: $font-weight-400;
|
||||
color: var(--text-core);
|
||||
//transition: all 0.4s ease;
|
||||
}
|
||||
.sidebar.close .nav-links li a .link_name{
|
||||
|
||||
.sidebar .navbar .navbar-item a .navbar-link:first-child {
|
||||
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.sidebar.close .navbar .navbar-item a .navbar-link{
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.sidebar .nav-links li .sub-menu{
|
||||
padding: 6px 6px 14px 70px;
|
||||
margin-top: -10px;
|
||||
background:var(--bg-core-primary-lighten);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar .navbar .navbar-item a .navbar-link.navbar-link-detail{
|
||||
flex: 0 0 auto;
|
||||
font-weight: $font-weight-600;
|
||||
color: var(--text-core-hc);
|
||||
text-align: right;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.sidebar .nav-links li.showMenu .sub-menu{
|
||||
display: block;
|
||||
}
|
||||
.sidebar .nav-links li .sub-menu a{
|
||||
color: var(--text-core);
|
||||
font-size: 15px;
|
||||
padding: 5px 0;
|
||||
white-space: nowrap;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.sidebar .nav-links li .sub-menu a:hover{
|
||||
color: var(--bg-core-primary-darken);
|
||||
}
|
||||
.sidebar.close .nav-links li .sub-menu{
|
||||
|
||||
|
||||
/*TOOLTIP*/
|
||||
.sidebar.close .navbar .navbar-item .navbar-tooltip{
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
top: -10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
width: max-content;
|
||||
left: calc(100% + 12px);
|
||||
top: 0;
|
||||
margin-top: 0;
|
||||
padding: 10px 20px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
border-radius: $border-radius-lg;
|
||||
opacity: 0;
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
transition: 0s;
|
||||
}
|
||||
.sidebar.close .nav-links li:hover .sub-menu{
|
||||
top: 0;
|
||||
|
||||
.sidebar.close .navbar .navbar-item:hover .navbar-tooltip{
|
||||
left: calc(100% + 24px);
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
.sidebar .nav-links li .sub-menu .link_name{
|
||||
display: none;
|
||||
}
|
||||
.sidebar.close .nav-links li .sub-menu .link_name{
|
||||
font-weight: 600;
|
||||
|
||||
.sidebar.close .navbar .navbar-tooltip {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
.sidebar .nav-links li .sub-menu.blank{
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
padding: 3px 20px 6px 16px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
.sidebar .navbar .navbar-tooltip {
|
||||
display: none;
|
||||
}
|
||||
.sidebar .nav-links li:hover .sub-menu.blank{
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.sidebar-divider {
|
||||
height: 0;
|
||||
margin: 0.5rem 0;
|
||||
overflow: hidden;
|
||||
border-top: 1px solid var(--border-core-lighten);
|
||||
}
|
||||
|
||||
|
||||
.badge-label {
|
||||
border-radius: $base-border-radius;
|
||||
font-size: $font-size-sm;
|
||||
color: var(--text-core-hc);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
letter-spacing: 0;
|
||||
padding: 12px;
|
||||
pointer-events: auto;
|
||||
text-indent: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
background-color: transparent;
|
||||
transition: .3s cubic-bezier(.25,.8,.5,1);
|
||||
}
|
||||
|
||||
/*BOOTOMBAR*/
|
||||
@include breakpoint-down(sm) {
|
||||
|
||||
.main {
|
||||
margin-bottom: rem(75);
|
||||
}
|
||||
|
||||
.sidebar.bottombar,
|
||||
.sidebar.close.bottombar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
transform: translateX(0);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: rem(75);
|
||||
width: 100%;
|
||||
color: $text-core;
|
||||
background: var(--bg-core-primary-light);
|
||||
border-radius: 0;
|
||||
z-index: $sidebar-zindex;
|
||||
|
||||
}
|
||||
.sidebar.bottombar .profile-description,
|
||||
.sidebar.close.bottombar .profile-description,
|
||||
.sidebar.bottombar .profile-details i,
|
||||
.sidebar.close.bottombar .profile-deteils i {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar.bottombar nav,
|
||||
.sidebar.close.bottombar nav {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
.sidebar.bottombar .navbar,
|
||||
.sidebar.close.bottombar .navbar {
|
||||
padding: 0;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.sidebar.bottombar .navbar .navbar-item,
|
||||
.sidebar.close.bottombar .navbar .navbar-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.sidebar.bottombar .navbar-link,
|
||||
.sidebar.close.bottombar .navbar-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar.bottombar .navbar .navbar-item .navbar-tooltip,
|
||||
.sidebar.close.bottombar .navbar .navbar-item .navbar-tooltip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar.bottombar .navbar-item.fab,
|
||||
.sidebar.close.bottombar .navbar-item.fab {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: -4rem;
|
||||
}
|
||||
|
||||
.sidebar.bottombar .sidebar-divider,
|
||||
.sidebar.close.bottombar .sidebar-divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*RIGHT SIDEBAR*/
|
||||
|
||||
|
||||
.sidebar.right{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
color: $text-core;
|
||||
background: var(--bg-core-primary-lighten);
|
||||
border-right: 1px solid rgba(0,0,0,.025);
|
||||
border-radius: 0 $border-radius-lg $border-radius-lg 0;
|
||||
z-index: $sidebar-right-zindex;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
@include breakpoint(sm) {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: $sidebar-right-width-open;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar.right.close-r{
|
||||
width: 0;
|
||||
transform: translateX($sidebar-right-width-closed);
|
||||
padding: 0;
|
||||
|
||||
@include breakpoint(sm) {
|
||||
width: $sidebar-right-width-closed;
|
||||
transform: translateX(0);
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar.right .navbar .navbar-item:hover,
|
||||
.sidebar.right .navbar .navbar-item:active,
|
||||
.sidebar.right .navbar .navbar-item.active{
|
||||
background: var(--bg-core-primary);
|
||||
}
|
||||
|
||||
// .scrollable {
|
||||
// display: block;
|
||||
// height: 100%;
|
||||
// max-height: 100vh;
|
||||
// min-height: 0;
|
||||
// }
|
||||
|
||||
// .scroll-wrapper {
|
||||
// position: relative;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// background-color: turquoise;
|
||||
// }
|
||||
|
||||
// .scroll-container {
|
||||
// position: relative;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// touch-action: pan-y;
|
||||
// overflow-x: hidden;
|
||||
// overflow-y: auto;
|
||||
// }
|
||||
|
||||
// .scroll-content {
|
||||
// height: auto;
|
||||
// transform: none;
|
||||
// position: relative;
|
||||
// min-height: 100%;
|
||||
// }
|
||||
|
||||
.scrollable {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
.scroll-wrapper {
|
||||
|
||||
|
||||
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events: auto;
|
||||
background-clip: padding-box;
|
||||
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
flex: 1 1 auto;
|
||||
|
||||
}
|
107
src/Connected.Components/Styles/components/_toggle.scss
Normal file
107
src/Connected.Components/Styles/components/_toggle.scss
Normal file
@ -0,0 +1,107 @@
|
||||
@use "../globals/" as *;
|
||||
@use "../util/" as *;
|
||||
|
||||
$toggle-primary-color: var(--bg-core-primary-darken);
|
||||
$toggle-secondary-color: #ddd;
|
||||
$toggle-disabled-color: darken($toggle-secondary-color, 25%);
|
||||
|
||||
.toggle-group {
|
||||
--width: 42px;
|
||||
--height: calc(var(--width) / 2);
|
||||
--border-radius: calc(var(--height) / 2);
|
||||
|
||||
margin: 0.75rem 0;
|
||||
width: max-content;
|
||||
cursor: pointer;
|
||||
position:relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap:.75rem;
|
||||
|
||||
&.reversed{
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
& :nth-child(1) {order:2;}
|
||||
& :nth-child(2) {order:1;}
|
||||
}
|
||||
|
||||
&.column{
|
||||
flex-direction: column;
|
||||
gap:.25rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-fill {
|
||||
position: relative;
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
border-radius: var(--border-radius);
|
||||
background: $toggle-secondary-color;
|
||||
//margin-right: .75rem;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.toggle-input:checked ~ .toggle-fill {
|
||||
background: var(--bg-core-primary-darken);
|
||||
}
|
||||
|
||||
.toggle-input:focus-within ~ .toggle-fill {
|
||||
outline: 1px solid $toggle-primary-color;
|
||||
}
|
||||
|
||||
.toggle-input:disabled ~ .toggle-fill {
|
||||
background: $toggle-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.toggle-input:disabled ~ .toggle-label {
|
||||
color: $toggle-disabled-color;
|
||||
}
|
||||
|
||||
.toggle-fill::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
height: calc(var(--height) - 4px);
|
||||
width: calc(var(--height) - 4px);
|
||||
background: #ffffff;
|
||||
border-radius: var(--border-radius);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.toggle-input:checked ~ .toggle-fill::after {
|
||||
transform: translateX(var(--height));
|
||||
}
|
||||
|
||||
.toggle-fill::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: calc(var(--height) * 1.8);
|
||||
height: calc(var(--height) * 1.8);
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
left: calc(30% - var(--height));
|
||||
top: calc(60% - var(--height));
|
||||
scale: .75;
|
||||
transform-origin: center;
|
||||
transition: scale 0.35s cubic-bezier(0.6,-1.25,0.6,2.25), transform 0.2s;
|
||||
}
|
||||
|
||||
.toggle-fill:hover::before {
|
||||
background: var(--bg-core-primary-lighten);
|
||||
scale: 1;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.toggle-input:checked ~ .toggle-fill::before {
|
||||
transform: translateX(var(--height));
|
||||
}
|
@ -8,15 +8,15 @@ body{
|
||||
background: linear-gradient(to left, var(--bg-core-primary-lighten), var(--bg-core-end));
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-size: $base-font-size;
|
||||
//font-size: clamp($base-font-size * 0.9, $base-font-size * 0.9+0.1vw, $base-font-size);
|
||||
//font-size: clamp($base-font-size * 0.9, $base-font-size * 0.9 + 0.1vw, $base-font-size);
|
||||
color: var(--text-core);
|
||||
|
||||
@include breakpoint(sm){
|
||||
background: linear-gradient(to left, var(--bg-core-primary), var(--bg-core-end));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//hr classes
|
||||
hr {
|
||||
border-top: 1px solid var(--border-core);
|
||||
@ -25,11 +25,11 @@ hr {
|
||||
background-color:var(--border-core);
|
||||
color: var(--border-core);
|
||||
}
|
||||
|
||||
|
||||
//section
|
||||
section,
|
||||
.section{
|
||||
margin-bottom: 1rem;
|
||||
.section{
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
|
||||
@ -39,4 +39,43 @@ margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*ICONS*/
|
||||
.icon-default {
|
||||
color: var(--bg-core-primary);
|
||||
}
|
||||
|
||||
|
||||
.disabled {
|
||||
.icon-root, .svg-icon, .icon-default {
|
||||
color: var(--bg-core-primary-light);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-root {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
display: inline-block;
|
||||
transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&.svg-icon {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-size-small {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.icon-size-medium {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.icon-size-large {
|
||||
font-size: 2.25rem;
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@ -48,7 +46,13 @@ a:not([class]) {
|
||||
text-decoration-skip-ink: auto;
|
||||
}
|
||||
|
||||
a, a:hover {
|
||||
a {
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
transition: color 0.15s ease-in-out;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ p,
|
||||
|
||||
@each $property, $map in $fw {
|
||||
$prefix: map-get($map, "prefix");
|
||||
$values: map-get($map, "values");
|
||||
$values: map-get($map, "values");
|
||||
|
||||
@each $k, $v in $values {
|
||||
@if $breakName != "" {
|
||||
@ -157,6 +157,27 @@ p,
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.text-hc {
|
||||
color: var(--text-core-hc);
|
||||
}
|
||||
|
||||
.text-lc {
|
||||
color: var(--text-core-lc);
|
||||
}
|
||||
|
||||
a.text-link{
|
||||
color: var(--bg-core-primary-dark);
|
||||
border-bottom:1px dotted;
|
||||
transition: all 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
a.text-link:hover{
|
||||
color: var(--bg-core-primary-darken);
|
||||
border-bottom:none;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// $fs: (
|
||||
// "font-size": (
|
||||
// "prefix": "fs",
|
||||
|
@ -1,8 +1,8 @@
|
||||
@use "sass:math";
|
||||
|
||||
//theme colors
|
||||
$bg-core-primary: hsl(225, 68%, 85%); // body-background;
|
||||
$bg-core-start: $bg-core-primary;
|
||||
//$bg-core-primary: hsl(225, 68%, 85%); // body-background;
|
||||
//$bg-core-start: $bg-core-primary;
|
||||
$bg-core-end: #fafafa;
|
||||
|
||||
$text-core-hc: #212121; //title
|
||||
@ -10,67 +10,112 @@ $text-core: #525252; //text
|
||||
$text-core-lc: #7d7d80; //metadata
|
||||
$text-core-vc: #969699; //ikona-text
|
||||
|
||||
$border-core: lighten($bg-core-primary, 7%); //border
|
||||
//$border-core: lighten($bg-core-primary, 7%); //border
|
||||
$element-bg-core: rgba(255, 255, 255, 0.5); // elements-background
|
||||
$element-fg-core: rgba(255, 255, 255, 0.25); // elements-foreground
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:root {
|
||||
--bg-core-primary: #{$bg-core-primary}; // body-background;
|
||||
--bg-core-primary-lighten: hsl(225, 68%, 90%); // lighten
|
||||
--bg-core-primary-darken: hsl(225, 68%, 75%); // darken;
|
||||
--bg-core-start: #{$bg-core-primary};
|
||||
--bg-core-end: #{$bg-core-end};
|
||||
$blue-50: #f2f4fd;
|
||||
$blue-100: #e5eafa;
|
||||
$blue-200: #cbd6f5;
|
||||
$blue-300: #b2c1f1;
|
||||
$blue-400: #98adec;
|
||||
$blue-500: #7e98e7;
|
||||
$blue-600: #657ab9;
|
||||
$blue-700: #4c5b8b;
|
||||
$blue-800: #323d5c;
|
||||
$blue-900: #191e2e;
|
||||
|
||||
--bg-core-primary: #{$blue-300}; // body-background;
|
||||
--bg-core-primary-light: #{$blue-50}; // light
|
||||
--bg-core-primary-lighten: #{$blue-200}; // lighten
|
||||
--bg-core-primary-darken: #{$blue-400}; // darken;
|
||||
--bg-core-primary-dark: #{$blue-600}; // dark;
|
||||
--bg-core-start: #{$blue-300}; // body-background
|
||||
--bg-core-end: #{$bg-core-end}; // body-background
|
||||
|
||||
--text-core-hc: #{$text-core-hc}; //title
|
||||
--text-core: #{$text-core}; //text
|
||||
--text-core: #{$blue-800}; //text
|
||||
--text-core-lc: #{$text-core-lc}; //metadata
|
||||
--text-core-vc: #{$text-core-vc}; //ikona-text
|
||||
|
||||
--bg-core-primary-lighter: hsl(225, 68%, 90%); //hover
|
||||
--border-core: #{$border-core}; //border
|
||||
--border-core-lighten:#{$blue-100}; //border-lighten
|
||||
--border-core: #{$blue-200}; //border
|
||||
--element-bg-core: #{$element-bg-core}; // elements-background
|
||||
--element-fg-core: #{$element-fg-core}; // elements-foreground
|
||||
}
|
||||
|
||||
.pink,
|
||||
:root:has(pink:checked) {
|
||||
--bg-core-primary: hsl(310 50% 90%);
|
||||
--bg-core-primary-lighten: hsl(310 50% 95%); //lighten
|
||||
--bg-core-primary-darken: hsl(310 50% 85%); //darken
|
||||
--element-bg-core: hsl(310 50% 100% / 50%);
|
||||
--text-core: hsl(310 50% 15%);
|
||||
--border-core: hsl(310 50% 90%);
|
||||
|
||||
.pink {
|
||||
$violet-50: #f0eef6;
|
||||
$violet-100: #e1dced;
|
||||
$violet-200: #c2b9db;
|
||||
$violet-300: #a496c8;
|
||||
$violet-400: #8573b6;
|
||||
$violet-500: #6750a4;
|
||||
$violet-600: #524083;
|
||||
$violet-700: #3e3062;
|
||||
$violet-800: #151021;
|
||||
$violet-900: #212529;
|
||||
|
||||
--bg-core-primary: #{$violet-300}; // body-background;
|
||||
--bg-core-primary-light: #{$violet-50}; // light
|
||||
--bg-core-primary-lighten: #{$violet-200}; // lighten
|
||||
--bg-core-primary-darken: #{$violet-400}; // darken;
|
||||
--bg-core-primary-dark: #{$violet-600}; // dark;
|
||||
--bg-core-start: #{$violet-200}; // body-background
|
||||
--bg-core-end: #{$bg-core-end}; // body-background
|
||||
|
||||
--text-core-hc: #{$text-core-hc}; //title
|
||||
--text-core: #{$violet-800}; //text
|
||||
--text-core-lc: #{$text-core-lc}; //metadata
|
||||
--text-core-vc: #{$text-core-vc}; //ikona-text
|
||||
|
||||
--border-core-lighten:#{$violet-100}; //border-lighten
|
||||
--border-core: #{$violet-200}; //border
|
||||
--element-bg-core: #{$element-bg-core}; // elements-background
|
||||
--element-fg-core: #{$element-fg-core}; // elements-foreground
|
||||
}
|
||||
|
||||
.dark,
|
||||
:root:has(dark:checked) {
|
||||
|
||||
|
||||
.dark {
|
||||
--bg-core-primary: hsl(0 0% 10% / 100%); // body-background;
|
||||
--bg-core-primary-lighten: hsl(0 0% 15% / 100%); // lighten
|
||||
--bg-core-primary-darken: hsl(0 0% 5% / 100%); // darken;
|
||||
--bg-core-start: var(--bg-core-primary);
|
||||
--bg-core-end: hsl(0 0% 15% / 100%);
|
||||
--bg-core-primary-light: hsl(0 0% 15% / 100%); // light
|
||||
--bg-core-primary-lighten: hsl(0 0% 17% / 100%); // lighten
|
||||
--bg-core-primary-darken: hsl(0 0% 7% / 100%); // darken;
|
||||
--bg-core-primary-dark: hsl(0 0% 5% / 100%); // dark;
|
||||
--bg-core-start: hsl(0 0% 10% / 100%); // body-background
|
||||
--bg-core-end: hsl(0 0% 15% / 100%); // body-background
|
||||
|
||||
--text-core-hc: hsl(0 0% 97% / 100%); //title
|
||||
--text-core: hsl(0 0% 73% / 100%); //text
|
||||
--text-core-lc: hsl(0 0% 53% / 100%); //metadata
|
||||
--text-core-vc: hsl(0 0% 60% / 100%); //ikona-text
|
||||
|
||||
--border-core: hsl(0 0% 27% / 100%); //border
|
||||
--border-core-lighten:hsl(0 0% 17% / 100%); //border-lighten
|
||||
--border-core: hsl(0 0% 20% / 100%); //border
|
||||
--element-bg-core: hsl(0 0% 13% / 100%); // elements-background
|
||||
--element-fg-core: hsl(0 0% 20% / 100%); // elements-foreground
|
||||
--element-fg-core: hsl(0 0% 15% / 100%); // elements-foreground
|
||||
}
|
||||
|
||||
// colors
|
||||
$blue: #0d6efd;
|
||||
$indigo: #6610f2;
|
||||
$purple: #6f42c1;
|
||||
$pink: #d63384;
|
||||
$red: #dc3545;
|
||||
$orange: #fd7e14;
|
||||
$yellow: #ffc107;
|
||||
$green: #00c851; //#198754;
|
||||
$teal: #20c997;
|
||||
$cyan: #0dcaf0;
|
||||
// $blue: #0d6efd;
|
||||
// $indigo: #6610f2;
|
||||
// $purple: #6f42c1;
|
||||
// $pink: #d63384;
|
||||
// $red: #dc3545;
|
||||
// $orange: #fd7e14;
|
||||
// $yellow: #ffc107;
|
||||
// $green: #00c851; //#198754;
|
||||
// $teal: #20c997;
|
||||
// $cyan: #0dcaf0;
|
||||
|
||||
$white: #fff;
|
||||
$gray-100: #f8f9fa;
|
||||
@ -84,13 +129,20 @@ $gray-800: #343a40;
|
||||
$gray-900: #212529;
|
||||
$black: #000;
|
||||
|
||||
$blue: #0dbcf0c4;
|
||||
$red: #ff7f78;
|
||||
$yellow: #ffb480;
|
||||
$green: #8fcaa3;
|
||||
$cyan: #729fe9;
|
||||
|
||||
|
||||
$primary: $blue;
|
||||
$secondary: $gray-600;
|
||||
$secondary: $gray-400;
|
||||
$success: $green;
|
||||
$info: $cyan;
|
||||
$warning: $yellow;
|
||||
$danger: $red;
|
||||
$light: $gray-400;
|
||||
$light: $gray-300;
|
||||
$dark: $gray-900;
|
||||
|
||||
//color palette
|
||||
@ -138,9 +190,16 @@ $font-weight-800: 800; // extra bold
|
||||
$base-border-radius: 0.3rem;
|
||||
$border-radius-sm: math.div($base-border-radius, 2);
|
||||
$border-radius-lg: $base-border-radius * 2;
|
||||
$border-radius-pill: 100vw;
|
||||
|
||||
// box-shadow
|
||||
$base-box-shadow: 0 0.125rem 0.25rem rgb(0 0 0 / 10%) !default;
|
||||
|
||||
// transition
|
||||
$transition: all 0.15s ease-in-out;
|
||||
|
||||
//z-index
|
||||
$sidebar-zindex: 899;
|
||||
$sidebar-right-zindex: 898;
|
||||
$backdrop-zindex: 999;
|
||||
$modal-zindex: 10000;
|
||||
|
@ -1,16 +1,21 @@
|
||||
@use "../globals" as *;
|
||||
|
||||
|
||||
.color-picker-container {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.color-picker > fieldset {
|
||||
border: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
//flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
width: fit-content;
|
||||
//background: #fff;
|
||||
padding: 1rem 3rem;
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
right: 0;
|
||||
padding: 0.5rem 1.5rem;
|
||||
//position: fixed;
|
||||
//top: 1rem;
|
||||
//right: 0;
|
||||
border-radius: 0 0 1rem 1rem;
|
||||
}
|
||||
|
||||
@ -31,14 +36,15 @@
|
||||
background-color: var(--radio-color);
|
||||
}
|
||||
|
||||
.color-picker input[type="radio"]light {
|
||||
.color-picker input[type="radio"] {
|
||||
--radio-color: hsl(225, 68%, 85%);
|
||||
}
|
||||
.color-picker input[type="radio"]pink {
|
||||
--radio-color: pink;
|
||||
|
||||
.color-picker input[type="radio"] {
|
||||
--radio-color: rebeccapurple;
|
||||
}
|
||||
|
||||
.color-picker input[type="radio"]dark {
|
||||
.color-picker input[type="radio"] {
|
||||
--radio-color: #232323;
|
||||
}
|
||||
|
||||
@ -58,8 +64,9 @@
|
||||
background: var(--element-fg-core);
|
||||
border: 1px solid;
|
||||
border-color: var(--border-core);
|
||||
color: inherit;
|
||||
//color: inherit;
|
||||
border-radius: $border-radius-lg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
|
||||
//test-sidebar
|
||||
.document-container {
|
||||
background-color: var(--element-bg-core);
|
||||
}
|
||||
|
||||
.document-container {
|
||||
//padding: rem(32);
|
||||
|
||||
@ -33,7 +37,8 @@
|
||||
border-radius: $border-radius-lg;
|
||||
// padding: rem(32);
|
||||
box-shadow: $base-box-shadow;
|
||||
overflow: hidden;
|
||||
//overflow: hidden;
|
||||
overflow-x: clip;
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,8 @@
|
||||
|
||||
|
||||
$breakpoints-up: (
|
||||
"": "",
|
||||
"": "1",
|
||||
//'xs': rem(1),
|
||||
'sm': rem(576),
|
||||
'md': rem(768),
|
||||
'lg': rem(992),
|
||||
@ -11,7 +12,8 @@ $breakpoints-up: (
|
||||
|
||||
// 639px, 1149px, 1399px
|
||||
$breakpoints-down: (
|
||||
"": "",
|
||||
"": "0",
|
||||
//'xs': rem(0),
|
||||
'sm': rem(575),
|
||||
'md': rem(767),
|
||||
'lg': rem(991),
|
||||
|
@ -58,8 +58,7 @@
|
||||
}
|
||||
|
||||
//change --bg-core-primary for dark
|
||||
.dark,
|
||||
:root:has(dark:checked) {
|
||||
.dark {
|
||||
$val: hsl(216 100% 70%);
|
||||
|
||||
.text-core {
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
// change text color based on background color - set-color(color-value)
|
||||
@function set-color($color) {
|
||||
@if (lightness($color) > 55) {
|
||||
@if (lightness($color) > 74) {
|
||||
@return #333;
|
||||
}
|
||||
@else {
|
||||
@return #FFF;
|
||||
@return #FFF;
|
||||
}
|
||||
}
|
||||
}
|
@ -160,6 +160,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Position classes
|
||||
$positionProps: (
|
||||
"absolute",
|
||||
"fixed",
|
||||
"inherit",
|
||||
"initial",
|
||||
"relative",
|
||||
"revert",
|
||||
"static",
|
||||
"sticky",
|
||||
"unset",
|
||||
);
|
||||
|
||||
@each $pos in $positionProps {
|
||||
@if $breakName != "" {
|
||||
@media (min-width: $breakValue) {
|
||||
.position-#{$breakName}-#{$pos} {
|
||||
position: #{$pos} !important;
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
.position-#{$pos} {
|
||||
position: #{$pos} !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Display classes
|
||||
$displayProps: (
|
||||
"block",
|
||||
|
@ -135,12 +135,24 @@ public static class Helper
|
||||
}
|
||||
}
|
||||
|
||||
public static T? ConvertToType<T>(object variable)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (variable is not null)
|
||||
return (T)Convert.ChangeType(variable, typeof(T));
|
||||
return default;
|
||||
} catch
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsNumeric(string input)
|
||||
{
|
||||
try
|
||||
{
|
||||
var number = Double.Parse(input);
|
||||
return true;
|
||||
return Double.TryParse(input, out var number);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user