@weave-framework/ui 0.2.107
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 +21 -0
- package/README.md +17 -0
- package/dist/autocomplete/autocomplete.d.ts +86 -0
- package/dist/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/autocomplete/autocomplete.js +263 -0
- package/dist/autocomplete/autocomplete.js.map +1 -0
- package/dist/badge/badge.d.ts +39 -0
- package/dist/badge/badge.d.ts.map +1 -0
- package/dist/badge/badge.js +59 -0
- package/dist/badge/badge.js.map +1 -0
- package/dist/bottom-sheet/bottom-sheet.d.ts +21 -0
- package/dist/bottom-sheet/bottom-sheet.d.ts.map +1 -0
- package/dist/bottom-sheet/bottom-sheet.js +82 -0
- package/dist/bottom-sheet/bottom-sheet.js.map +1 -0
- package/dist/button/button.d.ts +47 -0
- package/dist/button/button.d.ts.map +1 -0
- package/dist/button/button.js +47 -0
- package/dist/button/button.js.map +1 -0
- package/dist/button-toggle/button-toggle.d.ts +65 -0
- package/dist/button-toggle/button-toggle.d.ts.map +1 -0
- package/dist/button-toggle/button-toggle.js +127 -0
- package/dist/button-toggle/button-toggle.js.map +1 -0
- package/dist/card/card.d.ts +30 -0
- package/dist/card/card.d.ts.map +1 -0
- package/dist/card/card.js +32 -0
- package/dist/card/card.js.map +1 -0
- package/dist/cdk/bidi.d.ts +19 -0
- package/dist/cdk/bidi.d.ts.map +1 -0
- package/dist/cdk/bidi.js +32 -0
- package/dist/cdk/bidi.js.map +1 -0
- package/dist/cdk/breakpoints.d.ts +21 -0
- package/dist/cdk/breakpoints.d.ts.map +1 -0
- package/dist/cdk/breakpoints.js +39 -0
- package/dist/cdk/breakpoints.js.map +1 -0
- package/dist/cdk/clipboard.d.ts +8 -0
- package/dist/cdk/clipboard.d.ts.map +1 -0
- package/dist/cdk/clipboard.js +38 -0
- package/dist/cdk/clipboard.js.map +1 -0
- package/dist/cdk/data-source.d.ts +41 -0
- package/dist/cdk/data-source.d.ts.map +1 -0
- package/dist/cdk/data-source.js +36 -0
- package/dist/cdk/data-source.js.map +1 -0
- package/dist/cdk/date-adapter.d.ts +63 -0
- package/dist/cdk/date-adapter.d.ts.map +1 -0
- package/dist/cdk/date-adapter.js +155 -0
- package/dist/cdk/date-adapter.js.map +1 -0
- package/dist/cdk/drag-drop.d.ts +77 -0
- package/dist/cdk/drag-drop.d.ts.map +1 -0
- package/dist/cdk/drag-drop.js +268 -0
- package/dist/cdk/drag-drop.js.map +1 -0
- package/dist/cdk/focus-monitor.d.ts +27 -0
- package/dist/cdk/focus-monitor.d.ts.map +1 -0
- package/dist/cdk/focus-monitor.js +66 -0
- package/dist/cdk/focus-monitor.js.map +1 -0
- package/dist/cdk/focus-trap.d.ts +39 -0
- package/dist/cdk/focus-trap.d.ts.map +1 -0
- package/dist/cdk/focus-trap.js +127 -0
- package/dist/cdk/focus-trap.js.map +1 -0
- package/dist/cdk/index.d.ts +29 -0
- package/dist/cdk/index.d.ts.map +1 -0
- package/dist/cdk/index.js +29 -0
- package/dist/cdk/index.js.map +1 -0
- package/dist/cdk/interactivity.d.ts +19 -0
- package/dist/cdk/interactivity.d.ts.map +1 -0
- package/dist/cdk/interactivity.js +70 -0
- package/dist/cdk/interactivity.js.map +1 -0
- package/dist/cdk/key-manager.d.ts +41 -0
- package/dist/cdk/key-manager.d.ts.map +1 -0
- package/dist/cdk/key-manager.js +126 -0
- package/dist/cdk/key-manager.js.map +1 -0
- package/dist/cdk/live-announcer.d.ts +19 -0
- package/dist/cdk/live-announcer.d.ts.map +1 -0
- package/dist/cdk/live-announcer.js +48 -0
- package/dist/cdk/live-announcer.js.map +1 -0
- package/dist/cdk/observers.d.ts +17 -0
- package/dist/cdk/observers.d.ts.map +1 -0
- package/dist/cdk/observers.js +35 -0
- package/dist/cdk/observers.js.map +1 -0
- package/dist/cdk/overlay.d.ts +73 -0
- package/dist/cdk/overlay.d.ts.map +1 -0
- package/dist/cdk/overlay.js +154 -0
- package/dist/cdk/overlay.js.map +1 -0
- package/dist/cdk/platform.d.ts +22 -0
- package/dist/cdk/platform.d.ts.map +1 -0
- package/dist/cdk/platform.js +55 -0
- package/dist/cdk/platform.js.map +1 -0
- package/dist/cdk/portal.d.ts +31 -0
- package/dist/cdk/portal.d.ts.map +1 -0
- package/dist/cdk/portal.js +55 -0
- package/dist/cdk/portal.js.map +1 -0
- package/dist/cdk/positioning.d.ts +53 -0
- package/dist/cdk/positioning.d.ts.map +1 -0
- package/dist/cdk/positioning.js +140 -0
- package/dist/cdk/positioning.js.map +1 -0
- package/dist/cdk/scroll.d.ts +43 -0
- package/dist/cdk/scroll.d.ts.map +1 -0
- package/dist/cdk/scroll.js +97 -0
- package/dist/cdk/scroll.js.map +1 -0
- package/dist/cdk/selection-model.d.ts +50 -0
- package/dist/cdk/selection-model.d.ts.map +1 -0
- package/dist/cdk/selection-model.js +77 -0
- package/dist/cdk/selection-model.js.map +1 -0
- package/dist/cdk/virtual-scroll.d.ts +50 -0
- package/dist/cdk/virtual-scroll.d.ts.map +1 -0
- package/dist/cdk/virtual-scroll.js +92 -0
- package/dist/cdk/virtual-scroll.js.map +1 -0
- package/dist/checkbox/checkbox.d.ts +65 -0
- package/dist/checkbox/checkbox.d.ts.map +1 -0
- package/dist/checkbox/checkbox.js +82 -0
- package/dist/checkbox/checkbox.js.map +1 -0
- package/dist/chips/chips.d.ts +65 -0
- package/dist/chips/chips.d.ts.map +1 -0
- package/dist/chips/chips.js +119 -0
- package/dist/chips/chips.js.map +1 -0
- package/dist/context-menu/context-menu.d.ts +32 -0
- package/dist/context-menu/context-menu.d.ts.map +1 -0
- package/dist/context-menu/context-menu.js +63 -0
- package/dist/context-menu/context-menu.js.map +1 -0
- package/dist/datepicker/datepicker.d.ts +100 -0
- package/dist/datepicker/datepicker.d.ts.map +1 -0
- package/dist/datepicker/datepicker.js +440 -0
- package/dist/datepicker/datepicker.js.map +1 -0
- package/dist/dialog/dialog.d.ts +27 -0
- package/dist/dialog/dialog.d.ts.map +1 -0
- package/dist/dialog/dialog.js +47 -0
- package/dist/dialog/dialog.js.map +1 -0
- package/dist/dialog/modal-core.d.ts +42 -0
- package/dist/dialog/modal-core.d.ts.map +1 -0
- package/dist/dialog/modal-core.js +103 -0
- package/dist/dialog/modal-core.js.map +1 -0
- package/dist/expansion/expansion.d.ts +71 -0
- package/dist/expansion/expansion.d.ts.map +1 -0
- package/dist/expansion/expansion.js +127 -0
- package/dist/expansion/expansion.js.map +1 -0
- package/dist/form-field/form-field.d.ts +48 -0
- package/dist/form-field/form-field.d.ts.map +1 -0
- package/dist/form-field/form-field.js +89 -0
- package/dist/form-field/form-field.js.map +1 -0
- package/dist/grid-list/grid-list.d.ts +25 -0
- package/dist/grid-list/grid-list.d.ts.map +1 -0
- package/dist/grid-list/grid-list.js +22 -0
- package/dist/grid-list/grid-list.js.map +1 -0
- package/dist/icon/icon.d.ts +40 -0
- package/dist/icon/icon.d.ts.map +1 -0
- package/dist/icon/icon.js +99 -0
- package/dist/icon/icon.js.map +1 -0
- package/dist/icon/icons.d.ts +60 -0
- package/dist/icon/icons.d.ts.map +1 -0
- package/dist/icon/icons.js +126 -0
- package/dist/icon/icons.js.map +1 -0
- package/dist/icon/lucide-icons.d.ts +11 -0
- package/dist/icon/lucide-icons.d.ts.map +1 -0
- package/dist/icon/lucide-icons.js +65 -0
- package/dist/icon/lucide-icons.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/input/input.d.ts +90 -0
- package/dist/input/input.d.ts.map +1 -0
- package/dist/input/input.js +138 -0
- package/dist/input/input.js.map +1 -0
- package/dist/internal/compose.d.ts +26 -0
- package/dist/internal/compose.d.ts.map +1 -0
- package/dist/internal/compose.js +32 -0
- package/dist/internal/compose.js.map +1 -0
- package/dist/list/list.d.ts +70 -0
- package/dist/list/list.d.ts.map +1 -0
- package/dist/list/list.js +144 -0
- package/dist/list/list.js.map +1 -0
- package/dist/menu/menu-core.d.ts +56 -0
- package/dist/menu/menu-core.d.ts.map +1 -0
- package/dist/menu/menu-core.js +122 -0
- package/dist/menu/menu-core.js.map +1 -0
- package/dist/menu/menu.d.ts +31 -0
- package/dist/menu/menu.d.ts.map +1 -0
- package/dist/menu/menu.js +68 -0
- package/dist/menu/menu.js.map +1 -0
- package/dist/menubar/menubar.d.ts +49 -0
- package/dist/menubar/menubar.d.ts.map +1 -0
- package/dist/menubar/menubar.js +162 -0
- package/dist/menubar/menubar.js.map +1 -0
- package/dist/paginator/paginator.d.ts +89 -0
- package/dist/paginator/paginator.d.ts.map +1 -0
- package/dist/paginator/paginator.js +159 -0
- package/dist/paginator/paginator.js.map +1 -0
- package/dist/popover-edit/popover-edit.d.ts +33 -0
- package/dist/popover-edit/popover-edit.d.ts.map +1 -0
- package/dist/popover-edit/popover-edit.js +107 -0
- package/dist/popover-edit/popover-edit.js.map +1 -0
- package/dist/progress-bar/progress-bar.d.ts +32 -0
- package/dist/progress-bar/progress-bar.d.ts.map +1 -0
- package/dist/progress-bar/progress-bar.js +42 -0
- package/dist/progress-bar/progress-bar.js.map +1 -0
- package/dist/progress-spinner/progress-spinner.d.ts +25 -0
- package/dist/progress-spinner/progress-spinner.d.ts.map +1 -0
- package/dist/progress-spinner/progress-spinner.js +25 -0
- package/dist/progress-spinner/progress-spinner.js.map +1 -0
- package/dist/radio/radio.d.ts +68 -0
- package/dist/radio/radio.d.ts.map +1 -0
- package/dist/radio/radio.js +81 -0
- package/dist/radio/radio.js.map +1 -0
- package/dist/ripple/ripple.d.ts +20 -0
- package/dist/ripple/ripple.d.ts.map +1 -0
- package/dist/ripple/ripple.js +41 -0
- package/dist/ripple/ripple.js.map +1 -0
- package/dist/select/select.d.ts +83 -0
- package/dist/select/select.d.ts.map +1 -0
- package/dist/select/select.js +320 -0
- package/dist/select/select.js.map +1 -0
- package/dist/shared/options.d.ts +44 -0
- package/dist/shared/options.d.ts.map +1 -0
- package/dist/shared/options.js +59 -0
- package/dist/shared/options.js.map +1 -0
- package/dist/shared/positions.d.ts +20 -0
- package/dist/shared/positions.d.ts.map +1 -0
- package/dist/shared/positions.js +27 -0
- package/dist/shared/positions.js.map +1 -0
- package/dist/sidenav/sidenav.d.ts +65 -0
- package/dist/sidenav/sidenav.d.ts.map +1 -0
- package/dist/sidenav/sidenav.js +120 -0
- package/dist/sidenav/sidenav.js.map +1 -0
- package/dist/slide-toggle/slide-toggle.d.ts +56 -0
- package/dist/slide-toggle/slide-toggle.d.ts.map +1 -0
- package/dist/slide-toggle/slide-toggle.js +62 -0
- package/dist/slide-toggle/slide-toggle.js.map +1 -0
- package/dist/slider/slider.d.ts +69 -0
- package/dist/slider/slider.d.ts.map +1 -0
- package/dist/slider/slider.js +184 -0
- package/dist/slider/slider.js.map +1 -0
- package/dist/snackbar/snackbar.d.ts +25 -0
- package/dist/snackbar/snackbar.d.ts.map +1 -0
- package/dist/snackbar/snackbar.js +135 -0
- package/dist/snackbar/snackbar.js.map +1 -0
- package/dist/stepper/stepper.d.ts +87 -0
- package/dist/stepper/stepper.d.ts.map +1 -0
- package/dist/stepper/stepper.js +142 -0
- package/dist/stepper/stepper.js.map +1 -0
- package/dist/table/table.d.ts +140 -0
- package/dist/table/table.d.ts.map +1 -0
- package/dist/table/table.js +312 -0
- package/dist/table/table.js.map +1 -0
- package/dist/tabs/tabs.d.ts +64 -0
- package/dist/tabs/tabs.d.ts.map +1 -0
- package/dist/tabs/tabs.js +126 -0
- package/dist/tabs/tabs.js.map +1 -0
- package/dist/timepicker/timepicker.d.ts +83 -0
- package/dist/timepicker/timepicker.d.ts.map +1 -0
- package/dist/timepicker/timepicker.js +303 -0
- package/dist/timepicker/timepicker.js.map +1 -0
- package/dist/toolbar/toolbar.d.ts +34 -0
- package/dist/toolbar/toolbar.d.ts.map +1 -0
- package/dist/toolbar/toolbar.js +35 -0
- package/dist/toolbar/toolbar.js.map +1 -0
- package/dist/tooltip/tooltip.d.ts +30 -0
- package/dist/tooltip/tooltip.d.ts.map +1 -0
- package/dist/tooltip/tooltip.js +109 -0
- package/dist/tooltip/tooltip.js.map +1 -0
- package/dist/tree/tree.d.ts +100 -0
- package/dist/tree/tree.d.ts.map +1 -0
- package/dist/tree/tree.js +288 -0
- package/dist/tree/tree.js.map +1 -0
- package/package.json +230 -0
- package/src/styles/_api.scss +384 -0
- package/src/styles/_helpers.scss +101 -0
- package/src/styles/_index.scss +12 -0
- package/src/styles/_ref.scss +20 -0
- package/src/styles/_sass-utils.scss +14 -0
- package/src/styles/_token-utils.scss +24 -0
- package/src/styles/components/autocomplete/_index.scss +10 -0
- package/src/styles/components/autocomplete/_styles.scss +46 -0
- package/src/styles/components/autocomplete/_tokens.scss +28 -0
- package/src/styles/components/badge/_index.scss +12 -0
- package/src/styles/components/badge/_styles.scss +72 -0
- package/src/styles/components/badge/_tokens.scss +27 -0
- package/src/styles/components/bottom-sheet/_index.scss +9 -0
- package/src/styles/components/bottom-sheet/_styles.scss +77 -0
- package/src/styles/components/bottom-sheet/_tokens.scss +33 -0
- package/src/styles/components/button/_index.scss +12 -0
- package/src/styles/components/button/_styles.scss +106 -0
- package/src/styles/components/button/_tokens.scss +36 -0
- package/src/styles/components/button-toggle/_index.scss +12 -0
- package/src/styles/components/button-toggle/_styles.scss +57 -0
- package/src/styles/components/button-toggle/_tokens.scss +25 -0
- package/src/styles/components/card/_index.scss +15 -0
- package/src/styles/components/card/_styles.scss +68 -0
- package/src/styles/components/card/_tokens.scss +26 -0
- package/src/styles/components/checkbox/_index.scss +13 -0
- package/src/styles/components/checkbox/_styles.scss +108 -0
- package/src/styles/components/checkbox/_tokens.scss +25 -0
- package/src/styles/components/chips/_index.scss +12 -0
- package/src/styles/components/chips/_styles.scss +83 -0
- package/src/styles/components/chips/_tokens.scss +28 -0
- package/src/styles/components/datepicker/_index.scss +10 -0
- package/src/styles/components/datepicker/_styles.scss +203 -0
- package/src/styles/components/datepicker/_tokens.scss +50 -0
- package/src/styles/components/dialog/_index.scss +9 -0
- package/src/styles/components/dialog/_styles.scss +54 -0
- package/src/styles/components/dialog/_tokens.scss +29 -0
- package/src/styles/components/divider/_index.scss +8 -0
- package/src/styles/components/divider/_styles.scss +18 -0
- package/src/styles/components/divider/_tokens.scss +12 -0
- package/src/styles/components/expansion/_index.scss +14 -0
- package/src/styles/components/expansion/_styles.scss +128 -0
- package/src/styles/components/expansion/_tokens.scss +32 -0
- package/src/styles/components/form-field/_index.scss +13 -0
- package/src/styles/components/form-field/_styles.scss +39 -0
- package/src/styles/components/form-field/_tokens.scss +19 -0
- package/src/styles/components/grid-list/_index.scss +12 -0
- package/src/styles/components/grid-list/_styles.scss +31 -0
- package/src/styles/components/grid-list/_tokens.scss +18 -0
- package/src/styles/components/icon/_index.scss +8 -0
- package/src/styles/components/icon/_styles.scss +18 -0
- package/src/styles/components/icon/_tokens.scss +8 -0
- package/src/styles/components/input/_index.scss +13 -0
- package/src/styles/components/input/_styles.scss +111 -0
- package/src/styles/components/input/_tokens.scss +21 -0
- package/src/styles/components/list/_index.scss +12 -0
- package/src/styles/components/list/_styles.scss +87 -0
- package/src/styles/components/list/_tokens.scss +31 -0
- package/src/styles/components/menu/_index.scss +9 -0
- package/src/styles/components/menu/_styles.scss +60 -0
- package/src/styles/components/menu/_tokens.scss +33 -0
- package/src/styles/components/menubar/_index.scss +9 -0
- package/src/styles/components/menubar/_styles.scss +41 -0
- package/src/styles/components/menubar/_tokens.scss +25 -0
- package/src/styles/components/overlay/_index.scss +8 -0
- package/src/styles/components/overlay/_styles.scss +25 -0
- package/src/styles/components/overlay/_tokens.scss +21 -0
- package/src/styles/components/paginator/_index.scss +14 -0
- package/src/styles/components/paginator/_styles.scss +77 -0
- package/src/styles/components/paginator/_tokens.scss +28 -0
- package/src/styles/components/popover-edit/_index.scss +9 -0
- package/src/styles/components/popover-edit/_styles.scss +31 -0
- package/src/styles/components/popover-edit/_tokens.scss +21 -0
- package/src/styles/components/progress-bar/_index.scss +11 -0
- package/src/styles/components/progress-bar/_styles.scss +39 -0
- package/src/styles/components/progress-bar/_tokens.scss +17 -0
- package/src/styles/components/progress-spinner/_index.scss +11 -0
- package/src/styles/components/progress-spinner/_styles.scss +26 -0
- package/src/styles/components/progress-spinner/_tokens.scss +15 -0
- package/src/styles/components/radio/_index.scss +14 -0
- package/src/styles/components/radio/_styles.scss +92 -0
- package/src/styles/components/radio/_tokens.scss +24 -0
- package/src/styles/components/ripple/_index.scss +8 -0
- package/src/styles/components/ripple/_styles.scss +20 -0
- package/src/styles/components/ripple/_tokens.scss +12 -0
- package/src/styles/components/select/_index.scss +9 -0
- package/src/styles/components/select/_styles.scss +120 -0
- package/src/styles/components/select/_tokens.scss +35 -0
- package/src/styles/components/sidenav/_index.scss +14 -0
- package/src/styles/components/sidenav/_styles.scss +105 -0
- package/src/styles/components/sidenav/_tokens.scss +24 -0
- package/src/styles/components/slide-toggle/_index.scss +13 -0
- package/src/styles/components/slide-toggle/_styles.scss +86 -0
- package/src/styles/components/slide-toggle/_tokens.scss +24 -0
- package/src/styles/components/slider/_index.scss +13 -0
- package/src/styles/components/slider/_styles.scss +77 -0
- package/src/styles/components/slider/_tokens.scss +21 -0
- package/src/styles/components/snackbar/_index.scss +8 -0
- package/src/styles/components/snackbar/_styles.scss +59 -0
- package/src/styles/components/snackbar/_tokens.scss +28 -0
- package/src/styles/components/stepper/_index.scss +14 -0
- package/src/styles/components/stepper/_styles.scss +129 -0
- package/src/styles/components/stepper/_tokens.scss +44 -0
- package/src/styles/components/table/_index.scss +14 -0
- package/src/styles/components/table/_styles.scss +202 -0
- package/src/styles/components/table/_tokens.scss +47 -0
- package/src/styles/components/tabs/_index.scss +13 -0
- package/src/styles/components/tabs/_styles.scss +76 -0
- package/src/styles/components/tabs/_tokens.scss +28 -0
- package/src/styles/components/timepicker/_index.scss +9 -0
- package/src/styles/components/timepicker/_styles.scss +136 -0
- package/src/styles/components/timepicker/_tokens.scss +46 -0
- package/src/styles/components/toolbar/_index.scss +12 -0
- package/src/styles/components/toolbar/_styles.scss +41 -0
- package/src/styles/components/toolbar/_tokens.scss +17 -0
- package/src/styles/components/tooltip/_index.scss +8 -0
- package/src/styles/components/tooltip/_styles.scss +29 -0
- package/src/styles/components/tooltip/_tokens.scss +22 -0
- package/src/styles/components/tree/_index.scss +13 -0
- package/src/styles/components/tree/_styles.scss +99 -0
- package/src/styles/components/tree/_tokens.scss +38 -0
- package/src/styles/theme/_defaults.scss +50 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Menu — a dropdown of actions, applied as a Weave `use:` action to a trigger element:
|
|
3
|
+
*
|
|
4
|
+
* <button use:menu={{ { items: [{value:'edit',label:'Edit'}, {value:'del',label:'Delete'}],
|
|
5
|
+
* onSelect: (v) => run(v) } }}>Actions ▾</button>
|
|
6
|
+
*
|
|
7
|
+
* Click (or ArrowDown / Enter / Space) opens a CDK-overlay panel anchored under the
|
|
8
|
+
* trigger; keyboard, roving focus, typeahead, click-away and focus-return are handled by
|
|
9
|
+
* the shared menu core. The trigger carries `aria-haspopup=menu` + `aria-expanded`. The
|
|
10
|
+
* visual is `menu.styles()` (the `--weave-menu-*` republic). Zero-dep.
|
|
11
|
+
*/
|
|
12
|
+
import { type MenuItem, type MenuPosition, type OptionAccessors } from './menu-core.js';
|
|
13
|
+
export type { MenuItem, MenuPosition, OptionAccessors } from './menu-core.js';
|
|
14
|
+
export interface MenuOptions<T = MenuItem> extends OptionAccessors<T> {
|
|
15
|
+
/** The options — the default `{value,label,description?,disabled?,divider?}`, plain strings,
|
|
16
|
+
* or arbitrary objects (map their fields via the `option*` accessors). */
|
|
17
|
+
items: T[];
|
|
18
|
+
/** Called with the chosen option (value string, or the whole object — see `emit`). */
|
|
19
|
+
onSelect: (selected: string | T) => void;
|
|
20
|
+
/** Is this option a hairline separator? Default: `item.divider`. */
|
|
21
|
+
isDivider?: (item: T) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Where the panel sits relative to the trigger; flips to the opposite on overflow.
|
|
24
|
+
* A preset (`'bottom-start'`, `'top'`, `'bottom-end'`, …) or an explicit anchor pair.
|
|
25
|
+
* Default `'bottom-start'` (below, left-aligned).
|
|
26
|
+
*/
|
|
27
|
+
position?: MenuPosition;
|
|
28
|
+
}
|
|
29
|
+
/** Weave `use:` action: `(trigger, options) => cleanup`. */
|
|
30
|
+
export declare function menu<T = MenuItem>(trigger: HTMLElement, options: MenuOptions<T>): () => void;
|
|
31
|
+
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/menu/menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE9E,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,QAAQ,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IACnE;8EAC0E;IAC1E,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,sFAAsF;IACtF,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,KAAK,IAAI,CAAC;IACzC,oEAAoE;IACpE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,4DAA4D;AAC5D,wBAAgB,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAoD5F"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Menu — a dropdown of actions, applied as a Weave `use:` action to a trigger element:
|
|
3
|
+
*
|
|
4
|
+
* <button use:menu={{ { items: [{value:'edit',label:'Edit'}, {value:'del',label:'Delete'}],
|
|
5
|
+
* onSelect: (v) => run(v) } }}>Actions ▾</button>
|
|
6
|
+
*
|
|
7
|
+
* Click (or ArrowDown / Enter / Space) opens a CDK-overlay panel anchored under the
|
|
8
|
+
* trigger; keyboard, roving focus, typeahead, click-away and focus-return are handled by
|
|
9
|
+
* the shared menu core. The trigger carries `aria-haspopup=menu` + `aria-expanded`. The
|
|
10
|
+
* visual is `menu.styles()` (the `--weave-menu-*` republic). Zero-dep.
|
|
11
|
+
*/
|
|
12
|
+
import { openMenuPanel, buildPositions, } from './menu-core.js';
|
|
13
|
+
/** Weave `use:` action: `(trigger, options) => cleanup`. */
|
|
14
|
+
export function menu(trigger, options) {
|
|
15
|
+
let handle = null;
|
|
16
|
+
trigger.setAttribute('aria-haspopup', 'menu');
|
|
17
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
18
|
+
function openMenu(focusFirst) {
|
|
19
|
+
if (handle)
|
|
20
|
+
return;
|
|
21
|
+
handle = openMenuPanel({
|
|
22
|
+
origin: trigger,
|
|
23
|
+
items: options.items,
|
|
24
|
+
positions: buildPositions(options.position, 'bottom-start'),
|
|
25
|
+
focusFirst,
|
|
26
|
+
isDivider: options.isDivider,
|
|
27
|
+
optionValue: options.optionValue,
|
|
28
|
+
optionLabel: options.optionLabel,
|
|
29
|
+
optionDescription: options.optionDescription,
|
|
30
|
+
optionDisabled: options.optionDisabled,
|
|
31
|
+
emit: options.emit,
|
|
32
|
+
onSelect: options.onSelect,
|
|
33
|
+
onClose: (returnFocus) => {
|
|
34
|
+
handle = null;
|
|
35
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
36
|
+
if (returnFocus)
|
|
37
|
+
trigger.focus();
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
if (handle)
|
|
41
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
42
|
+
}
|
|
43
|
+
// Click = pointer open (no item pre-highlighted); ↓/Enter/Space = keyboard open (first item).
|
|
44
|
+
const onTriggerClick = () => {
|
|
45
|
+
if (handle)
|
|
46
|
+
handle.close(true);
|
|
47
|
+
else
|
|
48
|
+
openMenu(false);
|
|
49
|
+
};
|
|
50
|
+
const onTriggerKeydown = (event) => {
|
|
51
|
+
if (handle)
|
|
52
|
+
return; // once open, the panel owns the keyboard
|
|
53
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
openMenu(true);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
trigger.addEventListener('click', onTriggerClick);
|
|
59
|
+
trigger.addEventListener('keydown', onTriggerKeydown);
|
|
60
|
+
return () => {
|
|
61
|
+
handle?.close(false);
|
|
62
|
+
trigger.removeEventListener('click', onTriggerClick);
|
|
63
|
+
trigger.removeEventListener('keydown', onTriggerKeydown);
|
|
64
|
+
trigger.removeAttribute('aria-haspopup');
|
|
65
|
+
trigger.removeAttribute('aria-expanded');
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/menu/menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GAKf,MAAM,gBAAgB,CAAC;AAoBxB,4DAA4D;AAC5D,MAAM,UAAU,IAAI,CAAe,OAAoB,EAAE,OAAuB;IAC9E,IAAI,MAAM,GAAsB,IAAI,CAAC;IAErC,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAE/C,SAAS,QAAQ,CAAC,UAAmB;QACnC,IAAI,MAAM;YAAE,OAAO;QACnB,MAAM,GAAG,aAAa,CAAI;YACxB,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC;YAC3D,UAAU;YACV,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,OAAO,EAAE,CAAC,WAAoB,EAAQ,EAAE;gBACtC,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;gBAC/C,IAAI,WAAW;oBAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YACnC,CAAC;SACF,CAAC,CAAC;QACH,IAAI,MAAM;YAAE,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;IAED,8FAA8F;IAC9F,MAAM,cAAc,GAAG,GAAS,EAAE;QAChC,IAAI,MAAM;YAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;;YAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAQ,EAAE;QACtD,IAAI,MAAM;YAAE,OAAO,CAAC,yCAAyC;QAC7D,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YAC5E,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAClD,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAEtD,OAAO,GAAS,EAAE;QAChB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QACrD,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACzD,OAAO,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;QACzC,OAAO,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Menubar>` — an app menu bar (File / Edit / View …), the WAI-ARIA **menubar** pattern. A
|
|
3
|
+
* `role=menubar` row of top-level `<button role=menuitem>`s; activating one opens a dropdown
|
|
4
|
+
* **Menu** — the same panel as the U3 `use:menu` (composed via `menu-core.openMenuPanel`, so
|
|
5
|
+
* the panel chrome, roving focus, typeahead, Esc/backdrop are all reused, not re-created).
|
|
6
|
+
*
|
|
7
|
+
* Keyboard (APG menubar): Left/Right rove the top items (wrap), Home/End jump, typeahead;
|
|
8
|
+
* **ArrowDown / Enter / Space open** the active menu (focused on its first item); while a menu
|
|
9
|
+
* is open, **Left/Right switch to the neighbour's menu** (the classic menubar feel); Esc closes
|
|
10
|
+
* and returns focus to the top item. A single roving tab stop.
|
|
11
|
+
*
|
|
12
|
+
* import Menubar from '@weave-framework/ui/menubar';
|
|
13
|
+
* <Menubar menus={{ [{ label: 'File', items: [{ value: 'new', label: 'New' }] }] }}
|
|
14
|
+
* onSelect={{ (v) => run(v) }} />
|
|
15
|
+
*/
|
|
16
|
+
import { type Signal } from '@weave-framework/runtime';
|
|
17
|
+
import { type MenuItem } from '../menu/menu-core.js';
|
|
18
|
+
export interface MenubarMenu {
|
|
19
|
+
/** Top-level label. */
|
|
20
|
+
label: string;
|
|
21
|
+
/** The dropdown items (reuses the Menu item model — `divider`, `disabled`, `description`). */
|
|
22
|
+
items: MenuItem[];
|
|
23
|
+
/** Disable this whole top item. */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface MenubarProps {
|
|
27
|
+
/** The top-level menus, left to right. */
|
|
28
|
+
menus: MenubarMenu[];
|
|
29
|
+
/** Called with the chosen item's value (or the whole item object). */
|
|
30
|
+
onSelect?: (value: string | MenuItem) => void;
|
|
31
|
+
/** Accessible name for the menubar. */
|
|
32
|
+
label?: string;
|
|
33
|
+
/** Extra classes, forwarded onto the container. */
|
|
34
|
+
class?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare const template: string;
|
|
37
|
+
export interface MenubarContext {
|
|
38
|
+
host: Signal<HTMLElement | null>;
|
|
39
|
+
menus: () => MenubarMenu[];
|
|
40
|
+
rootClass: () => string;
|
|
41
|
+
label: () => string | undefined;
|
|
42
|
+
expandedAttr: (index: number) => 'true' | 'false';
|
|
43
|
+
disabledAttr: (menu: MenubarMenu) => 'true' | undefined;
|
|
44
|
+
tabindexFor: (index: number) => number;
|
|
45
|
+
onTopClick: (index: number) => void;
|
|
46
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
47
|
+
}
|
|
48
|
+
export declare function setup(props: MenubarProps): MenubarContext;
|
|
49
|
+
//# sourceMappingURL=menubar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../src/menubar/menubar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAA8B,KAAK,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEnF,OAAO,EAAiC,KAAK,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAErG,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC;IAC9C,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,QAAQ,EAAE,MASb,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,WAAW,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,MAAM,GAAG,SAAS,CAAC;IACxD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,cAAc,CAuIzD"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Menubar>` — an app menu bar (File / Edit / View …), the WAI-ARIA **menubar** pattern. A
|
|
3
|
+
* `role=menubar` row of top-level `<button role=menuitem>`s; activating one opens a dropdown
|
|
4
|
+
* **Menu** — the same panel as the U3 `use:menu` (composed via `menu-core.openMenuPanel`, so
|
|
5
|
+
* the panel chrome, roving focus, typeahead, Esc/backdrop are all reused, not re-created).
|
|
6
|
+
*
|
|
7
|
+
* Keyboard (APG menubar): Left/Right rove the top items (wrap), Home/End jump, typeahead;
|
|
8
|
+
* **ArrowDown / Enter / Space open** the active menu (focused on its first item); while a menu
|
|
9
|
+
* is open, **Left/Right switch to the neighbour's menu** (the classic menubar feel); Esc closes
|
|
10
|
+
* and returns focus to the top item. A single roving tab stop.
|
|
11
|
+
*
|
|
12
|
+
* import Menubar from '@weave-framework/ui/menubar';
|
|
13
|
+
* <Menubar menus={{ [{ label: 'File', items: [{ value: 'new', label: 'New' }] }] }}
|
|
14
|
+
* onSelect={{ (v) => run(v) }} />
|
|
15
|
+
*/
|
|
16
|
+
import { signal, onMount, onDispose } from '@weave-framework/runtime';
|
|
17
|
+
import { listKeyManager } from '../cdk/index.js';
|
|
18
|
+
import { openMenuPanel, buildPositions } from '../menu/menu-core.js';
|
|
19
|
+
export const template = '<div class={{ rootClass() }} role="menubar" aria-label={{ label() }} ref={{ host }} on:keydown={{ onKeydown }}>' +
|
|
20
|
+
'@for (menu of menus(); track $index) {' +
|
|
21
|
+
'<button class="weave-menubar__item" type="button" role="menuitem" aria-haspopup="menu"' +
|
|
22
|
+
' aria-expanded={{ expandedAttr($index) }} aria-disabled={{ disabledAttr(menu) }}' +
|
|
23
|
+
' tabindex={{ tabindexFor($index) }} on:click={{ () => onTopClick($index) }}>' +
|
|
24
|
+
'{{ menu.label }}' +
|
|
25
|
+
'</button>' +
|
|
26
|
+
'}' +
|
|
27
|
+
'</div>';
|
|
28
|
+
export function setup(props) {
|
|
29
|
+
const host = signal(null);
|
|
30
|
+
const openIndex = signal(-1);
|
|
31
|
+
let handle = null;
|
|
32
|
+
let arrowListener = null;
|
|
33
|
+
const menus = () => props.menus ?? [];
|
|
34
|
+
const isDisabled = (menu) => !!menu.disabled;
|
|
35
|
+
const manager = listKeyManager(menus, {
|
|
36
|
+
orientation: 'horizontal',
|
|
37
|
+
wrap: true,
|
|
38
|
+
skipDisabled: true,
|
|
39
|
+
isDisabled,
|
|
40
|
+
typeahead: true,
|
|
41
|
+
getLabel: (m) => m.label,
|
|
42
|
+
});
|
|
43
|
+
const rovingIndex = () => {
|
|
44
|
+
const active = manager.activeIndex();
|
|
45
|
+
if (active >= 0)
|
|
46
|
+
return active;
|
|
47
|
+
const first = menus().findIndex((m) => !isDisabled(m));
|
|
48
|
+
return first >= 0 ? first : 0;
|
|
49
|
+
};
|
|
50
|
+
const topButtons = () => Array.from(host()?.querySelectorAll('.weave-menubar__item') ?? []);
|
|
51
|
+
const focusTop = (index) => {
|
|
52
|
+
topButtons()[index]?.focus();
|
|
53
|
+
};
|
|
54
|
+
// Next enabled top index in a direction, wrapping.
|
|
55
|
+
const nextEnabled = (from, step) => {
|
|
56
|
+
const list = menus();
|
|
57
|
+
const n = list.length;
|
|
58
|
+
for (let k = 1; k <= n; k++) {
|
|
59
|
+
const i = (((from + step * k) % n) + n) % n;
|
|
60
|
+
if (!isDisabled(list[i]))
|
|
61
|
+
return i;
|
|
62
|
+
}
|
|
63
|
+
return from;
|
|
64
|
+
};
|
|
65
|
+
// While a menu is open, Left/Right switch to the neighbour's menu. The dropdown panel is
|
|
66
|
+
// portaled (not a menubar descendant), so we catch these at the document (capture) level;
|
|
67
|
+
// the menu core ignores Left/Right, so there's no conflict.
|
|
68
|
+
const addArrowSwitch = () => {
|
|
69
|
+
if (arrowListener)
|
|
70
|
+
return;
|
|
71
|
+
arrowListener = (event) => {
|
|
72
|
+
if (openIndex() < 0)
|
|
73
|
+
return;
|
|
74
|
+
if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
openMenu(nextEnabled(openIndex(), event.key === 'ArrowRight' ? 1 : -1));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
document.addEventListener('keydown', arrowListener, true);
|
|
80
|
+
};
|
|
81
|
+
const removeArrowSwitch = () => {
|
|
82
|
+
if (arrowListener)
|
|
83
|
+
document.removeEventListener('keydown', arrowListener, true);
|
|
84
|
+
arrowListener = null;
|
|
85
|
+
};
|
|
86
|
+
function closeMenu(returnFocus) {
|
|
87
|
+
handle?.close(returnFocus);
|
|
88
|
+
}
|
|
89
|
+
function openMenu(index) {
|
|
90
|
+
const menu = menus()[index];
|
|
91
|
+
if (!menu || isDisabled(menu))
|
|
92
|
+
return;
|
|
93
|
+
handle?.close(false); // close any currently-open menu first (no focus bounce)
|
|
94
|
+
const btn = topButtons()[index];
|
|
95
|
+
if (!btn)
|
|
96
|
+
return;
|
|
97
|
+
manager.setActiveItem(index);
|
|
98
|
+
handle = openMenuPanel({
|
|
99
|
+
origin: btn,
|
|
100
|
+
items: menu.items,
|
|
101
|
+
positions: buildPositions('bottom-start', 'bottom-start'),
|
|
102
|
+
focusFirst: true, // a menubar always opens focused on the first item
|
|
103
|
+
onSelect: (value) => props.onSelect?.(value),
|
|
104
|
+
onClose: (returnFocus) => {
|
|
105
|
+
handle = null;
|
|
106
|
+
openIndex.set(-1);
|
|
107
|
+
removeArrowSwitch();
|
|
108
|
+
if (returnFocus)
|
|
109
|
+
focusTop(index);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
if (handle) {
|
|
113
|
+
openIndex.set(index);
|
|
114
|
+
addArrowSwitch();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const onTopClick = (index) => {
|
|
118
|
+
if (openIndex() === index)
|
|
119
|
+
closeMenu(true);
|
|
120
|
+
else
|
|
121
|
+
openMenu(index);
|
|
122
|
+
};
|
|
123
|
+
const onKeydown = (event) => {
|
|
124
|
+
if (manager.activeIndex() < 0)
|
|
125
|
+
manager.setActiveItem(rovingIndex());
|
|
126
|
+
if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
openMenu(manager.activeIndex());
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (manager.onKeydown(event)) {
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
focusTop(manager.activeIndex());
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
onMount(() => {
|
|
137
|
+
// Seed the roving tab stop to the first enabled item.
|
|
138
|
+
manager.setActiveItem(rovingIndex());
|
|
139
|
+
});
|
|
140
|
+
// Close any open dropdown when the menubar unmounts (the panel overlay is created outside
|
|
141
|
+
// the owner scope, so tie its teardown here — else panels leak across renders/tests).
|
|
142
|
+
onDispose(() => {
|
|
143
|
+
handle?.close(false);
|
|
144
|
+
removeArrowSwitch();
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
host,
|
|
148
|
+
menus,
|
|
149
|
+
rootClass: () => (props.class ? `weave-menubar ${props.class}` : 'weave-menubar'),
|
|
150
|
+
label: () => props.label,
|
|
151
|
+
expandedAttr: (index) => (openIndex() === index ? 'true' : 'false'),
|
|
152
|
+
disabledAttr: (menu) => (isDisabled(menu) ? 'true' : undefined),
|
|
153
|
+
tabindexFor: (index) => {
|
|
154
|
+
if (isDisabled(menus()[index]))
|
|
155
|
+
return -1;
|
|
156
|
+
return index === rovingIndex() ? 0 : -1;
|
|
157
|
+
},
|
|
158
|
+
onTopClick,
|
|
159
|
+
onKeydown,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=menubar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menubar.js","sourceRoot":"","sources":["../../src/menubar/menubar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Paginator>` — page navigation over a total item count.
|
|
3
|
+
*
|
|
4
|
+
* Prev / next arrows around a **windowed** run of page buttons: the first and last
|
|
5
|
+
* page are always shown, a window of `siblingCount` pages surrounds the current one,
|
|
6
|
+
* and the gaps collapse to an ellipsis (…) — so 100 pages read as `‹ 1 … 5 6 7 … 100 ›`.
|
|
7
|
+
* The active page takes the ink fill. A **"N–M of T" range label**, a **manual
|
|
8
|
+
* "go to page" input**, and an optional **page-size menu** round it out.
|
|
9
|
+
*
|
|
10
|
+
* Pure + controlled: pass `length` (total items), `pageSize`, and `pageIndex` (0-based);
|
|
11
|
+
* every action calls `onPage({ pageIndex, pageSize, length })` — the paginator computes
|
|
12
|
+
* the page count, the window and the range label, and never fetches data itself.
|
|
13
|
+
*
|
|
14
|
+
* import Paginator from '@weave-framework/ui/paginator';
|
|
15
|
+
* <Paginator length={{ 973 }} pageSize={{ 12 }} pageIndex={{ page() }}
|
|
16
|
+
* pageSizeOptions={{ [12, 24, 48] }} onPage={{ (e) => setPage(e.pageIndex) }} />
|
|
17
|
+
*/
|
|
18
|
+
import { type Signal } from '@weave-framework/runtime';
|
|
19
|
+
/** A page-size option shown in the composed Select. */
|
|
20
|
+
interface SizeOption {
|
|
21
|
+
value: string;
|
|
22
|
+
label: string;
|
|
23
|
+
}
|
|
24
|
+
export interface PageEvent {
|
|
25
|
+
pageIndex: number;
|
|
26
|
+
pageSize: number;
|
|
27
|
+
length: number;
|
|
28
|
+
}
|
|
29
|
+
export interface PaginatorProps {
|
|
30
|
+
/** Total number of items. */
|
|
31
|
+
length: number;
|
|
32
|
+
/** Items per page. */
|
|
33
|
+
pageSize: number;
|
|
34
|
+
/** Current page, 0-based. */
|
|
35
|
+
pageIndex: number;
|
|
36
|
+
/** Called with the next state on any navigation / size change. */
|
|
37
|
+
onPage?: (event: PageEvent) => void;
|
|
38
|
+
/** If set, shows a page-size menu with these options. */
|
|
39
|
+
pageSizeOptions?: number[];
|
|
40
|
+
/** Pages shown on each side of the current one before an ellipsis. Default 1. */
|
|
41
|
+
siblingCount?: number;
|
|
42
|
+
/** Pages pinned at each end. Default 1. */
|
|
43
|
+
boundaryCount?: number;
|
|
44
|
+
/** Show the "N–M of T" range label. Default true. */
|
|
45
|
+
showRange?: boolean;
|
|
46
|
+
/** Show the manual "go to page" input. Default true. */
|
|
47
|
+
showJump?: boolean;
|
|
48
|
+
/** Disable the whole paginator. */
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
/** Accessible name for the nav landmark. Default "Pagination". */
|
|
51
|
+
label?: string;
|
|
52
|
+
/** Label before the jump input. Default "Go to". */
|
|
53
|
+
jumpLabel?: string;
|
|
54
|
+
/** Extra classes, forwarded onto the nav. */
|
|
55
|
+
class?: string;
|
|
56
|
+
}
|
|
57
|
+
type PageCell = number | 'ellipsis';
|
|
58
|
+
export declare const template: string;
|
|
59
|
+
export interface PaginatorContext {
|
|
60
|
+
host: Signal<Element | null>;
|
|
61
|
+
rootClass: () => string;
|
|
62
|
+
navLabel: () => string;
|
|
63
|
+
cells: () => PageCell[];
|
|
64
|
+
isPage: (cell: PageCell) => boolean;
|
|
65
|
+
pageLabel: (cell: PageCell) => string;
|
|
66
|
+
pageCurrent: (cell: PageCell) => string | undefined;
|
|
67
|
+
pageVariant: (cell: PageCell) => string;
|
|
68
|
+
isDisabled: () => boolean;
|
|
69
|
+
goTo: (page: number) => void;
|
|
70
|
+
prev: () => void;
|
|
71
|
+
next: () => void;
|
|
72
|
+
prevDisabled: () => boolean;
|
|
73
|
+
nextDisabled: () => boolean;
|
|
74
|
+
showRange: () => boolean;
|
|
75
|
+
rangeText: () => string;
|
|
76
|
+
showJump: () => boolean;
|
|
77
|
+
jumpLabel: () => string;
|
|
78
|
+
jumpValue: () => string;
|
|
79
|
+
pageCount: () => number;
|
|
80
|
+
currentPage: () => number;
|
|
81
|
+
onJumpKeydown: (event: KeyboardEvent) => void;
|
|
82
|
+
hasSizeOptions: () => boolean;
|
|
83
|
+
sizeOptions: () => SizeOption[];
|
|
84
|
+
sizeValue: () => string;
|
|
85
|
+
onSizeChange: (value: string) => void;
|
|
86
|
+
}
|
|
87
|
+
export declare function setup(props: PaginatorProps): PaginatorContext;
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=paginator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator.d.ts","sourceRoot":"","sources":["../../src/paginator/paginator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Paginator>` — page navigation over a total item count.
|
|
3
|
+
*
|
|
4
|
+
* Prev / next arrows around a **windowed** run of page buttons: the first and last
|
|
5
|
+
* page are always shown, a window of `siblingCount` pages surrounds the current one,
|
|
6
|
+
* and the gaps collapse to an ellipsis (…) — so 100 pages read as `‹ 1 … 5 6 7 … 100 ›`.
|
|
7
|
+
* The active page takes the ink fill. A **"N–M of T" range label**, a **manual
|
|
8
|
+
* "go to page" input**, and an optional **page-size menu** round it out.
|
|
9
|
+
*
|
|
10
|
+
* Pure + controlled: pass `length` (total items), `pageSize`, and `pageIndex` (0-based);
|
|
11
|
+
* every action calls `onPage({ pageIndex, pageSize, length })` — the paginator computes
|
|
12
|
+
* the page count, the window and the range label, and never fetches data itself.
|
|
13
|
+
*
|
|
14
|
+
* import Paginator from '@weave-framework/ui/paginator';
|
|
15
|
+
* <Paginator length={{ 973 }} pageSize={{ 12 }} pageIndex={{ page() }}
|
|
16
|
+
* pageSizeOptions={{ [12, 24, 48] }} onPage={{ (e) => setPage(e.pageIndex) }} />
|
|
17
|
+
*/
|
|
18
|
+
import { signal } from '@weave-framework/runtime';
|
|
19
|
+
export const template = '<nav class={{ rootClass() }} ref={{ host }} aria-label={{ navLabel() }}>' +
|
|
20
|
+
'<Button variant="ghost" class="weave-paginator__nav" label="Previous page"' +
|
|
21
|
+
' disabled={{ prevDisabled() }} on:click={{ prev }}>‹</Button>' +
|
|
22
|
+
'@for (cell of cells(); track $index) {' +
|
|
23
|
+
'@if (isPage(cell)) {' +
|
|
24
|
+
'<Button variant={{ pageVariant(cell) }} class="weave-paginator__page" label={{ pageLabel(cell) }}' +
|
|
25
|
+
' ariaCurrent={{ pageCurrent(cell) }} disabled={{ isDisabled() }}' +
|
|
26
|
+
' on:click={{ () => goTo(cell) }}>{{ cell }}</Button>' +
|
|
27
|
+
'}' +
|
|
28
|
+
'@if (!isPage(cell)) {<span class="weave-paginator__ellipsis" aria-hidden="true">…</span>}' +
|
|
29
|
+
'}' +
|
|
30
|
+
'<Button variant="ghost" class="weave-paginator__nav" label="Next page"' +
|
|
31
|
+
' disabled={{ nextDisabled() }} on:click={{ next }}>›</Button>' +
|
|
32
|
+
'@if (showRange()) {<span class="weave-paginator__range">{{ rangeText() }}</span>}' +
|
|
33
|
+
'@if (showJump()) {' +
|
|
34
|
+
'<span class="weave-paginator__jump">' +
|
|
35
|
+
'<label class="weave-paginator__jump-label">{{ jumpLabel() }}</label>' +
|
|
36
|
+
'<Input type="number" value={{ jumpValue() }} disabled={{ isDisabled() }} label="Go to page"' +
|
|
37
|
+
' class="weave-paginator__jump-field" on:keydown={{ onJumpKeydown }} />' +
|
|
38
|
+
'</span>' +
|
|
39
|
+
'}' +
|
|
40
|
+
'@if (hasSizeOptions()) {' +
|
|
41
|
+
'<Select options={{ sizeOptions() }} value={{ sizeValue() }} onChange={{ onSizeChange }}' +
|
|
42
|
+
' disabled={{ isDisabled() }} label="Items per page" class="weave-paginator__size" />' +
|
|
43
|
+
'}' +
|
|
44
|
+
'</nav>';
|
|
45
|
+
function range(start, end) {
|
|
46
|
+
const out = [];
|
|
47
|
+
for (let i = start; i <= end; i += 1)
|
|
48
|
+
out.push(i);
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
// The windowed page run: boundary pages pinned at each end, `siblings` around the
|
|
52
|
+
// current page, gaps collapsed to a single 'ellipsis'. A one-page gap shows the page
|
|
53
|
+
// instead of an ellipsis (never "1 … 3" when "1 2 3" fits).
|
|
54
|
+
function buildCells(current, total, siblings, boundary) {
|
|
55
|
+
const totalNumbers = siblings * 2 + 3 + boundary * 2;
|
|
56
|
+
if (total <= totalNumbers + 2)
|
|
57
|
+
return range(1, total);
|
|
58
|
+
const leftSibling = Math.max(current - siblings, boundary + 2);
|
|
59
|
+
const rightSibling = Math.min(current + siblings, total - boundary - 1);
|
|
60
|
+
const showLeftEllipsis = leftSibling > boundary + 2;
|
|
61
|
+
const showRightEllipsis = rightSibling < total - boundary - 1;
|
|
62
|
+
const cells = [...range(1, boundary)];
|
|
63
|
+
if (showLeftEllipsis)
|
|
64
|
+
cells.push('ellipsis');
|
|
65
|
+
else
|
|
66
|
+
cells.push(...range(boundary + 1, leftSibling - 1));
|
|
67
|
+
cells.push(...range(leftSibling, rightSibling));
|
|
68
|
+
if (showRightEllipsis)
|
|
69
|
+
cells.push('ellipsis');
|
|
70
|
+
else
|
|
71
|
+
cells.push(...range(rightSibling + 1, total - boundary));
|
|
72
|
+
cells.push(...range(total - boundary + 1, total));
|
|
73
|
+
return cells;
|
|
74
|
+
}
|
|
75
|
+
export function setup(props) {
|
|
76
|
+
const host = signal(null);
|
|
77
|
+
const length = () => Math.max(0, props.length ?? 0);
|
|
78
|
+
const pageSize = () => Math.max(1, props.pageSize ?? 1);
|
|
79
|
+
const pageCount = () => Math.max(1, Math.ceil(length() / pageSize()));
|
|
80
|
+
// Clamp the incoming index to the valid range.
|
|
81
|
+
const pageIndex = () => Math.min(Math.max(0, props.pageIndex ?? 0), pageCount() - 1);
|
|
82
|
+
const currentPage = () => pageIndex() + 1;
|
|
83
|
+
const disabled = () => !!props.disabled;
|
|
84
|
+
const emit = (nextIndex, nextSize) => {
|
|
85
|
+
props.onPage?.({ pageIndex: nextIndex, pageSize: nextSize, length: length() });
|
|
86
|
+
};
|
|
87
|
+
const goToIndex = (index) => {
|
|
88
|
+
if (disabled())
|
|
89
|
+
return;
|
|
90
|
+
const clamped = Math.min(Math.max(0, index), pageCount() - 1);
|
|
91
|
+
if (clamped === pageIndex())
|
|
92
|
+
return;
|
|
93
|
+
emit(clamped, pageSize());
|
|
94
|
+
};
|
|
95
|
+
const changeSize = (size) => {
|
|
96
|
+
if (disabled() || size === pageSize())
|
|
97
|
+
return;
|
|
98
|
+
// Keep the first visible item on screen when the page size changes.
|
|
99
|
+
const firstItem = pageIndex() * pageSize();
|
|
100
|
+
const nextIndex = Math.floor(firstItem / size);
|
|
101
|
+
props.onPage?.({ pageIndex: nextIndex, pageSize: size, length: length() });
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
host,
|
|
105
|
+
rootClass: () => {
|
|
106
|
+
const parts = ['weave-paginator'];
|
|
107
|
+
if (disabled())
|
|
108
|
+
parts.push('weave-paginator--disabled');
|
|
109
|
+
if (props.class)
|
|
110
|
+
parts.push(props.class);
|
|
111
|
+
return parts.join(' ');
|
|
112
|
+
},
|
|
113
|
+
navLabel: () => props.label ?? 'Pagination',
|
|
114
|
+
cells: () => buildCells(currentPage(), pageCount(), props.siblingCount ?? 1, props.boundaryCount ?? 1),
|
|
115
|
+
isPage: (cell) => typeof cell === 'number',
|
|
116
|
+
pageLabel: (cell) => `Go to page ${cell}`,
|
|
117
|
+
pageCurrent: (cell) => (cell === currentPage() ? 'page' : undefined),
|
|
118
|
+
// Active page = the Button's ink-fill primary variant; others = ghost.
|
|
119
|
+
pageVariant: (cell) => (cell === currentPage() ? 'primary' : 'ghost'),
|
|
120
|
+
isDisabled: () => disabled(),
|
|
121
|
+
goTo: (page) => goToIndex(page - 1),
|
|
122
|
+
prev: () => goToIndex(pageIndex() - 1),
|
|
123
|
+
next: () => goToIndex(pageIndex() + 1),
|
|
124
|
+
prevDisabled: () => disabled() || pageIndex() <= 0,
|
|
125
|
+
nextDisabled: () => disabled() || pageIndex() >= pageCount() - 1,
|
|
126
|
+
showRange: () => props.showRange !== false,
|
|
127
|
+
rangeText: () => {
|
|
128
|
+
const total = length();
|
|
129
|
+
if (total === 0)
|
|
130
|
+
return '0 of 0';
|
|
131
|
+
const start = pageIndex() * pageSize() + 1;
|
|
132
|
+
const end = Math.min(total, (pageIndex() + 1) * pageSize());
|
|
133
|
+
return `${start}–${end} of ${total}`;
|
|
134
|
+
},
|
|
135
|
+
showJump: () => props.showJump !== false,
|
|
136
|
+
jumpLabel: () => props.jumpLabel ?? 'Go to',
|
|
137
|
+
jumpValue: () => String(currentPage()),
|
|
138
|
+
pageCount,
|
|
139
|
+
currentPage,
|
|
140
|
+
// The jump field is a composed <Input>; on Enter, read the typed value off the
|
|
141
|
+
// native input the event bubbled from and navigate (clamped).
|
|
142
|
+
onJumpKeydown: (event) => {
|
|
143
|
+
if (event.key !== 'Enter')
|
|
144
|
+
return;
|
|
145
|
+
const input = event.target.closest('.weave-input')?.querySelector('input') ?? null;
|
|
146
|
+
const raw = input ? input.value : event.target.value;
|
|
147
|
+
const target = parseInt(raw, 10);
|
|
148
|
+
if (Number.isFinite(target))
|
|
149
|
+
goToIndex(target - 1);
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
},
|
|
152
|
+
hasSizeOptions: () => (props.pageSizeOptions?.length ?? 0) > 0,
|
|
153
|
+
// Page-size options + value for the composed <Select>.
|
|
154
|
+
sizeOptions: () => (props.pageSizeOptions ?? []).map((n) => ({ value: String(n), label: `${n} / page` })),
|
|
155
|
+
sizeValue: () => String(pageSize()),
|
|
156
|
+
onSizeChange: (value) => changeSize(Number(value)),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=paginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginator.js","sourceRoot":"","sources":["../../src/paginator/paginator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type MenuPosition } from '../shared/positions.js';
|
|
2
|
+
/** A custom editor: build the DOM + expose how to read its value + which element to focus. */
|
|
3
|
+
export interface PopoverEditor {
|
|
4
|
+
element: HTMLElement;
|
|
5
|
+
/** Read the current editor value (called on commit). */
|
|
6
|
+
read: () => string;
|
|
7
|
+
/** The element to focus on open (defaults to `element`). */
|
|
8
|
+
focusTarget?: HTMLElement;
|
|
9
|
+
}
|
|
10
|
+
export interface PopoverEditConfig {
|
|
11
|
+
/** Current value getter (seeds the editor on open). */
|
|
12
|
+
value: () => string;
|
|
13
|
+
/** Called with the next value on commit (Enter / click-away). */
|
|
14
|
+
onCommit: (next: string) => void;
|
|
15
|
+
/** Build a custom editor (default: a text field). */
|
|
16
|
+
editor?: (value: string) => PopoverEditor;
|
|
17
|
+
/** Placeholder for the default text editor. */
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
/** Accessible name for the default editor. */
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Popover position relative to the host. Default `'bottom-start'`. */
|
|
22
|
+
position?: MenuPosition;
|
|
23
|
+
/** Disable editing (boolean or a reactive getter). */
|
|
24
|
+
disabled?: boolean | (() => boolean);
|
|
25
|
+
}
|
|
26
|
+
export interface PopoverEditRef {
|
|
27
|
+
open(): void;
|
|
28
|
+
close(): void;
|
|
29
|
+
destroy(): void;
|
|
30
|
+
}
|
|
31
|
+
/** Attach inline popover editing to `host`. Returns a ref (also a cleanup contract for Weave). */
|
|
32
|
+
export declare function popoverEdit(host: HTMLElement, config: PopoverEditConfig): PopoverEditRef;
|
|
33
|
+
//# sourceMappingURL=popover-edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover-edit.d.ts","sourceRoot":"","sources":["../../src/popover-edit/popover-edit.ts"],"names":[],"mappings":"AAcA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3E,8FAA8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,wDAAwD;IACxD,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,qDAAqD;IACrD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,aAAa,CAAC;IAC1C,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,cAAc,CA4FxF"}
|