From e82c3ebc596391b51e35ac02aef880817ea5a2e5 Mon Sep 17 00:00:00 2001 From: Roman <51091564+jeanpierreroma@users.noreply.github.com> Date: Wed, 12 Aug 2026 18:12:22 +0300 Subject: [PATCH 1/2] feat(icons): make XmarkIcon public MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `XmarkIcon` was internal, so app code reaching for a close control had to fall back to the bundled `navigationbar-close` asset. That asset is fixed artwork: it neither scales cleanly to an arbitrary size nor takes a tint, which is exactly what a close control drawn at 12pt inside a menu row needs. The icon is already a `Shape` with `size` / `color` / `lineWidth` knobs, so nothing about it was internal by design — it simply had no reason to be exported until now. Publishing it adds an explicit public initializer, since a public struct gets no public memberwise init, and leaves the call site unchanged for the module's own use in `Toast` and `SystemMessageView`. `docs/feedback.md` claimed the opposite ("Internal to the module ... reach for the bundled navigationbar-close asset"), so it is corrected here and now says when to prefer each. --- .../Components/Icons/XmarkIcon.swift | 23 +++++++++++++++---- docs/feedback.md | 9 +++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Sources/DashUIKit/Components/Icons/XmarkIcon.swift b/Sources/DashUIKit/Components/Icons/XmarkIcon.swift index 8887323..eea8d4c 100644 --- a/Sources/DashUIKit/Components/Icons/XmarkIcon.swift +++ b/Sources/DashUIKit/Components/Icons/XmarkIcon.swift @@ -22,12 +22,25 @@ import SwiftUI /// A code-drawn "✕" (close) icon. Mirrors the source SVG (9×9 viewBox, two diagonals /// inset from 0.75 to 7.75, round caps/joins). Scales cleanly to any `size`. @available(iOS 14, macOS 11, *) -struct XmarkIcon: View { - var size: CGFloat = 9 - var color: Color = Color.dash.primaryText - var lineWidth: CGFloat = 1.5 +public struct XmarkIcon: View { + public var size: CGFloat = 9 + public var color: Color = Color.dash.primaryText + public var lineWidth: CGFloat = 1.5 - var body: some View { + /// A public struct gets no public memberwise initializer, so this one is + /// written out to keep the call site unchanged for module-internal users + /// and available to app code. + public init( + size: CGFloat = 9, + color: Color = Color.dash.primaryText, + lineWidth: CGFloat = 1.5 + ) { + self.size = size + self.color = color + self.lineWidth = lineWidth + } + + public var body: some View { XmarkShape() .stroke(color, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round)) .frame(width: size, height: size) diff --git a/docs/feedback.md b/docs/feedback.md index a50d614..cd08d4a 100644 --- a/docs/feedback.md +++ b/docs/feedback.md @@ -98,7 +98,7 @@ ErrorIllustration() ## XmarkIcon -File `Components/Icons/XmarkIcon.swift` · `@available(iOS 14, macOS 11, *)` · internal +File `Components/Icons/XmarkIcon.swift` · `@available(iOS 14, macOS 11, *)` · public A code-drawn "✕" close icon (a `Shape` with two round-capped diagonals, mirroring a 9×9 SVG), so it scales cleanly to any size without an asset. Used by `Toast`'s dismiss button. @@ -107,5 +107,8 @@ SVG), so it scales cleanly to any size without an asset. Used by `Toast`'s dismi XmarkIcon(size: 24, color: .white, lineWidth: 2) ``` -> Internal to the module (not part of the public API) — reach for the bundled -> `navigationbar-close` asset or an SF Symbol from app code. +> Prefer this over the bundled `navigationbar-close` asset when the close control +> is drawn at a non-standard size or needs to take the surrounding tint: being a +> `Shape`, it stays crisp at any `size` and honours `color` / `lineWidth`. The +> asset remains the right choice where the navigation bar's exact artwork is +> wanted. From aa00bc419bffee69d6bb042cc87241aee194a619 Mon Sep 17 00:00:00 2001 From: Roman <51091564+jeanpierreroma@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:10:50 +0300 Subject: [PATCH 2/2] feat(icons): add the disabled variant of menu-send-account `menu-send-account` had no disabled counterpart, so a `MenuItem` using it as its leading icon had nothing to pass for `disabledLeadingIcon` and kept the full-colour icon while the rest of the row was greyed out. Adds the imageset at the usual three scales (30/60/90) and maps it as `DashIcon.Menu.sendAccountDisabled`, following the existing `sendDisabled` / `receiveDisabled` pairs. --- .../DashUIKit/Foundation/Icon_DashUI.swift | 1 + .../Contents.json | 23 ++++++++++++++++++ .../menu-send-account-disabled.png | Bin 0 -> 575 bytes .../menu-send-account-disabled@2x.png | Bin 0 -> 993 bytes .../menu-send-account-disabled@3x.png | Bin 0 -> 1390 bytes 5 files changed, 24 insertions(+) create mode 100644 Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/Contents.json create mode 100644 Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled.png create mode 100644 Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled@2x.png create mode 100644 Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled@3x.png diff --git a/Sources/DashUIKit/Foundation/Icon_DashUI.swift b/Sources/DashUIKit/Foundation/Icon_DashUI.swift index 6c43553..3f5e278 100644 --- a/Sources/DashUIKit/Foundation/Icon_DashUI.swift +++ b/Sources/DashUIKit/Foundation/Icon_DashUI.swift @@ -156,6 +156,7 @@ public enum DashIcon { case security = "menu-security" case send = "menu-send" case sendAccount = "menu-send-account" + case sendAccountDisabled = "menu-send-account-disabled" case sendAddress = "menu-send-address" case sendDisabled = "menu-send-disabled" case settings = "menu-settings" diff --git a/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/Contents.json b/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/Contents.json new file mode 100644 index 0000000..7bdeb3f --- /dev/null +++ b/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "menu-send-account-disabled.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "menu-send-account-disabled@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "menu-send-account-disabled@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled.png b/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..35c922e9c9c2763400c3ea2929205e817b76d7fc GIT binary patch literal 575 zcmV-F0>J%=P)rrx6C~Q))4hsB;f&`JRFEI|bk9A%bLO1?46x>h5U`}( zy{!`9nBP1Bc|@vNF6OUo^00+l{eDUXq9!2H%M+1@$@Z!1?)#j45=^2*4P?$X$2Blv z318jxN>QR8;&3i|_YN4agoTV}z~wC{al&||CQ5*blp@KB!!N;nV&#DgffdUWo}vjZ zQ^ks93A=9YNkY_D#p$kYm{>5da;|pw?pV9j35m}QBtd=v*{BqI0#8hL23*JbzgU&JqwR1?>OePI5=!mq+q%5MR{~y~XjCd34Y;{j!ltPdR8@yZ zIv5c>3#bNXMMes@hQkE>ac!}Cxy)8%jLzI#_-IAWvGQLpY()*T6&c9$sF+Y;?kWry zhhuWUR@iD4hKZAOtc4M%7km>bg8fK^v|!HJGO7@x%L{zYO z?NlKQQP5L`?-en@d-WeB$>?6gK)F^sEJ6q|!Eviuh9`K0#jY(T*mO%`QMiesKrD0Q zo?%YbVDt+)!Nd`U05QR)ntE*fN$kgzD_V-Y^uCrr=T9JnnBe&r&&;9Z)7p-Zv$Jx8 zglOZTKpPOoG&AcEM7Gmv{@IX>vW@PmmyVhoZHXd7F>Q!^`#KVL#k3?*q+xeME@p@qKyVJ5w{|K#dk3)qy%n6!$IShwz zr`64t*>9m8&nZIrrg&SJH0TI{I`WaiH@O$V-PCHwg~nK;(|3y%kj>^I2LHDi2|(r*q$8zrr=yej_Gzw(3bw9; zj;Y$Kd3F~*%rz0gHlp~|s4}TVctBEkYQcN;da2puRUbR)Zmg@Qa{M-}=v0EO*j9_z zl3JoEh|G5MQ<@psc|7ccSWCe)-|se!%K=B6BHSrX#wGNf#<$T)@7CCBmp9E^DXc&t}k&XQQL-8*%@pzAaC3@$q`r!EHZ=6~&C-<}{K0oLFm|6XH{y4}LC8O?flgGcqzVG6s#mSz2Jj#r??W P00000NkvXXu0mjf>HE@q literal 0 HcmV?d00001 diff --git a/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled@3x.png b/Sources/DashUIKit/Resources/Media.xcassets/Icons & Illustrations/Menu/menu-send-account-disabled.imageset/menu-send-account-disabled@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..b41a15b96de58fc77acb1ae4aba422e7f7eaef5f GIT binary patch literal 1390 zcmV-!1(EuRP)FQlb=k|M_1l*10+XtX$=Felgw5m}X_|ZWkgWDxnWLozi#&+gBC%Ls)Rg z+~b%cJQ|^&9=@zOplt|<0cbv4FE=3qq7b@$@S;HmE06=Rh^;Pko+3{np#81&9~z*D z0Y#o3cItVH%phQeuLX*z3H{{R^GydJws^kQuFqyb2^FE+M@LHpMn1xIW$UlZpCHBdlBXiKySO8710W(duDvqm&ups2A|iwljW@EvF~w&I^CaiNKv z+Bg3cG${UNiwb?vd0l!}eN&~_ZXYdyAfiH(9mOE>ghJu=0tg~1^w^F>qv%tN@Xay^ zqIv|sN!(bWDVr0mRm<+tX!>wN5f$1DsRxl@2J@o#A}VyX%B>|*k7@+!RjYSI??e7% z=-?G7;~a>8vc!dUg=`PBQMd+JVK+VM8(lnQT}8*&R?qP3RxX<(?7z7&|QdcAj49pn3#(PTXm6EBr(31%Es;Q%S}M{b0pLL7wH?oCb!feXL1*st-+EG*)KuDn4hcAvmo-6yp8#}b-`yzWQL9T zyMG=9eO|~#auNFcAt$pV@)RUf<9ml32re{d7Y^Lai9E%($m){}DKNo>b{6XqW*1kX z$Z049CaBOH3B1?AjKjHpXuo*ah#u=aIUo-*=OPvwF^W@P2zhrIJ5{Q@%%8;c+?!Ltr_rAiop@?uQ*I1gh{ZiW9{-{m$0+ob!9yGz5{ zh0C%=UiRf&J1i56L;>q);w>~ud0s@Cv*#utQ}c^jjU~dRO-15!9bA6o${3d-5vb&Z zYS%2RuV3^Wr=Z4krJr!1J`%=eARN(B24>L`Exj`YQIUTl!oug?jERT@|4jZsJe?Ye wGXJ{;cQ(kVm&`