@g9tm/lynxcontrols 0.0.0-stage → 1.4.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 +22 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/base/base.css +16 -0
- package/dist/base/base.css.map +1 -0
- package/dist/base/control.d.ts +44 -0
- package/dist/base/control.d.ts.map +1 -0
- package/dist/base/control.jsx +24 -0
- package/dist/base/control.jsx.map +1 -0
- package/dist/base/corner-badge.d.ts +35 -0
- package/dist/base/corner-badge.d.ts.map +1 -0
- package/dist/base/corner-badge.jsx +45 -0
- package/dist/base/corner-badge.jsx.map +1 -0
- package/dist/base/disposer.d.ts +28 -0
- package/dist/base/disposer.d.ts.map +1 -0
- package/dist/base/disposer.jsx +61 -0
- package/dist/base/disposer.jsx.map +1 -0
- package/dist/base/index.d.ts +10 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.jsx +9 -0
- package/dist/base/press.d.ts +38 -0
- package/dist/base/press.d.ts.map +1 -0
- package/dist/base/press.jsx +73 -0
- package/dist/base/press.jsx.map +1 -0
- package/dist/base/pressable.d.ts +25 -0
- package/dist/base/pressable.d.ts.map +1 -0
- package/dist/base/pressable.jsx +38 -0
- package/dist/base/pressable.jsx.map +1 -0
- package/dist/base/selection-item.d.ts +29 -0
- package/dist/base/selection-item.d.ts.map +1 -0
- package/dist/base/selection-item.jsx +6 -0
- package/dist/base/selection-item.jsx.map +1 -0
- package/dist/base/timers.d.ts +7 -0
- package/dist/base/timers.d.ts.map +1 -0
- package/dist/base/timers.jsx +10 -0
- package/dist/base/timers.jsx.map +1 -0
- package/dist/base/use-controllable-state.d.ts +30 -0
- package/dist/base/use-controllable-state.d.ts.map +1 -0
- package/dist/base/use-controllable-state.jsx +49 -0
- package/dist/base/use-controllable-state.jsx.map +1 -0
- package/dist/base/use-stable-callback.d.ts +8 -0
- package/dist/base/use-stable-callback.d.ts.map +1 -0
- package/dist/base/use-stable-callback.jsx +12 -0
- package/dist/base/use-stable-callback.jsx.map +1 -0
- package/dist/button/button.css +162 -0
- package/dist/button/button.css.map +1 -0
- package/dist/button/button.d.ts +52 -0
- package/dist/button/button.d.ts.map +1 -0
- package/dist/button/button.jsx +87 -0
- package/dist/button/button.jsx.map +1 -0
- package/dist/button/header-action-button.d.ts +34 -0
- package/dist/button/header-action-button.d.ts.map +1 -0
- package/dist/button/header-action-button.jsx +51 -0
- package/dist/button/header-action-button.jsx.map +1 -0
- package/dist/button/icon-button.d.ts +46 -0
- package/dist/button/icon-button.d.ts.map +1 -0
- package/dist/button/icon-button.jsx +69 -0
- package/dist/button/icon-button.jsx.map +1 -0
- package/dist/button/index.d.ts +9 -0
- package/dist/button/index.d.ts.map +1 -0
- package/dist/button/index.jsx +8 -0
- package/dist/button/nav-card.d.ts +58 -0
- package/dist/button/nav-card.d.ts.map +1 -0
- package/dist/button/nav-card.jsx +95 -0
- package/dist/button/nav-card.jsx.map +1 -0
- package/dist/button/safe-tap.d.ts +27 -0
- package/dist/button/safe-tap.d.ts.map +1 -0
- package/dist/button/safe-tap.jsx +46 -0
- package/dist/button/safe-tap.jsx.map +1 -0
- package/dist/button/safe.d.ts +84 -0
- package/dist/button/safe.d.ts.map +1 -0
- package/dist/button/safe.jsx +116 -0
- package/dist/button/safe.jsx.map +1 -0
- package/dist/button/vertical-icon-text-button.d.ts +18 -0
- package/dist/button/vertical-icon-text-button.d.ts.map +1 -0
- package/dist/button/vertical-icon-text-button.jsx +21 -0
- package/dist/button/vertical-icon-text-button.jsx.map +1 -0
- package/dist/button/visuals.d.ts +53 -0
- package/dist/button/visuals.d.ts.map +1 -0
- package/dist/button/visuals.jsx +92 -0
- package/dist/button/visuals.jsx.map +1 -0
- package/dist/cascade/cascade-panel.d.ts +80 -0
- package/dist/cascade/cascade-panel.d.ts.map +1 -0
- package/dist/cascade/cascade-panel.jsx +179 -0
- package/dist/cascade/cascade-panel.jsx.map +1 -0
- package/dist/cascade/cascade.css +70 -0
- package/dist/cascade/cascade.css.map +1 -0
- package/dist/cascade/index.d.ts +3 -0
- package/dist/cascade/index.d.ts.map +1 -0
- package/dist/cascade/index.jsx +2 -0
- package/dist/cascade/model.d.ts +68 -0
- package/dist/cascade/model.d.ts.map +1 -0
- package/dist/cascade/model.jsx +161 -0
- package/dist/cascade/model.jsx.map +1 -0
- package/dist/deferred/deferred-content.d.ts +82 -0
- package/dist/deferred/deferred-content.d.ts.map +1 -0
- package/dist/deferred/deferred-content.jsx +263 -0
- package/dist/deferred/deferred-content.jsx.map +1 -0
- package/dist/deferred/deferred.css +62 -0
- package/dist/deferred/deferred.css.map +1 -0
- package/dist/deferred/index.d.ts +3 -0
- package/dist/deferred/index.d.ts.map +1 -0
- package/dist/deferred/index.jsx +2 -0
- package/dist/deferred/readiness-signal.d.ts +16 -0
- package/dist/deferred/readiness-signal.d.ts.map +1 -0
- package/dist/deferred/readiness-signal.jsx +29 -0
- package/dist/deferred/readiness-signal.jsx.map +1 -0
- package/dist/display/activity-indicator.d.ts +21 -0
- package/dist/display/activity-indicator.d.ts.map +1 -0
- package/dist/display/activity-indicator.jsx +22 -0
- package/dist/display/activity-indicator.jsx.map +1 -0
- package/dist/display/culture-date-time-label.d.ts +64 -0
- package/dist/display/culture-date-time-label.d.ts.map +1 -0
- package/dist/display/culture-date-time-label.jsx +71 -0
- package/dist/display/culture-date-time-label.jsx.map +1 -0
- package/dist/display/display.css +217 -0
- package/dist/display/display.css.map +1 -0
- package/dist/display/index.d.ts +7 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.jsx +6 -0
- package/dist/display/progress-bar.d.ts +38 -0
- package/dist/display/progress-bar.d.ts.map +1 -0
- package/dist/display/progress-bar.jsx +57 -0
- package/dist/display/progress-bar.jsx.map +1 -0
- package/dist/display/separator.d.ts +30 -0
- package/dist/display/separator.d.ts.map +1 -0
- package/dist/display/separator.jsx +55 -0
- package/dist/display/separator.jsx.map +1 -0
- package/dist/display/shimmer.d.ts +41 -0
- package/dist/display/shimmer.d.ts.map +1 -0
- package/dist/display/shimmer.jsx +41 -0
- package/dist/display/shimmer.jsx.map +1 -0
- package/dist/display/title-with-line.d.ts +13 -0
- package/dist/display/title-with-line.d.ts.map +1 -0
- package/dist/display/title-with-line.jsx +21 -0
- package/dist/display/title-with-line.jsx.map +1 -0
- package/dist/edge-panel/edge-panel.css +132 -0
- package/dist/edge-panel/edge-panel.css.map +1 -0
- package/dist/edge-panel/edge-panel.d.ts +87 -0
- package/dist/edge-panel/edge-panel.d.ts.map +1 -0
- package/dist/edge-panel/edge-panel.jsx +326 -0
- package/dist/edge-panel/edge-panel.jsx.map +1 -0
- package/dist/edge-panel/helper.d.ts +27 -0
- package/dist/edge-panel/helper.d.ts.map +1 -0
- package/dist/edge-panel/helper.jsx +118 -0
- package/dist/edge-panel/helper.jsx.map +1 -0
- package/dist/edge-panel/index.d.ts +4 -0
- package/dist/edge-panel/index.d.ts.map +1 -0
- package/dist/edge-panel/index.jsx +3 -0
- package/dist/edge-panel/types.d.ts +155 -0
- package/dist/edge-panel/types.d.ts.map +1 -0
- package/dist/edge-panel/types.jsx +139 -0
- package/dist/edge-panel/types.jsx.map +1 -0
- package/dist/expander/expander.css +54 -0
- package/dist/expander/expander.css.map +1 -0
- package/dist/expander/expander.d.ts +46 -0
- package/dist/expander/expander.d.ts.map +1 -0
- package/dist/expander/expander.jsx +110 -0
- package/dist/expander/expander.jsx.map +1 -0
- package/dist/expander/index.d.ts +2 -0
- package/dist/expander/index.d.ts.map +1 -0
- package/dist/expander/index.jsx +1 -0
- package/dist/fields/dictation.d.ts +43 -0
- package/dist/fields/dictation.d.ts.map +1 -0
- package/dist/fields/dictation.jsx +124 -0
- package/dist/fields/dictation.jsx.map +1 -0
- package/dist/fields/editor.d.ts +26 -0
- package/dist/fields/editor.d.ts.map +1 -0
- package/dist/fields/editor.jsx +46 -0
- package/dist/fields/editor.jsx.map +1 -0
- package/dist/fields/fields.css +156 -0
- package/dist/fields/fields.css.map +1 -0
- package/dist/fields/index.d.ts +12 -0
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/index.jsx +11 -0
- package/dist/fields/input-policy.d.ts +48 -0
- package/dist/fields/input-policy.d.ts.map +1 -0
- package/dist/fields/input-policy.jsx +215 -0
- package/dist/fields/input-policy.jsx.map +1 -0
- package/dist/fields/outlined-field.d.ts +146 -0
- package/dist/fields/outlined-field.d.ts.map +1 -0
- package/dist/fields/outlined-field.jsx +196 -0
- package/dist/fields/outlined-field.jsx.map +1 -0
- package/dist/fields/pin-entry.d.ts +63 -0
- package/dist/fields/pin-entry.d.ts.map +1 -0
- package/dist/fields/pin-entry.jsx +293 -0
- package/dist/fields/pin-entry.jsx.map +1 -0
- package/dist/fields/search-entry.d.ts +35 -0
- package/dist/fields/search-entry.d.ts.map +1 -0
- package/dist/fields/search-entry.jsx +118 -0
- package/dist/fields/search-entry.jsx.map +1 -0
- package/dist/fields/slot-layout.d.ts +33 -0
- package/dist/fields/slot-layout.d.ts.map +1 -0
- package/dist/fields/slot-layout.jsx +33 -0
- package/dist/fields/slot-layout.jsx.map +1 -0
- package/dist/fields/text-entry.d.ts +62 -0
- package/dist/fields/text-entry.d.ts.map +1 -0
- package/dist/fields/text-entry.jsx +72 -0
- package/dist/fields/text-entry.jsx.map +1 -0
- package/dist/fields/use-dictation.d.ts +34 -0
- package/dist/fields/use-dictation.d.ts.map +1 -0
- package/dist/fields/use-dictation.jsx +80 -0
- package/dist/fields/use-dictation.jsx.map +1 -0
- package/dist/fields/use-text-input.d.ts +150 -0
- package/dist/fields/use-text-input.d.ts.map +1 -0
- package/dist/fields/use-text-input.jsx +237 -0
- package/dist/fields/use-text-input.jsx.map +1 -0
- package/dist/fields/validator.d.ts +14 -0
- package/dist/fields/validator.d.ts.map +1 -0
- package/dist/fields/validator.jsx +20 -0
- package/dist/fields/validator.jsx.map +1 -0
- package/dist/host/back.d.ts +42 -0
- package/dist/host/back.d.ts.map +1 -0
- package/dist/host/back.jsx +47 -0
- package/dist/host/back.jsx.map +1 -0
- package/dist/host/hooks.d.ts +85 -0
- package/dist/host/hooks.d.ts.map +1 -0
- package/dist/host/hooks.jsx +163 -0
- package/dist/host/hooks.jsx.map +1 -0
- package/dist/host/host.css +81 -0
- package/dist/host/host.css.map +1 -0
- package/dist/host/host.d.ts +70 -0
- package/dist/host/host.d.ts.map +1 -0
- package/dist/host/host.jsx +229 -0
- package/dist/host/host.jsx.map +1 -0
- package/dist/host/index.d.ts +9 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.jsx +8 -0
- package/dist/host/keyboard.d.ts +24 -0
- package/dist/host/keyboard.d.ts.map +1 -0
- package/dist/host/keyboard.jsx +28 -0
- package/dist/host/keyboard.jsx.map +1 -0
- package/dist/host/layers.d.ts +69 -0
- package/dist/host/layers.d.ts.map +1 -0
- package/dist/host/layers.jsx +111 -0
- package/dist/host/layers.jsx.map +1 -0
- package/dist/host/page-loading-overlay.d.ts +17 -0
- package/dist/host/page-loading-overlay.d.ts.map +1 -0
- package/dist/host/page-loading-overlay.jsx +16 -0
- package/dist/host/page-loading-overlay.jsx.map +1 -0
- package/dist/host/readiness.d.ts +57 -0
- package/dist/host/readiness.d.ts.map +1 -0
- package/dist/host/readiness.jsx +138 -0
- package/dist/host/readiness.jsx.map +1 -0
- package/dist/host/registry.d.ts +106 -0
- package/dist/host/registry.d.ts.map +1 -0
- package/dist/host/registry.jsx +93 -0
- package/dist/host/registry.jsx.map +1 -0
- package/dist/icon/icon.css +39 -0
- package/dist/icon/icon.css.map +1 -0
- package/dist/icon/icon.d.ts +57 -0
- package/dist/icon/icon.d.ts.map +1 -0
- package/dist/icon/icon.jsx +115 -0
- package/dist/icon/icon.jsx.map +1 -0
- package/dist/icon/index.d.ts +4 -0
- package/dist/icon/index.d.ts.map +1 -0
- package/dist/icon/index.jsx +3 -0
- package/dist/icon/slot.d.ts +45 -0
- package/dist/icon/slot.d.ts.map +1 -0
- package/dist/icon/slot.jsx +61 -0
- package/dist/icon/slot.jsx.map +1 -0
- package/dist/icon/swatch.d.ts +29 -0
- package/dist/icon/swatch.d.ts.map +1 -0
- package/dist/icon/swatch.jsx +25 -0
- package/dist/icon/swatch.jsx.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.jsx +1 -0
- package/dist/pickers/combo-box.d.ts +42 -0
- package/dist/pickers/combo-box.d.ts.map +1 -0
- package/dist/pickers/combo-box.jsx +129 -0
- package/dist/pickers/combo-box.jsx.map +1 -0
- package/dist/pickers/date-time-picker.d.ts +63 -0
- package/dist/pickers/date-time-picker.d.ts.map +1 -0
- package/dist/pickers/date-time-picker.jsx +141 -0
- package/dist/pickers/date-time-picker.jsx.map +1 -0
- package/dist/pickers/date-time.d.ts +82 -0
- package/dist/pickers/date-time.d.ts.map +1 -0
- package/dist/pickers/date-time.jsx +130 -0
- package/dist/pickers/date-time.jsx.map +1 -0
- package/dist/pickers/index.d.ts +10 -0
- package/dist/pickers/index.d.ts.map +1 -0
- package/dist/pickers/index.jsx +9 -0
- package/dist/pickers/picker-sheet.d.ts +21 -0
- package/dist/pickers/picker-sheet.d.ts.map +1 -0
- package/dist/pickers/picker-sheet.jsx +61 -0
- package/dist/pickers/picker-sheet.jsx.map +1 -0
- package/dist/pickers/picker.d.ts +32 -0
- package/dist/pickers/picker.d.ts.map +1 -0
- package/dist/pickers/picker.jsx +72 -0
- package/dist/pickers/picker.jsx.map +1 -0
- package/dist/pickers/pickers.css +219 -0
- package/dist/pickers/pickers.css.map +1 -0
- package/dist/pickers/timespan-picker.d.ts +36 -0
- package/dist/pickers/timespan-picker.d.ts.map +1 -0
- package/dist/pickers/timespan-picker.jsx +99 -0
- package/dist/pickers/timespan-picker.jsx.map +1 -0
- package/dist/pickers/timespan.d.ts +38 -0
- package/dist/pickers/timespan.d.ts.map +1 -0
- package/dist/pickers/timespan.jsx +49 -0
- package/dist/pickers/timespan.jsx.map +1 -0
- package/dist/pickers/trigger.d.ts +34 -0
- package/dist/pickers/trigger.d.ts.map +1 -0
- package/dist/pickers/trigger.jsx +77 -0
- package/dist/pickers/trigger.jsx.map +1 -0
- package/dist/pickers/wheel-column.d.ts +32 -0
- package/dist/pickers/wheel-column.d.ts.map +1 -0
- package/dist/pickers/wheel-column.jsx +99 -0
- package/dist/pickers/wheel-column.jsx.map +1 -0
- package/dist/plus-button/index.d.ts +3 -0
- package/dist/plus-button/index.d.ts.map +1 -0
- package/dist/plus-button/index.jsx +2 -0
- package/dist/plus-button/model.d.ts +65 -0
- package/dist/plus-button/model.d.ts.map +1 -0
- package/dist/plus-button/model.jsx +86 -0
- package/dist/plus-button/model.jsx.map +1 -0
- package/dist/plus-button/plus-button.css +67 -0
- package/dist/plus-button/plus-button.css.map +1 -0
- package/dist/plus-button/plus-button.d.ts +38 -0
- package/dist/plus-button/plus-button.d.ts.map +1 -0
- package/dist/plus-button/plus-button.jsx +155 -0
- package/dist/plus-button/plus-button.jsx.map +1 -0
- package/dist/popup/frame.d.ts +101 -0
- package/dist/popup/frame.d.ts.map +1 -0
- package/dist/popup/frame.jsx +244 -0
- package/dist/popup/frame.jsx.map +1 -0
- package/dist/popup/index.d.ts +8 -0
- package/dist/popup/index.d.ts.map +1 -0
- package/dist/popup/index.jsx +7 -0
- package/dist/popup/input-form.d.ts +35 -0
- package/dist/popup/input-form.d.ts.map +1 -0
- package/dist/popup/input-form.jsx +160 -0
- package/dist/popup/input-form.jsx.map +1 -0
- package/dist/popup/input.d.ts +175 -0
- package/dist/popup/input.d.ts.map +1 -0
- package/dist/popup/input.jsx +176 -0
- package/dist/popup/input.jsx.map +1 -0
- package/dist/popup/popup-view.d.ts +25 -0
- package/dist/popup/popup-view.d.ts.map +1 -0
- package/dist/popup/popup-view.jsx +67 -0
- package/dist/popup/popup-view.jsx.map +1 -0
- package/dist/popup/popup.css +203 -0
- package/dist/popup/popup.css.map +1 -0
- package/dist/popup/queue.d.ts +90 -0
- package/dist/popup/queue.d.ts.map +1 -0
- package/dist/popup/queue.jsx +309 -0
- package/dist/popup/queue.jsx.map +1 -0
- package/dist/popup/service.d.ts +60 -0
- package/dist/popup/service.d.ts.map +1 -0
- package/dist/popup/service.jsx +342 -0
- package/dist/popup/service.jsx.map +1 -0
- package/dist/popup/types.d.ts +211 -0
- package/dist/popup/types.d.ts.map +1 -0
- package/dist/popup/types.jsx +218 -0
- package/dist/popup/types.jsx.map +1 -0
- package/dist/provider/contexts.d.ts +41 -0
- package/dist/provider/contexts.d.ts.map +1 -0
- package/dist/provider/contexts.jsx +11 -0
- package/dist/provider/contexts.jsx.map +1 -0
- package/dist/provider/global-events.d.ts +8 -0
- package/dist/provider/global-events.d.ts.map +1 -0
- package/dist/provider/global-events.jsx +17 -0
- package/dist/provider/global-events.jsx.map +1 -0
- package/dist/provider/hooks.d.ts +49 -0
- package/dist/provider/hooks.d.ts.map +1 -0
- package/dist/provider/hooks.jsx +72 -0
- package/dist/provider/hooks.jsx.map +1 -0
- package/dist/provider/index.d.ts +5 -0
- package/dist/provider/index.d.ts.map +1 -0
- package/dist/provider/index.jsx +3 -0
- package/dist/provider/provider.css +18 -0
- package/dist/provider/provider.css.map +1 -0
- package/dist/provider/provider.d.ts +51 -0
- package/dist/provider/provider.d.ts.map +1 -0
- package/dist/provider/provider.jsx +290 -0
- package/dist/provider/provider.jsx.map +1 -0
- package/dist/provider/settings.d.ts +99 -0
- package/dist/provider/settings.d.ts.map +1 -0
- package/dist/provider/settings.jsx +45 -0
- package/dist/provider/settings.jsx.map +1 -0
- package/dist/provider/theme-css.d.ts +12 -0
- package/dist/provider/theme-css.d.ts.map +1 -0
- package/dist/provider/theme-css.jsx +19 -0
- package/dist/provider/theme-css.jsx.map +1 -0
- package/dist/provider/theme-root.d.ts +10 -0
- package/dist/provider/theme-root.d.ts.map +1 -0
- package/dist/provider/theme-root.jsx +24 -0
- package/dist/provider/theme-root.jsx.map +1 -0
- package/dist/provider/theme.css +473 -0
- package/dist/provider/theme.css.map +1 -0
- package/dist/range-slider/index.d.ts +3 -0
- package/dist/range-slider/index.d.ts.map +1 -0
- package/dist/range-slider/index.jsx +2 -0
- package/dist/range-slider/math.d.ts +23 -0
- package/dist/range-slider/math.d.ts.map +1 -0
- package/dist/range-slider/math.jsx +71 -0
- package/dist/range-slider/math.jsx.map +1 -0
- package/dist/range-slider/range-slider.css +90 -0
- package/dist/range-slider/range-slider.css.map +1 -0
- package/dist/range-slider/range-slider.d.ts +52 -0
- package/dist/range-slider/range-slider.d.ts.map +1 -0
- package/dist/range-slider/range-slider.jsx +159 -0
- package/dist/range-slider/range-slider.jsx.map +1 -0
- package/dist/selection/index.d.ts +5 -0
- package/dist/selection/index.d.ts.map +1 -0
- package/dist/selection/index.jsx +3 -0
- package/dist/selection/model.d.ts +53 -0
- package/dist/selection/model.d.ts.map +1 -0
- package/dist/selection/model.jsx +69 -0
- package/dist/selection/model.jsx.map +1 -0
- package/dist/selection/selection-sheet.d.ts +80 -0
- package/dist/selection/selection-sheet.d.ts.map +1 -0
- package/dist/selection/selection-sheet.jsx +362 -0
- package/dist/selection/selection-sheet.jsx.map +1 -0
- package/dist/selection/selection.css +75 -0
- package/dist/selection/selection.css.map +1 -0
- package/dist/selection/use-selection-model.d.ts +9 -0
- package/dist/selection/use-selection-model.d.ts.map +1 -0
- package/dist/selection/use-selection-model.jsx +22 -0
- package/dist/selection/use-selection-model.jsx.map +1 -0
- package/dist/sheet/frame.d.ts +45 -0
- package/dist/sheet/frame.d.ts.map +1 -0
- package/dist/sheet/frame.jsx +205 -0
- package/dist/sheet/frame.jsx.map +1 -0
- package/dist/sheet/header.d.ts +35 -0
- package/dist/sheet/header.d.ts.map +1 -0
- package/dist/sheet/header.jsx +145 -0
- package/dist/sheet/header.jsx.map +1 -0
- package/dist/sheet/height-memo.d.ts +47 -0
- package/dist/sheet/height-memo.d.ts.map +1 -0
- package/dist/sheet/height-memo.jsx +100 -0
- package/dist/sheet/height-memo.jsx.map +1 -0
- package/dist/sheet/index.d.ts +11 -0
- package/dist/sheet/index.d.ts.map +1 -0
- package/dist/sheet/index.jsx +10 -0
- package/dist/sheet/loadable.d.ts +35 -0
- package/dist/sheet/loadable.d.ts.map +1 -0
- package/dist/sheet/loadable.jsx +65 -0
- package/dist/sheet/loadable.jsx.map +1 -0
- package/dist/sheet/options.d.ts +220 -0
- package/dist/sheet/options.d.ts.map +1 -0
- package/dist/sheet/options.jsx +91 -0
- package/dist/sheet/options.jsx.map +1 -0
- package/dist/sheet/processing.d.ts +22 -0
- package/dist/sheet/processing.d.ts.map +1 -0
- package/dist/sheet/processing.jsx +66 -0
- package/dist/sheet/processing.jsx.map +1 -0
- package/dist/sheet/service.d.ts +55 -0
- package/dist/sheet/service.d.ts.map +1 -0
- package/dist/sheet/service.jsx +143 -0
- package/dist/sheet/service.jsx.map +1 -0
- package/dist/sheet/sheet.css +195 -0
- package/dist/sheet/sheet.css.map +1 -0
- package/dist/sheet/sheet.d.ts +19 -0
- package/dist/sheet/sheet.d.ts.map +1 -0
- package/dist/sheet/sheet.jsx +40 -0
- package/dist/sheet/sheet.jsx.map +1 -0
- package/dist/sheet/sizing.d.ts +69 -0
- package/dist/sheet/sizing.d.ts.map +1 -0
- package/dist/sheet/sizing.jsx +146 -0
- package/dist/sheet/sizing.jsx.map +1 -0
- package/dist/sheet/stack.d.ts +161 -0
- package/dist/sheet/stack.d.ts.map +1 -0
- package/dist/sheet/stack.jsx +378 -0
- package/dist/sheet/stack.jsx.map +1 -0
- package/dist/swipe/index.d.ts +3 -0
- package/dist/swipe/index.d.ts.map +1 -0
- package/dist/swipe/index.jsx +2 -0
- package/dist/swipe/model.d.ts +72 -0
- package/dist/swipe/model.d.ts.map +1 -0
- package/dist/swipe/model.jsx +66 -0
- package/dist/swipe/model.jsx.map +1 -0
- package/dist/swipe/swipe-view.d.ts +40 -0
- package/dist/swipe/swipe-view.d.ts.map +1 -0
- package/dist/swipe/swipe-view.jsx +163 -0
- package/dist/swipe/swipe-view.jsx.map +1 -0
- package/dist/swipe/swipe.css +34 -0
- package/dist/swipe/swipe.css.map +1 -0
- package/dist/tab-bar/index.d.ts +4 -0
- package/dist/tab-bar/index.d.ts.map +1 -0
- package/dist/tab-bar/index.jsx +3 -0
- package/dist/tab-bar/metrics.d.ts +230 -0
- package/dist/tab-bar/metrics.d.ts.map +1 -0
- package/dist/tab-bar/metrics.jsx +221 -0
- package/dist/tab-bar/metrics.jsx.map +1 -0
- package/dist/tab-bar/model.d.ts +170 -0
- package/dist/tab-bar/model.d.ts.map +1 -0
- package/dist/tab-bar/model.jsx +349 -0
- package/dist/tab-bar/model.jsx.map +1 -0
- package/dist/tab-bar/tab-bar.css +173 -0
- package/dist/tab-bar/tab-bar.css.map +1 -0
- package/dist/tab-bar/tab-bar.d.ts +56 -0
- package/dist/tab-bar/tab-bar.d.ts.map +1 -0
- package/dist/tab-bar/tab-bar.jsx +343 -0
- package/dist/tab-bar/tab-bar.jsx.map +1 -0
- package/dist/tabs/index.d.ts +3 -0
- package/dist/tabs/index.d.ts.map +1 -0
- package/dist/tabs/index.jsx +2 -0
- package/dist/tabs/model.d.ts +83 -0
- package/dist/tabs/model.d.ts.map +1 -0
- package/dist/tabs/model.jsx +113 -0
- package/dist/tabs/model.jsx.map +1 -0
- package/dist/tabs/tab-view.d.ts +47 -0
- package/dist/tabs/tab-view.d.ts.map +1 -0
- package/dist/tabs/tab-view.jsx +227 -0
- package/dist/tabs/tab-view.jsx.map +1 -0
- package/dist/tabs/tabs.css +182 -0
- package/dist/tabs/tabs.css.map +1 -0
- package/dist/toast/index.d.ts +3 -0
- package/dist/toast/index.d.ts.map +1 -0
- package/dist/toast/index.jsx +2 -0
- package/dist/toast/service.d.ts +48 -0
- package/dist/toast/service.d.ts.map +1 -0
- package/dist/toast/service.jsx +201 -0
- package/dist/toast/service.jsx.map +1 -0
- package/dist/toast/store.d.ts +174 -0
- package/dist/toast/store.d.ts.map +1 -0
- package/dist/toast/store.jsx +353 -0
- package/dist/toast/store.jsx.map +1 -0
- package/dist/toast/toast.css +152 -0
- package/dist/toast/toast.css.map +1 -0
- package/dist/toggle/checkbox-math.d.ts +52 -0
- package/dist/toggle/checkbox-math.d.ts.map +1 -0
- package/dist/toggle/checkbox-math.jsx +111 -0
- package/dist/toggle/checkbox-math.jsx.map +1 -0
- package/dist/toggle/checkbox.d.ts +56 -0
- package/dist/toggle/checkbox.d.ts.map +1 -0
- package/dist/toggle/checkbox.jsx +152 -0
- package/dist/toggle/checkbox.jsx.map +1 -0
- package/dist/toggle/chip-group.d.ts +50 -0
- package/dist/toggle/chip-group.d.ts.map +1 -0
- package/dist/toggle/chip-group.jsx +107 -0
- package/dist/toggle/chip-group.jsx.map +1 -0
- package/dist/toggle/index.d.ts +5 -0
- package/dist/toggle/index.d.ts.map +1 -0
- package/dist/toggle/index.jsx +4 -0
- package/dist/toggle/switch.d.ts +52 -0
- package/dist/toggle/switch.d.ts.map +1 -0
- package/dist/toggle/switch.jsx +192 -0
- package/dist/toggle/switch.jsx.map +1 -0
- package/dist/toggle/toggle.css +189 -0
- package/dist/toggle/toggle.css.map +1 -0
- package/package.json +155 -4
- package/rspeedy/index.d.ts +21 -0
- package/rspeedy/index.mjs +75 -0
- package/rspeedy/index.test.mjs +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields/outlined-field.jsx","sources":["../../src/fields/outlined-field.tsx"],"sourcesContent":["import './fields.css';\nimport { G9FilledValueHighlight, type G9ImageSource, G9Metrics } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { g9RowStyle } from '../base/control';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Direction, useG9Settings } from '../provider/hooks';\nimport { type G9PhysicalPadding, resolveFieldSlotLayout } from './slot-layout';\n\n// MAUI `G9OutlinedFieldBase` (Controls/Shared/G9OutlinedFieldBase.cs) as composition (plan/specs/03 §5): the\n// props every outlined input shares, a pure state resolver, `useOutlinedField`, and the `<G9OutlinedField>` frame the\n// inputs put their element into.\n\n/** Props every outlined field shares (the public members of MAUI `G9OutlinedFieldBase`). */\nexport interface G9OutlinedFieldProps {\n /** Floating label. Without it the placeholder is the label (MAUI `Label ?? Placeholder`). */\n readonly label?: string | null;\n /** Placeholder; shown as the label when `label` is not set. */\n readonly placeholder?: string | null;\n /** Helper line under the field; replaced by `errorText` while the field has an error. */\n readonly helperText?: string | null;\n /** Error message, shown (in the error colour) while `hasError`. */\n readonly errorText?: string | null;\n /** Error state: error outline, label and helper colour. Validation can also set it (`validate()`). Default false. */\n readonly hasError?: boolean;\n /** Keep the label floated even when empty and unfocused. Default false. */\n readonly alwaysFloat?: boolean;\n /** Value visible and selectable but not editable (MAUI `IsReadOnly`). Default false. */\n readonly readOnly?: boolean;\n /** Not interactive and dimmed (MAUI `IsEnabled = false`). Default false. */\n readonly disabled?: boolean;\n /** Maximum characters; `-1` (default) or `0` means unlimited. */\n readonly maxLength?: number;\n /** Show the `n / max` counter (only when `maxLength > 0`). Default false. */\n readonly showCharacterCounter?: boolean;\n /** Status colour (any CSS colour or `g9Token(...)`); used while `useStatusColor`. Default the primary colour. */\n readonly statusColor?: string | null;\n /** Draw the outline in `statusColor` (emphasised) whatever the focus. Default false. */\n readonly useStatusColor?: boolean;\n /** Soft inner halo while focused (no error, no status colour). Default false. */\n readonly showFocusHalo?: boolean;\n /** Filled-value accent of this field; `'inherit'` (default) takes `settings.fields.highlightFilledValue`. */\n readonly filledValueHighlight?: G9FilledValueHighlight;\n readonly leadingEmoji?: string | null;\n readonly leadingIcon?: G9IconInput;\n readonly leadingImagePath?: string | null;\n readonly leadingImage?: G9ImageSource | null;\n readonly trailingEmoji?: string | null;\n readonly trailingIcon?: G9IconInput;\n readonly trailingImagePath?: string | null;\n readonly trailingImage?: G9ImageSource | null;\n /** Spinner in the trailing slot (wins over every trailing icon). Default false. */\n readonly isTrailingBusy?: boolean;\n /** Keep the trailing icon on the physical right in RTL too. Default false. */\n readonly forceTrailingIconRight?: boolean;\n /** Keep the leading icon on the physical left in RTL too. Default false. */\n readonly forceLeadingIconLeft?: boolean;\n /** Box height; `0` (default) uses `G9Metrics.ControlHeight` (52). */\n readonly fieldHeight?: number;\n /** Reserve the floated label's overhang above the box (MAUI `FloatingLabelClearance`, 6). Default false. */\n readonly reserveFloatingLabelClearance?: boolean;\n /** Leading icon tap (MAUI `LeadingCommand` + `CommandParameter`). Makes the icon actionable. */\n readonly onLeadingPress?: () => void;\n /** Trailing icon tap when no built-in affordance claims it (MAUI `TrailingCommand`). */\n readonly onTrailingPress?: () => void;\n /** Extra padding of the inner content (MAUI `InnerContentPadding`), physical sides. */\n readonly innerContentPadding?: Partial<G9PhysicalPadding>;\n /** Class of the root element. */\n readonly className?: string;\n}\n\n/** What {@link resolveOutlinedFieldState} needs besides the props. */\nexport interface G9OutlinedFieldStateInput {\n readonly focused: boolean;\n readonly hasValue: boolean;\n /** A value the field shows without text (a picker's selection): floats the label like a value. */\n readonly valueFloated?: boolean;\n /** App-wide filled-value accent (`settings.fields.highlightFilledValue`). */\n readonly highlightFilledValue: boolean;\n /** Characters of the value, for the counter. */\n readonly textLength: number;\n /** Resting chrome tone: `'outline'` (default) or `'placeholder'` (search). */\n readonly restingTone?: 'outline' | 'placeholder';\n}\n\n/** The resolved look of an outlined field (colours are CSS colour values). */\nexport interface G9OutlinedFieldState {\n readonly floated: boolean;\n /** Outline, floated label and trailing icon colour. */\n readonly stateColor: string;\n readonly labelColor: string;\n /** Leading icon and resting label colour. */\n readonly restingContentColor: string;\n readonly labelText: string;\n /** Helper line text (`errorText` while in error), `''` when hidden. */\n readonly helperText: string;\n readonly helperColor: string;\n /** Counter text (`'n / max'`), `''` when hidden. */\n readonly counterText: string;\n readonly footerVisible: boolean;\n readonly strokeWidth: number;\n /** Focus halo thickness, 0 when off. */\n readonly haloWidth: number;\n readonly fieldHeight: number;\n}\n\nconst v = (token: string): string => `var(--g9-${token})`;\n\n/**\n * Resolves the field's state colours and footer (MAUI `ResolveStateColor`, `ResolveFloatingLabelColor`, the footer\n * part of `Refresh`). Precedence: error > status colour > focus > accented filled value > resting.\n */\nexport function resolveOutlinedFieldState(\n props: G9OutlinedFieldProps,\n input: G9OutlinedFieldStateInput,\n): G9OutlinedFieldState {\n const hasError = props.hasError === true;\n const useStatus = props.useStatusColor === true;\n const filled = input.hasValue || input.valueFloated === true;\n const highlight = props.filledValueHighlight ?? G9FilledValueHighlight.Inherit;\n const accentFilled =\n highlight === G9FilledValueHighlight.Accent\n ? true\n : highlight === G9FilledValueHighlight.Neutral\n ? false\n : input.highlightFilledValue;\n const placeholderTone = input.restingTone === 'placeholder';\n const restingOutline = placeholderTone ? v('input-placeholder') : v('outline');\n const restingContentColor = placeholderTone ? v('input-placeholder') : v('text-tertiary');\n let stateColor: string;\n if (hasError) stateColor = v('error');\n else if (useStatus) stateColor = props.statusColor ?? v('primary');\n else if (input.focused) stateColor = v('primary');\n else stateColor = filled && accentFilled ? v('primary') : restingOutline;\n\n const floated = props.alwaysFloat === true || input.valueFloated === true || input.focused || input.hasValue;\n const neutralFilledRest = filled && !input.focused && !hasError && !useStatus && !accentFilled;\n const labelColor = floated && !neutralFilledRest ? stateColor : restingContentColor;\n\n const helperRaw = hasError ? (props.errorText ?? '') : (props.helperText ?? '');\n const helperText = helperRaw.trim() === '' ? '' : helperRaw;\n const maxLength = props.maxLength ?? -1;\n const counterText = props.showCharacterCounter === true && maxLength > 0 ? `${input.textLength} / ${maxLength}` : '';\n const emphasis = input.focused || hasError || useStatus;\n const halo = props.showFocusHalo === true && input.focused && !hasError && !useStatus;\n const labelRaw = props.label ?? props.placeholder ?? '';\n return {\n floated,\n stateColor,\n labelColor,\n restingContentColor,\n labelText: labelRaw.trim() === '' ? '' : labelRaw,\n helperText,\n helperColor: hasError ? v('error') : v('text-tertiary'),\n counterText,\n footerVisible: helperText !== '' || counterText !== '',\n strokeWidth: emphasis ? G9Metrics.OutlinedFieldEmphasisStrokeThickness : G9Metrics.OutlinedFieldStrokeThickness,\n haloWidth: halo ? G9Metrics.OutlinedFieldFocusHaloThickness : 0,\n fieldHeight: props.fieldHeight && props.fieldHeight > 0 ? props.fieldHeight : G9Metrics.ControlHeight,\n };\n}\n\n/** {@link resolveOutlinedFieldState} with the app-wide settings read from the provider. */\nexport function useOutlinedField(\n props: G9OutlinedFieldProps,\n input: Omit<G9OutlinedFieldStateInput, 'highlightFilledValue'>,\n): G9OutlinedFieldState {\n const settings = useG9Settings();\n return resolveOutlinedFieldState(props, { ...input, highlightFilledValue: settings.fields.highlightFilledValue });\n}\n\n/** A built-in trailing affordance an input puts in the trailing slot (password eye, microphone, clear). */\nexport interface G9TrailingAffordance {\n /** What it shows. */\n readonly icon: G9IconInput;\n /** Icon colour; default the state colour. */\n readonly color?: string;\n /** Accessibility label. */\n readonly label?: string;\n /** Stable key (MAUI `ResolveTrailingIconSignature`): the slot is rebuilt only when it changes. */\n readonly signature: string;\n readonly onPress: () => void;\n}\n\n/** Props of {@link G9OutlinedField}: the shared props plus what the composing input supplies. */\nexport interface G9OutlinedFieldFrameProps extends G9OutlinedFieldProps {\n readonly focused: boolean;\n readonly hasValue: boolean;\n readonly valueFloated?: boolean;\n readonly textLength?: number;\n /** The input element (or any content) inside the box. */\n readonly children?: ReactNode;\n /** A built-in trailing affordance; replaces the trailing icon props (busy still wins). */\n readonly trailingAffordance?: G9TrailingAffordance | null;\n /** Tapping the box (outside the icons) focuses the content (MAUI `FocusTarget`). */\n readonly onFocusRequest?: () => void;\n /** Resting tone (`'placeholder'` for search, MAUI `ResolveRestingOutlineColor` override). */\n readonly restingTone?: 'outline' | 'placeholder';\n /** Vertical placement of the icons and the resting label: centred (entries) or top/bottom (editor). */\n readonly multiline?: boolean;\n /** Accessibility label of the box (defaults to the label text). */\n readonly accessibilityLabel?: string;\n}\n\nfunction physicalSide(column: 0 | 2): 'left' | 'right' {\n return column === 0 ? 'left' : 'right';\n}\n\n/**\n * The outlined field frame (MAUI `G9OutlinedFieldBase`): outline with a notched floating label, leading and\n * trailing icon slots, helper/error line and counter. Inputs (`G9TextEntry`, `G9Editor`, `G9SearchEntry`, the pickers)\n * put their element in `children`. Direction is set on the root from the culture (labels, icons, helper follow it;\n * the input decides its own text direction). A tap on an icon never focuses the content; a tap elsewhere on the box\n * calls `onFocusRequest`.\n *\n * Look: colours come from the theme variables (`--g9-primary`, `--g9-outline`, `--g9-error`, …). The floated label\n * sits on the outline with the background `--g9-field-notch-background` (default `--g9-background`), which hides the\n * outline under it.\n */\nexport function G9OutlinedField(props: G9OutlinedFieldFrameProps): ReactNode {\n const direction = useG9Direction();\n const isRtl = direction === 'rtl';\n const state = useOutlinedField(props, {\n focused: props.focused,\n hasValue: props.hasValue,\n valueFloated: props.valueFloated ?? false,\n textLength: props.textLength ?? 0,\n restingTone: props.restingTone ?? 'outline',\n });\n const leading = {\n emoji: props.leadingEmoji ?? null,\n icon: props.leadingIcon,\n imagePath: props.leadingImagePath ?? null,\n image: props.leadingImage ?? null,\n };\n const trailing = {\n emoji: props.trailingEmoji ?? null,\n icon: props.trailingIcon,\n imagePath: props.trailingImagePath ?? null,\n image: props.trailingImage ?? null,\n };\n const busy = props.isTrailingBusy === true;\n const affordance = props.trailingAffordance ?? null;\n const hasLeading = hasIconSlot(leading);\n const hasTrailing = busy || affordance !== null || hasIconSlot(trailing);\n const pad = props.innerContentPadding ?? {};\n const slot = resolveFieldSlotLayout(\n {\n hasLeadingIcon: hasLeading,\n hasTrailingIcon: hasTrailing,\n isRtl,\n forceTrailingIconRight: props.forceTrailingIconRight === true,\n forceLeadingIconLeft: props.forceLeadingIconLeft === true,\n },\n { left: pad.left ?? 0, top: pad.top ?? 0, right: pad.right ?? 0, bottom: pad.bottom ?? 0 },\n );\n const disabled = props.disabled === true;\n const leadingActionable = props.onLeadingPress !== undefined;\n const trailingActionable = affordance !== null || props.onTrailingPress !== undefined;\n const onLeadingTap = () => {\n if (disabled || !leadingActionable) return;\n props.onLeadingPress?.();\n };\n const onTrailingTap = () => {\n if (disabled || busy || !trailingActionable) return;\n if (affordance) affordance.onPress();\n else props.onTrailingPress?.();\n };\n const onBoxTap = () => {\n if (!disabled) props.onFocusRequest?.();\n };\n\n const multiline = props.multiline === true;\n const labelHeight = G9Metrics.FloatingLabelHeight;\n const restTop = multiline ? (G9Metrics.ControlHeight - labelHeight) / 2 : (state.fieldHeight - labelHeight) / 2;\n const labelX = slot.labelRestX + (state.floated ? slot.labelFloatedX : 0);\n const labelAnchor = isRtl ? 'right' : 'left';\n const iconSize = G9Metrics.InputIconSize;\n const slotStyle = (column: 0 | 2, width: number, bottomAligned: boolean) => ({\n [physicalSide(column)]: '0px',\n width: `${width}px`,\n ...(bottomAligned\n ? { bottom: '0px', height: `${G9Metrics.EditorTrailingSlotHeight}px` }\n : { top: '0px', bottom: '0px' }),\n });\n\n const trailingContent = busy ? (\n <view className=\"g9-field__busy\" style={{ borderColor: state.stateColor, borderTopColor: 'transparent' }} />\n ) : affordance ? (\n <G9IconSlot icon={affordance.icon} color={affordance.color ?? state.stateColor} size={iconSize} />\n ) : (\n <G9IconSlot {...trailing} color={state.stateColor} size={iconSize} />\n );\n\n return (\n <view\n className={`g9-field g9-dir-${direction}${disabled ? ' g9-field--disabled' : ''}${props.className ? ` ${props.className}` : ''}`}\n >\n <view\n {...g9KeyboardTargetProps}\n className={`g9-field__box${state.floated ? ' g9-field__box--floated' : ''}${props.focused ? ' g9-field__box--focused' : ''}`}\n accessibility-element={false}\n style={{\n height: multiline ? undefined : `${state.fieldHeight}px`,\n minHeight: multiline ? `${state.fieldHeight}px` : undefined,\n marginTop: props.reserveFloatingLabelClearance ? `${G9Metrics.FloatingLabelClearance}px` : '0px',\n borderColor: state.stateColor,\n borderWidth: `${state.strokeWidth}px`,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n bindtap={onBoxTap}\n >\n {state.haloWidth > 0 ? (\n <view\n className=\"g9-field__halo\"\n style={{\n borderColor: state.stateColor,\n borderWidth: `${state.haloWidth}px`,\n opacity: G9Metrics.FocusRingOpacity,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n />\n ) : null}\n <view\n className=\"g9-field__content\"\n style={{\n paddingLeft: `${slot.innerPadding.left + (hasLeading && slot.leadingColumn === 0 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 0 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingRight: `${slot.innerPadding.right + (hasLeading && slot.leadingColumn === 2 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 2 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingTop: `${slot.innerPadding.top}px`,\n paddingBottom: `${slot.innerPadding.bottom}px`,\n }}\n >\n {props.children}\n </view>\n {hasLeading ? (\n <view\n className=\"g9-field__slot g9-field__slot--leading\"\n style={slotStyle(slot.leadingColumn, G9Metrics.LeadingIconSlotWidth, false)}\n catchtap={onLeadingTap}\n {...(leadingActionable ? { 'accessibility-element': true, 'accessibility-traits': 'button' } : {})}\n >\n <G9IconSlot {...leading} color={state.restingContentColor} size={iconSize} />\n </view>\n ) : null}\n {hasTrailing ? (\n <view\n key={busy ? 'busy' : affordance ? affordance.signature : 'icon'}\n className=\"g9-field__slot g9-field__slot--trailing\"\n style={slotStyle(slot.trailingColumn, G9Metrics.TrailingIconSlotWidth, multiline && !busy)}\n catchtap={onTrailingTap}\n {...(trailingActionable\n ? {\n 'accessibility-element': true,\n 'accessibility-traits': 'button',\n ...(affordance?.label ? { 'accessibility-label': affordance.label } : {}),\n }\n : {})}\n >\n {trailingContent}\n </view>\n ) : null}\n {state.labelText ? (\n <text\n className={`g9-field__label${state.floated ? ' g9-field__label--floated' : ''}`}\n style={{\n [labelAnchor]: `${G9Metrics.InputHorizontalPadding}px`,\n top: `${state.floated ? G9Metrics.FloatingLabelFloatedY : restTop}px`,\n fontSize: `${state.floated ? G9Metrics.FloatingLabelFontSizeFloat : G9Metrics.FloatingLabelFontSizeRest}px`,\n color: state.labelColor,\n transform: `translateX(${labelX}px)`,\n }}\n >\n {state.labelText}\n </text>\n ) : null}\n </view>\n {state.footerVisible ? (\n <view className=\"g9-field__footer\" style={g9RowStyle(direction)}>\n {state.helperText ? (\n <text\n className=\"g9-field__helper\"\n style={{ color: state.helperColor, textAlign: isRtl ? 'right' : 'left' }}\n >\n {state.helperText}\n </text>\n ) : (\n <view className=\"g9-field__helper\" />\n )}\n {state.counterText ? <text className=\"g9-field__counter\">{state.counterText}</text> : null}\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["v","token","resolveOutlinedFieldState","props","input","_props_filledValueHighlight","_props_statusColor","_props_errorText","_props_helperText","_props_maxLength","_ref","hasError","useStatus","filled","highlight","G9FilledValueHighlight","accentFilled","placeholderTone","restingOutline","restingContentColor","stateColor","floated","neutralFilledRest","labelColor","helperRaw","helperText","maxLength","counterText","emphasis","halo","labelRaw","G9Metrics","useOutlinedField","settings","useG9Settings","physicalSide","column","G9OutlinedField","_props_valueFloated","_props_textLength","_props_restingTone","_props_leadingEmoji","_props_leadingImagePath","_props_leadingImage","_props_trailingEmoji","_props_trailingImagePath","_props_trailingImage","_props_trailingAffordance","_props_innerContentPadding","_pad_left","_pad_top","_pad_right","_pad_bottom","_affordance_color","direction","useG9Direction","isRtl","state","leading","trailing","busy","affordance","hasLeading","hasIconSlot","hasTrailing","pad","slot","resolveFieldSlotLayout","disabled","leadingActionable","undefined","trailingActionable","onLeadingTap","onTrailingTap","onBoxTap","multiline","labelHeight","restTop","labelX","labelAnchor","iconSize","slotStyle","width","bottomAligned","trailingContent","view","G9IconSlot","g9KeyboardTargetProps","text","g9RowStyle"],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import './fields.css';
|
|
2
|
+
import { G9PinEntryType } from '@g9tm/lynxcontrols-foundation';
|
|
3
|
+
/** Props of {@link G9PinEntry} (MAUI `G9PinEntry`). */
|
|
4
|
+
export interface G9PinEntryProps {
|
|
5
|
+
/** Number of cells when `groupSizes` is not set (at least 1). Default 4. */
|
|
6
|
+
readonly length?: number;
|
|
7
|
+
/** The code (controlled; MAUI `Value`). */
|
|
8
|
+
readonly value?: string;
|
|
9
|
+
/** Initial code while uncontrolled. Default `''`. */
|
|
10
|
+
readonly defaultValue?: string;
|
|
11
|
+
/** Once per change of the code (MAUI `ValueChanged`): typing, paste, `clear()`, a re-filter after a type change. */
|
|
12
|
+
readonly onValueChange?: (value: string) => void;
|
|
13
|
+
/** Once each time the code becomes complete (MAUI `Completed`); not for a complete value the parent pushes in. */
|
|
14
|
+
readonly onComplete?: (value: string) => void;
|
|
15
|
+
/** Accepted characters; `'password'` is digits shown masked. Default `'number'`. */
|
|
16
|
+
readonly type?: G9PinEntryType;
|
|
17
|
+
/** Filler glyph of an empty cell. Default none. */
|
|
18
|
+
readonly placeholder?: string | null;
|
|
19
|
+
/** Glyph of a masked cell. Default `'●'`. */
|
|
20
|
+
readonly maskCharacter?: string;
|
|
21
|
+
/** Cell groups such as `'4-4-4-4'`; when set, their sum is the cell count and `separator` sits between groups. */
|
|
22
|
+
readonly groupSizes?: string | null;
|
|
23
|
+
/** Text between groups. Default `'-'`. */
|
|
24
|
+
readonly separator?: string | null;
|
|
25
|
+
/** Cell width. Default 44 (`G9Metrics.PinCellWidth`). */
|
|
26
|
+
readonly cellWidth?: number;
|
|
27
|
+
/** Cell height. Default 52 (`G9Metrics.PinCellHeight`). */
|
|
28
|
+
readonly cellHeight?: number;
|
|
29
|
+
/** Focus once when mounted. Default false. */
|
|
30
|
+
readonly autoFocus?: boolean;
|
|
31
|
+
readonly disabled?: boolean;
|
|
32
|
+
/** Accessibility label of the row (the progress `n / total` is always announced). */
|
|
33
|
+
readonly accessibilityLabel?: string;
|
|
34
|
+
readonly className?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Imperative handle of {@link G9PinEntry}. */
|
|
37
|
+
export interface G9PinEntryHandle {
|
|
38
|
+
/** Focuses the hidden input; typing appends after the last character (MAUI `FocusFirstEmpty`). */
|
|
39
|
+
focusFirstEmpty(): void;
|
|
40
|
+
/** Empties every cell (MAUI `Clear`). */
|
|
41
|
+
clear(): void;
|
|
42
|
+
/** Every cell is filled (MAUI `IsComplete`). */
|
|
43
|
+
readonly isComplete: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** Parses `'4-3-3-2'` into positive group sizes; blanks and non-numbers are skipped (MAUI `ParseGroupSizes`). */
|
|
46
|
+
export declare function parsePinGroupSizes(raw: string | null | undefined): number[];
|
|
47
|
+
/** Cell count: the groups' sum, else `max(1, length)`. */
|
|
48
|
+
export declare function pinCellCount(length: number, groups: readonly number[]): number;
|
|
49
|
+
/** Whether the PIN type accepts a character (MAUI `IsAllowed`: `char.IsDigit` / `IsLetter` / `IsLetterOrDigit`). */
|
|
50
|
+
export declare function isPinCharAllowed(type: G9PinEntryType, ch: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Filters and clamps a code (MAUI `FilterAndClamp`): Persian and Arabic-Indic digits become ASCII, disallowed
|
|
53
|
+
* characters are dropped, the rest is cut to `cells`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function filterPin(raw: string | null | undefined, type: G9PinEntryType, cells: number): string;
|
|
56
|
+
/**
|
|
57
|
+
* One-time-code / PIN entry (MAUI `G9PinEntry`): a row of cells over one hidden `<input>` (the lynx-ui `InputOTP`
|
|
58
|
+
* pattern). Append-only: typing fills the next cell, backspace empties the last, a tap anywhere focuses the end.
|
|
59
|
+
* Paste is filtered and clamped. Digits are stored as ASCII whatever keyboard produced them. Masked with
|
|
60
|
+
* `type: 'password'`. Requires the host's `xelement-input` registration.
|
|
61
|
+
*/
|
|
62
|
+
export declare const G9PinEntry: import("react").ForwardRefExoticComponent<G9PinEntryProps & import("react").RefAttributes<G9PinEntryHandle>>;
|
|
63
|
+
//# sourceMappingURL=pin-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin-entry.d.ts","sourceRoot":"","sources":["../../src/fields/pin-entry.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAa,cAAc,EAAoB,MAAM,+BAA+B,CAAC;AAiB5F,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,oHAAoH;IACpH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kHAAkH;IAClH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,6CAA6C;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kHAAkH;IAClH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,kGAAkG;IAClG,eAAe,IAAI,IAAI,CAAC;IACxB,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAAC;IACd,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAU3E;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE9E;AAoCD,oHAAoH;AACpH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAS1E;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CASrG;AAgBD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,8GA8KrB,CAAC"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import "./fields.css";
|
|
2
|
+
import { G9Metrics, G9PinEntryType, normalizeToAscii } from "@g9tm/lynxcontrols-foundation";
|
|
3
|
+
import { KeyboardAwareTriggerContext } from "@lynx-js/lynx-ui-input";
|
|
4
|
+
import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from "@lynx-js/react";
|
|
5
|
+
import { startTimer } from "../base/timers.jsx";
|
|
6
|
+
import { useControllableState } from "../base/use-controllable-state.jsx";
|
|
7
|
+
import { g9KeyboardTargetProps } from "../host/keyboard.jsx";
|
|
8
|
+
import { invokeNode, invokeNodeWhenReady } from "./use-text-input.jsx";
|
|
9
|
+
function parsePinGroupSizes(raw) {
|
|
10
|
+
if (null == raw || '' === raw.trim()) return [];
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const part of raw.split('-')){
|
|
13
|
+
const trimmed = part.trim();
|
|
14
|
+
if (!/^[+]?\d+$/.test(trimmed)) continue;
|
|
15
|
+
const n = Number(trimmed);
|
|
16
|
+
if (n > 0) out.push(n);
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function pinCellCount(length, groups) {
|
|
21
|
+
return groups.length > 0 ? groups.reduce((a, b)=>a + b, 0) : Math.max(1, length);
|
|
22
|
+
}
|
|
23
|
+
const digitZeros = [
|
|
24
|
+
0x30,
|
|
25
|
+
0x660,
|
|
26
|
+
0x6f0,
|
|
27
|
+
0x7c0,
|
|
28
|
+
0x966,
|
|
29
|
+
0x9e6,
|
|
30
|
+
0xa66,
|
|
31
|
+
0xae6,
|
|
32
|
+
0xb66,
|
|
33
|
+
0xbe6,
|
|
34
|
+
0xc66,
|
|
35
|
+
0xce6,
|
|
36
|
+
0xd66,
|
|
37
|
+
0xde6,
|
|
38
|
+
0xe50,
|
|
39
|
+
0xed0,
|
|
40
|
+
0xf20,
|
|
41
|
+
0x1040,
|
|
42
|
+
0x1090,
|
|
43
|
+
0x17e0,
|
|
44
|
+
0x1810,
|
|
45
|
+
0x1946,
|
|
46
|
+
0x19d0,
|
|
47
|
+
0x1a80,
|
|
48
|
+
0x1a90,
|
|
49
|
+
0x1b50,
|
|
50
|
+
0x1bb0,
|
|
51
|
+
0x1c40,
|
|
52
|
+
0x1c50,
|
|
53
|
+
0xa620,
|
|
54
|
+
0xa8d0,
|
|
55
|
+
0xa900,
|
|
56
|
+
0xa9d0,
|
|
57
|
+
0xa9f0,
|
|
58
|
+
0xaa50,
|
|
59
|
+
0xabf0,
|
|
60
|
+
0xff10
|
|
61
|
+
];
|
|
62
|
+
const uncasedLetterRanges = [
|
|
63
|
+
[
|
|
64
|
+
0x5d0,
|
|
65
|
+
0x5ea
|
|
66
|
+
],
|
|
67
|
+
[
|
|
68
|
+
0x620,
|
|
69
|
+
0x64a
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
0x66e,
|
|
73
|
+
0x6d3
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
0x6fa,
|
|
77
|
+
0x6ff
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
0x904,
|
|
81
|
+
0x939
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
0xe01,
|
|
85
|
+
0xe30
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
0x3041,
|
|
89
|
+
0x30ff
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
0x3400,
|
|
93
|
+
0x4dbf
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
0x4e00,
|
|
97
|
+
0x9fff
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
0xac00,
|
|
101
|
+
0xd7a3
|
|
102
|
+
]
|
|
103
|
+
];
|
|
104
|
+
function isUnicodeDigit(ch) {
|
|
105
|
+
const c = ch.charCodeAt(0);
|
|
106
|
+
for (const zero of digitZeros)if (c >= zero && c <= zero + 9) return true;
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
function isUnicodeLetter(ch) {
|
|
110
|
+
if (ch.toLowerCase() !== ch.toUpperCase()) return true;
|
|
111
|
+
const c = ch.charCodeAt(0);
|
|
112
|
+
for (const [from, to] of uncasedLetterRanges)if (c >= from && c <= to) return true;
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
function isPinCharAllowed(type, ch) {
|
|
116
|
+
switch(type){
|
|
117
|
+
case G9PinEntryType.Letters:
|
|
118
|
+
return isUnicodeLetter(ch);
|
|
119
|
+
case G9PinEntryType.Alphanumeric:
|
|
120
|
+
return isUnicodeLetter(ch) || isUnicodeDigit(ch);
|
|
121
|
+
default:
|
|
122
|
+
return isUnicodeDigit(ch);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function filterPin(raw, type, cells) {
|
|
126
|
+
if (!raw) return '';
|
|
127
|
+
let out = '';
|
|
128
|
+
for (const typed of Array.from(raw)){
|
|
129
|
+
if (Array.from(out).length >= cells) break;
|
|
130
|
+
const ch = normalizeToAscii(typed);
|
|
131
|
+
if (isPinCharAllowed(type, ch)) out += ch;
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
const hiddenInputStyle = {
|
|
136
|
+
position: 'absolute',
|
|
137
|
+
top: '0px',
|
|
138
|
+
left: '0px',
|
|
139
|
+
width: '1px',
|
|
140
|
+
height: '1px',
|
|
141
|
+
padding: '0px',
|
|
142
|
+
borderWidth: '0px',
|
|
143
|
+
opacity: 0,
|
|
144
|
+
color: 'transparent',
|
|
145
|
+
caretColor: 'transparent',
|
|
146
|
+
backgroundColor: 'transparent'
|
|
147
|
+
};
|
|
148
|
+
const pin_entry_G9PinEntry = forwardRef(function(props, ref) {
|
|
149
|
+
var _props_type, _props_length, _props_defaultValue, _props_separator;
|
|
150
|
+
const keyboardAware = useContext(KeyboardAwareTriggerContext);
|
|
151
|
+
const type = null != (_props_type = props.type) ? _props_type : G9PinEntryType.Number;
|
|
152
|
+
const groups = parsePinGroupSizes(props.groupSizes);
|
|
153
|
+
const cells = pinCellCount(null != (_props_length = props.length) ? _props_length : 4, groups);
|
|
154
|
+
const [value, setValue] = useControllableState({
|
|
155
|
+
value: props.value,
|
|
156
|
+
defaultValue: null != (_props_defaultValue = props.defaultValue) ? _props_defaultValue : '',
|
|
157
|
+
onChange: props.onValueChange,
|
|
158
|
+
name: 'G9PinEntry.value'
|
|
159
|
+
});
|
|
160
|
+
const clean = filterPin(value, type, cells);
|
|
161
|
+
const chars = Array.from(clean);
|
|
162
|
+
const complete = chars.length === cells;
|
|
163
|
+
const [focused, setFocused] = useState(false);
|
|
164
|
+
const inputRef = useRef(null);
|
|
165
|
+
const native = useRef('');
|
|
166
|
+
const completedFired = useRef(complete);
|
|
167
|
+
const latest = useRef(clean);
|
|
168
|
+
latest.current = clean;
|
|
169
|
+
const [, bump] = useState(0);
|
|
170
|
+
const refiltered = useRef(null);
|
|
171
|
+
useEffect(()=>{
|
|
172
|
+
if (clean !== value && refiltered.current !== value) {
|
|
173
|
+
refiltered.current = value;
|
|
174
|
+
setValue(clean);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
const lastSeen = useRef(clean);
|
|
178
|
+
if (lastSeen.current !== clean) {
|
|
179
|
+
lastSeen.current = clean;
|
|
180
|
+
if (!complete) completedFired.current = false;
|
|
181
|
+
}
|
|
182
|
+
const retries = useRef(0);
|
|
183
|
+
const sync = ()=>{
|
|
184
|
+
const current = latest.current;
|
|
185
|
+
if (native.current === current) return;
|
|
186
|
+
if (invokeNode(inputRef, 'setValue', {
|
|
187
|
+
value: current
|
|
188
|
+
})) {
|
|
189
|
+
native.current = current;
|
|
190
|
+
retries.current = 0;
|
|
191
|
+
} else if (inputRef.current && retries.current < 5) {
|
|
192
|
+
retries.current += 1;
|
|
193
|
+
startTimer(()=>syncRef.current(), 0);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const syncRef = useRef(sync);
|
|
197
|
+
syncRef.current = sync;
|
|
198
|
+
const attach = useRef((node)=>{
|
|
199
|
+
inputRef.current = node;
|
|
200
|
+
if (node) syncRef.current();
|
|
201
|
+
}).current;
|
|
202
|
+
useEffect(()=>{
|
|
203
|
+
sync();
|
|
204
|
+
});
|
|
205
|
+
const focus = ()=>{
|
|
206
|
+
if (props.disabled) return;
|
|
207
|
+
invokeNode(inputRef, 'focus');
|
|
208
|
+
invokeNode(inputRef, 'setSelectionRange', {
|
|
209
|
+
selectionStart: chars.length,
|
|
210
|
+
selectionEnd: chars.length
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
const clear = ()=>{
|
|
214
|
+
latest.current = '';
|
|
215
|
+
completedFired.current = false;
|
|
216
|
+
setValue('');
|
|
217
|
+
bump((n)=>n + 1);
|
|
218
|
+
};
|
|
219
|
+
useImperativeHandle(ref, ()=>({
|
|
220
|
+
focusFirstEmpty: focus,
|
|
221
|
+
clear,
|
|
222
|
+
get isComplete () {
|
|
223
|
+
return Array.from(latest.current).length === cells;
|
|
224
|
+
}
|
|
225
|
+
}));
|
|
226
|
+
const autoFocused = useRef(false);
|
|
227
|
+
useEffect(()=>{
|
|
228
|
+
if (props.autoFocus && !autoFocused.current && !props.disabled) {
|
|
229
|
+
autoFocused.current = true;
|
|
230
|
+
invokeNodeWhenReady(inputRef, 'focus');
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
const onInput = (event)=>{
|
|
234
|
+
var _ref;
|
|
235
|
+
var _event_detail;
|
|
236
|
+
const raw = null != (_ref = null == (_event_detail = event.detail) ? void 0 : _event_detail.value) ? _ref : '';
|
|
237
|
+
native.current = raw;
|
|
238
|
+
const next = filterPin(raw, type, cells);
|
|
239
|
+
latest.current = next;
|
|
240
|
+
lastSeen.current = next;
|
|
241
|
+
setValue(next);
|
|
242
|
+
const ready = Array.from(next).length === cells;
|
|
243
|
+
if (ready && !completedFired.current) {
|
|
244
|
+
var _props_onComplete;
|
|
245
|
+
completedFired.current = true;
|
|
246
|
+
null == (_props_onComplete = props.onComplete) || _props_onComplete.call(props, next);
|
|
247
|
+
} else if (!ready) completedFired.current = false;
|
|
248
|
+
bump((n)=>n + 1);
|
|
249
|
+
};
|
|
250
|
+
const cellWidth = props.cellWidth && props.cellWidth > 0 ? props.cellWidth : G9Metrics.PinCellWidth;
|
|
251
|
+
const cellHeight = props.cellHeight && props.cellHeight > 0 ? props.cellHeight : G9Metrics.PinCellHeight;
|
|
252
|
+
const active = focused ? Math.min(chars.length, cells - 1) : -1;
|
|
253
|
+
const separator = null != (_props_separator = props.separator) ? _props_separator : '';
|
|
254
|
+
const row = [];
|
|
255
|
+
let groupIndex = 0;
|
|
256
|
+
let inGroup = 0;
|
|
257
|
+
for(let i = 0; i < cells; i++){
|
|
258
|
+
var _props_maskCharacter, _props_placeholder;
|
|
259
|
+
const ch = chars[i];
|
|
260
|
+
const state = i === active ? 'active' : void 0 !== ch ? 'filled' : 'empty';
|
|
261
|
+
row.push(<view key={`c${i}`} className={`g9-pin__cell g9-pin__cell--${state}`} style={{
|
|
262
|
+
width: `${cellWidth}px`,
|
|
263
|
+
height: `${cellHeight}px`
|
|
264
|
+
}}>
|
|
265
|
+
<text className={void 0 !== ch ? 'g9-pin__char' : 'g9-pin__placeholder'}>
|
|
266
|
+
{void 0 !== ch ? type === G9PinEntryType.Password ? null != (_props_maskCharacter = props.maskCharacter) ? _props_maskCharacter : '●' : ch : null != (_props_placeholder = props.placeholder) ? _props_placeholder : ''}
|
|
267
|
+
</text>
|
|
268
|
+
</view>);
|
|
269
|
+
inGroup++;
|
|
270
|
+
if (groups.length > 0 && groupIndex < groups.length - 1 && inGroup === groups[groupIndex]) {
|
|
271
|
+
if ('' !== separator) row.push(<text key={`s${groupIndex}`} className="g9-pin__separator">
|
|
272
|
+
{separator}
|
|
273
|
+
</text>);
|
|
274
|
+
groupIndex++;
|
|
275
|
+
inGroup = 0;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return <view {...g9KeyboardTargetProps} className={`g9-pin g9-dir-ltr${props.disabled ? ' g9-pin--disabled' : ''}${complete ? ' g9-pin--complete' : ''}${props.className ? ` ${props.className}` : ''}`} accessibility-element={true} accessibility-label={`${props.accessibilityLabel ? `${props.accessibilityLabel}, ` : ''}${chars.length} / ${cells}`} bindtap={focus}>
|
|
279
|
+
{row}
|
|
280
|
+
<input {...g9KeyboardTargetProps} ref={attach} className="g9-pin__input" android-fullscreen-mode={false} ignore-focus={true} confirm-type="done" disabled={true === props.disabled} maxlength={cells} ios-auto-correct={false} ios-spell-check={false} type={type === G9PinEntryType.Number || type === G9PinEntryType.Password ? 'number' : 'text'} style={hiddenInputStyle} bindinput={onInput} bindfocus={()=>{
|
|
281
|
+
var _keyboardAware_onInputFocused;
|
|
282
|
+
setFocused(true);
|
|
283
|
+
null == (_keyboardAware_onInputFocused = keyboardAware.onInputFocused) || _keyboardAware_onInputFocused.call(keyboardAware);
|
|
284
|
+
}} bindblur={()=>{
|
|
285
|
+
var _keyboardAware_onInputBlurred;
|
|
286
|
+
setFocused(false);
|
|
287
|
+
null == (_keyboardAware_onInputBlurred = keyboardAware.onInputBlurred) || _keyboardAware_onInputBlurred.call(keyboardAware);
|
|
288
|
+
}}/>
|
|
289
|
+
</view>;
|
|
290
|
+
});
|
|
291
|
+
export { filterPin, isPinCharAllowed, parsePinGroupSizes, pinCellCount, pin_entry_G9PinEntry as G9PinEntry };
|
|
292
|
+
|
|
293
|
+
//# sourceMappingURL=pin-entry.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields/pin-entry.jsx","sources":["../../src/fields/pin-entry.tsx"],"sourcesContent":["import './fields.css';\nimport { G9Metrics, G9PinEntryType, normalizeToAscii } from '@g9tm/lynxcontrols-foundation';\nimport { KeyboardAwareTriggerContext } from '@lynx-js/lynx-ui-input';\nimport {\n forwardRef,\n type ReactNode,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from '@lynx-js/react';\nimport type { NodesRef } from '@lynx-js/types';\nimport { startTimer } from '../base/timers';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport { invokeNode, invokeNodeWhenReady } from './use-text-input';\n\n/** Props of {@link G9PinEntry} (MAUI `G9PinEntry`). */\nexport interface G9PinEntryProps {\n /** Number of cells when `groupSizes` is not set (at least 1). Default 4. */\n readonly length?: number;\n /** The code (controlled; MAUI `Value`). */\n readonly value?: string;\n /** Initial code while uncontrolled. Default `''`. */\n readonly defaultValue?: string;\n /** Once per change of the code (MAUI `ValueChanged`): typing, paste, `clear()`, a re-filter after a type change. */\n readonly onValueChange?: (value: string) => void;\n /** Once each time the code becomes complete (MAUI `Completed`); not for a complete value the parent pushes in. */\n readonly onComplete?: (value: string) => void;\n /** Accepted characters; `'password'` is digits shown masked. Default `'number'`. */\n readonly type?: G9PinEntryType;\n /** Filler glyph of an empty cell. Default none. */\n readonly placeholder?: string | null;\n /** Glyph of a masked cell. Default `'●'`. */\n readonly maskCharacter?: string;\n /** Cell groups such as `'4-4-4-4'`; when set, their sum is the cell count and `separator` sits between groups. */\n readonly groupSizes?: string | null;\n /** Text between groups. Default `'-'`. */\n readonly separator?: string | null;\n /** Cell width. Default 44 (`G9Metrics.PinCellWidth`). */\n readonly cellWidth?: number;\n /** Cell height. Default 52 (`G9Metrics.PinCellHeight`). */\n readonly cellHeight?: number;\n /** Focus once when mounted. Default false. */\n readonly autoFocus?: boolean;\n readonly disabled?: boolean;\n /** Accessibility label of the row (the progress `n / total` is always announced). */\n readonly accessibilityLabel?: string;\n readonly className?: string;\n}\n\n/** Imperative handle of {@link G9PinEntry}. */\nexport interface G9PinEntryHandle {\n /** Focuses the hidden input; typing appends after the last character (MAUI `FocusFirstEmpty`). */\n focusFirstEmpty(): void;\n /** Empties every cell (MAUI `Clear`). */\n clear(): void;\n /** Every cell is filled (MAUI `IsComplete`). */\n readonly isComplete: boolean;\n}\n\n/** Parses `'4-3-3-2'` into positive group sizes; blanks and non-numbers are skipped (MAUI `ParseGroupSizes`). */\nexport function parsePinGroupSizes(raw: string | null | undefined): number[] {\n if (raw == null || raw.trim() === '') return [];\n const out: number[] = [];\n for (const part of raw.split('-')) {\n const trimmed = part.trim();\n if (!/^[+]?\\d+$/.test(trimmed)) continue;\n const n = Number(trimmed);\n if (n > 0) out.push(n);\n }\n return out;\n}\n\n/** Cell count: the groups' sum, else `max(1, length)`. */\nexport function pinCellCount(length: number, groups: readonly number[]): number {\n return groups.length > 0 ? groups.reduce((a, b) => a + b, 0) : Math.max(1, length);\n}\n\n// Lynx's JavaScript engine rejects Unicode property escapes (`/\\p{Nd}/u`), so `char.IsDigit` / `char.IsLetter` are\n// spelled out: the zero code points of every BMP decimal-digit block (Unicode category Nd), and \"letter\" as a cased\n// character or one of the uncased letter blocks forms meet (Arabic/Persian, Hebrew, Indic, Thai, CJK, kana, Hangul).\nconst digitZeros = [\n 0x30, 0x660, 0x6f0, 0x7c0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe6, 0xc66, 0xce6, 0xd66, 0xde6, 0xe50, 0xed0, 0xf20,\n 0x1040, 0x1090, 0x17e0, 0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, 0x1c40, 0x1c50, 0xa620, 0xa8d0,\n 0xa900, 0xa9d0, 0xa9f0, 0xaa50, 0xabf0, 0xff10,\n];\nconst uncasedLetterRanges: ReadonlyArray<readonly [number, number]> = [\n [0x5d0, 0x5ea],\n [0x620, 0x64a],\n [0x66e, 0x6d3],\n [0x6fa, 0x6ff],\n [0x904, 0x939],\n [0xe01, 0xe30],\n [0x3041, 0x30ff],\n [0x3400, 0x4dbf],\n [0x4e00, 0x9fff],\n [0xac00, 0xd7a3],\n];\n\nfunction isUnicodeDigit(ch: string): boolean {\n const c = ch.charCodeAt(0);\n for (const zero of digitZeros) if (c >= zero && c <= zero + 9) return true;\n return false;\n}\n\nfunction isUnicodeLetter(ch: string): boolean {\n if (ch.toLowerCase() !== ch.toUpperCase()) return true;\n const c = ch.charCodeAt(0);\n for (const [from, to] of uncasedLetterRanges) if (c >= from && c <= to) return true;\n return false;\n}\n\n/** Whether the PIN type accepts a character (MAUI `IsAllowed`: `char.IsDigit` / `IsLetter` / `IsLetterOrDigit`). */\nexport function isPinCharAllowed(type: G9PinEntryType, ch: string): boolean {\n switch (type) {\n case G9PinEntryType.Letters:\n return isUnicodeLetter(ch);\n case G9PinEntryType.Alphanumeric:\n return isUnicodeLetter(ch) || isUnicodeDigit(ch);\n default:\n return isUnicodeDigit(ch);\n }\n}\n\n/**\n * Filters and clamps a code (MAUI `FilterAndClamp`): Persian and Arabic-Indic digits become ASCII, disallowed\n * characters are dropped, the rest is cut to `cells`.\n */\nexport function filterPin(raw: string | null | undefined, type: G9PinEntryType, cells: number): string {\n if (!raw) return '';\n let out = '';\n for (const typed of Array.from(raw)) {\n if (Array.from(out).length >= cells) break;\n const ch = normalizeToAscii(typed);\n if (isPinCharAllowed(type, ch)) out += ch;\n }\n return out;\n}\n\nconst hiddenInputStyle = {\n position: 'absolute',\n top: '0px',\n left: '0px',\n width: '1px',\n height: '1px',\n padding: '0px',\n borderWidth: '0px',\n opacity: 0,\n color: 'transparent',\n caretColor: 'transparent',\n backgroundColor: 'transparent',\n} as const;\n\n/**\n * One-time-code / PIN entry (MAUI `G9PinEntry`): a row of cells over one hidden `<input>` (the lynx-ui `InputOTP`\n * pattern). Append-only: typing fills the next cell, backspace empties the last, a tap anywhere focuses the end.\n * Paste is filtered and clamped. Digits are stored as ASCII whatever keyboard produced them. Masked with\n * `type: 'password'`. Requires the host's `xelement-input` registration.\n */\nexport const G9PinEntry = forwardRef<G9PinEntryHandle, G9PinEntryProps>(function G9PinEntry(props, ref): ReactNode {\n const keyboardAware = useContext(KeyboardAwareTriggerContext);\n const type = props.type ?? G9PinEntryType.Number;\n const groups = parsePinGroupSizes(props.groupSizes);\n const cells = pinCellCount(props.length ?? 4, groups);\n const [value, setValue] = useControllableState<string>({\n value: props.value,\n defaultValue: props.defaultValue ?? '',\n onChange: props.onValueChange,\n name: 'G9PinEntry.value',\n });\n const clean = filterPin(value, type, cells);\n const chars = Array.from(clean);\n const complete = chars.length === cells;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<NodesRef | null>(null);\n const native = useRef('');\n const completedFired = useRef(complete);\n const latest = useRef(clean);\n latest.current = clean;\n const [, bump] = useState(0);\n\n // A pushed value the filter rejects is replaced once; a pushed complete value never fires `onComplete`.\n const refiltered = useRef<string | null>(null);\n useEffect(() => {\n if (clean !== value && refiltered.current !== value) {\n refiltered.current = value;\n setValue(clean);\n }\n });\n const lastSeen = useRef(clean);\n if (lastSeen.current !== clean) {\n lastSeen.current = clean;\n if (!complete) completedFired.current = false;\n }\n const retries = useRef(0);\n const sync = () => {\n const current = latest.current;\n if (native.current === current) return;\n if (invokeNode(inputRef, 'setValue', { value: current })) {\n native.current = current;\n retries.current = 0;\n } else if (inputRef.current && retries.current < 5) {\n retries.current += 1;\n startTimer(() => syncRef.current(), 0);\n }\n };\n const syncRef = useRef(sync);\n syncRef.current = sync;\n const attach = useRef((node: NodesRef | null) => {\n inputRef.current = node;\n if (node) syncRef.current();\n }).current;\n useEffect(() => {\n sync();\n });\n\n const focus = () => {\n if (props.disabled) return;\n invokeNode(inputRef, 'focus');\n invokeNode(inputRef, 'setSelectionRange', { selectionStart: chars.length, selectionEnd: chars.length });\n };\n const clear = () => {\n latest.current = '';\n completedFired.current = false;\n setValue('');\n bump((n) => n + 1);\n };\n useImperativeHandle(ref, () => ({\n focusFirstEmpty: focus,\n clear,\n get isComplete() {\n return Array.from(latest.current).length === cells;\n },\n }));\n\n const autoFocused = useRef(false);\n useEffect(() => {\n if (props.autoFocus && !autoFocused.current && !props.disabled) {\n autoFocused.current = true;\n invokeNodeWhenReady(inputRef, 'focus');\n }\n });\n\n const onInput = (event: { detail?: { value?: string } }) => {\n const raw = event.detail?.value ?? '';\n native.current = raw;\n const next = filterPin(raw, type, cells);\n latest.current = next;\n lastSeen.current = next;\n setValue(next);\n const ready = Array.from(next).length === cells;\n if (ready && !completedFired.current) {\n completedFired.current = true;\n props.onComplete?.(next);\n } else if (!ready) {\n completedFired.current = false;\n }\n bump((n) => n + 1);\n };\n\n const cellWidth = props.cellWidth && props.cellWidth > 0 ? props.cellWidth : G9Metrics.PinCellWidth;\n const cellHeight = props.cellHeight && props.cellHeight > 0 ? props.cellHeight : G9Metrics.PinCellHeight;\n const active = focused ? Math.min(chars.length, cells - 1) : -1;\n const separator = props.separator ?? '';\n const row: ReactNode[] = [];\n let groupIndex = 0;\n let inGroup = 0;\n for (let i = 0; i < cells; i++) {\n const ch = chars[i];\n const state = i === active ? 'active' : ch !== undefined ? 'filled' : 'empty';\n row.push(\n <view\n key={`c${i}`}\n className={`g9-pin__cell g9-pin__cell--${state}`}\n style={{ width: `${cellWidth}px`, height: `${cellHeight}px` }}\n >\n <text className={ch !== undefined ? 'g9-pin__char' : 'g9-pin__placeholder'}>\n {ch !== undefined\n ? type === G9PinEntryType.Password\n ? (props.maskCharacter ?? '●')\n : ch\n : (props.placeholder ?? '')}\n </text>\n </view>,\n );\n inGroup++;\n if (groups.length > 0 && groupIndex < groups.length - 1 && inGroup === groups[groupIndex]) {\n if (separator !== '') {\n row.push(\n <text key={`s${groupIndex}`} className=\"g9-pin__separator\">\n {separator}\n </text>,\n );\n }\n groupIndex++;\n inGroup = 0;\n }\n }\n\n return (\n <view\n {...g9KeyboardTargetProps}\n className={`g9-pin g9-dir-ltr${props.disabled ? ' g9-pin--disabled' : ''}${complete ? ' g9-pin--complete' : ''}${props.className ? ` ${props.className}` : ''}`}\n accessibility-element={true}\n accessibility-label={`${props.accessibilityLabel ? `${props.accessibilityLabel}, ` : ''}${chars.length} / ${cells}`}\n bindtap={focus}\n >\n {row}\n <input\n {...g9KeyboardTargetProps}\n ref={attach}\n className=\"g9-pin__input\"\n android-fullscreen-mode={false}\n ignore-focus={true}\n confirm-type=\"done\"\n disabled={props.disabled === true}\n maxlength={cells}\n ios-auto-correct={false}\n ios-spell-check={false}\n type={type === G9PinEntryType.Number || type === G9PinEntryType.Password ? 'number' : 'text'}\n style={hiddenInputStyle}\n bindinput={onInput}\n bindfocus={() => {\n setFocused(true);\n keyboardAware.onInputFocused?.();\n }}\n bindblur={() => {\n setFocused(false);\n keyboardAware.onInputBlurred?.();\n }}\n />\n </view>\n );\n});\n"],"names":["parsePinGroupSizes","raw","out","part","trimmed","n","Number","pinCellCount","length","groups","a","b","Math","digitZeros","uncasedLetterRanges","isUnicodeDigit","ch","c","zero","isUnicodeLetter","from","to","isPinCharAllowed","type","G9PinEntryType","filterPin","cells","typed","Array","normalizeToAscii","hiddenInputStyle","G9PinEntry","forwardRef","props","ref","_props_type","_props_length","_props_defaultValue","_props_separator","keyboardAware","useContext","KeyboardAwareTriggerContext","value","setValue","useControllableState","clean","chars","complete","focused","setFocused","useState","inputRef","useRef","native","completedFired","latest","bump","refiltered","useEffect","lastSeen","retries","sync","current","invokeNode","startTimer","syncRef","attach","node","focus","clear","useImperativeHandle","autoFocused","invokeNodeWhenReady","onInput","event","_event_detail","next","ready","cellWidth","G9Metrics","cellHeight","active","separator","row","groupIndex","inGroup","i","_props_maskCharacter","_props_placeholder","state","undefined","view","text","g9KeyboardTargetProps","input"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type G9AbortSignal } from '@g9tm/lynxcontrols-foundation';
|
|
2
|
+
import { type G9TextEntryHandle, type G9TextEntryProps } from './text-entry.js';
|
|
3
|
+
/** Context of one search (`onSearch`). */
|
|
4
|
+
export interface G9SearchContext {
|
|
5
|
+
/** Aborted when a newer query fires or the field unmounts: drop this query's results. */
|
|
6
|
+
readonly signal: G9AbortSignal;
|
|
7
|
+
/** Increases with every fired query; compare to discard a stale result. */
|
|
8
|
+
readonly version: number;
|
|
9
|
+
}
|
|
10
|
+
/** Props of {@link G9SearchEntry} (MAUI `G9SearchEntry`). */
|
|
11
|
+
export interface G9SearchEntryProps extends G9TextEntryProps {
|
|
12
|
+
/** Quiet time after the last change before the query fires; `0` fires on every change. Default 250. */
|
|
13
|
+
readonly debounceMs?: number;
|
|
14
|
+
/** The debounced text (MAUI `DebouncedTextChanged`). */
|
|
15
|
+
readonly onDebouncedValueChange?: (value: string) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Runs the search (MAUI `SearchCommand`): after the debounce, on the keyboard's search key and on `submit()`.
|
|
18
|
+
* A newer query aborts the previous one's signal (query versioning). A thrown error or rejected promise (other
|
|
19
|
+
* than an abort) goes to the provider's diagnostics.
|
|
20
|
+
*/
|
|
21
|
+
readonly onSearch?: (query: string, context: G9SearchContext) => unknown;
|
|
22
|
+
}
|
|
23
|
+
/** Imperative handle of {@link G9SearchEntry}. */
|
|
24
|
+
export interface G9SearchEntryHandle extends G9TextEntryHandle {
|
|
25
|
+
/** Fires the current text now, skipping the debounce (MAUI `Submit`). */
|
|
26
|
+
submit(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Search field (MAUI `G9SearchEntry`): a `G9TextEntry` with a leading search glyph, the clear button, dictation on,
|
|
30
|
+
* the localized `search` placeholder, the floating-label clearance reserved, the keyboard's search key, and a
|
|
31
|
+
* debounced query. Every change of the text (typing, dictation, clear, a new `value` from the parent) restarts the
|
|
32
|
+
* debounce; the search key and `submit()` fire at once. Pending queries never fire after unmount.
|
|
33
|
+
*/
|
|
34
|
+
export declare const G9SearchEntry: import("react").ForwardRefExoticComponent<G9SearchEntryProps & import("react").RefAttributes<G9SearchEntryHandle>>;
|
|
35
|
+
//# sourceMappingURL=search-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-entry.d.ts","sourceRoot":"","sources":["../../src/fields/search-entry.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAGnB,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAGjH,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,uGAAuG;IACvG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC;CAC1E;AAED,kDAAkD;AAClD,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,yEAAyE;IACzE,MAAM,IAAI,IAAI,CAAC;CAChB;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,oHAmHzB,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { G9StringKey, createAbortController, isAbortError } from "@g9tm/lynxcontrols-foundation";
|
|
2
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from "@lynx-js/react";
|
|
3
|
+
import { startTimer, stopTimer } from "../base/timers.jsx";
|
|
4
|
+
import { useControllableState } from "../base/use-controllable-state.jsx";
|
|
5
|
+
import { useG9Diagnostics, useG9Settings, useG9Strings } from "../provider/hooks.jsx";
|
|
6
|
+
import { TextEntryBody } from "./text-entry.jsx";
|
|
7
|
+
const search_entry_G9SearchEntry = forwardRef(function(props, ref) {
|
|
8
|
+
var _props_defaultValue, _props_clearButton, _props_voiceEnabled, _props_reserveFloatingLabelClearance;
|
|
9
|
+
const glyphs = useG9Settings().glyphs;
|
|
10
|
+
const strings = useG9Strings();
|
|
11
|
+
const diagnostics = useG9Diagnostics();
|
|
12
|
+
const [text, setText] = useControllableState({
|
|
13
|
+
value: props.value,
|
|
14
|
+
defaultValue: null != (_props_defaultValue = props.defaultValue) ? _props_defaultValue : '',
|
|
15
|
+
onChange: props.onValueChange,
|
|
16
|
+
name: 'G9SearchEntry.value'
|
|
17
|
+
});
|
|
18
|
+
const latest = useRef({
|
|
19
|
+
text,
|
|
20
|
+
props
|
|
21
|
+
});
|
|
22
|
+
latest.current = {
|
|
23
|
+
text,
|
|
24
|
+
props
|
|
25
|
+
};
|
|
26
|
+
const timer = useRef(null);
|
|
27
|
+
const current = useRef(null);
|
|
28
|
+
const version = useRef(0);
|
|
29
|
+
const inner = useRef(null);
|
|
30
|
+
const stopDebounce = ()=>{
|
|
31
|
+
if (null !== timer.current) {
|
|
32
|
+
stopTimer(timer.current);
|
|
33
|
+
timer.current = null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const report = (error)=>{
|
|
37
|
+
if (isAbortError(error)) return;
|
|
38
|
+
diagnostics.log({
|
|
39
|
+
level: 'error',
|
|
40
|
+
message: 'G9SearchEntry.onSearch failed.',
|
|
41
|
+
source: 'G9SearchEntry',
|
|
42
|
+
error
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
const fire = (value)=>{
|
|
46
|
+
var _current_current;
|
|
47
|
+
const p = latest.current.props;
|
|
48
|
+
null == (_current_current = current.current) || _current_current.abort();
|
|
49
|
+
const controller = createAbortController();
|
|
50
|
+
current.current = controller;
|
|
51
|
+
version.current += 1;
|
|
52
|
+
try {
|
|
53
|
+
var _p_onDebouncedValueChange, _p_onSearch;
|
|
54
|
+
null == (_p_onDebouncedValueChange = p.onDebouncedValueChange) || _p_onDebouncedValueChange.call(p, value);
|
|
55
|
+
const result = null == (_p_onSearch = p.onSearch) ? void 0 : _p_onSearch.call(p, value, {
|
|
56
|
+
signal: controller.signal,
|
|
57
|
+
version: version.current
|
|
58
|
+
});
|
|
59
|
+
if (result && 'function' == typeof result.then) result.then(void 0, report);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
report(error);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const submit = ()=>{
|
|
65
|
+
stopDebounce();
|
|
66
|
+
fire(latest.current.text);
|
|
67
|
+
};
|
|
68
|
+
const first = useRef(true);
|
|
69
|
+
useEffect(()=>{
|
|
70
|
+
var _latest_current_props_debounceMs;
|
|
71
|
+
if (first.current) {
|
|
72
|
+
first.current = false;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const ms = null != (_latest_current_props_debounceMs = latest.current.props.debounceMs) ? _latest_current_props_debounceMs : 250;
|
|
76
|
+
stopDebounce();
|
|
77
|
+
if (ms <= 0) return void fire(text);
|
|
78
|
+
timer.current = startTimer(()=>{
|
|
79
|
+
timer.current = null;
|
|
80
|
+
fire(latest.current.text);
|
|
81
|
+
}, ms);
|
|
82
|
+
}, [
|
|
83
|
+
text
|
|
84
|
+
]);
|
|
85
|
+
useEffect(()=>()=>{
|
|
86
|
+
var _current_current;
|
|
87
|
+
stopDebounce();
|
|
88
|
+
null == (_current_current = current.current) || _current_current.abort();
|
|
89
|
+
}, []);
|
|
90
|
+
useImperativeHandle(ref, ()=>{
|
|
91
|
+
const base = inner.current;
|
|
92
|
+
return {
|
|
93
|
+
focus: ()=>base.focus(),
|
|
94
|
+
blur: ()=>base.blur(),
|
|
95
|
+
validate: ()=>base.validate(),
|
|
96
|
+
get isListening () {
|
|
97
|
+
return base.isListening;
|
|
98
|
+
},
|
|
99
|
+
toggleVoice: ()=>base.toggleVoice(),
|
|
100
|
+
startVoice: ()=>base.startVoice(),
|
|
101
|
+
stopVoice: ()=>base.stopVoice(),
|
|
102
|
+
get element () {
|
|
103
|
+
return base.element;
|
|
104
|
+
},
|
|
105
|
+
submit
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
const variant = {
|
|
109
|
+
name: 'G9SearchEntry.value',
|
|
110
|
+
restingTone: 'placeholder',
|
|
111
|
+
confirmType: 'search',
|
|
112
|
+
onConfirm: submit
|
|
113
|
+
};
|
|
114
|
+
return <TextEntryBody {...props} leadingIcon={void 0 === props.leadingIcon ? glyphs.search : props.leadingIcon} clearButton={null != (_props_clearButton = props.clearButton) ? _props_clearButton : true} voiceEnabled={null != (_props_voiceEnabled = props.voiceEnabled) ? _props_voiceEnabled : true} placeholder={void 0 === props.placeholder ? strings.get(G9StringKey.Search) : props.placeholder} reserveFloatingLabelClearance={null != (_props_reserveFloatingLabelClearance = props.reserveFloatingLabelClearance) ? _props_reserveFloatingLabelClearance : true} value={text} onValueChange={(value, details)=>setText(value, details)} variant={variant} ref={inner}/>;
|
|
115
|
+
});
|
|
116
|
+
export { search_entry_G9SearchEntry as G9SearchEntry };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=search-entry.jsx.map
|