@nvidia-elements/core 2.6.1 → 2.7.1
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/CHANGELOG.md +14 -0
- package/dist/accordion/accordion2.js +4 -4
- package/dist/alert/alert-group2.js +1 -1
- package/dist/alert/alert2.js +1 -1
- package/dist/avatar/avatar-group2.js +1 -1
- package/dist/avatar/avatar2.js +1 -1
- package/dist/badge/badge2.js +1 -1
- package/dist/breadcrumb/breadcrumb2.js +1 -1
- package/dist/bundles/index.d.ts +37 -11
- package/dist/bundles/index.js +5 -5
- package/dist/button/button2.js +1 -1
- package/dist/button-group/button-group2.js +1 -1
- package/dist/card/card2.js +4 -4
- package/dist/chat-message/chat-message2.js +1 -1
- package/dist/checkbox/checkbox-group2.js +1 -1
- package/dist/checkbox/checkbox2.js +1 -1
- package/dist/color/color2.js +1 -1
- package/dist/combobox/combobox2.js +1 -1
- package/dist/copy-button/copy-button2.js +1 -1
- package/dist/custom-elements-jsx.d.ts +6 -30
- package/dist/custom-elements-vue.d.ts +6 -30
- package/dist/custom-elements.json +618 -330
- package/dist/data.html.json +4 -20
- package/dist/data.snippets.json +42 -42
- package/dist/date/date2.js +1 -1
- package/dist/datetime/datetime2.js +1 -1
- package/dist/dialog/dialog-footer2.js +1 -1
- package/dist/dialog/dialog-header2.js +1 -1
- package/dist/dialog/dialog2.js +1 -1
- package/dist/divider/divider.examples.js.map +1 -1
- package/dist/divider/divider.examples.json +1 -1
- package/dist/divider/divider2.js +1 -1
- package/dist/dot/dot2.js +1 -1
- package/dist/drawer/drawer-content2.js +1 -1
- package/dist/drawer/drawer-footer2.js +1 -1
- package/dist/drawer/drawer-header2.js +1 -1
- package/dist/drawer/drawer2.js +1 -1
- package/dist/dropdown/dropdown-footer2.js +1 -1
- package/dist/dropdown/dropdown-header2.js +1 -1
- package/dist/dropdown/dropdown2.js +1 -1
- package/dist/dropdown-group/dropdown-group.js +1 -1
- package/dist/dropzone/dropzone2.js +1 -1
- package/dist/file/file2.js +1 -1
- package/dist/format-bytes/format-bytes2.js +1 -1
- package/dist/format-datetime/format-datetime2.js +1 -1
- package/dist/format-number/format-number2.js +1 -1
- package/dist/format-relative-time/format-relative-time2.js +1 -1
- package/dist/format-truncate/format-truncate2.js +1 -1
- package/dist/forms/actions.examples.js.map +1 -1
- package/dist/forms/actions.examples.json +1 -1
- package/dist/forms/control/control2.js +1 -1
- package/dist/forms/control-group/control-group2.js +1 -1
- package/dist/forms/control-message/control-message2.js +3 -3
- package/dist/forms/control-message/control-message2.js.map +1 -1
- package/dist/gauge/gauge2.js +1 -1
- package/dist/grid/cell/cell2.js +1 -1
- package/dist/grid/column/column2.js +1 -1
- package/dist/grid/footer/footer2.js +1 -1
- package/dist/grid/grid2.js +1 -1
- package/dist/grid/header/header2.js +1 -1
- package/dist/grid/placeholder/placeholder2.js +1 -1
- package/dist/grid/row/row2.js +1 -1
- package/dist/icon/define.js +15 -1
- package/dist/icon/define.js.map +1 -1
- package/dist/icon/icon2.js +2 -2
- package/dist/icon/icons/bell-solid.js +6 -0
- package/dist/icon/icons/bell-solid.js.map +1 -0
- package/dist/icon/icons/bell.js +1 -1
- package/dist/icon/icons/book-solid.js +6 -0
- package/dist/icon/icons/book-solid.js.map +1 -0
- package/dist/icon/icons/bookmark-solid.js +6 -0
- package/dist/icon/icons/bookmark-solid.js.map +1 -0
- package/dist/icon/icons/bookmark.js +1 -1
- package/dist/icon/icons/caret.js +1 -1
- package/dist/icon/icons/chat-bubble-solid.js +6 -0
- package/dist/icon/icons/chat-bubble-solid.js.map +1 -0
- package/dist/icon/icons/check-badge-solid.js +6 -0
- package/dist/icon/icons/check-badge-solid.js.map +1 -0
- package/dist/icon/icons/checkmark-circle-solid.js +6 -0
- package/dist/icon/icons/checkmark-circle-solid.js.map +1 -0
- package/dist/icon/icons/checkmark-circle.js +1 -1
- package/dist/icon/icons/circle-angled-line-solid.js +6 -0
- package/dist/icon/icons/circle-angled-line-solid.js.map +1 -0
- package/dist/icon/icons/connect-node.js +1 -1
- package/dist/icon/icons/delete-node.js +1 -1
- package/dist/icon/icons/delete-solid.js +6 -0
- package/dist/icon/icons/delete-solid.js.map +1 -0
- package/dist/icon/icons/dock-none.js +1 -1
- package/dist/icon/icons/dot-solid.js +6 -0
- package/dist/icon/icons/dot-solid.js.map +1 -0
- package/dist/icon/icons/dot.js +1 -1
- package/dist/icon/icons/exclamation-circle-solid.js +6 -0
- package/dist/icon/icons/exclamation-circle-solid.js.map +1 -0
- package/dist/icon/icons/exclamation-circle.js +1 -1
- package/dist/icon/icons/exclamation-mark.js +1 -1
- package/dist/icon/icons/exclamation-triangle-solid.js +6 -0
- package/dist/icon/icons/exclamation-triangle-solid.js.map +1 -0
- package/dist/icon/icons/exclamation-triangle.js +1 -1
- package/dist/icon/icons/face-smile-solid.js +6 -0
- package/dist/icon/icons/face-smile-solid.js.map +1 -0
- package/dist/icon/icons/fast-forward-10.js +1 -1
- package/dist/icon/icons/fast-forward.js +1 -1
- package/dist/icon/icons/filter-solid.js +6 -0
- package/dist/icon/icons/filter-solid.js.map +1 -0
- package/dist/icon/icons/filter.js +1 -1
- package/dist/icon/icons/flag-solid.js +6 -0
- package/dist/icon/icons/flag-solid.js.map +1 -0
- package/dist/icon/icons/flag.js +1 -1
- package/dist/icon/icons/gear-solid.js +6 -0
- package/dist/icon/icons/gear-solid.js.map +1 -0
- package/dist/icon/icons/{globe-alt-stroke.js → globe-alt.js} +2 -2
- package/dist/icon/icons/globe-alt.js.map +1 -0
- package/dist/icon/icons/home-solid.js +6 -0
- package/dist/icon/icons/home-solid.js.map +1 -0
- package/dist/icon/icons/hourglass-end.js +1 -1
- package/dist/icon/icons/hourglass-mid.js +1 -1
- package/dist/icon/icons/hourglass-start.js +1 -1
- package/dist/icon/icons/information-circle-solid.js +6 -0
- package/dist/icon/icons/information-circle-solid.js.map +1 -0
- package/dist/icon/icons/{information-circle-stroke.js → information-circle.js} +2 -2
- package/dist/icon/icons/information-circle.js.map +1 -0
- package/dist/icon/icons/lightning-bolt-solid.js +6 -0
- package/dist/icon/icons/lightning-bolt-solid.js.map +1 -0
- package/dist/icon/icons/lock-solid.js +6 -0
- package/dist/icon/icons/lock-solid.js.map +1 -0
- package/dist/icon/icons/map-drives.js +1 -1
- package/dist/icon/icons/markdown.js +1 -1
- package/dist/icon/icons/minus-circle-solid.js +6 -0
- package/dist/icon/icons/minus-circle-solid.js.map +1 -0
- package/dist/icon/icons/multiselect.js +1 -1
- package/dist/icon/icons/numbers.js +1 -1
- package/dist/icon/icons/pause.js +1 -1
- package/dist/icon/icons/person-3.js +1 -1
- package/dist/icon/icons/person-solid.js +6 -0
- package/dist/icon/icons/person-solid.js.map +1 -0
- package/dist/icon/icons/pin-solid.js +6 -0
- package/dist/icon/icons/pin-solid.js.map +1 -0
- package/dist/icon/icons/play.js +1 -1
- package/dist/icon/icons/plus-circle-solid.js +6 -0
- package/dist/icon/icons/plus-circle-solid.js.map +1 -0
- package/dist/icon/icons/{pointer-stroke.js → pointer-solid.js} +2 -2
- package/dist/icon/icons/pointer-solid.js.map +1 -0
- package/dist/icon/icons/priority-high.js +1 -1
- package/dist/icon/icons/priority-low.js +1 -1
- package/dist/icon/icons/priority-medium.js +1 -1
- package/dist/icon/icons/question-mark-circle-solid.js +6 -0
- package/dist/icon/icons/question-mark-circle-solid.js.map +1 -0
- package/dist/icon/icons/question-mark-circle.js +1 -1
- package/dist/icon/icons/rewind-10.js +1 -1
- package/dist/icon/icons/rewind.js +1 -1
- package/dist/icon/icons/running.js +1 -1
- package/dist/icon/icons/soundwave.js +1 -1
- package/dist/icon/icons/sparkles-solid.js +6 -0
- package/dist/icon/icons/sparkles-solid.js.map +1 -0
- package/dist/icon/icons/star.js +1 -1
- package/dist/icon/icons/stop.js +1 -1
- package/dist/icon/icons/thumb-solid.js +6 -0
- package/dist/icon/icons/thumb-solid.js.map +1 -0
- package/dist/icon/icons/thumb.js +1 -1
- package/dist/icon/icons/transparent-box.js +1 -1
- package/dist/icon/icons/unlock-solid.js +6 -0
- package/dist/icon/icons/unlock-solid.js.map +1 -0
- package/dist/icon/icons/volume-solid.js +6 -0
- package/dist/icon/icons/volume-solid.js.map +1 -0
- package/dist/icon/icons/wrench-solid.js +6 -0
- package/dist/icon/icons/wrench-solid.js.map +1 -0
- package/dist/icon/icons/x-circle-solid.js +6 -0
- package/dist/icon/icons/x-circle-solid.js.map +1 -0
- package/dist/icon/icons/x-circle.js +1 -1
- package/dist/icon/icons.d.ts +36 -11
- package/dist/icon/icons.js +35 -12
- package/dist/icon/icons.js.map +1 -1
- package/dist/icon/index.js +3 -3
- package/dist/icon/server.js +71 -48
- package/dist/icon/server.js.map +1 -1
- package/dist/icon-button/icon-button.examples.js.map +1 -1
- package/dist/icon-button/icon-button.examples.json +1 -1
- package/dist/icon-button/icon-button2.js +1 -1
- package/dist/index.js +1 -1
- package/dist/input/input-group2.js +1 -1
- package/dist/input/input2.js +1 -1
- package/dist/internal/controllers/gesture.controller.d.ts +65 -0
- package/dist/internal/controllers/gesture.controller.examples.js +6 -0
- package/dist/internal/controllers/gesture.controller.examples.js.map +1 -0
- package/dist/internal/controllers/gesture.controller.examples.json +16 -0
- package/dist/internal/controllers/gesture.controller.js +235 -0
- package/dist/internal/controllers/gesture.controller.js.map +1 -0
- package/dist/internal/controllers/keynav-spatial.controller.d.ts +24 -0
- package/dist/internal/controllers/keynav-spatial.controller.js +75 -0
- package/dist/internal/controllers/keynav-spatial.controller.js.map +1 -0
- package/dist/internal/controllers/popover.examples.js.map +1 -1
- package/dist/internal/controllers/popover.examples.json +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.js +30 -29
- package/dist/internal/services/global.service.js +1 -1
- package/dist/internal/types/index.js +4 -4
- package/dist/internal/types/index.js.map +1 -1
- package/dist/logo/logo2.js +1 -1
- package/dist/menu/menu-item2.js +1 -1
- package/dist/menu/menu2.js +1 -1
- package/dist/month/month2.js +1 -1
- package/dist/notification/notification-group2.js +1 -1
- package/dist/notification/notification2.js +1 -1
- package/dist/page/page-panel/page-panel-content2.js +1 -1
- package/dist/page/page-panel/page-panel-footer2.js +1 -1
- package/dist/page/page-panel/page-panel-header2.js +1 -1
- package/dist/page/page-panel/page-panel2.js +1 -1
- package/dist/page/page.examples.js.map +1 -1
- package/dist/page/page.examples.json +3 -3
- package/dist/page/page2.js +1 -1
- package/dist/page-header/page-header2.js +1 -1
- package/dist/page-loader/page-loader2.js +1 -1
- package/dist/pagination/pagination2.js +1 -1
- package/dist/panel/panel2.js +4 -4
- package/dist/password/password2.js +1 -1
- package/dist/preferences-input/preferences-input2.js +1 -1
- package/dist/progress-bar/progress-bar2.js +1 -1
- package/dist/progress-ring/progress-ring2.js +1 -1
- package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
- package/dist/pulse/pulse2.js +1 -1
- package/dist/radio/radio-group2.js +1 -1
- package/dist/radio/radio2.js +1 -1
- package/dist/range/range2.js +1 -1
- package/dist/resize-handle/resize-handle.d.ts +1 -0
- package/dist/resize-handle/resize-handle2.js +42 -23
- package/dist/resize-handle/resize-handle2.js.map +1 -1
- package/dist/search/search2.js +1 -1
- package/dist/select/select2.js +1 -1
- package/dist/skeleton/skeleton2.js +1 -1
- package/dist/sort-button/sort-button2.js +1 -1
- package/dist/sparkline/sparkline2.js +1 -1
- package/dist/star-rating/star-rating2.js +1 -1
- package/dist/steps/steps2.js +2 -2
- package/dist/switch/switch-group2.js +1 -1
- package/dist/switch/switch2.js +1 -1
- package/dist/tabs/tabs-group2.js +1 -1
- package/dist/tabs/tabs2.js +2 -2
- package/dist/tag/tag2.js +1 -1
- package/dist/textarea/textarea2.js +1 -1
- package/dist/time/time2.js +1 -1
- package/dist/toast/toast2.js +1 -1
- package/dist/toggletip/toggletip-footer2.js +1 -1
- package/dist/toggletip/toggletip-header2.js +1 -1
- package/dist/toggletip/toggletip2.js +1 -1
- package/dist/toolbar/toolbar2.js +1 -1
- package/dist/tooltip/tooltip.examples.js.map +1 -1
- package/dist/tooltip/tooltip.examples.json +1 -1
- package/dist/tooltip/tooltip2.js +1 -1
- package/dist/tree/tree-node2.js +1 -1
- package/dist/tree/tree2.js +1 -1
- package/dist/week/week2.js +1 -1
- package/package.json +23 -1
- package/dist/icon/icons/bell-stroke.js +0 -6
- package/dist/icon/icons/bell-stroke.js.map +0 -1
- package/dist/icon/icons/bookmark-stroke.js +0 -6
- package/dist/icon/icons/bookmark-stroke.js.map +0 -1
- package/dist/icon/icons/dot-stroke.js +0 -6
- package/dist/icon/icons/dot-stroke.js.map +0 -1
- package/dist/icon/icons/filter-stroke.js +0 -6
- package/dist/icon/icons/filter-stroke.js.map +0 -1
- package/dist/icon/icons/flag-stroke.js +0 -6
- package/dist/icon/icons/flag-stroke.js.map +0 -1
- package/dist/icon/icons/globe-alt-stroke.js.map +0 -1
- package/dist/icon/icons/information-circle-stroke.js.map +0 -1
- package/dist/icon/icons/pointer-stroke.js.map +0 -1
- package/dist/icon/icons/question-mark-circle-stroke.js +0 -6
- package/dist/icon/icons/question-mark-circle-stroke.js.map +0 -1
- package/dist/icon/icons/thumb-stroke.js +0 -6
- package/dist/icon/icons/thumb-stroke.js.map +0 -1
- package/dist/internal/controllers/type-touch.controller.d.ts +0 -22
- package/dist/internal/controllers/type-touch.controller.examples.js +0 -6
- package/dist/internal/controllers/type-touch.controller.examples.js.map +0 -1
- package/dist/internal/controllers/type-touch.controller.examples.json +0 -16
- package/dist/internal/controllers/type-touch.controller.js +0 -58
- package/dist/internal/controllers/type-touch.controller.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon-button.examples.js","names":[],"sources":["../../src/icon-button/icon-button.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/icon-button/define.js';\n\nexport default {\n title: 'Elements/Icon Button',\n component: 'nve-icon-button'\n};\n\n/**\n * @summary Basic icon button for compact actions and toolbar controls with minimal visual footprint.\n */\nexport const Default = {\n render: () => html`\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n `\n};\n\n/**\n * @summary Icon buttons with different interaction styles including default, emphasis, destructive, and disabled states.\n */\nexport const Interactions = {\n render: () => html`\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button disabled icon-name=\"menu\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons in different sizes (small, medium, large) for varying contexts and visual hierarchy.\n * @tags test-case\n */\nexport const Size = {\n render: () => html`\n <nve-icon-button size=\"sm\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button size=\"lg\" icon-name=\"menu\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Flat container icon buttons with interaction styles for minimal visual weight in dense toolbars.\n * @tags test-case\n */\nexport const FlatInteractions = {\n render: () => html`\n <nve-icon-button container=\"flat\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"menu\" disabled></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons with pressed state for toggle functionality like filters or visibility controls.\n */\nexport const Pressed = {\n render: () => html`\n <nve-icon-button pressed icon-name=\"filter
|
|
1
|
+
{"version":3,"file":"icon-button.examples.js","names":[],"sources":["../../src/icon-button/icon-button.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/icon-button/define.js';\n\nexport default {\n title: 'Elements/Icon Button',\n component: 'nve-icon-button'\n};\n\n/**\n * @summary Basic icon button for compact actions and toolbar controls with minimal visual footprint.\n */\nexport const Default = {\n render: () => html`\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n `\n};\n\n/**\n * @summary Icon buttons with different interaction styles including default, emphasis, destructive, and disabled states.\n */\nexport const Interactions = {\n render: () => html`\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button disabled icon-name=\"menu\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons in different sizes (small, medium, large) for varying contexts and visual hierarchy.\n * @tags test-case\n */\nexport const Size = {\n render: () => html`\n <nve-icon-button size=\"sm\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button size=\"lg\" icon-name=\"menu\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Flat container icon buttons with interaction styles for minimal visual weight in dense toolbars.\n * @tags test-case\n */\nexport const FlatInteractions = {\n render: () => html`\n <nve-icon-button container=\"flat\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"menu\" disabled></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons with pressed state for toggle functionality like filters or visibility controls.\n */\nexport const Pressed = {\n render: () => html`\n <nve-icon-button pressed icon-name=\"filter\"></nve-icon-button>\n <nve-icon-button icon-name=\"filter\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Flat icon buttons with pressed state for low-emphasis toggles and compact toggle controls.\n * @tags test-case\n */\nexport const PressedFlat = {\n render: () => html`\n <nve-icon-button pressed container=\"flat\" icon-name=\"eye-hidden\" aria-label=\"show\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"eye\" aria-label=\"hide\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Inline icon buttons with pressed state for minimal toggle controls within text or content flows.\n * @tags test-case\n */\nexport const PressedInline = {\n render: () => html`\n <nve-icon-button pressed container=\"inline\" icon-name=\"eye-hidden\" aria-label=\"show\"></nve-icon-button>\n <nve-icon-button container=\"inline\" icon-name=\"eye\" aria-label=\"hide\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons with selected state for mutually exclusive options like view modes or layout choices.\n */\nexport const Selected = {\n render: () => html`\n <nve-icon-button selected icon-name=\"split-vertical\" aria-label=\"split vertical\"></nve-icon-button>\n <nve-icon-button icon-name=\"split-horizontal\" aria-label=\"split horizontal\"></nve-icon-button>\n <nve-icon-button icon-name=\"split-none\" aria-label=\"preview\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Flat icon buttons with selected state for low-emphasis mode selection in compact toolbars.\n * @tags test-case\n */\nexport const SelectedFlat = {\n render: () => html`\n <nve-icon-button selected container=\"flat\" icon-name=\"split-vertical\" aria-label=\"split vertical\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"split-horizontal\" aria-label=\"split horizontal\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"split-none\" aria-label=\"preview\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Inline icon buttons with selected state for minimal mode selection within content flows.\n * @tags test-case\n */\nexport const SelectedInline = {\n render: () => html`\n <nve-icon-button selected container=\"inline\" icon-name=\"split-vertical\" aria-label=\"split vertical\"></nve-icon-button>\n <nve-icon-button container=\"inline\" icon-name=\"split-horizontal\" aria-label=\"split horizontal\"></nve-icon-button>\n <nve-icon-button container=\"inline\" icon-name=\"split-none\" aria-label=\"preview\"></nve-icon-button>\n `\n}\n\n/**\n * @summary Icon buttons with custom content like text initials, emojis, or symbols for personalized actions.\n * @tags test-case\n */\nexport const CustomIcon = {\n render: () => html`\n <nve-icon-button interaction=\"emphasis\">ML</nve-icon-button>\n <nve-icon-button>🎉</nve-icon-button>\n <nve-icon-button>\n 🔗 <a href=\"#\" aria-label=\"custom icon button\"></a>\n </nve-icon-button>\n `\n}\n\n/**\n * @summary Proper implementation of icon buttons with links, showing correct and incorrect anchor placement patterns.\n */\nexport const Link = {\n render: () => html`\n<nve-icon-button icon-name=\"menu\">\n <a href=\"#\" aria-label=\"link to page\"></a>\n</nve-icon-button>`\n}\n\n/**\n * @summary Icon buttons styled for light and dark themes with all interaction states for theme consistency.\n * @tags test-case\n */\nexport const Themes = {\n render: () => html`\n <div nve-theme=\"root light\">\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button disabled icon-name=\"menu\"></nve-icon-button>\n </div>\n <div nve-theme=\"root dark\">\n <nve-icon-button icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"emphasis\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button interaction=\"destructive\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button container=\"flat\" icon-name=\"menu\"></nve-icon-button>\n <nve-icon-button disabled icon-name=\"menu\"></nve-icon-button>\n </div>\n `\n}"],"mappings":";AAGA,IAAA,IAAS"}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
{
|
|
46
46
|
"id": "icon-button-pressed",
|
|
47
47
|
"name": "Pressed",
|
|
48
|
-
"template": "<nve-icon-button pressed icon-name=\"filter
|
|
48
|
+
"template": "<nve-icon-button pressed icon-name=\"filter\"></nve-icon-button>\n<nve-icon-button icon-name=\"filter\"></nve-icon-button>\n",
|
|
49
49
|
"summary": "Icon buttons with pressed state for toggle functionality like filters or visibility controls.",
|
|
50
50
|
"description": "",
|
|
51
51
|
"composition": false,
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { I18nService as e } from "./internal/services/i18n.service.js";
|
|
|
2
2
|
import { getThemeTokens as t } from "./internal/utils/dom.js";
|
|
3
3
|
import { statusIcons as n } from "./internal/types/index.js";
|
|
4
4
|
//#region src/index.ts
|
|
5
|
-
var r = "2.
|
|
5
|
+
var r = "2.7.1", i = "@nvidia-elements";
|
|
6
6
|
//#endregion
|
|
7
7
|
export { e as I18nService, i as SCOPE, r as VERSION, t as getThemeTokens, n as statusIcons };
|
|
8
8
|
|
package/dist/input/input2.js
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
export interface GestureCapabilities {
|
|
3
|
+
readonly drag: boolean;
|
|
4
|
+
readonly pan: boolean;
|
|
5
|
+
readonly pinch: boolean;
|
|
6
|
+
readonly wheel: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface PointerMovementGesture {
|
|
9
|
+
readonly event: PointerEvent;
|
|
10
|
+
readonly movementX: number;
|
|
11
|
+
readonly movementY: number;
|
|
12
|
+
}
|
|
13
|
+
export type Gesture<TPinchContext> = (PointerMovementGesture & {
|
|
14
|
+
readonly kind: 'drag';
|
|
15
|
+
}) | (PointerMovementGesture & {
|
|
16
|
+
readonly kind: 'pan';
|
|
17
|
+
}) | {
|
|
18
|
+
readonly context: TPinchContext;
|
|
19
|
+
readonly event: PointerEvent;
|
|
20
|
+
readonly kind: 'pinch';
|
|
21
|
+
readonly scale: number;
|
|
22
|
+
} | {
|
|
23
|
+
readonly deltaPixels: number;
|
|
24
|
+
readonly event: WheelEvent;
|
|
25
|
+
readonly kind: 'wheel';
|
|
26
|
+
};
|
|
27
|
+
export type UnhandledPointerInput = {
|
|
28
|
+
readonly event: PointerEvent;
|
|
29
|
+
readonly kind: 'click';
|
|
30
|
+
} | {
|
|
31
|
+
readonly event: PointerEvent;
|
|
32
|
+
readonly kind: 'lostpointercapture';
|
|
33
|
+
} | {
|
|
34
|
+
readonly event: PointerEvent;
|
|
35
|
+
readonly kind: 'pointercancel';
|
|
36
|
+
} | {
|
|
37
|
+
readonly event: PointerEvent;
|
|
38
|
+
readonly kind: 'pointerdown';
|
|
39
|
+
} | {
|
|
40
|
+
readonly event: PointerEvent;
|
|
41
|
+
readonly kind: 'pointermove';
|
|
42
|
+
} | {
|
|
43
|
+
readonly event: PointerEvent;
|
|
44
|
+
readonly kind: 'pointerup';
|
|
45
|
+
};
|
|
46
|
+
export interface GestureControllerOptions<TPinchContext = undefined> {
|
|
47
|
+
/** Creates a snapshot of caller state when a pinch begins. Omit this field to disable pinch recognition. */
|
|
48
|
+
readonly createPinchContext?: () => TPinchContext;
|
|
49
|
+
/** Returns the gesture kinds that the controller can recognize for the current input event. */
|
|
50
|
+
readonly getCapabilities: () => GestureCapabilities;
|
|
51
|
+
/** Updates caller state before the controller reads capabilities for a nonignored input event. */
|
|
52
|
+
readonly prepare?: () => void;
|
|
53
|
+
/** Returns whether the controller should skip an input event before preparing or recognizing it. */
|
|
54
|
+
readonly shouldIgnore?: (event: Event) => boolean;
|
|
55
|
+
}
|
|
56
|
+
type GestureHost = EventTarget & ReactiveControllerHost;
|
|
57
|
+
/** Recognizes drag, pan, pinch, and wheel input on a dynamically assigned target. */
|
|
58
|
+
export declare class GestureController<TPinchContext = undefined> implements ReactiveController {
|
|
59
|
+
#private;
|
|
60
|
+
constructor(host: GestureHost, options: GestureControllerOptions<TPinchContext>);
|
|
61
|
+
set target(target: HTMLElement | undefined);
|
|
62
|
+
hostConnected(): void;
|
|
63
|
+
hostDisconnected(): void;
|
|
64
|
+
}
|
|
65
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture.controller.examples.js","names":["#gestureController"],"sources":["../../../src/internal/controllers/gesture.controller.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { css, html, LitElement } from 'lit';\nimport { GestureController } from '@nvidia-elements/core/internal';\n\nexport default {\n title: 'Internal/Controllers'\n};\n\nclass GestureDemoElement extends LitElement {\n readonly #gestureController = new GestureController(this, {\n getCapabilities: () => ({ drag: true, pan: false, pinch: false, wheel: false })\n });\n\n static styles = css`\n :host {\n cursor: grab;\n display: grid;\n height: 64px;\n place-items: center;\n width: 64px;\n }\n\n :host([data-active]) {\n cursor: grabbing;\n }\n `;\n\n constructor() {\n super();\n this.#gestureController.target = this;\n }\n\n render() {\n return html`drag`;\n }\n}\n\nif (!customElements.get('gesture-controller-demo-element')) {\n customElements.define('gesture-controller-demo-element', GestureDemoElement);\n}\n\n/**\n * @summary Drag recognition delivered through gesture and unmatched pointer events. Use event details to move content and represent active pointer state.\n * @tags test-case\n */\nexport const Drag = {\n render: () => html`\n<gesture-controller-demo-element></gesture-controller-demo-element>\n<script type=\"module\">\n const element = document.querySelector('gesture-controller-demo-element');\n let x = 0;\n let y = 0;\n\n element.addEventListener('nve-pointer-input', ({ detail }) => {\n if (detail.kind === 'pointerdown') element.dataset.active = '';\n if (detail.kind === 'pointerup' || detail.kind === 'pointercancel') delete element.dataset.active;\n });\n\n element.addEventListener('nve-gesture', ({ detail }) => {\n if (detail.kind !== 'drag') return;\n x += detail.movementX;\n y += detail.movementY;\n element.style.translate = x + 'px ' + y + 'px';\n });\n</script>\n`\n};\n"],"mappings":";AAGA,IAAA,IAAc"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"entrypoint": "@nvidia-elements/core/internal/controllers/gesture.controller.examples.json",
|
|
3
|
+
"items": [
|
|
4
|
+
{
|
|
5
|
+
"id": "internal-controllers-gesture.controller-drag",
|
|
6
|
+
"name": "Drag",
|
|
7
|
+
"template": "<gesture-controller-demo-element></gesture-controller-demo-element>\n<script type=\"module\">\n const element = document.querySelector(\"gesture-controller-demo-element\");\n let x = 0;\n let y = 0;\n element.addEventListener(\"nve-pointer-input\", ({ detail }) => {\n if (detail.kind === \"pointerdown\") element.dataset.active = \"\";\n if (detail.kind === \"pointerup\" || detail.kind === \"pointercancel\") delete element.dataset.active;\n });\n element.addEventListener(\"nve-gesture\", ({ detail }) => {\n if (detail.kind !== \"drag\") return;\n x += detail.movementX;\n y += detail.movementY;\n element.style.translate = x + \"px \" + y + \"px\";\n });\n</script>\n",
|
|
8
|
+
"summary": "Drag recognition delivered through gesture and unmatched pointer events. Use event details to move content and represent active pointer state.",
|
|
9
|
+
"description": "",
|
|
10
|
+
"composition": false,
|
|
11
|
+
"tags": [
|
|
12
|
+
"test-case"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
//#region src/internal/controllers/gesture.controller.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"auxclick",
|
|
4
|
+
"click",
|
|
5
|
+
"contextmenu",
|
|
6
|
+
"lostpointercapture",
|
|
7
|
+
"pointercancel",
|
|
8
|
+
"pointerdown",
|
|
9
|
+
"pointermove",
|
|
10
|
+
"pointerup",
|
|
11
|
+
"wheel"
|
|
12
|
+
], t = class {
|
|
13
|
+
#e;
|
|
14
|
+
#t;
|
|
15
|
+
#n = /* @__PURE__ */ new Set();
|
|
16
|
+
#r = /* @__PURE__ */ new Map();
|
|
17
|
+
#i = !1;
|
|
18
|
+
#a;
|
|
19
|
+
#o;
|
|
20
|
+
constructor(e, t) {
|
|
21
|
+
this.#e = e, this.#t = t, e.addController(this);
|
|
22
|
+
}
|
|
23
|
+
set target(e) {
|
|
24
|
+
e !== this.#o && (this.#c(), this.#E(), this.#o = e, this.#s());
|
|
25
|
+
}
|
|
26
|
+
hostConnected() {
|
|
27
|
+
this.#i = !0, this.#s();
|
|
28
|
+
}
|
|
29
|
+
hostDisconnected() {
|
|
30
|
+
this.#c(), this.#E(), this.#i = !1;
|
|
31
|
+
}
|
|
32
|
+
#s() {
|
|
33
|
+
if (!(!this.#i || !this.#o)) for (let t of e) this.#o.addEventListener(t, this.#l, !0);
|
|
34
|
+
}
|
|
35
|
+
#c() {
|
|
36
|
+
if (!(!this.#i || !this.#o)) for (let t of e) this.#o.removeEventListener(t, this.#l, !0);
|
|
37
|
+
}
|
|
38
|
+
#l = (e) => {
|
|
39
|
+
let t = this.#o;
|
|
40
|
+
if (!t || e.currentTarget !== t || this.#t.shouldIgnore?.(e)) return;
|
|
41
|
+
this.#t.prepare?.();
|
|
42
|
+
let n = this.#t.getCapabilities();
|
|
43
|
+
e instanceof WheelEvent ? this.#u(e, n) : e.type === "contextmenu" ? n.pan && e.preventDefault() : e instanceof PointerEvent && this.#d(e, n);
|
|
44
|
+
};
|
|
45
|
+
#u(e, t) {
|
|
46
|
+
let n = this.#o;
|
|
47
|
+
!t.wheel || !n || (this.#w({
|
|
48
|
+
deltaPixels: i(e, n),
|
|
49
|
+
event: e,
|
|
50
|
+
kind: "wheel"
|
|
51
|
+
}), e.preventDefault());
|
|
52
|
+
}
|
|
53
|
+
#d(e, t) {
|
|
54
|
+
switch (e.type) {
|
|
55
|
+
case "auxclick":
|
|
56
|
+
case "click":
|
|
57
|
+
this.#f(e, t);
|
|
58
|
+
break;
|
|
59
|
+
case "lostpointercapture":
|
|
60
|
+
this.#r.delete(e.pointerId), this.#n.delete(e.pointerId), this.#a?.pointerIds.includes(e.pointerId) && (this.#a = void 0), this.#T({
|
|
61
|
+
event: e,
|
|
62
|
+
kind: "lostpointercapture"
|
|
63
|
+
});
|
|
64
|
+
break;
|
|
65
|
+
case "pointercancel":
|
|
66
|
+
this.#r.delete(e.pointerId), this.#n.delete(e.pointerId), this.#a = void 0, this.#T({
|
|
67
|
+
event: e,
|
|
68
|
+
kind: "pointercancel"
|
|
69
|
+
});
|
|
70
|
+
break;
|
|
71
|
+
case "pointerdown":
|
|
72
|
+
this.#p(e, t);
|
|
73
|
+
break;
|
|
74
|
+
case "pointermove":
|
|
75
|
+
this.#h(e, t);
|
|
76
|
+
break;
|
|
77
|
+
case "pointerup":
|
|
78
|
+
this.#m(e);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
#f(e, t) {
|
|
83
|
+
e.button === 2 && t.pan ? r(e) : e.type === "click" && this.#T({
|
|
84
|
+
event: e,
|
|
85
|
+
kind: "click"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
#p(e, t) {
|
|
89
|
+
let i = t.pinch && this.#t.createPinchContext !== void 0;
|
|
90
|
+
if (this.#r.set(e.pointerId, {
|
|
91
|
+
x: e.clientX,
|
|
92
|
+
y: e.clientY
|
|
93
|
+
}), e.button === 2 && t.pan && this.#n.add(e.pointerId), n(t, i) && this.#C(e.pointerId), this.#n.has(e.pointerId)) {
|
|
94
|
+
r(e);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
i && this.#b(), this.#T({
|
|
98
|
+
event: e,
|
|
99
|
+
kind: "pointerdown"
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
#m(e) {
|
|
103
|
+
this.#r.delete(e.pointerId);
|
|
104
|
+
let t = this.#n.delete(e.pointerId);
|
|
105
|
+
this.#a?.pointerIds.includes(e.pointerId) && (this.#a = void 0), t ? r(e) : this.#T({
|
|
106
|
+
event: e,
|
|
107
|
+
kind: "pointerup"
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
#h(e, t) {
|
|
111
|
+
if (e.buttons === 0) {
|
|
112
|
+
this.#g(e);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
let r = t.pinch && this.#t.createPinchContext !== void 0, i = this.#v(e);
|
|
116
|
+
if (!i || !n(t, r)) return this.#T({
|
|
117
|
+
event: e,
|
|
118
|
+
kind: "pointermove"
|
|
119
|
+
});
|
|
120
|
+
if (!this.#_(e, i, t) && !(this.#r.size >= 2 && r && this.#y(e))) {
|
|
121
|
+
if (!t.drag) return this.#T({
|
|
122
|
+
event: e,
|
|
123
|
+
kind: "pointermove"
|
|
124
|
+
});
|
|
125
|
+
this.#C(e.pointerId), e.preventDefault(), this.#w({
|
|
126
|
+
event: e,
|
|
127
|
+
kind: "drag",
|
|
128
|
+
movementX: i.x,
|
|
129
|
+
movementY: i.y
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
#g(e) {
|
|
134
|
+
this.#r.delete(e.pointerId), this.#n.delete(e.pointerId), this.#a = void 0, this.#T({
|
|
135
|
+
event: e,
|
|
136
|
+
kind: "pointermove"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
#_(e, t, n) {
|
|
140
|
+
return !n.pan || !this.#n.has(e.pointerId) ? !1 : (this.#C(e.pointerId), e.preventDefault(), this.#w({
|
|
141
|
+
event: e,
|
|
142
|
+
kind: "pan",
|
|
143
|
+
movementX: t.x,
|
|
144
|
+
movementY: t.y
|
|
145
|
+
}), !0);
|
|
146
|
+
}
|
|
147
|
+
#v(e) {
|
|
148
|
+
let t = this.#r.get(e.pointerId);
|
|
149
|
+
if (!t) return;
|
|
150
|
+
this.#r.set(e.pointerId, {
|
|
151
|
+
x: e.clientX,
|
|
152
|
+
y: e.clientY
|
|
153
|
+
});
|
|
154
|
+
let n = {
|
|
155
|
+
x: e.clientX - t.x,
|
|
156
|
+
y: e.clientY - t.y
|
|
157
|
+
};
|
|
158
|
+
return n.x === 0 && n.y === 0 ? void 0 : n;
|
|
159
|
+
}
|
|
160
|
+
#y(e) {
|
|
161
|
+
let t = this.#t.createPinchContext;
|
|
162
|
+
if (!t) return !1;
|
|
163
|
+
if (this.#a && !this.#a.pointerIds.includes(e.pointerId)) return !0;
|
|
164
|
+
let n = this.#a?.pointerIds ?? this.#x();
|
|
165
|
+
if (!n) return !1;
|
|
166
|
+
let r = this.#S(n);
|
|
167
|
+
return r === void 0 || r <= 0 ? !1 : (this.#a ??= {
|
|
168
|
+
context: t(),
|
|
169
|
+
distance: r,
|
|
170
|
+
pointerIds: n
|
|
171
|
+
}, this.#C(e.pointerId), e.preventDefault(), this.#w({
|
|
172
|
+
context: this.#a.context,
|
|
173
|
+
event: e,
|
|
174
|
+
kind: "pinch",
|
|
175
|
+
scale: r / this.#a.distance
|
|
176
|
+
}), !0);
|
|
177
|
+
}
|
|
178
|
+
#b() {
|
|
179
|
+
let e = this.#t.createPinchContext;
|
|
180
|
+
if (this.#r.size !== 2 || !e) return;
|
|
181
|
+
let t = this.#x();
|
|
182
|
+
if (!t) return;
|
|
183
|
+
let n = this.#S(t);
|
|
184
|
+
n !== void 0 && n > 0 && (this.#a = {
|
|
185
|
+
context: e(),
|
|
186
|
+
distance: n,
|
|
187
|
+
pointerIds: t
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
#x() {
|
|
191
|
+
let e = [...this.#r.keys()], t = e[0], n = e[1];
|
|
192
|
+
return t === void 0 || n === void 0 ? void 0 : [t, n];
|
|
193
|
+
}
|
|
194
|
+
#S(e) {
|
|
195
|
+
let t = this.#r.get(e[0]), n = this.#r.get(e[1]);
|
|
196
|
+
return t && n ? Math.hypot(t.x - n.x, t.y - n.y) : void 0;
|
|
197
|
+
}
|
|
198
|
+
#C(e) {
|
|
199
|
+
try {
|
|
200
|
+
this.#o?.setPointerCapture?.(e);
|
|
201
|
+
} catch {}
|
|
202
|
+
}
|
|
203
|
+
#w(e) {
|
|
204
|
+
this.#e.dispatchEvent(new CustomEvent("nve-gesture", {
|
|
205
|
+
bubbles: !1,
|
|
206
|
+
cancelable: !1,
|
|
207
|
+
composed: !1,
|
|
208
|
+
detail: e
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
#T(e) {
|
|
212
|
+
this.#e.dispatchEvent(new CustomEvent("nve-pointer-input", {
|
|
213
|
+
bubbles: !1,
|
|
214
|
+
cancelable: !1,
|
|
215
|
+
composed: !1,
|
|
216
|
+
detail: e
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
#E() {
|
|
220
|
+
this.#r.clear(), this.#n.clear(), this.#a = void 0;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
function n(e, t) {
|
|
224
|
+
return e.drag || e.pan || t;
|
|
225
|
+
}
|
|
226
|
+
function r(e) {
|
|
227
|
+
e.preventDefault(), e.stopImmediatePropagation();
|
|
228
|
+
}
|
|
229
|
+
function i(e, t) {
|
|
230
|
+
return e.deltaMode === WheelEvent.DOM_DELTA_LINE ? e.deltaY * 16 : e.deltaMode === WheelEvent.DOM_DELTA_PAGE ? e.deltaY * t.getBoundingClientRect().height : e.deltaY;
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
export { t as GestureController };
|
|
234
|
+
|
|
235
|
+
//# sourceMappingURL=gesture.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture.controller.js","names":["#host","#options","#panPointerIds","#pointerPositions","#target","#removeTargetListeners","#resetGestureState","#addTargetListeners","#connected","#handleEvent","#handleWheel","#handlePointer","#dispatchGesture","#handleClick","#pinch","#dispatchPointerInput","#handlePointerDown","#handlePointerMove","#handlePointerUp","#capturePointer","#startPinchIfNeeded","#handlePointerButtonsReleased","#updatePointerPosition","#handlePanMove","#handlePinch","#getPinchPointerIds","#getPointerDistance"],"sources":["../../../src/internal/controllers/gesture.controller.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nconst GESTURE_EVENT_TYPES = [\n 'auxclick',\n 'click',\n 'contextmenu',\n 'lostpointercapture',\n 'pointercancel',\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'wheel'\n] as const;\n\ninterface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface GestureCapabilities {\n readonly drag: boolean;\n readonly pan: boolean;\n readonly pinch: boolean;\n readonly wheel: boolean;\n}\n\ninterface PointerMovementGesture {\n readonly event: PointerEvent;\n readonly movementX: number;\n readonly movementY: number;\n}\n\nexport type Gesture<TPinchContext> =\n | (PointerMovementGesture & { readonly kind: 'drag' })\n | (PointerMovementGesture & { readonly kind: 'pan' })\n | {\n readonly context: TPinchContext;\n readonly event: PointerEvent;\n readonly kind: 'pinch';\n readonly scale: number;\n }\n | {\n readonly deltaPixels: number;\n readonly event: WheelEvent;\n readonly kind: 'wheel';\n };\n\nexport type UnhandledPointerInput =\n | { readonly event: PointerEvent; readonly kind: 'click' }\n | { readonly event: PointerEvent; readonly kind: 'lostpointercapture' }\n | { readonly event: PointerEvent; readonly kind: 'pointercancel' }\n | { readonly event: PointerEvent; readonly kind: 'pointerdown' }\n | { readonly event: PointerEvent; readonly kind: 'pointermove' }\n | { readonly event: PointerEvent; readonly kind: 'pointerup' };\n\nexport interface GestureControllerOptions<TPinchContext = undefined> {\n /** Creates a snapshot of caller state when a pinch begins. Omit this field to disable pinch recognition. */\n readonly createPinchContext?: () => TPinchContext;\n /** Returns the gesture kinds that the controller can recognize for the current input event. */\n readonly getCapabilities: () => GestureCapabilities;\n /** Updates caller state before the controller reads capabilities for a nonignored input event. */\n readonly prepare?: () => void;\n /** Returns whether the controller should skip an input event before preparing or recognizing it. */\n readonly shouldIgnore?: (event: Event) => boolean;\n}\n\ninterface PinchState<TPinchContext> {\n readonly context: TPinchContext;\n readonly distance: number;\n readonly pointerIds: readonly [number, number];\n}\n\ntype GestureHost = EventTarget & ReactiveControllerHost;\n\n/** Recognizes drag, pan, pinch, and wheel input on a dynamically assigned target. */\nexport class GestureController<TPinchContext = undefined> implements ReactiveController {\n readonly #host: GestureHost;\n readonly #options: GestureControllerOptions<TPinchContext>;\n readonly #panPointerIds = new Set<number>();\n readonly #pointerPositions = new Map<number, Point>();\n #connected = false;\n #pinch?: PinchState<TPinchContext>;\n #target?: HTMLElement;\n\n constructor(host: GestureHost, options: GestureControllerOptions<TPinchContext>) {\n this.#host = host;\n this.#options = options;\n host.addController(this);\n }\n\n set target(target: HTMLElement | undefined) {\n if (target === this.#target) return;\n this.#removeTargetListeners();\n this.#resetGestureState();\n this.#target = target;\n this.#addTargetListeners();\n }\n\n hostConnected(): void {\n this.#connected = true;\n this.#addTargetListeners();\n }\n\n hostDisconnected(): void {\n this.#removeTargetListeners();\n this.#resetGestureState();\n this.#connected = false;\n }\n\n #addTargetListeners(): void {\n if (!this.#connected || !this.#target) return;\n for (const type of GESTURE_EVENT_TYPES) this.#target.addEventListener(type, this.#handleEvent, true);\n }\n\n #removeTargetListeners(): void {\n if (!this.#connected || !this.#target) return;\n for (const type of GESTURE_EVENT_TYPES) this.#target.removeEventListener(type, this.#handleEvent, true);\n }\n\n #handleEvent = (event: Event): void => {\n const target = this.#target;\n if (!target || event.currentTarget !== target || this.#options.shouldIgnore?.(event)) return;\n this.#options.prepare?.();\n const capabilities = this.#options.getCapabilities();\n if (event instanceof WheelEvent) {\n this.#handleWheel(event, capabilities);\n } else if (event.type === 'contextmenu') {\n if (capabilities.pan) event.preventDefault();\n } else if (event instanceof PointerEvent) {\n this.#handlePointer(event, capabilities);\n }\n };\n\n #handleWheel(event: WheelEvent, capabilities: GestureCapabilities): void {\n const target = this.#target;\n if (!capabilities.wheel || !target) return;\n this.#dispatchGesture({\n deltaPixels: normalizeWheelDelta(event, target),\n event,\n kind: 'wheel'\n });\n event.preventDefault();\n }\n\n #handlePointer(event: PointerEvent, capabilities: GestureCapabilities): void {\n switch (event.type) {\n case 'auxclick':\n case 'click':\n this.#handleClick(event, capabilities);\n break;\n case 'lostpointercapture':\n this.#pointerPositions.delete(event.pointerId);\n this.#panPointerIds.delete(event.pointerId);\n if (this.#pinch?.pointerIds.includes(event.pointerId)) this.#pinch = undefined;\n this.#dispatchPointerInput({ event, kind: 'lostpointercapture' });\n break;\n case 'pointercancel':\n this.#pointerPositions.delete(event.pointerId);\n this.#panPointerIds.delete(event.pointerId);\n this.#pinch = undefined;\n this.#dispatchPointerInput({ event, kind: 'pointercancel' });\n break;\n case 'pointerdown':\n this.#handlePointerDown(event, capabilities);\n break;\n case 'pointermove':\n this.#handlePointerMove(event, capabilities);\n break;\n case 'pointerup':\n this.#handlePointerUp(event);\n break;\n }\n }\n\n #handleClick(event: PointerEvent, capabilities: GestureCapabilities): void {\n if (event.button === 2 && capabilities.pan) {\n consumePanBoundaryEvent(event);\n } else if (event.type === 'click') {\n this.#dispatchPointerInput({ event, kind: 'click' });\n }\n }\n\n #handlePointerDown(event: PointerEvent, capabilities: GestureCapabilities): void {\n const canPinch = capabilities.pinch && this.#options.createPinchContext !== undefined;\n this.#pointerPositions.set(event.pointerId, { x: event.clientX, y: event.clientY });\n if (event.button === 2 && capabilities.pan) this.#panPointerIds.add(event.pointerId);\n if (hasPointerCapability(capabilities, canPinch)) this.#capturePointer(event.pointerId);\n if (this.#panPointerIds.has(event.pointerId)) {\n consumePanBoundaryEvent(event);\n return;\n }\n if (canPinch) this.#startPinchIfNeeded();\n this.#dispatchPointerInput({ event, kind: 'pointerdown' });\n }\n\n #handlePointerUp(event: PointerEvent): void {\n this.#pointerPositions.delete(event.pointerId);\n const wasPanPointer = this.#panPointerIds.delete(event.pointerId);\n if (this.#pinch?.pointerIds.includes(event.pointerId)) this.#pinch = undefined;\n if (wasPanPointer) {\n consumePanBoundaryEvent(event);\n } else {\n this.#dispatchPointerInput({ event, kind: 'pointerup' });\n }\n }\n\n #handlePointerMove(event: PointerEvent, capabilities: GestureCapabilities): void {\n if (event.buttons === 0) {\n this.#handlePointerButtonsReleased(event);\n return;\n }\n const canPinch = capabilities.pinch && this.#options.createPinchContext !== undefined;\n const movement = this.#updatePointerPosition(event);\n if (!movement || !hasPointerCapability(capabilities, canPinch)) {\n return this.#dispatchPointerInput({ event, kind: 'pointermove' });\n }\n if (this.#handlePanMove(event, movement, capabilities)) return;\n if (this.#pointerPositions.size >= 2 && canPinch && this.#handlePinch(event)) return;\n if (!capabilities.drag) return this.#dispatchPointerInput({ event, kind: 'pointermove' });\n this.#capturePointer(event.pointerId);\n event.preventDefault();\n this.#dispatchGesture({ event, kind: 'drag', movementX: movement.x, movementY: movement.y });\n }\n\n #handlePointerButtonsReleased(event: PointerEvent): void {\n this.#pointerPositions.delete(event.pointerId);\n this.#panPointerIds.delete(event.pointerId);\n this.#pinch = undefined;\n this.#dispatchPointerInput({ event, kind: 'pointermove' });\n }\n\n #handlePanMove(event: PointerEvent, movement: Point, capabilities: GestureCapabilities): boolean {\n if (!capabilities.pan || !this.#panPointerIds.has(event.pointerId)) return false;\n this.#capturePointer(event.pointerId);\n event.preventDefault();\n this.#dispatchGesture({ event, kind: 'pan', movementX: movement.x, movementY: movement.y });\n return true;\n }\n\n #updatePointerPosition(event: PointerEvent): Point | undefined {\n const previous = this.#pointerPositions.get(event.pointerId);\n if (!previous) return undefined;\n this.#pointerPositions.set(event.pointerId, { x: event.clientX, y: event.clientY });\n const movement = { x: event.clientX - previous.x, y: event.clientY - previous.y };\n return movement.x === 0 && movement.y === 0 ? undefined : movement;\n }\n\n #handlePinch(event: PointerEvent): boolean {\n const createPinchContext = this.#options.createPinchContext;\n if (!createPinchContext) return false;\n if (this.#pinch && !this.#pinch.pointerIds.includes(event.pointerId)) return true;\n const pointerIds = this.#pinch?.pointerIds ?? this.#getPinchPointerIds();\n if (!pointerIds) return false;\n const distance = this.#getPointerDistance(pointerIds);\n if (distance === undefined || distance <= 0) return false;\n this.#pinch ??= { context: createPinchContext(), distance, pointerIds };\n this.#capturePointer(event.pointerId);\n event.preventDefault();\n this.#dispatchGesture({\n context: this.#pinch.context,\n event,\n kind: 'pinch',\n scale: distance / this.#pinch.distance\n });\n return true;\n }\n\n #startPinchIfNeeded(): void {\n const createPinchContext = this.#options.createPinchContext;\n if (this.#pointerPositions.size !== 2 || !createPinchContext) return;\n const pointerIds = this.#getPinchPointerIds();\n if (!pointerIds) return;\n const distance = this.#getPointerDistance(pointerIds);\n if (distance !== undefined && distance > 0) {\n this.#pinch = { context: createPinchContext(), distance, pointerIds };\n }\n }\n\n #getPinchPointerIds(): [number, number] | undefined {\n const pointerIds = [...this.#pointerPositions.keys()];\n const first = pointerIds[0];\n const second = pointerIds[1];\n return first === undefined || second === undefined ? undefined : [first, second];\n }\n\n #getPointerDistance(pointerIds: readonly [number, number]): number | undefined {\n const first = this.#pointerPositions.get(pointerIds[0]);\n const second = this.#pointerPositions.get(pointerIds[1]);\n return first && second ? Math.hypot(first.x - second.x, first.y - second.y) : undefined;\n }\n\n #capturePointer(pointerId: number): void {\n try {\n this.#target?.setPointerCapture?.(pointerId);\n } catch {\n // Synthetic test events and browser implementations may not have an active pointer to capture.\n }\n }\n\n #dispatchGesture(gesture: Gesture<TPinchContext>): void {\n this.#host.dispatchEvent(\n new CustomEvent<Gesture<TPinchContext>>('nve-gesture', {\n bubbles: false,\n cancelable: false,\n composed: false,\n detail: gesture\n })\n );\n }\n\n #dispatchPointerInput(input: UnhandledPointerInput): void {\n this.#host.dispatchEvent(\n new CustomEvent<UnhandledPointerInput>('nve-pointer-input', {\n bubbles: false,\n cancelable: false,\n composed: false,\n detail: input\n })\n );\n }\n\n #resetGestureState(): void {\n this.#pointerPositions.clear();\n this.#panPointerIds.clear();\n this.#pinch = undefined;\n }\n}\n\nfunction hasPointerCapability(capabilities: GestureCapabilities, canPinch: boolean): boolean {\n return capabilities.drag || capabilities.pan || canPinch;\n}\n\nfunction consumePanBoundaryEvent(event: Event): void {\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n\nfunction normalizeWheelDelta(event: WheelEvent, target: HTMLElement): number {\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return event.deltaY * 16;\n if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return event.deltaY * target.getBoundingClientRect().height;\n return event.deltaY;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
type SpatialKeyHost = ReactiveControllerHost & HTMLElement;
|
|
3
|
+
export type SpatialKeyHandling = 'handled' | 'ignored';
|
|
4
|
+
export type SpatialKeyCommand = {
|
|
5
|
+
readonly ctrlKey: boolean;
|
|
6
|
+
readonly event: KeyboardEvent;
|
|
7
|
+
readonly kind: 'direction';
|
|
8
|
+
readonly horizontal: -1 | 0 | 1;
|
|
9
|
+
readonly key: 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'ArrowUp';
|
|
10
|
+
readonly shiftKey: boolean;
|
|
11
|
+
readonly vertical: -1 | 0 | 1;
|
|
12
|
+
} | {
|
|
13
|
+
readonly event: KeyboardEvent;
|
|
14
|
+
readonly kind: 'zoom';
|
|
15
|
+
readonly key: '+' | '-' | '=';
|
|
16
|
+
};
|
|
17
|
+
/** Converts direct-host keyboard input into spatial direction and zoom commands. */
|
|
18
|
+
export declare class KeyNavigationSpatialController implements ReactiveController {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(host: SpatialKeyHost);
|
|
21
|
+
hostConnected(): void;
|
|
22
|
+
hostDisconnected(): void;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//#region src/internal/controllers/keynav-spatial.controller.ts
|
|
2
|
+
var e = class {
|
|
3
|
+
#e;
|
|
4
|
+
constructor(e) {
|
|
5
|
+
this.#e = e, e.addController(this);
|
|
6
|
+
}
|
|
7
|
+
hostConnected() {
|
|
8
|
+
this.#e.addEventListener("keydown", this.#t);
|
|
9
|
+
}
|
|
10
|
+
hostDisconnected() {
|
|
11
|
+
this.#e.removeEventListener("keydown", this.#t);
|
|
12
|
+
}
|
|
13
|
+
#t = (e) => {
|
|
14
|
+
if (e.composedPath()[0] !== this.#e) return;
|
|
15
|
+
let n = t(e);
|
|
16
|
+
n && this.#e.dispatchEvent(new CustomEvent("nve-key", {
|
|
17
|
+
bubbles: !1,
|
|
18
|
+
cancelable: !1,
|
|
19
|
+
composed: !1,
|
|
20
|
+
detail: n
|
|
21
|
+
}));
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
function t(e) {
|
|
25
|
+
switch (e.key) {
|
|
26
|
+
case "ArrowDown": return {
|
|
27
|
+
ctrlKey: e.ctrlKey,
|
|
28
|
+
event: e,
|
|
29
|
+
horizontal: 0,
|
|
30
|
+
key: e.key,
|
|
31
|
+
kind: "direction",
|
|
32
|
+
shiftKey: e.shiftKey,
|
|
33
|
+
vertical: -1
|
|
34
|
+
};
|
|
35
|
+
case "ArrowLeft": return {
|
|
36
|
+
ctrlKey: e.ctrlKey,
|
|
37
|
+
event: e,
|
|
38
|
+
horizontal: -1,
|
|
39
|
+
key: e.key,
|
|
40
|
+
kind: "direction",
|
|
41
|
+
shiftKey: e.shiftKey,
|
|
42
|
+
vertical: 0
|
|
43
|
+
};
|
|
44
|
+
case "ArrowRight": return {
|
|
45
|
+
ctrlKey: e.ctrlKey,
|
|
46
|
+
event: e,
|
|
47
|
+
horizontal: 1,
|
|
48
|
+
key: e.key,
|
|
49
|
+
kind: "direction",
|
|
50
|
+
shiftKey: e.shiftKey,
|
|
51
|
+
vertical: 0
|
|
52
|
+
};
|
|
53
|
+
case "ArrowUp": return {
|
|
54
|
+
ctrlKey: e.ctrlKey,
|
|
55
|
+
event: e,
|
|
56
|
+
horizontal: 0,
|
|
57
|
+
key: e.key,
|
|
58
|
+
kind: "direction",
|
|
59
|
+
shiftKey: e.shiftKey,
|
|
60
|
+
vertical: 1
|
|
61
|
+
};
|
|
62
|
+
case "+":
|
|
63
|
+
case "-":
|
|
64
|
+
case "=": return {
|
|
65
|
+
event: e,
|
|
66
|
+
key: e.key,
|
|
67
|
+
kind: "zoom"
|
|
68
|
+
};
|
|
69
|
+
default: return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { e as KeyNavigationSpatialController };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=keynav-spatial.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keynav-spatial.controller.js","names":["#host","#handleKeydown"],"sources":["../../../src/internal/controllers/keynav-spatial.controller.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\n\ntype SpatialKeyHost = ReactiveControllerHost & HTMLElement;\n\nexport type SpatialKeyHandling = 'handled' | 'ignored';\n\nexport type SpatialKeyCommand =\n | {\n readonly ctrlKey: boolean;\n readonly event: KeyboardEvent;\n readonly kind: 'direction';\n readonly horizontal: -1 | 0 | 1;\n readonly key: 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'ArrowUp';\n readonly shiftKey: boolean;\n readonly vertical: -1 | 0 | 1;\n }\n | {\n readonly event: KeyboardEvent;\n readonly kind: 'zoom';\n readonly key: '+' | '-' | '=';\n };\n\n/** Converts direct-host keyboard input into spatial direction and zoom commands. */\nexport class KeyNavigationSpatialController implements ReactiveController {\n readonly #host: SpatialKeyHost;\n\n constructor(host: SpatialKeyHost) {\n this.#host = host;\n host.addController(this);\n }\n\n hostConnected(): void {\n this.#host.addEventListener('keydown', this.#handleKeydown);\n }\n\n hostDisconnected(): void {\n this.#host.removeEventListener('keydown', this.#handleKeydown);\n }\n\n #handleKeydown = (event: KeyboardEvent): void => {\n if (event.composedPath()[0] !== this.#host) return;\n const command = getSpatialKeyCommand(event);\n if (!command) return;\n this.#host.dispatchEvent(\n new CustomEvent<SpatialKeyCommand>('nve-key', {\n bubbles: false,\n cancelable: false,\n composed: false,\n detail: command\n })\n );\n };\n}\n\nfunction getSpatialKeyCommand(event: KeyboardEvent): SpatialKeyCommand | undefined {\n switch (event.key) {\n case 'ArrowDown':\n return {\n ctrlKey: event.ctrlKey,\n event,\n horizontal: 0,\n key: event.key,\n kind: 'direction',\n shiftKey: event.shiftKey,\n vertical: -1\n };\n case 'ArrowLeft':\n return {\n ctrlKey: event.ctrlKey,\n event,\n horizontal: -1,\n key: event.key,\n kind: 'direction',\n shiftKey: event.shiftKey,\n vertical: 0\n };\n case 'ArrowRight':\n return {\n ctrlKey: event.ctrlKey,\n event,\n horizontal: 1,\n key: event.key,\n kind: 'direction',\n shiftKey: event.shiftKey,\n vertical: 0\n };\n case 'ArrowUp':\n return {\n ctrlKey: event.ctrlKey,\n event,\n horizontal: 0,\n key: event.key,\n kind: 'direction',\n shiftKey: event.shiftKey,\n vertical: 1\n };\n case '+':\n case '-':\n case '=':\n return { event, key: event.key, kind: 'zoom' };\n default:\n return undefined;\n }\n}\n"],"mappings":";AA0BA,IAAa,IAAb,MAA0E;CACxE;CAEA,YAAY,GAAsB;EAEhC,AADA,KAAKA,KAAQ,GACb,EAAK,cAAc,IAAI;CACzB;CAEA,gBAAsB;EACpB,KAAKA,GAAM,iBAAiB,WAAW,KAAKC,EAAc;CAC5D;CAEA,mBAAyB;EACvB,KAAKD,GAAM,oBAAoB,WAAW,KAAKC,EAAc;CAC/D;CAEA,MAAkB,MAA+B;EAC/C,IAAI,EAAM,aAAa,CAAC,CAAC,OAAO,KAAKD,IAAO;EAC5C,IAAM,IAAU,EAAqB,CAAK;EACrC,KACL,KAAKA,GAAM,cACT,IAAI,YAA+B,WAAW;GAC5C,SAAS;GACT,YAAY;GACZ,UAAU;GACV,QAAQ;EACV,CAAC,CACH;CACF;AACF;AAEA,SAAS,EAAqB,GAAqD;CACjF,QAAQ,EAAM,KAAd;EACE,KAAK,aACH,OAAO;GACL,SAAS,EAAM;GACf;GACA,YAAY;GACZ,KAAK,EAAM;GACX,MAAM;GACN,UAAU,EAAM;GAChB,UAAU;EACZ;EACF,KAAK,aACH,OAAO;GACL,SAAS,EAAM;GACf;GACA,YAAY;GACZ,KAAK,EAAM;GACX,MAAM;GACN,UAAU,EAAM;GAChB,UAAU;EACZ;EACF,KAAK,cACH,OAAO;GACL,SAAS,EAAM;GACf;GACA,YAAY;GACZ,KAAK,EAAM;GACX,MAAM;GACN,UAAU,EAAM;GAChB,UAAU;EACZ;EACF,KAAK,WACH,OAAO;GACL,SAAS,EAAM;GACf;GACA,YAAY;GACZ,KAAK,EAAM;GACX,MAAM;GACN,UAAU,EAAM;GAChB,UAAU;EACZ;EACF,KAAK;EACL,KAAK;EACL,KAAK,KACH,OAAO;GAAE;GAAO,KAAK,EAAM;GAAK,MAAM;EAAO;EAC/C,SACE;CACJ;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.examples.js","names":[],"sources":["../../../src/internal/controllers/popover.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/forms/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/icon-button/define.js';\nimport '@nvidia-elements/core/search/define.js';\nimport '@nvidia-elements/core/dialog/define.js';\nimport '@nvidia-elements/core/tooltip/define.js';\nimport '@nvidia-elements/core/toast/define.js';\nimport '@nvidia-elements/core/drawer/define.js';\nimport '@nvidia-elements/core/dropdown/define.js';\nimport '@nvidia-elements/core/notification/define.js';\nimport '@nvidia-elements/core/toggletip/define.js';\n\nexport default {\n title: 'Elements/Popovers',\n parameters: {\n layout: 'centered'\n }\n}\n\n/* eslint-disable @nvidia-elements/lint/no-missing-popover-trigger */\n\n/**\n * @summary Anchor-based positioning where popovers anchor to specific elements rather than their triggers.\n * @tags test-case\n */\nexport const Anchor = {\n render: () => html`\n <nve-tooltip id=\"popover-1\" anchor=\"btn-2\">tooltip 1</nve-tooltip>\n <nve-tooltip id=\"popover-2\" anchor=\"btn-1\">tooltip 2</nve-tooltip>\n <div nve-layout=\"row gap:xs align:center\">\n <nve-button id=\"btn-1\" popovertarget=\"popover-1\">button 1</nve-button>\n <nve-button id=\"btn-2\" popovertarget=\"popover-2\">button 2</nve-button>\n </div>\n `\n}\n\n/**\n * @summary Nested popovers within dialogs and notifications, with proper layering and stacking order.\n * @tags test-case\n */\nexport const Nested = {\n render: () => html`\n<style>\n #root-inner { height: 2000px;}\n</style>\n<nve-dialog closable modal>\n <h3 nve-text=\"heading\">Dialog</h3>\n <p nve-text=\"body\" style=\"margin-bottom: 48px\">hello there</p>\n\n <nve-button id=\"dropdown-btn\">search</nve-button>\n <nve-dropdown anchor=\"dropdown-btn\" closable position=\"bottom\" alignment=\"start\">\n <nve-search rounded>\n <label>search dataset</label>\n <nve-icon-button id=\"tooltip-btn\" icon-name=\"information-circle
|
|
1
|
+
{"version":3,"file":"popover.examples.js","names":[],"sources":["../../../src/internal/controllers/popover.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html } from 'lit';\nimport '@nvidia-elements/core/forms/define.js';\nimport '@nvidia-elements/core/button/define.js';\nimport '@nvidia-elements/core/icon-button/define.js';\nimport '@nvidia-elements/core/search/define.js';\nimport '@nvidia-elements/core/dialog/define.js';\nimport '@nvidia-elements/core/tooltip/define.js';\nimport '@nvidia-elements/core/toast/define.js';\nimport '@nvidia-elements/core/drawer/define.js';\nimport '@nvidia-elements/core/dropdown/define.js';\nimport '@nvidia-elements/core/notification/define.js';\nimport '@nvidia-elements/core/toggletip/define.js';\n\nexport default {\n title: 'Elements/Popovers',\n parameters: {\n layout: 'centered'\n }\n}\n\n/* eslint-disable @nvidia-elements/lint/no-missing-popover-trigger */\n\n/**\n * @summary Anchor-based positioning where popovers anchor to specific elements rather than their triggers.\n * @tags test-case\n */\nexport const Anchor = {\n render: () => html`\n <nve-tooltip id=\"popover-1\" anchor=\"btn-2\">tooltip 1</nve-tooltip>\n <nve-tooltip id=\"popover-2\" anchor=\"btn-1\">tooltip 2</nve-tooltip>\n <div nve-layout=\"row gap:xs align:center\">\n <nve-button id=\"btn-1\" popovertarget=\"popover-1\">button 1</nve-button>\n <nve-button id=\"btn-2\" popovertarget=\"popover-2\">button 2</nve-button>\n </div>\n `\n}\n\n/**\n * @summary Nested popovers within dialogs and notifications, with proper layering and stacking order.\n * @tags test-case\n */\nexport const Nested = {\n render: () => html`\n<style>\n #root-inner { height: 2000px;}\n</style>\n<nve-dialog closable modal>\n <h3 nve-text=\"heading\">Dialog</h3>\n <p nve-text=\"body\" style=\"margin-bottom: 48px\">hello there</p>\n\n <nve-button id=\"dropdown-btn\">search</nve-button>\n <nve-dropdown anchor=\"dropdown-btn\" closable position=\"bottom\" alignment=\"start\">\n <nve-search rounded>\n <label>search dataset</label>\n <nve-icon-button id=\"tooltip-btn\" icon-name=\"information-circle\" container=\"flat\" aria-label=\"more details\" slot=\"label\"></nve-icon-button>\n <input type=\"search\" placeholder=\"search\" />\n </nve-search>\n <nve-tooltip anchor=\"tooltip-btn\" position=\"top\">hello there</nve-tooltip>\n </nve-dropdown>\n</nve-dialog>\n\n<nve-notification closable position=\"bottom\" alignment=\"end\">\n <h3 nve-text=\"label\">notification</h3>\n <p nve-text=\"body\">some text content in a notification</p> \n</nve-notification>\n `\n}\n\n/**\n * @summary Programmatic popover control with async operations before showing the popover.\n * @tags test-case\n */\nexport const ProgrammaticTrigger = {\n render: () => html`\n<nve-toast hidden close-timeout=\"3000\">hello there</nve-toast>\n<nve-button>open after 2s</nve-button>\n\n<script type=\"module\">\n const toast = document.querySelector('nve-toast');\n const button = document.querySelector('nve-button');\n\n button.addEventListener('click', async () => {\n await new Promise(r => setTimeout(r, 2000)); // do an async task then open the popover\n toast.showPopover();\n });\n</script>`\n}\n\n/**\n * @summary Interactive showcase of all popover types (tooltip, toast, drawer, dropdown, dialog, notification) using modern popovertarget API.\n */\nexport const Interactive = {\n render: () => html`\n <div nve-layout=\"row align:center gap:xl\" style=\"height: 300px\">\n <nve-tooltip id=\"tooltip\">hello there</nve-tooltip>\n <nve-button popovertarget=\"tooltip\">tooltip</nve-button>\n\n <nve-toast id=\"toast\" close-timeout=\"1500\">copied!</nve-toast>\n <nve-button popovertarget=\"toast\">toast</nve-button>\n\n <nve-drawer id=\"drawer\" closable modal>\n <nve-drawer-header>\n <h3 nve-text=\"heading semibold sm\">Title</h3>\n </nve-drawer-header>\n <p nve-text=\"body\">some text content in a drawer</p>\n </nve-drawer>\n <nve-button popovertarget=\"drawer\">drawer</nve-button>\n\n <nve-dropdown id=\"dropdown\" closable>\n <h3 nve-text=\"heading\">Title</h3>\n <p nve-text=\"body\">some text content in a dropdown</p>\n </nve-dropdown>\n <nve-button popovertarget=\"dropdown\">dropdown</nve-button>\n\n <nve-dialog id=\"dialog\" closable modal>\n <h3 nve-text=\"heading\">Title</h3>\n <p nve-text=\"body\">some text content in a closable dialog</p>\n </nve-dialog>\n <nve-button popovertarget=\"dialog\">dialog</nve-button>\n\n <nve-notification id=\"notification\" closable position=\"bottom\" alignment=\"end\" close-timeout=\"2000\">\n <h3 nve-text=\"label\">notification</h3>\n <p nve-text=\"body\">some text content in a notification</p> \n </nve-notification>\n <nve-button popovertarget=\"notification\">notification snackbar</nve-button>\n </div>\n `\n}\n\n/* eslint-disable @nvidia-elements/lint/no-deprecated-popover-attributes */\n\n/**\n * @deprecated\n * @summary Legacy implementation showing all popover types using the older trigger/behavior-trigger API for backward compatibility.\n * @tags test-case\n */\nexport const LegacyInteractive = {\n render: () => html`\n <div nve-layout=\"row align:center gap:xl\" style=\"height: 300px\">\n <nve-tooltip trigger=\"tooltip-btn\" behavior-trigger position=\"top\" hidden>hello there</nve-tooltip>\n <nve-button id=\"tooltip-btn\">tooltip</nve-button>\n\n <nve-button id=\"toast-btn\">toast</nve-button>\n <nve-toast trigger=\"toast-btn\" behavior-trigger position=\"top\" close-timeout=\"1500\" hidden>copied!</nve-toast>\n\n <nve-button id=\"drawer-btn\" size=\"sm\">drawer</nve-button>\n <nve-drawer trigger=\"drawer-btn\" behavior-trigger hidden closable modal>\n <nve-drawer-header>\n <h3 nve-text=\"heading semibold sm\">Title</h3>\n </nve-drawer-header>\n <p nve-text=\"body\">some text content in a drawer</p>\n </nve-drawer>\n\n <nve-button id=\"dropdown-btn\">dropdown</nve-button>\n <nve-dropdown trigger=\"dropdown-btn\" behavior-trigger closable hidden>\n <h3 nve-text=\"heading\">Title</h3>\n <p nve-text=\"body\">some text content in a dropdown</p>\n </nve-dropdown>\n\n <nve-button id=\"dialog-btn\">dialog</nve-button>\n <nve-dialog trigger=\"dialog-btn\" behavior-trigger closable modal hidden>\n <h3 nve-text=\"heading\">Title</h3>\n <p nve-text=\"body\">some text content in a closable dialog</p>\n </nve-dialog>\n\n <nve-button id=\"notification-btn\">notification snackbar</nve-button>\n <nve-notification trigger=\"notification-btn\" behavior-trigger hidden closable position=\"bottom\" alignment=\"end\" close-timeout=\"2000\">\n <h3 nve-text=\"label\">notification</h3>\n <p nve-text=\"body\">some text content in a notification</p> \n </nve-notification>\n </div>\n `\n}\n\n/**\n * @summary Simple modal dialog with keyboard accessibility, including escape key to close functionality.\n * @tags test-case\n */\nexport const Closable = {\n render: () => html`\n <nve-button popovertarget=\"popover\">open dialog</nve-button>\n <nve-dialog id=\"popover\" modal>\n <p nve-text=\"body\">Press \"escape\" key to close.</p>\n </nve-dialog>\n `\n}\n\n/**\n * @summary example of declarative popovers using the Invoker Commands API\n */\nexport const InvokerCommand = {\n render: () => html`\n <nve-button commandfor=\"popover\" command=\"toggle-popover\">toggle-popover</nve-button>\n <nve-button commandfor=\"popover\" command=\"show-popover\">show-popover</nve-button>\n <nve-toggletip id=\"popover\">\n toggletip\n <nve-button commandfor=\"popover\" command=\"hide-popover\">hide-popover</nve-button>\n </nve-toggletip>\n `\n};\n\n/**\n * @summary Custom events like many standard DOM events bubble. When listening\n * to larger DOM trees, check which element dispatched the source event.\n */\nexport const EventBubbling = {\n render: () => html`\n <div style=\"width: 100vw; height: 100vh;\">\n <p nve-text=\"body\" id=\"event-example\">event:</p>\n <nve-button popovertarget=\"event-example-dialog\">open</nve-button>\n\n <nve-dialog id=\"event-example-dialog\" closable modal (close)=\"close($event)\" (open)=\"open($event)\">\n <nve-dialog-header>Header</nve-dialog-header>\n <div>\n <nve-button popovertarget=\"event-example-dropdown\">show dropdown</nve-button>\n </div>\n <nve-dropdown id=\"event-example-dropdown\">\n dropdown content\n </nve-dropdown>\n </nve-dialog>\n </div>\n\n <script type=\"module\">\n const dialog = document.querySelector('#event-example-dialog');\n const eventLabel = document.querySelector('#event-example');\n\n // Custom events like many standard DOM events bubble. By listening to\n // larger DOM trees check which element dispatched the source event\n dialog.addEventListener('open', e => {\n eventLabel.innerText = 'open: ' + e.target.localName;\n });\n\n dialog.addEventListener('close', e => {\n eventLabel.innerText = 'close: ' + e.target.localName;\n });\n </script>\n `\n}\n"],"mappings":";AAGA,IAAA,IAAS"}
|