@eifi1/ui-kit 0.4.0 → 0.5.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/LICENSE +32 -0
- package/README.md +498 -57
- package/dist/chart.d.ts +10 -0
- package/dist/chart.js +10 -0
- package/dist/chart.js.map +1 -0
- package/dist/components/account-settings.d.ts +11 -0
- package/dist/components/account-settings.js +19 -12
- package/dist/components/account-settings.js.map +1 -1
- package/dist/components/alert-banner.d.ts +10 -6
- package/dist/components/alert-banner.js +20 -16
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +30 -4
- package/dist/components/amount-input.js +36 -14
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/calculator.d.ts +24 -7
- package/dist/components/calculator.js +37 -20
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/chart-zoom.d.ts +156 -0
- package/dist/components/chart-zoom.js +262 -0
- package/dist/components/chart-zoom.js.map +1 -0
- package/dist/components/chart.d.ts +28 -3
- package/dist/components/chart.js +71 -32
- package/dist/components/chart.js.map +1 -1
- package/dist/components/checkbox.d.ts +51 -0
- package/dist/components/checkbox.js +123 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/chip.d.ts +128 -0
- package/dist/components/chip.js +357 -0
- package/dist/components/chip.js.map +1 -0
- package/dist/components/choice-parts.d.ts +24 -0
- package/dist/components/choice-parts.js +18 -0
- package/dist/components/choice-parts.js.map +1 -0
- package/dist/components/combobox-core.d.ts +52 -9
- package/dist/components/combobox-core.js +91 -20
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.d.ts +43 -33
- package/dist/components/combobox.js +409 -340
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/currency-select.d.ts +48 -8
- package/dist/components/currency-select.js +107 -65
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/data-table-filter-popover.d.ts +15 -3
- package/dist/components/data-table-filter-popover.js +23 -17
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +1 -1
- package/dist/components/data-table-filters.js +3 -2
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/data-table-labels.d.ts +53 -2
- package/dist/components/data-table-labels.js +31 -2
- package/dist/components/data-table-labels.js.map +1 -1
- package/dist/components/data-table-pagination.d.ts +3 -1
- package/dist/components/data-table-pagination.js +16 -10
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-sort.js +1 -0
- package/dist/components/data-table-sort.js.map +1 -1
- package/dist/components/data-table.d.ts +1 -1
- package/dist/components/data-table.js +201 -85
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +25 -9
- package/dist/components/date-picker.js +232 -94
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/dropdown.d.ts +96 -20
- package/dist/components/dropdown.js +77 -33
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/entity-combobox.d.ts +5 -4
- package/dist/components/entity-combobox.js +107 -76
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/facing-pair.d.ts +36 -0
- package/dist/components/facing-pair.js +40 -0
- package/dist/components/facing-pair.js.map +1 -0
- package/dist/components/field-sync.d.ts +164 -0
- package/dist/components/field-sync.js +264 -0
- package/dist/components/field-sync.js.map +1 -0
- package/dist/components/file-dropzone.d.ts +38 -6
- package/dist/components/file-dropzone.js +34 -9
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/full-bleed-dialog.d.ts +37 -26
- package/dist/components/full-bleed-dialog.js +20 -5
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/grouped-picker.d.ts +21 -10
- package/dist/components/grouped-picker.js +66 -52
- package/dist/components/grouped-picker.js.map +1 -1
- package/dist/components/hover-menu.d.ts +20 -4
- package/dist/components/hover-menu.js +15 -4
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/mini-calendar.d.ts +102 -14
- package/dist/components/mini-calendar.js +256 -70
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +9 -3
- package/dist/components/modal.js +34 -45
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-picker.d.ts +79 -0
- package/dist/components/month-picker.js +342 -0
- package/dist/components/month-picker.js.map +1 -0
- package/dist/components/multi-entity-combobox.d.ts +7 -6
- package/dist/components/multi-entity-combobox.js +112 -72
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.d.ts +13 -11
- package/dist/components/multi-select.js +161 -84
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-field.d.ts +92 -0
- package/dist/components/number-field.js +111 -0
- package/dist/components/number-field.js.map +1 -0
- package/dist/components/number-input.d.ts +28 -2
- package/dist/components/number-input.js +12 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.d.ts +32 -4
- package/dist/components/numpad-sheet.js +30 -13
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/page-contents.d.ts +90 -0
- package/dist/components/page-contents.js +170 -0
- package/dist/components/page-contents.js.map +1 -0
- package/dist/components/password-strength.d.ts +106 -0
- package/dist/components/password-strength.js +132 -0
- package/dist/components/password-strength.js.map +1 -0
- package/dist/components/picker-sheet.d.ts +23 -15
- package/dist/components/picker-sheet.js +34 -14
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/popover.d.ts +62 -4
- package/dist/components/popover.js +52 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/search-field.d.ts +25 -7
- package/dist/components/search-field.js +7 -5
- package/dist/components/search-field.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +14 -0
- package/dist/components/series-chart-labels.js +11 -0
- package/dist/components/series-chart-labels.js.map +1 -0
- package/dist/components/series-chart.d.ts +207 -0
- package/dist/components/series-chart.js +223 -0
- package/dist/components/series-chart.js.map +1 -0
- package/dist/components/settings-fields.d.ts +14 -4
- package/dist/components/settings-fields.js +19 -8
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/signature-pad.d.ts +119 -0
- package/dist/components/signature-pad.js +405 -0
- package/dist/components/signature-pad.js.map +1 -0
- package/dist/components/slider.d.ts +80 -0
- package/dist/components/slider.js +155 -0
- package/dist/components/slider.js.map +1 -0
- package/dist/components/sparkline.d.ts +93 -0
- package/dist/components/sparkline.js +205 -0
- package/dist/components/sparkline.js.map +1 -0
- package/dist/components/stat-tile.d.ts +151 -0
- package/dist/components/stat-tile.js +236 -0
- package/dist/components/stat-tile.js.map +1 -0
- package/dist/components/swipeable-row.d.ts +25 -2
- package/dist/components/swipeable-row.js +31 -0
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/switch.d.ts +60 -0
- package/dist/components/switch.js +81 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/time-input.d.ts +58 -0
- package/dist/components/time-input.js +50 -0
- package/dist/components/time-input.js.map +1 -0
- package/dist/components/toggle-group.d.ts +18 -3
- package/dist/components/toggle-group.js +10 -6
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +115 -0
- package/dist/components/toggle-legend.js +114 -0
- package/dist/components/toggle-legend.js.map +1 -0
- package/dist/components/tooltip.d.ts +40 -11
- package/dist/components/tooltip.js +77 -20
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/treemap.d.ts +132 -0
- package/dist/components/treemap.js +179 -0
- package/dist/components/treemap.js.map +1 -0
- package/dist/components/ui.d.ts +159 -46
- package/dist/components/ui.js +220 -115
- package/dist/components/ui.js.map +1 -1
- package/dist/components/use-mobile-reveal.js +1 -0
- package/dist/components/use-mobile-reveal.js.map +1 -1
- package/dist/components/use-table-state.d.ts +1 -1
- package/dist/components/use-table-state.js +38 -17
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/components/user-avatar.d.ts +15 -4
- package/dist/components/user-avatar.js +5 -4
- package/dist/components/user-avatar.js.map +1 -1
- package/dist/components/wizard-stepper.js +3 -2
- package/dist/components/wizard-stepper.js.map +1 -1
- package/dist/{data-table-filters-aXyf0Xub.d.ts → data-table-filters-DM1auUfH.d.ts} +27 -5
- package/dist/data-table.d.ts +7 -0
- package/dist/data-table.js +12 -0
- package/dist/data-table.js.map +1 -0
- package/dist/feedback/feedback-attachment.js +12 -11
- package/dist/feedback/feedback-attachment.js.map +1 -1
- package/dist/feedback/feedback-dialog.js +2 -1
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-inbox.d.ts +33 -7
- package/dist/feedback/feedback-inbox.js +49 -37
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/feedback.d.ts +5 -0
- package/dist/feedback.js +5 -0
- package/dist/feedback.js.map +1 -0
- package/dist/hooks/use-anchored-panel.js +1 -0
- package/dist/hooks/use-anchored-panel.js.map +1 -1
- package/dist/hooks/use-anchored-rect.js +1 -0
- package/dist/hooks/use-anchored-rect.js.map +1 -1
- package/dist/hooks/use-announce.d.ts +46 -0
- package/dist/hooks/use-announce.js +37 -0
- package/dist/hooks/use-announce.js.map +1 -0
- package/dist/hooks/use-body-scroll-lock.js +1 -0
- package/dist/hooks/use-body-scroll-lock.js.map +1 -1
- package/dist/hooks/use-close-transition.js +1 -0
- package/dist/hooks/use-close-transition.js.map +1 -1
- package/dist/hooks/use-dismiss.js +1 -0
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +16 -0
- package/dist/hooks/use-focus-trap.js +67 -0
- package/dist/hooks/use-focus-trap.js.map +1 -0
- package/dist/hooks/use-media-query.js +1 -0
- package/dist/hooks/use-media-query.js.map +1 -1
- package/dist/hooks/use-overlay-history.js +27 -1
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/hooks/use-row-swipe.js +1 -0
- package/dist/hooks/use-row-swipe.js.map +1 -1
- package/dist/i18n/defaults.d.ts +31 -0
- package/dist/i18n/defaults.js +63 -0
- package/dist/i18n/defaults.js.map +1 -0
- package/dist/i18n/kit-labels.d.ts +250 -0
- package/dist/i18n/kit-labels.js +184 -0
- package/dist/i18n/kit-labels.js.map +1 -0
- package/dist/index.d.ts +47 -22
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/calc.js +1 -0
- package/dist/lib/calc.js.map +1 -1
- package/dist/lib/cn.js +1 -0
- package/dist/lib/cn.js.map +1 -1
- package/dist/lib/dates.js +1 -0
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/logger.js +1 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/safe-storage.js +1 -0
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/search/command-palette.d.ts +11 -1
- package/dist/search/command-palette.js +21 -15
- package/dist/search/command-palette.js.map +1 -1
- package/dist/search.d.ts +2 -0
- package/dist/search.js +3 -0
- package/dist/search.js.map +1 -0
- package/dist/shell/app-shell.d.ts +33 -4
- package/dist/shell/app-shell.js +275 -78
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/option-switcher-menu.js +3 -2
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +6 -0
- package/dist/shell/role-switcher.js +7 -4
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/top-bar.d.ts +15 -7
- package/dist/shell/top-bar.js +3 -5
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/shell/topbar-action-menu.js +3 -2
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.d.ts +5 -2
- package/dist/shell/topbar-controls.js +20 -15
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/shell.d.ts +13 -0
- package/dist/shell.js +8 -0
- package/dist/shell.js.map +1 -0
- package/dist/theme/chart-palette.d.ts +19 -12
- package/dist/theme/chart-palette.js +24 -30
- package/dist/theme/chart-palette.js.map +1 -1
- package/dist/theme/color.d.ts +78 -0
- package/dist/theme/color.js +148 -0
- package/dist/theme/color.js.map +1 -0
- package/dist/theme/palette-derive.d.ts +140 -0
- package/dist/theme/palette-derive.js +376 -0
- package/dist/theme/palette-derive.js.map +1 -0
- package/dist/theme/palette-presets.d.ts +27 -5
- package/dist/theme/palette-presets.js +231 -33
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/theme/palette-store.js +1 -0
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/theme-store.js +1 -0
- package/dist/theme/theme-store.js.map +1 -1
- package/dist/tour/tour.d.ts +2 -1
- package/dist/tour/tour.js +15 -9
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour.d.ts +2 -0
- package/dist/tour.js +3 -0
- package/dist/tour.js.map +1 -0
- package/dist/wizard/stepper-nav.js +10 -8
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +18 -2
- package/dist/wizard/types.js +4 -1
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.js +12 -4
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/validation.js +1 -0
- package/dist/wizard/validation.js.map +1 -1
- package/dist/wizard/wizard-context.js +1 -0
- package/dist/wizard/wizard-context.js.map +1 -1
- package/dist/wizard/wizard-step.js +1 -0
- package/dist/wizard/wizard-step.js.map +1 -1
- package/dist/wizard/wizard-summary.js +5 -3
- package/dist/wizard/wizard-summary.js.map +1 -1
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +9 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +67 -14
- package/src/chart.ts +22 -0
- package/src/components/account-settings.tsx +275 -0
- package/src/components/alert-banner.tsx +75 -0
- package/src/components/amount-input.tsx +471 -0
- package/src/components/calculator.tsx +252 -0
- package/src/components/chart-zoom.tsx +499 -0
- package/src/components/chart.tsx +363 -0
- package/src/components/checkbox.tsx +222 -0
- package/src/components/chip.tsx +570 -0
- package/src/components/choice-parts.ts +33 -0
- package/src/components/combobox-core.tsx +540 -0
- package/src/components/combobox.tsx +1026 -0
- package/src/components/currency-select.tsx +269 -0
- package/src/components/data-table-filter-popover.tsx +252 -0
- package/src/components/data-table-filters.ts +176 -0
- package/src/components/data-table-labels.ts +190 -0
- package/src/components/data-table-pagination.tsx +126 -0
- package/src/components/data-table-sort.ts +70 -0
- package/src/components/data-table.tsx +1740 -0
- package/src/components/date-picker.tsx +631 -0
- package/src/components/dropdown.tsx +341 -0
- package/src/components/entity-combobox.tsx +215 -0
- package/src/components/facing-pair.ts +86 -0
- package/src/components/field-sync.tsx +472 -0
- package/src/components/file-dropzone.tsx +181 -0
- package/src/components/full-bleed-dialog.tsx +179 -0
- package/src/components/grouped-picker.tsx +157 -0
- package/src/components/hover-menu.tsx +183 -0
- package/src/components/mini-calendar.tsx +554 -0
- package/src/components/modal.tsx +287 -0
- package/src/components/month-picker.tsx +549 -0
- package/src/components/multi-entity-combobox.tsx +226 -0
- package/src/components/multi-select.tsx +303 -0
- package/src/components/number-field.tsx +225 -0
- package/src/components/number-input.tsx +211 -0
- package/src/components/numpad-sheet.tsx +264 -0
- package/src/components/page-contents.tsx +289 -0
- package/src/components/password-strength.tsx +258 -0
- package/src/components/picker-sheet.tsx +251 -0
- package/src/components/popover.tsx +195 -0
- package/src/components/search-field.tsx +146 -0
- package/src/components/series-chart-labels.ts +26 -0
- package/src/components/series-chart.tsx +481 -0
- package/src/components/settings-fields.tsx +68 -0
- package/src/components/signature-pad.tsx +630 -0
- package/src/components/slider.tsx +313 -0
- package/src/components/sparkline.tsx +329 -0
- package/src/components/stat-tile.tsx +448 -0
- package/src/components/swipeable-row.tsx +271 -0
- package/src/components/switch.tsx +170 -0
- package/src/components/time-input.tsx +107 -0
- package/src/components/toggle-group.tsx +153 -0
- package/src/components/toggle-legend.tsx +229 -0
- package/src/components/tooltip.tsx +477 -0
- package/src/components/treemap.tsx +390 -0
- package/src/components/ui.tsx +1284 -0
- package/src/components/use-mobile-reveal.ts +54 -0
- package/src/components/use-table-state.ts +295 -0
- package/src/components/user-avatar.tsx +61 -0
- package/src/components/wizard-stepper.tsx +37 -0
- package/src/data-table.ts +19 -0
- package/src/feedback/feedback-attachment.tsx +246 -0
- package/src/feedback/feedback-dialog.tsx +209 -0
- package/src/feedback/feedback-inbox.tsx +615 -0
- package/src/feedback.ts +8 -0
- package/src/hooks/use-anchored-panel.ts +169 -0
- package/src/hooks/use-anchored-rect.ts +78 -0
- package/src/hooks/use-announce.ts +85 -0
- package/src/hooks/use-body-scroll-lock.ts +94 -0
- package/src/hooks/use-close-transition.ts +99 -0
- package/src/hooks/use-dismiss.ts +77 -0
- package/src/hooks/use-focus-trap.ts +160 -0
- package/src/hooks/use-media-query.ts +23 -0
- package/src/hooks/use-overlay-history.ts +345 -0
- package/src/hooks/use-row-swipe.ts +212 -0
- package/src/i18n/defaults.ts +68 -0
- package/src/i18n/kit-labels.tsx +447 -0
- package/src/index.ts +169 -0
- package/src/lib/calc.ts +309 -0
- package/src/lib/cn.ts +5 -0
- package/src/lib/dates.ts +187 -0
- package/src/lib/logger.ts +73 -0
- package/src/lib/safe-storage.ts +37 -0
- package/src/search/command-palette.tsx +342 -0
- package/src/search.ts +3 -0
- package/src/shell/app-shell.tsx +772 -0
- package/src/shell/option-switcher-menu.tsx +72 -0
- package/src/shell/role-switcher.tsx +46 -0
- package/src/shell/top-bar.tsx +39 -0
- package/src/shell/topbar-action-menu.tsx +91 -0
- package/src/shell/topbar-controls.tsx +229 -0
- package/src/shell.ts +10 -0
- package/src/theme/chart-palette.ts +145 -0
- package/src/theme/color.ts +266 -0
- package/src/theme/palette-derive.ts +681 -0
- package/src/theme/palette-presets.ts +760 -0
- package/src/theme/palette-store.ts +94 -0
- package/src/theme/theme-store.ts +145 -0
- package/src/tour/tour.tsx +586 -0
- package/src/tour.ts +3 -0
- package/src/vite-env.d.ts +26 -0
- package/src/wizard/stepper-nav.tsx +221 -0
- package/src/wizard/types.ts +178 -0
- package/src/wizard/use-wizard.ts +345 -0
- package/src/wizard/validation.ts +37 -0
- package/src/wizard/wizard-context.tsx +29 -0
- package/src/wizard/wizard-step.tsx +14 -0
- package/src/wizard/wizard-summary.tsx +69 -0
- package/src/wizard.ts +14 -0
- package/tokens.css +222 -20
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import type { PointerEvent } from "react";
|
|
3
|
+
|
|
4
|
+
// ---------- Mobile swipe gesture ----------
|
|
5
|
+
//
|
|
6
|
+
// Multi-stage half-swipe affordance (feedback #103, extended #9): drag a row
|
|
7
|
+
// horizontally to commit an action; how FAR you drag picks which action, so a
|
|
8
|
+
// single gesture can walk a chain of increasingly involved outcomes (e.g. on a
|
|
9
|
+
// cleared row, a short left-swipe un-clears it, further un-accepts it, further
|
|
10
|
+
// still deletes it). We track via Pointer Events, lock the gesture to the X axis
|
|
11
|
+
// only after the user has moved more horizontally than vertically, and clamp the
|
|
12
|
+
// drag to `maxDrag` so the row can't be pulled across the whole viewport.
|
|
13
|
+
//
|
|
14
|
+
// Each side is an ordered list of stages sorted by ascending `threshold` (px of
|
|
15
|
+
// drag magnitude). On release the LAST stage whose threshold the drag passed is
|
|
16
|
+
// committed; while dragging, `armedRightIndex`/`armedLeftIndex` report which
|
|
17
|
+
// stage is currently armed so the reveal panel can preview its label/colour.
|
|
18
|
+
|
|
19
|
+
export interface SwipeStage {
|
|
20
|
+
/** Drag magnitude (px) at which this stage arms. Stages must be sorted ascending. */
|
|
21
|
+
threshold: number;
|
|
22
|
+
onCommit: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Below this much horizontal travel a gesture is treated as a clumsy click, not
|
|
26
|
+
* a swipe: the row still follows the pointer, but the click that follows is NOT
|
|
27
|
+
* swallowed. Without it, `swallowClick` was set the instant the axis lock
|
|
28
|
+
* resolved to "x" — 8px — so a slightly-draggy click on a control INSIDE a
|
|
29
|
+
* swipeable row silently did nothing, which is a poor trade on rows whose
|
|
30
|
+
* content is itself interactive (Keksdose feedback #144: budget rows edit their
|
|
31
|
+
* assigned amount and their name by clicking them). */
|
|
32
|
+
const CLICK_SWALLOW_PX = 24;
|
|
33
|
+
|
|
34
|
+
/** How far a drag may travel toward a side that has no actions. Zero — the old
|
|
35
|
+
* behaviour — makes the row completely inert in that direction, which reads as
|
|
36
|
+
* "this row is not swipeable at all" rather than "there is nothing on this
|
|
37
|
+
* side"; that is exactly the report behind Keksdose feedback #144 ("tried, but
|
|
38
|
+
* there is nothing swipeable"). A short, resisted travel that snaps back is the
|
|
39
|
+
* conventional answer and the one that answers the question the drag asked. */
|
|
40
|
+
const EMPTY_SIDE_RUBBER_PX = 28;
|
|
41
|
+
|
|
42
|
+
/** Resistance applied past a bound: the row keeps moving, at a fraction of the
|
|
43
|
+
* pointer, so the gesture feels answered without ever looking committed. */
|
|
44
|
+
function rubberBand(overshoot: number, limit: number): number {
|
|
45
|
+
const eased = limit * (1 - Math.exp(-Math.abs(overshoot) / limit));
|
|
46
|
+
return Math.sign(overshoot) * eased;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface RowSwipeOptions {
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
// Ordered stages per direction (ascending threshold). A longer drag commits a
|
|
52
|
+
// later — usually more involved — stage. An empty/undefined side means that
|
|
53
|
+
// direction rubber-bands a little and snaps back, committing nothing.
|
|
54
|
+
leftStages?: SwipeStage[];
|
|
55
|
+
rightStages?: SwipeStage[];
|
|
56
|
+
maxDrag?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface RowSwipeReturn {
|
|
60
|
+
dx: number;
|
|
61
|
+
dragging: boolean;
|
|
62
|
+
/** Highest armed stage index for the current drag (-1 when none armed). */
|
|
63
|
+
armedRightIndex: number;
|
|
64
|
+
armedLeftIndex: number;
|
|
65
|
+
handlers: {
|
|
66
|
+
onPointerDown: (e: PointerEvent) => void;
|
|
67
|
+
onPointerMove: (e: PointerEvent) => void;
|
|
68
|
+
onPointerUp: (e: PointerEvent) => void;
|
|
69
|
+
onPointerCancel: (e: PointerEvent) => void;
|
|
70
|
+
};
|
|
71
|
+
consumeClick: () => boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** The highest index whose threshold the magnitude has reached (-1 if none).
|
|
75
|
+
* Stages are ascending, so we can stop at the first one not yet reached. */
|
|
76
|
+
function lastArmed(stages: SwipeStage[] | undefined, magnitude: number): number {
|
|
77
|
+
if (!stages) return -1;
|
|
78
|
+
let idx = -1;
|
|
79
|
+
for (let i = 0; i < stages.length; i++) {
|
|
80
|
+
if (magnitude >= stages[i].threshold) idx = i;
|
|
81
|
+
else break;
|
|
82
|
+
}
|
|
83
|
+
return idx;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function useRowSwipe({
|
|
87
|
+
enabled,
|
|
88
|
+
leftStages,
|
|
89
|
+
rightStages,
|
|
90
|
+
maxDrag = 252,
|
|
91
|
+
}: RowSwipeOptions): RowSwipeReturn {
|
|
92
|
+
const [dx, setDx] = useState(0);
|
|
93
|
+
const [dragging, setDragging] = useState(false);
|
|
94
|
+
const startX = useRef(0);
|
|
95
|
+
const startY = useRef(0);
|
|
96
|
+
const axis = useRef<"none" | "x" | "y">("none");
|
|
97
|
+
const pointerId = useRef<number | null>(null);
|
|
98
|
+
const dxRef = useRef(0);
|
|
99
|
+
// True after the user has dragged horizontally far enough that the following
|
|
100
|
+
// synthetic click should be swallowed (so a swipe doesn't also expand the row).
|
|
101
|
+
const swallowClick = useRef(false);
|
|
102
|
+
|
|
103
|
+
// Keep the latest stage arrays in refs so the memoised pointer handlers always
|
|
104
|
+
// commit against the current plan rather than a stale closure — the arrays and
|
|
105
|
+
// their onCommit closures are rebuilt on every render. Written in an effect (not
|
|
106
|
+
// during render) so it satisfies react-hooks/refs; pointer events fire after the
|
|
107
|
+
// commit, so the refs are always current by the time a gesture reads them.
|
|
108
|
+
const leftRef = useRef(leftStages);
|
|
109
|
+
const rightRef = useRef(rightStages);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
leftRef.current = leftStages;
|
|
112
|
+
rightRef.current = rightStages;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const reset = useCallback(() => {
|
|
116
|
+
setDx(0);
|
|
117
|
+
dxRef.current = 0;
|
|
118
|
+
setDragging(false);
|
|
119
|
+
startX.current = 0;
|
|
120
|
+
startY.current = 0;
|
|
121
|
+
axis.current = "none";
|
|
122
|
+
pointerId.current = null;
|
|
123
|
+
}, []);
|
|
124
|
+
|
|
125
|
+
const onPointerDown = useCallback(
|
|
126
|
+
(e: PointerEvent) => {
|
|
127
|
+
if (!enabled) return;
|
|
128
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
129
|
+
pointerId.current = e.pointerId;
|
|
130
|
+
startX.current = e.clientX;
|
|
131
|
+
startY.current = e.clientY;
|
|
132
|
+
axis.current = "none";
|
|
133
|
+
swallowClick.current = false;
|
|
134
|
+
setDragging(true);
|
|
135
|
+
},
|
|
136
|
+
[enabled],
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const onPointerMove = useCallback(
|
|
140
|
+
(e: PointerEvent) => {
|
|
141
|
+
if (pointerId.current !== e.pointerId) return;
|
|
142
|
+
const rawDx = e.clientX - startX.current;
|
|
143
|
+
const rawDy = e.clientY - startY.current;
|
|
144
|
+
if (axis.current === "none") {
|
|
145
|
+
if (Math.abs(rawDx) < 8 && Math.abs(rawDy) < 8) return;
|
|
146
|
+
axis.current = Math.abs(rawDx) > Math.abs(rawDy) ? "x" : "y";
|
|
147
|
+
if (axis.current === "x") {
|
|
148
|
+
(e.currentTarget as Element).setPointerCapture?.(e.pointerId);
|
|
149
|
+
} else {
|
|
150
|
+
// Vertical scroll wins — bail out of the gesture entirely.
|
|
151
|
+
reset();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (axis.current !== "x") return;
|
|
156
|
+
if (Math.abs(rawDx) >= CLICK_SWALLOW_PX) swallowClick.current = true;
|
|
157
|
+
// Toward a side that HAS actions the row tracks the pointer up to maxDrag.
|
|
158
|
+
// Toward an empty one it rubber-bands a little and snaps back on release —
|
|
159
|
+
// inert would be indistinguishable from "not swipeable".
|
|
160
|
+
const hasLeft = (leftRef.current?.length ?? 0) > 0;
|
|
161
|
+
const hasRight = (rightRef.current?.length ?? 0) > 0;
|
|
162
|
+
let next: number;
|
|
163
|
+
if (rawDx > 0) {
|
|
164
|
+
next = hasRight ? Math.min(maxDrag, rawDx) : rubberBand(rawDx, EMPTY_SIDE_RUBBER_PX);
|
|
165
|
+
} else if (rawDx < 0) {
|
|
166
|
+
next = hasLeft ? Math.max(-maxDrag, rawDx) : rubberBand(rawDx, EMPTY_SIDE_RUBBER_PX);
|
|
167
|
+
} else {
|
|
168
|
+
next = 0;
|
|
169
|
+
}
|
|
170
|
+
dxRef.current = next;
|
|
171
|
+
setDx(next);
|
|
172
|
+
},
|
|
173
|
+
[maxDrag, reset],
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const onPointerUp = useCallback(
|
|
177
|
+
(e: PointerEvent) => {
|
|
178
|
+
if (pointerId.current !== e.pointerId) return;
|
|
179
|
+
const finalDx = dxRef.current;
|
|
180
|
+
const wasDragX = axis.current === "x";
|
|
181
|
+
reset();
|
|
182
|
+
if (!wasDragX) return;
|
|
183
|
+
if (finalDx > 0) {
|
|
184
|
+
const i = lastArmed(rightRef.current, finalDx);
|
|
185
|
+
if (i >= 0) rightRef.current![i].onCommit();
|
|
186
|
+
} else if (finalDx < 0) {
|
|
187
|
+
const i = lastArmed(leftRef.current, -finalDx);
|
|
188
|
+
if (i >= 0) leftRef.current![i].onCommit();
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
[reset],
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const onPointerCancel = useCallback(() => reset(), [reset]);
|
|
195
|
+
|
|
196
|
+
const consumeClick = useCallback(() => {
|
|
197
|
+
if (swallowClick.current) {
|
|
198
|
+
swallowClick.current = false;
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}, []);
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
dx,
|
|
206
|
+
dragging,
|
|
207
|
+
armedRightIndex: lastArmed(rightStages, dx > 0 ? dx : 0),
|
|
208
|
+
armedLeftIndex: lastArmed(leftStages, dx < 0 ? -dx : 0),
|
|
209
|
+
handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel },
|
|
210
|
+
consumeClick,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { DEFAULT_DATA_TABLE_LABELS } from "../components/data-table-labels";
|
|
2
|
+
import { DEFAULT_MINI_CALENDAR_LABELS } from "../components/mini-calendar";
|
|
3
|
+
import { DEFAULT_MONTH_PICKER_LABELS } from "../components/month-picker";
|
|
4
|
+
import { DEFAULT_PAGE_CONTENTS_LABELS } from "../components/page-contents";
|
|
5
|
+
import { DEFAULT_POPOVER_LABELS } from "../components/popover";
|
|
6
|
+
import { DEFAULT_CHIP_INPUT_LABELS } from "../components/chip";
|
|
7
|
+
import { DEFAULT_FIELD_SYNC_LABELS } from "../components/field-sync";
|
|
8
|
+
import { DEFAULT_PASSWORD_REVEAL_LABELS } from "../components/ui";
|
|
9
|
+
import { DEFAULT_WIZARD_LABELS } from "../wizard/types";
|
|
10
|
+
import { DEFAULT_TOUR_LABELS } from "../tour/tour";
|
|
11
|
+
import { DEFAULT_COMMAND_PALETTE_LABELS } from "../search/command-palette";
|
|
12
|
+
import { DEFAULT_SERIES_CHART_LABELS } from "../components/series-chart-labels";
|
|
13
|
+
import { DEFAULT_SPARKLINE_LABELS } from "../components/sparkline";
|
|
14
|
+
import { DEFAULT_STAT_TILE_LABELS } from "../components/stat-tile";
|
|
15
|
+
import { DEFAULT_SIGNATURE_PAD_LABELS } from "../components/signature-pad";
|
|
16
|
+
import { DEFAULT_PASSWORD_STRENGTH_LABELS } from "../components/password-strength";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_APP_SHELL_LABELS,
|
|
19
|
+
DEFAULT_CALCULATOR_LABELS,
|
|
20
|
+
DEFAULT_COMBOBOX_LABELS,
|
|
21
|
+
DEFAULT_COMMON_LABELS,
|
|
22
|
+
DEFAULT_CURRENCY_LABELS,
|
|
23
|
+
DEFAULT_DATE_PICKER_LABELS,
|
|
24
|
+
DEFAULT_FILE_LABELS,
|
|
25
|
+
DEFAULT_MULTI_SELECT_LABELS,
|
|
26
|
+
DEFAULT_PICKER_SHEET_LABELS,
|
|
27
|
+
DEFAULT_SWIPEABLE_ROW_LABELS,
|
|
28
|
+
DEFAULT_TOP_BAR_LABELS,
|
|
29
|
+
} from "./kit-labels";
|
|
30
|
+
import type { UiKitLabels } from "./kit-labels";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The whole English tree in one object: what a translation is written against, and
|
|
34
|
+
* the `reference` for {@link missingKitLabels}.
|
|
35
|
+
*
|
|
36
|
+
* A separate module from the provider on purpose. Components import the provider's
|
|
37
|
+
* hooks; this file imports the components' defaults. Kept together they would be an
|
|
38
|
+
* import cycle through every component in the kit.
|
|
39
|
+
*/
|
|
40
|
+
export const DEFAULT_UI_KIT_LABELS: UiKitLabels = {
|
|
41
|
+
common: DEFAULT_COMMON_LABELS,
|
|
42
|
+
dataTable: DEFAULT_DATA_TABLE_LABELS,
|
|
43
|
+
miniCalendar: DEFAULT_MINI_CALENDAR_LABELS,
|
|
44
|
+
datePicker: DEFAULT_DATE_PICKER_LABELS,
|
|
45
|
+
monthPicker: DEFAULT_MONTH_PICKER_LABELS,
|
|
46
|
+
popover: DEFAULT_POPOVER_LABELS,
|
|
47
|
+
combobox: DEFAULT_COMBOBOX_LABELS,
|
|
48
|
+
multiSelect: DEFAULT_MULTI_SELECT_LABELS,
|
|
49
|
+
calculator: DEFAULT_CALCULATOR_LABELS,
|
|
50
|
+
currency: DEFAULT_CURRENCY_LABELS,
|
|
51
|
+
chipInput: DEFAULT_CHIP_INPUT_LABELS,
|
|
52
|
+
fieldSync: DEFAULT_FIELD_SYNC_LABELS,
|
|
53
|
+
passwordReveal: DEFAULT_PASSWORD_REVEAL_LABELS,
|
|
54
|
+
appShell: DEFAULT_APP_SHELL_LABELS,
|
|
55
|
+
pageContents: DEFAULT_PAGE_CONTENTS_LABELS,
|
|
56
|
+
topBar: DEFAULT_TOP_BAR_LABELS,
|
|
57
|
+
pickerSheet: DEFAULT_PICKER_SHEET_LABELS,
|
|
58
|
+
swipeableRow: DEFAULT_SWIPEABLE_ROW_LABELS,
|
|
59
|
+
file: DEFAULT_FILE_LABELS,
|
|
60
|
+
wizard: DEFAULT_WIZARD_LABELS,
|
|
61
|
+
tour: DEFAULT_TOUR_LABELS,
|
|
62
|
+
commandPalette: DEFAULT_COMMAND_PALETTE_LABELS,
|
|
63
|
+
seriesChart: DEFAULT_SERIES_CHART_LABELS,
|
|
64
|
+
sparkline: DEFAULT_SPARKLINE_LABELS,
|
|
65
|
+
statTile: DEFAULT_STAT_TILE_LABELS,
|
|
66
|
+
signaturePad: DEFAULT_SIGNATURE_PAD_LABELS,
|
|
67
|
+
passwordStrength: DEFAULT_PASSWORD_STRENGTH_LABELS,
|
|
68
|
+
};
|