@sharedex/ui 0.9.0 → 0.10.0
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.
- package/README.md +37 -2
- package/dist/backgrounds/hosts/CssHost.d.ts +2 -6
- package/dist/backgrounds/hosts/CssHost.js +3 -17
- package/dist/backgrounds/hosts/styleHref.d.ts +6 -0
- package/dist/backgrounds/hosts/styleHref.js +20 -0
- package/dist/buttons/pick.d.ts +9 -3
- package/dist/buttons/pick.js +4 -1
- package/dist/forms/base.d.ts +1 -0
- package/dist/forms/base.js +224 -0
- package/dist/forms/buddy.d.ts +6 -0
- package/dist/forms/buddy.js +150 -0
- package/dist/forms/chips.d.ts +1 -0
- package/dist/forms/chips.js +140 -0
- package/dist/forms/choice.d.ts +1 -0
- package/dist/forms/choice.js +208 -0
- package/dist/forms/controls/CheckGroup.d.ts +65 -0
- package/dist/forms/controls/CheckGroup.js +99 -0
- package/dist/forms/controls/Checkbox.d.ts +43 -0
- package/dist/forms/controls/Checkbox.js +67 -0
- package/dist/forms/controls/ChipGroup.d.ts +50 -0
- package/dist/forms/controls/ChipGroup.js +56 -0
- package/dist/forms/controls/Combobox.d.ts +75 -0
- package/dist/forms/controls/Combobox.js +249 -0
- package/dist/forms/controls/ErrorSummary.d.ts +29 -0
- package/dist/forms/controls/ErrorSummary.js +79 -0
- package/dist/forms/controls/Field.d.ts +92 -0
- package/dist/forms/controls/Field.js +219 -0
- package/dist/forms/controls/FileDrop.d.ts +81 -0
- package/dist/forms/controls/FileDrop.js +328 -0
- package/dist/forms/controls/FormBuddy.d.ts +22 -0
- package/dist/forms/controls/FormBuddy.js +143 -0
- package/dist/forms/controls/FormReveal.d.ts +21 -0
- package/dist/forms/controls/FormReveal.js +19 -0
- package/dist/forms/controls/FormSteps.d.ts +75 -0
- package/dist/forms/controls/FormSteps.js +205 -0
- package/dist/forms/controls/FormSwap.d.ts +27 -0
- package/dist/forms/controls/FormSwap.js +38 -0
- package/dist/forms/controls/InlineEdit.d.ts +50 -0
- package/dist/forms/controls/InlineEdit.js +136 -0
- package/dist/forms/controls/NumberField.d.ts +43 -0
- package/dist/forms/controls/NumberField.js +205 -0
- package/dist/forms/controls/OtpField.d.ts +46 -0
- package/dist/forms/controls/OtpField.js +195 -0
- package/dist/forms/controls/PasswordRules.d.ts +31 -0
- package/dist/forms/controls/PasswordRules.js +85 -0
- package/dist/forms/controls/RadioGroup.d.ts +69 -0
- package/dist/forms/controls/RadioGroup.js +95 -0
- package/dist/forms/controls/Range.d.ts +60 -0
- package/dist/forms/controls/Range.js +169 -0
- package/dist/forms/controls/SaveStatus.d.ts +25 -0
- package/dist/forms/controls/SaveStatus.js +88 -0
- package/dist/forms/controls/Select.d.ts +46 -0
- package/dist/forms/controls/Select.js +35 -0
- package/dist/forms/controls/Switch.d.ts +54 -0
- package/dist/forms/controls/Switch.js +91 -0
- package/dist/forms/controls/TagsField.d.ts +68 -0
- package/dist/forms/controls/TagsField.js +0 -0
- package/dist/forms/controls/choiceChecks.d.ts +11 -0
- package/dist/forms/controls/choiceChecks.js +19 -0
- package/dist/forms/controls/choiceParts.d.ts +40 -0
- package/dist/forms/controls/choiceParts.js +49 -0
- package/dist/forms/controls/fieldChecks.d.ts +17 -0
- package/dist/forms/controls/fieldChecks.js +34 -0
- package/dist/forms/controls/fieldTools.d.ts +62 -0
- package/dist/forms/controls/fieldTools.js +54 -0
- package/dist/forms/controls/pickerChecks.d.ts +10 -0
- package/dist/forms/controls/pickerChecks.js +27 -0
- package/dist/forms/controls/rangeChecks.d.ts +11 -0
- package/dist/forms/controls/rangeChecks.js +23 -0
- package/dist/forms/controls/shared.d.ts +8 -0
- package/dist/forms/controls/shared.js +18 -0
- package/dist/forms/effects/cards.d.ts +11 -0
- package/dist/forms/effects/cards.js +52 -0
- package/dist/forms/effects/check/checkCard.d.ts +10 -0
- package/dist/forms/effects/check/checkCard.js +15 -0
- package/dist/forms/effects/check/checkCard.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkCard.schema.js +9 -0
- package/dist/forms/effects/check/checkConfetti.d.ts +18 -0
- package/dist/forms/effects/check/checkConfetti.js +38 -0
- package/dist/forms/effects/check/checkConfetti.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkConfetti.schema.js +13 -0
- package/dist/forms/effects/check/checkDraw.d.ts +7 -0
- package/dist/forms/effects/check/checkDraw.js +12 -0
- package/dist/forms/effects/check/checkDraw.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkDraw.schema.js +9 -0
- package/dist/forms/effects/check/checkHeart.d.ts +9 -0
- package/dist/forms/effects/check/checkHeart.js +84 -0
- package/dist/forms/effects/check/checkHeart.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkHeart.schema.js +10 -0
- package/dist/forms/effects/check/checkJelly.d.ts +9 -0
- package/dist/forms/effects/check/checkJelly.js +23 -0
- package/dist/forms/effects/check/checkJelly.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkJelly.schema.js +10 -0
- package/dist/forms/effects/check/checkMerge.d.ts +9 -0
- package/dist/forms/effects/check/checkMerge.js +37 -0
- package/dist/forms/effects/check/checkMerge.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkMerge.schema.js +10 -0
- package/dist/forms/effects/check/checkMixed.d.ts +7 -0
- package/dist/forms/effects/check/checkMixed.js +25 -0
- package/dist/forms/effects/check/checkMixed.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkMixed.schema.js +9 -0
- package/dist/forms/effects/check/checkMorph.d.ts +9 -0
- package/dist/forms/effects/check/checkMorph.js +53 -0
- package/dist/forms/effects/check/checkMorph.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkMorph.schema.js +10 -0
- package/dist/forms/effects/check/checkPop.d.ts +9 -0
- package/dist/forms/effects/check/checkPop.js +27 -0
- package/dist/forms/effects/check/checkPop.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkPop.schema.js +10 -0
- package/dist/forms/effects/check/checkRipple.d.ts +7 -0
- package/dist/forms/effects/check/checkRipple.js +33 -0
- package/dist/forms/effects/check/checkRipple.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkRipple.schema.js +9 -0
- package/dist/forms/effects/check/checkScribble.d.ts +11 -0
- package/dist/forms/effects/check/checkScribble.js +42 -0
- package/dist/forms/effects/check/checkScribble.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkScribble.schema.js +11 -0
- package/dist/forms/effects/check/checkStrike.d.ts +9 -0
- package/dist/forms/effects/check/checkStrike.js +54 -0
- package/dist/forms/effects/check/checkStrike.schema.d.ts +1 -0
- package/dist/forms/effects/check/checkStrike.schema.js +10 -0
- package/dist/forms/effects/chip/chipCheck.d.ts +7 -0
- package/dist/forms/effects/chip/chipCheck.js +26 -0
- package/dist/forms/effects/chip/chipCheck.schema.d.ts +1 -0
- package/dist/forms/effects/chip/chipCheck.schema.js +9 -0
- package/dist/forms/effects/chip/chipMerge.d.ts +9 -0
- package/dist/forms/effects/chip/chipMerge.js +63 -0
- package/dist/forms/effects/chip/chipMerge.schema.d.ts +1 -0
- package/dist/forms/effects/chip/chipMerge.schema.js +10 -0
- package/dist/forms/effects/file/fileButton.d.ts +7 -0
- package/dist/forms/effects/file/fileButton.js +28 -0
- package/dist/forms/effects/file/fileButton.schema.d.ts +1 -0
- package/dist/forms/effects/file/fileButton.schema.js +9 -0
- package/dist/forms/effects/file/fileCards.d.ts +7 -0
- package/dist/forms/effects/file/fileCards.js +38 -0
- package/dist/forms/effects/file/fileCards.schema.d.ts +1 -0
- package/dist/forms/effects/file/fileCards.schema.js +9 -0
- package/dist/forms/effects/file/fileDrag.d.ts +9 -0
- package/dist/forms/effects/file/fileDrag.js +45 -0
- package/dist/forms/effects/file/fileDrag.schema.d.ts +1 -0
- package/dist/forms/effects/file/fileDrag.schema.js +10 -0
- package/dist/forms/effects/file/filePage.d.ts +7 -0
- package/dist/forms/effects/file/filePage.js +46 -0
- package/dist/forms/effects/file/filePage.schema.d.ts +1 -0
- package/dist/forms/effects/file/filePage.schema.js +9 -0
- package/dist/forms/effects/file/filePreview.d.ts +7 -0
- package/dist/forms/effects/file/filePreview.js +17 -0
- package/dist/forms/effects/file/filePreview.schema.d.ts +1 -0
- package/dist/forms/effects/file/filePreview.schema.js +9 -0
- package/dist/forms/effects/file/fileProgress.d.ts +9 -0
- package/dist/forms/effects/file/fileProgress.js +92 -0
- package/dist/forms/effects/file/fileProgress.schema.d.ts +1 -0
- package/dist/forms/effects/file/fileProgress.schema.js +10 -0
- package/dist/forms/effects/file/fileReject.d.ts +7 -0
- package/dist/forms/effects/file/fileReject.js +24 -0
- package/dist/forms/effects/file/fileReject.schema.d.ts +1 -0
- package/dist/forms/effects/file/fileReject.schema.js +9 -0
- package/dist/forms/effects/input/inputAside.d.ts +11 -0
- package/dist/forms/effects/input/inputAside.js +42 -0
- package/dist/forms/effects/input/inputAside.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputAside.schema.js +11 -0
- package/dist/forms/effects/input/inputBeam.d.ts +14 -0
- package/dist/forms/effects/input/inputBeam.js +51 -0
- package/dist/forms/effects/input/inputBeam.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputBeam.schema.js +18 -0
- package/dist/forms/effects/input/inputCaret.d.ts +13 -0
- package/dist/forms/effects/input/inputCaret.js +33 -0
- package/dist/forms/effects/input/inputCaret.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputCaret.schema.js +26 -0
- package/dist/forms/effects/input/inputCounter.d.ts +16 -0
- package/dist/forms/effects/input/inputCounter.js +84 -0
- package/dist/forms/effects/input/inputCounter.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputCounter.schema.js +12 -0
- package/dist/forms/effects/input/inputCycle.d.ts +19 -0
- package/dist/forms/effects/input/inputCycle.js +93 -0
- package/dist/forms/effects/input/inputCycle.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputCycle.schema.js +11 -0
- package/dist/forms/effects/input/inputDepth.d.ts +11 -0
- package/dist/forms/effects/input/inputDepth.js +31 -0
- package/dist/forms/effects/input/inputDepth.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputDepth.schema.js +11 -0
- package/dist/forms/effects/input/inputDraw.d.ts +13 -0
- package/dist/forms/effects/input/inputDraw.js +27 -0
- package/dist/forms/effects/input/inputDraw.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputDraw.schema.js +12 -0
- package/dist/forms/effects/input/inputFlap.d.ts +9 -0
- package/dist/forms/effects/input/inputFlap.js +24 -0
- package/dist/forms/effects/input/inputFlap.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputFlap.schema.js +10 -0
- package/dist/forms/effects/input/inputFloat.d.ts +12 -0
- package/dist/forms/effects/input/inputFloat.js +46 -0
- package/dist/forms/effects/input/inputFloat.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputFloat.schema.js +10 -0
- package/dist/forms/effects/input/inputFlood.d.ts +11 -0
- package/dist/forms/effects/input/inputFlood.js +30 -0
- package/dist/forms/effects/input/inputFlood.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputFlood.schema.js +11 -0
- package/dist/forms/effects/input/inputFrame.d.ts +18 -0
- package/dist/forms/effects/input/inputFrame.js +77 -0
- package/dist/forms/effects/input/inputFrame.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputFrame.schema.js +13 -0
- package/dist/forms/effects/input/inputIcon.d.ts +11 -0
- package/dist/forms/effects/input/inputIcon.js +18 -0
- package/dist/forms/effects/input/inputIcon.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputIcon.schema.js +11 -0
- package/dist/forms/effects/input/inputNotch.d.ts +9 -0
- package/dist/forms/effects/input/inputNotch.js +70 -0
- package/dist/forms/effects/input/inputNotch.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputNotch.schema.js +10 -0
- package/dist/forms/effects/input/inputReveal.d.ts +15 -0
- package/dist/forms/effects/input/inputReveal.js +56 -0
- package/dist/forms/effects/input/inputReveal.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputReveal.schema.js +16 -0
- package/dist/forms/effects/input/inputRing.d.ts +13 -0
- package/dist/forms/effects/input/inputRing.js +27 -0
- package/dist/forms/effects/input/inputRing.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputRing.schema.js +12 -0
- package/dist/forms/effects/input/inputRise.d.ts +9 -0
- package/dist/forms/effects/input/inputRise.js +22 -0
- package/dist/forms/effects/input/inputRise.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputRise.schema.js +10 -0
- package/dist/forms/effects/input/inputSearch.d.ts +9 -0
- package/dist/forms/effects/input/inputSearch.js +37 -0
- package/dist/forms/effects/input/inputSearch.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputSearch.schema.js +10 -0
- package/dist/forms/effects/input/inputSkeleton.d.ts +7 -0
- package/dist/forms/effects/input/inputSkeleton.js +41 -0
- package/dist/forms/effects/input/inputSkeleton.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputSkeleton.schema.js +9 -0
- package/dist/forms/effects/input/inputSpotlight.d.ts +9 -0
- package/dist/forms/effects/input/inputSpotlight.js +20 -0
- package/dist/forms/effects/input/inputSpotlight.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputSpotlight.schema.js +10 -0
- package/dist/forms/effects/input/inputStrength.d.ts +9 -0
- package/dist/forms/effects/input/inputStrength.js +29 -0
- package/dist/forms/effects/input/inputStrength.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputStrength.schema.js +10 -0
- package/dist/forms/effects/input/inputSwap.d.ts +11 -0
- package/dist/forms/effects/input/inputSwap.js +39 -0
- package/dist/forms/effects/input/inputSwap.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputSwap.schema.js +11 -0
- package/dist/forms/effects/input/inputUnderline.d.ts +13 -0
- package/dist/forms/effects/input/inputUnderline.js +36 -0
- package/dist/forms/effects/input/inputUnderline.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputUnderline.schema.js +18 -0
- package/dist/forms/effects/input/inputWave.d.ts +11 -0
- package/dist/forms/effects/input/inputWave.js +23 -0
- package/dist/forms/effects/input/inputWave.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputWave.schema.js +11 -0
- package/dist/forms/effects/input/inputWavy.d.ts +11 -0
- package/dist/forms/effects/input/inputWavy.js +53 -0
- package/dist/forms/effects/input/inputWavy.schema.d.ts +1 -0
- package/dist/forms/effects/input/inputWavy.schema.js +11 -0
- package/dist/forms/effects/kit.d.ts +213 -0
- package/dist/forms/effects/kit.js +226 -0
- package/dist/forms/effects/picker/chipPop.d.ts +7 -0
- package/dist/forms/effects/picker/chipPop.js +28 -0
- package/dist/forms/effects/picker/chipPop.schema.d.ts +1 -0
- package/dist/forms/effects/picker/chipPop.schema.js +9 -0
- package/dist/forms/effects/picker/listHighlight.d.ts +9 -0
- package/dist/forms/effects/picker/listHighlight.js +42 -0
- package/dist/forms/effects/picker/listHighlight.schema.d.ts +1 -0
- package/dist/forms/effects/picker/listHighlight.schema.js +10 -0
- package/dist/forms/effects/picker/listMatch.d.ts +7 -0
- package/dist/forms/effects/picker/listMatch.js +21 -0
- package/dist/forms/effects/picker/listMatch.schema.d.ts +1 -0
- package/dist/forms/effects/picker/listMatch.schema.js +9 -0
- package/dist/forms/effects/picker/pickerArrow.d.ts +9 -0
- package/dist/forms/effects/picker/pickerArrow.js +17 -0
- package/dist/forms/effects/picker/pickerArrow.schema.d.ts +1 -0
- package/dist/forms/effects/picker/pickerArrow.schema.js +10 -0
- package/dist/forms/effects/picker/pickerCheck.d.ts +7 -0
- package/dist/forms/effects/picker/pickerCheck.js +31 -0
- package/dist/forms/effects/picker/pickerCheck.schema.d.ts +1 -0
- package/dist/forms/effects/picker/pickerCheck.schema.js +9 -0
- package/dist/forms/effects/picker/pickerOpen.d.ts +12 -0
- package/dist/forms/effects/picker/pickerOpen.js +34 -0
- package/dist/forms/effects/picker/pickerOpen.schema.d.ts +1 -0
- package/dist/forms/effects/picker/pickerOpen.schema.js +16 -0
- package/dist/forms/effects/picker/pickerSheet.d.ts +9 -0
- package/dist/forms/effects/picker/pickerSheet.js +47 -0
- package/dist/forms/effects/picker/pickerSheet.schema.d.ts +1 -0
- package/dist/forms/effects/picker/pickerSheet.schema.js +10 -0
- package/dist/forms/effects/picker/pickerStagger.d.ts +9 -0
- package/dist/forms/effects/picker/pickerStagger.js +31 -0
- package/dist/forms/effects/picker/pickerStagger.schema.d.ts +1 -0
- package/dist/forms/effects/picker/pickerStagger.schema.js +10 -0
- package/dist/forms/effects/radio/radioCard.d.ts +10 -0
- package/dist/forms/effects/radio/radioCard.js +15 -0
- package/dist/forms/effects/radio/radioCard.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioCard.schema.js +9 -0
- package/dist/forms/effects/radio/radioCircle.d.ts +9 -0
- package/dist/forms/effects/radio/radioCircle.js +49 -0
- package/dist/forms/effects/radio/radioCircle.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioCircle.schema.js +10 -0
- package/dist/forms/effects/radio/radioDot.d.ts +7 -0
- package/dist/forms/effects/radio/radioDot.js +10 -0
- package/dist/forms/effects/radio/radioDot.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioDot.schema.js +9 -0
- package/dist/forms/effects/radio/radioEmoji.d.ts +9 -0
- package/dist/forms/effects/radio/radioEmoji.js +94 -0
- package/dist/forms/effects/radio/radioEmoji.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioEmoji.schema.js +10 -0
- package/dist/forms/effects/radio/radioPulse.d.ts +9 -0
- package/dist/forms/effects/radio/radioPulse.js +24 -0
- package/dist/forms/effects/radio/radioPulse.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioPulse.schema.js +10 -0
- package/dist/forms/effects/radio/radioScale.d.ts +9 -0
- package/dist/forms/effects/radio/radioScale.js +73 -0
- package/dist/forms/effects/radio/radioScale.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioScale.schema.js +10 -0
- package/dist/forms/effects/radio/radioSegment.d.ts +7 -0
- package/dist/forms/effects/radio/radioSegment.js +52 -0
- package/dist/forms/effects/radio/radioSegment.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioSegment.schema.js +9 -0
- package/dist/forms/effects/radio/radioStars.d.ts +15 -0
- package/dist/forms/effects/radio/radioStars.js +125 -0
- package/dist/forms/effects/radio/radioStars.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioStars.schema.js +13 -0
- package/dist/forms/effects/radio/radioTravel.d.ts +9 -0
- package/dist/forms/effects/radio/radioTravel.js +49 -0
- package/dist/forms/effects/radio/radioTravel.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioTravel.schema.js +10 -0
- package/dist/forms/effects/radio/radioUnderline.d.ts +9 -0
- package/dist/forms/effects/radio/radioUnderline.js +61 -0
- package/dist/forms/effects/radio/radioUnderline.schema.d.ts +1 -0
- package/dist/forms/effects/radio/radioUnderline.schema.js +10 -0
- package/dist/forms/effects/radio/shape.d.ts +13 -0
- package/dist/forms/effects/radio/shape.js +61 -0
- package/dist/forms/effects/range/rangeBubble.d.ts +9 -0
- package/dist/forms/effects/range/rangeBubble.js +54 -0
- package/dist/forms/effects/range/rangeBubble.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeBubble.schema.js +10 -0
- package/dist/forms/effects/range/rangeElastic.d.ts +9 -0
- package/dist/forms/effects/range/rangeElastic.js +101 -0
- package/dist/forms/effects/range/rangeElastic.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeElastic.schema.js +10 -0
- package/dist/forms/effects/range/rangeFace.d.ts +11 -0
- package/dist/forms/effects/range/rangeFace.js +68 -0
- package/dist/forms/effects/range/rangeFace.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeFace.schema.js +11 -0
- package/dist/forms/effects/range/rangeFill.d.ts +7 -0
- package/dist/forms/effects/range/rangeFill.js +29 -0
- package/dist/forms/effects/range/rangeFill.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeFill.schema.js +9 -0
- package/dist/forms/effects/range/rangeHistogram.d.ts +14 -0
- package/dist/forms/effects/range/rangeHistogram.js +65 -0
- package/dist/forms/effects/range/rangeHistogram.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeHistogram.schema.js +11 -0
- package/dist/forms/effects/range/rangeThumb.d.ts +9 -0
- package/dist/forms/effects/range/rangeThumb.js +39 -0
- package/dist/forms/effects/range/rangeThumb.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeThumb.schema.js +10 -0
- package/dist/forms/effects/range/rangeTicks.d.ts +9 -0
- package/dist/forms/effects/range/rangeTicks.js +44 -0
- package/dist/forms/effects/range/rangeTicks.schema.d.ts +1 -0
- package/dist/forms/effects/range/rangeTicks.schema.js +18 -0
- package/dist/forms/effects/ring.d.ts +5 -0
- package/dist/forms/effects/ring.js +12 -0
- package/dist/forms/effects/step/stepProgress.d.ts +9 -0
- package/dist/forms/effects/step/stepProgress.js +35 -0
- package/dist/forms/effects/step/stepProgress.schema.d.ts +1 -0
- package/dist/forms/effects/step/stepProgress.schema.js +10 -0
- package/dist/forms/effects/step/stepSlide.d.ts +9 -0
- package/dist/forms/effects/step/stepSlide.js +50 -0
- package/dist/forms/effects/step/stepSlide.schema.d.ts +1 -0
- package/dist/forms/effects/step/stepSlide.schema.js +10 -0
- package/dist/forms/effects/switch/switchBulb.d.ts +9 -0
- package/dist/forms/effects/switch/switchBulb.js +70 -0
- package/dist/forms/effects/switch/switchBulb.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchBulb.schema.js +10 -0
- package/dist/forms/effects/switch/switchDayNight.d.ts +15 -0
- package/dist/forms/effects/switch/switchDayNight.js +96 -0
- package/dist/forms/effects/switch/switchDayNight.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchDayNight.schema.js +13 -0
- package/dist/forms/effects/switch/switchFace.d.ts +7 -0
- package/dist/forms/effects/switch/switchFace.js +75 -0
- package/dist/forms/effects/switch/switchFace.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchFace.schema.js +9 -0
- package/dist/forms/effects/switch/switchFlip.d.ts +7 -0
- package/dist/forms/effects/switch/switchFlip.js +45 -0
- package/dist/forms/effects/switch/switchFlip.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchFlip.schema.js +9 -0
- package/dist/forms/effects/switch/switchGoo.d.ts +7 -0
- package/dist/forms/effects/switch/switchGoo.js +95 -0
- package/dist/forms/effects/switch/switchGoo.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchGoo.schema.js +9 -0
- package/dist/forms/effects/switch/switchIcon.d.ts +9 -0
- package/dist/forms/effects/switch/switchIcon.js +63 -0
- package/dist/forms/effects/switch/switchIcon.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchIcon.schema.js +10 -0
- package/dist/forms/effects/switch/switchLabels.d.ts +11 -0
- package/dist/forms/effects/switch/switchLabels.js +55 -0
- package/dist/forms/effects/switch/switchLabels.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchLabels.schema.js +11 -0
- package/dist/forms/effects/switch/switchMorph.d.ts +9 -0
- package/dist/forms/effects/switch/switchMorph.js +22 -0
- package/dist/forms/effects/switch/switchMorph.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchMorph.schema.js +10 -0
- package/dist/forms/effects/switch/switchNeon.d.ts +11 -0
- package/dist/forms/effects/switch/switchNeon.js +53 -0
- package/dist/forms/effects/switch/switchNeon.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchNeon.schema.js +11 -0
- package/dist/forms/effects/switch/switchSlide.d.ts +7 -0
- package/dist/forms/effects/switch/switchSlide.js +11 -0
- package/dist/forms/effects/switch/switchSlide.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchSlide.schema.js +9 -0
- package/dist/forms/effects/switch/switchStretch.d.ts +9 -0
- package/dist/forms/effects/switch/switchStretch.js +21 -0
- package/dist/forms/effects/switch/switchStretch.schema.d.ts +1 -0
- package/dist/forms/effects/switch/switchStretch.schema.js +10 -0
- package/dist/forms/effects/valid/validAsync.d.ts +7 -0
- package/dist/forms/effects/valid/validAsync.js +36 -0
- package/dist/forms/effects/valid/validAsync.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validAsync.schema.js +9 -0
- package/dist/forms/effects/valid/validBubble.d.ts +7 -0
- package/dist/forms/effects/valid/validBubble.js +61 -0
- package/dist/forms/effects/valid/validBubble.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validBubble.schema.js +9 -0
- package/dist/forms/effects/valid/validCheck.d.ts +9 -0
- package/dist/forms/effects/valid/validCheck.js +50 -0
- package/dist/forms/effects/valid/validCheck.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validCheck.schema.js +10 -0
- package/dist/forms/effects/valid/validColor.d.ts +11 -0
- package/dist/forms/effects/valid/validColor.js +28 -0
- package/dist/forms/effects/valid/validColor.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validColor.schema.js +11 -0
- package/dist/forms/effects/valid/validFlash.d.ts +9 -0
- package/dist/forms/effects/valid/validFlash.js +36 -0
- package/dist/forms/effects/valid/validFlash.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validFlash.schema.js +10 -0
- package/dist/forms/effects/valid/validMessage.d.ts +7 -0
- package/dist/forms/effects/valid/validMessage.js +24 -0
- package/dist/forms/effects/valid/validMessage.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validMessage.schema.js +9 -0
- package/dist/forms/effects/valid/validShake.d.ts +9 -0
- package/dist/forms/effects/valid/validShake.js +37 -0
- package/dist/forms/effects/valid/validShake.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validShake.schema.js +10 -0
- package/dist/forms/effects/valid/validSwap.d.ts +7 -0
- package/dist/forms/effects/valid/validSwap.js +33 -0
- package/dist/forms/effects/valid/validSwap.schema.d.ts +1 -0
- package/dist/forms/effects/valid/validSwap.schema.js +9 -0
- package/dist/forms/errors.d.ts +12 -0
- package/dist/forms/errors.js +20 -0
- package/dist/forms/file.d.ts +1 -0
- package/dist/forms/file.js +268 -0
- package/dist/forms/files.d.ts +7 -0
- package/dist/forms/files.js +29 -0
- package/dist/forms/formSteps.d.ts +9 -0
- package/dist/forms/formSteps.js +6 -0
- package/dist/forms/ids.d.ts +17 -0
- package/dist/forms/ids.js +13 -0
- package/dist/forms/inline.d.ts +3 -0
- package/dist/forms/inline.js +128 -0
- package/dist/forms/number.d.ts +1 -0
- package/dist/forms/number.js +67 -0
- package/dist/forms/otp.d.ts +4 -0
- package/dist/forms/otp.js +171 -0
- package/dist/forms/picker.d.ts +1 -0
- package/dist/forms/picker.js +303 -0
- package/dist/forms/range.d.ts +3 -0
- package/dist/forms/range.js +223 -0
- package/dist/forms/registry.d.ts +4 -0
- package/dist/forms/registry.js +133 -0
- package/dist/forms/reveal.d.ts +6 -0
- package/dist/forms/reveal.js +51 -0
- package/dist/forms/runtime/focus.d.ts +16 -0
- package/dist/forms/runtime/focus.js +55 -0
- package/dist/forms/runtime/listMatch.d.ts +2 -0
- package/dist/forms/runtime/listMatch.js +33 -0
- package/dist/forms/runtime/origin.d.ts +10 -0
- package/dist/forms/runtime/origin.js +25 -0
- package/dist/forms/runtime/placePopup.d.ts +10 -0
- package/dist/forms/runtime/placePopup.js +55 -0
- package/dist/forms/runtime/useFlip.d.ts +7 -0
- package/dist/forms/runtime/useFlip.js +38 -0
- package/dist/forms/runtime/useMorph.d.ts +8 -0
- package/dist/forms/runtime/useMorph.js +56 -0
- package/dist/forms/runtime/useOffScreen.d.ts +3 -0
- package/dist/forms/runtime/useOffScreen.js +16 -0
- package/dist/forms/runtime/useSwitchDrag.d.ts +8 -0
- package/dist/forms/runtime/useSwitchDrag.js +83 -0
- package/dist/forms/runtime/vanish.d.ts +6 -0
- package/dist/forms/runtime/vanish.js +185 -0
- package/dist/forms/steps.d.ts +1 -0
- package/dist/forms/steps.js +149 -0
- package/dist/forms/swap.d.ts +7 -0
- package/dist/forms/swap.js +149 -0
- package/dist/forms/switch.d.ts +1 -0
- package/dist/forms/switch.js +99 -0
- package/dist/forms/tools.d.ts +3 -0
- package/dist/forms/tools.js +248 -0
- package/dist/forms/types.d.ts +161 -0
- package/dist/forms/types.js +5 -0
- package/dist/index.d.ts +234 -0
- package/dist/index.js +119 -0
- package/dist/schema/forms.d.ts +3 -0
- package/dist/schema/forms.js +194 -0
- package/dist/schema/index.d.ts +2 -1
- package/dist/schema/index.js +3 -1
- package/dist/schema/types.d.ts +2 -2
- package/dist/schema/types.js +1 -0
- package/guides/README.md +62 -61
- package/guides/contact.md +100 -77
- package/guides/forms.md +105 -0
- package/package.json +1 -1
- package/styles/form.css +594 -0
- package/theme.css +6 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Every form effect's metadata, from the Form Effects Atlas and the rows found
|
|
3
|
+
// online. The docs and the schemas read it. Factories live in the barrel; this
|
|
4
|
+
// file imports none of them. Keep it in step with test/fixtures/forms-atlas.mjs.
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
function row(id, label, group, fits, fires, tech, description, extra = {}) {
|
|
7
|
+
return { id, label, group, fits, fires, tech, tier: extra.tier ?? "all", description, ...(extra.limited ? { limited: extra.limited } : {}) };
|
|
8
|
+
}
|
|
9
|
+
const FIELD = ["field"];
|
|
10
|
+
const CHECK = ["checkbox"];
|
|
11
|
+
const RADIO = ["radio"];
|
|
12
|
+
const SWITCH = ["switch"];
|
|
13
|
+
const PICKER = ["picker"];
|
|
14
|
+
const RANGE = ["range"];
|
|
15
|
+
const CHIP = ["chip"];
|
|
16
|
+
const FILE = ["file"];
|
|
17
|
+
const STEPS = ["steps"];
|
|
18
|
+
export const FORM_EFFECTS = [
|
|
19
|
+
row("inputFloat", "Floating label", "input", FIELD, ["focus", "typing"], "css", "The label sits in the field and moves up, smaller, on focus or once there is text."),
|
|
20
|
+
row("inputUnderline", "Underline grow", "input", FIELD, ["focus"], "css", "A line grows along the bottom edge on focus: from a side, the centre or where you clicked."),
|
|
21
|
+
row("inputDraw", "Border draw-around", "input", FIELD, ["focus"], "svg", "The outline draws itself around the field on focus."),
|
|
22
|
+
row("inputRise", "Background rise", "input", FIELD, ["focus"], "css", "A colour rises from the bottom and fills the field on focus."),
|
|
23
|
+
row("inputAside", "Label slides aside", "input", FIELD, ["focus", "typing"], "css", "The label's panel covers the field, then shrinks to its start side so you can type."),
|
|
24
|
+
row("inputWavy", "Wavy line", "input", FIELD, ["focus"], "svg", "The bottom line wobbles like jelly on focus, then settles flat."),
|
|
25
|
+
row("inputRing", "Focus glow ring", "input", FIELD, ["focus"], "css", "A soft ring grows out from the field, or shrinks onto it, on focus."),
|
|
26
|
+
row("inputSpotlight", "Spotlight on focus", "input", FIELD, ["focus"], "css", "The other fields of the form dim while one has the focus."),
|
|
27
|
+
row("inputIcon", "Icon reacts on focus", "input", FIELD, ["focus"], "css", "The field's icon takes the colour and grows a little on focus."),
|
|
28
|
+
row("inputSearch", "Expanding search", "input", FIELD, ["focus", "typing"], "css", "A search icon opens into a full field on focus, and closes again when left empty."),
|
|
29
|
+
row("inputNotch", "Notched outline", "input", FIELD, ["focus", "typing"], "css", "The label floats onto the border, which opens a gap for it."),
|
|
30
|
+
row("inputSwap", "Label text swap", "input", FIELD, ["focus"], "css", "The label's words roll up, and other words (or a coloured copy) roll in."),
|
|
31
|
+
row("inputFrame", "Frame split", "input", FIELD, ["focus"], "css", "Bars meet and slide apart to frame the field, or its two bracket halves pull apart."),
|
|
32
|
+
row("inputFlap", "Flap fold", "input", FIELD, ["focus"], "css", "A coloured flap swings down from the top edge on focus."),
|
|
33
|
+
row("inputFlood", "Icon flood", "input", FIELD, ["focus"], "css", "A circle grows out of the icon until it floods the field."),
|
|
34
|
+
row("inputWave", "Wave label", "input", FIELD, ["focus"], "css", "The label's letters hop up one after another on focus."),
|
|
35
|
+
row("inputBeam", "Border beam", "input", FIELD, ["focus", "idle"], "css", "A light with a tail runs around the edge while the field has focus, or all the time."),
|
|
36
|
+
row("inputDepth", "Depth sink / lift", "input", FIELD, ["focus"], "css", "The field sinks into the page, or lifts off a hard shadow, on focus."),
|
|
37
|
+
row("inputSkeleton", "Skeleton while loading", "input", FIELD, ["idle"], "css", "A shimmering placeholder covers the field while its value loads (`busy`)."),
|
|
38
|
+
row("inputCaret", "Caret shape and blink", "input", FIELD, ["focus"], "native", "A coloured caret, a block or underscore shape, a soft or steady blink.", {
|
|
39
|
+
limited: "caret-shape and caret-animation: Chrome only; other browsers keep the colour and their own caret.",
|
|
40
|
+
}),
|
|
41
|
+
row("inputCounter", "Character counter ring", "input", FIELD, ["typing"], "svg", "A ring fills as you type, turns amber near the limit and red past it (`counter`)."),
|
|
42
|
+
row("inputReveal", "Password reveal", "input", FIELD, ["change"], "svg", "The show-password eye blinks and is crossed out, or a flashlight beam lights the password (`reveal`)."),
|
|
43
|
+
row("inputStrength", "Strength meter fill", "input", FIELD, ["typing"], "css", "The strength meter's bars fill one after another, and the new word drops in (`strength`)."),
|
|
44
|
+
row("inputCycle", "Cycling placeholders + vanish", "input", FIELD, ["idle", "submit"], "js", "The empty field's placeholder cycles through phrases; the text you send breaks into dust and the field empties."),
|
|
45
|
+
row("validColor", "Red / green border", "valid", FIELD, ["validate"], "css", "The border turns red when the field is wrong and green when it is right, once the user has left it."),
|
|
46
|
+
row("validShake", "Shake on error", "valid", FIELD, ["validate", "submit"], "css", "The field shakes when it turns wrong, and again when the user is sent back to it."),
|
|
47
|
+
row("validMessage", "Error message slide-down", "valid", FIELD, ["validate"], "css", "The error slides down under the field as its row opens smoothly."),
|
|
48
|
+
row("validCheck", "Check draws in", "valid", FIELD, ["validate"], "svg", "A check mark draws itself at the end of the field once it is right."),
|
|
49
|
+
row("validSwap", "Help → error swap", "valid", FIELD, ["validate"], "css", "The help text rolls away and the error rolls into its place."),
|
|
50
|
+
row("validBubble", "Anchored error bubble", "valid", FIELD, ["validate"], "css", "The error pops up in a bubble tied to the field, over the page, so nothing moves.", {
|
|
51
|
+
limited: "anchor positioning: without it the bubble sits under the whole field.",
|
|
52
|
+
}),
|
|
53
|
+
row("validFlash", "Flash the first error", "valid", FIELD, ["submit"], "css", "The field blinks twice when the user is sent to it (`focusFirstError`, `ErrorSummary`)."),
|
|
54
|
+
row("validAsync", "Async check mark", "valid", FIELD, ["validate"], "svg", "The async check's spinner closes into a ring and a check or a cross draws inside (`status`)."),
|
|
55
|
+
row("checkDraw", "Check mark draw", "check", CHECK, ["change"], "svg", "The tick draws itself into the box, a moment after the box fills."),
|
|
56
|
+
row("checkPop", "Scale pop", "check", CHECK, ["change"], "css", "The box squeezes while pressed and springs back; the tick grows in."),
|
|
57
|
+
row("checkMorph", "Box → tick morph", "check", CHECK, ["change"], "svg", "The box's outline runs off and folds into the tick: one line becomes the other."),
|
|
58
|
+
row("checkJelly", "Jelly bounce", "check", CHECK, ["change"], "css", "The box wobbles like jelly when checked by hand."),
|
|
59
|
+
row("checkScribble", "Hand-drawn scribble", "check", CHECK, ["change"], "svg", "A loose hand-drawn tick, or a cross, scribbles itself over the box."),
|
|
60
|
+
row("checkStrike", "To-do strikethrough", "check", CHECK, ["change"], "css", "A line strikes the words through and they go quiet; or the box flattens into the line."),
|
|
61
|
+
row("checkMixed", "Indeterminate dash", "check", CHECK, ["change"], "css", "The mixed dash grows out from the middle and gives way to the tick."),
|
|
62
|
+
row("checkCard", "Selectable card", "check", CHECK, ["change"], "css", "The option is a card holding box, words and help, lit when checked."),
|
|
63
|
+
row("checkConfetti", "Confetti on check", "check", CHECK, ["change"], "canvas", "Confetti bursts from the box when it is checked by hand (the page's one burst canvas)."),
|
|
64
|
+
row("checkRipple", "State layer and ripple", "check", CHECK, ["focus", "change"], "css", "A soft disc behind the box answers the mouse, the keyboard's focus and a press."),
|
|
65
|
+
row("checkHeart", "Heart like with burst", "check", CHECK, ["change"], "svg", "The box is a heart: liked, it fills, pops and throws a ring of dots."),
|
|
66
|
+
row("checkMerge", "Merging neighbours", "check", CHECK, ["change"], "css", "Checked neighbours' highlights join into one block."),
|
|
67
|
+
row("radioDot", "Dot scale-in", "radio", RADIO, ["change"], "css", "The dot springs in on the chosen radio and shrinks away on the one left."),
|
|
68
|
+
row("radioPulse", "Ring pulse", "radio", RADIO, ["change"], "css", "A ring pulses out once from the radio the user chose."),
|
|
69
|
+
row("radioCircle", "Hand-drawn circle", "radio", RADIO, ["change"], "svg", "A pen circles the chosen option's words."),
|
|
70
|
+
row("radioSegment", "Segmented control", "radio", RADIO, ["change"], "css", "Options in a tray, a thumb sliding under the chosen one."),
|
|
71
|
+
row("radioCard", "Radio cards", "radio", RADIO, ["change"], "css", "Each option is a card holding circle, words and help; the chosen one lit."),
|
|
72
|
+
row("radioStars", "Star rating", "radio", RADIO, ["change"], "svg", "Stars fill up to the choice; half stars, a wave under the mouse, a burst of sparks."),
|
|
73
|
+
row("radioEmoji", "Emoji rating", "radio", RADIO, ["change"], "svg", "Five faces, frown to smile: the chosen one lights up and wobbles."),
|
|
74
|
+
row("radioTravel", "Travelling dot", "radio", RADIO, ["change"], "css", "One dot travels from the old choice to the new one.", {
|
|
75
|
+
limited: "anchor positioning: Firefox moves the dot at once; without it, each circle keeps its own dot.",
|
|
76
|
+
}),
|
|
77
|
+
row("radioUnderline", "Tab underline", "radio", RADIO, ["change"], "css", "Tabs: an underline follows the chosen option.", {
|
|
78
|
+
limited: "anchor positioning: Firefox moves the line at once; without it, the chosen tab is underlined on its own.",
|
|
79
|
+
}),
|
|
80
|
+
row("radioScale", "NPS 0-10 scale", "radio", RADIO, ["change"], "css", "Numbered cells, the chosen one filled; groups marked by a quiet bar."),
|
|
81
|
+
row("switchSlide", "iOS-style slide", "switch", SWITCH, ["change"], "css", "The thumb slides across with a little overshoot."),
|
|
82
|
+
row("switchStretch", "Thumb stretch", "switch", SWITCH, ["change"], "css", "The thumb stretches toward the other side while pressed, then springs back."),
|
|
83
|
+
row("switchDayNight", "Day / night toggle", "switch", SWITCH, ["change"], "css", "The sun turns into a moon, clouds drift off and stars come out."),
|
|
84
|
+
row("switchBulb", "Light bulb", "switch", SWITCH, ["change"], "svg", "The thumb is a bulb: on, it lights up, catching with a stutter, and glows."),
|
|
85
|
+
row("switchNeon", "Neon switch", "switch", SWITCH, ["change", "idle"], "css", "A neon tube strikes with a flicker, then hums (an endless glow: it pauses off screen)."),
|
|
86
|
+
row("switchFlip", "3D coin flip", "switch", SWITCH, ["change"], "css", "The thumb is a coin that turns over: a cross on one face, a tick on the other."),
|
|
87
|
+
row("switchMorph", "Shape-morph thumb", "switch", SWITCH, ["change"], "css", "The thumb morphs from a circle into a rounded square, turning as it crosses."),
|
|
88
|
+
row("switchGoo", "Gooey switch", "switch", SWITCH, ["change"], "svg", "The thumb is a drop that stretches into a bridge and snaps round on the other side.", { tier: "mid" }),
|
|
89
|
+
row("switchFace", "Character switch", "switch", SWITCH, ["change"], "svg", "A sleeping face wakes up when switched on: eyes open, a smile, a blink."),
|
|
90
|
+
row("switchIcon", "Thumb grows with ✓ / ✗", "switch", SWITCH, ["change"], "css", "The thumb grows when on and shows a tick; off, it shrinks and shows a cross."),
|
|
91
|
+
row("switchLabels", "ON / OFF in the track", "switch", SWITCH, ["change"], "css", "A short word inside the track on the side the thumb has left."),
|
|
92
|
+
row("pickerArrow", "Arrow rotate on open", "select", PICKER, ["focus"], "css", "The arrow turns over while the list is open, and back when it closes."),
|
|
93
|
+
row("pickerOpen", "Popover fade / scale / unroll", "select", PICKER, ["focus"], "css", "The list grows, fades or unrolls into view as it opens, and back as it closes.", {
|
|
94
|
+
limited: "a Select's own list only where it can be styled (appearance: base-select, Chrome 135+, Safari 27); a Combobox everywhere. Firefox shows a list that flips above at once.",
|
|
95
|
+
}),
|
|
96
|
+
row("pickerStagger", "Staggered options", "select", PICKER, ["focus"], "css", "The options drop into the list one after another as it opens.", {
|
|
97
|
+
limited: "a Select's options need sibling-index() and a stylable list; elsewhere they arrive together.",
|
|
98
|
+
}),
|
|
99
|
+
row("listHighlight", "Highlight slide", "select", PICKER, ["typing"], "css", "One highlight slides from option to option as you move through the list. A Combobox's only.", {
|
|
100
|
+
limited: "anchor positioning: Firefox moves the highlight at once; without it, each option lights on its own.",
|
|
101
|
+
}),
|
|
102
|
+
row("chipPop", "Chips pop in and out", "select", PICKER, ["change"], "css", "Chips pop in when picked and shrink away when removed; the others glide into place. A Combobox's only."),
|
|
103
|
+
row("pickerCheck", "Option checkmark", "select", PICKER, ["change"], "svg", "The chosen option's tick draws itself in, at the end of the option."),
|
|
104
|
+
row("pickerSheet", "Bottom sheet on phones", "select", PICKER, ["focus"], "css", "On a phone the list docks at the bottom of the screen and slides up, within reach of a thumb."),
|
|
105
|
+
row("listMatch", "Typed text marked", "select", PICKER, ["typing"], "js", "The typed text is marked inside each option as you filter (the Custom Highlight API). A Combobox's only."),
|
|
106
|
+
row("rangeThumb", "Thumb grow on drag", "range", RANGE, ["drag"], "css", "The thumb grows under the finger, with a soft halo round it."),
|
|
107
|
+
row("rangeFill", "Filled track", "range", RANGE, ["drag"], "css", "The rail fills up to the thumb, or between the two thumbs."),
|
|
108
|
+
row("rangeBubble", "Value bubble", "range", RANGE, ["drag"], "css", "A bubble above the thumb shows the value while you drag (or always)."),
|
|
109
|
+
row("rangeElastic", "Elastic slider", "range", RANGE, ["drag"], "js", "Pull past the end and the rail stretches after the finger, then springs back."),
|
|
110
|
+
row("rangeTicks", "Snap ticks", "range", RANGE, ["drag"], "css", "Ticks under the rail, one per step; the thumb springs from tick to tick."),
|
|
111
|
+
row("rangeFace", "Face slider", "range", RANGE, ["drag"], "svg", "The thumb is a face that frowns at the low end and smiles at the high end."),
|
|
112
|
+
row("rangeHistogram", "Histogram range", "range", RANGE, ["drag"], "svg", "Bars above the rail show how the values spread; the chosen stretch lights up.", {
|
|
113
|
+
limited: "across only: an upright Range hides the bars.",
|
|
114
|
+
}),
|
|
115
|
+
row("chipCheck", "Filter chip check slides in", "select", CHIP, ["change"], "css", "A chip's check slides in from its start as it turns on, the words making room, and its tick draws."),
|
|
116
|
+
row("chipMerge", "Merging filter chips", "select", CHIP, ["change"], "css", "Chips that are on next to each other merge into one block: the gap fills, the corners that meet square off."),
|
|
117
|
+
row("fileDrag", "Drag-over highlight", "file", FILE, ["drag"], "css", "While files are dragged over the zone it takes a tint, grows a little and its icon hops; red for files it won't take."),
|
|
118
|
+
row("fileButton", "Styled file button", "file", FILE, ["change"], "css", "The browser's own file button, dressed as a solid pill that lifts on hover and dips on a press."),
|
|
119
|
+
row("fileCards", "File cards + micro interactions", "file", FILE, ["change"], "css", "Cards rise in as files are added, slide out when removed, and the others glide into place."),
|
|
120
|
+
row("fileProgress", "Upload progress", "file", FILE, ["submit"], "css", "Each file's upload fills a bar (or a ring) smoothly, ending in a check that draws itself."),
|
|
121
|
+
row("filePreview", "Image preview fade-in", "file", FILE, ["change"], "css", "Image files show a thumbnail in their card, fading in once it has loaded."),
|
|
122
|
+
row("filePage", "Page-wide drop overlay", "file", FILE, ["drag"], "css", "The page-wide drop overlay (`page`) fades in, its dashed frame settling and its words rising."),
|
|
123
|
+
row("fileReject", "Reject shake", "file", FILE, ["drag"], "css", "A refused file shakes the zone and turns its line red; so do files it won't take, while dragged over it."),
|
|
124
|
+
row("stepSlide", "Step slide (next / back)", "flow", STEPS, ["submit"], "css", "Steps slide in from the end and out toward the start (back the other way), or rise and fall one question at a time."),
|
|
125
|
+
row("stepProgress", "Progress stepper", "flow", STEPS, ["submit"], "css", "The progress rail fills smoothly, finished steps' checks draw themselves, the new current step pops."),
|
|
126
|
+
];
|
|
127
|
+
export const FORM_IDS = new Set(FORM_EFFECTS.map((m) => m.id));
|
|
128
|
+
export function formMetaOf(id) {
|
|
129
|
+
const meta = FORM_EFFECTS.find((m) => m.id === id);
|
|
130
|
+
if (!meta)
|
|
131
|
+
throw new Error(`[@sharedex/ui] unknown form effect "${id}"`);
|
|
132
|
+
return meta;
|
|
133
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const REVEAL_CSS = "@layer theme, base, components, utilities;\n@layer components {\n :where([data-sx-reveal]) {\n display: grid;\n grid-template-rows: 0fr;\n min-inline-size: 0;\n }\n :where([data-sx-reveal][data-sx-open]) {\n grid-template-rows: 1fr;\n }\n :where([data-sx-reveal-body]) {\n display: grid;\n gap: 1rem;\n min-block-size: 0;\n min-inline-size: 0;\n margin: 0;\n padding: 0;\n border: 0;\n overflow: hidden;\n }\n :where([data-sx-reveal][data-sx-open] > [data-sx-reveal-body]) {\n overflow: visible;\n }\n :where([data-sx-reveal-body] > legend) {\n padding: 0;\n }\n}";
|
|
2
|
+
/**
|
|
3
|
+
* What moves: the row eases open and shut (the one repaint it needs), the fields fade in from a little above. The body
|
|
4
|
+
* clips while it moves and lets focus rings out once open (overflow flips at the end, as a discrete transition).
|
|
5
|
+
*/
|
|
6
|
+
export declare const REVEAL_MOTION = "@layer components {\n :where([data-sx-reveal]) {\n transition: grid-template-rows 0.3s var(--ease-sx-out, ease-out);\n }\n :where([data-sx-reveal-body]) {\n transition: opacity 0.25s ease-out, translate 0.3s var(--ease-sx-out, ease-out), overflow 0s;\n transition-behavior: allow-discrete;\n }\n :where([data-sx-reveal]:not([data-sx-open]) > [data-sx-reveal-body]) {\n translate: 0 -0.5rem;\n opacity: 0;\n }\n :where([data-sx-reveal][data-sx-open] > [data-sx-reveal-body]) {\n transition-delay: 0s, 0s, 0.3s;\n }\n}";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// The sheets of FormReveal: fields that open below a choice. A grid row that grows from 0fr to 1fr round a fieldset
|
|
2
|
+
// that is disabled (and inert) while closed, so its fields are neither submitted nor checked until they show. Pure strings.
|
|
3
|
+
import { LAYER_ORDER } from "../backgrounds/runtime/rootCss.js";
|
|
4
|
+
const OPEN = "[data-sx-reveal][data-sx-open]";
|
|
5
|
+
export const REVEAL_CSS = `${LAYER_ORDER}
|
|
6
|
+
@layer components {
|
|
7
|
+
:where([data-sx-reveal]) {
|
|
8
|
+
display: grid;
|
|
9
|
+
grid-template-rows: 0fr;
|
|
10
|
+
min-inline-size: 0;
|
|
11
|
+
}
|
|
12
|
+
:where(${OPEN}) {
|
|
13
|
+
grid-template-rows: 1fr;
|
|
14
|
+
}
|
|
15
|
+
:where([data-sx-reveal-body]) {
|
|
16
|
+
display: grid;
|
|
17
|
+
gap: 1rem;
|
|
18
|
+
min-block-size: 0;
|
|
19
|
+
min-inline-size: 0;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
border: 0;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
}
|
|
25
|
+
:where(${OPEN} > [data-sx-reveal-body]) {
|
|
26
|
+
overflow: visible;
|
|
27
|
+
}
|
|
28
|
+
:where([data-sx-reveal-body] > legend) {
|
|
29
|
+
padding: 0;
|
|
30
|
+
}
|
|
31
|
+
}`;
|
|
32
|
+
/**
|
|
33
|
+
* What moves: the row eases open and shut (the one repaint it needs), the fields fade in from a little above. The body
|
|
34
|
+
* clips while it moves and lets focus rings out once open (overflow flips at the end, as a discrete transition).
|
|
35
|
+
*/
|
|
36
|
+
export const REVEAL_MOTION = `@layer components {
|
|
37
|
+
:where([data-sx-reveal]) {
|
|
38
|
+
transition: grid-template-rows 0.3s var(--ease-sx-out, ease-out);
|
|
39
|
+
}
|
|
40
|
+
:where([data-sx-reveal-body]) {
|
|
41
|
+
transition: opacity 0.25s ease-out, translate 0.3s var(--ease-sx-out, ease-out), overflow 0s;
|
|
42
|
+
transition-behavior: allow-discrete;
|
|
43
|
+
}
|
|
44
|
+
:where([data-sx-reveal]:not([data-sx-open]) > [data-sx-reveal-body]) {
|
|
45
|
+
translate: 0 -0.5rem;
|
|
46
|
+
opacity: 0;
|
|
47
|
+
}
|
|
48
|
+
:where(${OPEN} > [data-sx-reveal-body]) {
|
|
49
|
+
transition-delay: 0s, 0s, 0.3s;
|
|
50
|
+
}
|
|
51
|
+
}`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Marks the control's field `data-sx-flash` for one flash, restarting it when it is already flashing. */
|
|
2
|
+
export declare function flashField(control: Element): void;
|
|
3
|
+
/** Scrolls a control to the middle of the screen (no glide under reduced motion), focuses it and flashes its field. */
|
|
4
|
+
export declare function goToField(control: HTMLElement, flash?: boolean): void;
|
|
5
|
+
/**
|
|
6
|
+
* After a failed submit: moves the focus to the first wrong field (in page order), scrolled to the middle of the
|
|
7
|
+
* screen, and flashes it. It waits two frames first, so the `aria-invalid` your app just set is on the page. Resolves
|
|
8
|
+
* to the control, or `null` when nothing is wrong.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const onSubmit = form.handleSubmit(save, () => focusFirstError(formRef.current));
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function focusFirstError(within?: ParentNode | null, options?: {
|
|
15
|
+
readonly flash?: boolean;
|
|
16
|
+
}): Promise<HTMLElement | null>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Sending the user to a field: scroll it to the middle of the screen, move the focus there, and flash it once
|
|
2
|
+
// (`validFlash`, `validShake` play on `data-sx-flash`). Plain functions, no React: `focusFirstError` is called from a
|
|
3
|
+
// submit handler. Safe to import on the server: nothing runs until it is called.
|
|
4
|
+
const FLASH_MS = 1200;
|
|
5
|
+
const timers = new WeakMap();
|
|
6
|
+
/** Marks the control's field `data-sx-flash` for one flash, restarting it when it is already flashing. */
|
|
7
|
+
export function flashField(control) {
|
|
8
|
+
const root = control.closest("[data-sx-field]");
|
|
9
|
+
if (!root)
|
|
10
|
+
return;
|
|
11
|
+
root.removeAttribute("data-sx-flash");
|
|
12
|
+
// read a size so the browser sees the attribute go, and plays the animation again when it comes back
|
|
13
|
+
void root.offsetWidth;
|
|
14
|
+
root.setAttribute("data-sx-flash", "");
|
|
15
|
+
clearTimeout(timers.get(root));
|
|
16
|
+
timers.set(root, setTimeout(() => root.removeAttribute("data-sx-flash"), FLASH_MS));
|
|
17
|
+
}
|
|
18
|
+
/** Scrolls a control to the middle of the screen (no glide under reduced motion), focuses it and flashes its field. */
|
|
19
|
+
export function goToField(control, flash = true) {
|
|
20
|
+
const still = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
21
|
+
control.scrollIntoView({ block: "center", behavior: still ? "auto" : "smooth" });
|
|
22
|
+
control.focus({ preventScroll: true });
|
|
23
|
+
if (flash)
|
|
24
|
+
flashField(control);
|
|
25
|
+
}
|
|
26
|
+
/** The app said it's wrong, or the browser did once the user had a go at it. Never `:invalid`: an untouched field isn't. */
|
|
27
|
+
const WRONG = '[aria-invalid="true"], input:user-invalid, textarea:user-invalid, select:user-invalid';
|
|
28
|
+
const frame = () => new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
29
|
+
/**
|
|
30
|
+
* After a failed submit: moves the focus to the first wrong field (in page order), scrolled to the middle of the
|
|
31
|
+
* screen, and flashes it. It waits two frames first, so the `aria-invalid` your app just set is on the page. Resolves
|
|
32
|
+
* to the control, or `null` when nothing is wrong.
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* const onSubmit = form.handleSubmit(save, () => focusFirstError(formRef.current));
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export async function focusFirstError(within, options = {}) {
|
|
39
|
+
if (typeof document === "undefined")
|
|
40
|
+
return null;
|
|
41
|
+
await frame();
|
|
42
|
+
await frame();
|
|
43
|
+
const scope = within ?? document;
|
|
44
|
+
let control;
|
|
45
|
+
try {
|
|
46
|
+
control = scope.querySelector(WRONG);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// a browser without :user-invalid
|
|
50
|
+
control = scope.querySelector('[aria-invalid="true"]');
|
|
51
|
+
}
|
|
52
|
+
if (control)
|
|
53
|
+
goToField(control, options.flash !== false);
|
|
54
|
+
return control;
|
|
55
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Marks the typed text inside a combobox's options with the Custom Highlight API: no extra elements, no re-render, and
|
|
2
|
+
// the option's words stay one text node for screen readers. One highlight (`sx-list-match`) serves every combobox on the
|
|
3
|
+
// page; each adds its own ranges and takes them back. A browser without the API marks nothing.
|
|
4
|
+
let shared = null;
|
|
5
|
+
/** Replaces this list's marked ranges with the places `query` appears in its options' words. Returns the new ranges. */
|
|
6
|
+
export function markMatches(list, query, previous) {
|
|
7
|
+
if (typeof Highlight === "undefined" || typeof CSS === "undefined" || !("highlights" in CSS))
|
|
8
|
+
return [];
|
|
9
|
+
if (!shared) {
|
|
10
|
+
shared = new Highlight();
|
|
11
|
+
CSS.highlights.set("sx-list-match", shared);
|
|
12
|
+
}
|
|
13
|
+
for (const range of previous)
|
|
14
|
+
shared.delete(range);
|
|
15
|
+
const needle = query.trim().toLowerCase();
|
|
16
|
+
if (!list || !needle)
|
|
17
|
+
return [];
|
|
18
|
+
const ranges = [];
|
|
19
|
+
for (const words of list.querySelectorAll("[data-sx-option-text]")) {
|
|
20
|
+
const walk = document.createTreeWalker(words, NodeFilter.SHOW_TEXT);
|
|
21
|
+
for (let node = walk.nextNode(); node; node = walk.nextNode()) {
|
|
22
|
+
const hay = node.data.toLowerCase();
|
|
23
|
+
for (let at = hay.indexOf(needle); at !== -1; at = hay.indexOf(needle, at + needle.length)) {
|
|
24
|
+
const range = new Range();
|
|
25
|
+
range.setStart(node, at);
|
|
26
|
+
range.setEnd(node, at + needle.length);
|
|
27
|
+
ranges.push(range);
|
|
28
|
+
shared.add(range);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return ranges;
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The press's position across the box, 0 (left edge) to 1 (right edge). Pure; tested. */
|
|
2
|
+
export declare function originOf(clientX: number, rect: {
|
|
3
|
+
readonly left: number;
|
|
4
|
+
readonly width: number;
|
|
5
|
+
}): number;
|
|
6
|
+
/**
|
|
7
|
+
* Writes `--sx-field-ox` on `root` on each press inside `box`, and removes it when the field loses the focus, so the
|
|
8
|
+
* next keyboard focus grows from the effect's own default. Returns what stops it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function attachOrigin(root: HTMLElement, box: HTMLElement): () => void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Where a field was pressed, for effects that grow from that point (`inputUnderline({ from: "pointer" })`). Plain
|
|
2
|
+
// module: one listener on the box, attached only while such an effect is on the field.
|
|
3
|
+
/** The press's position across the box, 0 (left edge) to 1 (right edge). Pure; tested. */
|
|
4
|
+
export function originOf(clientX, rect) {
|
|
5
|
+
if (rect.width <= 0)
|
|
6
|
+
return 0.5;
|
|
7
|
+
return Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Writes `--sx-field-ox` on `root` on each press inside `box`, and removes it when the field loses the focus, so the
|
|
11
|
+
* next keyboard focus grows from the effect's own default. Returns what stops it.
|
|
12
|
+
*/
|
|
13
|
+
export function attachOrigin(root, box) {
|
|
14
|
+
const press = (event) => root.style.setProperty("--sx-field-ox", String(originOf(event.clientX, box.getBoundingClientRect())));
|
|
15
|
+
const leave = (event) => {
|
|
16
|
+
if (!root.contains(event.relatedTarget))
|
|
17
|
+
root.style.removeProperty("--sx-field-ox");
|
|
18
|
+
};
|
|
19
|
+
box.addEventListener("pointerdown", press);
|
|
20
|
+
root.addEventListener("focusout", leave);
|
|
21
|
+
return () => {
|
|
22
|
+
box.removeEventListener("pointerdown", press);
|
|
23
|
+
root.removeEventListener("focusout", leave);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Starts placing `popup` against `box`. Returns what stops it. */
|
|
2
|
+
export declare function placeByHand(popup: HTMLElement, box: HTMLElement): () => void;
|
|
3
|
+
/**
|
|
4
|
+
* A popup docked at the bottom of a phone's screen (`pickerSheet`, which sets `--sx-picker-docked: 1` there) must not
|
|
5
|
+
* cover the box being typed into, nor sit behind the on-screen keyboard (a phone shrinks only the visible part of the
|
|
6
|
+
* page for it, so `bottom: 0` is behind the keys). So, while it is open: the box scrolls to the top of the screen once,
|
|
7
|
+
* the keyboard's height goes in `--sx-picker-keyboard`, and the room left between the box and the keyboard in
|
|
8
|
+
* `--sx-picker-room`, which caps the sheet. Elsewhere it does nothing. Returns what stops it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function dockSheet(popup: HTMLElement, box: HTMLElement): () => void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Places a combobox's popup by hand in a browser without anchor positioning: under the box, as wide as it, flipped
|
|
2
|
+
// above when the screen has no room below, kept in place on scroll and resize. Where anchor positioning exists (every
|
|
3
|
+
// current engine), CSS does it all and this does nothing.
|
|
4
|
+
/** Starts placing `popup` against `box`. Returns what stops it. */
|
|
5
|
+
export function placeByHand(popup, box) {
|
|
6
|
+
if (typeof CSS === "undefined" || CSS.supports("position-area: block-end"))
|
|
7
|
+
return () => { };
|
|
8
|
+
const place = () => {
|
|
9
|
+
const r = box.getBoundingClientRect();
|
|
10
|
+
const high = popup.offsetHeight;
|
|
11
|
+
const below = innerHeight - r.bottom;
|
|
12
|
+
const up = below < high + 8 && r.top > below;
|
|
13
|
+
Object.assign(popup.style, {
|
|
14
|
+
position: "fixed",
|
|
15
|
+
margin: "0",
|
|
16
|
+
left: `${r.left}px`,
|
|
17
|
+
width: `${r.width}px`,
|
|
18
|
+
top: `${up ? r.top - high - 4 : r.bottom + 4}px`,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
place();
|
|
22
|
+
addEventListener("scroll", place, true);
|
|
23
|
+
addEventListener("resize", place);
|
|
24
|
+
return () => {
|
|
25
|
+
removeEventListener("scroll", place, true);
|
|
26
|
+
removeEventListener("resize", place);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A popup docked at the bottom of a phone's screen (`pickerSheet`, which sets `--sx-picker-docked: 1` there) must not
|
|
31
|
+
* cover the box being typed into, nor sit behind the on-screen keyboard (a phone shrinks only the visible part of the
|
|
32
|
+
* page for it, so `bottom: 0` is behind the keys). So, while it is open: the box scrolls to the top of the screen once,
|
|
33
|
+
* the keyboard's height goes in `--sx-picker-keyboard`, and the room left between the box and the keyboard in
|
|
34
|
+
* `--sx-picker-room`, which caps the sheet. Elsewhere it does nothing. Returns what stops it.
|
|
35
|
+
*/
|
|
36
|
+
export function dockSheet(popup, box) {
|
|
37
|
+
const view = typeof visualViewport === "undefined" ? null : visualViewport;
|
|
38
|
+
if (!view || getComputedStyle(popup).getPropertyValue("--sx-picker-docked").trim() !== "1")
|
|
39
|
+
return () => { };
|
|
40
|
+
box.scrollIntoView({ block: "start", behavior: "instant" });
|
|
41
|
+
const place = () => {
|
|
42
|
+
const keys = Math.max(0, innerHeight - view.height - view.offsetTop);
|
|
43
|
+
popup.style.setProperty("--sx-picker-keyboard", `${keys}px`);
|
|
44
|
+
popup.style.setProperty("--sx-picker-room", `${Math.max(160, innerHeight - keys - box.getBoundingClientRect().bottom - 8)}px`);
|
|
45
|
+
};
|
|
46
|
+
place();
|
|
47
|
+
view.addEventListener("resize", place);
|
|
48
|
+
view.addEventListener("scroll", place);
|
|
49
|
+
addEventListener("scroll", place, true);
|
|
50
|
+
return () => {
|
|
51
|
+
view.removeEventListener("resize", place);
|
|
52
|
+
view.removeEventListener("scroll", place);
|
|
53
|
+
removeEventListener("scroll", place, true);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* FLIP for a row of items keyed by `data-key` (a combobox's chips): after each render, an item that moved starts where
|
|
4
|
+
* it was (an inline `translate` with no transition) and, one frame later, glides to its new place through the
|
|
5
|
+
* transition an effect gives it (`chipPop`). Items leaving (`data-sx-leaving`) stay put. Off unless `enabled`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useFlip(container: RefObject<HTMLElement | null>, enabled: boolean, selector: string): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLayoutEffect, useRef } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* FLIP for a row of items keyed by `data-key` (a combobox's chips): after each render, an item that moved starts where
|
|
5
|
+
* it was (an inline `translate` with no transition) and, one frame later, glides to its new place through the
|
|
6
|
+
* transition an effect gives it (`chipPop`). Items leaving (`data-sx-leaving`) stay put. Off unless `enabled`.
|
|
7
|
+
*/
|
|
8
|
+
export function useFlip(container, enabled, selector) {
|
|
9
|
+
const last = useRef(new Map());
|
|
10
|
+
useLayoutEffect(() => {
|
|
11
|
+
const root = container.current;
|
|
12
|
+
if (!root || !enabled)
|
|
13
|
+
return;
|
|
14
|
+
const now = new Map();
|
|
15
|
+
for (const item of root.querySelectorAll(selector)) {
|
|
16
|
+
const key = item.dataset.key;
|
|
17
|
+
if (!key)
|
|
18
|
+
continue;
|
|
19
|
+
const rect = item.getBoundingClientRect();
|
|
20
|
+
now.set(key, rect);
|
|
21
|
+
const before = last.current.get(key);
|
|
22
|
+
if (!before || item.hasAttribute("data-sx-leaving"))
|
|
23
|
+
continue;
|
|
24
|
+
const dx = before.left - rect.left;
|
|
25
|
+
const dy = before.top - rect.top;
|
|
26
|
+
if (!dx && !dy)
|
|
27
|
+
continue;
|
|
28
|
+
item.style.transition = "none";
|
|
29
|
+
item.style.translate = `${dx}px ${dy}px`;
|
|
30
|
+
void item.offsetWidth;
|
|
31
|
+
requestAnimationFrame(() => {
|
|
32
|
+
item.style.transition = "";
|
|
33
|
+
item.style.translate = "";
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
last.current = now;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A box that eases from its old height to its new one when `key` changes (a step, a swapped view), instead of jumping:
|
|
4
|
+
* the old height is kept from the last commit (and from a ResizeObserver as the content changes in between), the box
|
|
5
|
+
* is held there before the browser paints, then let go to the new height through a transition of `block-size`, the one
|
|
6
|
+
* repaint the plan allows for this. Nothing under reduced motion, or with `on` false.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMorph(ref: RefObject<HTMLElement | null>, key: unknown, on: boolean): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useLayoutEffect, useRef } from "react";
|
|
3
|
+
import { stillMotion } from "../../buttons/runtime/press.js";
|
|
4
|
+
/**
|
|
5
|
+
* A box that eases from its old height to its new one when `key` changes (a step, a swapped view), instead of jumping:
|
|
6
|
+
* the old height is kept from the last commit (and from a ResizeObserver as the content changes in between), the box
|
|
7
|
+
* is held there before the browser paints, then let go to the new height through a transition of `block-size`, the one
|
|
8
|
+
* repaint the plan allows for this. Nothing under reduced motion, or with `on` false.
|
|
9
|
+
*/
|
|
10
|
+
export function useMorph(ref, key, on) {
|
|
11
|
+
const last = useRef(0);
|
|
12
|
+
const busy = useRef(false);
|
|
13
|
+
useLayoutEffect(() => {
|
|
14
|
+
const el = ref.current;
|
|
15
|
+
if (!el)
|
|
16
|
+
return;
|
|
17
|
+
const to = el.offsetHeight;
|
|
18
|
+
const from = last.current;
|
|
19
|
+
last.current = to;
|
|
20
|
+
if (!on || !from || Math.abs(to - from) < 2 || stillMotion())
|
|
21
|
+
return;
|
|
22
|
+
busy.current = true;
|
|
23
|
+
el.style.overflow = "clip";
|
|
24
|
+
el.style.blockSize = `${from}px`;
|
|
25
|
+
void el.offsetHeight;
|
|
26
|
+
el.style.transition = "block-size var(--sx-morph-time, 0.32s) var(--ease-sx-out, ease-out)";
|
|
27
|
+
el.style.blockSize = `${to}px`;
|
|
28
|
+
let timer = 0;
|
|
29
|
+
const done = (e) => {
|
|
30
|
+
if (e && (e.target !== el || e.propertyName !== "block-size"))
|
|
31
|
+
return;
|
|
32
|
+
window.clearTimeout(timer);
|
|
33
|
+
el.removeEventListener("transitionend", done);
|
|
34
|
+
el.style.blockSize = "";
|
|
35
|
+
el.style.transition = "";
|
|
36
|
+
el.style.overflow = "";
|
|
37
|
+
busy.current = false;
|
|
38
|
+
last.current = el.offsetHeight;
|
|
39
|
+
};
|
|
40
|
+
el.addEventListener("transitionend", done);
|
|
41
|
+
timer = window.setTimeout(done, 700);
|
|
42
|
+
return () => done();
|
|
43
|
+
}, [key]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
44
|
+
// the content grows and shrinks between changes (a message opens, a textarea grows): keep the height fresh
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const el = ref.current;
|
|
47
|
+
if (!el || typeof ResizeObserver === "undefined")
|
|
48
|
+
return;
|
|
49
|
+
const watch = new ResizeObserver(() => {
|
|
50
|
+
if (!busy.current)
|
|
51
|
+
last.current = el.offsetHeight;
|
|
52
|
+
});
|
|
53
|
+
watch.observe(el);
|
|
54
|
+
return () => watch.disconnect();
|
|
55
|
+
}, [ref]);
|
|
56
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
/** Marks a control `data-sx-field-off` while it is off screen, so CSS pauses its endless effects. */
|
|
4
|
+
export function useOffScreen(ref, enabled) {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const el = ref.current;
|
|
7
|
+
if (!el || !enabled || typeof IntersectionObserver === "undefined")
|
|
8
|
+
return;
|
|
9
|
+
const io = new IntersectionObserver((entries) => {
|
|
10
|
+
for (const entry of entries)
|
|
11
|
+
el.toggleAttribute("data-sx-field-off", !entry.isIntersecting);
|
|
12
|
+
});
|
|
13
|
+
io.observe(el);
|
|
14
|
+
return () => io.disconnect();
|
|
15
|
+
}, [ref, enabled]);
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Drag a switch's thumb with a finger or the mouse; let go past halfway and it toggles, short of it and it snaps back.
|
|
4
|
+
* A tap still toggles as always, and the value still commits on the click, never on the press: the drag only decides
|
|
5
|
+
* whether that click goes through. While dragging, the root carries `data-sx-dragging` and `--sx-switch-drag` (0-1),
|
|
6
|
+
* which the base sheet turns into the thumb's place.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useSwitchDrag(root: RefObject<HTMLElement | null>, enabled: boolean): void;
|