@swiftbrowser/swift 0.5.3 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,14 @@
1
1
  // iOS 26 Liquid Glass. The page has no refracting glass, so a glass effect
2
- // is approximated by what it looks like at rest: a translucent material
3
- // (`regularMaterial`, `ultraThinMaterial` for `.clear`) filling the given
4
- // shape behind the view, under the glass's tint when it has one. The
5
- // `interactive` response to touches (the glass swelling under a finger),
6
- // the merging of nearby glass shapes in a `GlassEffectContainer` and the
7
- // morphing between `glassEffectID`s are not drawn: containers lay their
8
- // content out as given and ids are accepted. The glass button styles draw
9
- // as the bordered ones (`.glass` as `.bordered`, `.glassProminent` as
10
- // `.borderedProminent`).
2
+ // is approximated by what it looks like at rest: the `glass` material
3
+ // (`glassClear` for `.clear`: the bar buttons' translucent fill over a
4
+ // blurred backdrop, with the rim that catches the light; see styles.css)
5
+ // filling the given shape behind the view, under the glass's tint when it
6
+ // has one. The `interactive` response to touches (the glass swelling under
7
+ // a finger), the merging of nearby glass shapes in a `GlassEffectContainer`
8
+ // and the morphing between `glassEffectID`s are not drawn: containers lay
9
+ // their content out as given and ids are accepted. `.buttonStyle(.glass)`
10
+ // is a glass capsule (`glass`); `.glassProminent` draws as
11
+ // `.borderedProminent`.
11
12
 
12
13
  /// The material of a glass effect.
13
14
  public struct Glass: Equatable, Sendable {
@@ -36,7 +37,7 @@ public struct Glass: Equatable, Sendable {
36
37
  Glass(variant: variant, tintColor: tintColor, isInteractive: isEnabled)
37
38
  }
38
39
 
39
- var material: Material { variant == .clear ? .ultraThinMaterial : .regularMaterial }
40
+ var material: Material { Material(name: variant == .clear ? "glassClear" : "glass") }
40
41
  }
41
42
 
42
43
  /// The glass behind a view: the material, then the tint, in the shape.
@@ -104,11 +105,11 @@ extension GlassEffectContainer: _GroupView {
104
105
 
105
106
  // MARK: - Glass button styles
106
107
 
107
- /// `.buttonStyle(.glass)`: drawn as `.bordered` (a gray capsule).
108
+ /// `.buttonStyle(.glass)`: a Liquid Glass capsule (sized like `.bordered`).
108
109
  public struct GlassButtonStyle: PrimitiveButtonStyle {
109
110
  public init() {}
110
111
  public init(_ glass: Glass) {}
111
- public var _name: String { "bordered" }
112
+ public var _name: String { "glass" }
112
113
  }
113
114
 
114
115
  /// `.buttonStyle(.glassProminent)`: drawn as `.borderedProminent` (a tinted capsule).
@@ -11,6 +11,9 @@ struct _Element {
11
11
  /// `accessibilityLabel` / `accessibilityIdentifier`, for event scripts (the
12
12
  /// label is in `props` too, Runtime.swift).
13
13
  var accessibility: _AccessibilityMark?
14
+ /// The `accessibilityLabel` prop was taken from the content (a control
15
+ /// named by its icon-only label): a label set on the control replaces it.
16
+ var labelFromContent = false
14
17
  /// `.layoutValue(key:value:)` above this element, by key type: what a
15
18
  /// custom layout's subview reads (CustomLayout.swift).
16
19
  var layoutValues: [ObjectIdentifier: Any]?
@@ -1676,6 +1676,17 @@ public final class _Runtime {
1676
1676
  children: children,
1677
1677
  handler: node.handler ?? hostView._handler
1678
1678
  )
1679
+ // A control whose content shows no text (an icon-only `Label`) is
1680
+ // named by the label its content carries, on the control itself:
1681
+ // browsers and screen readers do not all take a name from an
1682
+ // inner element (a menu's content is its label, the first child).
1683
+ if kind == "button" || kind == "navlink" || kind == "menu", case .object(var fields) = element.props,
1684
+ fields["accessibilityLabel"] == nil,
1685
+ let label = _contentLabel(of: kind == "menu" ? Array(children.prefix(1)) : children) {
1686
+ fields["accessibilityLabel"] = .string(label)
1687
+ element.props = .object(fields)
1688
+ element.labelFromContent = true
1689
+ }
1679
1690
  if traits.contains(.navigationValueLink), let link = node.view as? any _NavigationValueLinkView, let value = link._value {
1680
1691
  element.row = _RowMark(linkValue: value, linkHandler: element.handler)
1681
1692
  }
@@ -1727,9 +1738,11 @@ public final class _Runtime {
1727
1738
  // it already. The innermost label wins; a changed element is a
1728
1739
  // new value, so the reconciler does not skip it as cached.
1729
1740
  if let label = mark.label, !label.isEmpty, case .object(var props) = produced[index].props,
1730
- props["accessibilityLabel"] == nil, !_showsText(label, in: produced[index]) {
1741
+ props["accessibilityLabel"] == nil || produced[index].labelFromContent,
1742
+ !_showsText(label, in: produced[index]) {
1731
1743
  props["accessibilityLabel"] = .string(label)
1732
1744
  produced[index].props = .object(props)
1745
+ produced[index].labelFromContent = false
1733
1746
  produced[index].token = _Element.nextToken()
1734
1747
  }
1735
1748
  }
@@ -1748,6 +1761,22 @@ public final class _Runtime {
1748
1761
  return produced
1749
1762
  }
1750
1763
 
1764
+ /// The accessibility label content carries when it shows no text (the
1765
+ /// first, depth first), else nil.
1766
+ private func _contentLabel(of elements: [_Element]) -> String? {
1767
+ func showsText(_ element: _Element) -> Bool {
1768
+ element.kind == "text" || element.children.contains(where: showsText)
1769
+ }
1770
+ func label(_ element: _Element) -> String? {
1771
+ if case .object(let props) = element.props, case .string(let label)? = props["accessibilityLabel"], !label.isEmpty {
1772
+ return label
1773
+ }
1774
+ return element.children.lazy.compactMap(label).first
1775
+ }
1776
+ guard !elements.contains(where: showsText) else { return nil }
1777
+ return elements.lazy.compactMap(label).first
1778
+ }
1779
+
1751
1780
  /// Whether `element` or an element under it is a `text` showing `text`.
1752
1781
  private func _showsText(_ text: String, in element: _Element) -> Bool {
1753
1782
  if element.kind == "text", case .object(let props) = element.props, case .string(let shown)? = props["text"], shown == text {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swiftbrowser/swift",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "The SwiftBrowser Swift package (the SwiftUI shim, Charts, SwiftData and FoundationBridge) as an npm package, so @swiftbrowser/cli builds apps against the exact version it ships with.",
5
5
  "repository": {
6
6
  "type": "git",