Implement remaining W3C HTML global attributes#257
Merged
Conversation
This commit implements 25 W3C global HTML attributes as ViewModifiers, completing the full suite of remaining global attributes from the HTML specification. Each modifier balances W3C idioms with SwiftUI conventions to provide a familiar experience for SwiftUI developers. New modifiers added: - accesskey(_:) - Keyboard shortcuts for element activation - autocapitalize(_:) - Text capitalization control with enum - autofocus(_:) - Page load focus control - contenteditable(_:) - Content editability with enum/bool support - direction(_:) - Text directionality (ltr, rtl, auto) - draggable(_:) - Drag and drop support - enterKeyHint(_:) - Virtual keyboard enter key hints - hidden(_:) - Element visibility with state support - inert(_:) - Non-interactive element marking - inputMode(_:) - Virtual keyboard type hints - customElement(_:) - Custom element support (is attribute) - Microdata support (itemscope, itemtype, itemid, itemprop, itemref) - nonce(_:) - Content Security Policy nonce - popover(_:) - Popover element support with state - slot(_:) - Shadow DOM slot assignment - spellcheck(_:) - Spell checking control - inlineStyle(_:) - Inline CSS (style attribute) - tabIndex(_:) / focusable() - Focus and keyboard navigation - tooltip(_:) - Advisory information (title attribute) - translatable(_:) - Translation control - writingSuggestions(_:) - Browser writing suggestions Updated AttributeModifier.GlobalAttribute enum with all new cases. Updated documentation in SlipstreamForWebDevelopers.md with a new "Global attributes" section mapping W3C attributes to Slipstream modifiers. Implementation follows established patterns using AttributeModifier and ConditionalAttributeModifier for consistent behavior across the codebase.
Move all enum types outside of View protocol extensions to resolve Swift compilation errors. Swift does not allow nested types in protocol extensions. Fixed enums: - Autocapitalize (in View+autocapitalize.swift) - Contenteditable (in View+contenteditable.swift) - TextDirection (in View+dir.swift) - EnterKeyHint (in View+enterkeyhint.swift) - HiddenState (in View+hidden.swift) - InputMode (in View+inputmode.swift) - PopoverState (in View+popover.swift) - TranslateMode (in View+translate.swift) All enums are now top-level types with @available(iOS 17.0, macOS 14.0, *) annotations, making them accessible while maintaining the same API surface.
Rename the accesskey(_:) modifier to keyboardShortcut(_:) to better align with SwiftUI naming conventions. SwiftUI uses keyboardShortcut for similar functionality, making this name more familiar to SwiftUI developers. The modifier still sets the HTML accesskey attribute internally, maintaining full W3C compatibility while providing a more intuitive API. Updated: - View+accesskey.swift: Renamed function and updated example - SlipstreamForWebDevelopers.md: Updated documentation table
Rename the enterKeyHint(_:) modifier to submitLabel(_:) to better align with SwiftUI naming conventions. SwiftUI uses submitLabel(_:) for controlling the appearance of the return key on virtual keyboards. The modifier still sets the HTML enterkeyhint attribute internally, maintaining full W3C compatibility while providing a more familiar API for SwiftUI developers. Updated: - View+enterkeyhint.swift: Renamed function and parameter, updated example - SlipstreamForWebDevelopers.md: Updated documentation table
Rename modifiers to better align with SwiftUI naming conventions: 1. inert(_:) → allowsHitTesting(_:) - Inverted logic: allowsHitTesting(false) sets the inert attribute - allowsHitTesting(true) is the default (no inert attribute) - Matches SwiftUI's allowsHitTesting modifier semantics 2. inputMode(_:) → keyboardType(_:) - Renamed InputMode enum to KeyboardType - Matches SwiftUI's keyboardType modifier - Still sets the HTML inputmode attribute internally Updated: - View+inert.swift: Renamed to allowsHitTesting with inverted logic - View+inputmode.swift: Renamed to keyboardType, enum to KeyboardType - SlipstreamForWebDevelopers.md: Updated documentation table
Rename all microdata modifiers to use proper Swift camelCase naming: - itemscope(_:) → itemScope(_:) - itemtype(_:) → itemType(_:) - itemid(_:) → itemID(_:) - itemprop(_:) → itemProp(_:) - itemref(_:) → itemRef(_:) All modifiers still set the correct HTML attributes (itemscope, itemtype, etc.) internally while providing a more Swift-idiomatic API. Updated: - View+microdata.swift: All function names and examples - SlipstreamForWebDevelopers.md: Updated documentation table
Add test coverage for all 21 new W3C global attribute modifiers: Keyboard & Input: - KeyboardShortcutTests: Tests for keyboardShortcut(_:) modifier - AutocapitalizeTests: Tests for all autocapitalize modes (none, sentences, words, characters) - AutofocusTests: Tests for autofocus(_:) with boolean values - SubmitLabelTests: Tests for all submitLabel cases (enter, done, go, next, previous, search, send) - KeyboardTypeTests: Tests for all keyboardType cases (none, text, decimal, numeric, tel, search, email, url) Content & Display: - ContenteditableTests: Tests for contenteditable with enum and boolean values - DirectionTests: Tests for direction(_:) with ltr, rtl, and auto - HiddenTests: Tests for hidden(_:) with boolean and HiddenState enum - TranslatableTests: Tests for translatable(_:) with enum and boolean values - TooltipTests: Tests for tooltip(_:) modifier Interaction: - AllowsHitTestingTests: Tests for allowsHitTesting(_:) with inverted inert logic - DraggableTests: Tests for draggable(_:) modifier - PopoverTests: Tests for popover(_:) with PopoverState and boolean - TabIndexTests: Tests for tabIndex(_:) and focusable() convenience method Microdata: - MicrodataTests: Comprehensive tests for itemScope, itemType, itemID, itemProp, itemRef, and combined usage Miscellaneous: - NonceTests: Tests for nonce(_:) modifier - SlotTests: Tests for slot(_:) modifier - SpellcheckTests: Tests for spellcheck(_:) modifier - InlineStyleTests: Tests for inlineStyle(_:) modifier - CustomElementTests: Tests for customElement(_:) modifier - WritingSuggestionsTests: Tests for writingSuggestions(_:) modifier All tests follow existing Slipstream test patterns and verify correct HTML attribute generation.
The file SlotTests.swift conflicts with the existing W3C/SlotTests.swift that tests the <slot> element. Renamed to SlotAttributeTests.swift to test the slot attribute specifically.
Remove the boolean overload of hidden(_:) to avoid conflict with the existing TailwindCSS hidden() modifier. Now only the HiddenState version exists: hidden(.hidden) or hidden(.untilFound). The two modifiers serve different purposes: - TailwindCSS hidden(): Visual hiding via CSS display property - W3C hidden(_:): Semantic hiding via HTML hidden attribute Users should use: - TailwindCSS .hidden() for CSS-based visual hiding - W3C .hidden(.hidden) for semantic HTML attribute hiding - W3C .hidden(.untilFound) for hidden-until-found state Updated: - View+hidden.swift: Removed boolean overload, clarified documentation - HiddenTests.swift: Removed boolean tests, kept only HiddenState tests - SlipstreamForWebDevelopers.md: Clarified the difference
Update test expectations to match actual HTML rendering: - Change multiline expectations to single-line for elements with text content - Fix boolean attribute expectations (itemscope without ="") - Update KeyboardShortcutTests, SlotAttributeTests, MicrodataTests, CustomElementTests, TooltipTests, and NonceTests The HTML output is semantically correct, just formatted differently than initially expected.
Update remaining tests to expect single-line HTML output: - KeyboardShortcutTests - SlotAttributeTests - TooltipTests All tests now match the actual rendering behavior.
Boolean attributes now render without ="" suffix (HTML5 standard): - autofocus="" → autofocus - inert="" → inert - hidden="" → hidden (when using .hidden state) Also fixed combinedMicrodata test to expect multi-line output. Updated tests: - AllowsHitTestingTests: inert without ="" - HiddenTests: hidden without ="" - AutofocusTests: autofocus without ="" - MicrodataTests: combinedMicrodata multi-line format
9cad748 to
ace0ccb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit implements 25 W3C global HTML attributes as ViewModifiers, completing the full suite of remaining global attributes from the HTML specification. Each modifier balances W3C idioms with SwiftUI conventions to provide a familiar experience for SwiftUI developers.
New modifiers added:
Updated AttributeModifier.GlobalAttribute enum with all new cases.
Updated documentation in SlipstreamForWebDevelopers.md with a new "Global attributes" section mapping W3C attributes to Slipstream modifiers.
Implementation follows established patterns using AttributeModifier and ConditionalAttributeModifier for consistent behavior across the codebase.
Part of #27