diff --git a/src/.editorconfig b/src/.editorconfig index cfb7e4f786..cce712f5f9 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -9,6 +9,7 @@ spelling_languages = en-US spelling_checkable_types = strings,identifiers,comments spelling_error_severity = information spelling_exclusion_path = spellcheckerexclusion.dic +spelling_use_default_exclusion_dictionary = true # Use CRLF for end of line [*] diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 5daad4f971..40bedea1b8 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -7,7 +7,6 @@ 8.1.0 7.1.2 7.0.0 - 2.0.1 4.7.37 7.1.100 8.0.0-dev.65 @@ -30,7 +29,6 @@ - diff --git a/src/app/dev/DevToys.Api/Core/ObservableHashSet.cs b/src/app/dev/DevToys.Api/Core/ObservableHashSet.cs new file mode 100644 index 0000000000..12aa580dff --- /dev/null +++ b/src/app/dev/DevToys.Api/Core/ObservableHashSet.cs @@ -0,0 +1,486 @@ +using System.Collections; +using System.Collections.Specialized; + +namespace DevToys.Api.Core; + +/// +/// COPY FROM https://github.com/dotnet/efcore/blob/2d7c4a407e3ae8b1fab38500465e37619786d362/src/EFCore/ChangeTracking/ObservableHashSet.cs +/// +/// +/// See Local views of tracked entities in EF Core for more information and +/// examples. +/// +/// The type of elements in the hash set. +public class ObservableHashSet + : ISet, IReadOnlyCollection, INotifyCollectionChanged, INotifyPropertyChanged, INotifyPropertyChanging +{ + private HashSet _set; + + /// + /// Initializes a new instance of the class + /// that is empty and uses the default equality comparer for the set type. + /// + public ObservableHashSet() + : this(EqualityComparer.Default) + { + } + + /// + /// Initializes a new instance of the class + /// that is empty and uses the specified equality comparer for the set type. + /// + /// + /// The implementation to use when + /// comparing values in the set, or null to use the default + /// implementation for the set type. + /// + public ObservableHashSet(IEqualityComparer comparer) + { + _set = new HashSet(comparer); + } + + /// + /// Initializes a new instance of the class + /// that uses the default equality comparer for the set type, contains elements copied + /// from the specified collection, and has sufficient capacity to accommodate the + /// number of elements copied. + /// + /// The collection whose elements are copied to the new set. + public ObservableHashSet(IEnumerable collection) + : this(collection, EqualityComparer.Default) + { + } + + /// + /// Initializes a new instance of the class + /// that uses the specified equality comparer for the set type, contains elements + /// copied from the specified collection, and has sufficient capacity to accommodate + /// the number of elements copied. + /// + /// The collection whose elements are copied to the new set. + /// + /// The implementation to use when + /// comparing values in the set, or null to use the default + /// implementation for the set type. + /// + public ObservableHashSet(IEnumerable collection, IEqualityComparer comparer) + { + _set = new HashSet(collection, comparer); + } + + /// + /// Occurs when a property of this hash set (such as ) changes. + /// + public event PropertyChangedEventHandler? PropertyChanged; + + /// + /// Occurs when a property of this hash set (such as ) is changing. + /// + public event PropertyChangingEventHandler? PropertyChanging; + + /// + /// Occurs when the contents of the hash set changes. + /// + public event NotifyCollectionChangedEventHandler? CollectionChanged; + + void ICollection.Add(T item) + => Add(item); + + /// + /// Removes all elements from the hash set. + /// + public virtual void Clear() + { + if (_set.Count == 0) + { + return; + } + + OnCountPropertyChanging(); + + var removed = this.ToList(); + + _set.Clear(); + + OnCollectionChanged(ObservableHashSetSingletons.NoItems, removed); + + OnCountPropertyChanged(); + } + + /// + /// Determines whether the hash set object contains the + /// specified element. + /// + /// The element to locate in the hash set. + /// + /// if the hash set contains the specified element; otherwise, . + /// + public virtual bool Contains(T item) + => _set.Contains(item); + + /// + /// Copies the elements of the hash set to an array, starting at the specified array index. + /// + /// + /// The one-dimensional array that is the destination of the elements copied from + /// the hash set. The array must have zero-based indexing. + /// + /// The zero-based index in array at which copying begins. + public virtual void CopyTo(T[] array, int arrayIndex) + => _set.CopyTo(array, arrayIndex); + + /// + /// Removes the specified element from the hash set. + /// + /// The element to remove. + /// + /// if the element is successfully found and removed; otherwise, . + /// + public virtual bool Remove(T item) + { + if (!_set.Contains(item)) + { + return false; + } + + OnCountPropertyChanging(); + + _set.Remove(item); + + OnCollectionChanged(NotifyCollectionChangedAction.Remove, item); + + OnCountPropertyChanged(); + + return true; + } + + /// + /// Gets the number of elements that are contained in the hash set. + /// + public virtual int Count + => _set.Count; + + /// + /// Gets a value indicating whether the hash set is read-only. + /// + public virtual bool IsReadOnly + => ((ICollection)_set).IsReadOnly; + + /// + /// Returns an enumerator that iterates through the hash set. + /// + /// + /// An enumerator for the hash set. + /// + public virtual HashSet.Enumerator GetEnumerator() + => _set.GetEnumerator(); + + /// + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + /// + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + /// + /// Adds the specified element to the hash set. + /// + /// The element to add to the set. + /// + /// if the element is added to the hash set; if the element is already present. + /// + public virtual bool Add(T item) + { + if (_set.Contains(item)) + { + return false; + } + + OnCountPropertyChanging(); + + _set.Add(item); + + OnCollectionChanged(NotifyCollectionChangedAction.Add, item); + + OnCountPropertyChanged(); + + return true; + } + + /// + /// Modifies the hash set to contain all elements that are present in itself, the specified collection, or both. + /// + /// The collection to compare to the current hash set. + public virtual void UnionWith(IEnumerable other) + { + var copy = new HashSet(_set, _set.Comparer); + + copy.UnionWith(other); + + if (copy.Count == _set.Count) + { + return; + } + + var added = copy.Where(i => !_set.Contains(i)).ToList(); + + OnCountPropertyChanging(); + + _set = copy; + + OnCollectionChanged(added, ObservableHashSetSingletons.NoItems); + + OnCountPropertyChanged(); + } + + /// + /// Modifies the current hash set to contain only + /// elements that are present in that object and in the specified collection. + /// + /// The collection to compare to the current hash set. + public virtual void IntersectWith(IEnumerable other) + { + var copy = new HashSet(_set, _set.Comparer); + + copy.IntersectWith(other); + + if (copy.Count == _set.Count) + { + return; + } + + var removed = _set.Where(i => !copy.Contains(i)).ToList(); + + OnCountPropertyChanging(); + + _set = copy; + + OnCollectionChanged(ObservableHashSetSingletons.NoItems, removed); + + OnCountPropertyChanged(); + } + + /// + /// Removes all elements in the specified collection from the hash set. + /// + /// The collection of items to remove from the current hash set. + public virtual void ExceptWith(IEnumerable other) + { + var copy = new HashSet(_set, _set.Comparer); + + copy.ExceptWith(other); + + if (copy.Count == _set.Count) + { + return; + } + + var removed = _set.Where(i => !copy.Contains(i)).ToList(); + + OnCountPropertyChanging(); + + _set = copy; + + OnCollectionChanged(ObservableHashSetSingletons.NoItems, removed); + + OnCountPropertyChanged(); + } + + /// + /// Modifies the current hash set to contain only elements that are present either in that + /// object or in the specified collection, but not both. + /// + /// The collection to compare to the current hash set. + public virtual void SymmetricExceptWith(IEnumerable other) + { + var copy = new HashSet(_set, _set.Comparer); + + copy.SymmetricExceptWith(other); + + var removed = _set.Where(i => !copy.Contains(i)).ToList(); + var added = copy.Where(i => !_set.Contains(i)).ToList(); + + if (removed.Count == 0 + && added.Count == 0) + { + return; + } + + OnCountPropertyChanging(); + + _set = copy; + + OnCollectionChanged(added, removed); + + OnCountPropertyChanged(); + } + + /// + /// Determines whether the hash set is a subset of the specified collection. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set is a subset of other; otherwise, . + /// + public virtual bool IsSubsetOf(IEnumerable other) + => _set.IsSubsetOf(other); + + /// + /// Determines whether the hash set is a proper subset of the specified collection. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set is a proper subset of other; otherwise, . + /// + public virtual bool IsProperSubsetOf(IEnumerable other) + => _set.IsProperSubsetOf(other); + + /// + /// Determines whether the hash set is a superset of the specified collection. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set is a superset of other; otherwise, . + /// + public virtual bool IsSupersetOf(IEnumerable other) + => _set.IsSupersetOf(other); + + /// + /// Determines whether the hash set is a proper superset of the specified collection. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set is a proper superset of other; otherwise, . + /// + public virtual bool IsProperSupersetOf(IEnumerable other) + => _set.IsProperSupersetOf(other); + + /// + /// Determines whether the current System.Collections.Generic.HashSet`1 object and a specified collection share common elements. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set and other share at least one common element; otherwise, . + /// + public virtual bool Overlaps(IEnumerable other) + => _set.Overlaps(other); + + /// + /// Determines whether the hash set and the specified collection contain the same elements. + /// + /// The collection to compare to the current hash set. + /// + /// if the hash set is equal to other; otherwise, . + /// + public virtual bool SetEquals(IEnumerable other) + => _set.SetEquals(other); + + /// + /// Copies the elements of the hash set to an array. + /// + /// + /// The one-dimensional array that is the destination of the elements copied from + /// the hash set. The array must have zero-based indexing. + /// + public virtual void CopyTo(T[] array) + => _set.CopyTo(array); + + /// + /// Copies the specified number of elements of the hash set to an array, starting at the specified array index. + /// + /// + /// The one-dimensional array that is the destination of the elements copied from + /// the hash set. The array must have zero-based indexing. + /// + /// The zero-based index in array at which copying begins. + /// The number of elements to copy to array. + public virtual void CopyTo(T[] array, int arrayIndex, int count) + => _set.CopyTo(array, arrayIndex, count); + + /// + /// Removes all elements that match the conditions defined by the specified predicate + /// from the hash set. + /// + /// + /// The delegate that defines the conditions of the elements to remove. + /// + /// The number of elements that were removed from the hash set. + public virtual int RemoveWhere(Predicate match) + { + var copy = new HashSet(_set, _set.Comparer); + + int removedCount = copy.RemoveWhere(match); + + if (removedCount == 0) + { + return 0; + } + + var removed = _set.Where(i => !copy.Contains(i)).ToList(); + + OnCountPropertyChanging(); + + _set = copy; + + OnCollectionChanged(ObservableHashSetSingletons.NoItems, removed); + + OnCountPropertyChanged(); + + return removedCount; + } + + /// + /// Gets the object that is used to determine equality for the values in the set. + /// + public virtual IEqualityComparer Comparer + => _set.Comparer; + + /// + /// Sets the capacity of the hash set to the actual number of elements it contains, rounded up to a nearby, + /// implementation-specific value. + /// + public virtual void TrimExcess() + => _set.TrimExcess(); + + /// + /// Raises the event. + /// + /// Details of the property that changed. + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + => PropertyChanged?.Invoke(this, e); + + /// + /// Raises the event. + /// + /// Details of the property that is changing. + protected virtual void OnPropertyChanging(PropertyChangingEventArgs e) + => PropertyChanging?.Invoke(this, e); + + private void OnCountPropertyChanged() + => OnPropertyChanged(ObservableHashSetSingletons.CountPropertyChanged); + + private void OnCountPropertyChanging() + => OnPropertyChanging(ObservableHashSetSingletons.CountPropertyChanging); + + private void OnCollectionChanged(NotifyCollectionChangedAction action, object? item) + => OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item)); + + private void OnCollectionChanged(IList newItems, IList oldItems) + => OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItems, oldItems)); + + /// + /// Raises the event. + /// + /// Details of the change. + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + => CollectionChanged?.Invoke(this, e); +} + +internal static class ObservableHashSetSingletons +{ + public static readonly PropertyChangedEventArgs CountPropertyChanged = new("Count"); + public static readonly PropertyChangingEventArgs CountPropertyChanging = new("Count"); + + public static readonly object[] NoItems = Array.Empty(); +} diff --git a/src/app/dev/DevToys.Api/Core/Threading/TaskExtensions.cs b/src/app/dev/DevToys.Api/Core/Threading/TaskExtensions.cs index d5147362ea..40fac5f735 100644 --- a/src/app/dev/DevToys.Api/Core/Threading/TaskExtensions.cs +++ b/src/app/dev/DevToys.Api/Core/Threading/TaskExtensions.cs @@ -1,6 +1,4 @@ -using System.Threading; - -namespace DevToys.Api; +namespace DevToys.Api; /// /// Provides a set of helper method to play around with threads. diff --git a/src/app/dev/DevToys.Api/Core/Threading/TaskSchedulerAwaiter.cs b/src/app/dev/DevToys.Api/Core/Threading/TaskSchedulerAwaiter.cs index f837584c4c..e38fd7fa4c 100644 --- a/src/app/dev/DevToys.Api/Core/Threading/TaskSchedulerAwaiter.cs +++ b/src/app/dev/DevToys.Api/Core/Threading/TaskSchedulerAwaiter.cs @@ -68,7 +68,7 @@ public bool IsCompleted // We special case the TaskScheduler.Default since that is semantically equivalent to being // on a ThreadPool thread, and there are various ways to get on those threads. // TaskScheduler.Current is never null. Even if no scheduler is really active and the current - // thread is not a threadpool thread, TaskScheduler.Current == TaskScheduler.Default, so we have + // thread is not a thread pool thread, TaskScheduler.Current == TaskScheduler.Default, so we have // to protect against that case too. bool isThreadPoolThread = Thread.CurrentThread.IsThreadPoolThread; return (_scheduler == TaskScheduler.Default && isThreadPoolThread) diff --git a/src/app/dev/DevToys.Api/Settings/ISettingsProvider.cs b/src/app/dev/DevToys.Api/Settings/ISettingsProvider.cs index 1403ef67b8..d9ee8c81fb 100644 --- a/src/app/dev/DevToys.Api/Settings/ISettingsProvider.cs +++ b/src/app/dev/DevToys.Api/Settings/ISettingsProvider.cs @@ -14,7 +14,7 @@ public interface ISettingsProvider /// Gets the value of a defined setting. /// /// The type of value that will be retrieved. - /// The that defines the targetted setting. + /// The that defines the targeted setting. /// Return the value of the setting or its default value. T GetSetting(SettingDefinition settingDefinition); @@ -22,7 +22,7 @@ public interface ISettingsProvider /// Sets the value of a given setting. /// /// The type of value that will be set. - /// The that defines the targetted setting. + /// The that defines the targeted setting. /// The value to set void SetSetting(SettingDefinition settingDefinition, T value); diff --git a/src/app/dev/DevToys.Api/Tool/CLI/ICommandLineTool.cs b/src/app/dev/DevToys.Api/Tool/CLI/ICommandLineTool.cs index 55de329d13..18801c0575 100644 --- a/src/app/dev/DevToys.Api/Tool/CLI/ICommandLineTool.cs +++ b/src/app/dev/DevToys.Api/Tool/CLI/ICommandLineTool.cs @@ -46,7 +46,7 @@ public interface ICommandLineTool /// Using : /// - DO report errors. /// - DO report information about performance of some tasks, if relevant. - /// - DO report some system information, but only if it can truly be helpful when investigating performance or compatiblity issues. + /// - DO report some system information, but only if it can truly be helpful when investigating performance or compatibility issues. /// - DO NOT report what the user input in the app as it might contains user personal information. /// ValueTask InvokeAsync(ILogger logger, CancellationToken cancellationToken); diff --git a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIDiffTextInput.cs b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIDiffTextInput.cs index a1c94c49f0..3bb847c7ed 100644 --- a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIDiffTextInput.cs +++ b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIDiffTextInput.cs @@ -4,7 +4,7 @@ /// A component that can be used to display side by side or inlined texts and highlight differences between them. /// This component is powered by Monaco Editor. /// -public interface IUIDiffTextInput : IUISinglelineTextInput +public interface IUIDiffTextInput : IUISingleLineTextInput { /// /// Gets the text displayed to the right of the diff view. diff --git a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIMultilineLineTextInput.cs b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIMultilineLineTextInput.cs index 6f22a198ba..c047ba532a 100644 --- a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIMultilineLineTextInput.cs +++ b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUIMultilineLineTextInput.cs @@ -9,7 +9,7 @@ namespace DevToys.Api; /// /// This component is powered by Monaco Editor. /// -public interface IUIMultilineLineTextInput : IUISinglelineTextInput +public interface IUIMultilineLineTextInput : IUISingleLineTextInput { /// /// Gets the list of spans to highlight in the text document. @@ -33,7 +33,7 @@ public interface IUIMultilineLineTextInput : IUISinglelineTextInput } [DebuggerDisplay($"Id = {{{nameof(Id)}}}, Text = {{{nameof(Text)}}}")] -internal class UIMultilineTextInput : UISinglelineTextInput, IUIMultilineLineTextInput +internal class UIMultilineTextInput : UISingleLineTextInput, IUIMultilineLineTextInput { private IReadOnlyList? _highlightedSpans; private string? _syntaxColorizationLanguageName; diff --git a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUISinglelineTextInput.cs b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUISinglelineTextInput.cs index 8fc2e44696..6772d9ef5b 100644 --- a/src/app/dev/DevToys.Api/Tool/GUI/Components/IUISinglelineTextInput.cs +++ b/src/app/dev/DevToys.Api/Tool/GUI/Components/IUISinglelineTextInput.cs @@ -3,7 +3,7 @@ /// /// A component that can be used to display or edit unformatted text on a single line. /// -public interface IUISinglelineTextInput : IUITitledElement +public interface IUISingleLineTextInput : IUITitledElement { /// /// Gets whether the user can edit the text or not. Default is false. @@ -47,14 +47,14 @@ public interface IUISinglelineTextInput : IUITitledElement } [DebuggerDisplay($"Id = {{{nameof(Id)}}}, Text = {{{nameof(Text)}}}")] -internal class UISinglelineTextInput : UITitledElement, IUISinglelineTextInput +internal class UISingleLineTextInput : UITitledElement, IUISingleLineTextInput { private string? _text; private bool _isReadOnly; private bool _canCopyWhenEditable; private TextSpan? _selection; - internal UISinglelineTextInput(string? id) + internal UISingleLineTextInput(string? id) : base(id) { } @@ -125,26 +125,26 @@ public static partial class GUI /// /// Create a component that can be used to display or edit unformatted text on a single line. /// - public static IUISinglelineTextInput SinglelineTextInput() + public static IUISingleLineTextInput SingleLineTextInput() { - return SinglelineTextInput(null); + return SingleLineTextInput(null); } /// /// Create a component that can be used to display or edit unformatted text on a single line. /// /// An optional unique identifier for this UI element. - public static IUISinglelineTextInput SinglelineTextInput(string? id) + public static IUISingleLineTextInput SingleLineTextInput(string? id) { - return new UISinglelineTextInput(id); + return new UISingleLineTextInput(id); } /// /// Sets the text input control as read-only. /// - public static T ReadOnly(this T element) where T : IUISinglelineTextInput + public static T ReadOnly(this T element) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.IsReadOnly = true; } @@ -154,9 +154,9 @@ public static T ReadOnly(this T element) where T : IUISinglelineTextInput /// /// Sets the text input control as editable. /// - public static T Editable(this T element) where T : IUISinglelineTextInput + public static T Editable(this T element) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.IsReadOnly = false; } @@ -166,9 +166,9 @@ public static T Editable(this T element) where T : IUISinglelineTextInput /// /// Shows the "copy" button when the editor is editable. /// - public static T CanCopyWhenEditable(this T element) where T : IUISinglelineTextInput + public static T CanCopyWhenEditable(this T element) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.CanCopyWhenEditable = true; } @@ -178,9 +178,9 @@ public static T CanCopyWhenEditable(this T element) where T : IUISinglelineTe /// /// Hides the "copy" button when the editor is editable. /// - public static T CannotCopyWhenEditable(this T element) where T : IUISinglelineTextInput + public static T CannotCopyWhenEditable(this T element) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.CanCopyWhenEditable = false; } @@ -190,9 +190,9 @@ public static T CannotCopyWhenEditable(this T element) where T : IUISinglelin /// /// Sets the unformatted text of the control. /// - public static T Text(this T element, string text) where T : IUISinglelineTextInput + public static T Text(this T element, string text) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.Text = text; } @@ -202,9 +202,9 @@ public static T Text(this T element, string text) where T : IUISinglelineText /// /// Selects the given span in the text document. /// - public static T Select(this T element, TextSpan span) where T : IUISinglelineTextInput + public static T Select(this T element, TextSpan span) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.Selection = span; } @@ -214,9 +214,9 @@ public static T Select(this T element, TextSpan span) where T : IUISingleline /// /// Selects the given span in the text document. /// - public static T Select(this T element, int start, int length) where T : IUISinglelineTextInput + public static T Select(this T element, int start, int length) where T : IUISingleLineTextInput { - if (element is UISinglelineTextInput strongElement) + if (element is UISingleLineTextInput strongElement) { strongElement.Selection = new TextSpan(start, length); } diff --git a/src/app/dev/DevToys.Api/Tool/Metadata/Attributes/ToolDisplayInformationAttribute.cs b/src/app/dev/DevToys.Api/Tool/Metadata/Attributes/ToolDisplayInformationAttribute.cs index df9d3a091a..f452d81a4d 100644 --- a/src/app/dev/DevToys.Api/Tool/Metadata/Attributes/ToolDisplayInformationAttribute.cs +++ b/src/app/dev/DevToys.Api/Tool/Metadata/Attributes/ToolDisplayInformationAttribute.cs @@ -13,7 +13,7 @@ public sealed class ToolDisplayInformationAttribute : Attribute private string _longDisplayTitleResourceName = string.Empty; private string _descriptionResourceName = string.Empty; private string _accessibleNameResourceName = string.Empty; - private string _searchkeywordsResourceName = string.Empty; + private string _searchKeywordsResourceName = string.Empty; private char _iconGlyph; private string _iconFontName = string.Empty; private string _groupName = string.Empty; @@ -124,11 +124,11 @@ public string AccessibleNameResourceName /// public string SearchKeywordsResourceName { - get => _searchkeywordsResourceName; + get => _searchKeywordsResourceName; set { Guard.IsNotNullOrWhiteSpace(value); - _searchkeywordsResourceName = value; + _searchKeywordsResourceName = value; } } diff --git a/src/app/dev/DevToys.Business/ViewModels/MainWindowViewModel.cs b/src/app/dev/DevToys.Business/ViewModels/MainWindowViewModel.cs index f1528df3e7..0522b5ffe5 100644 --- a/src/app/dev/DevToys.Business/ViewModels/MainWindowViewModel.cs +++ b/src/app/dev/DevToys.Business/ViewModels/MainWindowViewModel.cs @@ -53,16 +53,16 @@ public MainWindowViewModel( /// Gets a hierarchical list containing all the tools available, ordered, to display in the top and body menu. /// This includes "All tools" menu item, recents and favorites. /// - internal ReadOnlyObservableCollection HeaderAndBodyToolViewItems => _guiToolProvider.HeaderAndBodyToolViewItems; + internal ReadOnlyObservableCollection HeaderAndBodyToolViewItems => _guiToolProvider.HeaderAndBodyToolViewItems; /// /// Gets a flat list containing all the footer tools available, ordered. /// - internal ReadOnlyObservableCollection FooterToolViewItems => _guiToolProvider.FooterToolViewItems; + internal ReadOnlyObservableCollection FooterToolViewItems => _guiToolProvider.FooterToolViewItems; // Can't use CommunityToolkit.MVVM due to https://github.com/dotnet/roslyn/issues/57239#issuecomment-1437895948 /// - /// Gets or sets the selected menu item in the NavitationView. + /// Gets or sets the selected menu item in the NavigationView. /// public INotifyPropertyChanged? SelectedMenuItem { @@ -237,7 +237,7 @@ IReadOnlyList detectedTools // And that the current selected menu item is a group, or that the user didn't selected another menu item since the smart detection started if (detectedTools.Count == 1 && (SelectedMenuItem == selectedMenuBeforeSmartDetection || SelectedMenuItem is GroupViewItem && firstToolViewItem is not null)) { - // Then let's navigate immeditaly to it and set the detected data as an input. + // Then let's navigate immediately to it and set the detected data as an input. SelectedMenuItem = firstToolViewItem; detectedTools[0].ToolInstance.PassSmartDetectedData(detectedTools[0].DataTypeName, detectedTools[0].ParsedData); } diff --git a/src/app/dev/DevToys.Core/IGroup.cs b/src/app/dev/DevToys.Core/IGroup.cs new file mode 100644 index 0000000000..f44451c09e --- /dev/null +++ b/src/app/dev/DevToys.Core/IGroup.cs @@ -0,0 +1,24 @@ +namespace DevToys.Core; + +public interface IGroup +{ + /// + /// Gets all the children items of this group. + /// + IEnumerable? ChildrenItems { get; set; } + + /// + /// Gets whether the group should be expanded by default. + /// + bool GroupShouldBeExpandedByDefaultInUI { get; } + + /// + /// Gets whether the group should be expanded. + /// + public bool GroupShouldBeExpandedInUI { get; } + + /// + /// Gets or sets whether the group is expanded in the UI. + /// + public bool GroupIsExpandedInUI { get; set; } +} diff --git a/src/app/dev/DevToys.Core/IItem.cs b/src/app/dev/DevToys.Core/IItem.cs new file mode 100644 index 0000000000..f8df4212f1 --- /dev/null +++ b/src/app/dev/DevToys.Core/IItem.cs @@ -0,0 +1,5 @@ +namespace DevToys.Core; + +public interface IItem +{ +} diff --git a/src/app/dev/DevToys.Core/ISeparator.cs b/src/app/dev/DevToys.Core/ISeparator.cs new file mode 100644 index 0000000000..826a18b2e0 --- /dev/null +++ b/src/app/dev/DevToys.Core/ISeparator.cs @@ -0,0 +1,5 @@ +namespace DevToys.Core; + +public interface ISeparator +{ +} diff --git a/src/app/dev/DevToys.Core/Tools/GuiToolProvider.cs b/src/app/dev/DevToys.Core/Tools/GuiToolProvider.cs index 521b3f4625..d4a097df87 100644 --- a/src/app/dev/DevToys.Core/Tools/GuiToolProvider.cs +++ b/src/app/dev/DevToys.Core/Tools/GuiToolProvider.cs @@ -43,10 +43,10 @@ public static readonly GuiToolViewItem NoResultFoundItem private readonly IReadOnlyList _footerToolInstances; private readonly IReadOnlyList _bodyToolInstances; - private ObservableCollection? _headerAndBodyToolViewItems; - private ReadOnlyObservableCollection? _headerAndBodyToolViewItemsReadOnly; - private ObservableCollection? _footerToolViewItems; - private ReadOnlyObservableCollection? _footerToolViewItemsReadOnly; + private ObservableCollection? _headerAndBodyToolViewItems; + private ReadOnlyObservableCollection? _headerAndBodyToolViewItemsReadOnly; + private ObservableCollection? _footerToolViewItems; + private ReadOnlyObservableCollection? _footerToolViewItemsReadOnly; private GroupViewItem? _favoriteToolsGroupViewItem; private SeparatorViewItem? _separatorAfterAllToolsItem; private SeparatorViewItem? _separatorAfterRecentTools; @@ -81,7 +81,7 @@ public GuiToolProvider( /// Gets a hierarchical list containing all the tools available, ordered, to display in the top and body menu. /// This includes "All tools" menu item, recents and favorites. /// - public ReadOnlyObservableCollection HeaderAndBodyToolViewItems + public ReadOnlyObservableCollection HeaderAndBodyToolViewItems { get { @@ -100,7 +100,7 @@ public ReadOnlyObservableCollection HeaderAndBodyToolVie /// /// Gets a flat list containing all the footer tools available, ordered. /// - public ReadOnlyObservableCollection FooterToolViewItems + public ReadOnlyObservableCollection FooterToolViewItems { get { @@ -184,7 +184,8 @@ public void SetToolIsFavorite(GuiToolInstance guiToolInstance, bool isFavorite) if (_headerAndBodyToolViewItems is not null) { Guard.HasSizeGreaterThan((ICollection)_headerAndBodyToolViewItems!, 2); - Guard.IsOfType(_headerAndBodyToolViewItems[1]); + Guard.IsNotNull(_headerAndBodyToolViewItems[1]); + Guard.IsOfType(_headerAndBodyToolViewItems[1]!); if (isFavorite) // Add the tool to the favorites { @@ -256,7 +257,7 @@ public IEnumerable GetViewItemFromTool(GuiToolInstance guiToolI { for (int i = 0; i < FooterToolViewItems.Count; i++) { - INotifyPropertyChanged item = FooterToolViewItems[i]; + INotifyPropertyChanged? item = FooterToolViewItems[i]; if (item is GuiToolViewItem guiToolViewItem && guiToolViewItem.ToolInstance == guiToolInstance) { yield return guiToolViewItem; @@ -265,7 +266,7 @@ public IEnumerable GetViewItemFromTool(GuiToolInstance guiToolI for (int i = 0; i < HeaderAndBodyToolViewItems.Count; i++) { - INotifyPropertyChanged item = HeaderAndBodyToolViewItems[i]; + INotifyPropertyChanged? item = HeaderAndBodyToolViewItems[i]; if (item is GuiToolViewItem guiToolViewItem && guiToolViewItem.ToolInstance == guiToolInstance) { yield return guiToolViewItem; @@ -288,7 +289,7 @@ public void ForEachToolViewItem(Action action) { for (int i = 0; i < FooterToolViewItems.Count; i++) { - INotifyPropertyChanged item = FooterToolViewItems[i]; + INotifyPropertyChanged? item = FooterToolViewItems[i]; if (item is GuiToolViewItem guiToolViewItem) { action(guiToolViewItem); @@ -297,7 +298,7 @@ public void ForEachToolViewItem(Action action) for (int i = 0; i < HeaderAndBodyToolViewItems.Count; i++) { - INotifyPropertyChanged item = HeaderAndBodyToolViewItems[i]; + INotifyPropertyChanged? item = HeaderAndBodyToolViewItems[i]; if (item is GuiToolViewItem guiToolViewItem) { action(guiToolViewItem); diff --git a/src/app/dev/DevToys.Core/Tools/SmartDetectionService.cs b/src/app/dev/DevToys.Core/Tools/SmartDetectionService.cs index f1e73dc6b4..b8e7617738 100644 --- a/src/app/dev/DevToys.Core/Tools/SmartDetectionService.cs +++ b/src/app/dev/DevToys.Core/Tools/SmartDetectionService.cs @@ -22,7 +22,7 @@ public SmartDetectionService( { _logger = this.Log(); - // Build a hiearchy of detectors based on their indicated base data type name. + // Build a hierarchy of detectors based on their indicated base data type name. _detectorHierarchy = BuildDetectorNodeHierarchy(dataTypeDetectors); // Create a map of data types to tools. @@ -30,7 +30,7 @@ public SmartDetectionService( } /// - /// Presumbly the active tool in the app. + /// Presumably the active tool in the app. /// public GuiToolInstance? ActiveToolInstance { private get; set; } @@ -40,10 +40,10 @@ public SmartDetectionService( /// The raw data to use to detect the tools that could be used. /// When true, only returns tools that fit the best the given . /// When false, returns in priority the best tools that fit the given , then the first level of data type base that fit the . - /// Example: Assuming the following data type dependencies: JWT-Header > JSON > Text. If is a JWT-Header and that is true, only tools that stricly support JWT-Header data type will be return. + /// Example: Assuming the following data type dependencies: JWT-Header > JSON > Text. If is a JWT-Header and that is true, only tools that strictly support JWT-Header data type will be return. /// if is false, tools that support JWT-Header and JSON data types will be return, but tools that support Text won't be returned. /// - /// Assuming the following data type dependencies: JWT-Header > JSON > Text. If is a JWT-Header and that is true, only tools that stricly support JWT-Header data type will be return. + /// Assuming the following data type dependencies: JWT-Header > JSON > Text. If is a JWT-Header and that is true, only tools that strictly support JWT-Header data type will be return. /// if is false, tools that support JWT-Header and JSON data types will be return, but tools that support Text won't be returned. /// public async Task> DetectAsync(object? rawData, bool strict, CancellationToken cancellationToken) diff --git a/src/app/dev/DevToys.Core/Tools/ViewItems/GroupViewItem.cs b/src/app/dev/DevToys.Core/Tools/ViewItems/GroupViewItem.cs index 0cbda43f48..3c0edf2341 100644 --- a/src/app/dev/DevToys.Core/Tools/ViewItems/GroupViewItem.cs +++ b/src/app/dev/DevToys.Core/Tools/ViewItems/GroupViewItem.cs @@ -8,9 +8,10 @@ namespace DevToys.Core.Tools.ViewItems; /// Represents a group or category in the main menu. /// [DebuggerDisplay($"DisplayTitle = {{{nameof(DisplayTitle)}}}")] -public sealed class GroupViewItem : ObservableObject +public sealed class GroupViewItem : ObservableObject, IGroup { private bool _childItemJustGotSelected; + private bool _isExpanded; internal GroupViewItem( string internalName, @@ -43,7 +44,8 @@ internal GroupViewItem( IconFontName = iconFontName; IconGlyph = iconGlyph; Children = children; - MenuItemShouldBeExpandedByDefault = menuItemShouldBeExpandedByDefault; + ChildrenItems = Children; + GroupShouldBeExpandedByDefaultInUI = menuItemShouldBeExpandedByDefault; if (children is not null) { @@ -89,15 +91,20 @@ internal GroupViewItem( /// public ObservableCollection? Children { get; } + /// + /// Gets all the children items of this group. + /// + public IEnumerable? ChildrenItems { get; set; } + /// /// Gets whether the group should be expanded by default. /// - public bool MenuItemShouldBeExpandedByDefault { get; } + public bool GroupShouldBeExpandedByDefaultInUI { get; } /// /// Gets whether the group should be expanded. /// - public bool MenuItemShouldBeExpanded + public bool GroupShouldBeExpandedInUI { get { @@ -120,6 +127,15 @@ public bool MenuItemShouldBeExpanded } } + /// + /// Gets or sets whether the group is expanded in the UI. + /// + public bool GroupIsExpandedInUI + { + get => _isExpanded; + set => SetProperty(ref _isExpanded, value); + } + private void Children_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.OldItems is not null) @@ -151,14 +167,14 @@ private void Child_PropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(GuiToolViewItem.IsRecommended) && IsAnyChildrenRecommended()) { - OnPropertyChanged(nameof(MenuItemShouldBeExpanded)); + OnPropertyChanged(nameof(GroupShouldBeExpandedInUI)); } } private void Child_GotSelected(object? sender, EventArgs e) { _childItemJustGotSelected = true; - OnPropertyChanged(nameof(MenuItemShouldBeExpanded)); + OnPropertyChanged(nameof(GroupShouldBeExpandedInUI)); } private bool IsAnyChildrenRecommended() diff --git a/src/app/dev/DevToys.Core/Tools/ViewItems/GuiToolViewItem.cs b/src/app/dev/DevToys.Core/Tools/ViewItems/GuiToolViewItem.cs index 32265a0362..5479d866df 100644 --- a/src/app/dev/DevToys.Core/Tools/ViewItems/GuiToolViewItem.cs +++ b/src/app/dev/DevToys.Core/Tools/ViewItems/GuiToolViewItem.cs @@ -7,7 +7,7 @@ namespace DevToys.Core.Tools.ViewItems; /// Represents a tool in the main menu. /// [DebuggerDisplay($"InternalComponentName = {{{nameof(ToolInstance)}.{nameof(GuiToolInstance.InternalComponentName)}}}")] -public sealed partial class GuiToolViewItem : ObservableObject +public sealed partial class GuiToolViewItem : ObservableObject, IItem { private readonly bool _showLongDisplayTitle; diff --git a/src/app/dev/DevToys.Core/Tools/ViewItems/SeparatorViewItem.cs b/src/app/dev/DevToys.Core/Tools/ViewItems/SeparatorViewItem.cs index 9898c8d02b..467539bad0 100644 --- a/src/app/dev/DevToys.Core/Tools/ViewItems/SeparatorViewItem.cs +++ b/src/app/dev/DevToys.Core/Tools/ViewItems/SeparatorViewItem.cs @@ -5,6 +5,6 @@ namespace DevToys.Core.Tools.ViewItems; /// /// Represents a separator in the main menu. /// -public sealed class SeparatorViewItem : ObservableObject +public sealed class SeparatorViewItem : ObservableObject, ISeparator { } diff --git a/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js b/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js deleted file mode 100644 index 760d8fe0ab..0000000000 --- a/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js +++ /dev/null @@ -1,544 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -//} -var callParentEventAsync = function (editorContext, name, parameters) { - return editorContext.Accessor.callEvent(name, parameters); -}; -var callParentActionWithParameters = function (editorContext, name, parameters) { - return editorContext.Accessor.callActionWithParameters(name, parameters); -}; -var getParentJsonValue = function (editorContext, name) { - return editorContext.Accessor.getJsonValue(name); -}; -var getParentValue = function (editorContext, name) { - return __awaiter(this, void 0, void 0, function* () { - var jsonString = yield editorContext.Accessor.getJsonValue(name); - var obj = JSON.parse(jsonString); - return obj; - }); -}; -const getAccentColorHtmlHex = function (editorContext) { - return editorContext.Theme.accentColorHtmlHex; -}; -const getThemeCurrentThemeName = function (editorContext) { - return editorContext.Theme.currentThemeName; -}; -const getThemeIsHighContrast = function (editorContext) { - return editorContext.Theme.isHighContrast; -}; -//} -//} -//} -/// -class EditorContext { - static registerEditorForElement(element, editor) { - var value = EditorContext.getEditorForElement(element); - value.editor = editor; - return value; - } - static getEditorForElement(element) { - var context = EditorContext._editors.get(element); - if (!context) { - context = new EditorContext(); - context.htmlElement = element; - EditorContext._editors.set(element, context); - } - return context; - } - constructor() { - this.modifingSelection = false; - this.contexts = {}; - this.decorations = []; - } -} -EditorContext._editors = new Map(); -/// -const createMonacoEditor = (basePath, element) => { - let editorContext = EditorContext.getEditorForElement(element); - let debug = editorContext.Debug; - debug.log("Create dynamic style element"); - var head = document.head || document.getElementsByTagName('head')[0]; - var style = document.createElement('style'); - style.id = 'dynamic'; - head.appendChild(style); - debug.log("Starting Monaco Load"); - window.require.config({ paths: { 'vs': `${basePath}/monaco-editor/min/vs` } }); - window.require(['vs/editor/editor.main'], function () { - return __awaiter(this, void 0, void 0, function* () { - yield initializeMonacoEditorAsync(editorContext); - }); - }); -}; -const initializeMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Determining if a standard editor or diff view editor should be created."); - let isDiffView = yield getParentValue(editorContext, "IsDiffViewMode"); - isDiffView = (isDiffView === "true" || isDiffView == true); - if (isDiffView) { - yield initializeDiffModeMonacoEditorAsync(editorContext); - } - else { - yield initializeStandardMonacoEditorAsync(editorContext); - } - //// Set theme - debug.log("Getting accessor theme value"); - let theme = yield getParentJsonValue(editorContext, "ActualTheme"); - switch (theme) { - case "0": - theme = "Default"; - break; - case "1": - theme = "Light"; - break; - case "2": - theme = "Dark"; - break; - default: - debug.log("Unknown theme"); - } - debug.log("Current theme value - " + theme); - if (theme == "Default") { - debug.log("Loading default theme"); - theme = yield getThemeCurrentThemeName(editorContext); - } - debug.log("Changing theme"); - setTheme(editorContext, yield getAccentColorHtmlHex(editorContext)); - changeTheme(editorContext, theme, yield getThemeIsHighContrast(editorContext)); - // Update Monaco Size when we receive a window resize event - debug.log("Listen for resize events on the window and resize the editor"); - window.addEventListener("resize", () => { - editorContext.editor.layout(); - }); - // Disable WebView Scrollbar so Monaco Scrollbar can do heavy lifting - document.body.style.overflow = 'hidden'; - // Callback to Parent that we're loaded - debug.log("Loaded Monaco"); - accessor.callAction("Loaded"); - debug.log("Ending Monaco Load"); -}); -const initializeStandardMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Grabbing Monaco Options"); - // link:CodeEditor.Options - let opt = yield getOptions(editorContext); - debug.log("Getting Parent Text value"); - // link:CodeEditor.Text - opt["value"] = yield getParentValue(editorContext, "Text"); - debug.log("Creating Editor"); - const editor = monaco.editor.create(editorContext.htmlElement, opt); - EditorContext.registerEditorForElement(editorContext.htmlElement, editor); - editorContext.standaloneEditor = editor; - debug.log("Getting & Configuring Editor model"); - let model = editor.getModel(); - model.updateOptions({ - bracketColorizationOptions: { enabled: true } - }); - editorContext.model = model; - // Listen for Content Changes - debug.log("Listening for changes in the editor model - " + (!model)); - model.onDidChangeContent((event) => __awaiter(this, void 0, void 0, function* () { - // link:CodeEditor.Text - yield accessor.setValue("Text", stringifyForMarshalling(model.getValue())); - })); - // Listen for Selection Changes - debug.log("Listening for changes in the editor selection"); - editor.onDidChangeCursorSelection((event) => __awaiter(this, void 0, void 0, function* () { - if (!editorContext.modifingSelection) { - // link:CodeEditor.SelectedText - yield accessor.setValue("SelectedText", stringifyForMarshalling(model.getValueInRange(event.selection))); - // link:CodeEditor.SelectedRange of type Selection - yield accessor.setValueWithType("SelectedRange", stringifyForMarshalling(JSON.stringify(event.selection)), "Selection"); - } - })); - // Listen for focus changes. - debug.log("Listen for focus events"); - editorContext.standaloneEditor.onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.standaloneEditor.onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); -}); -const initializeDiffModeMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Grabbing Monaco Options"); - // link:CodeEditor.DiffOptions - let opt = yield getDiffOptions(editorContext); - debug.log("Creating Diff Editor"); - const editor = monaco.editor.createDiffEditor(editorContext.htmlElement, opt); - EditorContext.registerEditorForElement(editorContext.htmlElement, editor); - editorContext.diffEditor = editor; - debug.log("Getting & Configuring Diff Editor model"); - let originalModel = monaco.editor.createModel("", "text/plain"); - let modifiedModel = monaco.editor.createModel("", "text/plain"); - editor.setModel({ - original: originalModel, - modified: modifiedModel - }); - // Listen for focus changes. - debug.log("Listen for focus events"); - editorContext.diffEditor.getOriginalEditor().onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.diffEditor.getModifiedEditor().onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.diffEditor.getOriginalEditor().onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); - editorContext.diffEditor.getModifiedEditor().onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); -}); -/// -const registerHoverProvider = function (editorContext, languageId) { - return monaco.languages.registerHoverProvider(languageId, { - provideHover: function (model, position) { - return callParentEventAsync(editorContext, "HoverProvider" + languageId, [JSON.stringify(position)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -const addAction = function (editorContext, action) { - action.run = function (ed) { - editorContext.Accessor.callAction("Action" + action.id); - }; - if (editorContext.standaloneEditor != null) { - editorContext.standaloneEditor.addAction(action); - } - else { - editorContext.diffEditor.addAction(action); - } -}; -const addCommand = function (editorContext, keybindingStr, handlerName, context) { - if (editorContext.standaloneEditor != null) { - return editorContext.standaloneEditor.addCommand(parseInt(keybindingStr), function () { - const objs = []; - if (arguments) { // Use arguments as Monaco will pass each as it's own parameter, so we don't know how many that may be. - for (let i = 1; i < arguments.length; i++) { // Skip first one as that's the sender? - objs.push(JSON.stringify(arguments[i])); - } - } - editorContext.Accessor.callActionWithParameters(handlerName, objs); - }, context); - } - else { - return editorContext.diffEditor.addCommand(parseInt(keybindingStr), function () { - const objs = []; - if (arguments) { // Use arguments as Monaco will pass each as it's own parameter, so we don't know how many that may be. - for (let i = 1; i < arguments.length; i++) { // Skip first one as that's the sender? - objs.push(JSON.stringify(arguments[i])); - } - } - editorContext.Accessor.callActionWithParameters(handlerName, objs); - }, context); - } -}; -const createContext = function (editorContext, context) { - if (context) { - if (editorContext.standaloneEditor != null) { - editorContext.contexts[context.key] = editorContext.standaloneEditor.createContextKey(context.key, context.defaultValue); - } - else { - editorContext.contexts[context.key] = editorContext.diffEditor.createContextKey(context.key, context.defaultValue); - } - } -}; -const updateContext = function (editorContext, key, value) { - editorContext.contexts[key].set(value); -}; -// link:CodeEditor.cs:updateContent -const updateContent = function (editorContext, content) { - // Need to ignore updates from us notifying of a change - if (content !== editorContext.model.getValue()) { - editorContext.model.setValue(content); - } -}; -// link:CodeEditor.cs:updateDiffContent -var updateDiffContent = function (editorContext, left, right) { - var diffModel = editorContext.model; - // Need to ignore updates from us notifying of a change - if (left != diffModel.original.getValue()) { - diffModel.original.setValue(left); - } - if (right != diffModel.modified.getValue()) { - diffModel.modified.setValue(right); - } -}; -const updateDecorations = function (editorContext, newHighlights) { - if (editorContext.standaloneEditor != null) { - if (newHighlights) { - editorContext.decorations = editorContext.standaloneEditor.deltaDecorations(editorContext.decorations, newHighlights); - } - else { - editorContext.decorations = editorContext.standaloneEditor.deltaDecorations(editorContext.decorations, []); - } - } -}; -const updateStyle = function (innerStyle) { - var style = document.getElementById("dynamic"); - style.innerHTML = innerStyle; -}; -const getOptions = function (editorContext) { - let opt = null; - try { - opt = getParentValue(editorContext, "Options"); - } - finally { - } - return opt; -}; -var getDiffOptions = function (editorContext) { - let opt = null; - try { - opt = getParentValue(editorContext, "DiffOptions"); - } - finally { - } - return opt; -}; -const updateOptions = function (editorContext, opt) { - if (opt !== null && typeof opt === "object") { - editorContext.editor.updateOptions(opt); - } -}; -var updateDiffOptions = function (editorContext, opt) { - if (opt !== null && typeof opt === "object") { - editorContext.diffEditor.updateOptions(opt); - } -}; -const updateLanguage = function (editorContext, language) { - monaco.editor.setModelLanguage(editorContext.model, language); -}; -const changeTheme = function (editorContext, theme, highcontrast) { - let newTheme = 'devtoys'; - if (highcontrast == "True" || highcontrast == "true") { - newTheme = 'hc-black'; - } - else if (theme == "Dark") { - newTheme = 'devtoys-dark'; - } - monaco.editor.setTheme(newTheme); -}; -var setTheme = function (editorContext, accentColor) { - // Define themes - // https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-exposed-colors - // remove quotes. - accentColor = accentColor.replace(/"/g, ''); - monaco.editor.defineTheme('devtoys-dark', { - base: 'vs-dark', - inherit: true, - rules: [], - colors: { - 'foreground': '#FFFFFF', - 'editor.foreground': '#FFFFFF', - 'editor.background': '#00000000', - 'editor.lineHighlightBackground': '#FFFFFF00', - 'editor.lineHighlightBorder': '#FFFFFF19', - 'editorLineNumber.foreground': '#EEEEEE99', - 'editorLineNumber.activeForeground': '#EEEEEEFF', - 'editor.inactiveSelectionBackground': '#00000000', - 'editor.selectionForeground': '#FFFFFF', - 'editor.selectionBackground': accentColor, - 'editorWidget.background': '#252526' - } - }); - monaco.editor.defineTheme('devtoys', { - base: 'vs', - inherit: true, - rules: [], - colors: { - 'foreground': '#000000', - 'editor.foreground': '#000000', - 'editor.background': '#FFFFFF00', - 'editor.lineHighlightBackground': '#00000000', - 'editor.lineHighlightBorder': '#00000019', - 'editorLineNumber.foreground': '#00000099', - 'editorLineNumber.activeForeground': '#000000FF', - 'editor.inactiveSelectionBackground': '#00000000', - 'editor.selectionForeground': '#000000', - 'editor.selectionBackground': accentColor, - 'editorWidget.background': '#F3F3F3' - } - }); -}; -const keyDown = function (element, event) { - return __awaiter(this, void 0, void 0, function* () { - //Debug.log("Key Down:" + event.keyCode + " " + event.ctrlKey); - //const result = await editorContext.Keyboard.keyDown(event.keyCode, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey); - //if (result) { - // event.cancelBubble = true; - // event.preventDefault(); - // event.stopPropagation(); - // event.stopImmediatePropagation(); - // return false; - //} - }); -}; -const stringifyForMarshalling = (value) => sanitize(value); -const sanitize = (jsonString) => { - if (jsonString == null) { - //console.log('Sanitized is null'); - return null; - } - const replacements = "%&\\\"'{}:,"; - for (let i = 0; i < replacements.length; i++) { - jsonString = replaceAll(jsonString, replacements.charAt(i), `%${replacements.charCodeAt(i)}`); - } - //console.log('Sanitized: ' + jsonString); - return jsonString; -}; -const replaceAll = (str, find, rep) => { - if (find == "\\") { - find = "\\\\"; - } - return (`${str}`).replace(new RegExp(find, "g"), rep); -}; -/// -function isTextEdit(edit) { - return edit.edit !== undefined; -} -const registerCodeActionProvider = function (editorContext, languageId) { - return monaco.languages.registerCodeActionProvider(languageId, { - provideCodeActions: function (model, range, context, token) { - return callParentEventAsync(editorContext, "ProvideCodeActions" + languageId, [JSON.stringify(range), JSON.stringify(context)]).then(result => { - if (result) { - const list = JSON.parse(result); - // Need to add in the model.uri to any edits to connect the dots - if (list.actions && - list.actions.length > 0) { - list.actions.forEach((action) => { - if (action.edit && - action.edit.edits && - action.edit.edits.length > 0) { - action.edit.edits.forEach((inneredit) => { - if (isTextEdit(inneredit)) { - inneredit.resource = model.uri; - } - }); - } - }); - } - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - }); - }, - }); -}; -/// -const registerCodeLensProvider = function (editorContext, any, languageId) { - return monaco.languages.registerCodeLensProvider(languageId, { - provideCodeLenses: function (model, token) { - return callParentEventAsync(editorContext, "ProvideCodeLenses" + languageId, []).then(result => { - if (result) { - const list = JSON.parse(result); - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - return null; - }); - }, - resolveCodeLens: function (model, codeLens, token) { - return callParentEventAsync(editorContext, "ResolveCodeLens" + languageId, [JSON.stringify(codeLens)]).then(result => { - if (result) { - return JSON.parse(result); - } - return null; - }); - } - // TODO: onDidChange, don't know what this does. - }); -}; -/// -const registerColorProvider = function (editorContext, languageId) { - return monaco.languages.registerColorProvider(languageId, { - provideColorPresentations: function (model, colorInfo, token) { - return callParentEventAsync(editorContext, "ProvideColorPresentations" + languageId, [JSON.stringify(colorInfo)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - }, - provideDocumentColors: function (model, token) { - return callParentEventAsync(editorContext, "ProvideDocumentColors" + languageId, []).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -/// -const registerCompletionItemProvider = function (editorContext, languageId, characters) { - return monaco.languages.registerCompletionItemProvider(languageId, { - triggerCharacters: characters, - provideCompletionItems: function (model, position, context, token) { - return callParentEventAsync(editorContext, "CompletionItemProvider" + languageId, [JSON.stringify(position), JSON.stringify(context)]).then(result => { - if (result) { - const list = JSON.parse(result); - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - }); - }, - resolveCompletionItem: function (item, token) { - return callParentEventAsync(editorContext, "CompletionItemRequested" + languageId, [JSON.stringify(item)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -/// -// link:CodeEditor.Properties.cs:updateSelectedContent -const updateSelectedContent = function (element, content) { - var editorContext = EditorContext.getEditorForElement(element); - let selection = editorContext.editor.getSelection(); - // Need to ignore updates from us notifying of a change - if (content != editorContext.model.getValueInRange(selection)) { - editorContext.modifingSelection = true; - let range = new monaco.Range(selection.startLineNumber, selection.startColumn, selection.endLineNumber, selection.endColumn); - let op = { identifier: { major: 1, minor: 1 }, range, text: content, forceMoveMarkers: true }; - // Make change to selection - //TODO how to properly fix this code? - //model.pushEditOperations([], [op]); - editorContext.model.pushEditOperations([], [op], null); - // Update selection to new text. - const newEndLineNumber = selection.startLineNumber + content.split('\r').length - 1; // TODO: Not sure if line end is situational/platform specific... investigate more. - const newEndColumn = (selection.startLineNumber === selection.endLineNumber) - ? selection.startColumn + content.length - : content.length - content.lastIndexOf('\r'); - selection = selection.setEndPosition(newEndLineNumber, newEndColumn); - // Update other selection bound for direction. - //TODO how to properly fix this code? - selection = selection.setEndPosition(selection.endLineNumber, selection.endColumn); - //if (selection.getDirection() == monaco.SelectionDirection.LTR) { - // selection.positionColumn = selection.endColumn; - // selection.positionLineNumber = selection.endLineNumber; - //} else { - // selection.selectionStartColumn = selection.endColumn; - // selection.selectionStartLineNumber = selection.endLineNumber; - //} - editorContext.modifingSelection = false; - editorContext.editor.setSelection(selection); - } -}; -//# sourceMappingURL=uno-monaco-helpers.g.js.map \ No newline at end of file diff --git a/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js.map b/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js.map deleted file mode 100644 index d4711dde69..0000000000 --- a/src/app/dev/DevToys.MonacoEditor/WasmScripts/UWP/uno-monaco-helpers.g.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"uno-monaco-helpers.g.js","sourceRoot":"","sources":["../../ts-helpermethods/ts-helpermethods-UWP/Monaco.Helpers.ThemeAccessor.ts","../../ts-helpermethods/ts-helpermethods-UWP/asyncCallbackHelpers.ts","../../ts-helpermethods/Monaco.Helpers.DebugLogger.ts","../../ts-helpermethods/Monaco.Helpers.KeyboardListener.ts","../../ts-helpermethods/Monaco.Helpers.ParentAccessor.ts","../../ts-helpermethods/editorContext.ts","../../ts-helpermethods/monacoInitializer.ts","../../ts-helpermethods/otherScriptsToBeOrganized.ts","../../ts-helpermethods/registerCodeActionProvider.ts","../../ts-helpermethods/registerCodeLensProvider.ts","../../ts-helpermethods/registerColorProvider.ts","../../ts-helpermethods/registerCompletionItemProvider.ts","../../ts-helpermethods/updateSelection.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js b/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js deleted file mode 100644 index a5e2defa89..0000000000 --- a/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js +++ /dev/null @@ -1,610 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -//} -nextAsync = 1; -asyncCallbackMap = {}; -nextReturn = 1; -returnValueCallbackMap = {}; -const asyncCallback = (promiseId, parameter) => { - const promise = asyncCallbackMap[promiseId]; - if (promise) { - //console.log('Async response: ' + parameter); - promise(parameter); - } -}; -const returnValueCallback = (returnId, returnValue) => { - //console.log('Return value for id ' + returnId + ' is ' + returnValue); - returnValueCallbackMap[returnId] = returnValue; -}; -const invokeAsyncMethod = (syncMethod) => { - if (nextAsync == null) { - nextAsync = 0; - } - if (asyncCallbackMap == null) { - asyncCallbackMap = {}; - } - const promise = new Promise((resolve, reject) => { - var nextId = nextAsync++; - asyncCallbackMap[nextId] = resolve; - syncMethod(`${nextId}`); - }); - return promise; -}; -const desantize = (parameter) => { - //System.Diagnostics.Debug.WriteLine($"Encoded String: {parameter}"); - if (parameter == null) - return parameter; - const replacements = "&\\\"'{}:,%"; - //System.Diagnostics.Debug.WriteLine($"Replacements: >{replacements}<"); - for (let i = 0; i < replacements.length; i++) { - //console.log("Replacing: >%" + replacements.charCodeAt(i) + "< with >" + replacements.charAt(i) + "< "); - parameter = replaceAll(parameter, "%" + replacements.charCodeAt(i), replacements.charAt(i)); - } - //console.log("Decoded String: " + parameter ); - return parameter; -}; -const invokeWithReturnValue = (methodToInvoke) => { - const nextId = nextReturn++; - methodToInvoke(nextId + ''); - var json = returnValueCallbackMap[nextId]; - //console.log('Return json ' + json); - json = desantize(json); - return json; -}; -const getParentValue = (editorContext, name) => { - return new Promise((resolve, reject) => { - const jsonString = invokeWithReturnValue((returnId) => editorContext.Accessor.getJsonValue(name, returnId)); - const obj = JSON.parse(jsonString); - resolve(obj); - }); -}; -const getParentJsonValue = function (editorContext, name) { - return new Promise((resolve, reject) => { - const json = invokeWithReturnValue((returnId) => editorContext.Accessor.getJsonValue(name, returnId)); - resolve(json); - }); -}; -const callParentEventAsync = (editorContext, name, parameters) => invokeAsyncMethod((promiseId) => __awaiter(this, void 0, void 0, function* () { - let result = yield editorContext.Accessor.callEvent(name, promiseId, parameters != null && parameters.length > 0 ? stringifyForMarshalling(parameters[0]) : null, parameters != null && parameters.length > 1 ? stringifyForMarshalling(parameters[1]) : null); - if (result) { - console.log('Parent event result: ' + name + ' - ' + result); - result = desantize(result); - console.log('Desanitized: ' + name + ' - ' + result); - } - else { - console.log('No Parent event result for ' + name); - } - return result; -})); -const callParentActionWithParameters = (name, parameters) => Parent.callActionWithParameters(name, parameters != null && parameters.length > 0 ? stringifyForMarshalling(parameters[0]) : null, parameters != null && parameters.length > 1 ? stringifyForMarshalling(parameters[1]) : null); -const getAccentColorHtmlHex = function (editorContext) { - return new Promise((resolve, reject) => { - resolve(invokeWithReturnValue((returnId) => editorContext.Theme.getAccentColorHtmlHex(returnId))); - }); -}; -const getThemeCurrentThemeName = function (editorContext) { - return new Promise((resolve, reject) => { - resolve(invokeWithReturnValue((returnId) => editorContext.Theme.getCurrentThemeName(returnId))); - }); -}; -const getThemeIsHighContrast = function (editorContext) { - return new Promise((resolve, reject) => { - resolve(invokeWithReturnValue((returnId) => editorContext.Theme.getIsHighContrast(returnId)) == "true"); - }); -}; -//} -//} -//} -/// -class EditorContext { - static registerEditorForElement(element, editor) { - var value = EditorContext.getEditorForElement(element); - value.editor = editor; - return value; - } - static getEditorForElement(element) { - var context = EditorContext._editors.get(element); - if (!context) { - context = new EditorContext(); - context.htmlElement = element; - EditorContext._editors.set(element, context); - } - return context; - } - constructor() { - this.modifingSelection = false; - this.contexts = {}; - this.decorations = []; - } -} -EditorContext._editors = new Map(); -/// -const createMonacoEditor = (basePath, element) => { - let editorContext = EditorContext.getEditorForElement(element); - let debug = editorContext.Debug; - debug.log("Create dynamic style element"); - var head = document.head || document.getElementsByTagName('head')[0]; - var style = document.createElement('style'); - style.id = 'dynamic'; - head.appendChild(style); - debug.log("Starting Monaco Load"); - window.require.config({ paths: { 'vs': `${basePath}/monaco-editor/min/vs` } }); - window.require(['vs/editor/editor.main'], function () { - return __awaiter(this, void 0, void 0, function* () { - yield initializeMonacoEditorAsync(editorContext); - }); - }); -}; -const initializeMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Determining if a standard editor or diff view editor should be created."); - let isDiffView = yield getParentValue(editorContext, "IsDiffViewMode"); - isDiffView = (isDiffView === "true" || isDiffView == true); - if (isDiffView) { - yield initializeDiffModeMonacoEditorAsync(editorContext); - } - else { - yield initializeStandardMonacoEditorAsync(editorContext); - } - //// Set theme - debug.log("Getting accessor theme value"); - let theme = yield getParentJsonValue(editorContext, "ActualTheme"); - switch (theme) { - case "0": - theme = "Default"; - break; - case "1": - theme = "Light"; - break; - case "2": - theme = "Dark"; - break; - default: - debug.log("Unknown theme"); - } - debug.log("Current theme value - " + theme); - if (theme == "Default") { - debug.log("Loading default theme"); - theme = yield getThemeCurrentThemeName(editorContext); - } - debug.log("Changing theme"); - setTheme(editorContext, yield getAccentColorHtmlHex(editorContext)); - changeTheme(editorContext, theme, yield getThemeIsHighContrast(editorContext)); - // Update Monaco Size when we receive a window resize event - debug.log("Listen for resize events on the window and resize the editor"); - window.addEventListener("resize", () => { - editorContext.editor.layout(); - }); - // Disable WebView Scrollbar so Monaco Scrollbar can do heavy lifting - document.body.style.overflow = 'hidden'; - // Callback to Parent that we're loaded - debug.log("Loaded Monaco"); - accessor.callAction("Loaded"); - debug.log("Ending Monaco Load"); -}); -const initializeStandardMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Grabbing Monaco Options"); - // link:CodeEditor.Options - let opt = yield getOptions(editorContext); - debug.log("Getting Parent Text value"); - // link:CodeEditor.Text - opt["value"] = yield getParentValue(editorContext, "Text"); - debug.log("Creating Editor"); - const editor = monaco.editor.create(editorContext.htmlElement, opt); - EditorContext.registerEditorForElement(editorContext.htmlElement, editor); - editorContext.standaloneEditor = editor; - debug.log("Getting & Configuring Editor model"); - let model = editor.getModel(); - model.updateOptions({ - bracketColorizationOptions: { enabled: true } - }); - editorContext.model = model; - // Listen for Content Changes - debug.log("Listening for changes in the editor model - " + (!model)); - model.onDidChangeContent((event) => __awaiter(this, void 0, void 0, function* () { - // link:CodeEditor.Text - yield accessor.setValue("Text", stringifyForMarshalling(model.getValue())); - })); - // Listen for Selection Changes - debug.log("Listening for changes in the editor selection"); - editor.onDidChangeCursorSelection((event) => __awaiter(this, void 0, void 0, function* () { - if (!editorContext.modifingSelection) { - // link:CodeEditor.SelectedText - yield accessor.setValue("SelectedText", stringifyForMarshalling(model.getValueInRange(event.selection))); - // link:CodeEditor.SelectedRange of type Selection - yield accessor.setValueWithType("SelectedRange", stringifyForMarshalling(JSON.stringify(event.selection)), "Selection"); - } - })); - // Listen for focus changes. - debug.log("Listen for focus events"); - editorContext.standaloneEditor.onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.standaloneEditor.onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); -}); -const initializeDiffModeMonacoEditorAsync = (editorContext) => __awaiter(this, void 0, void 0, function* () { - let debug = editorContext.Debug; - let accessor = editorContext.Accessor; - debug.log("Grabbing Monaco Options"); - // link:CodeEditor.DiffOptions - let opt = yield getDiffOptions(editorContext); - debug.log("Creating Diff Editor"); - const editor = monaco.editor.createDiffEditor(editorContext.htmlElement, opt); - EditorContext.registerEditorForElement(editorContext.htmlElement, editor); - editorContext.diffEditor = editor; - debug.log("Getting & Configuring Diff Editor model"); - let originalModel = monaco.editor.createModel("", "text/plain"); - let modifiedModel = monaco.editor.createModel("", "text/plain"); - editor.setModel({ - original: originalModel, - modified: modifiedModel - }); - // Listen for focus changes. - debug.log("Listen for focus events"); - editorContext.diffEditor.getOriginalEditor().onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.diffEditor.getModifiedEditor().onDidFocusEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("GotFocus"); - })); - editorContext.diffEditor.getOriginalEditor().onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); - editorContext.diffEditor.getModifiedEditor().onDidBlurEditorWidget((event) => __awaiter(this, void 0, void 0, function* () { - accessor.callAction("LostFocus"); - })); -}); -/// -const registerHoverProvider = function (editorContext, languageId) { - return monaco.languages.registerHoverProvider(languageId, { - provideHover: function (model, position) { - return callParentEventAsync(editorContext, "HoverProvider" + languageId, [JSON.stringify(position)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -const addAction = function (editorContext, action) { - action.run = function (ed) { - editorContext.Accessor.callAction("Action" + action.id); - }; - if (editorContext.standaloneEditor != null) { - editorContext.standaloneEditor.addAction(action); - } - else { - editorContext.diffEditor.addAction(action); - } -}; -const addCommand = function (editorContext, keybindingStr, handlerName, context) { - if (editorContext.standaloneEditor != null) { - return editorContext.standaloneEditor.addCommand(parseInt(keybindingStr), function () { - const objs = []; - if (arguments) { // Use arguments as Monaco will pass each as it's own parameter, so we don't know how many that may be. - for (let i = 1; i < arguments.length; i++) { // Skip first one as that's the sender? - objs.push(JSON.stringify(arguments[i])); - } - } - editorContext.Accessor.callActionWithParameters(handlerName, objs); - }, context); - } - else { - return editorContext.diffEditor.addCommand(parseInt(keybindingStr), function () { - const objs = []; - if (arguments) { // Use arguments as Monaco will pass each as it's own parameter, so we don't know how many that may be. - for (let i = 1; i < arguments.length; i++) { // Skip first one as that's the sender? - objs.push(JSON.stringify(arguments[i])); - } - } - editorContext.Accessor.callActionWithParameters(handlerName, objs); - }, context); - } -}; -const createContext = function (editorContext, context) { - if (context) { - if (editorContext.standaloneEditor != null) { - editorContext.contexts[context.key] = editorContext.standaloneEditor.createContextKey(context.key, context.defaultValue); - } - else { - editorContext.contexts[context.key] = editorContext.diffEditor.createContextKey(context.key, context.defaultValue); - } - } -}; -const updateContext = function (editorContext, key, value) { - editorContext.contexts[key].set(value); -}; -// link:CodeEditor.cs:updateContent -const updateContent = function (editorContext, content) { - // Need to ignore updates from us notifying of a change - if (content !== editorContext.model.getValue()) { - editorContext.model.setValue(content); - } -}; -// link:CodeEditor.cs:updateDiffContent -var updateDiffContent = function (editorContext, left, right) { - var diffModel = editorContext.model; - // Need to ignore updates from us notifying of a change - if (left != diffModel.original.getValue()) { - diffModel.original.setValue(left); - } - if (right != diffModel.modified.getValue()) { - diffModel.modified.setValue(right); - } -}; -const updateDecorations = function (editorContext, newHighlights) { - if (editorContext.standaloneEditor != null) { - if (newHighlights) { - editorContext.decorations = editorContext.standaloneEditor.deltaDecorations(editorContext.decorations, newHighlights); - } - else { - editorContext.decorations = editorContext.standaloneEditor.deltaDecorations(editorContext.decorations, []); - } - } -}; -const updateStyle = function (innerStyle) { - var style = document.getElementById("dynamic"); - style.innerHTML = innerStyle; -}; -const getOptions = function (editorContext) { - let opt = null; - try { - opt = getParentValue(editorContext, "Options"); - } - finally { - } - return opt; -}; -var getDiffOptions = function (editorContext) { - let opt = null; - try { - opt = getParentValue(editorContext, "DiffOptions"); - } - finally { - } - return opt; -}; -const updateOptions = function (editorContext, opt) { - if (opt !== null && typeof opt === "object") { - editorContext.editor.updateOptions(opt); - } -}; -var updateDiffOptions = function (editorContext, opt) { - if (opt !== null && typeof opt === "object") { - editorContext.diffEditor.updateOptions(opt); - } -}; -const updateLanguage = function (editorContext, language) { - monaco.editor.setModelLanguage(editorContext.model, language); -}; -const changeTheme = function (editorContext, theme, highcontrast) { - let newTheme = 'devtoys'; - if (highcontrast == "True" || highcontrast == "true") { - newTheme = 'hc-black'; - } - else if (theme == "Dark") { - newTheme = 'devtoys-dark'; - } - monaco.editor.setTheme(newTheme); -}; -var setTheme = function (editorContext, accentColor) { - // Define themes - // https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-exposed-colors - // remove quotes. - accentColor = accentColor.replace(/"/g, ''); - monaco.editor.defineTheme('devtoys-dark', { - base: 'vs-dark', - inherit: true, - rules: [], - colors: { - 'foreground': '#FFFFFF', - 'editor.foreground': '#FFFFFF', - 'editor.background': '#00000000', - 'editor.lineHighlightBackground': '#FFFFFF00', - 'editor.lineHighlightBorder': '#FFFFFF19', - 'editorLineNumber.foreground': '#EEEEEE99', - 'editorLineNumber.activeForeground': '#EEEEEEFF', - 'editor.inactiveSelectionBackground': '#00000000', - 'editor.selectionForeground': '#FFFFFF', - 'editor.selectionBackground': accentColor, - 'editorWidget.background': '#252526' - } - }); - monaco.editor.defineTheme('devtoys', { - base: 'vs', - inherit: true, - rules: [], - colors: { - 'foreground': '#000000', - 'editor.foreground': '#000000', - 'editor.background': '#FFFFFF00', - 'editor.lineHighlightBackground': '#00000000', - 'editor.lineHighlightBorder': '#00000019', - 'editorLineNumber.foreground': '#00000099', - 'editorLineNumber.activeForeground': '#000000FF', - 'editor.inactiveSelectionBackground': '#00000000', - 'editor.selectionForeground': '#000000', - 'editor.selectionBackground': accentColor, - 'editorWidget.background': '#F3F3F3' - } - }); -}; -const keyDown = function (element, event) { - return __awaiter(this, void 0, void 0, function* () { - //Debug.log("Key Down:" + event.keyCode + " " + event.ctrlKey); - //const result = await editorContext.Keyboard.keyDown(event.keyCode, event.ctrlKey, event.shiftKey, event.altKey, event.metaKey); - //if (result) { - // event.cancelBubble = true; - // event.preventDefault(); - // event.stopPropagation(); - // event.stopImmediatePropagation(); - // return false; - //} - }); -}; -const stringifyForMarshalling = (value) => sanitize(value); -const sanitize = (jsonString) => { - if (jsonString == null) { - //console.log('Sanitized is null'); - return null; - } - const replacements = "%&\\\"'{}:,"; - for (let i = 0; i < replacements.length; i++) { - jsonString = replaceAll(jsonString, replacements.charAt(i), `%${replacements.charCodeAt(i)}`); - } - //console.log('Sanitized: ' + jsonString); - return jsonString; -}; -const replaceAll = (str, find, rep) => { - if (find == "\\") { - find = "\\\\"; - } - return (`${str}`).replace(new RegExp(find, "g"), rep); -}; -/// -function isTextEdit(edit) { - return edit.edit !== undefined; -} -const registerCodeActionProvider = function (editorContext, languageId) { - return monaco.languages.registerCodeActionProvider(languageId, { - provideCodeActions: function (model, range, context, token) { - return callParentEventAsync(editorContext, "ProvideCodeActions" + languageId, [JSON.stringify(range), JSON.stringify(context)]).then(result => { - if (result) { - const list = JSON.parse(result); - // Need to add in the model.uri to any edits to connect the dots - if (list.actions && - list.actions.length > 0) { - list.actions.forEach((action) => { - if (action.edit && - action.edit.edits && - action.edit.edits.length > 0) { - action.edit.edits.forEach((inneredit) => { - if (isTextEdit(inneredit)) { - inneredit.resource = model.uri; - } - }); - } - }); - } - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - }); - }, - }); -}; -/// -const registerCodeLensProvider = function (editorContext, any, languageId) { - return monaco.languages.registerCodeLensProvider(languageId, { - provideCodeLenses: function (model, token) { - return callParentEventAsync(editorContext, "ProvideCodeLenses" + languageId, []).then(result => { - if (result) { - const list = JSON.parse(result); - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - return null; - }); - }, - resolveCodeLens: function (model, codeLens, token) { - return callParentEventAsync(editorContext, "ResolveCodeLens" + languageId, [JSON.stringify(codeLens)]).then(result => { - if (result) { - return JSON.parse(result); - } - return null; - }); - } - // TODO: onDidChange, don't know what this does. - }); -}; -/// -const registerColorProvider = function (editorContext, languageId) { - return monaco.languages.registerColorProvider(languageId, { - provideColorPresentations: function (model, colorInfo, token) { - return callParentEventAsync(editorContext, "ProvideColorPresentations" + languageId, [JSON.stringify(colorInfo)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - }, - provideDocumentColors: function (model, token) { - return callParentEventAsync(editorContext, "ProvideDocumentColors" + languageId, []).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -/// -const registerCompletionItemProvider = function (editorContext, languageId, characters) { - return monaco.languages.registerCompletionItemProvider(languageId, { - triggerCharacters: characters, - provideCompletionItems: function (model, position, context, token) { - return callParentEventAsync(editorContext, "CompletionItemProvider" + languageId, [JSON.stringify(position), JSON.stringify(context)]).then(result => { - if (result) { - const list = JSON.parse(result); - // Add dispose method for IDisposable that Monaco is looking for. - list.dispose = () => { }; - return list; - } - }); - }, - resolveCompletionItem: function (item, token) { - return callParentEventAsync(editorContext, "CompletionItemRequested" + languageId, [JSON.stringify(item)]).then(result => { - if (result) { - return JSON.parse(result); - } - }); - } - }); -}; -/// -// link:CodeEditor.Properties.cs:updateSelectedContent -const updateSelectedContent = function (element, content) { - var editorContext = EditorContext.getEditorForElement(element); - let selection = editorContext.editor.getSelection(); - // Need to ignore updates from us notifying of a change - if (content != editorContext.model.getValueInRange(selection)) { - editorContext.modifingSelection = true; - let range = new monaco.Range(selection.startLineNumber, selection.startColumn, selection.endLineNumber, selection.endColumn); - let op = { identifier: { major: 1, minor: 1 }, range, text: content, forceMoveMarkers: true }; - // Make change to selection - //TODO how to properly fix this code? - //model.pushEditOperations([], [op]); - editorContext.model.pushEditOperations([], [op], null); - // Update selection to new text. - const newEndLineNumber = selection.startLineNumber + content.split('\r').length - 1; // TODO: Not sure if line end is situational/platform specific... investigate more. - const newEndColumn = (selection.startLineNumber === selection.endLineNumber) - ? selection.startColumn + content.length - : content.length - content.lastIndexOf('\r'); - selection = selection.setEndPosition(newEndLineNumber, newEndColumn); - // Update other selection bound for direction. - //TODO how to properly fix this code? - selection = selection.setEndPosition(selection.endLineNumber, selection.endColumn); - //if (selection.getDirection() == monaco.SelectionDirection.LTR) { - // selection.positionColumn = selection.endColumn; - // selection.positionLineNumber = selection.endLineNumber; - //} else { - // selection.selectionStartColumn = selection.endColumn; - // selection.selectionStartLineNumber = selection.endLineNumber; - //} - editorContext.modifingSelection = false; - editorContext.editor.setSelection(selection); - } -}; -//# sourceMappingURL=uno-monaco-helpers.g.js.map \ No newline at end of file diff --git a/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js.map b/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js.map deleted file mode 100644 index 80a143348f..0000000000 --- a/src/app/dev/DevToys.MonacoEditor/WasmScripts/WASM/uno-monaco-helpers.g.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"uno-monaco-helpers.g.js","sourceRoot":"","sources":["../../ts-helpermethods/ts-helpermethods-Wasm/Monaco.Helpers.ThemeAccessor.ts","../../ts-helpermethods/ts-helpermethods-Wasm/asyncCallbackHelpers.ts","../../ts-helpermethods/Monaco.Helpers.DebugLogger.ts","../../ts-helpermethods/Monaco.Helpers.KeyboardListener.ts","../../ts-helpermethods/Monaco.Helpers.ParentAccessor.ts","../../ts-helpermethods/editorContext.ts","../../ts-helpermethods/monacoInitializer.ts","../../ts-helpermethods/otherScriptsToBeOrganized.ts","../../ts-helpermethods/registerCodeActionProvider.ts","../../ts-helpermethods/registerCodeLensProvider.ts","../../ts-helpermethods/registerColorProvider.ts","../../ts-helpermethods/registerCompletionItemProvider.ts","../../ts-helpermethods/updateSelection.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/app/dev/DevToys.Tools/Tools/Settings/SettingsGuiTool.cs b/src/app/dev/DevToys.Tools/Tools/Settings/SettingsGuiTool.cs index df7c621418..ca5c7564bf 100644 --- a/src/app/dev/DevToys.Tools/Tools/Settings/SettingsGuiTool.cs +++ b/src/app/dev/DevToys.Tools/Tools/Settings/SettingsGuiTool.cs @@ -92,7 +92,7 @@ public IUIElement View Button().Text("Bottom Left button"), Button().Text("Bottom Center button").OnClick(OnBottomCenterButtonClickAsync), Button().Text("Bottom Right button")), - SinglelineTextInput().CanCopyWhenEditable()); + SingleLineTextInput().CanCopyWhenEditable()); public void OnDataReceived(string dataTypeName, object? parsedData) { diff --git a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UIElementTemplateSelector.cs b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UIElementTemplateSelector.cs index 4065f4bd75..b2f7333795 100644 --- a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UIElementTemplateSelector.cs +++ b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UIElementTemplateSelector.cs @@ -55,7 +55,7 @@ internal sealed class UIElementTemplateSelector : DataTemplateSelector public DataTemplate UIMultilineTextInputTemplate { get; set; } = null!; /// - /// The data template used to display a . + /// The data template used to display a . /// public DataTemplate UISinglelineTextInputTemplate { get; set; } = null!; @@ -77,7 +77,7 @@ protected override DataTemplate SelectTemplateCore(object item, DependencyObject IUIDropDownList => UIDropDownListTemplate, IUIDiffTextInput => UIDiffTextInputTemplate, IUIMultilineLineTextInput => UIMultilineTextInputTemplate, - IUISinglelineTextInput => UISinglelineTextInputTemplate, + IUISingleLineTextInput => UISinglelineTextInputTemplate, _ => throw new NotSupportedException($"Gui Tool component of type '{item.GetType().FullName}' isn't supported.") }; diff --git a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UISinglelineTextInputPresenter.xaml.cs b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UISinglelineTextInputPresenter.xaml.cs index 26ac105453..f5da77658f 100644 --- a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UISinglelineTextInputPresenter.xaml.cs +++ b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UISinglelineTextInputPresenter.xaml.cs @@ -16,7 +16,7 @@ public UISinglelineTextInputPresenter() Unloaded += UISinglelineTextInputPresenter_Unloaded; } - internal IUISinglelineTextInput UISinglelineTextInput => (IUISinglelineTextInput)DataContext; + internal IUISingleLineTextInput UISinglelineTextInput => (IUISingleLineTextInput)DataContext; private void UISinglelineTextInputPresenter_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { diff --git a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UITextInputHeader.xaml.cs b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UITextInputHeader.xaml.cs index c32d62d2e5..0205f0710c 100644 --- a/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UITextInputHeader.xaml.cs +++ b/src/app/dev/DevToys.UI.Framework/Controls/GuiTool/UITextInputHeader.xaml.cs @@ -41,7 +41,7 @@ public UITextInputHeader() Unloaded += UITextInputHeader_Unloaded; } - internal IUISinglelineTextInput UITextInput => (IUISinglelineTextInput)DataContext; + internal IUISingleLineTextInput UITextInput => (IUISingleLineTextInput)DataContext; public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( diff --git a/src/app/dev/DevToys.UI/Views/MainWindow.xaml.cs b/src/app/dev/DevToys.UI/Views/MainWindow.xaml.cs index 9981143422..4ac6369124 100644 --- a/src/app/dev/DevToys.UI/Views/MainWindow.xaml.cs +++ b/src/app/dev/DevToys.UI/Views/MainWindow.xaml.cs @@ -93,7 +93,7 @@ private void MainWindow_Loaded(object sender, RoutedEventArgs e) // So we manually expand the items that should be expanded on load. foreach (INotifyPropertyChanged? item in ViewModel.HeaderAndBodyToolViewItems) { - if (item is GroupViewItem groupViewItem && groupViewItem.MenuItemShouldBeExpandedByDefault) + if (item is GroupViewItem groupViewItem && groupViewItem.GroupShouldBeExpandedByDefaultInUI) { var menuItem = MenuNavigationView.ContainerFromMenuItem(item) as NavigationViewItem; if (menuItem is not null) diff --git a/src/app/dev/platforms/desktop/DevToys.CLI/Program.cs b/src/app/dev/platforms/desktop/DevToys.CLI/Program.cs index c7d9d7c659..5b5da3ad0b 100644 --- a/src/app/dev/platforms/desktop/DevToys.CLI/Program.cs +++ b/src/app/dev/platforms/desktop/DevToys.CLI/Program.cs @@ -102,7 +102,7 @@ IEnumerable> commandLineTools private static CommandToICommandLineToolMap? CreateCommandForTool(Lazy commandLineTool) { - // Make sure the tool is supported by the current OS. If no platform is precised by the tool, + // Make sure the tool is supported by the current OS. If no platform is precise by the tool, // it means it's supported by every OS. if (!OSHelper.IsOsSupported(commandLineTool.Metadata.TargetPlatforms)) { diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/.eslintrc.json b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/.eslintrc.json new file mode 100644 index 0000000000..f67a849dd9 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/.eslintrc.json @@ -0,0 +1,38 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "overrides": [ + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "windows" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ] + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom.js new file mode 100644 index 0000000000..25623b81f0 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom.js @@ -0,0 +1,7 @@ +class DOM { + static setFocus(element) { + element.focus(); + } +} + +export default DOM; \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/data.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/data.js deleted file mode 100644 index 2c6a46e9b9..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/data.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/data.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -/** - * Constants - */ - -const elementMap = new Map() - -export default { - set(element, key, instance) { - if (!elementMap.has(element)) { - elementMap.set(element, new Map()) - } - - const instanceMap = elementMap.get(element) - - // make it clear we only want one instance per element - // can be removed later when multiple key/instances are fine to be used - if (!instanceMap.has(key) && instanceMap.size !== 0) { - // eslint-disable-next-line no-console - console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`) - return - } - - instanceMap.set(key, instance) - }, - - get(element, key) { - if (elementMap.has(element)) { - return elementMap.get(element).get(key) || null - } - - return null - }, - - remove(element, key) { - if (!elementMap.has(element)) { - return - } - - const instanceMap = elementMap.get(element) - - instanceMap.delete(key) - - // free up element references if there are no instances left for an element - if (instanceMap.size === 0) { - elementMap.delete(element) - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/event-handler.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/event-handler.js deleted file mode 100644 index 9876d7733d..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/event-handler.js +++ /dev/null @@ -1,320 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/event-handler.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { getjQuery } from '../util/index' - -/** - * Constants - */ - -const namespaceRegex = /[^.]*(?=\..*)\.|.*/ -const stripNameRegex = /\..*/ -const stripUidRegex = /::\d+$/ -const eventRegistry = {} // Events storage -let uidEvent = 1 -const customEvents = { - mouseenter: 'mouseover', - mouseleave: 'mouseout' -} - -const nativeEvents = new Set([ - 'click', - 'dblclick', - 'mouseup', - 'mousedown', - 'contextmenu', - 'mousewheel', - 'DOMMouseScroll', - 'mouseover', - 'mouseout', - 'mousemove', - 'selectstart', - 'selectend', - 'keydown', - 'keypress', - 'keyup', - 'orientationchange', - 'touchstart', - 'touchmove', - 'touchend', - 'touchcancel', - 'pointerdown', - 'pointermove', - 'pointerup', - 'pointerleave', - 'pointercancel', - 'gesturestart', - 'gesturechange', - 'gestureend', - 'focus', - 'blur', - 'change', - 'reset', - 'select', - 'submit', - 'focusin', - 'focusout', - 'load', - 'unload', - 'beforeunload', - 'resize', - 'move', - 'DOMContentLoaded', - 'readystatechange', - 'error', - 'abort', - 'scroll' -]) - -/** - * Private methods - */ - -function makeEventUid(element, uid) { - return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++ -} - -function getElementEvents(element) { - const uid = makeEventUid(element) - - element.uidEvent = uid - eventRegistry[uid] = eventRegistry[uid] || {} - - return eventRegistry[uid] -} - -function bootstrapHandler(element, fn) { - return function handler(event) { - hydrateObj(event, { delegateTarget: element }) - - if (handler.oneOff) { - EventHandler.off(element, event.type, fn) - } - - return fn.apply(element, [event]) - } -} - -function bootstrapDelegationHandler(element, selector, fn) { - return function handler(event) { - const domElements = element.querySelectorAll(selector) - - for (let { target } = event; target && target !== this; target = target.parentNode) { - for (const domElement of domElements) { - if (domElement !== target) { - continue - } - - hydrateObj(event, { delegateTarget: target }) - - if (handler.oneOff) { - EventHandler.off(element, event.type, selector, fn) - } - - return fn.apply(target, [event]) - } - } - } -} - -function findHandler(events, callable, delegationSelector = null) { - return Object.values(events) - .find(event => event.callable === callable && event.delegationSelector === delegationSelector) -} - -function normalizeParameters(originalTypeEvent, handler, delegationFunction) { - const isDelegated = typeof handler === 'string' - // todo: tooltip passes `false` instead of selector, so we need to check - const callable = isDelegated ? delegationFunction : (handler || delegationFunction) - let typeEvent = getTypeEvent(originalTypeEvent) - - if (!nativeEvents.has(typeEvent)) { - typeEvent = originalTypeEvent - } - - return [isDelegated, callable, typeEvent] -} - -function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { - if (typeof originalTypeEvent !== 'string' || !element) { - return - } - - let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction) - - // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position - // this prevents the handler from being dispatched the same way as mouseover or mouseout does - if (originalTypeEvent in customEvents) { - const wrapFunction = fn => { - return function (event) { - if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) { - return fn.call(this, event) - } - } - } - - callable = wrapFunction(callable) - } - - const events = getElementEvents(element) - const handlers = events[typeEvent] || (events[typeEvent] = {}) - const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null) - - if (previousFunction) { - previousFunction.oneOff = previousFunction.oneOff && oneOff - - return - } - - const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')) - const fn = isDelegated ? - bootstrapDelegationHandler(element, handler, callable) : - bootstrapHandler(element, callable) - - fn.delegationSelector = isDelegated ? handler : null - fn.callable = callable - fn.oneOff = oneOff - fn.uidEvent = uid - handlers[uid] = fn - - element.addEventListener(typeEvent, fn, isDelegated) -} - -function removeHandler(element, events, typeEvent, handler, delegationSelector) { - const fn = findHandler(events[typeEvent], handler, delegationSelector) - - if (!fn) { - return - } - - element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)) - delete events[typeEvent][fn.uidEvent] -} - -function removeNamespacedHandlers(element, events, typeEvent, namespace) { - const storeElementEvent = events[typeEvent] || {} - - for (const handlerKey of Object.keys(storeElementEvent)) { - if (handlerKey.includes(namespace)) { - const event = storeElementEvent[handlerKey] - removeHandler(element, events, typeEvent, event.callable, event.delegationSelector) - } - } -} - -function getTypeEvent(event) { - // allow to get the native events from namespaced events ('click.bs.button' --> 'click') - event = event.replace(stripNameRegex, '') - return customEvents[event] || event -} - -const EventHandler = { - on(element, event, handler, delegationFunction) { - addHandler(element, event, handler, delegationFunction, false) - }, - - one(element, event, handler, delegationFunction) { - addHandler(element, event, handler, delegationFunction, true) - }, - - off(element, originalTypeEvent, handler, delegationFunction) { - if (typeof originalTypeEvent !== 'string' || !element) { - return - } - - const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction) - const inNamespace = typeEvent !== originalTypeEvent - const events = getElementEvents(element) - const storeElementEvent = events[typeEvent] || {} - const isNamespace = originalTypeEvent.startsWith('.') - - if (typeof callable !== 'undefined') { - // Simplest case: handler is passed, remove that listener ONLY. - if (!Object.keys(storeElementEvent).length) { - return - } - - removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null) - return - } - - if (isNamespace) { - for (const elementEvent of Object.keys(events)) { - removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)) - } - } - - for (const keyHandlers of Object.keys(storeElementEvent)) { - const handlerKey = keyHandlers.replace(stripUidRegex, '') - - if (!inNamespace || originalTypeEvent.includes(handlerKey)) { - const event = storeElementEvent[keyHandlers] - removeHandler(element, events, typeEvent, event.callable, event.delegationSelector) - } - } - }, - - trigger(element, event, args) { - if (typeof event !== 'string' || !element) { - return null - } - - const $ = getjQuery() - const typeEvent = getTypeEvent(event) - const inNamespace = event !== typeEvent - - let jQueryEvent = null - let bubbles = true - let nativeDispatch = true - let defaultPrevented = false - - if (inNamespace && $) { - jQueryEvent = $.Event(event, args) - - $(element).trigger(jQueryEvent) - bubbles = !jQueryEvent.isPropagationStopped() - nativeDispatch = !jQueryEvent.isImmediatePropagationStopped() - defaultPrevented = jQueryEvent.isDefaultPrevented() - } - - let evt = new Event(event, { bubbles, cancelable: true }) - evt = hydrateObj(evt, args) - - if (defaultPrevented) { - evt.preventDefault() - } - - if (nativeDispatch) { - element.dispatchEvent(evt) - } - - if (evt.defaultPrevented && jQueryEvent) { - jQueryEvent.preventDefault() - } - - return evt - } -} - -function hydrateObj(obj, meta) { - for (const [key, value] of Object.entries(meta || {})) { - try { - obj[key] = value - } catch { - Object.defineProperty(obj, key, { - configurable: true, - get() { - return value - } - }) - } - } - - return obj -} - -export default EventHandler diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/manipulator.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/manipulator.js deleted file mode 100644 index 38ecfe4817..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/manipulator.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/manipulator.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -function normalizeData(value) { - if (value === 'true') { - return true - } - - if (value === 'false') { - return false - } - - if (value === Number(value).toString()) { - return Number(value) - } - - if (value === '' || value === 'null') { - return null - } - - if (typeof value !== 'string') { - return value - } - - try { - return JSON.parse(decodeURIComponent(value)) - } catch { - return value - } -} - -function normalizeDataKey(key) { - return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`) -} - -const Manipulator = { - setDataAttribute(element, key, value) { - element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value) - }, - - removeDataAttribute(element, key) { - element.removeAttribute(`data-bs-${normalizeDataKey(key)}`) - }, - - getDataAttributes(element) { - if (!element) { - return {} - } - - const attributes = {} - const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')) - - for (const key of bsKeys) { - let pureKey = key.replace(/^bs/, '') - pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length) - attributes[pureKey] = normalizeData(element.dataset[key]) - } - - return attributes - }, - - getDataAttribute(element, key) { - return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)) - } -} - -export default Manipulator diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/selector-engine.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/selector-engine.js deleted file mode 100644 index 1ba104f9e0..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/dom/selector-engine.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/selector-engine.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { isDisabled, isVisible } from '../util/index' - -/** - * Constants - */ - -const SelectorEngine = { - find(selector, element = document.documentElement) { - return [].concat(...Element.prototype.querySelectorAll.call(element, selector)) - }, - - findOne(selector, element = document.documentElement) { - return Element.prototype.querySelector.call(element, selector) - }, - - children(element, selector) { - return [].concat(...element.children).filter(child => child.matches(selector)) - }, - - parents(element, selector) { - const parents = [] - let ancestor = element.parentNode.closest(selector) - - while (ancestor) { - parents.push(ancestor) - ancestor = ancestor.parentNode.closest(selector) - } - - return parents - }, - - prev(element, selector) { - let previous = element.previousElementSibling - - while (previous) { - if (previous.matches(selector)) { - return [previous] - } - - previous = previous.previousElementSibling - } - - return [] - }, - // TODO: this is now unused; remove later along with prev() - next(element, selector) { - let next = element.nextElementSibling - - while (next) { - if (next.matches(selector)) { - return [next] - } - - next = next.nextElementSibling - } - - return [] - }, - - focusableChildren(element) { - const focusables = [ - 'a', - 'button', - 'input', - 'textarea', - 'select', - 'details', - '[tabindex]', - '[contenteditable="true"]' - ].map(selector => `${selector}:not([tabindex^="-"])`).join(',') - - return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)) - } -} - -export default SelectorEngine diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/index.esm.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/index.esm.js index 61f885b92f..28f2ab297c 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/index.esm.js +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/index.esm.js @@ -4,5 +4,5 @@ * -------------------------------------------------------------------------- */ -export { default as Collapse } from './src/collapse' -export { default as Sidebar } from './src/sidebar' +export { default as DOM } from "./dom"; +//export { default as Sidebar } from './src/sidebar' diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/base-component.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/base-component.js deleted file mode 100644 index c0674bc9df..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/base-component.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): base-component.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import Data from '../dom/data' -import { executeAfterTransition, getElement } from '../util/index' -import EventHandler from '../dom/event-handler' -import Config from '../util/config' - -/** - * Constants - */ - -const VERSION = '5.2.3' - -/** - * Class definition - */ - -class BaseComponent extends Config { - constructor(element, config) { - super() - - element = getElement(element) - if (!element) { - return - } - - this._element = element - this._config = this._getConfig(config) - - Data.set(this._element, this.constructor.DATA_KEY, this) - } - - // Public - dispose() { - Data.remove(this._element, this.constructor.DATA_KEY) - EventHandler.off(this._element, this.constructor.EVENT_KEY) - - for (const propertyName of Object.getOwnPropertyNames(this)) { - this[propertyName] = null - } - } - - _queueCallback(callback, element, isAnimated = true) { - executeAfterTransition(callback, element, isAnimated) - } - - _getConfig(config) { - config = this._mergeConfigObj(config, this._element) - config = this._configAfterMerge(config) - this._typeCheckConfig(config) - return config - } - - // Static - static getInstance(element) { - return Data.get(getElement(element), this.DATA_KEY) - } - - static getOrCreateInstance(element, config = {}) { - return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null) - } - - static get VERSION() { - return VERSION - } - - static get DATA_KEY() { - return `bs.${this.NAME}` - } - - static get EVENT_KEY() { - return `.${this.DATA_KEY}` - } - - static eventName(name) { - return `${name}${this.EVENT_KEY}` - } -} - -export default BaseComponent diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/collapse.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/collapse.js deleted file mode 100644 index 459a5d9a62..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/collapse.js +++ /dev/null @@ -1,305 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): collapse.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { - defineJQueryPlugin, - getElement, - getElementFromSelector, - getSelectorFromElement, - reflow -} from '../util/index' -import EventHandler from '../dom/event-handler' -import SelectorEngine from '../dom/selector-engine' -import BaseComponent from './base-component' - -/** - * Constants - */ - -const NAME = 'collapse' -const DATA_KEY = 'bs.collapse' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' - -const EVENT_SHOW = `show${EVENT_KEY}` -const EVENT_SHOWN = `shown${EVENT_KEY}` -const EVENT_HIDE = `hide${EVENT_KEY}` -const EVENT_HIDDEN = `hidden${EVENT_KEY}` -const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` - -const CLASS_NAME_SHOW = 'show' -const CLASS_NAME_COLLAPSE = 'collapse' -const CLASS_NAME_COLLAPSING = 'collapsing' -const CLASS_NAME_COLLAPSED = 'collapsed' -const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}` -const CLASS_NAME_HORIZONTAL = 'collapse-horizontal' - -const WIDTH = 'width' -const HEIGHT = 'height' - -const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing' -const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' - -const Default = { - parent: null, - toggle: true -} - -const DefaultType = { - parent: '(null|element)', - toggle: 'boolean' -} - -/** - * Class definition - */ - -class Collapse extends BaseComponent { - constructor(element, config) { - super(element, config) - - this._isTransitioning = false - this._triggerArray = [] - - const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE) - - for (const elem of toggleList) { - const selector = getSelectorFromElement(elem) - const filterElement = SelectorEngine.find(selector) - .filter(foundElement => foundElement === this._element) - - if (selector !== null && filterElement.length) { - this._triggerArray.push(elem) - } - } - - this._initializeChildren() - - if (!this._config.parent) { - this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()) - } - - if (this._config.toggle) { - this.toggle() - } - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - toggle() { - console.log(this._isShown()); - if (this._isShown()) { - this.hide() - } else { - this.show() - } - } - - show() { - if (this._isTransitioning || this._isShown()) { - return - } - - let activeChildren = [] - - // find active children - if (this._config.parent) { - activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES) - .filter(element => element !== this._element) - .map(element => Collapse.getOrCreateInstance(element, { toggle: false })) - } - - if (activeChildren.length && activeChildren[0]._isTransitioning) { - return - } - - const startEvent = EventHandler.trigger(this._element, EVENT_SHOW) - if (startEvent.defaultPrevented) { - return - } - - for (const activeInstance of activeChildren) { - activeInstance.hide() - } - - const dimension = this._getDimension() - - this._element.classList.remove(CLASS_NAME_COLLAPSE) - this._element.classList.add(CLASS_NAME_COLLAPSING) - - this._element.style[dimension] = 0 - - this._addAriaAndCollapsedClass(this._triggerArray, true) - this._isTransitioning = true - - const complete = () => { - this._isTransitioning = false - - this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) - - this._element.style[dimension] = '' - - EventHandler.trigger(this._element, EVENT_SHOWN) - } - - const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1) - const scrollSize = `scroll${capitalizedDimension}` - - this._queueCallback(complete, this._element, true) - this._element.style[dimension] = `${this._element[scrollSize]}px` - } - - hide() { - if (this._isTransitioning || !this._isShown()) { - return - } - - const startEvent = EventHandler.trigger(this._element, EVENT_HIDE) - if (startEvent.defaultPrevented) { - return - } - - const dimension = this._getDimension() - - this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px` - - reflow(this._element) - - this._element.classList.add(CLASS_NAME_COLLAPSING) - this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) - - for (const trigger of this._triggerArray) { - const element = getElementFromSelector(trigger) - - if (element && !this._isShown(element)) { - this._addAriaAndCollapsedClass([trigger], false) - } - } - - this._isTransitioning = true - - const complete = () => { - this._isTransitioning = false - this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE) - EventHandler.trigger(this._element, EVENT_HIDDEN) - } - - this._element.style[dimension] = '' - - this._queueCallback(complete, this._element, true) - } - - _isShown(element = this._element) { - return element.classList.contains(CLASS_NAME_SHOW) - } - - // Private - _configAfterMerge(config) { - config.toggle = Boolean(config.toggle) // Coerce string values - config.parent = getElement(config.parent) - return config - } - - _getDimension() { - return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT - } - - _initializeChildren() { - if (!this._config.parent) { - return - } - - const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE) - - for (const element of children) { - const selected = getElementFromSelector(element) - - if (selected) { - this._addAriaAndCollapsedClass([element], this._isShown(selected)) - } - } - } - - _getFirstLevelChildren(selector) { - const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent) - // remove children if greater depth - return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)) - } - - _addAriaAndCollapsedClass(triggerArray, isOpen) { - if (!triggerArray.length) { - return - } - - for (const element of triggerArray) { - element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen) - element.setAttribute('aria-expanded', isOpen) - } - } - - // Static - static jQueryInterface(config) { - const _config = {} - if (typeof config === 'string' && /show|hide/.test(config)) { - _config.toggle = false - } - - return this.each(function () { - const data = Collapse.getOrCreateInstance(this, _config) - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - } - }) - } -} - -/** - * Data API implementation - */ - -EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { - - console.log(event.target); - // preventDefault only for elements (which change the URL) not inside the collapsible element - if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) { - event.preventDefault() - } - - const selector = getSelectorFromElement(this) - const selectorElements = SelectorEngine.find(selector) - - for (const element of selectorElements) { - Collapse.getOrCreateInstance(element, { toggle: false }).toggle() - } -}) - -/** - * jQuery - */ - -defineJQueryPlugin(Collapse) - -export default Collapse diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/sidebar.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/sidebar.js deleted file mode 100644 index 8ec221e2a2..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/src/sidebar.js +++ /dev/null @@ -1,295 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): collapse.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { - defineJQueryPlugin, - getElement, - getElementFromSelector, - getSelectorFromElement, - reflow -} from '../util/index' -import EventHandler from '../dom/event-handler' -import SelectorEngine from '../dom/selector-engine' -import BaseComponent from './base-component' - -/** - * Constants - */ - -const NAME = 'sidebar-collapse' -const DATA_KEY = 'dt.collapse' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' - -const EVENT_SHOW = `show${EVENT_KEY}` -const EVENT_SHOWN = `shown${EVENT_KEY}` -const EVENT_HIDE = `hide${EVENT_KEY}` -const EVENT_HIDDEN = `hidden${EVENT_KEY}` -const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const EVENT_RESIZE_DATA_API = 'resize' - -const CLASS_NAME_SHOW = 'show' -const CLASS_NAME_COLLAPSE = 'sidebar-collapse' -const CLASS_NAME_COLLAPSING = 'sidebar-collapsing' -const CLASS_NAME_COLLAPSED = 'sidebar-collapsed' -const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}` - -const WIDTH = 'width' -const HEIGHT = 'height' - -const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing' -const SELECTOR_DATA_TOGGLE = '[data-toggle="sidebar"]' - -const Default = { - parent: null, - toggle: true -} - -const DefaultType = { - parent: '(null|element)', - toggle: 'boolean' -} - -/** - * Class definition - */ - -class Sidebar extends BaseComponent { - constructor(element, config) { - super(element, config) - - this._isTransitioning = false - this._triggerArray = [] - - const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE) - - for (const elem of toggleList) { - const selector = getSelectorFromElement(elem) - const filterElement = SelectorEngine.find(selector) - .filter(foundElement => foundElement === this._element) - - if (selector !== null && filterElement.length) { - this._triggerArray.push(elem) - } - } - - this._initializeChildren() - - if (!this._config.parent) { - this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()) - } - - if (this._config.toggle) { - this.toggle() - } - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - toggle() { - if (this._isShown()) { - this.hide() - } else { - this.show() - } - } - - show() { - if (this._isTransitioning || this._isShown()) { - return - } - - let activeChildren = [] - - // find active children - if (this._config.parent) { - activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES) - .filter(element => element !== this._element) - .map(element => Collapse.getOrCreateInstance(element, { toggle: false })) - } - - if (activeChildren.length && activeChildren[0]._isTransitioning) { - return - } - - const startEvent = EventHandler.trigger(this._element, EVENT_SHOW) - if (startEvent.defaultPrevented) { - return - } - - for (const activeInstance of activeChildren) { - activeInstance.hide() - } - - this._element.classList.remove(CLASS_NAME_COLLAPSE) - this._element.classList.add(CLASS_NAME_COLLAPSING) - - this._element.style[WIDTH] = 0 - - this._addAriaAndCollapsedClass(this._triggerArray, true) - this._isTransitioning = true - - const complete = () => { - this._isTransitioning = false - - this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) - - this._element.style[WIDTH] = '' - - EventHandler.trigger(this._element, EVENT_SHOWN) - } - - - const capitalizedDimension = WIDTH[0].toUpperCase() + WIDTH.slice(1) - const scrollSize = `scroll${capitalizedDimension}` - - this._queueCallback(complete, this._element, true) - this._element.style[WIDTH] = `${this._element[scrollSize]}px` - } - - hide() { - if (this._isTransitioning || !this._isShown()) { - return - } - - const startEvent = EventHandler.trigger(this._element, EVENT_HIDE) - if (startEvent.defaultPrevented) { - return - } - - this._element.style[WIDTH] = `${this._element.getBoundingClientRect()[WIDTH]}px` - - reflow(this._element) - - this._element.classList.add(CLASS_NAME_COLLAPSING) - this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW) - - for (const trigger of this._triggerArray) { - const element = getElementFromSelector(trigger) - - if (element && !this._isShown(element)) { - this._addAriaAndCollapsedClass([trigger], false) - } - } - - this._isTransitioning = true - - const complete = () => { - this._isTransitioning = false - this._element.classList.remove(CLASS_NAME_COLLAPSING) - this._element.classList.add(CLASS_NAME_COLLAPSE) - EventHandler.trigger(this._element, EVENT_HIDDEN) - } - - this._element.style[WIDTH] = '' - - this._queueCallback(complete, this._element, true) - } - - _isShown(element = this._element) { - return element.classList.contains(CLASS_NAME_SHOW) - } - - // Private - _configAfterMerge(config) { - config.toggle = Boolean(config.toggle) // Coerce string values - config.parent = getElement(config.parent) - return config - } - - _initializeChildren() { - if (!this._config.parent) { - return - } - - const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE) - - for (const element of children) { - const selected = getElementFromSelector(element) - - if (selected) { - this._addAriaAndCollapsedClass([element], this._isShown(selected)) - } - } - } - - _getFirstLevelChildren(selector) { - const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent) - // remove children if greater depth - return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)) - } - - _addAriaAndCollapsedClass(triggerArray, isOpen) { - if (!triggerArray.length) { - return - } - - for (const element of triggerArray) { - element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen) - element.setAttribute('aria-expanded', isOpen) - } - } - - // Static - static jQueryInterface(config) { - const _config = {} - if (typeof config === 'string' && /show|hide/.test(config)) { - _config.toggle = false - } - - return this.each(function () { - const data = Collapse.getOrCreateInstance(this, _config) - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`) - } - - data[config]() - } - }) - } -} - -/** - * Data API implementation - */ - -EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { - // preventDefault only for elements (which change the URL) not inside the collapsible element - if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) { - event.preventDefault() - } - - const selector = getSelectorFromElement(this) - const selectorElements = SelectorEngine.find(selector) - - for (const element of selectorElements) { - Sidebar.getOrCreateInstance(element, { toggle: false }).toggle() - } -}) - -/** - * jQuery - */ - -defineJQueryPlugin(Sidebar) - -export default Sidebar diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/backdrop.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/backdrop.js deleted file mode 100644 index 83927401f1..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/backdrop.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/backdrop.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import EventHandler from '../dom/event-handler' -import { execute, executeAfterTransition, getElement, reflow } from './index' -import Config from './config' - -/** - * Constants - */ - -const NAME = 'backdrop' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' -const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}` - -const Default = { - className: 'modal-backdrop', - clickCallback: null, - isAnimated: false, - isVisible: true, // if false, we use the backdrop helper without adding any element to the dom - rootElement: 'body' // give the choice to place backdrop under different elements -} - -const DefaultType = { - className: 'string', - clickCallback: '(function|null)', - isAnimated: 'boolean', - isVisible: 'boolean', - rootElement: '(element|string)' -} - -/** - * Class definition - */ - -class Backdrop extends Config { - constructor(config) { - super() - this._config = this._getConfig(config) - this._isAppended = false - this._element = null - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - show(callback) { - if (!this._config.isVisible) { - execute(callback) - return - } - - this._append() - - const element = this._getElement() - if (this._config.isAnimated) { - reflow(element) - } - - element.classList.add(CLASS_NAME_SHOW) - - this._emulateAnimation(() => { - execute(callback) - }) - } - - hide(callback) { - if (!this._config.isVisible) { - execute(callback) - return - } - - this._getElement().classList.remove(CLASS_NAME_SHOW) - - this._emulateAnimation(() => { - this.dispose() - execute(callback) - }) - } - - dispose() { - if (!this._isAppended) { - return - } - - EventHandler.off(this._element, EVENT_MOUSEDOWN) - - this._element.remove() - this._isAppended = false - } - - // Private - _getElement() { - if (!this._element) { - const backdrop = document.createElement('div') - backdrop.className = this._config.className - if (this._config.isAnimated) { - backdrop.classList.add(CLASS_NAME_FADE) - } - - this._element = backdrop - } - - return this._element - } - - _configAfterMerge(config) { - // use getElement() with the default "body" to get a fresh Element on each instantiation - config.rootElement = getElement(config.rootElement) - return config - } - - _append() { - if (this._isAppended) { - return - } - - const element = this._getElement() - this._config.rootElement.append(element) - - EventHandler.on(element, EVENT_MOUSEDOWN, () => { - execute(this._config.clickCallback) - }) - - this._isAppended = true - } - - _emulateAnimation(callback) { - executeAfterTransition(callback, this._getElement(), this._config.isAnimated) - } -} - -export default Backdrop diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/component-functions.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/component-functions.js deleted file mode 100644 index c2f99cceb5..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/component-functions.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/component-functions.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import EventHandler from '../dom/event-handler' -import { getElementFromSelector, isDisabled } from './index' - -const enableDismissTrigger = (component, method = 'hide') => { - const clickEvent = `click.dismiss${component.EVENT_KEY}` - const name = component.NAME - - EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { - if (['A', 'AREA'].includes(this.tagName)) { - event.preventDefault() - } - - if (isDisabled(this)) { - return - } - - const target = getElementFromSelector(this) || this.closest(`.${name}`) - const instance = component.getOrCreateInstance(target) - - // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method - instance[method]() - }) -} - -export { - enableDismissTrigger -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/config.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/config.js deleted file mode 100644 index 8aa99ccd1a..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/config.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/config.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { isElement, toType } from './index' -import Manipulator from '../dom/manipulator' - -/** - * Class definition - */ - -class Config { - // Getters - static get Default() { - return {} - } - - static get DefaultType() { - return {} - } - - static get NAME() { - throw new Error('You have to implement the static method "NAME", for each component!') - } - - _getConfig(config) { - config = this._mergeConfigObj(config) - config = this._configAfterMerge(config) - this._typeCheckConfig(config) - return config - } - - _configAfterMerge(config) { - return config - } - - _mergeConfigObj(config, element) { - const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse - return { - ...this.constructor.Default, - ...(typeof jsonConfig === 'object' ? jsonConfig : {}), - ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}), - ...(typeof config === 'object' ? config : {}) - } - } - - _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { - for (const property of Object.keys(configTypes)) { - const expectedTypes = configTypes[property] - const value = config[property] - const valueType = isElement(value) ? 'element' : toType(value) - - if (!new RegExp(expectedTypes).test(valueType)) { - throw new TypeError( - `${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".` - ) - } - } - } -} - -export default Config diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/focustrap.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/focustrap.js deleted file mode 100644 index ef6916679c..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/focustrap.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/focustrap.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import EventHandler from '../dom/event-handler' -import SelectorEngine from '../dom/selector-engine' -import Config from './config' - -/** - * Constants - */ - -const NAME = 'focustrap' -const DATA_KEY = 'bs.focustrap' -const EVENT_KEY = `.${DATA_KEY}` -const EVENT_FOCUSIN = `focusin${EVENT_KEY}` -const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}` - -const TAB_KEY = 'Tab' -const TAB_NAV_FORWARD = 'forward' -const TAB_NAV_BACKWARD = 'backward' - -const Default = { - autofocus: true, - trapElement: null // The element to trap focus inside of -} - -const DefaultType = { - autofocus: 'boolean', - trapElement: 'element' -} - -/** - * Class definition - */ - -class FocusTrap extends Config { - constructor(config) { - super() - this._config = this._getConfig(config) - this._isActive = false - this._lastTabNavDirection = null - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - activate() { - if (this._isActive) { - return - } - - if (this._config.autofocus) { - this._config.trapElement.focus() - } - - EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop - EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event)) - EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)) - - this._isActive = true - } - - deactivate() { - if (!this._isActive) { - return - } - - this._isActive = false - EventHandler.off(document, EVENT_KEY) - } - - // Private - _handleFocusin(event) { - const { trapElement } = this._config - - if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { - return - } - - const elements = SelectorEngine.focusableChildren(trapElement) - - if (elements.length === 0) { - trapElement.focus() - } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { - elements[elements.length - 1].focus() - } else { - elements[0].focus() - } - } - - _handleKeydown(event) { - if (event.key !== TAB_KEY) { - return - } - - this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD - } -} - -export default FocusTrap diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/index.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/index.js deleted file mode 100644 index f3f6fd7a82..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/index.js +++ /dev/null @@ -1,336 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/index.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -const MAX_UID = 1_000_000 -const MILLISECONDS_MULTIPLIER = 1000 -const TRANSITION_END = 'transitionend' - -// Shout-out Angus Croll (https://goo.gl/pxwQGp) -const toType = object => { - if (object === null || object === undefined) { - return `${object}` - } - - return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase() -} - -/** - * Public Util API - */ - -const getUID = prefix => { - do { - prefix += Math.floor(Math.random() * MAX_UID) - } while (document.getElementById(prefix)) - - return prefix -} - -const getSelector = element => { - let selector = element.getAttribute('data-target') - - if (!selector || selector === '#') { - let hrefAttribute = element.getAttribute('href') - - // The only valid content that could double as a selector are IDs or classes, - // so everything starting with `#` or `.`. If a "real" URL is used as the selector, - // `document.querySelector` will rightfully complain it is invalid. - // See https://github.com/twbs/bootstrap/issues/32273 - if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) { - return null - } - - // Just in case some CMS puts out a full URL with the anchor appended - if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { - hrefAttribute = `#${hrefAttribute.split('#')[1]}` - } - - selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null - } - - return selector -} - -const getSelectorFromElement = element => { - const selector = getSelector(element) - - if (selector) { - return document.querySelector(selector) ? selector : null - } - - return null -} - -const getElementFromSelector = element => { - const selector = getSelector(element) - - return selector ? document.querySelector(selector) : null -} - -const getTransitionDurationFromElement = element => { - if (!element) { - return 0 - } - - // Get transition-duration of the element - let { transitionDuration, transitionDelay } = window.getComputedStyle(element) - - const floatTransitionDuration = Number.parseFloat(transitionDuration) - const floatTransitionDelay = Number.parseFloat(transitionDelay) - - // Return 0 if element or transition duration is not found - if (!floatTransitionDuration && !floatTransitionDelay) { - return 0 - } - - // If multiple durations are defined, take the first - transitionDuration = transitionDuration.split(',')[0] - transitionDelay = transitionDelay.split(',')[0] - - return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER -} - -const triggerTransitionEnd = element => { - element.dispatchEvent(new Event(TRANSITION_END)) -} - -const isElement = object => { - if (!object || typeof object !== 'object') { - return false - } - - if (typeof object.jquery !== 'undefined') { - object = object[0] - } - - return typeof object.nodeType !== 'undefined' -} - -const getElement = object => { - // it's a jQuery object or a node element - if (isElement(object)) { - return object.jquery ? object[0] : object - } - - if (typeof object === 'string' && object.length > 0) { - return document.querySelector(object) - } - - return null -} - -const isVisible = element => { - if (!isElement(element) || element.getClientRects().length === 0) { - return false - } - - const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible' - // Handle `details` element as its content may falsie appear visible when it is closed - const closedDetails = element.closest('details:not([open])') - - if (!closedDetails) { - return elementIsVisible - } - - if (closedDetails !== element) { - const summary = element.closest('summary') - if (summary && summary.parentNode !== closedDetails) { - return false - } - - if (summary === null) { - return false - } - } - - return elementIsVisible -} - -const isDisabled = element => { - if (!element || element.nodeType !== Node.ELEMENT_NODE) { - return true - } - - if (element.classList.contains('disabled')) { - return true - } - - if (typeof element.disabled !== 'undefined') { - return element.disabled - } - - return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false' -} - -const findShadowRoot = element => { - if (!document.documentElement.attachShadow) { - return null - } - - // Can find the shadow root otherwise it'll return the document - if (typeof element.getRootNode === 'function') { - const root = element.getRootNode() - return root instanceof ShadowRoot ? root : null - } - - if (element instanceof ShadowRoot) { - return element - } - - // when we don't find a shadow root - if (!element.parentNode) { - return null - } - - return findShadowRoot(element.parentNode) -} - -const noop = () => {} - -/** - * Trick to restart an element's animation - * - * @param {HTMLElement} element - * @return void - * - * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation - */ -const reflow = element => { - element.offsetHeight // eslint-disable-line no-unused-expressions -} - -const getjQuery = () => { - if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { - return window.jQuery - } - - return null -} - -const DOMContentLoadedCallbacks = [] - -const onDOMContentLoaded = callback => { - if (document.readyState === 'loading') { - // add listener on the first call when the document is in loading state - if (!DOMContentLoadedCallbacks.length) { - document.addEventListener('DOMContentLoaded', () => { - for (const callback of DOMContentLoadedCallbacks) { - callback() - } - }) - } - - DOMContentLoadedCallbacks.push(callback) - } else { - callback() - } -} - -const isRTL = () => document.documentElement.dir === 'rtl' - -const defineJQueryPlugin = plugin => { - onDOMContentLoaded(() => { - const $ = getjQuery() - /* istanbul ignore if */ - if ($) { - const name = plugin.NAME - const JQUERY_NO_CONFLICT = $.fn[name] - $.fn[name] = plugin.jQueryInterface - $.fn[name].Constructor = plugin - $.fn[name].noConflict = () => { - $.fn[name] = JQUERY_NO_CONFLICT - return plugin.jQueryInterface - } - } - }) -} - -const execute = callback => { - if (typeof callback === 'function') { - callback() - } -} - -const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { - if (!waitForTransition) { - execute(callback) - return - } - - const durationPadding = 5 - const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding - - let called = false - - const handler = ({ target }) => { - if (target !== transitionElement) { - return - } - - called = true - transitionElement.removeEventListener(TRANSITION_END, handler) - execute(callback) - } - - transitionElement.addEventListener(TRANSITION_END, handler) - setTimeout(() => { - if (!called) { - triggerTransitionEnd(transitionElement) - } - }, emulatedDuration) -} - -/** - * Return the previous/next element of a list. - * - * @param {array} list The list of elements - * @param activeElement The active element - * @param shouldGetNext Choose to get next or previous element - * @param isCycleAllowed - * @return {Element|elem} The proper element - */ -const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { - const listLength = list.length - let index = list.indexOf(activeElement) - - // if the element does not exist in the list return an element - // depending on the direction and if cycle is allowed - if (index === -1) { - return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0] - } - - index += shouldGetNext ? 1 : -1 - - if (isCycleAllowed) { - index = (index + listLength) % listLength - } - - return list[Math.max(0, Math.min(index, listLength - 1))] -} - -export { - defineJQueryPlugin, - execute, - executeAfterTransition, - findShadowRoot, - getElement, - getElementFromSelector, - getjQuery, - getNextActiveElement, - getSelectorFromElement, - getTransitionDurationFromElement, - getUID, - isDisabled, - isElement, - isRTL, - isVisible, - noop, - onDOMContentLoaded, - reflow, - triggerTransitionEnd, - toType -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/sanitizer.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/sanitizer.js deleted file mode 100644 index 532869167c..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/sanitizer.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/sanitizer.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -const uriAttributes = new Set([ - 'background', - 'cite', - 'href', - 'itemtype', - 'longdesc', - 'poster', - 'src', - 'xlink:href' -]) - -const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i - -/** - * A pattern that recognizes a commonly useful subset of URLs that are safe. - * - * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts - */ -const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i - -/** - * A pattern that matches safe data URLs. Only matches image, video and audio types. - * - * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts - */ -const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i - -const allowedAttribute = (attribute, allowedAttributeList) => { - const attributeName = attribute.nodeName.toLowerCase() - - if (allowedAttributeList.includes(attributeName)) { - if (uriAttributes.has(attributeName)) { - return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue)) - } - - return true - } - - // Check if a regular expression validates the attribute. - return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp) - .some(regex => regex.test(attributeName)) -} - -export const DefaultAllowlist = { - // Global attributes allowed on any supplied element below. - '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], - a: ['target', 'href', 'title', 'rel'], - area: [], - b: [], - br: [], - col: [], - code: [], - div: [], - em: [], - hr: [], - h1: [], - h2: [], - h3: [], - h4: [], - h5: [], - h6: [], - i: [], - img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], - li: [], - ol: [], - p: [], - pre: [], - s: [], - small: [], - span: [], - sub: [], - sup: [], - strong: [], - u: [], - ul: [] -} - -export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { - if (!unsafeHtml.length) { - return unsafeHtml - } - - if (sanitizeFunction && typeof sanitizeFunction === 'function') { - return sanitizeFunction(unsafeHtml) - } - - const domParser = new window.DOMParser() - const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html') - const elements = [].concat(...createdDocument.body.querySelectorAll('*')) - - for (const element of elements) { - const elementName = element.nodeName.toLowerCase() - - if (!Object.keys(allowList).includes(elementName)) { - element.remove() - - continue - } - - const attributeList = [].concat(...element.attributes) - const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []) - - for (const attribute of attributeList) { - if (!allowedAttribute(attribute, allowedAttributes)) { - element.removeAttribute(attribute.nodeName) - } - } - } - - return createdDocument.body.innerHTML -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/scrollbar.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/scrollbar.js deleted file mode 100644 index 5cac7b6d16..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/scrollbar.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/scrollBar.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import SelectorEngine from '../dom/selector-engine' -import Manipulator from '../dom/manipulator' -import { isElement } from './index' - -/** - * Constants - */ - -const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' -const SELECTOR_STICKY_CONTENT = '.sticky-top' -const PROPERTY_PADDING = 'padding-right' -const PROPERTY_MARGIN = 'margin-right' - -/** - * Class definition - */ - -class ScrollBarHelper { - constructor() { - this._element = document.body - } - - // Public - getWidth() { - // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes - const documentWidth = document.documentElement.clientWidth - return Math.abs(window.innerWidth - documentWidth) - } - - hide() { - const width = this.getWidth() - this._disableOverFlow() - // give padding to element to balance the hidden scrollbar width - this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width) - // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth - this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width) - this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width) - } - - reset() { - this._resetElementAttributes(this._element, 'overflow') - this._resetElementAttributes(this._element, PROPERTY_PADDING) - this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING) - this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN) - } - - isOverflowing() { - return this.getWidth() > 0 - } - - // Private - _disableOverFlow() { - this._saveInitialAttribute(this._element, 'overflow') - this._element.style.overflow = 'hidden' - } - - _setElementAttributes(selector, styleProperty, callback) { - const scrollbarWidth = this.getWidth() - const manipulationCallBack = element => { - if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { - return - } - - this._saveInitialAttribute(element, styleProperty) - const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty) - element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`) - } - - this._applyManipulationCallback(selector, manipulationCallBack) - } - - _saveInitialAttribute(element, styleProperty) { - const actualValue = element.style.getPropertyValue(styleProperty) - if (actualValue) { - Manipulator.setDataAttribute(element, styleProperty, actualValue) - } - } - - _resetElementAttributes(selector, styleProperty) { - const manipulationCallBack = element => { - const value = Manipulator.getDataAttribute(element, styleProperty) - // We only want to remove the property if the value is `null`; the value can also be zero - if (value === null) { - element.style.removeProperty(styleProperty) - return - } - - Manipulator.removeDataAttribute(element, styleProperty) - element.style.setProperty(styleProperty, value) - } - - this._applyManipulationCallback(selector, manipulationCallBack) - } - - _applyManipulationCallback(selector, callBack) { - if (isElement(selector)) { - callBack(selector) - return - } - - for (const sel of SelectorEngine.find(selector, this._element)) { - callBack(sel) - } - } -} - -export default ScrollBarHelper diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/swipe.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/swipe.js deleted file mode 100644 index 7126360cea..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/swipe.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/swipe.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import Config from './config' -import EventHandler from '../dom/event-handler' -import { execute } from './index' - -/** - * Constants - */ - -const NAME = 'swipe' -const EVENT_KEY = '.bs.swipe' -const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` -const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` -const EVENT_TOUCHEND = `touchend${EVENT_KEY}` -const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` -const EVENT_POINTERUP = `pointerup${EVENT_KEY}` -const POINTER_TYPE_TOUCH = 'touch' -const POINTER_TYPE_PEN = 'pen' -const CLASS_NAME_POINTER_EVENT = 'pointer-event' -const SWIPE_THRESHOLD = 40 - -const Default = { - endCallback: null, - leftCallback: null, - rightCallback: null -} - -const DefaultType = { - endCallback: '(function|null)', - leftCallback: '(function|null)', - rightCallback: '(function|null)' -} - -/** - * Class definition - */ - -class Swipe extends Config { - constructor(element, config) { - super() - this._element = element - - if (!element || !Swipe.isSupported()) { - return - } - - this._config = this._getConfig(config) - this._deltaX = 0 - this._supportPointerEvents = Boolean(window.PointerEvent) - this._initEvents() - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - dispose() { - EventHandler.off(this._element, EVENT_KEY) - } - - // Private - _start(event) { - if (!this._supportPointerEvents) { - this._deltaX = event.touches[0].clientX - - return - } - - if (this._eventIsPointerPenTouch(event)) { - this._deltaX = event.clientX - } - } - - _end(event) { - if (this._eventIsPointerPenTouch(event)) { - this._deltaX = event.clientX - this._deltaX - } - - this._handleSwipe() - execute(this._config.endCallback) - } - - _move(event) { - this._deltaX = event.touches && event.touches.length > 1 ? - 0 : - event.touches[0].clientX - this._deltaX - } - - _handleSwipe() { - const absDeltaX = Math.abs(this._deltaX) - - if (absDeltaX <= SWIPE_THRESHOLD) { - return - } - - const direction = absDeltaX / this._deltaX - - this._deltaX = 0 - - if (!direction) { - return - } - - execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback) - } - - _initEvents() { - if (this._supportPointerEvents) { - EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)) - EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)) - - this._element.classList.add(CLASS_NAME_POINTER_EVENT) - } else { - EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)) - EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)) - EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)) - } - } - - _eventIsPointerPenTouch(event) { - return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH) - } - - // Static - static isSupported() { - return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 - } -} - -export default Swipe diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/template-factory.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/template-factory.js deleted file mode 100644 index cf402fa3b0..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/javascript/util/template-factory.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/template-factory.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - -import { DefaultAllowlist, sanitizeHtml } from './sanitizer' -import { getElement, isElement } from '../util/index' -import SelectorEngine from '../dom/selector-engine' -import Config from './config' - -/** - * Constants - */ - -const NAME = 'TemplateFactory' - -const Default = { - allowList: DefaultAllowlist, - content: {}, // { selector : text , selector2 : text2 , } - extraClass: '', - html: false, - sanitize: true, - sanitizeFn: null, - template: '
' -} - -const DefaultType = { - allowList: 'object', - content: 'object', - extraClass: '(string|function)', - html: 'boolean', - sanitize: 'boolean', - sanitizeFn: '(null|function)', - template: 'string' -} - -const DefaultContentType = { - entry: '(string|element|function|null)', - selector: '(string|element)' -} - -/** - * Class definition - */ - -class TemplateFactory extends Config { - constructor(config) { - super() - this._config = this._getConfig(config) - } - - // Getters - static get Default() { - return Default - } - - static get DefaultType() { - return DefaultType - } - - static get NAME() { - return NAME - } - - // Public - getContent() { - return Object.values(this._config.content) - .map(config => this._resolvePossibleFunction(config)) - .filter(Boolean) - } - - hasContent() { - return this.getContent().length > 0 - } - - changeContent(content) { - this._checkContent(content) - this._config.content = { ...this._config.content, ...content } - return this - } - - toHtml() { - const templateWrapper = document.createElement('div') - templateWrapper.innerHTML = this._maybeSanitize(this._config.template) - - for (const [selector, text] of Object.entries(this._config.content)) { - this._setContent(templateWrapper, text, selector) - } - - const template = templateWrapper.children[0] - const extraClass = this._resolvePossibleFunction(this._config.extraClass) - - if (extraClass) { - template.classList.add(...extraClass.split(' ')) - } - - return template - } - - // Private - _typeCheckConfig(config) { - super._typeCheckConfig(config) - this._checkContent(config.content) - } - - _checkContent(arg) { - for (const [selector, content] of Object.entries(arg)) { - super._typeCheckConfig({ selector, entry: content }, DefaultContentType) - } - } - - _setContent(template, content, selector) { - const templateElement = SelectorEngine.findOne(selector, template) - - if (!templateElement) { - return - } - - content = this._resolvePossibleFunction(content) - - if (!content) { - templateElement.remove() - return - } - - if (isElement(content)) { - this._putElementInTemplate(getElement(content), templateElement) - return - } - - if (this._config.html) { - templateElement.innerHTML = this._maybeSanitize(content) - return - } - - templateElement.textContent = content - } - - _maybeSanitize(arg) { - return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg - } - - _resolvePossibleFunction(arg) { - return typeof arg === 'function' ? arg(this) : arg - } - - _putElementInTemplate(element, templateElement) { - if (this._config.html) { - templateElement.innerHTML = '' - templateElement.append(element) - return - } - - templateElement.textContent = element.textContent - } -} - -export default TemplateFactory diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_layout.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_layout.scss new file mode 100644 index 0000000000..18d1fda95b --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_layout.scss @@ -0,0 +1,85 @@ +@mixin flex( $direction: false, $justify: false, $align: false, $inline: false, $wrap: false, $gap: false ) { + // display: flex/inline-flex + @if $inline { + display: inline-flex; + } + @else { + display: flex; + } + + // flex-direction + @if $direction != false { + @if $direction == row { + flex-direction: row; + } + @else if $direction == column { + flex-direction: column; + } + @else if $direction == row-reverse { + flex-direction: row-reverse; + } + @else if $direction == column-reverse { + flex-direction: column-reverse; + } + } + + // justify-content + @if $justify != false { + @if $justify == normal { + justify-content: normal; + } + @else if $justify == center { + justify-content: center; + } + @else if $justify == start { + justify-content: flex-start; + } + @else if $justify == end { + justify-content: flex-end; + } + @else if $justify == between { + justify-content: space-between; + } + @else if $justify == around { + justify-content: space-around; + } + @else if $justify == evenly { + justify-content: space-evenly; + } + } + + // align-items/align-content + @if $align != false { + @if $align == normal { + align-items: normal; + } + @else if $align == center { + align-items: center; + } + @else if $align == start { + align-items: flex-start; + } + @else if $align == end { + align-items: flex-end; + } + @else if $align == between { + align-content: space-between; + } + @else if $align == around { + align-content: space-around; + } + @else if $align == evenly { + align-content: space-evenly; + } + } + + // flex-wrap + @if $wrap { + flex-wrap: wrap; + } + + // gap + @if $gap { + gap: $gap; + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_transitions.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_transitions.scss new file mode 100644 index 0000000000..d48e01543a --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_transitions.scss @@ -0,0 +1,38 @@ +@keyframes entrance-theme-transition-key-frames { + from { + opacity: 0; + transform: translateY(150px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.entrance-theme-transition { + animation-name: entrance-theme-transition-key-frames; + animation-duration: 0.15s; + animation-timing-function: ease-out; +} + +@mixin transition($transition...) { + @if length($transition) == 0 { + $transition: all 0.2s ease-in-out !default; + } + + @if length($transition) > 1 { + @each $value in $transition { + @if $value == null or $value == none { + @warn "The keyword 'none' or 'null' must be used as a single argument."; + } + } + } + + @if nth($transition, 1) != null { + -webkit-transition: $transition; + -o-transition: $transition; + -ms-transition: $transition; + transition: $transition; + } +} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_fonts.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_typography.scss similarity index 68% rename from src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_fonts.scss rename to src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_typography.scss index 633bfcfb28..4299b8de73 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_fonts.scss +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/_typography.scss @@ -1,4 +1,4 @@ -@font-face { +@font-face { font-family: "FluentSystemIcons-Regular"; src: url("../fonts/FluentSystemIcons-Regular.woff2?b48ba7b19a15536ed3d062b9b6c8fa0e") format("woff2"), url("../fonts/FluentSystemIcons-Regular.woff?b48ba7b19a15536ed3d062b9b6c8fa0e") format("woff"), url("../fonts/FluentSystemIcons-Regular.ttf?b48ba7b19a15536ed3d062b9b6c8fa0e") format("truetype"); } @@ -10,6 +10,22 @@ i[class^="FluentSystemIcons"]:before, i[class*=" FluentSystemIcons"]:before { font-variant: normal; text-transform: none; line-height: 1; - -webkit-font-smoothing: antialiased; + -webkit-font-smoothing: subpixel-antialiased; -moz-osx-font-smoothing: grayscale; +} + +* { + text-rendering: geometricPrecision; +} + +@mixin typography-body { + user-select: none; + + font: { + family: var(--font-family-text); + size: var(--font-size-body); + weight: normal; + } + + line-height: 20px; } \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_variables.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_variables.scss deleted file mode 100644 index 949c63dbc8..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/configs/_variables.scss +++ /dev/null @@ -1,23 +0,0 @@ -$enable-filter: true !default; -$enable-shadows: true !default; -$enable-transitions: true !default; -$enable-reduced-motion: true !default; - -$header-small-height: 48px; -$header-medium-height: 48px; -$header-wide-height: 48px; - -$grid-separator: 0px; - -$sidebar-small-width: 0px; -$sidebar-medium-width: 48px; -$sidebar-wide-width: 320px; - -$transition-base: 0.2s ease-in-out !default; -$transition-all: all 0.2s ease-in-out !default; -$transition-fade: opacity 0.15s linear !default; - -$border-radius: 7px; -$corner-radius: 4px; - -$grid-breakpoints: (small: 0, medium: 640px, wide: 992px); diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/devtoys.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/devtoys.scss index c22e5553f1..d1f3ad08ed 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/devtoys.scss +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/devtoys.scss @@ -1,39 +1,18 @@ -@use "configs/variables" as variables; -@use "configs/fonts"; -@use "mixins/index" as mixins; +@import "theme/default"; +@import "transitions"; +@import "typography"; +@import "layout"; -@use "features/page"; -@use "features/form"; -@use "features/header"; -@use "features/navbar"; -@use "features/control"; -@use "features/scrollbars"; -@use "features/text"; -@use "features/transitions"; - -@use "theme/default"; +*, *::before, *::after { + box-sizing: border-box; +} html, body { /* Default margin and padding */ padding: 0; margin: 0; - /* Default fonts */ - font-family: - "Segoe UI", /* Windows (Vista+) and Windows Phone. */ - -apple-system, /* San Francisco in Safari (on Mac OS X and iOS); Neue Helvetica and Lucida Grande on older versions of Mac OS X. */ - BlinkMacSystemFont, /* Equivalent of -apple-system, for Chrome on Mac OS X. */ - Roboto, /* Android (Ice Cream Sandwich (4.0)+) and Chrome OS. */ - Ubuntu, /* all versions of Ubuntu. */ - system-ui, /* Default UI font on a given platform. */ - 'Helvetica Neue', Helvetica, Arial, sans-serif; /* Fallback */ - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 20px; - font-feature-settings: "rclt" off; - - /* Default overflow behavior */ + /* Default scrollbar behavior */ overflow: hidden; } @@ -46,7 +25,7 @@ html, body { padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; - z-index: 2147483647; /* maximum range */ + z-index: 2147483647; // maximum range } #blazor-error-ui .dismiss { @@ -65,67 +44,3 @@ html, body { .blazor-error-boundary::after { content: "An error has occurred." } - -// need to handle dynamic font depending on user settings -body { - - &:before { - content: "small"; - display: none; - visibility: hidden; - - @include mixins.media-breakpoint-up(medium) { - content: "medium"; - } - - @include mixins.media-breakpoint-up(wide) { - content: "wide"; - } - } -} - -.container { - margin: 0; - padding: 0; - display: grid; - grid-template-columns: auto 1fr; - grid-template-rows: variables.$header-medium-height calc(100vh - variables.$header-medium-height); - grid-template-areas: "header header" "sidebar page"; - column-gap: 0; - row-gap: 0; - min-height: 100vh; - min-width: calc(100vw - 17px); - - @include mixins.media-breakpoint-up(medium) { - grid-template-areas: "sidebar header" "sidebar page"; - grid-template-columns: variables.$sidebar-medium-width 1fr; - column-gap: 0; - row-gap: variables.$grid-separator; - } - - @include mixins.media-breakpoint-up(wide) { - margin: 0; - row-gap: 0; - column-gap: 0; - grid-template-columns: auto 1fr; - /*grid-template-rows: variables.$header-wide-height 1.8fr;*/ - } -} - -.collapse { - &:not(.show) { - display: none; - } -} - -.collapsing { - height: 0; - overflow: hidden; - transition: height 0.35s ease; -} - - -.sticky-bottom { - position: sticky; - bottom: 0; -} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_control.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_control.scss deleted file mode 100644 index b6dc4bc760..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_control.scss +++ /dev/null @@ -1,26 +0,0 @@ -/*@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -button { - padding: 7px 9px; - border-radius: 3px; - border-width: 1px; - border-style: solid; - - @include mixins.transition( - color variables.$transition-base, - background-color variables.$transition-base, - border-color variables.$transition-base - ); - - &.icon { - font-size: 16px; - line-height: 16px; - font-style: normal; - font-weight: 400; - } - - &.stealth { - } -} -*/ \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_form.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_form.scss deleted file mode 100644 index 75ce6b9ef9..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_form.scss +++ /dev/null @@ -1,85 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -input[type="text"] { - display: block; - width: 100%; - padding: 9px 0 9px 11px; - outline: none; - background-clip: padding-box; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-width: 2px; - border-style: inset; - border-radius: 4px; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 16px; - max-height: 30px; - @include mixins.transition(variables.$transition-all); -} - -.form-input-group { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: stretch; - width: 100%; - border-width: 1px; - border-style: inset; - border-radius: 4px; - border-bottom-width: 2px; - outline: none; - @include mixins.transition(variables.$transition-all); - - > input[type="text"], - > .form-select { - position: relative; - flex: 1 1 auto; - width: 1%; - min-width: 0; - } - - .form-input-group-text { - display: flex; - align-items: center; - padding: 0.375rem 0.75rem; - font-style: normal; - font-weight: 400; - font-size: 16px; - line-height: 16px; - text-align: center; - white-space: nowrap; - border-width: 0; - border-style: inset; - border-radius: 4px; - border-bottom-width: 2px; - max-height: 30px; - } -} - -.form-input-group:not(.has-validation) - > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.form-input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n + 3), -.form-input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control, -.form-input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select, -.form-input-group:not(.has-validation) - > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.form-input-group - > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not( - .invalid-feedback - ) { - margin-left: -2px; - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_header.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_header.scss deleted file mode 100644 index ed9cc9d40d..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_header.scss +++ /dev/null @@ -1,6 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -header { - grid-area: header; -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_navbar.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_navbar.scss deleted file mode 100644 index 2cdbe47c67..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_navbar.scss +++ /dev/null @@ -1,296 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -.navbar { - display: flex; - flex-shrink: 0; - - &.navbar-vertical { - flex-direction: column; - align-content: flex-start; - align-items: flex-start; - z-index: 1002; - padding: 0; - grid-area: sidebar; - height: 100vh; - width: variables.$sidebar-small-width; - max-width: variables.$sidebar-small-width; - position: absolute; - left: -10px; - // width: variables.$sidebar-wide-width; - border-top-right-radius: variables.$border-radius; - border-bottom-right-radius: variables.$border-radius; - @include mixins.transition( left variables.$transition-base, width variables.$transition-base, box-shadow variables.$transition-base ); - - .navbar-header-container { - height: calc(variables.$header-small-height + 7px); - - .navbar-toggler { - left: 8px; - margin: 5px 5px; - position: relative; - @include mixins.transition(left variables.$transition-base); - } - } - - .nav-items { - list-style-type: none; - margin-block-start: 0; - padding-inline-start: 0; - margin-bottom: auto; - - .nav-item { - margin: 5px; - outline: none; - padding: 1px 0; - border-width: 1px; - border-style: solid; - border-radius: 3px; - width: 0; - overflow: hidden; - @include mixins.transition( border-color variables.$transition-base, background-color variables.$transition-base ); - - .item-link { - height: 32px; - line-height: 32px; - display: flex; - column-gap: 0.5rem; - align-items: center; - align-items: center; - text-decoration: none; - font-style: normal; - font-weight: 400; - font-size: 14px; - width: 0; - overflow: hidden; - @include mixins.transition(color variables.$transition-base, width variables.$transition-base); - - .item-content { - font-style: inherit; - font-weight: inherit; - font-size: inherit; - line-height: 20px; - height: 20px; - width: 0; - flex-grow: 0; - overflow: hidden; - @include mixins.transition(width variables.$transition-base); - } - - [class^="icon-"] { - font-style: inherit; - font-size: inherit; - line-height: 16px; - margin: 4px 0 0 0; - } - - &::before { - content: " "; - width: 3px; - height: 16px; - border-radius: 999px; - display: block; - @include mixins.transition(background variables.$transition-base); - } - - &:first-child { - margin-top: 0; - } - } - - > .nav-items { - .nav-item { - .item-link { - margin-left: 2.3rem; - } - } - } - - .collapsed { - font-style: inherit; - font-size: inherit; - line-height: 16px; - margin: 4px 0 0 0; - cursor: pointer; - margin-left: 3px; - @include mixins.transition(margin-left variables.$transition-base); - - &.icon-active { - font-weight: 400; - font-size: 12px; - line-height: 12px; - margin: 0; - transform: rotate(180deg); - overflow: hidden; - width: 0; - @include mixins.transition( transform variables.$transition-base, width variables.$transition-base ); - } - } - - &.nav-group-child { - margin-top: -1px; - padding-top: 0; - - .nav-items { - .nav-item { - margin-left: 0; - margin-right: 0; - width: auto; - - &:first-child { - margin-top: 0; - padding-top: 0; - } - } - } - } - - &.nav-separator { - margin: 0; - padding: 0; - height: 1px; - } - } - - &.sticky-bottom { - height: initial; - margin-bottom: 0; - } - } - - &[data-collapse="false"] { - left: 0px; - width: variables.$sidebar-wide-width; - max-width: variables.$sidebar-wide-width; - @include mixins.transition( left variables.$transition-base, width variables.$transition-base, box-shadow variables.$transition-base ); - - .navbar-toggler { - left: 0px; - } - - .nav-items { - .nav-item { - width: inherit; - overflow: hidden; - - .item-link { - width: inherit; - overflow: hidden; - - .item-content { - width: inherit; - overflow: hidden; - } - } - - &.nav-group { - width: calc(variables.$sidebar-wide-width - 10px); - display: inline-flex; - flex-direction: row; - flex-wrap: nowrap; - align-content: center; - justify-content: space-between; - align-items: center; - } - } - - &.sticky-bottom { - height: initial; - } - } - } - - @include mixins.media-breakpoint-up(medium) { - left: 0; - padding: 0; - position: relative; - width: variables.$sidebar-medium-width; - max-width: variables.$sidebar-medium-width; - - .navbar-header-container { - height: calc(variables.$header-medium-height + 7px); - - .navbar-toggler { - left: 0px; - } - } - - .nav-items { - height: calc(100vh - variables.$header-medium-height - variables.$grid-separator); - - .nav-item { - width: auto; - - .item-link { - width: calc(variables.$sidebar-medium-width - 11px); - } - - .collapsed { - width: 0; - display: none; - } - - &.nav-group-child { - width: 0; - overflow: hidden; - } - } - } - - &[data-collapse="false"] { - position: absolute; - - .nav-items { - .nav-item { - .collapsed { - width: auto; - display: block; - } - - &.nav-group-child { - width: auto; - overflow: hidden; - } - } - } - } - } - - @include mixins.media-breakpoint-up(wide) { - left: 0; - padding: 0; - position: relative; - width: variables.$sidebar-medium-width; - - .navbar-header-container { - height: calc(variables.$header-wide-height + 7px); - - .navbar-toggler { - left: 0px; - } - } - - - - &[data-collapse="false"] { - position: relative; - - .nav-items { - height: calc(100vh - variables.$header-wide-height - variables.$grid-separator); - - .nav-item { - .collapsed { - width: auto; - display: block; - } - - &.nav-group-child { - width: auto; - overflow: hidden; - } - } - } - } - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_page.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_page.scss deleted file mode 100644 index faac2967ba..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_page.scss +++ /dev/null @@ -1,13 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -.page { - grid-area: page; - border-width: 1px; - border-style: solid; - border-top-left-radius: 5px; - - h1 { - margin-top: 0; - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_scrollbars.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_scrollbars.scss deleted file mode 100644 index 1fa657c84d..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_scrollbars.scss +++ /dev/null @@ -1,38 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -.scrollable { - overflow-y: overlay; - overflow-x: overlay; - - &.vertical { - overflow-y: overlay; - overflow-x: hidden; - } - - &.horizontal { - overflow-y: hidden; - overflow-x: overlay; - } - /* Works on Chrome, Edge, and Safari */ - &::-webkit-scrollbar { - width: 3px; - @include mixins.transition(all variables.$transition-base); - } - - &::-webkit-scrollbar-track { - border-radius: 999px; - } - - &::-webkit-scrollbar-thumb { - border-radius: 999px; - border-width: 3px; - border-style: solid; - } - - &:hover { - &::-webkit-scrollbar { - width: 12px; - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_text.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_text.scss deleted file mode 100644 index b0629b2b08..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_text.scss +++ /dev/null @@ -1,38 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -:root { - --font-weight-thin: 100; - --font-weight-extra-light: 200; - --font-weight-light: 300; - --font-weight-normal: 400; - --font-weight-medium: 500; - --font-weight-semi-bold: 600; - --font-weight-bold: 700; - --font-weight-extra-bold: 800; - --font-weight-black: 900; -} - -.body-strong-text-block { - font-size: 14px; - line-height: 18px; - font-weight: var(--font-weight-semi-bold); - text-overflow: ellipsis; - word-wrap: break-word; -} - -.caption-text-block { - font-size: 12px; - line-height: 15px; - font-weight: var(--font-weight-normal); - text-overflow: ellipsis; - word-wrap: break-word; -} - -.subtitle-text-block { - font-size: 20px; - line-height: 26px; - font-weight: var(--font-weight-normal); - text-overflow: ellipsis; - word-wrap: break-word; -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_transitions.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_transitions.scss deleted file mode 100644 index e857a7d14f..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/features/_transitions.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables" as variables; - -@keyframes entranceThemeTransitionKeyFrames { - from { - opacity: 0; - transform: translateY(150px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} - -.entranceThemeTransition { - animation-name: entranceThemeTransitionKeyFrames; - animation-duration: 0.15s; - animation-timing-function: ease-out; -} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_backdrop-filter.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_backdrop-filter.scss deleted file mode 100644 index f2256daeec..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_backdrop-filter.scss +++ /dev/null @@ -1,27 +0,0 @@ -@use '../configs/variables' as variables; - -@mixin backdrop-filter($filter...) { - @if variables.$enable-filter { - $result: (); - - @each $value in $filter { - @if $value != null { - $result: append($result, $value, "comma"); - } - - @if $value == none and length($filter) > 1 { - @warn "The keyword 'none' must be used as a single argument."; - } - } - - @if (length($result) > 0) { - -webkit-backdrop-filter: $result; - backdrop-filter: $result; - } - } -} - - -@mixin mica { - @include backdrop-filter(blur(120px)); -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_box-shadow.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_box-shadow.scss deleted file mode 100644 index e8e91849cd..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_box-shadow.scss +++ /dev/null @@ -1,42 +0,0 @@ -@use '../configs/variables' as variables; - -@mixin box-shadow($shadow...) { - @if variables.$enable-shadows { - $result: (); - - @each $value in $shadow { - @if $value != null { - $result: append($result, $value, "comma"); - } - - @if $value == none and length($shadow) > 1 { - @warn "The keyword 'none' must be used as a single argument."; - } - } - - @if (length($result) > 0) { - box-shadow: $result; - } - } -} - - -// cards, grid item -@mixin depth-04 { - @include box-shadow(0px 0.3px 0.9px var(--palette-neutral-black-10), 0px 1.6px 3.6px var(--palette-neutral-black-10)); -} - -// command bar, dropdown, context menu -@mixin depth-08 { - @include box-shadow(0px 0.6px 1.8px var(--palette-neutral-black-10), 0px 3.2px 7.2px var(--palette-neutral-black-10)); -} - -// callout, hover card, tooltip -@mixin depth-16 { - @include box-shadow(0px 1.2px 3.6px var(--palette-neutral-black-10), 0px 6.4px 14.4px var(--palette-neutral-black-10)); -} - -// panel, popup dialogs -@mixin depth-64 { - @include box-shadow(0px 4.8px 14.4px var(--palette-neutral-black-20), 0px 25.6px 57.6px var(--palette-neutral-black-20)); -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_breakpoints.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_breakpoints.scss deleted file mode 100644 index 6cd8dd505c..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_breakpoints.scss +++ /dev/null @@ -1,138 +0,0 @@ -@use "../configs/variables" as variables; - -// Breakpoint viewport sizes and media queries. -// -// Breakpoints are defined as a map of (name: minimum width), order from small to large: -// -// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px) -// -// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default. -// Name of the next breakpoint, or null for the last breakpoint. -// -// >> breakpoint-next(sm) -// md -// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) -// md -// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl)) -// md -@function breakpoint-next($name, $breakpoints: variables.$grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) { - $n: index($breakpoint-names, $name); - - @if not $n { - @error "breakpoint `#{$name}` not found in `#{$breakpoints}`"; - } - - @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); -} - -// Minimum breakpoint width. Null for the smallest (first) breakpoint. -// -// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) -// 576px -@function breakpoint-min($name, $breakpoints: variables.$grid-breakpoints) { - $min: map-get($breakpoints, $name); - @return if($min != 0, $min, null); -} - -// Maximum breakpoint width. -// The maximum value is reduced by 0.02px to work around the limitations of -// `min-` and `max-` prefixes and viewports with fractional widths. -// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max -// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari. -// See https://bugs.webkit.org/show_bug.cgi?id=178261 -// -// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) -// 767.98px -@function breakpoint-max($name, $breakpoints: variables.$grid-breakpoints) { - $max: map-get($breakpoints, $name); - @return if($max and $max > 0, $max - .02, null); -} - -// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front. -// Useful for making responsive utilities. -// -// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) -// "" (Returns a blank string) -// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) -// "-sm" -@function breakpoint-infix($name, $breakpoints: variables.$grid-breakpoints) { - @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}"); -} - -// Media of at least the minimum breakpoint width. No query for the smallest breakpoint. -// Makes the @content apply to the given breakpoint and wider. -@mixin media-breakpoint-up($name, $breakpoints: variables.$grid-breakpoints) { - $min: breakpoint-min($name, $breakpoints); - - @if $min { - @media (min-width: $min) { - @content; - } - } - @else { - @content; - } -} - -// Media of at most the maximum breakpoint width. No query for the largest breakpoint. -// Makes the @content apply to the given breakpoint and narrower. -@mixin media-breakpoint-down($name, $breakpoints: variables.$grid-breakpoints) { - $max: breakpoint-max($name, $breakpoints); - - @if $max { - @media (max-width: $max) { - @content; - } - } - @else { - @content; - } -} - -// Media that spans multiple breakpoint widths. -// Makes the @content apply between the min and max breakpoints -@mixin media-breakpoint-between($lower, $upper, $breakpoints: variables.$grid-breakpoints) { - $min: breakpoint-min($lower, $breakpoints); - $max: breakpoint-max($upper, $breakpoints); - - @if $min != null and $max != null { - @media (min-width: $min) and (max-width: $max) { - @content; - } - } - @else if $max == null { - @include media-breakpoint-up($lower, $breakpoints) { - @content; - } - } - @else if $min == null { - @include media-breakpoint-down($upper, $breakpoints) { - @content; - } - } -} - -// Media between the breakpoint's minimum and maximum widths. -// No minimum for the smallest breakpoint, and no maximum for the largest one. -// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower. -@mixin media-breakpoint-only($name, $breakpoints: variables.$grid-breakpoints) { - $min: breakpoint-min($name, $breakpoints); - $next: breakpoint-next($name, $breakpoints); - $max: breakpoint-max($next, $breakpoints); - - @if $min != null and $max != null { - @media (min-width: $min) and (max-width: $max) { - @content; - } - } - @else if $max == null { - @include media-breakpoint-up($name, $breakpoints) { - @content; - } - } - @else if $min == null { - @include media-breakpoint-down($next, $breakpoints) { - @content; - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_gradient.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_gradient.scss deleted file mode 100644 index 9675b897ab..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_gradient.scss +++ /dev/null @@ -1,9 +0,0 @@ -@use '../configs/variables' as variables; - -// stylelint-disable property-disallowed-list -@mixin gradient($color1, $color2) { - background-color: $color1; - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#{$color1}, endColorstr=#{$color2}); - background-image: -moz-linear-gradient(center top, $color1, $color2); - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from($color1), to($color2)); -} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_index.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_index.scss deleted file mode 100644 index 7450008ba9..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_index.scss +++ /dev/null @@ -1,8 +0,0 @@ -@forward 'box-shadow'; -@forward 'breakpoints'; -@forward 'gradient'; -@forward 'placeholder'; -@forward 'texts'; -@forward 'transition'; -@forward 'transform'; -@forward 'backdrop-filter'; \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_placeholder.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_placeholder.scss deleted file mode 100644 index b53ce6d948..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_placeholder.scss +++ /dev/null @@ -1,24 +0,0 @@ -@use '../configs/variables' as variables; - -// stylelint-disable property-disallowed-list -@mixin placeholder ($color, $font-size) { - ::-webkit-input-placeholder { - color: $color !important; - font-size: $font-size !important; - } - - :-moz-placeholder { - color: $color !important; - font-size: $font-size !important; - } - - ::-moz-placeholder { - color: $color !important; - font-size: $font-size !important; - } - - :-ms-input-placeholder { - color: $color !important; - font-size: $font-size !important; - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_texts.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_texts.scss deleted file mode 100644 index 84d08e8e0a..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_texts.scss +++ /dev/null @@ -1,23 +0,0 @@ - - -@mixin fontSize1() { - font-size: .875rem; - font-weight: 600; - line-height: normal; - font-style: normal; - font-family: "Segoe UI"; -} - -@mixin fontSize42() { - font-size: 42px; - font-weight: 600; - line-height: 52px; - font-style: normal; - font-family: inherit; -} - -@mixin textEllipsis() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transform.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transform.scss deleted file mode 100644 index ba78162f83..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transform.scss +++ /dev/null @@ -1,58 +0,0 @@ -@use '../configs/variables' as variables; - -// stylelint-disable property-disallowed-list -@mixin transform($transform...) { - @if length($transform) > 1 { - @each $value in $transform { - @if $value == null or $value == none { - @warn "The keyword 'none' or 'null' must be used as a single argument."; - } - } - } - - @if variables.$enable-transforms { - @if nth($transform, 1) != null { - -webkit-transform: $transform; - -ms-transform: $transform; - -o-transform: $transform; - transform: $transform; - } - - @if variables.$enable-reduced-motion and nth($transform, 1) != null and nth($transform, 1) != none { - @media (prefers-reduced-motion: reduce) { - -webkit-transform: none; - -ms-transform: none; - -o-transform: none; - transform: none; - } - } - } -} - -@mixin transform-origin($transform...) { - @if length($transform) > 1 { - @each $value in $transform { - @if $value == null or $value == none { - @warn "The keyword 'none' or 'null' must be used as a single argument."; - } - } - } - - @if variables.$enable-transforms { - @if nth($transform, 1) != null { - -webkit-transform-origin: $transform; - -ms-transform-origin: $transform; - -o-transform-origin: $transform; - transform-origin: $transform; - } - - @if variables.$enable-reduced-motion and nth($transform, 1) != null and nth($transform, 1) != none { - @media (prefers-reduced-motion: reduce) { - -webkit-transform-origin: none; - -ms-transform-origin: none; - -o-transform-origin: none; - transform-origin: none; - } - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transition.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transition.scss deleted file mode 100644 index 6b57c97994..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/mixins/_transition.scss +++ /dev/null @@ -1,34 +0,0 @@ -@use '../configs/variables' as variables; - -// stylelint-disable property-disallowed-list -@mixin transition($transition...) { - @if length($transition) == 0 { - $transition: variables.$transition-all; - } - - @if length($transition) > 1 { - @each $value in $transition { - @if $value == null or $value == none { - @warn "The keyword 'none' or 'null' must be used as a single argument."; - } - } - } - - @if variables.$enable-transitions { - @if nth($transition, 1) != null { - -webkit-transition: $transition; - -o-transition: $transition; - -ms-transition: $transition; - transition: $transition; - } - - @if variables.$enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { - @media (prefers-reduced-motion: reduce) { - -webkit-transition: none; - -o-transition: none; - -ms-transition: none; - transition: none; - } - } - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/_default.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/_default.scss index 357f5a559b..f7e67c9a5f 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/_default.scss +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/_default.scss @@ -1,277 +1,68 @@ -@use "../mixins/index" as mixins; -@use "../configs/variables"; - -:root { - --current-accent-color: #60cdff; - --background-color: #202020; - /*--page-background-color: rgba(58, 58, 58, 0.3);*/ - --page-background-color: rgba(44, 44, 44, 0.96); - --sidebar-hover-background-color: rgba(255, 255, 255, 0.1); - // --neutral-fill-stealth-rest: blue; - - --system-reveal-base-low-color: rgba(255, 255, 255, 0.2); - --subtle-fill-color-secondary: rgba(255, 255, 255, 0.06); - - --card-background-fill-color-default: rgba(255, 255, 255, 0.05); - --card-stroke-color-default: rgba(0, 0, 0, 0.3); - - --text-fill-color-primary: rgba(255, 255, 255, 1); - --text-fill-color-secondary: rgba(255, 255, 255, 0.77); - - --navbar-border-color: transparent; - --navbar-background-color: transparent; - --navbar-item-color: #ffffff; - --navbar-separator-background-color: rgba(255, 255, 255, 0.0605); - --navbar-item-hover-border-color: rgba(255, 255, 255, 0.1); - --navbar-item-hover-background-color: rgba(255, 255, 255, 0.1); - --navbar-flyout-border-color: #202020; - --navbar-flyout-background-color: #2c2c2c; - --button-text-primary-color: #ffffff; - // scrollbar - --scrollbar-track-background-color: transparent; - --scrollbar-track-background-color-hover: rgba(44, 44, 44, 0.96); - --scrollbar-thumb-border-color: transparent; - --scrollbar-thumb-border-color-hover: rgba(44, 44, 44, 0.96); - --scrollbar-thumb-background-color: rgba(255, 255, 255, 0.5442); - --scrollbar-thumb-background-color-hover: rgba(255, 255, 255, 0.5442); - - @include mixins.media-breakpoint-up(wide) { - --navbar-border-color: rgba(0, 0, 0, 0.1); - --navbar-background-color: #202020; - } -} - -html[data-theme="light-fluent"] { +@import 'windows/dark'; +@import 'windows/light'; +@import 'macos/dark'; +@import 'macos/light'; + +html, body { + /* Font Families */ + --font-family-fallback: + "Segoe UI", /* Windows (Vista+) and Windows Phone. */ + -apple-system, /* San Francisco in Safari (on Mac OS X and iOS); Neue Helvetica and Lucida Grande on older versions of Mac OS X. */ + BlinkMacSystemFont, /* Equivalent of -apple-system, for Chrome on Mac OS X. */ + Roboto, /* Android (Ice Cream Sandwich (4.0)+) and Chrome OS. */ + Ubuntu, /* all versions of Ubuntu. */ + system-ui, /* Default UI font on a given platform. */ + 'Helvetica Neue', Helvetica, Arial, sans-serif; /* Fallback */ + --font-family-text: "Segoe UI Variable Text", "Seoge UI Variable Static Text", var(--font-family-fallback); + --font-family-small: "Segoe UI Variable Small", "Seoge UI Variable Static Small", var(--font-family-fallback); + --font-family-display: "Segoe UI Variable Display", "Seoge UI Variable Static Display", var(--font-family-fallback); + + /* Font Size */ + --font-size-caption: 12px; + --font-size-body: 14px; + --font-size-body-large: 18px; + --font-size-subtitle: 20px; + --font-size-title: 28px; + --font-size-title-large: 40px; + --font-size-display: 68px; + + /* Roundness */ + --control-corner-radius: 4px; + --overlay-corner-radius: 8px; + + /* Focus Stroke */ + --focus-stroke: + 0 0 0 1px var(--focus-stroke-inner), + 0 0 0 3px var(--focus-stroke-outer); } -html[data-theme="dark-fluent"] { - --background-color: rgba(32, 32, 32, 0.8); - --page-background-color: rgba(255, 255, 255, 0.1); - --sidebar-hover-background-color: rgba(255, 255, 255, 0.0605); +/* Themes */ +div[data-theme='windows-dark-theme'] { + @include windows-dark; } -html[data-theme="light-macos"] { +div[data-theme='windows-light-theme'] { + @include windows-light; } -html[data-theme="dark-macos"] { +div[data-theme='macos-dark-theme'] { + @include macos-dark; } -body { - background: var(--background-color); - - .navbar { - &.navbar-vertical { - border-color: var(--navbar-flyout-border-color); - background-color: var(--navbar-flyout-background-color); - - .nav-items { - .nav-item { - border-color: transparent; - background-color: transparent; - - .item-link { - color: var(--navbar-item-color); - - &::before { - background: transparent; - } - } - - &.active, - &:hover { - border-color: var(--navbar-item-hover-border-color); - background-color: var(--navbar-item-hover-background-color); - - button { - &.stealth { - &:hover { - border-color: transparent; - background-color: transparent; - } - } - } - } - - &.active { - .item-link { - &::before { - background: var(--current-accent-color); - } - } - } - - &.nav-group-child { - &.active, - &:hover { - border-color: transparent; - background-color: transparent; - } - } - - &.nav-separator { - border-color: transparent; - background-color: var(--navbar-separator-background-color); - } - } - } - - &[data-collapse="false"] { - @include mixins.box-shadow(0px 8px 16px rgba(0, 0, 0, 0.26)); - } - - @include mixins.media-breakpoint-up(medium) { - border-color: var(--navbar-border-color); - background-color: var(--navbar-background-color); - - .nav-items { - } - - &[data-collapse="false"] { - border-color: var(--navbar-flyout-border-color); - background-color: var(--navbar-flyout-background-color); - } - } - - @include mixins.media-breakpoint-up(wide) { - border-color: var(--navbar-border-color); - background-color: var(--navbar-background-color); - - &[data-collapse="false"] { - border-color: var(--navbar-border-color); - background-color: var(--navbar-background-color); - @include mixins.box-shadow(none); - } - } - // .form-input-group { - // color: rgba(255, 255, 255, 0.786); - // border-color: transparent; - // border-bottom-color: transparent; - // background-color: transparent; - // } - // .nav-items { - // .nav-item { - // &.list-item-container { - // color: #ffffff; - // color: var(--sidebar-content-color, #ffffff); - // } - // &.nav-group-child { - // &.active, - // &:hover { - // border-color: transparent; - // background-color: transparent; - // } - // } - // } - // } - // .navbar-toggler { - // background: inherit; - // } - // &.show { - // .form-input-group { - // color: rgba(255, 255, 255, 0.786); - // border-color: transparent; - // border-bottom-color: rgba(255, 255, 255, 0.54); - // background-color: rgba(255, 255, 255, 0.0605); - // } - // } - } - } - - .page { - color: #ffffff; - border-color: rgba(0, 0, 0, 0.1); - background: rgba(58, 58, 58, 0.3); - } - - input[type="text"] { - color: rgba(255, 255, 255, 0.786); - background-color: rgba(255, 255, 255, 0.0605); - border-color: transparent; - border-bottom-color: rgba(255, 255, 255, 0.54); - - &:focus { - color: rgba(255, 255, 255, 0.786); - background-color: rgba(30, 30, 30, 0.7); - border-color: rgba(255, 255, 255, 0.0698); - border-bottom-color: rgba(96, 205, 255, 1); - } - } - - .form-input-group { - color: rgba(255, 255, 255, 0.786); - border-color: transparent; - border-bottom-color: rgba(255, 255, 255, 0.54); - background-color: rgba(255, 255, 255, 0.0605); - - input[type="text"] { - color: inherit; - background-color: transparent; - border-color: transparent; - border-bottom-color: transparent; - } - - .form-input-group-text { - color: inherit; - background-color: transparent; - border-color: transparent; - border-bottom-color: transparent; - } - - &:focus-within { - color: rgba(255, 255, 255, 0.786); - background-color: rgba(30, 30, 30, 0.7); - border-color: rgba(255, 255, 255, 0.0698); - border-bottom-color: rgba(96, 205, 255, 1); - - input[type="text"] { - &:focus { - border-color: transparent; - border-bottom-color: transparent; - } - } - } - } - - button { - &.stealth { - color: #ffffff; - color: var(--button-text-primary-color, #ffffff); - border-color: transparent; - background-color: transparent; - - &:hover { - border-color: rgba(255, 255, 255, 0.0605); - background-color: rgba(255, 255, 255, 0.0605); - } - } - } - - .scrollable { - &::-webkit-scrollbar-track { - background: var(--scrollbar-track-background-color); - } - - &::-webkit-scrollbar-thumb { - border-color: var(--scrollbar-thumb-border-color); - background-color: var(--scrollbar-thumb-background-color); - } - - &:hover { - &::-webkit-scrollbar-track { - background: var(--scrollbar-track-background-color-hover); - } - - &::-webkit-scrollbar-thumb { - border-color: var(--scrollbar-thumb-border-color-hover); - background-color: var(--scrollbar-thumb-background-color-hover); - } - } - } +div[data-theme='macos-light-theme'] { + @include macos-light; } -/* Works on Firefox */ -* { - scrollbar-width: thin; - scrollbar-color: blue orange; +div { + color: var(--text-fill-color-primary); } +.theme-transition, +.theme-transition *, +.theme-transition *:before, +.theme-transition *:after { + transition-property: color, background-color; + transition-timing-function: ease-out; + transition-duration: 200ms; + transition-delay: 0 !important; +} \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/dark.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/dark.scss new file mode 100644 index 0000000000..d899c8a6e0 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/dark.scss @@ -0,0 +1,3 @@ +@mixin macos-dark { + --text-fill-color-primary: rgba(255, 255, 255, 1); +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/light.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/light.scss new file mode 100644 index 0000000000..629a64d873 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/macos/light.scss @@ -0,0 +1,3 @@ +@mixin macos-light { + --text-fill-color-primary: rgba(0, 0, 0, 1); +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/dark.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/dark.scss new file mode 100644 index 0000000000..74b0e10d41 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/dark.scss @@ -0,0 +1,169 @@ +@mixin windows-dark { + /* Accent Colors (rgb) */ + --accent-light-3: 154, 236, 254; + --accent-light-2: 98, 205, 254; + --accent-light-1: 0, 146, 250; + --accent-base: 0, 121, 214; + --accent-dark-1: 0, 95, 184; + --accent-dark-2: 0, 62, 148; + --accent-dark-3: 0, 24, 102; + --accent-default: rgba(var(--accent-light-2)); + --accent-secondary: rgba(var(--accent-light-2), 0.9); + --accent-tertiary: rgba(var(--accent-light-2), 0.8); + --accent-disabled: rgba(255, 255, 255, 0.158); + + /* Text on Accent */ + --text-on-accent-primary: rgb(0, 0, 0); + --text-on-accent-secondary: rgba(0, 0, 0, 0.5); + --text-on-accent-disabled: rgba(255, 255, 255, 0.53); + --text-on-accent-selected: rgb(255, 255, 255); + + /* Focus Stroke */ + --focus-stroke-outer: rgb(255, 255, 255); + --focus-stroke-inner: rgba(0, 0, 0, 0.7); + + /* Text */ + --text-fill-color-primary: rgba(255, 255, 255, 1); + --text-fill-color-secondary: rgba(255, 255, 255, 0.77); + --text-fill-color-tertiary: rgba(255, 255, 255, 0.53); + --text-fill-color-disabled: rgba(255, 255, 255, 0.36); + --text-fill-color-inverse: rgba(0, 0, 0, 0.89); + + /* Control Fill */ + --control-fill-color-default: rgba(255, 255, 255, 0.059); + --control-fill-color-secondary: rgba(255, 255, 255, 0.082); + --control-fill-color-tertiary: rgba(255, 255, 255, 0.031); + --control-fill-color-disabled: rgba(255, 255, 255, 0.043); + --control-fill-color-transparent: rgba(255, 255, 255, 0); + --control-fill-color-input-active: rgba(30, 30, 30, 0.702); + + /* Control Stroke */ + --control-stroke-color-default: rgba(255, 255, 255, 0.071); + --control-stroke-color-secondary: rgba(255, 255, 255, 0.094); + --control-stroke-on-accent-default: hsla(0, 0%, 100%, 8%); + --control-stroke-on-accent-secondary: hsla(0, 0%, 0%, 14%); + --control-strong-stroke-default: rgba(255, 255, 255, 0.544); + + /* Subtle Fill */ + --subtle-fill-transparent: transparent; + --subtle-fill-secondary: rgba(255, 255, 255, 0.061); + --subtle-fill-tertiary: rgba(255, 255, 255, 0.042); + --subtle-fill-disabled: transparent; + + /* Background */ + --background-color: rgba(32, 32, 32, 1); + --layer-fill-color-default: rgba(58, 58, 58, 0.3); + + /* Borders */ + --control-border-color-default: + var(--control-stroke-color-secondary) + var(--control-stroke-color-default) + var(--control-stroke-color-default) + var(--control-stroke-color-default); + --accent-control-border-color-default: + var(--control-stroke-on-accent-default) + var(--control-stroke-on-accent-secondary) + var(--control-stroke-on-accent-secondary) + var(--control-stroke-on-accent-secondary); + + /* Card */ + --card-stroke-color-default: rgba(0, 0, 0, 0.06); + --card-background-color: rgba(255, 255, 255, 0.05); + --card-hover-background-color: rgba(255, 255, 255, 0.06); + + /* Button */ + --button-background: var(--control-fill-color-default); + --button-background-pointer-over: var(--control-fill-color-secondary); + --button-background-pressed: var(--control-fill-color-tertiary); + --button-background-disabled: var(--control-fill-color-disabled); + --button-foreground: var(--text-fill-color-primary); + --button-foreground-pointer-over: var(--text-fill-color-primary); + --button-foreground-pressed: var(--text-fill-color-secondary); + --button-foreground-disabled: var(--text-fill-color-disabled); + --button-border: var(--control-border-color-default); + --button-border-pointer-over: var(--control-border-color-default); + --button-border-pressed: var(--control-stroke-color-default); + --button-border-disabled: var(--control-stroke-color-default); + --button-border-thickness: 1px solid; + + --accent-button-background: var(--accent-default); + --accent-button-background-pointer-over: var(--accent-secondary); + --accent-button-background-pressed: var(--accent-tertiary); + --accent-button-background-disabled: var(--accent-disabled); + --accent-button-foreground: var(--text-on-accent-primary); + --accent-button-foreground-pointer-over: var(--text-on-accent-primary); + --accent-button-foreground-pressed: var(--text-on-accent-secondary); + --accent-button-foreground-disabled: var(--text-on-accent-disabled); + --accent-button-border: var(--accent-control-border-color-default); + --accent-button-border-pointer-over: var(--accent-control-border-color-default); + --accent-button-border-pressed: var(--control-fill-color-transparent); + --accent-button-border-disabled: var(--control-fill-color-transparent); + --accent-button-border-thickness: 1px solid; + + --stealth-button-background: var(--control-fill-color-transparent); + --stealth-button-background-pointer-over: var(--control-fill-color-secondary); + --stealth-button-background-pressed: var(--control-fill-color-tertiary); + --stealth-button-background-disabled: var(--control-fill-color-transparent); + --stealth-button-foreground: var(--text-fill-color-primary); + --stealth-button-foreground-pointer-over: var(--text-fill-color-primary); + --stealth-button-foreground-pressed: var(--text-fill-color-secondary); + --stealth-button-foreground-disabled: var(--text-fill-color-disabled); + --stealth-button-border: var(--control-fill-color-transparent); + --stealth-button-border-pointer-over: var(--control-border-color-default); + --stealth-button-border-pressed: var(--control-stroke-color-default); + --stealth-button-border-disabled: var(--control-fill-color-transparent); + --stealth-button-border-thickness: 1px solid; + + /* GridView */ + --grid-view-header-border-line: rgba(255, 255, 255, 0.2); + --grid-view-item-background: var(--card-background-color); + --grid-view-item-background-hover: var(--card-hover-background-color); + --grid-view-item-stroke: rgba(0, 0, 0, 0.3); + + /* NavBar */ + --navigation-view-content-background: var(--layer-fill-color-default); + --navigation-view-content-grid-border: var(--card-stroke-color-default); + --navigation-view-content-grid-border-thickness: 1px solid; + --navigation-view-flyout-border-color: var(--control-stroke-color-secondary); + --navigation-view-flyout-background-color: rgba(32, 32, 32, 0.4); + --navigation-view-flyout-backdrop-filter: blur(50px) saturate(125%); + --navigation-view-separator-color: rgba(255, 255, 255, 0.0605); + + /* List Box */ + --list-box-item-background: var(--subtle-fill-transparent); + --list-box-item-background-disabled: var(--subtle-fill-transparent); + --list-box-item-background-pointer-over: var(--subtle-fill-secondary); + --list-box-item-background-selected: var(--subtle-fill-secondary); + --list-box-item-background-selected-disabled: var(--subtle-fill-secondary); + --list-box-item-background-active: var(--subtle-fill-tertiary); + --list-box-item-foreground: var(--text-fill-color-primary); + --list-box-item-foreground-active: var(--text-fill-color-secondary); + --list-box-item-foreground-disabled: var(--text-fill-color-disabled); + + /* Text Box */ + --text-box-background: var(--control-fill-color-default); + --text-box-background-pointer-over: var(--control-fill-color-secondary); + --text-box-background-focused: var(--control-fill-color-input-active); + --text-box-background-disabled: var(--control-fill-color-disabled); + --text-box-border: var(--control-stroke-color-default); + --text-box-border-pointer-over: var(--control-stroke-color-default); + --text-box-border-focused: var(--control-stroke-color-default); + --text-box-border-disabled: var(--control-stroke-color-default); + --text-box-foreground: var(--text-fill-color-primary); + --text-box-foreground-pointer-over: var(--text-fill-color-primary); + --text-box-foreground-focused: var(--text-fill-color-primary); + --text-box-foreground-disabled: var(--text-fill-color-disabled); + --text-box-placeholder-foreground: var(--text-fill-color-secondary); + --text-box-placeholder-foreground-pointer-over: var(--text-fill-color-secondary); + --text-box-placeholder-foreground-focused: var(--text-fill-color-tertiary); + --text-box-placeholder-foreground-disabled: var(--text-fill-color-disabled); + --text-box-selection-highlight-color: rgb(var(--accent-base)); + + /* Scrollbars */ + --scrollbar-track-background-color: transparent; + --scrollbar-track-background-color-hover: rgba(44, 44, 44, 0.96); + --scrollbar-thumb-border-color: transparent; + --scrollbar-thumb-border-color-hover: rgba(44, 44, 44, 0.96); + --scrollbar-thumb-background-color: rgba(255, 255, 255, 0.5442); + --scrollbar-thumb-background-color-hover: rgba(255, 255, 255, 0.5442); +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/light.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/light.scss new file mode 100644 index 0000000000..e29300cd9a --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Assets/sass/theme/windows/light.scss @@ -0,0 +1,4 @@ +@mixin windows-light { + --text-fill-color-primary: rgba(0, 0, 0, 1); + --background-color: rgba(255, 255, 255, 1); // not sure if good. TODO +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor new file mode 100644 index 0000000000..657afe7f0c --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor @@ -0,0 +1,20 @@ +@namespace DevToys.MauiBlazor.Components +@inherits StyledComponentBase + + + + + + + + \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor.cs new file mode 100644 index 0000000000..4f512afd27 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor.cs @@ -0,0 +1,35 @@ +namespace DevToys.MauiBlazor.Components; + +public partial class AutoSuggestBox : StyledComponentBase +{ + private TextBox? _textBox = default!; + + [Parameter] + public string? Header { get; set; } + + [Parameter] + public string? Placeholder { get; set; } + + [Parameter] + public string? Query { get; set; } + + [Parameter] + public bool IsEnabled { get; set; } = true; + + [Parameter] + public bool IsReadOnly { get; set; } + + [Parameter] + public EventCallback QueryChanged { get; set; } + + internal ValueTask FocusAsync() + { + Guard.IsNotNull(_textBox); + return _textBox.FocusAsync(); + } + + private Task OnTextBoxTextChangedAsync(string text) + { + return QueryChanged.InvokeAsync(text); + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/AutoSuggestBox/AutoSuggestBox.razor.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor new file mode 100644 index 0000000000..c0a423af3f --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor @@ -0,0 +1,14 @@ +@namespace DevToys.MauiBlazor.Components + +@inherits JSStyledComponentBase + + + + \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.cs new file mode 100644 index 0000000000..5f3e127740 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.cs @@ -0,0 +1,43 @@ +namespace DevToys.MauiBlazor.Components; + +public partial class Button : JSStyledComponentBase +{ + [Parameter] + public bool IsEnabled { get; set; } = true; + + [Parameter] + public ButtonAppearance Appearance { get; set; } = ButtonAppearance.Neutral; + + /// + /// Gets or sets the content to be rendered inside the component. + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } + + protected override void OnParametersSet() + { + CSS.Clear(); + CSS.Add($"type-{Appearance.Class}"); + + if (IsEnabled && AdditionalAttributes is not null) + { + AdditionalAttributes.Remove("disabled"); + } + + if (!IsEnabled) + { + CSS.Add("disabled"); + + AdditionalAttributes ??= new Dictionary(); + + AdditionalAttributes.TryAdd("disabled", true); + } + + base.OnParametersSet(); + } + + internal ValueTask FocusAsync() + { + return JSRuntime.InvokeVoidAsync("devtoys.DOM.setFocus", Element); + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.scss new file mode 100644 index 0000000000..ba24cbe718 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/Button.razor.scss @@ -0,0 +1,106 @@ +@use "../../Assets/sass/devtoys" as *; + +// TODO: credit https://fluent-svelte.vercel.app/docs in Third Party Licenses. + +button { + @include flex($inline: true, $align: center, $justify: center); + @include typography-body; + position: relative; + box-sizing: border-box; + padding-block: 4px 6px; + padding-inline: 11px; + text-decoration: none; + border: none; + outline: none; + cursor: default; + border-radius: var(--control-corner-radius); + transition: 83ms ease background; + + &:focus-visible { + box-shadow: var(--focus-stroke); + } + + &.type- { + &neutral { + border: var(--button-border-thickness); + border-color: var(--button-border); + background-color: var(--button-background); + color: var(--button-foreground); + background-clip: padding-box; + + &:hover { + border-color: var(--button-border-pointer-over); + background-color: var(--button-background-pointer-over); + color: var(--button-foreground-pointer-over); + } + + &:active { + border-color: var(--button-border-pressed); + background-color: var(--button-background-pressed); + color: var(--button-foreground-pressed); + } + + &.disabled { + border-color: var(--button-border-disabled); + background-color: var(--button-background-disabled); + color: var(--button-foreground-disabled); + } + } + + &accent { + border: var(--accent-button-border-thickness); + border-color: var(--accent-button-border); + background-color: var(--accent-button-background); + color: var(--accent-button-foreground); + transition: 83ms ease border-color; + + &:hover { + border-color: var(--accent-button-border-pointer-over); + background-color: var(--accent-button-background-pointer-over); + color: var(--accent-button-foreground-pointer-over); + } + + &:active { + border-color: var(--accent-button-border-pressed); + background-color: var(--accent-button-background-pressed); + color: var(--accent-button-foreground-pressed); + } + + &.disabled { + border-color: var(--accent-button-border-disabled); + background-color: var(--accent-button-background-disabled); + color: var(--accent-button-foreground-disabled); + } + } + + &stealth { + border: var(--stealth-button-border-thickness); + border-color: var(--stealth-button-border); + background-color: var(--stealth-button-background); + color: var(--stealth-button-foreground); + background-clip: padding-box; + + &:hover { + border-color: var(--stealth-button-border-pointer-over); + background-color: var(--stealth-button-background-pointer-over); + color: var(--stealth-button-foreground-pointer-over); + } + + &:active { + border-color: var(--stealth-button-border-pressed); + background-color: var(--stealth-button-background-pressed); + color: var(--stealth-button-foreground-pressed); + } + + &.disabled { + border-color: var(--stealth-button-border-disabled); + background-color: var(--stealth-button-background-disabled); + color: var(--stealth-button-foreground-disabled); + } + } + } + + &.disabled { + pointer-events: none; + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/ButtonAppearance.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/ButtonAppearance.cs new file mode 100644 index 0000000000..c394a99bab --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Button/ButtonAppearance.cs @@ -0,0 +1,16 @@ +namespace DevToys.MauiBlazor.Components; + +public sealed class ButtonAppearance +{ + internal static readonly ButtonAppearance Neutral = new("neutral"); + internal static readonly ButtonAppearance Accent = new("accent"); + internal static readonly ButtonAppearance Stealth = new("stealth"); + + private ButtonAppearance(string className) + { + Guard.IsNotNullOrWhiteSpace(className); + Class = className; + } + + public string Class { get; } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor new file mode 100644 index 0000000000..52a7caaf9e --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor @@ -0,0 +1,25 @@ +@namespace DevToys.MauiBlazor.Components +@inherits JSStyledComponentBase + + + + \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.cs new file mode 100644 index 0000000000..7cda054ddc --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.cs @@ -0,0 +1,24 @@ +namespace DevToys.MauiBlazor.Components; + +public partial class ContextMenuItem : JSStyledComponentBase +{ + [Parameter] + public string? Text { get; set; } + + [Parameter] + public char IconGlyph { get; set; } + + [Parameter] + public string IconFontFamily { get; set; } = "FluentSystemIcons"; + + [Parameter] + public string? KeyboardShortcut { get; set; } + + [Parameter] + public EventCallback OnClick { get; set; } + + private Task OnItemClickAsync() + { + return OnClick.InvokeAsync(); + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.scss new file mode 100644 index 0000000000..9b08010a61 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ContextMenu/ContextMenuItem.razor.scss @@ -0,0 +1,23 @@ +.context-menu-item { + padding: 8px 10px; + font-size: 15px; + color: #eee; + cursor: pointer; + border-radius: inherit; + display: flex; + gap: 8px; + + .font-icon { + align-self: center; + } + + .text { + flex-grow: 1; + align-self: center; + } + + .keyboard-accelerator { + color: var(--text-fill-color-secondary); + align-self: center; + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor deleted file mode 100644 index 18768c0a57..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor +++ /dev/null @@ -1,14 +0,0 @@ -@namespace DevToys.MauiBlazor.Components -@inherits StyledLayoutComponentBase - - - - \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.cs deleted file mode 100644 index eeb9459fc2..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Globalization; - -namespace DevToys.MauiBlazor.Components; - -public partial class Button : StyledLayoutComponentBase -{ - [Parameter] - public ButtonType Type { get; set; } = ButtonType.Button; - - [Parameter] - public string? Title { get; set; } - - [Parameter] - public bool IconOnly { get; set; } = false; - - [Parameter] - public ButtonAppearance Appearance { get; set; } = ButtonAppearance.Neutral; - - [Parameter] - public RenderFragment? ChildContent { get; set; } - - protected override void AppendClasses(ClassHelper helper) - { - helper.Append("button"); - helper.Append(Appearance.Code); - - if (IconOnly) - { - helper.Append("icon"); - } - - base.AppendClasses(helper); - } - - protected override void OnParametersSet() - { - if (AdditionalAttributes != null && AdditionalAttributes.TryGetValue("class", out object? obj)) - { - string classes = Convert.ToString(obj, CultureInfo.InvariantCulture) ?? string.Empty; - Classes = new HashSet(classes.Split(' ')); - } - - base.OnParametersSet(); - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.scss deleted file mode 100644 index 8c00e52343..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Control/Button.razor.scss +++ /dev/null @@ -1,21 +0,0 @@ -@use "../../Assets/sass/mixins/index" as mixins; -@use "../../Assets/sass/configs/variables" as variables; - -button { - padding: 7px 9px; - border-radius: 3px; - border-width: 1px; - border-style: solid; - - @include mixins.transition( color variables.$transition-base, background-color variables.$transition-base, border-color variables.$transition-base ); - - &.icon { - font-size: 16px; - line-height: 16px; - font-style: normal; - font-weight: 400; - } - - &.stealth { - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor index 9a0e551ab5..57267cf223 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor @@ -1,9 +1,10 @@ @namespace DevToys.MauiBlazor.Components -@inherits StyledLayoutComponentBase +@inherits StyledComponentBase diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.cs index 0c9a8a080c..06898c9a10 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.cs +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.cs @@ -1,17 +1,18 @@ namespace DevToys.MauiBlazor.Components; -public partial class FontIcon : StyledLayoutComponentBase +public partial class FontIcon : StyledComponentBase { [Parameter] public char Glyph { get; set; } [Parameter] - public string FontFamily { get; set; } = string.Empty; + public string FontFamily { get; set; } = "FluentSystemIcons"; - protected override void AppendClasses(ClassHelper helper) + protected override void OnParametersSet() { - helper.Append("font-icon"); - helper.Append(FontFamily); - base.AppendClasses(helper); + CSS.Clear(); + CSS.Add(FontFamily); + + base.OnParametersSet(); } } diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.scss index 7381bc4e92..3cce813b90 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.scss +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/FontIcon/FontIcon.razor.scss @@ -1,9 +1,15 @@ -@use "../../Assets/sass/mixins/index" as mixins; -@use "../../Assets/sass/configs/variables" as variables; - .font-icon { display: block; - color: var(--text-fill-color-primary); + color: currentColor; + user-select: none; + + /* Center the icon in its parent */ + margin: 0; + position: relative; + top: 50%; + left: 50%; + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); &::before { content: attr(data-glyph) diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Alignment.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Alignment.cs deleted file mode 100644 index a2b5f1c5c7..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Alignment.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace DevToys.MauiBlazor.Components; - -public static class Alignment -{ - public static CssAlignment Start => new("start"); - - public static CssAlignment Center => new("center"); - - public static CssAlignment End => new("end"); - - public static CssAlignment Stretch => new("stretch"); -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/ColumnDefinition.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/ColumnDefinition.razor deleted file mode 100644 index f2232643ed..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/ColumnDefinition.razor +++ /dev/null @@ -1,30 +0,0 @@ -@using Microsoft.Fast.Components.FluentUI -@using Microsoft.Fast.Components.FluentUI.DesignTokens - -@namespace DevToys.MauiBlazor.Components - -@code { - [CascadingParameter] - private Grid Parent { get; set; } - - [Parameter] - public string Width { get; set; } = "*"; - - [Parameter] - public string MinWidth { get; set; } = null; - - [Parameter] - public string MaxWidth { get; set; } = null; - - protected override void OnInitialized() - { - if(Parent == null) - { - throw new ArgumentException("Parent not defined. Make sure your component is in a grid element"); - } - - Parent.AddColumn(Width, MinWidth, MaxWidth); - base.OnInitialized(); - StateHasChanged(); - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/CssAlignment.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/CssAlignment.cs deleted file mode 100644 index 7c3455edec..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/CssAlignment.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace DevToys.MauiBlazor.Components; - -public class CssAlignment -{ - public string Css { get; } - - public CssAlignment(string css) - { - Css = css; - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Grid.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Grid.razor deleted file mode 100644 index 9655ed6d43..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/Grid.razor +++ /dev/null @@ -1,59 +0,0 @@ -@using Microsoft.Fast.Components.FluentUI -@using Microsoft.Fast.Components.FluentUI.DesignTokens - -@namespace DevToys.MauiBlazor.Components - -@inherits FluentComponentBase - - - @ColumnDefinitions - @RowDefinitions - -
- @Content -
-
- -@code { - [Parameter] - public RenderFragment ColumnDefinitions { get; set; } - - [Parameter] - public RenderFragment RowDefinitions { get; set; } - - [Parameter] - public RenderFragment Content { get; set; } - - [Parameter] - public double ColumnGap { get; set; } = 0; - - [Parameter] - public double RowGap { get; set; } = 0; - - [Parameter] - public double? Width { get; set; } - - [Parameter] - public double? Height { get; set; } - - private readonly GridWrapper _wrapper = new GridWrapper(); - - public void AddColumn(string width, string min, string max) - { - _wrapper.AddColumn(width, min, max); - StateHasChanged(); - } - - public void AddRow(string height, string min, string max) - { - _wrapper.AddRow(height, min, max); - StateHasChanged(); - } - - protected override void OnParametersSet() - { - _wrapper.SetWidth(Width); - _wrapper.SetHeight(Height); - base.OnParametersSet(); - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridElement.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridElement.razor deleted file mode 100644 index f5689ffaf5..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridElement.razor +++ /dev/null @@ -1,58 +0,0 @@ -@namespace DevToys.MauiBlazor.Components -@using Microsoft.Fast.Components.FluentUI -@using Microsoft.Fast.Components.FluentUI.DesignTokens - -
- @ChildContent -
- -@code { - - [CascadingParameter] - private Grid Parent { get; set; } - - [Parameter] - public int Column { get; set; } = 1; - - [Parameter] - public int Row { get; set; } = 1; - - [Parameter] - public int RowSpan - { - get => (_rowSpan ?? Row) + 1; - set => _rowSpan = value; - } - - [Parameter] - public int ColumnSpan - { - get => (_columnSpan ?? Column) + 1; - set => _columnSpan = value; - } - - [Parameter] - public CssAlignment HorizontalAlignment { get; set; } = Alignment.Stretch; - - [Parameter] - public CssAlignment VerticalAlignment { get; set; } = Alignment.Stretch; - - - [Parameter] - public RenderFragment ChildContent { get; set; } - - protected override void OnInitialized() - { - if (Parent == null) - throw new ArgumentException("Parent not defined. Make sure your component is in a grid element"); - base.OnInitialized(); - } - - private int? _rowSpan; - private int? _columnSpan; -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridLayoutException.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridLayoutException.cs deleted file mode 100644 index 542b56bec5..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridLayoutException.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DevToys.MauiBlazor.Components; - -public class GridLayoutException : Exception -{ - public GridLayoutException(string data) - : base($"'{data} is not a valid unit. Accepted values are *, auto or a number'") - { - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridTemplateConverter.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridTemplateConverter.cs deleted file mode 100644 index 8945d03f34..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridTemplateConverter.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections; -using System.Text.RegularExpressions; - -namespace DevToys.MauiBlazor.Components; - -public class GridTemplateConverter : IEnumerable -{ - private readonly List _convertedData = new(); - private readonly Regex _proportionPattern = new("^[0-9]*\\*$"); - private readonly Regex _fixedSizePattern = new("^[0-9]*$"); - - public void AddData(string data, string? min = null, string? max = null) - { - if (!string.IsNullOrWhiteSpace(min) || !string.IsNullOrWhiteSpace(max)) - { - _convertedData.Add($"minmax({ConvertToCss(!string.IsNullOrWhiteSpace(min) ? min : "1")},{ConvertToCss(!string.IsNullOrWhiteSpace(max) ? max : "*")})"); - } - else - { - _convertedData.Add(ConvertToCss(data)); - } - } - - private string ConvertToCss(string data) - { - if (string.IsNullOrWhiteSpace(data)) - { - return "1fr"; - } - - if (data == "*") - { - return "1fr"; - } - - if (data.ToLower() == "auto") - { - return "auto"; - } - - if (_fixedSizePattern.IsMatch(data)) - { - return data + "px"; - } - - if (_proportionPattern.IsMatch(data)) - { - return data.Replace("*", "fr"); - } - - throw new GridLayoutException(data); - } - - public IEnumerator GetEnumerator() - => _convertedData.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridWrapper.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridWrapper.cs deleted file mode 100644 index e811a23818..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/GridWrapper.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace DevToys.MauiBlazor.Components; - -public class GridWrapper -{ - private readonly GridTemplateConverter _columns = new(); - private readonly GridTemplateConverter _rows = new(); - - private double? _width; - private double? _height; - - public string Css - => $"display: grid; {Width()}{Height()}{GenerateTemplateColumnsIfAny()}{GenerateTemplateRowsIfAny()}".TrimEnd(); - - private string GenerateTemplateColumnsIfAny() - => _columns.Any() - ? $"grid-template-columns: {string.Join(" ", _columns)}; " - : string.Empty; - - private string GenerateTemplateRowsIfAny() - => _rows.Any() - ? $"grid-template-rows: {string.Join(" ", _rows)};" - : string.Empty; - - private string Width() - => $"width: {(_width.HasValue ? _width.Value.ToString() + "px;" : "100%;")} "; - private string Height() - => $"height: {(_height.HasValue ? _height.Value.ToString() + "px;" : "100%;")} "; - - public void AddColumn(string width, string? min = null, string? max = null) - => _columns.AddData(width, min, max); - - public void AddRow(string height, string? min = null, string? max = null) - => _rows.AddData(height, min, max); - - public void SetWidth(double? value) => _width = value; - public void SetHeight(double? value) => _height = value; - - public string RowGap(double gap) - => gap > 0 ? $"grid-row-gap: {gap}px;" : string.Empty; - - public string ColumnGap(double gap) - => gap > 0 ? $"grid-column-gap: {gap}px;" : string.Empty; -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/README.md b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/README.md deleted file mode 100644 index 81cd9a03a5..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Comes from https://github.com/aboudoux/WpfGridLayout.Blazor - -The difference is that we removed the ZIndex support. - -License: https://github.com/aboudoux/WpfGridLayout.Blazor/blob/40f5c265ac15e46507c3df291d7368f00e9773da/README.md?plain=1#L260 \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/RowDefinition.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/RowDefinition.razor deleted file mode 100644 index ab3edf5174..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/Grid/RowDefinition.razor +++ /dev/null @@ -1,30 +0,0 @@ -@using Microsoft.Fast.Components.FluentUI -@using Microsoft.Fast.Components.FluentUI.DesignTokens - -@namespace DevToys.MauiBlazor.Components - -@code { - - [CascadingParameter] - private Grid Parent { get; set; } - - [Parameter] - public string Height { get; set; } = "*"; - - [Parameter] - public string MinHeight { get; set; } = null; - - [Parameter] - public string MaxHeight { get; set; } = null; - - protected override void OnInitialized() - { - if (Parent == null) - { - throw new ArgumentException("Parent not defined. Make sure your component is in a grid element"); - } - - Parent.AddRow(Height, MinHeight, MaxHeight); - base.OnInitialized(); - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor index 92100d53c6..4d4a4eb692 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor @@ -1,52 +1,52 @@ @namespace DevToys.MauiBlazor.Components -@inherits StyledLayoutComponentBase +@inherits JSStyledComponentBase @typeparam TKey @typeparam TElement -
- - @if (Header is not null) - { -
@Header
- } - - @if (ItemsSource is not null) - { - Guard.IsNotNull(ItemTemplate); + + @if (Header is not null) + { +
@Header
+ } - foreach (IGrouping group in ItemsSource) + @if (ItemsSource is not null) { -
-
- @if (GroupHeaderTemplate is null) - { - @group.Key?.ToString() - } - else - { - @GroupHeaderTemplate(group.Key) - } -
+ Guard.IsNotNull(ItemTemplate); + + foreach (IGrouping group in ItemsSource) + { +
+
+ @if (GroupHeaderTemplate is null) + { + @group.Key?.ToString() + } + else + { + @GroupHeaderTemplate(group.Key) + } +
-
    - @foreach (TElement item in group) - { -
  • -
    - @ItemTemplate(item) -
    -
  • - } -
-
+
    + @foreach (TElement item in group) + { +
  • +
    + @ItemTemplate(item) +
    +
  • + } +
+
+ } } - } - @Footer -
+ @Footer +
\ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.cs index 5ed2a38ad0..f6fb110efb 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.cs +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.cs @@ -1,13 +1,10 @@ namespace DevToys.MauiBlazor.Components; -public partial class GridView : StyledLayoutComponentBase, IAsyncDisposable +public partial class GridView : JSStyledComponentBase { - private const string JAVASCRIPT_FILE = "./Components/GridView/GridView.razor.js"; + private ScrollViewer? _scrollViewer = default!; - [Inject] - private IJSRuntime JSRuntime { get; set; } = default!; - - private IJSObjectReference JSModule { get; set; } = default!; + protected override string? JavaScriptFile => "./Components/GridView/GridView.razor.js"; [Parameter] public RenderFragment? Header { get; set; } @@ -30,29 +27,25 @@ public partial class GridView : StyledLayoutComponentBase, IAsyn [Parameter] public int ItemMinWidth { get; set; } + public GridView() + { + CSS.Add("grid-view"); + } + protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - JSModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); - await JSModule.InvokeVoidAsync("initializeStickyHeaders", Id); + Guard.IsNotNull(_scrollViewer); + await (await JSModule).InvokeVoidAsync("initializeStickyHeaders", _scrollViewer.Id); if (ItemMinWidth > 0) { - await JSModule.InvokeVoidAsync("initializeDynamicItemSize", Id, ItemMinWidth); + await (await JSModule).InvokeVoidAsync("initializeDynamicItemSize", _scrollViewer.Id, ItemMinWidth); } } } - /// - async ValueTask IAsyncDisposable.DisposeAsync() - { - if (JSModule is not null) - { - await JSModule.DisposeAsync(); - } - } - internal Task OnItemClickAsync(TElement item) { return OnItemClick.InvokeAsync(item); diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.js b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.js index 1f21a1f4c8..0ab4f0d15c 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.js +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.js @@ -21,19 +21,19 @@ function onGridViewScroll(ev) { const gridView = ev.target; const gridViewPosition = gridView.getBoundingClientRect(); const gridViewPaddingTop = parseFloat(getComputedStyle(gridView).paddingTop); - let groups = gridView.querySelectorAll(".grid-view-group"); - for (var i = 0; i < groups.length; i++) { - let group = groups[i]; - let header = group.querySelector(".grid-view-group-header"); - let itemsContainer = group.querySelector(".grid-view-items-container"); - let headerMarginBottom = parseFloat(getComputedStyle(header).marginBottom); - let headerTopPositionInGridView = header.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; + const groups = gridView.querySelectorAll(".grid-view-group"); + for (let i = 0; i < groups.length; i++) { + const group = groups[i]; + const header = group.querySelector(".grid-view-group-header"); + const itemsContainer = group.querySelector(".grid-view-items-container"); + const headerMarginBottom = parseFloat(getComputedStyle(header).marginBottom); + const headerTopPositionInGridView = header.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; if (headerTopPositionInGridView <= 0) { - let itemsContainerTopPositionInGridView = itemsContainer.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; + const itemsContainerTopPositionInGridView = itemsContainer.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; itemsContainer.style.clipPath = `inset(${header.offsetHeight + headerMarginBottom - itemsContainerTopPositionInGridView}px 0 0 0)`; } else { - itemsContainer.style.clipPath = `none`; + itemsContainer.style.clipPath = "none"; } } } @@ -42,27 +42,26 @@ function onGridViewScroll(ev) { function fitGridViewItemsToContainer(gridView, gridViewBounds, itemMinWidth) { const newGridViewContentSize = gridViewBounds; const gridViewWidth = newGridViewContentSize.width; - let groups = gridView.querySelectorAll(".grid-view-group"); + const groups = gridView.querySelectorAll(".grid-view-group"); if (groups.length > 0) { // Calculating the number of columns based on the width of the page - let firstGroupItemsContainer = groups[0].querySelector(".grid-view-items-container"); - let gapBetweenItems = parseFloat(getComputedStyle(firstGroupItemsContainer).gap); - let itemMinWidthWithGap = itemMinWidth + gapBetweenItems; - let columns = Math.max(1, Math.floor(gridViewWidth / itemMinWidthWithGap)); + const firstGroupItemsContainer = groups[0].querySelector(".grid-view-items-container"); + const gapBetweenItems = parseFloat(getComputedStyle(firstGroupItemsContainer).gap); + const itemMinWidthWithGap = itemMinWidth + gapBetweenItems; + const columns = Math.max(1, Math.floor(gridViewWidth / itemMinWidthWithGap)); // Calculating the new width of the grid view item. let newItemWidth; if (columns == 1) { newItemWidth = "100%"; } else { - let gridViewWidthWithoutGaps = gridViewWidth - (gapBetweenItems * (columns - 1)); + const gridViewWidthWithoutGaps = gridViewWidth - (gapBetweenItems * (columns - 1)); newItemWidth = `${Math.max(itemMinWidth, (gridViewWidthWithoutGaps / columns))}px`; - ; } // Apply the new width to every items. - let items = gridView.querySelectorAll(".grid-view-item"); - for (var i = 0; i < items.length; i++) { - let item = items[i]; + const items = gridView.querySelectorAll(".grid-view-item"); + for (let i = 0; i < items.length; i++) { + const item = items[i]; item.style.width = newItemWidth; } } diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.scss index 563f170d4f..df1fccf25a 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.scss +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.scss @@ -1,6 +1,3 @@ -@use "../../Assets/sass/mixins/index" as mixins; -@use "../../Assets/sass/configs/variables" as variables; - .grid-view { position: relative; width: 100%; @@ -8,7 +5,7 @@ flex: 1; .header { - margin-bottom: 30px; + margin-bottom: 24px; } .grid-view-group { @@ -19,7 +16,7 @@ top: 0; z-index: 10; background-color: transparent; - border-bottom: 1px solid var(--system-reveal-base-low-color); + border-bottom: 1px solid var(--grid-view-header-border-line); padding-bottom: 8px; margin-top: 8px; margin-bottom: 4px; @@ -34,15 +31,16 @@ margin: 16px 0 0 0; .grid-view-item { - background-color: var(--card-background-fill-color-default); + background-color: var(--grid-view-item-background); border-style: solid; border-width: 1px; - border-color: var(--card-stroke-color-default); - border-radius: variables.$corner-radius; + border-color: var(--grid-view-item-stroke); + border-radius: var(--control-corner-radius); list-style-type: none; .grid-view-item-hover-filter:hover { - background-color: var(--subtle-fill-color-secondary); + background-color: var(--grid-view-item-background-hover); + height: 100%; } } } diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.ts b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.ts index d834151521..e8c943cf89 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.ts +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/GridView/GridView.razor.ts @@ -28,21 +28,21 @@ function onGridViewScroll(ev: Event): void { const gridViewPosition = gridView.getBoundingClientRect(); const gridViewPaddingTop = parseFloat(getComputedStyle(gridView).paddingTop); - let groups = gridView.querySelectorAll(".grid-view-group"); + const groups = gridView.querySelectorAll(".grid-view-group"); - for (var i = 0; i < groups.length; i++) { - let group = groups[i]; - let header = group.querySelector(".grid-view-group-header") as HTMLElement; - let itemsContainer = group.querySelector(".grid-view-items-container") as HTMLElement; - let headerMarginBottom = parseFloat(getComputedStyle(header).marginBottom); - let headerTopPositionInGridView = header.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; + for (let i = 0; i < groups.length; i++) { + const group = groups[i]; + const header = group.querySelector(".grid-view-group-header") as HTMLElement; + const itemsContainer = group.querySelector(".grid-view-items-container") as HTMLElement; + const headerMarginBottom = parseFloat(getComputedStyle(header).marginBottom); + const headerTopPositionInGridView = header.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; if (headerTopPositionInGridView <= 0) { - let itemsContainerTopPositionInGridView = itemsContainer.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; + const itemsContainerTopPositionInGridView = itemsContainer.getBoundingClientRect().top - gridViewPosition.top - gridViewPaddingTop; itemsContainer.style.clipPath = `inset(${header.offsetHeight + headerMarginBottom - itemsContainerTopPositionInGridView}px 0 0 0)`; } else { - itemsContainer.style.clipPath = `none`; + itemsContainer.style.clipPath = "none"; } } } @@ -53,14 +53,14 @@ function fitGridViewItemsToContainer(gridView: HTMLElement, gridViewBounds: DOMR const newGridViewContentSize = gridViewBounds; const gridViewWidth = newGridViewContentSize.width; - let groups = gridView.querySelectorAll(".grid-view-group"); + const groups = gridView.querySelectorAll(".grid-view-group"); if (groups.length > 0) { // Calculating the number of columns based on the width of the page - let firstGroupItemsContainer = groups[0].querySelector(".grid-view-items-container") as HTMLElement - let gapBetweenItems = parseFloat(getComputedStyle(firstGroupItemsContainer).gap); - let itemMinWidthWithGap = itemMinWidth + gapBetweenItems; - let columns = Math.max(1, Math.floor(gridViewWidth / itemMinWidthWithGap)); + const firstGroupItemsContainer = groups[0].querySelector(".grid-view-items-container") as HTMLElement; + const gapBetweenItems = parseFloat(getComputedStyle(firstGroupItemsContainer).gap); + const itemMinWidthWithGap = itemMinWidth + gapBetweenItems; + const columns = Math.max(1, Math.floor(gridViewWidth / itemMinWidthWithGap)); // Calculating the new width of the grid view item. let newItemWidth: string; @@ -68,14 +68,14 @@ function fitGridViewItemsToContainer(gridView: HTMLElement, gridViewBounds: DOMR newItemWidth = "100%"; } else { - let gridViewWidthWithoutGaps = gridViewWidth - (gapBetweenItems * (columns - 1)); - newItemWidth = `${Math.max(itemMinWidth, (gridViewWidthWithoutGaps / columns))}px`;; + const gridViewWidthWithoutGaps = gridViewWidth - (gapBetweenItems * (columns - 1)); + newItemWidth = `${Math.max(itemMinWidth, (gridViewWidthWithoutGaps / columns))}px`; } // Apply the new width to every items. - let items = gridView.querySelectorAll(".grid-view-item"); - for (var i = 0; i < items.length; i++) { - let item = items[i] as HTMLElement; + const items = gridView.querySelectorAll(".grid-view-item"); + for (let i = 0; i < items.length; i++) { + const item = items[i] as HTMLElement; item.style.width = newItemWidth; } } diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/JSStyledComponentBase.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/JSStyledComponentBase.cs new file mode 100644 index 0000000000..5b18eac4fd --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/JSStyledComponentBase.cs @@ -0,0 +1,42 @@ +namespace DevToys.MauiBlazor.Components; + +public abstract class JSStyledComponentBase : StyledComponentBase, IAsyncDisposable +{ + private Task? _jsModule; + + /// + /// Gets the JavaScript file to use in this component. + /// + protected virtual string? JavaScriptFile { get; } + + [Inject] + protected IJSRuntime JSRuntime { get; set; } = default!; + + protected Task JSModule + { + get + { + lock (JSRuntime) + { + if (_jsModule is null) + { + Guard.IsNotNullOrWhiteSpace(JavaScriptFile); + _jsModule = JSRuntime.InvokeAsync("import", JavaScriptFile).AsTask(); + } + + return _jsModule; + } + } + } + + /// + public virtual async ValueTask DisposeAsync() + { + if (_jsModule is not null) + { + await (await _jsModule).DisposeAsync(); + } + + GC.SuppressFinalize(this); + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor new file mode 100644 index 0000000000..d9e11a6b80 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor @@ -0,0 +1,12 @@ +@namespace DevToys.MauiBlazor.Components +@inherits StyledComponentBase + + +
  • + @ChildContent +
  • +
    \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.cs new file mode 100644 index 0000000000..b998fe802b --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.cs @@ -0,0 +1,50 @@ +namespace DevToys.MauiBlazor.Components; + +public partial class ListBoxItem : StyledComponentBase +{ + [Parameter] + public object Item { get; set; } = default!; + + [Parameter] + public bool IsSelected { get; set; } + + [Parameter] + public bool IsEnabled { get; set; } = true; + + [Parameter] + public EventCallback OnSelected { get; set; } + + /// + /// Gets or sets the content to be rendered inside the component. + /// + [Parameter] + public RenderFragment? ChildContent { get; set; } + + protected override void OnParametersSet() + { + if (IsSelected) + { + CSS.Add("selected"); + } + else + { + CSS.Remove("selected"); + } + + if (IsEnabled) + { + CSS.Remove("disabled"); + } + else + { + CSS.Add("disabled"); + } + + base.OnParametersSet(); + } + + private Task OnClickAsync() + { + return OnSelected.InvokeAsync(Item); + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.scss b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.scss new file mode 100644 index 0000000000..f805b935e3 --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/ListBox/ListBoxItem.razor.scss @@ -0,0 +1,80 @@ +@use "../../Assets/sass/devtoys" as *; + +.list-box-item { + @include flex( $align: center, $inline: true ); + inline-size: calc(100% - 10px); + position: relative; + box-sizing: border-box; + flex: 0 0 auto; + margin: 3px 5px; + padding-inline: 12px; + border-radius: var(--control-corner-radius); + outline: none; + background-color: var(--list-box-item-background); + color: var(--list-box-item-foreground); + text-decoration: none; + cursor: default; + user-select: none; + block-size: 34px; + text-decoration: none; + + &::before { + content: ""; + position: absolute; + border-radius: 3px; + background-color: var(--accent-default); + transition: transform 167ms cubic-bezier(0, 0, 0, 1); + opacity: 0; + inset-inline-start: 0; + inline-size: 3px; + block-size: 16px; + transform: scaleY(0); + } + + &.selected::before { + transform: scaleY(1); + opacity: 1; + } + + &:focus-visible { + box-shadow: var(--focus-stroke); + } + + &:hover { + background-color: var(--list-box-item-background-pointer-over); + } + + &.selected { + background-color: var(--list-box-item-background-selected); + } + + &:active { + background-color: var(--list-box-item-background-active); + color: var(--list-box-item-foreground-active); + + &::before { + transform: scaleY(0.625); + } + } + + &.disabled { + background-color: var(--list-box-item-background-disabled); + color: var(--list-box-item-foreground-disabled); + pointer-events: none; + + &.selected { + background-color: var(--list-box-item-background-selected-disabled); + + &::before { + background-color: var(--accent-disabled); + } + } + } + + > :global(svg) { + inline-size: 16px; + block-size: auto; + fill: currentColor; + margin-inline-end: 16px; + } +} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefLayoutComponentBase.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefComponentBase.cs similarity index 79% rename from src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefLayoutComponentBase.cs rename to src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefComponentBase.cs index ed03b5022a..fd9d943c7d 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefLayoutComponentBase.cs +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefComponentBase.cs @@ -2,7 +2,7 @@ namespace DevToys.MauiBlazor.Components; -public abstract class MefLayoutComponentBase : StyledLayoutComponentBase +public abstract class MefComponentBase : StyledComponentBase { [Inject] protected IMefProvider MefProvider { get; set; } = default!; diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefFluentComponentBase.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefFluentComponentBase.cs deleted file mode 100644 index ced8c9e4bc..0000000000 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MefFluentComponentBase.cs +++ /dev/null @@ -1,19 +0,0 @@ -using DevToys.Api; -using Microsoft.AspNetCore.Components; -using Microsoft.Fast.Components.FluentUI; - -namespace DevToys.MauiBlazor.Components; - -public abstract class MefFluentComponentBase : FluentComponentBase -{ -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - [Inject] - protected IMefProvider MefProvider { get; set; } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - - protected override void OnInitialized() - { - MefProvider.SatisfyImports(this); - base.OnInitialized(); - } -} diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor index b19f0e9f17..10413e4b73 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor @@ -1,9 +1,6 @@ -@using Microsoft.Fast.Components.FluentUI -@using Microsoft.Fast.Components.FluentUI.DesignTokens - -@inherits FluentComponentBase +@inherits JSStyledComponentBase
    - + @* *@
    \ No newline at end of file diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor.cs b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor.cs index 21a8d9cf91..b46dad1ab3 100644 --- a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor.cs +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/MonacoEditor.razor.cs @@ -1,11 +1,6 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.Fast.Components.FluentUI; -using Microsoft.Fast.Components.FluentUI.Utilities; -using Microsoft.JSInterop; +namespace DevToys.MauiBlazor.Components; -namespace DevToys.MauiBlazor.Components; - -public partial class MonacoEditor : FluentComponentBase, IAsyncDisposable +public partial class MonacoEditor : JSStyledComponentBase, IAsyncDisposable { private const string JAVASCRIPT_FILE = "./Components/MonacoEditor.razor.js"; private const string MONACO_VS_PATH = "./lib/monaco-editor/min/vs"; @@ -19,9 +14,7 @@ void Main() } """; - - protected string? ClassValue => new CssBuilder(Class) - .Build(); + protected string? ClassValue => new CssBuilder(FinalCssClasses).Build(); protected string? StyleValue => new StyleBuilder() .AddStyle("height", Height, () => !string.IsNullOrEmpty(Height)) @@ -35,12 +28,6 @@ void Main() private IJSObjectReference JSModule { get; set; } = default!; - /// - /// Unique identifier of this component. - /// - [Parameter] - public string Id { get; set; } = Identifier.NewId(); - /// /// Language used by the editor: csharp, javascript, ... /// @@ -86,7 +73,7 @@ public string Value /// Gets or sets a callback that updates the bound value. /// [Parameter] - public EventCallback ValueChanged { get; set; } + public EventCallback OnValueChanged { get; set; } /// protected override async Task OnParametersSetAsync() @@ -134,9 +121,9 @@ private string GetTheme(bool isDarkMode) public async Task UpdateValueAsync(string value) { _value = value; - if (ValueChanged.HasDelegate) + if (OnValueChanged.HasDelegate) { - await ValueChanged.InvokeAsync(_value); + await OnValueChanged.InvokeAsync(_value); } } diff --git a/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/NavBar/NavBar.razor b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/NavBar/NavBar.razor new file mode 100644 index 0000000000..03e62ba32d --- /dev/null +++ b/src/app/dev/platforms/desktop/DevToys.MauiBlazor/Components/NavBar/NavBar.razor @@ -0,0 +1,126 @@ +@namespace DevToys.MauiBlazor.Components +@using DevToys.Core.Tools.ViewItems; +@using DevToys.Core; + +@inherits JSStyledComponentBase +@typeparam TElement + + +