@nanoporetech-digital/components 3.13.0 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/nano-checkbox.cjs.entry.js.map +1 -1
  3. package/dist/cjs/nano-drawer.cjs.entry.js.map +1 -1
  4. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js +1 -1
  5. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js.map +1 -1
  6. package/dist/cjs/nano-global-nav.cjs.entry.js +30 -41
  7. package/dist/cjs/nano-global-nav.cjs.entry.js.map +1 -1
  8. package/dist/cjs/nano-hero.cjs.entry.js +1 -1
  9. package/dist/cjs/nano-hero.cjs.entry.js.map +1 -1
  10. package/dist/cjs/nano-progress-bar_2.cjs.entry.js.map +1 -1
  11. package/dist/cjs/nano-range.cjs.entry.js.map +1 -1
  12. package/dist/cjs/nano-resize-observe_2.cjs.entry.js.map +1 -1
  13. package/dist/cjs/nano-slides.cjs.entry.js +10 -13
  14. package/dist/cjs/nano-slides.cjs.entry.js.map +1 -1
  15. package/dist/cjs/nano-spinner.cjs.entry.js.map +1 -1
  16. package/dist/cjs/nano-tab.cjs.entry.js.map +1 -1
  17. package/dist/cjs/{nano-table-60c06885.js → nano-table-9044710f.js} +2 -2
  18. package/dist/cjs/{nano-table-60c06885.js.map → nano-table-9044710f.js.map} +1 -1
  19. package/dist/cjs/nano-table.cjs.entry.js +1 -1
  20. package/dist/cjs/{table.worker-f902766e.js → table.worker-8ad26746.js} +2 -2
  21. package/dist/cjs/table.worker-8ad26746.js.map +1 -0
  22. package/dist/collection/components/checkbox/checkbox.css +3 -3
  23. package/dist/collection/components/drawer/drawer.css +1 -1
  24. package/dist/collection/components/global-nav/global-nav.js +30 -42
  25. package/dist/collection/components/global-nav/global-nav.js.map +1 -1
  26. package/dist/collection/components/global-nav/style/global-nav.css +2 -2
  27. package/dist/collection/components/hero/hero.css +2 -2
  28. package/dist/collection/components/input/input.css +3 -3
  29. package/dist/collection/components/nav-item/nav-item.css +2 -0
  30. package/dist/collection/components/progress-bar/progress-bar.css +2 -2
  31. package/dist/collection/components/range/range.css +1 -1
  32. package/dist/collection/components/select/select.css +3 -3
  33. package/dist/collection/components/skeleton/skeleton.css +2 -2
  34. package/dist/collection/components/slides/slides.css +5 -1
  35. package/dist/collection/components/slides/slides.js +9 -12
  36. package/dist/collection/components/slides/slides.js.map +1 -1
  37. package/dist/collection/components/spinner/spinner.css +2 -2
  38. package/dist/collection/components/tabs/tab.css +2 -2
  39. package/dist/components/nano-checkbox.js.map +1 -1
  40. package/dist/components/nano-drawer.js.map +1 -1
  41. package/dist/components/nano-global-nav.js +30 -42
  42. package/dist/components/nano-global-nav.js.map +1 -1
  43. package/dist/components/nano-hero.js +1 -1
  44. package/dist/components/nano-hero.js.map +1 -1
  45. package/dist/components/nano-range.js.map +1 -1
  46. package/dist/components/nano-slides.js +10 -13
  47. package/dist/components/nano-slides.js.map +1 -1
  48. package/dist/components/nano-tab.js.map +1 -1
  49. package/dist/components/nav-item.js +1 -1
  50. package/dist/components/nav-item.js.map +1 -1
  51. package/dist/components/progress-bar.js.map +1 -1
  52. package/dist/components/skeleton.js.map +1 -1
  53. package/dist/components/spinner.js.map +1 -1
  54. package/dist/esm/nano-checkbox.entry.js.map +1 -1
  55. package/dist/esm/nano-drawer.entry.js.map +1 -1
  56. package/dist/esm/nano-global-nav-user-profile_3.entry.js +1 -1
  57. package/dist/esm/nano-global-nav-user-profile_3.entry.js.map +1 -1
  58. package/dist/esm/nano-global-nav.entry.js +30 -41
  59. package/dist/esm/nano-global-nav.entry.js.map +1 -1
  60. package/dist/esm/nano-hero.entry.js +1 -1
  61. package/dist/esm/nano-hero.entry.js.map +1 -1
  62. package/dist/esm/nano-progress-bar_2.entry.js.map +1 -1
  63. package/dist/esm/nano-range.entry.js.map +1 -1
  64. package/dist/esm/nano-resize-observe_2.entry.js.map +1 -1
  65. package/dist/esm/nano-slides.entry.js +10 -13
  66. package/dist/esm/nano-slides.entry.js.map +1 -1
  67. package/dist/esm/nano-spinner.entry.js.map +1 -1
  68. package/dist/esm/nano-tab.entry.js.map +1 -1
  69. package/dist/esm/{nano-table-e64af51e.js → nano-table-c46586f1.js} +2 -2
  70. package/dist/esm/{nano-table-e64af51e.js.map → nano-table-c46586f1.js.map} +1 -1
  71. package/dist/esm/nano-table.entry.js +1 -1
  72. package/dist/esm/{table.worker-2f887b5f.js → table.worker-72318b56.js} +2 -2
  73. package/dist/esm/table.worker-72318b56.js.map +1 -0
  74. package/dist/nano-components/nano-components.esm.js +1 -1
  75. package/dist/nano-components/p-17eebe94.entry.js.map +1 -1
  76. package/dist/nano-components/p-4bbb04d3.entry.js.map +1 -1
  77. package/dist/nano-components/{p-add3ac22.js → p-4c5e0c9e.js} +2 -2
  78. package/dist/nano-components/{p-3d27d563.entry.js → p-4f17deb9.entry.js} +3 -3
  79. package/dist/nano-components/{p-3d27d563.entry.js.map → p-4f17deb9.entry.js.map} +1 -1
  80. package/dist/nano-components/p-63f1e229.entry.js.map +1 -1
  81. package/dist/nano-components/p-75df97c2.entry.js +5 -0
  82. package/dist/nano-components/p-75df97c2.entry.js.map +1 -0
  83. package/dist/nano-components/p-7733f1f8.entry.js.map +1 -1
  84. package/dist/nano-components/p-8332890e.js +5 -0
  85. package/dist/nano-components/{p-80ddfa30.entry.js → p-8c04640c.entry.js} +2 -2
  86. package/dist/nano-components/p-dc88e52b.entry.js.map +1 -1
  87. package/dist/nano-components/p-e113074e.entry.js.map +1 -1
  88. package/dist/nano-components/{p-80ecc273.entry.js → p-e44332c2.entry.js} +2 -2
  89. package/dist/nano-components/p-e44332c2.entry.js.map +1 -0
  90. package/dist/nano-components/p-ece694af.entry.js.map +1 -1
  91. package/dist/nano-components/p-fa676bc6.entry.js +5 -0
  92. package/dist/nano-components/p-fa676bc6.entry.js.map +1 -0
  93. package/dist/themes/nanopore.cn.css +1 -0
  94. package/dist/themes/nanopore.cn.css.map +1 -0
  95. package/dist/types/components/global-nav/global-nav.d.ts +1 -0
  96. package/docs-json.json +22 -22
  97. package/hydrate/index.js +42 -49
  98. package/package.json +2 -2
  99. package/dist/cjs/table.worker-f902766e.js.map +0 -1
  100. package/dist/esm/table.worker-2f887b5f.js.map +0 -1
  101. package/dist/nano-components/p-0e2f0040.entry.js +0 -5
  102. package/dist/nano-components/p-0e2f0040.entry.js.map +0 -1
  103. package/dist/nano-components/p-80ecc273.entry.js.map +0 -1
  104. package/dist/nano-components/p-a145fbc1.js +0 -5
  105. package/dist/nano-components/p-b4b55f64.entry.js +0 -5
  106. package/dist/nano-components/p-b4b55f64.entry.js.map +0 -1
  107. /package/dist/nano-components/{p-add3ac22.js.map → p-4c5e0c9e.js.map} +0 -0
  108. /package/dist/nano-components/{p-80ddfa30.entry.js.map → p-8332890e.js.map} +0 -0
  109. /package/dist/nano-components/{p-a145fbc1.js.map → p-8c04640c.entry.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"names":["drawerCss","id","Drawer","this","componentId","handleOpenChange","open","show","hide","handleTypeChange","type","contentEle","console","warn","handleContentSelector","contentSelector","host","ownerDocument","querySelector","connectedCallback","handleCloseClick","bind","handleTransitionEnd","handleKeyDown","handleOverlayClick","handleSlotChange","modal","Modal","componentWillLoad","disconnectedCallback","unlockBodyScrolling","async","isVisible","nanoShow","emit","defaultPrevented","contained","activate","lockBodyScrolling","style","right","transition","position","overflow","setTimeout","_","nanoHide","deactivate","event","key","slOverlayDismiss","nanoOverlayDismiss","hasFooter","target","propertyName","classList","contains","nanoAfterShow","nanoAfterHide","panel","focus","render","placementClass","placement","typeClass","h","Host","part","class","drawer","onKeyDown","onTransitionEnd","onClick","ref","el","role","noHeader","label","tabIndex","name","String","fromCharCode","onSlotchange"],"sources":["./src/components/drawer/drawer.scss?tag=nano-drawer&encapsulation=shadow","./src/components/drawer/drawer.tsx"],"sourcesContent":["@import '../../global/style/utilities/globals';\n@import '../../global/style/utilities/css-patterns/visually_hidden';\n\n:host {\n /**\n * @prop --size: The preferred size of the drawer; width or height depending on placement. Note that the drawer will shrink to accommodate smaller screens. Defaults to 25rem\n * @prop --panel-background-color: background color of panel. Default to 'white'\n * @prop --panel-shadow: Defaults to '0 4px 16px rgba(0, 0, 0, 0.1)';\n * @prop --overlay-color: Defaults to 'hsla(203, 10%, 20%, 0.5)';\n */\n\n position: relative;\n display: block;\n\n --size: 25rem;\n --panel-background-color: white;\n --panel-shadow: 0 4px 16px rgb(0 0 0 / 10%);\n --overlay-color: hsl(203deg 10% 20% / 50%);\n}\n\n.drawer {\n inset-block-start: 0;\n inset-inline-start: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n\n &:not(.drawer--visible) {\n @include hidden;\n }\n}\n\n.drawer--contained {\n position: absolute;\n z-index: initial;\n}\n\n.drawer--fixed {\n position: fixed;\n z-index: 2000;\n}\n\n.drawer__panel {\n position: absolute;\n display: flex;\n flex-direction: column;\n z-index: 2;\n max-width: 100%;\n max-height: 100%;\n background-color: var(--panel-background-color);\n box-shadow: var(--panel-shadow);\n transition: 250ms transform;\n overflow: auto;\n pointer-events: all;\n\n &:focus {\n outline: none;\n }\n}\n\n.drawer--start .drawer__panel {\n @include transform(translate3d(-100%, 0, 0));\n\n inset-block: 0 auto;\n width: var(--size);\n height: 100%;\n}\n\n.drawer--end .drawer__panel {\n @include transform(translate3d(100%, 0, 0));\n\n inset-block: 0 auto;\n width: var(--size);\n height: 100%;\n}\n\n.drawer--top .drawer__panel {\n inset-inline: auto 0;\n inset-block: 0 auto;\n width: 100%;\n height: var(--size);\n transform: translate(0, -100%);\n}\n\n.drawer--bottom .drawer__panel {\n inset-inline: auto 0;\n inset-block: auto 0;\n width: 100%;\n height: var(--size);\n transform: translate(0, 100%);\n}\n\n.drawer--open .drawer__panel {\n transform: translate(0, 0);\n}\n\n.drawer__header {\n display: flex;\n}\n\n.drawer__title {\n flex: 1 1 auto;\n // font-size: var(--sl-font-size-large);\n // line-height: var(--sl-line-height-dense);\n padding: 20px;\n}\n\n.drawer__close {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n // font-size: var(--sl-font-size-x-large);\n // padding: 0 var(--sl-spacing-large);\n}\n\n.drawer__body {\n flex: 1 1 auto;\n // padding: var(--sl-spacing-large);\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.drawer__footer {\n text-align: end;\n // padding: var(--sl-spacing-large);\n\n // ::slotted(sl-button:not(:last-of-type)) {\n // margin-right: var(--sl-spacing-x-small);\n // }\n}\n\n.drawer:not(.drawer--has-footer) .drawer__footer {\n display: none;\n}\n\n.drawer__overlay {\n display: block;\n position: fixed;\n inset: 0;\n background-color: var(--overlay-color);\n opacity: 0;\n transition: 250ms opacity;\n pointer-events: all;\n}\n\n.drawer--contained .drawer__overlay {\n position: absolute;\n}\n\n.drawer--open .drawer__overlay {\n opacity: 1;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport Modal from '../../utils/modal';\nimport { lockBodyScrolling, unlockBodyScrolling } from '../../utils/scroll';\n\nlet id = 0;\n\n/**\n * WIP / TODO. https://git.oxfordnanolabs.local/Digital/nano-components/-/issues/24\n * @slot - The drawer's content.\n * @slot label - The dialog's label. Alternatively, you can use the label prop.\n * @slot footer - The drawer's footer, usually one or more buttons representing various options.\n */\n@Component({\n tag: 'nano-drawer',\n styleUrl: 'drawer.scss',\n shadow: true,\n})\nexport class Drawer {\n private componentId = `drawer-${++id}`;\n private modal: Modal;\n private panel: HTMLElement;\n private contentEle: HTMLElement;\n\n @Element() host: HTMLNanoDrawerElement;\n\n @State() hasFooter = false;\n @State() isVisible = false;\n\n /**\n * Indicates whether or not the drawer is open. You can use this in lieu of the show/hide methods.\n */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /**\n * The drawer's label as displayed in the header. You should always include a relevant label even when using\n * `no-header`, as it is required for proper accessibility.\n */\n @Prop() label = '';\n\n /** The direction from which the drawer will open. */\n @Prop() placement: 'top' | 'end' | 'bottom' | 'start' = 'end';\n\n /**\n * By default, the drawer slides out of its containing block (usually the viewport). To make the drawer slide out of\n * its parent element, set this prop and add `position: relative` to the parent.\n */\n @Prop() contained = false;\n\n /**\n * Removes the header. This will also remove the default close button, so please ensure you provide an easy,\n * accessible way for users to dismiss the drawer.\n */\n @Prop() noHeader = false;\n\n /**\n * The display type of the drawer\n */\n @Prop() type: 'overlay' | 'reveal' | 'push' = 'overlay';\n\n /**\n * Required for 'reveal' and 'push' types\n * A valid DOM selector of the content element that this drawer will push or reveal underneath\n * Please remember - elements wrapping the content element must be 'overflow: hidden'\n * otherwise menus will be shown when closed\n */\n @Prop() contentSelector: string;\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n @Watch('type')\n handleTypeChange() {\n if (this.type !== 'push' && this.type !== 'reveal') return;\n if (!this.contentEle) {\n this.type = 'overlay';\n console.warn('a valid contentSelector must be set');\n return;\n }\n }\n\n @Watch('contentSelector')\n handleContentSelector() {\n if (!this.contentSelector) this.contentEle = null;\n else\n this.contentEle = (this.host.ownerDocument as Document).querySelector(\n this.contentSelector\n );\n }\n\n /**\n * Emitted when the drawer opens. Calling `event.preventDefault()` will prevent it from being opened.\n */\n @Event() nanoShow: EventEmitter;\n\n /**\n * Emitted after the drawer opens and all transitions are complete.\n */\n @Event() nanoAfterShow: EventEmitter;\n\n /**\n * Emitted when the drawer closes. Calling `event.preventDefault()` will prevent it from being closed.\n */\n @Event() nanoHide: EventEmitter;\n\n /**\n * Emitted after the drawer closes and all transitions are complete.\n */\n @Event() nanoAfterHide: EventEmitter;\n\n /**\n * Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the drawer from closing.\n */\n @Event() nanoOverlayDismiss: EventEmitter;\n\n connectedCallback() {\n this.handleCloseClick = this.handleCloseClick.bind(this);\n this.handleTransitionEnd = this.handleTransitionEnd.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleOverlayClick = this.handleOverlayClick.bind(this);\n this.handleSlotChange = this.handleSlotChange.bind(this);\n\n this.modal = new Modal(this.host);\n }\n\n componentWillLoad() {\n // Show on init if open\n if (this.open) {\n this.show();\n }\n this.handleContentSelector();\n }\n\n disconnectedCallback() {\n unlockBodyScrolling(this.host);\n }\n\n /** Shows the drawer */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible) {\n return;\n }\n\n const nanoShow = this.nanoShow.emit();\n if (nanoShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n\n // Lock body scrolling only if the drawer isn't contained\n if (!this.contained) {\n this.modal.activate();\n lockBodyScrolling(this.host);\n }\n\n if (!this.contentEle || (this.type !== 'push' && this.type !== 'reveal'))\n return;\n this.contentEle.style.right = '0';\n this.contentEle.style.transition = 'all ease 250ms';\n this.contentEle.style.position = 'relative';\n this.contentEle.style.overflow = 'hidden';\n setTimeout((_) => (this.contentEle.style.right = '25rem'), 0);\n }\n\n /** Hides the drawer */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const nanoHide = this.nanoHide.emit();\n if (nanoHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.open = false;\n this.modal.deactivate();\n\n unlockBodyScrolling(this.host);\n\n if (!this.contentEle) return;\n this.contentEle.style.transition = '';\n this.contentEle.style.position = '';\n this.contentEle.style.overflow = '';\n this.contentEle.style.right = '';\n }\n\n private handleCloseClick() {\n this.hide();\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n this.hide();\n }\n }\n\n private handleOverlayClick() {\n const slOverlayDismiss = this.nanoOverlayDismiss.emit();\n\n if (!slOverlayDismiss.defaultPrevented) {\n this.hide();\n }\n }\n\n private handleSlotChange() {\n this.hasFooter = !!this.host.querySelector('[slot=\"footer\"]');\n }\n\n private handleTransitionEnd(event: TransitionEvent) {\n const target = event.target as HTMLElement;\n\n // Ensure we only emit one event when the target element is no longer visible\n if (\n event.propertyName === 'transform' &&\n target.classList.contains('drawer__panel')\n ) {\n this.isVisible = this.open;\n this.open ? this.nanoAfterShow.emit() : this.nanoAfterHide.emit();\n\n if (this.open) {\n this.panel.focus();\n }\n }\n }\n\n render() {\n const placementClass = 'drawer--' + this.placement;\n const typeClass = 'drawer--' + this.type;\n\n return (\n <Host>\n <div\n part=\"base\"\n class={{\n drawer: true,\n 'drawer--open': this.open,\n 'drawer--visible': this.isVisible,\n [typeClass]: true,\n [placementClass]: true,\n 'drawer--contained': this.contained,\n 'drawer--fixed': !this.contained,\n 'drawer--has-footer': this.hasFooter,\n }}\n onKeyDown={this.handleKeyDown}\n onTransitionEnd={this.handleTransitionEnd}\n >\n <div\n part=\"overlay\"\n class=\"drawer__overlay\"\n onClick={this.handleOverlayClick}\n />\n\n <div\n ref={(el) => (this.panel = el)}\n part=\"panel\"\n class=\"drawer__panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-hidden={this.open ? 'false' : 'true'}\n aria-label={this.noHeader ? this.label : null}\n aria-labelledby={\n !this.noHeader ? `${this.componentId}-title` : null\n }\n tabIndex={0}\n >\n {!this.noHeader && (\n <header part=\"header\" class=\"drawer__header\">\n <span\n part=\"title\"\n class=\"drawer__title\"\n id={`${this.componentId}-title`}\n >\n <slot name=\"label\">\n {/* If there's no label, use an invisible character to prevent the heading from collapsing */}\n {this.label || String.fromCharCode(65279)}\n </slot>\n </span>\n {/* <sl-icon-button part=\"close-button\" class=\"drawer__close\" name=\"x\" onClick={this.handleCloseClick} /> */}\n </header>\n )}\n\n <div part=\"body\" class=\"drawer__body\">\n <slot />\n </div>\n\n <footer part=\"footer\" class=\"drawer__footer\">\n <slot name=\"footer\" onSlotchange={this.handleSlotChange} />\n </footer>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["drawerCss","id","Drawer","this","componentId","handleOpenChange","open","show","hide","handleTypeChange","type","contentEle","console","warn","handleContentSelector","contentSelector","host","ownerDocument","querySelector","connectedCallback","handleCloseClick","bind","handleTransitionEnd","handleKeyDown","handleOverlayClick","handleSlotChange","modal","Modal","componentWillLoad","disconnectedCallback","unlockBodyScrolling","async","isVisible","nanoShow","emit","defaultPrevented","contained","activate","lockBodyScrolling","style","right","transition","position","overflow","setTimeout","_","nanoHide","deactivate","event","key","slOverlayDismiss","nanoOverlayDismiss","hasFooter","target","propertyName","classList","contains","nanoAfterShow","nanoAfterHide","panel","focus","render","placementClass","placement","typeClass","h","Host","part","class","drawer","onKeyDown","onTransitionEnd","onClick","ref","el","role","noHeader","label","tabIndex","name","String","fromCharCode","onSlotchange"],"sources":["./src/components/drawer/drawer.scss?tag=nano-drawer&encapsulation=shadow","./src/components/drawer/drawer.tsx"],"sourcesContent":["@import '../../global/style/utilities/globals';\n@import '../../global/style/utilities/css-patterns/visually_hidden';\n\n:host {\n /**\n * @prop --size: The preferred size of the drawer; width or height depending on placement. Note that the drawer will shrink to accommodate smaller screens. Defaults to 25rem\n * @prop --panel-background-color: background color of panel. Default to 'white'\n * @prop --panel-shadow: Defaults to '0 4px 16px rgb(0 0 0 / 10%)';\n * @prop --overlay-color: Defaults to 'hsla(203, 10%, 20%, 0.5)';\n */\n\n position: relative;\n display: block;\n\n --size: 25rem;\n --panel-background-color: white;\n --panel-shadow: 0 4px 16px rgb(0 0 0 / 10%);\n --overlay-color: hsl(203deg 10% 20% / 50%);\n}\n\n.drawer {\n inset-block-start: 0;\n inset-inline-start: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n overflow: hidden;\n\n &:not(.drawer--visible) {\n @include hidden;\n }\n}\n\n.drawer--contained {\n position: absolute;\n z-index: initial;\n}\n\n.drawer--fixed {\n position: fixed;\n z-index: 2000;\n}\n\n.drawer__panel {\n position: absolute;\n display: flex;\n flex-direction: column;\n z-index: 2;\n max-width: 100%;\n max-height: 100%;\n background-color: var(--panel-background-color);\n box-shadow: var(--panel-shadow);\n transition: 250ms transform;\n overflow: auto;\n pointer-events: all;\n\n &:focus {\n outline: none;\n }\n}\n\n.drawer--start .drawer__panel {\n @include transform(translate3d(-100%, 0, 0));\n\n inset-block: 0 auto;\n width: var(--size);\n height: 100%;\n}\n\n.drawer--end .drawer__panel {\n @include transform(translate3d(100%, 0, 0));\n\n inset-block: 0 auto;\n width: var(--size);\n height: 100%;\n}\n\n.drawer--top .drawer__panel {\n inset-inline: auto 0;\n inset-block: 0 auto;\n width: 100%;\n height: var(--size);\n transform: translate(0, -100%);\n}\n\n.drawer--bottom .drawer__panel {\n inset-inline: auto 0;\n inset-block: auto 0;\n width: 100%;\n height: var(--size);\n transform: translate(0, 100%);\n}\n\n.drawer--open .drawer__panel {\n transform: translate(0, 0);\n}\n\n.drawer__header {\n display: flex;\n}\n\n.drawer__title {\n flex: 1 1 auto;\n // font-size: var(--sl-font-size-large);\n // line-height: var(--sl-line-height-dense);\n padding: 20px;\n}\n\n.drawer__close {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n // font-size: var(--sl-font-size-x-large);\n // padding: 0 var(--sl-spacing-large);\n}\n\n.drawer__body {\n flex: 1 1 auto;\n // padding: var(--sl-spacing-large);\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.drawer__footer {\n text-align: end;\n // padding: var(--sl-spacing-large);\n\n // ::slotted(sl-button:not(:last-of-type)) {\n // margin-right: var(--sl-spacing-x-small);\n // }\n}\n\n.drawer:not(.drawer--has-footer) .drawer__footer {\n display: none;\n}\n\n.drawer__overlay {\n display: block;\n position: fixed;\n inset: 0;\n background-color: var(--overlay-color);\n opacity: 0;\n transition: 250ms opacity;\n pointer-events: all;\n}\n\n.drawer--contained .drawer__overlay {\n position: absolute;\n}\n\n.drawer--open .drawer__overlay {\n opacity: 1;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport Modal from '../../utils/modal';\nimport { lockBodyScrolling, unlockBodyScrolling } from '../../utils/scroll';\n\nlet id = 0;\n\n/**\n * WIP / TODO. https://git.oxfordnanolabs.local/Digital/nano-components/-/issues/24\n * @slot - The drawer's content.\n * @slot label - The dialog's label. Alternatively, you can use the label prop.\n * @slot footer - The drawer's footer, usually one or more buttons representing various options.\n */\n@Component({\n tag: 'nano-drawer',\n styleUrl: 'drawer.scss',\n shadow: true,\n})\nexport class Drawer {\n private componentId = `drawer-${++id}`;\n private modal: Modal;\n private panel: HTMLElement;\n private contentEle: HTMLElement;\n\n @Element() host: HTMLNanoDrawerElement;\n\n @State() hasFooter = false;\n @State() isVisible = false;\n\n /**\n * Indicates whether or not the drawer is open. You can use this in lieu of the show/hide methods.\n */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /**\n * The drawer's label as displayed in the header. You should always include a relevant label even when using\n * `no-header`, as it is required for proper accessibility.\n */\n @Prop() label = '';\n\n /** The direction from which the drawer will open. */\n @Prop() placement: 'top' | 'end' | 'bottom' | 'start' = 'end';\n\n /**\n * By default, the drawer slides out of its containing block (usually the viewport). To make the drawer slide out of\n * its parent element, set this prop and add `position: relative` to the parent.\n */\n @Prop() contained = false;\n\n /**\n * Removes the header. This will also remove the default close button, so please ensure you provide an easy,\n * accessible way for users to dismiss the drawer.\n */\n @Prop() noHeader = false;\n\n /**\n * The display type of the drawer\n */\n @Prop() type: 'overlay' | 'reveal' | 'push' = 'overlay';\n\n /**\n * Required for 'reveal' and 'push' types\n * A valid DOM selector of the content element that this drawer will push or reveal underneath\n * Please remember - elements wrapping the content element must be 'overflow: hidden'\n * otherwise menus will be shown when closed\n */\n @Prop() contentSelector: string;\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n @Watch('type')\n handleTypeChange() {\n if (this.type !== 'push' && this.type !== 'reveal') return;\n if (!this.contentEle) {\n this.type = 'overlay';\n console.warn('a valid contentSelector must be set');\n return;\n }\n }\n\n @Watch('contentSelector')\n handleContentSelector() {\n if (!this.contentSelector) this.contentEle = null;\n else\n this.contentEle = (this.host.ownerDocument as Document).querySelector(\n this.contentSelector\n );\n }\n\n /**\n * Emitted when the drawer opens. Calling `event.preventDefault()` will prevent it from being opened.\n */\n @Event() nanoShow: EventEmitter;\n\n /**\n * Emitted after the drawer opens and all transitions are complete.\n */\n @Event() nanoAfterShow: EventEmitter;\n\n /**\n * Emitted when the drawer closes. Calling `event.preventDefault()` will prevent it from being closed.\n */\n @Event() nanoHide: EventEmitter;\n\n /**\n * Emitted after the drawer closes and all transitions are complete.\n */\n @Event() nanoAfterHide: EventEmitter;\n\n /**\n * Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the drawer from closing.\n */\n @Event() nanoOverlayDismiss: EventEmitter;\n\n connectedCallback() {\n this.handleCloseClick = this.handleCloseClick.bind(this);\n this.handleTransitionEnd = this.handleTransitionEnd.bind(this);\n this.handleKeyDown = this.handleKeyDown.bind(this);\n this.handleOverlayClick = this.handleOverlayClick.bind(this);\n this.handleSlotChange = this.handleSlotChange.bind(this);\n\n this.modal = new Modal(this.host);\n }\n\n componentWillLoad() {\n // Show on init if open\n if (this.open) {\n this.show();\n }\n this.handleContentSelector();\n }\n\n disconnectedCallback() {\n unlockBodyScrolling(this.host);\n }\n\n /** Shows the drawer */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible) {\n return;\n }\n\n const nanoShow = this.nanoShow.emit();\n if (nanoShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n\n // Lock body scrolling only if the drawer isn't contained\n if (!this.contained) {\n this.modal.activate();\n lockBodyScrolling(this.host);\n }\n\n if (!this.contentEle || (this.type !== 'push' && this.type !== 'reveal'))\n return;\n this.contentEle.style.right = '0';\n this.contentEle.style.transition = 'all ease 250ms';\n this.contentEle.style.position = 'relative';\n this.contentEle.style.overflow = 'hidden';\n setTimeout((_) => (this.contentEle.style.right = '25rem'), 0);\n }\n\n /** Hides the drawer */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const nanoHide = this.nanoHide.emit();\n if (nanoHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.open = false;\n this.modal.deactivate();\n\n unlockBodyScrolling(this.host);\n\n if (!this.contentEle) return;\n this.contentEle.style.transition = '';\n this.contentEle.style.position = '';\n this.contentEle.style.overflow = '';\n this.contentEle.style.right = '';\n }\n\n private handleCloseClick() {\n this.hide();\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n this.hide();\n }\n }\n\n private handleOverlayClick() {\n const slOverlayDismiss = this.nanoOverlayDismiss.emit();\n\n if (!slOverlayDismiss.defaultPrevented) {\n this.hide();\n }\n }\n\n private handleSlotChange() {\n this.hasFooter = !!this.host.querySelector('[slot=\"footer\"]');\n }\n\n private handleTransitionEnd(event: TransitionEvent) {\n const target = event.target as HTMLElement;\n\n // Ensure we only emit one event when the target element is no longer visible\n if (\n event.propertyName === 'transform' &&\n target.classList.contains('drawer__panel')\n ) {\n this.isVisible = this.open;\n this.open ? this.nanoAfterShow.emit() : this.nanoAfterHide.emit();\n\n if (this.open) {\n this.panel.focus();\n }\n }\n }\n\n render() {\n const placementClass = 'drawer--' + this.placement;\n const typeClass = 'drawer--' + this.type;\n\n return (\n <Host>\n <div\n part=\"base\"\n class={{\n drawer: true,\n 'drawer--open': this.open,\n 'drawer--visible': this.isVisible,\n [typeClass]: true,\n [placementClass]: true,\n 'drawer--contained': this.contained,\n 'drawer--fixed': !this.contained,\n 'drawer--has-footer': this.hasFooter,\n }}\n onKeyDown={this.handleKeyDown}\n onTransitionEnd={this.handleTransitionEnd}\n >\n <div\n part=\"overlay\"\n class=\"drawer__overlay\"\n onClick={this.handleOverlayClick}\n />\n\n <div\n ref={(el) => (this.panel = el)}\n part=\"panel\"\n class=\"drawer__panel\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-hidden={this.open ? 'false' : 'true'}\n aria-label={this.noHeader ? this.label : null}\n aria-labelledby={\n !this.noHeader ? `${this.componentId}-title` : null\n }\n tabIndex={0}\n >\n {!this.noHeader && (\n <header part=\"header\" class=\"drawer__header\">\n <span\n part=\"title\"\n class=\"drawer__title\"\n id={`${this.componentId}-title`}\n >\n <slot name=\"label\">\n {/* If there's no label, use an invisible character to prevent the heading from collapsing */}\n {this.label || String.fromCharCode(65279)}\n </slot>\n </span>\n {/* <sl-icon-button part=\"close-button\" class=\"drawer__close\" name=\"x\" onClick={this.handleCloseClick} /> */}\n </header>\n )}\n\n <div part=\"body\" class=\"drawer__body\">\n <slot />\n </div>\n\n <footer part=\"footer\" class=\"drawer__footer\">\n <slot name=\"footer\" onSlotchange={this.handleSlotChange} />\n </footer>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":";;;+LAAA,MAAMA,EAAY,qqECelB,IAAIC,EAAK,E,MAaIC,EAAM,M,gPACTC,KAAAC,YAAc,YAAYH,I,eAOb,M,eACA,M,UAK0B,M,WAM/B,G,eAGwC,M,eAMpC,M,cAMD,M,UAK2B,U,+BAW9CI,mBACEF,KAAKG,KAAOH,KAAKI,OAASJ,KAAKK,M,CAIjCC,mBACE,GAAIN,KAAKO,OAAS,QAAUP,KAAKO,OAAS,SAAU,OACpD,IAAKP,KAAKQ,WAAY,CACpBR,KAAKO,KAAO,UACZE,QAAQC,KAAK,uCACb,M,EAKJC,wBACE,IAAKX,KAAKY,gBAAiBZ,KAAKQ,WAAa,UAE3CR,KAAKQ,WAAcR,KAAKa,KAAKC,cAA2BC,cACtDf,KAAKY,gB,CA6BXI,oBACEhB,KAAKiB,iBAAmBjB,KAAKiB,iBAAiBC,KAAKlB,MACnDA,KAAKmB,oBAAsBnB,KAAKmB,oBAAoBD,KAAKlB,MACzDA,KAAKoB,cAAgBpB,KAAKoB,cAAcF,KAAKlB,MAC7CA,KAAKqB,mBAAqBrB,KAAKqB,mBAAmBH,KAAKlB,MACvDA,KAAKsB,iBAAmBtB,KAAKsB,iBAAiBJ,KAAKlB,MAEnDA,KAAKuB,MAAQ,IAAIC,EAAMxB,KAAKa,K,CAG9BY,oBAEE,GAAIzB,KAAKG,KAAM,CACbH,KAAKI,M,CAEPJ,KAAKW,uB,CAGPe,uBACEC,EAAoB3B,KAAKa,K,CAK3Be,aAEE,GAAI5B,KAAK6B,UAAW,CAClB,M,CAGF,MAAMC,EAAW9B,KAAK8B,SAASC,OAC/B,GAAID,EAASE,iBAAkB,CAC7BhC,KAAKG,KAAO,MACZ,M,CAGFH,KAAK6B,UAAY,KACjB7B,KAAKG,KAAO,KAGZ,IAAKH,KAAKiC,UAAW,CACnBjC,KAAKuB,MAAMW,WACXC,EAAkBnC,KAAKa,K,CAGzB,IAAKb,KAAKQ,YAAeR,KAAKO,OAAS,QAAUP,KAAKO,OAAS,SAC7D,OACFP,KAAKQ,WAAW4B,MAAMC,MAAQ,IAC9BrC,KAAKQ,WAAW4B,MAAME,WAAa,iBACnCtC,KAAKQ,WAAW4B,MAAMG,SAAW,WACjCvC,KAAKQ,WAAW4B,MAAMI,SAAW,SACjCC,YAAYC,GAAO1C,KAAKQ,WAAW4B,MAAMC,MAAQ,SAAU,E,CAK7DT,aAEE,IAAK5B,KAAK6B,UAAW,CACnB,M,CAGF,MAAMc,EAAW3C,KAAK2C,SAASZ,OAC/B,GAAIY,EAASX,iBAAkB,CAC7BhC,KAAKG,KAAO,KACZ,M,CAGFH,KAAKG,KAAO,MACZH,KAAKuB,MAAMqB,aAEXjB,EAAoB3B,KAAKa,MAEzB,IAAKb,KAAKQ,WAAY,OACtBR,KAAKQ,WAAW4B,MAAME,WAAa,GACnCtC,KAAKQ,WAAW4B,MAAMG,SAAW,GACjCvC,KAAKQ,WAAW4B,MAAMI,SAAW,GACjCxC,KAAKQ,WAAW4B,MAAMC,MAAQ,E,CAGxBpB,mBACNjB,KAAKK,M,CAGCe,cAAcyB,GACpB,GAAIA,EAAMC,MAAQ,SAAU,CAC1B9C,KAAKK,M,EAIDgB,qBACN,MAAM0B,EAAmB/C,KAAKgD,mBAAmBjB,OAEjD,IAAKgB,EAAiBf,iBAAkB,CACtChC,KAAKK,M,EAIDiB,mBACNtB,KAAKiD,YAAcjD,KAAKa,KAAKE,cAAc,kB,CAGrCI,oBAAoB0B,GAC1B,MAAMK,EAASL,EAAMK,OAGrB,GACEL,EAAMM,eAAiB,aACvBD,EAAOE,UAAUC,SAAS,iBAC1B,CACArD,KAAK6B,UAAY7B,KAAKG,KACtBH,KAAKG,KAAOH,KAAKsD,cAAcvB,OAAS/B,KAAKuD,cAAcxB,OAE3D,GAAI/B,KAAKG,KAAM,CACbH,KAAKwD,MAAMC,O,GAKjBC,SACE,MAAMC,EAAiB,WAAa3D,KAAK4D,UACzC,MAAMC,EAAY,WAAa7D,KAAKO,KAEpC,OACEuD,EAACC,EAAI,KACHD,EAAA,OACEE,KAAK,OACLC,MAAO,CACLC,OAAQ,KACR,eAAgBlE,KAAKG,KACrB,kBAAmBH,KAAK6B,UACxBgC,CAACA,GAAY,KACbF,CAACA,GAAiB,KAClB,oBAAqB3D,KAAKiC,UAC1B,iBAAkBjC,KAAKiC,UACvB,qBAAsBjC,KAAKiD,WAE7BkB,UAAWnE,KAAKoB,cAChBgD,gBAAiBpE,KAAKmB,qBAEtB2C,EAAA,OACEE,KAAK,UACLC,MAAM,kBACNI,QAASrE,KAAKqB,qBAGhByC,EAAA,OACEQ,IAAMC,GAAQvE,KAAKwD,MAAQe,EAC3BP,KAAK,QACLC,MAAM,gBACNO,KAAK,SAAQ,aACF,OAAM,cACJxE,KAAKG,KAAO,QAAU,OAAM,aAC7BH,KAAKyE,SAAWzE,KAAK0E,MAAQ,KAAI,mBAE1C1E,KAAKyE,SAAW,GAAGzE,KAAKC,oBAAsB,KAEjD0E,SAAU,IAER3E,KAAKyE,UACLX,EAAA,UAAQE,KAAK,SAASC,MAAM,kBAC1BH,EAAA,QACEE,KAAK,QACLC,MAAM,gBACNnE,GAAI,GAAGE,KAAKC,qBAEZ6D,EAAA,QAAMc,KAAK,SAER5E,KAAK0E,OAASG,OAAOC,aAAa,UAO3ChB,EAAA,OAAKE,KAAK,OAAOC,MAAM,gBACrBH,EAAA,cAGFA,EAAA,UAAQE,KAAK,SAASC,MAAM,kBAC1BH,EAAA,QAAMc,KAAK,SAASG,aAAc/E,KAAKsB,sB"}
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Web Components for Nanopore digital Web Apps
3
+ */
4
+ import{r as n,h as t,a as i,g as e}from"./p-6ef53fa1.js";const o=":host {\n box-sizing: border-box;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n[hidden] {\n display: none !important;\n}\n/**\nTODO - as soon as container queries hits everywhere, strip out reliance on nano-grid breakpoints\n**/\n:host {\n /**\n * @prop --nano-loader-base: Base colour of nano-skeleton. Default depends on theme;\n * @prop --nano-loader-tint: Tint colour of nano-skeleton. Default depends on theme;\n * @prop --theme-color: Text color. Default depends on theme;\n * @prop --theme-tint-color: Color used for bread crumbs and icons. Defaults to #90c6e7;\n * @prop --scrim-color: Color of the gradient covering the background. Default depends on theme;\n * @prop --scrim-direction: Direction of the gradient covering the background. Default what content slots are present;\n * @prop --scrim-opacity-from: Starting opactiy of the gradient covering the background. Default .25;\n * @prop --scrim-opacity-to: Final opactiy of the gradient covering the background. Default depends on `theme`;\n * @prop --quote-size: Font size of the quote. Defaults to 1.3em and grows to 3rem on the xl breakpoint;\n */\n display: block;\n --nano-loader-base: #4a4a4a;\n --nano-loader-tint: #7d7d7d;\n --theme-color: #fff;\n --theme-tint-color: #90c6e7;\n --scrim-color: 0 0 0;\n --scrim-direction: 90deg;\n --scrim-opacity-from: 0.25;\n --scrim-opacity-to: 0.7;\n --padding: 0;\n --quote-size: 1.3rem;\n color: var(--theme-color);\n}\n\n:host(.is-xl) {\n --quote-size: 3rem;\n}\n\n:host([theme=light]) {\n --nano-loader-base: #fff;\n --nano-loader-tint: white;\n --theme-color: #4a4a4a;\n --scrim-color: 255 255 255;\n --scrim-opacity-from: 0.25;\n --scrim-opacity-to: 1;\n --scrim-direction: 270deg;\n color: var(--theme-color);\n}\n:host([theme=light]) .hero__primary-content {\n --color: #4a4a4a;\n}\n\n.hero {\n position: relative;\n}\n.hero--rtl {\n --scrim-direction: 270deg;\n}\n.hero--secondary:not(.hero--iconbox) {\n --scrim-direction: 0deg;\n}\n.hero__bg-wrap {\n overflow: hidden;\n}\n.hero__bg-slot {\n position: absolute;\n inset: 0;\n}\n.hero__ctas {\n display: flex;\n justify-content: flex-end;\n padding-block: 32px 0;\n padding-inline: 32px;\n -webkit-margin-after: -64px;\n margin-block-end: -64px;\n position: relative;\n z-index: 1;\n}\n@media (max-width: 52em) {\n .hero__ctas {\n display: none;\n }\n}\n@media (max-width: 58em) {\n .hero__ctas {\n -webkit-margin-after: -48px;\n margin-block-end: -48px;\n }\n}\n.hero__ctas ::slotted(a.button[slot=secondary-ctas]) {\n padding-block: 0.25rem !important;\n padding-inline: 0.5rem !important;\n font-size: 0.875rem !important;\n margin-block: 0 !important;\n margin-inline: 0.25rem !important;\n}\n.hero__img {\n display: block;\n container-type: inline-size;\n --padding: inherit;\n}\n.hero__breadcrumbs {\n display: none;\n margin-block: 20px 0;\n margin-inline: 14px;\n line-height: 14px;\n}\n.hero--breadcrumb .hero__breadcrumbs {\n display: block;\n}\n.is-xl .hero__breadcrumbs {\n margin-block: 0;\n margin-inline: 50px;\n max-inline-size: 50%;\n}\n@container (min-width: 800px) {\n .hero__breadcrumbs {\n margin-block: 0;\n margin-inline: 50px;\n max-inline-size: 50%;\n }\n}\n.is-xxl .hero__breadcrumbs {\n margin-block: 0;\n margin-inline: 83px;\n}\n@container (min-width: 900px) {\n .hero__breadcrumbs {\n margin-block: 0;\n margin-inline: 83px;\n }\n}\n.hero__breadcrumbs ::slotted(*[slot=breadcrumb]) {\n font-size: 0.85rem;\n text-transform: uppercase;\n letter-spacing: 1.5px;\n font-weight: 600;\n font-stretch: 125%;\n display: inline-block;\n -webkit-margin-after: 16px;\n margin-block-end: 16px;\n position: relative;\n z-index: 2;\n}\n.hero--hasbg .hero__breadcrumbs ::slotted(*[slot=breadcrumb]) {\n text-shadow: 1px 1px rgba(0, 0, 0, 0.15);\n}\n.hero__breadcrumbs ::slotted(a[slot=breadcrumb]) {\n color: var(--theme-tint-color) !important;\n cursor: pointer;\n}\n.hero__breadcrumbs ::slotted(.slash[slot=breadcrumb]) {\n color: var(--theme-color);\n position: relative;\n margin-block: 0;\n margin-inline: 0.5rem;\n display: inline-block;\n}\n.hero__scrim {\n position: absolute;\n inset: 0;\n z-index: 0;\n background: linear-gradient(var(--scrim-direction), rgb(var(--scrim-color)/var(--scrim-opacity-from)) 0%, rgb(var(--scrim-color)/var(--scrim-opacity-to)) 100%);\n}\n.hero--scrim .hero__scrim {\n background: none;\n}\n.hero__content {\n max-inline-size: 1440px;\n display: block;\n --grid-row-gap: 0;\n margin-block: 0;\n margin-inline: auto;\n position: relative;\n}\n.hero__content.is-xl {\n -webkit-margin-before: 50px;\n margin-block-start: 50px;\n max-inline-size: 1540px;\n}\n@container (min-width: 800px) {\n .hero__content {\n margin-block: 50px 0 !important;\n max-inline-size: 1540px !important;\n }\n}\n.hero__content.is-xxl {\n -webkit-margin-before: 83px;\n margin-block-start: 83px;\n max-inline-size: 1606px;\n}\n@container (min-width: 900px) {\n .hero__content {\n margin-block: 83px 0 !important;\n max-inline-size: 1606px !important;\n }\n}\n.hero__primary {\n margin: 16px;\n}\n.hero--breadcrumb .hero__primary {\n margin-block: 0;\n margin-inline: 16px;\n}\n.hero--backbtn .hero__primary {\n -webkit-margin-start: 0;\n margin-inline-start: 0;\n}\n.hero__primary ::slotted(nano-icon-button[slot=back-btn]) {\n font-size: 2rem;\n}\n.is-xl .hero__primary {\n margin-block: 0 50px;\n margin-inline: 50px 0;\n}\n.is-xl .hero__primary ::slotted(nano-icon-button[slot=back-btn]) {\n margin-block: 0;\n margin-inline: -3rem 0;\n}\n@container (min-width: 800px) {\n .hero__primary {\n margin-block: 0 50px !important;\n margin-inline: 50px 0 !important;\n }\n .hero__primary ::slotted(nano-icon-button[slot=back-btn]) {\n margin-block: 0 !important;\n margin-inline: -3rem 0 !important;\n }\n}\n.is-xxl .hero__primary {\n margin-block: 0 83px !important;\n margin-inline: 83px 0 !important;\n}\n@container (min-width: 900px) {\n .hero__primary {\n margin-block: 0 83px !important;\n margin-inline: 83px 0 !important;\n }\n}\n.hero__primary-content {\n max-inline-size: 45rem;\n --color: #fff;\n display: flex;\n}\n.hero--backbtn .hero__primary-content > div {\n padding-block: 10px 0;\n padding-inline: 0;\n}\n.hero__primary-content ::slotted(h1[slot=primary-content]) {\n line-height: 26px !important;\n margin-block: 0 18px !important;\n font-size: 2rem !important;\n}\n.is-xl .hero__primary-content ::slotted(h1[slot=primary-content]) {\n line-height: 31px !important;\n -webkit-margin-after: 30px !important;\n margin-block-end: 30px !important;\n}\n.is-xl .hero__primary-content ::slotted(.button[slot=primary-content]) {\n -webkit-margin-before: 20px !important;\n margin-block-start: 20px !important;\n}\n@container (min-width: 800px) {\n .hero__primary-content ::slotted(h1[slot=primary-content]) {\n line-height: 31px !important;\n -webkit-margin-after: 30px !important;\n margin-block-end: 30px !important;\n }\n .hero__primary-content ::slotted(.button[slot=primary-content]) {\n -webkit-margin-before: 20px !important;\n margin-block-start: 20px !important;\n }\n}\n.hero__secondary {\n display: none;\n block-size: 100%;\n padding-block: 0 20px;\n padding-inline: 14px;\n}\n.hero--secondary .hero__secondary {\n display: flex;\n align-items: center;\n}\n.is-xl .hero__secondary {\n padding-block: 0 50px;\n padding-inline: 50px;\n justify-content: flex-end;\n}\n@container (min-width: 800px) {\n .hero__secondary {\n padding-block: 0 50px;\n padding-inline: 50px;\n justify-content: flex-end;\n }\n}\n.is-xxl .hero__secondary {\n padding-block: 0 83px;\n padding-inline: 83px;\n}\n@container (min-width: 900px) {\n .hero__secondary {\n padding-block: 0 83px;\n padding-inline: 83px;\n }\n}\n.hero__icon-box {\n background: rgba(0, 0, 0, 0.7);\n padding: 24px;\n inline-size: 100%;\n -webkit-margin-after: auto;\n margin-block-end: auto;\n display: flex;\n flex-direction: column;\n color: white;\n}\n.is-xl .hero__icon-box {\n max-inline-size: 410px;\n flex: 0 1 410px;\n}\n.hero__icon-box ::slotted([slot=icon-box-item]) {\n --nano-color-base: var(--theme-tint-color);\n --nano-icon-size: 32px;\n --nano-icon-margin-end: 20px;\n display: flex;\n align-items: center;\n font-size: 0.8125rem;\n -webkit-margin-after: 20px;\n margin-block-end: 20px;\n}\n.hero__icon-box ::slotted(.last[slot=icon-box-item]) {\n -webkit-margin-after: 0;\n margin-block-end: 0;\n}\n.hero__quote-content {\n -webkit-margin-before: auto;\n margin-block-start: auto;\n text-align: center;\n inline-size: 100%;\n}\n.is-xl .hero__quote-content {\n max-inline-size: 500px;\n flex: 0 1 500px;\n text-align: initial;\n}\n@container (min-width: 800px) {\n .hero__quote-content {\n max-inline-size: 500px;\n flex: 0 1 500px;\n text-align: initial;\n }\n}\n.hero__quote::before, .hero__quote::after {\n content: '\"';\n font-size: var(--quote-size);\n font-weight: 700;\n font-style: italic;\n line-height: 0;\n color: #abb6b8;\n display: inline;\n position: relative;\n}\n.hero__quote ::slotted([slot=quote]) {\n font-size: var(--quote-size);\n font-weight: 300;\n font-style: italic;\n display: inline;\n}\n.hero__quote-author {\n text-align: end;\n font-size: 1rem;\n opacity: 0.8;\n}\n.hero--sub .hero__content.is-xl {\n -webkit-margin-before: 40px;\n margin-block-start: 40px;\n}\n.hero--sub .hero__content.is-xl .hero__primary {\n margin-block: 0 40px;\n margin-inline: 50px 0;\n}\n.hero--sub .hero__content.is-xl .hero__secondary {\n padding-block: 0 50px;\n padding-inline: 40px 50px;\n}\n.hero--sub .hero__content.is-xl ::slotted(.button[slot=primary-content]) {\n -webkit-margin-before: 8px !important;\n margin-block-start: 8px !important;\n}\n.hero--sub .hero__content.is-xl ::slotted(h1[slot=primary-content]) {\n -webkit-margin-after: 18px !important;\n margin-block-end: 18px !important;\n}\n.hero--sub .hero__content.is-xxl .hero__primary {\n margin-block: 0 40px;\n margin-inline: 83px 0;\n}\n.hero--sub .hero__content.is-xxl .hero__secondary {\n padding-block: 0 83px;\n padding-inline: 40px 83px;\n}";const r=class{constructor(i){n(this,i);this.handleGridChange=n=>{this.gridSizes=n.detail};this.HeroContent=()=>[!this.hasIconBox&&this.hasCtas?t("div",{class:"hero__ctas"},t("slot",{name:"secondary-ctas"})):"",t("div",{class:"hero__scrim"},t("slot",{name:"scrim"})),t("nano-grid",{onNanoBpChange:this.handleGridChange,class:"hero__content",xlCols:2,xlSize:this.largeScreenBP},t("nano-grid-item",{gridStates:"xl-col-span-2"},t("div",{class:"hero__breadcrumbs"},t("slot",{name:"breadcrumb"}))),t("nano-grid-item",{gridStates:this.hasSecondaryContent?"xl-col-span-1 xl-col-start-1 xl-row-start-2":"xl-col-span-2 xl-col-start-1 xl-row-start-2"},t("div",{class:"hero__primary"},t("div",{class:"hero__primary-content"},t("slot",{name:"back-btn"}),t("div",null,t("slot",{name:"primary-content"}))))),this.hasSecondaryContent&&t("nano-grid-item",{gridStates:"xl-col-span-1 xl-col-start-2 xl-row-start-2"},t("div",{class:"hero__secondary"},t("slot",{name:"secondary-content"}),this.hasIconBox&&t("div",{class:"hero__icon-box"},t("slot",{name:"icon-box"}),t("slot",{name:"icon-box-item"})),this.hasQuote&&t("div",{class:"hero__quote-content"},t("span",{class:"hero__quote"},t("slot",{name:"quote"})),t("div",{class:"hero__quote-author"},t("slot",{name:"quote-author"}))))))];this.gridSizes=[];this.hasIconBox=undefined;this.hasScrim=undefined;this.hasSecondaryContent=undefined;this.hasQuote=undefined;this.hasBg=undefined;this.hasBackBtn=undefined;this.hasCtas=undefined;this.breadCrumbs=undefined;this.iconBoxItems=undefined;this.imgSrc=undefined;this.imgSrcSet=null;this.largeScreenBP=900;this.theme="dark";this.level="top"}breadCrumbChange(){this.breadCrumbs.filter((n=>n.tagName==="A"&&!n.nextElementSibling.classList.contains("slash"))).forEach((n=>{n.insertAdjacentHTML("afterend",'<span slot="breadcrumb" class="slash">/</span>')}))}iconBoxItemChange(){this.iconBoxItems.forEach((n=>n.classList.remove("last")));if(this.iconBoxItems[this.iconBoxItems.length-1]&&this.iconBoxItems[this.iconBoxItems.length-1].classList)this.iconBoxItems[this.iconBoxItems.length-1].classList.add("last")}slotChangeObserver(){if(!window["MutationObserver"])return;if(this.mo)this.mo.disconnect();const n=this.mo=new MutationObserver((()=>this.processSlottedContent()));n.observe(this.host,{childList:true})}processSlottedContent(){this.hasCtas=!!this.host.querySelector('[slot="secondary-ctas"]');this.iconBoxItems=Array.from(this.host.querySelectorAll('[slot="icon-box-item"]'));this.hasIconBox=!!this.host.querySelector('[slot="icon-box"]')||!!this.iconBoxItems.length;this.hasScrim=!!this.host.querySelector('[slot="scrim"]');this.breadCrumbs=Array.from(this.host.querySelectorAll('[slot="breadcrumb"]'));this.hasSecondaryContent=!!this.host.querySelector('[slot="icon-box"]')||!!this.host.querySelector('[slot="quote"]')||!!this.host.querySelector('[slot="icon-box-item"]')||!!this.host.querySelector('[slot="secondary-content"]');this.hasBg=!!this.host.querySelector('[slot="background"]')||!!this.imgSrc;this.hasBackBtn=!!this.host.querySelector('[slot="back-btn"]');this.hasQuote=!!this.host.querySelector('[slot="quote"]')}disconnectedCallback(){if(this.mo)this.mo.disconnect()}componentDidLoad(){this.slotChangeObserver()}componentWillLoad(){this.processSlottedContent()}render(){const n=this.host.dir==="rtl"||this.host.ownerDocument.dir==="rtl";return t(i,{class:{[this.gridSizes.join(" ")]:true}},t("div",{class:{hero:true,"hero--light":this.theme==="light","hero--secondary":this.hasSecondaryContent,"hero--iconbox":this.hasIconBox,"hero--rtl":n,"hero--scrim":this.hasScrim,"hero--breadcrumb":!!this.breadCrumbs.length,"hero--hasbg":this.hasBg,"hero--backbtn":this.hasBackBtn,"hero--sub":this.level==="sub"}},t("div",{class:"hero__bg-wrap"},!!this.imgSrc&&t("nano-img",{class:"hero__img",lazy:false,background:true,srcSet:this.imgSrcSet,src:this.imgSrc},t(this.HeroContent,null)),!this.imgSrc&&[t("div",{class:"hero__bg-slot"},t("slot",{name:"background"})),t(this.HeroContent,null)])))}get host(){return e(this)}static get watchers(){return{breadCrumbs:["breadCrumbChange"],iconBoxItems:["iconBoxItemChange"]}}};r.style=o;export{r as nano_hero};
5
+ //# sourceMappingURL=p-75df97c2.entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["heroCss","Hero","this","handleGridChange","e","gridSizes","detail","HeroContent","hasIconBox","hasCtas","h","class","name","onNanoBpChange","xlCols","xlSize","largeScreenBP","gridStates","hasSecondaryContent","hasQuote","breadCrumbChange","breadCrumbs","filter","crumb","tagName","nextElementSibling","classList","contains","forEach","insertAdjacentHTML","iconBoxItemChange","iconBoxItems","item","remove","length","add","slotChangeObserver","window","mo","disconnect","MutationObserver","processSlottedContent","observe","host","childList","querySelector","Array","from","querySelectorAll","hasScrim","hasBg","imgSrc","hasBackBtn","disconnectedCallback","componentDidLoad","componentWillLoad","render","rtl","dir","ownerDocument","Host","join","hero","theme","level","lazy","background","srcSet","imgSrcSet","src"],"sources":["./src/components/hero/hero.scss?tag=nano-hero&encapsulation=shadow","./src/components/hero/hero.tsx"],"sourcesContent":["@use 'sass:map';\n@use 'sass:list';\n\n@import '../../global/style/utilities/globals';\n@import '../../global/style/nano-theme/colours';\n\n/**\nTODO - as soon as container queries hits everywhere, strip out reliance on nano-grid breakpoints\n**/\n\n:host {\n /**\n * @prop --nano-loader-base: Base colour of nano-skeleton. Default depends on theme;\n * @prop --nano-loader-tint: Tint colour of nano-skeleton. Default depends on theme;\n * @prop --theme-color: Text color. Default depends on theme;\n * @prop --theme-tint-color: Color used for bread crumbs and icons. Defaults to #{map.get($colors, lightblue)};\n * @prop --scrim-color: Color of the gradient covering the background. Default depends on theme;\n * @prop --scrim-direction: Direction of the gradient covering the background. Default what content slots are present;\n * @prop --scrim-opacity-from: Starting opactiy of the gradient covering the background. Default .25;\n * @prop --scrim-opacity-to: Final opactiy of the gradient covering the background. Default depends on `theme`;\n * @prop --quote-size: Font size of the quote. Defaults to 1.3em and grows to 3rem on the xl breakpoint;\n */\n\n display: block;\n\n --nano-loader-base: #{map.get($colors, black)};\n --nano-loader-tint: #{lighten(map.get($colors, black), 20%)};\n --theme-color: #{map.get($colors, white)};\n --theme-tint-color: #{map.get($colors, lightblue)};\n --scrim-color: 0 0 0;\n --scrim-direction: 90deg;\n --scrim-opacity-from: 0.25;\n --scrim-opacity-to: 0.7;\n --padding: 0;\n --quote-size: 1.3rem;\n\n color: var(--theme-color);\n}\n\n:host(.is-xl) {\n --quote-size: 3rem;\n}\n\n:host([theme='light']) {\n --nano-loader-base: #{map.get($colors, white)};\n --nano-loader-tint: #{lighten(map.get($colors, white), 20%)};\n --theme-color: #{map.get($colors, black)};\n --scrim-color: 255 255 255;\n --scrim-opacity-from: 0.25;\n --scrim-opacity-to: 1;\n --scrim-direction: 270deg;\n\n color: var(--theme-color);\n\n .hero__primary-content {\n --color: #{map.get($colors, black)};\n }\n}\n\n.hero {\n position: relative;\n\n &--rtl {\n --scrim-direction: 270deg;\n }\n\n &--secondary:not(.hero--iconbox) {\n --scrim-direction: 0deg;\n }\n\n &__bg-wrap {\n overflow: hidden;\n }\n\n &__bg-slot {\n position: absolute;\n inset: 0;\n }\n\n &__ctas {\n @media (max-width: 52em) {\n display: none;\n }\n\n @media (max-width: 58em) {\n margin-block-end: -48px;\n }\n\n display: flex;\n justify-content: flex-end;\n padding-block: 32px 0;\n padding-inline: 32px;\n margin-block-end: -64px;\n position: relative;\n z-index: 1;\n\n ::slotted(a.button[slot='secondary-ctas']) {\n padding-block: 0.25rem !important;\n padding-inline: 0.5rem !important;\n font-size: 0.875rem !important;\n margin-block: 0 !important;\n margin-inline: 0.25rem !important;\n }\n }\n\n &__img {\n display: block;\n container-type: inline-size;\n\n --padding: inherit;\n }\n\n &__breadcrumbs {\n display: none;\n margin-block: 20px 0;\n margin-inline: 14px;\n line-height: 14px;\n\n .hero--breadcrumb & {\n display: block;\n }\n\n .is-xl & {\n margin-block: 0;\n margin-inline: 50px;\n max-inline-size: 50%;\n }\n\n @container (min-width: 800px) {\n margin-block: 0;\n margin-inline: 50px;\n max-inline-size: 50%;\n }\n\n .is-xxl & {\n margin-block: 0;\n margin-inline: 83px;\n }\n\n @container (min-width: 900px) {\n margin-block: 0;\n margin-inline: 83px;\n }\n\n ::slotted(*[slot='breadcrumb']) {\n font-size: 0.85rem;\n text-transform: uppercase;\n letter-spacing: 1.5px;\n font-weight: 600;\n font-stretch: 125%;\n display: inline-block;\n margin-block-end: 16px;\n position: relative;\n z-index: 2;\n\n .hero--hasbg & {\n text-shadow: 1px 1px rgb(0 0 0 / 15%);\n }\n }\n\n ::slotted(a[slot='breadcrumb']) {\n color: var(--theme-tint-color) !important;\n cursor: pointer;\n }\n\n ::slotted(.slash[slot='breadcrumb']) {\n color: var(--theme-color);\n position: relative;\n margin-block: 0;\n margin-inline: 0.5rem;\n display: inline-block;\n }\n }\n\n &__scrim {\n position: absolute;\n inset: 0;\n z-index: 0;\n background:\n linear-gradient(\n var(--scrim-direction),\n rgb(var(--scrim-color) / var(--scrim-opacity-from)) 0%,\n rgb(var(--scrim-color) / var(--scrim-opacity-to)) 100%\n );\n\n .hero--scrim & {\n background: none;\n }\n }\n\n &__content {\n max-inline-size: 1440px;\n display: block;\n\n --grid-row-gap: 0;\n\n margin-block: 0;\n margin-inline: auto;\n position: relative;\n\n &.is-xl {\n margin-block-start: 50px;\n max-inline-size: 1540px;\n }\n\n @container (min-width: 800px) {\n margin-block: 50px 0 !important;\n max-inline-size: 1540px !important;\n }\n\n &.is-xxl {\n margin-block-start: 83px;\n max-inline-size: 1606px;\n }\n\n @container (min-width: 900px) {\n margin-block: 83px 0 !important;\n max-inline-size: 1606px !important;\n }\n }\n\n &__primary {\n margin: 16px;\n\n .hero--breadcrumb & {\n margin-block: 0;\n margin-inline: 16px;\n }\n\n .hero--backbtn & {\n margin-inline-start: 0;\n }\n\n ::slotted(nano-icon-button[slot='back-btn']) {\n font-size: 2rem;\n }\n\n .is-xl & {\n margin-block: 0 50px;\n margin-inline: 50px 0;\n\n ::slotted(nano-icon-button[slot='back-btn']) {\n margin-block: 0;\n margin-inline: -3rem 0;\n }\n }\n\n @container (min-width: 800px) {\n margin-block: 0 50px !important;\n margin-inline: 50px 0 !important;\n\n ::slotted(nano-icon-button[slot='back-btn']) {\n margin-block: 0 !important;\n margin-inline: -3rem 0 !important;\n }\n }\n\n .is-xxl & {\n margin-block: 0 83px !important;\n margin-inline: 83px 0 !important;\n }\n\n @container (min-width: 900px) {\n margin-block: 0 83px !important;\n margin-inline: 83px 0 !important;\n }\n }\n\n &__primary-content {\n max-inline-size: 45rem;\n\n --color: #fff;\n\n display: flex;\n\n .hero--backbtn & {\n > div {\n padding-block: 10px 0;\n padding-inline: 0;\n }\n }\n\n ::slotted(h1[slot='primary-content']) {\n line-height: 26px !important;\n margin-block: 0 18px !important;\n font-size: 2rem !important;\n }\n\n .is-xl & {\n ::slotted(h1[slot='primary-content']) {\n line-height: 31px !important;\n margin-block-end: 30px !important;\n }\n\n ::slotted(.button[slot='primary-content']) {\n margin-block-start: 20px !important;\n }\n }\n\n @container (min-width: 800px) {\n ::slotted(h1[slot='primary-content']) {\n line-height: 31px !important;\n margin-block-end: 30px !important;\n }\n\n ::slotted(.button[slot='primary-content']) {\n margin-block-start: 20px !important;\n }\n }\n }\n\n &__secondary {\n display: none;\n block-size: 100%;\n padding-block: 0 20px;\n padding-inline: 14px;\n\n .hero--secondary & {\n display: flex;\n align-items: center;\n }\n\n .is-xl & {\n padding-block: 0 50px;\n padding-inline: 50px;\n justify-content: flex-end;\n }\n\n @container (min-width: 800px) {\n padding-block: 0 50px;\n padding-inline: 50px;\n justify-content: flex-end;\n }\n\n .is-xxl & {\n padding-block: 0 83px;\n padding-inline: 83px;\n }\n\n @container (min-width: 900px) {\n padding-block: 0 83px;\n padding-inline: 83px;\n }\n }\n\n &__icon-box {\n background: rgb(0 0 0 / 70%);\n padding: 24px;\n inline-size: 100%;\n margin-block-end: auto;\n display: flex;\n flex-direction: column;\n color: white;\n\n .is-xl & {\n max-inline-size: 410px;\n flex: 0 1 410px;\n }\n\n ::slotted([slot='icon-box-item']) {\n --nano-color-base: var(--theme-tint-color);\n --nano-icon-size: 32px;\n --nano-icon-margin-end: 20px;\n\n display: flex;\n align-items: center;\n font-size: 0.8125rem;\n margin-block-end: 20px;\n }\n\n ::slotted(.last[slot='icon-box-item']) {\n margin-block-end: 0;\n }\n }\n\n &__quote-content {\n margin-block-start: auto;\n text-align: center;\n inline-size: 100%;\n\n .is-xl & {\n max-inline-size: 500px;\n flex: 0 1 500px;\n text-align: initial;\n }\n\n @container (min-width: 800px) {\n max-inline-size: 500px;\n flex: 0 1 500px;\n text-align: initial;\n }\n }\n\n &__quote {\n &::before,\n &::after {\n content: '\"';\n font-size: var(--quote-size);\n font-weight: 700;\n font-style: italic;\n line-height: 0;\n color: #abb6b8;\n display: inline;\n position: relative;\n }\n\n ::slotted([slot='quote']) {\n font-size: var(--quote-size);\n font-weight: 300;\n font-style: italic;\n display: inline;\n }\n }\n\n &__quote-author {\n text-align: end;\n font-size: 1rem;\n opacity: 0.8;\n }\n\n &--sub {\n .hero__content.is-xl {\n margin-block-start: 40px;\n\n .hero__primary {\n margin-block: 0 40px;\n margin-inline: 50px 0;\n }\n\n .hero__secondary {\n padding-block: 0 50px;\n padding-inline: 40px 50px;\n }\n\n ::slotted(.button[slot='primary-content']) {\n margin-block-start: 8px !important;\n }\n\n ::slotted(h1[slot='primary-content']) {\n margin-block-end: 18px !important;\n }\n }\n\n .hero__content.is-xxl {\n .hero__primary {\n margin-block: 0 40px;\n margin-inline: 83px 0;\n }\n\n .hero__secondary {\n padding-block: 0 83px;\n padding-inline: 40px 83px;\n }\n }\n }\n}\n","import {\n Component,\n Prop,\n h,\n ComponentInterface,\n VNode,\n State,\n Element,\n Watch,\n Host,\n} from '@stencil/core';\n/**\n * Hero components are designed to be used once per content page to add visual impact to the introductory section of a page.\n * @slot primary-content - title, leading paragraph and CTA\n * @slot breadcrumb - each individual bread crumb should be assigned seperately\n * @slot secondary-content - free form secondary content.\n * @slot icon-box - free form icon box container\n * @slot icon-box-item - seperate icon box items. Designed to contain 1 icon and 1 text element.\n * @slot secondary-ctas - CTAs. each individual button should be assigned seperately\n * @slot quote - quote content\n * @slot quote-author - quote author\n * @slot scrim - optional background overlay (e.g. faded colour or gradient)\n * @slot background - custom background. Only active when img-src is empty\n * @slot back-btn - a back button.\n */\n@Component({\n tag: 'nano-hero',\n styleUrl: 'hero.scss',\n shadow: true,\n})\nexport class Hero implements ComponentInterface {\n private mo?: MutationObserver;\n\n @Element() host: HTMLNanoHeroElement;\n\n @State() gridSizes: string[] = [];\n @State() hasIconBox: boolean;\n @State() hasScrim: boolean;\n @State() hasSecondaryContent: boolean;\n @State() hasQuote: boolean;\n @State() hasBg: boolean;\n @State() hasBackBtn: boolean;\n @State() hasCtas: boolean;\n @State() breadCrumbs: Element[];\n @Watch('breadCrumbs')\n breadCrumbChange() {\n // safari doesn't support ::slotted()::after ... so this :/\n this.breadCrumbs\n .filter(\n (crumb) =>\n crumb.tagName === 'A' &&\n !crumb.nextElementSibling.classList.contains('slash')\n )\n .forEach((crumb) => {\n crumb.insertAdjacentHTML(\n 'afterend',\n '<span slot=\"breadcrumb\" class=\"slash\">/</span>'\n );\n });\n }\n @State() iconBoxItems: Element[];\n @Watch('iconBoxItems')\n iconBoxItemChange() {\n this.iconBoxItems.forEach((item) => item.classList.remove('last'));\n if (\n this.iconBoxItems[this.iconBoxItems.length - 1] &&\n this.iconBoxItems[this.iconBoxItems.length - 1].classList\n )\n this.iconBoxItems[this.iconBoxItems.length - 1].classList.add('last');\n }\n\n /** src for backgronund image. For more control use the `background` slot instead. */\n @Prop() imgSrc?: string;\n\n /** Optional list string providing media sizes with corresponding image srcs.\n * i.e. show img-x at 300px wide. Format `srcSet=\"200w src/imgSmall.jpg, 500h src/imgMed.png\"` */\n @Prop() imgSrcSet?: string = null;\n\n /** The Break Point width that the hero component will change to the large view. Defaults to the XL grid size (900px) */\n @Prop() largeScreenBP: number = 900;\n\n /** Base style for the hero. Either 'light' (white bg / dark text), or 'dark' (dark bg / white text) */\n @Prop() theme: 'dark' | 'light' = 'dark';\n\n /** Set the content structure level of the hero. Defaults to 'top' */\n @Prop() level: 'top' | 'sub' = 'top';\n\n private slotChangeObserver() {\n if (!window['MutationObserver']) return;\n\n if (this.mo) this.mo.disconnect();\n const mo = (this.mo = new MutationObserver(() =>\n this.processSlottedContent()\n ));\n mo.observe(this.host, { childList: true });\n }\n\n // Event handlers\n\n private processSlottedContent() {\n this.hasCtas = !!this.host.querySelector('[slot=\"secondary-ctas\"]');\n this.iconBoxItems = Array.from(\n this.host.querySelectorAll('[slot=\"icon-box-item\"]')\n );\n this.hasIconBox =\n !!this.host.querySelector('[slot=\"icon-box\"]') ||\n !!this.iconBoxItems.length;\n this.hasScrim = !!this.host.querySelector('[slot=\"scrim\"]');\n this.breadCrumbs = Array.from(\n this.host.querySelectorAll('[slot=\"breadcrumb\"]')\n );\n this.hasSecondaryContent =\n !!this.host.querySelector('[slot=\"icon-box\"]') ||\n !!this.host.querySelector('[slot=\"quote\"]') ||\n !!this.host.querySelector('[slot=\"icon-box-item\"]') ||\n !!this.host.querySelector('[slot=\"secondary-content\"]');\n this.hasBg =\n !!this.host.querySelector('[slot=\"background\"]') || !!this.imgSrc;\n this.hasBackBtn = !!this.host.querySelector('[slot=\"back-btn\"]');\n this.hasQuote = !!this.host.querySelector('[slot=\"quote\"]');\n }\n\n private handleGridChange = (e: CustomEvent & { detail: string[] }) => {\n this.gridSizes = e.detail;\n };\n\n // Component lifecycle\n\n disconnectedCallback() {\n if (this.mo) this.mo.disconnect();\n }\n\n componentDidLoad() {\n this.slotChangeObserver();\n }\n\n componentWillLoad() {\n this.processSlottedContent();\n }\n\n private HeroContent = (): VNode[] => {\n return [\n !this.hasIconBox && this.hasCtas ? (\n <div class=\"hero__ctas\">\n <slot name=\"secondary-ctas\" />\n </div>\n ) : (\n ''\n ),\n <div class=\"hero__scrim\">\n <slot name=\"scrim\" />\n </div>,\n <nano-grid\n onNanoBpChange={this.handleGridChange}\n class=\"hero__content\"\n xlCols={2}\n xlSize={this.largeScreenBP}\n >\n <nano-grid-item gridStates=\"xl-col-span-2\">\n <div class=\"hero__breadcrumbs\">\n <slot name=\"breadcrumb\" />\n </div>\n </nano-grid-item>\n <nano-grid-item\n gridStates={\n this.hasSecondaryContent\n ? 'xl-col-span-1 xl-col-start-1 xl-row-start-2'\n : 'xl-col-span-2 xl-col-start-1 xl-row-start-2'\n }\n >\n <div class=\"hero__primary\">\n <div class=\"hero__primary-content\">\n <slot name=\"back-btn\" />\n <div>\n <slot name=\"primary-content\" />\n </div>\n </div>\n </div>\n </nano-grid-item>\n {this.hasSecondaryContent && (\n <nano-grid-item gridStates=\"xl-col-span-1 xl-col-start-2 xl-row-start-2\">\n <div class=\"hero__secondary\">\n <slot name=\"secondary-content\" />\n {this.hasIconBox && (\n <div class=\"hero__icon-box\">\n <slot name=\"icon-box\" />\n <slot name=\"icon-box-item\" />\n </div>\n )}\n {this.hasQuote && (\n <div class=\"hero__quote-content\">\n <span class=\"hero__quote\">\n <slot name=\"quote\" />\n </span>\n <div class=\"hero__quote-author\">\n <slot name=\"quote-author\" />\n </div>\n </div>\n )}\n </div>\n </nano-grid-item>\n )}\n </nano-grid>,\n ];\n };\n\n render() {\n const rtl =\n this.host.dir === 'rtl' ||\n (this.host.ownerDocument as Document).dir === 'rtl';\n\n return (\n <Host\n class={{\n [this.gridSizes.join(' ')]: true,\n }}\n >\n <div\n class={{\n hero: true,\n 'hero--light': this.theme === 'light',\n 'hero--secondary': this.hasSecondaryContent,\n 'hero--iconbox': this.hasIconBox,\n 'hero--rtl': rtl,\n 'hero--scrim': this.hasScrim,\n 'hero--breadcrumb': !!this.breadCrumbs.length,\n 'hero--hasbg': this.hasBg,\n 'hero--backbtn': this.hasBackBtn,\n 'hero--sub': this.level === 'sub',\n }}\n >\n <div class=\"hero__bg-wrap\">\n {!!this.imgSrc && (\n <nano-img\n class=\"hero__img\"\n lazy={false}\n background\n srcSet={this.imgSrcSet}\n src={this.imgSrc}\n >\n <this.HeroContent />\n </nano-img>\n )}\n {!this.imgSrc && [\n <div class=\"hero__bg-slot\">\n <slot name=\"background\" />\n </div>,\n <this.HeroContent />,\n ]}\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":["ResizeObserve","this","isReady","assessChanges","currentWidth","currentHeight","readTask","assesContentFit","states","appliedStates","changedStates","h","Map","w","hasChanged","Object","keys","forEach","dimType","dim","state","bp","applied","set","applyChanges","classNames","includes","classNameChange","host","className","join","nanoResizeObserverReady","emit","newStatesProp","statesChanged","dimensionChanged","toBpDir","bpDir","bpDirSpl","split","filter","bs","length","parseInt","dir","map","st","trim","key","classes","notifyContentFit","findNonContentsEle","ele","window","getComputedStyle","display","recurse","e","Array","from","children","find","cEle","didChange","measureEle","firstElementChild","scrollWidth","contentFitX","scrollHeight","contentFitY","nanoResizeContentFitChange","x","y","changes","push","cl","nanoResizeStateChange","toSimpleObj","stateMaps","retObj","attachRO","ro","ResizeObserver","width","height","getBoundingClientRect","Math","ceil","observe","componentWillLoad","classList","connectedCallback","disconnectedCallback","disconnect","render","Host","name","skeletonCss","Skeleton","class","skeleton","animate","animated"],"sources":["./src/components/resize-observe/resize-observe.tsx","./src/components/skeleton/skeleton.scss?tag=nano-skeleton&encapsulation=shadow","./src/components/skeleton/skeleton.tsx"],"sourcesContent":["import {\n Component,\n h,\n Prop,\n Element,\n Host,\n State,\n Watch,\n ComponentInterface,\n Event,\n EventEmitter,\n readTask,\n} from '@stencil/core';\nimport type { ResizeStateChangeEventDetail } from '../../interface';\n\ntype ResizeObserverState = { states?: string[]; applied?: boolean };\ninterface StateMaps {\n h: Map<number, ResizeObserverState>;\n w: Map<number, ResizeObserverState>;\n}\n\n/**\n * A Resize-Observer utility component.\n * Takes a string list of sizes and optional class-names.\n * Adds class-names and fires `nanoResizeStateChange` events when the component reaches those sizes.\n * Additionally, can fire events when content no-longer fits within the element.\n * @slot - Main slot for any content.\n * @slot content-fit-x - optional slot (when `notifyContentFit` is set). Shows when content fits / doesn't get cut off\n * @slot content-nofit-x - optional slot (when `notifyContentFit` is set). Shows when content doesn't get cut off\n * @slot content-fit-y - optional slot (when `notifyContentFit` is set). Shows when content fits / doesn't get cut off\n * @slot content-nofit-y - optional slot (when `notifyContentFit` is set). Shows when content doesn't get cut off\n */\n@Component({\n tag: 'nano-resize-observe',\n styles: `nano-resize-observe { display: block }`,\n shadow: true,\n})\nexport class ResizeObserve implements ComponentInterface {\n private ro: ResizeObserver;\n private appliedStates: StateMaps;\n private isReady = false;\n\n @Element() host: HTMLNanoResizeObserveElement;\n @State() currentWidth: number;\n @State() currentHeight: number;\n @State() classNames: string[] = [];\n @State() contentFitX = null;\n @State() contentFitY = null;\n\n @Watch('classNames')\n classNameChange() {\n this.host.className = this.classNames.join(' ');\n if (!this.isReady && this.classNames.includes('is-ready')) {\n this.isReady = true;\n this.nanoResizeObserverReady.emit();\n }\n }\n\n /** Fire `nanoResizeContentFitChange` events notifying\n * whether content currently fits or does not on the x, y or both axis'.\n * Also makes the `content-fit-...` slots available */\n @Prop() notifyContentFit: 'x' | 'y' | 'xy';\n\n /** string list of sizes and optional class-names. Adds class-names and fires nanoResizeStateChange events. Upon hitting breakpoints.\n * Format: `states=\"800w, 300h class1 class2\"` */\n @Prop() states: string;\n\n @Watch('states')\n newStatesProp() {\n this.statesChanged();\n }\n\n /** A resize break point is switched on or off */\n @Event() nanoResizeStateChange!: EventEmitter<ResizeStateChangeEventDetail>;\n\n /** Fires after the initial loading and assessment */\n @Event() nanoResizeObserverReady!: EventEmitter<void>;\n\n /** Fires when the content either begins or stops to fit. Will only work when `notifyContentFit` is set. */\n @Event() nanoResizeContentFitChange!: EventEmitter<{\n x: boolean;\n y: boolean;\n }>;\n\n @Watch('currentHeight')\n @Watch('currentWidth')\n dimensionChanged() {\n this.assessChanges();\n }\n\n @Watch('states')\n statesChanged() {\n if (!this.states) return;\n\n const toBpDir = (bpDir: string) => {\n const bpDirSpl = bpDir.split(/(\\d+)/).filter((bs) => bs.length);\n return { bp: parseInt(bpDirSpl[0]), dir: bpDirSpl[1] };\n };\n this.appliedStates = { h: new Map(), w: new Map() };\n\n // parse state string\n this.states.split(',').map((st) => {\n st = st.trim();\n if (st.includes(' ')) {\n const [key, ...classes] = st.split(' ');\n const { bp, dir } = toBpDir(key);\n this.appliedStates[dir as keyof StateMaps].set(bp, {\n states: classes,\n applied: false,\n });\n } else {\n const { bp, dir } = toBpDir(st);\n this.appliedStates[dir as keyof StateMaps].set(bp, { applied: false });\n }\n });\n }\n\n private assesContentFit() {\n if (!this.notifyContentFit) return;\n\n const findNonContentsEle = (ele: Element) => {\n if (window.getComputedStyle(ele).display !== 'contents') return ele;\n\n const recurse = (e: Element): Element | null => {\n return Array.from(e.children).find((cEle: HTMLElement) => {\n if (window.getComputedStyle(cEle).display !== 'contents') return cEle;\n recurse(cEle);\n });\n };\n return recurse(ele);\n };\n\n let didChange = false;\n const measureEle = findNonContentsEle(this.host.firstElementChild);\n\n if (measureEle) {\n if (this.notifyContentFit && this.notifyContentFit.includes('x')) {\n if (\n this.currentWidth < measureEle.scrollWidth &&\n this.contentFitX !== false\n ) {\n didChange = true;\n this.contentFitX = false;\n } else if (\n this.currentWidth >= measureEle.scrollWidth &&\n this.contentFitX !== true\n ) {\n didChange = true;\n this.contentFitX = true;\n }\n }\n\n if (this.notifyContentFit && this.notifyContentFit.includes('y')) {\n if (\n this.currentHeight < measureEle.scrollHeight &&\n this.contentFitY !== false\n ) {\n didChange = true;\n this.contentFitY = false;\n } else if (\n this.currentHeight >= measureEle.scrollHeight &&\n this.contentFitY !== true\n ) {\n didChange = true;\n this.contentFitY = true;\n }\n }\n\n if (didChange) {\n this.nanoResizeContentFitChange.emit({\n x: this.contentFitX,\n y: this.contentFitY,\n });\n }\n }\n }\n\n private assessChanges = () => {\n if (!this.currentWidth && !this.currentHeight) return;\n readTask(() => this.assesContentFit());\n\n if (!this.states || !this.appliedStates) return;\n\n const changedStates: StateMaps = { h: new Map(), w: new Map() };\n let hasChanged = false;\n\n Object.keys(this.appliedStates).forEach((dimType) => {\n let dim: number;\n if (dimType === 'h') dim = this.currentHeight;\n else dim = this.currentWidth;\n\n this.appliedStates[dimType].forEach(\n (state: ResizeObserverState, bp: number) => {\n if (dim >= bp && state.applied === false) {\n state.applied = true;\n changedStates[dimType].set(bp, state);\n hasChanged = true;\n } else if (dim < bp && state.applied === true) {\n state.applied = false;\n changedStates[dimType].set(bp, state);\n hasChanged = true;\n }\n }\n );\n });\n if (hasChanged) this.applyChanges(changedStates);\n else if (!this.classNames.includes('is-ready'))\n this.classNames = ['is-ready'];\n };\n\n private applyChanges(changes: StateMaps) {\n if (!this.states) return;\n\n let classNames = [...this.classNames];\n Object.keys(changes).forEach((dimType: keyof StateMaps) => {\n changes[dimType].forEach((state) => {\n if (!state.states) return;\n state.states.map((st) => {\n if (state.applied) {\n classNames.push(st);\n classNames = classNames.filter((cl) => cl !== 'not-' + st);\n } else {\n classNames.push('not-' + st);\n classNames = classNames.filter((cl) => cl !== st);\n }\n });\n });\n });\n this.classNames = ['is-ready', ...classNames];\n this.nanoResizeStateChange.emit(this.toSimpleObj(changes));\n }\n\n private toSimpleObj(stateMaps: StateMaps) {\n const retObj = {};\n Object.keys(stateMaps).forEach((dimType: keyof StateMaps) => {\n stateMaps[dimType].forEach((state: ResizeObserverState, bp: number) => {\n retObj[bp + dimType] = state.applied;\n });\n });\n return retObj;\n }\n\n private attachRO() {\n if (!window['ResizeObserver']) return;\n\n this.ro = new ResizeObserver(() => {\n const { width, height } = this.host.getBoundingClientRect();\n this.currentWidth = Math.ceil(width);\n this.currentHeight = Math.ceil(height);\n });\n this.ro.observe(this.host);\n }\n\n componentWillLoad() {\n this.statesChanged();\n // set all class as 'not-' by deafult\n this.applyChanges(this.appliedStates);\n\n this.classNames = Array.from(this.host.classList);\n\n if (!this.currentWidth && !this.currentHeight) {\n readTask(() => {\n const { width, height } = this.host.getBoundingClientRect();\n this.currentWidth = Math.ceil(width);\n this.currentHeight = Math.ceil(height);\n });\n } else {\n this.assessChanges();\n }\n }\n\n connectedCallback() {\n if (!this.ro) this.attachRO();\n }\n\n disconnectedCallback() {\n if (this.ro) this.ro.disconnect();\n }\n\n render() {\n return (\n <Host>\n <slot />\n {!!this.notifyContentFit &&\n (this.contentFitX !== null || this.contentFitY !== null) && [\n !!this.contentFitX ? (\n <slot name=\"content-fit-x\" />\n ) : (\n <slot name=\"content-nofit-x\" />\n ),\n !!this.contentFitY ? (\n <slot name=\"content-fit-y\" />\n ) : (\n <slot name=\"content-nofit-y\" />\n ),\n ]}\n </Host>\n );\n }\n}\n","@import '../../global/style/nano-theme/components';\n\n:host {\n /**\n * @prop --base-color-rgb: default #{$skeleton-color-rgb};\n * @prop --color: default var(--nano-skeleton-color, rgba(var(--base-color-rgb), 1));\n * @prop --tint: default var(--nano-skeleton-tint, rgba(var(--base-color-rgb), .3));\n */\n\n --base-color-rgb: #{$skeleton-color-rgb};\n --color: var(--nano-skeleton-color, rgb(var(--base-color-rgb) / 100%));\n --tint: var(--nano-skeleton-tint, rgb(var(--base-color-rgb) / 50%));\n\n display: block;\n position: relative;\n border-radius: 0.25rem;\n min-block-size: 1em;\n line-height: inherit;\n}\n\n.skeleton {\n display: flex;\n min-inline-size: 100%;\n min-block-size: 100%;\n border-radius: inherit;\n line-height: inherit;\n}\n\n.skeleton__indicator {\n flex: 1 1 auto;\n background: var(--color);\n border-radius: inherit;\n line-height: inherit;\n}\n\n.skeleton.animate .skeleton__indicator {\n background:\n linear-gradient(\n 270deg,\n var(--tint),\n var(--color),\n var(--color),\n var(--tint)\n );\n background-size: 400% 100%;\n animation: loader 6s ease-in-out infinite;\n}\n\n@keyframes loader {\n 0% {\n background-position: 200% 0;\n }\n\n 100% {\n background-position: -200% 0;\n }\n}\n","import { Component, Prop, h, ComponentInterface } from '@stencil/core';\n\n/**\n * Skeletons are used to show where content will eventually be drawn.\n * Simple containers for scaffolding layouts that mimic what users will see when content has finished loading.\n * Prevents large areas of empty space during asynchronous operations.\n */\n@Component({\n tag: 'nano-skeleton',\n styleUrl: 'skeleton.scss',\n shadow: true,\n})\nexport class Skeleton implements ComponentInterface {\n /** When `true`, the skeleton will animate. */\n @Prop() animated = true;\n\n render() {\n return (\n <div\n class={{\n skeleton: true,\n animate: this.animated,\n }}\n >\n <div class=\"skeleton__indicator\">&nbsp;</div>\n </div>\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["ResizeObserve","this","isReady","assessChanges","currentWidth","currentHeight","readTask","assesContentFit","states","appliedStates","changedStates","h","Map","w","hasChanged","Object","keys","forEach","dimType","dim","state","bp","applied","set","applyChanges","classNames","includes","classNameChange","host","className","join","nanoResizeObserverReady","emit","newStatesProp","statesChanged","dimensionChanged","toBpDir","bpDir","bpDirSpl","split","filter","bs","length","parseInt","dir","map","st","trim","key","classes","notifyContentFit","findNonContentsEle","ele","window","getComputedStyle","display","recurse","e","Array","from","children","find","cEle","didChange","measureEle","firstElementChild","scrollWidth","contentFitX","scrollHeight","contentFitY","nanoResizeContentFitChange","x","y","changes","push","cl","nanoResizeStateChange","toSimpleObj","stateMaps","retObj","attachRO","ro","ResizeObserver","width","height","getBoundingClientRect","Math","ceil","observe","componentWillLoad","classList","connectedCallback","disconnectedCallback","disconnect","render","Host","name","skeletonCss","Skeleton","class","skeleton","animate","animated"],"sources":["./src/components/resize-observe/resize-observe.tsx","./src/components/skeleton/skeleton.scss?tag=nano-skeleton&encapsulation=shadow","./src/components/skeleton/skeleton.tsx"],"sourcesContent":["import {\n Component,\n h,\n Prop,\n Element,\n Host,\n State,\n Watch,\n ComponentInterface,\n Event,\n EventEmitter,\n readTask,\n} from '@stencil/core';\nimport type { ResizeStateChangeEventDetail } from '../../interface';\n\ntype ResizeObserverState = { states?: string[]; applied?: boolean };\ninterface StateMaps {\n h: Map<number, ResizeObserverState>;\n w: Map<number, ResizeObserverState>;\n}\n\n/**\n * A Resize-Observer utility component.\n * Takes a string list of sizes and optional class-names.\n * Adds class-names and fires `nanoResizeStateChange` events when the component reaches those sizes.\n * Additionally, can fire events when content no-longer fits within the element.\n * @slot - Main slot for any content.\n * @slot content-fit-x - optional slot (when `notifyContentFit` is set). Shows when content fits / doesn't get cut off\n * @slot content-nofit-x - optional slot (when `notifyContentFit` is set). Shows when content doesn't get cut off\n * @slot content-fit-y - optional slot (when `notifyContentFit` is set). Shows when content fits / doesn't get cut off\n * @slot content-nofit-y - optional slot (when `notifyContentFit` is set). Shows when content doesn't get cut off\n */\n@Component({\n tag: 'nano-resize-observe',\n styles: `nano-resize-observe { display: block }`,\n shadow: true,\n})\nexport class ResizeObserve implements ComponentInterface {\n private ro: ResizeObserver;\n private appliedStates: StateMaps;\n private isReady = false;\n\n @Element() host: HTMLNanoResizeObserveElement;\n @State() currentWidth: number;\n @State() currentHeight: number;\n @State() classNames: string[] = [];\n @State() contentFitX = null;\n @State() contentFitY = null;\n\n @Watch('classNames')\n classNameChange() {\n this.host.className = this.classNames.join(' ');\n if (!this.isReady && this.classNames.includes('is-ready')) {\n this.isReady = true;\n this.nanoResizeObserverReady.emit();\n }\n }\n\n /** Fire `nanoResizeContentFitChange` events notifying\n * whether content currently fits or does not on the x, y or both axis'.\n * Also makes the `content-fit-...` slots available */\n @Prop() notifyContentFit: 'x' | 'y' | 'xy';\n\n /** string list of sizes and optional class-names. Adds class-names and fires nanoResizeStateChange events. Upon hitting breakpoints.\n * Format: `states=\"800w, 300h class1 class2\"` */\n @Prop() states: string;\n\n @Watch('states')\n newStatesProp() {\n this.statesChanged();\n }\n\n /** A resize break point is switched on or off */\n @Event() nanoResizeStateChange!: EventEmitter<ResizeStateChangeEventDetail>;\n\n /** Fires after the initial loading and assessment */\n @Event() nanoResizeObserverReady!: EventEmitter<void>;\n\n /** Fires when the content either begins or stops to fit. Will only work when `notifyContentFit` is set. */\n @Event() nanoResizeContentFitChange!: EventEmitter<{\n x: boolean;\n y: boolean;\n }>;\n\n @Watch('currentHeight')\n @Watch('currentWidth')\n dimensionChanged() {\n this.assessChanges();\n }\n\n @Watch('states')\n statesChanged() {\n if (!this.states) return;\n\n const toBpDir = (bpDir: string) => {\n const bpDirSpl = bpDir.split(/(\\d+)/).filter((bs) => bs.length);\n return { bp: parseInt(bpDirSpl[0]), dir: bpDirSpl[1] };\n };\n this.appliedStates = { h: new Map(), w: new Map() };\n\n // parse state string\n this.states.split(',').map((st) => {\n st = st.trim();\n if (st.includes(' ')) {\n const [key, ...classes] = st.split(' ');\n const { bp, dir } = toBpDir(key);\n this.appliedStates[dir as keyof StateMaps].set(bp, {\n states: classes,\n applied: false,\n });\n } else {\n const { bp, dir } = toBpDir(st);\n this.appliedStates[dir as keyof StateMaps].set(bp, { applied: false });\n }\n });\n }\n\n private assesContentFit() {\n if (!this.notifyContentFit) return;\n\n const findNonContentsEle = (ele: Element) => {\n if (window.getComputedStyle(ele).display !== 'contents') return ele;\n\n const recurse = (e: Element): Element | null => {\n return Array.from(e.children).find((cEle: HTMLElement) => {\n if (window.getComputedStyle(cEle).display !== 'contents') return cEle;\n recurse(cEle);\n });\n };\n return recurse(ele);\n };\n\n let didChange = false;\n const measureEle = findNonContentsEle(this.host.firstElementChild);\n\n if (measureEle) {\n if (this.notifyContentFit && this.notifyContentFit.includes('x')) {\n if (\n this.currentWidth < measureEle.scrollWidth &&\n this.contentFitX !== false\n ) {\n didChange = true;\n this.contentFitX = false;\n } else if (\n this.currentWidth >= measureEle.scrollWidth &&\n this.contentFitX !== true\n ) {\n didChange = true;\n this.contentFitX = true;\n }\n }\n\n if (this.notifyContentFit && this.notifyContentFit.includes('y')) {\n if (\n this.currentHeight < measureEle.scrollHeight &&\n this.contentFitY !== false\n ) {\n didChange = true;\n this.contentFitY = false;\n } else if (\n this.currentHeight >= measureEle.scrollHeight &&\n this.contentFitY !== true\n ) {\n didChange = true;\n this.contentFitY = true;\n }\n }\n\n if (didChange) {\n this.nanoResizeContentFitChange.emit({\n x: this.contentFitX,\n y: this.contentFitY,\n });\n }\n }\n }\n\n private assessChanges = () => {\n if (!this.currentWidth && !this.currentHeight) return;\n readTask(() => this.assesContentFit());\n\n if (!this.states || !this.appliedStates) return;\n\n const changedStates: StateMaps = { h: new Map(), w: new Map() };\n let hasChanged = false;\n\n Object.keys(this.appliedStates).forEach((dimType) => {\n let dim: number;\n if (dimType === 'h') dim = this.currentHeight;\n else dim = this.currentWidth;\n\n this.appliedStates[dimType].forEach(\n (state: ResizeObserverState, bp: number) => {\n if (dim >= bp && state.applied === false) {\n state.applied = true;\n changedStates[dimType].set(bp, state);\n hasChanged = true;\n } else if (dim < bp && state.applied === true) {\n state.applied = false;\n changedStates[dimType].set(bp, state);\n hasChanged = true;\n }\n }\n );\n });\n if (hasChanged) this.applyChanges(changedStates);\n else if (!this.classNames.includes('is-ready'))\n this.classNames = ['is-ready'];\n };\n\n private applyChanges(changes: StateMaps) {\n if (!this.states) return;\n\n let classNames = [...this.classNames];\n Object.keys(changes).forEach((dimType: keyof StateMaps) => {\n changes[dimType].forEach((state) => {\n if (!state.states) return;\n state.states.map((st) => {\n if (state.applied) {\n classNames.push(st);\n classNames = classNames.filter((cl) => cl !== 'not-' + st);\n } else {\n classNames.push('not-' + st);\n classNames = classNames.filter((cl) => cl !== st);\n }\n });\n });\n });\n this.classNames = ['is-ready', ...classNames];\n this.nanoResizeStateChange.emit(this.toSimpleObj(changes));\n }\n\n private toSimpleObj(stateMaps: StateMaps) {\n const retObj = {};\n Object.keys(stateMaps).forEach((dimType: keyof StateMaps) => {\n stateMaps[dimType].forEach((state: ResizeObserverState, bp: number) => {\n retObj[bp + dimType] = state.applied;\n });\n });\n return retObj;\n }\n\n private attachRO() {\n if (!window['ResizeObserver']) return;\n\n this.ro = new ResizeObserver(() => {\n const { width, height } = this.host.getBoundingClientRect();\n this.currentWidth = Math.ceil(width);\n this.currentHeight = Math.ceil(height);\n });\n this.ro.observe(this.host);\n }\n\n componentWillLoad() {\n this.statesChanged();\n // set all class as 'not-' by deafult\n this.applyChanges(this.appliedStates);\n\n this.classNames = Array.from(this.host.classList);\n\n if (!this.currentWidth && !this.currentHeight) {\n readTask(() => {\n const { width, height } = this.host.getBoundingClientRect();\n this.currentWidth = Math.ceil(width);\n this.currentHeight = Math.ceil(height);\n });\n } else {\n this.assessChanges();\n }\n }\n\n connectedCallback() {\n if (!this.ro) this.attachRO();\n }\n\n disconnectedCallback() {\n if (this.ro) this.ro.disconnect();\n }\n\n render() {\n return (\n <Host>\n <slot />\n {!!this.notifyContentFit &&\n (this.contentFitX !== null || this.contentFitY !== null) && [\n !!this.contentFitX ? (\n <slot name=\"content-fit-x\" />\n ) : (\n <slot name=\"content-nofit-x\" />\n ),\n !!this.contentFitY ? (\n <slot name=\"content-fit-y\" />\n ) : (\n <slot name=\"content-nofit-y\" />\n ),\n ]}\n </Host>\n );\n }\n}\n","@import '../../global/style/nano-theme/components';\n\n:host {\n /**\n * @prop --base-color-rgb: default #{$skeleton-color-rgb};\n * @prop --color: default var(--nano-skeleton-color, rgb(var(--base-color-rgb), 1));\n * @prop --tint: default var(--nano-skeleton-tint, rgb(var(--base-color-rgb), .3));\n */\n\n --base-color-rgb: #{$skeleton-color-rgb};\n --color: var(--nano-skeleton-color, rgb(var(--base-color-rgb) / 100%));\n --tint: var(--nano-skeleton-tint, rgb(var(--base-color-rgb) / 50%));\n\n display: block;\n position: relative;\n border-radius: 0.25rem;\n min-block-size: 1em;\n line-height: inherit;\n}\n\n.skeleton {\n display: flex;\n min-inline-size: 100%;\n min-block-size: 100%;\n border-radius: inherit;\n line-height: inherit;\n}\n\n.skeleton__indicator {\n flex: 1 1 auto;\n background: var(--color);\n border-radius: inherit;\n line-height: inherit;\n}\n\n.skeleton.animate .skeleton__indicator {\n background:\n linear-gradient(\n 270deg,\n var(--tint),\n var(--color),\n var(--color),\n var(--tint)\n );\n background-size: 400% 100%;\n animation: loader 6s ease-in-out infinite;\n}\n\n@keyframes loader {\n 0% {\n background-position: 200% 0;\n }\n\n 100% {\n background-position: -200% 0;\n }\n}\n","import { Component, Prop, h, ComponentInterface } from '@stencil/core';\n\n/**\n * Skeletons are used to show where content will eventually be drawn.\n * Simple containers for scaffolding layouts that mimic what users will see when content has finished loading.\n * Prevents large areas of empty space during asynchronous operations.\n */\n@Component({\n tag: 'nano-skeleton',\n styleUrl: 'skeleton.scss',\n shadow: true,\n})\nexport class Skeleton implements ComponentInterface {\n /** When `true`, the skeleton will animate. */\n @Prop() animated = true;\n\n render() {\n return (\n <div\n class={{\n skeleton: true,\n animate: this.animated,\n }}\n >\n <div class=\"skeleton__indicator\">&nbsp;</div>\n </div>\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /*!
2
+ * Web Components for Nanopore digital Web Apps
3
+ */
4
+ import{c as t}from"./p-4c5e0c9e.js";import"./p-6ef53fa1.js";import"./p-ee045579.js";import"./p-9746b0a5.js";import"./p-b65e0e63.js";const e="table.worker";const o="stencil.table.worker";const p=new URL("p-e2f9ccfa.js",import.meta.url).href;const s=new Blob(['importScripts("'+p+'")'],{type:"text/javascript"});const r=URL.createObjectURL(s);const c=t(r,e,o);URL.revokeObjectURL(r);export{c as worker,o as workerMsgId,e as workerName,p as workerPath};
5
+ //# sourceMappingURL=p-8332890e.js.map
@@ -1,5 +1,5 @@
1
1
  /*!
2
2
  * Web Components for Nanopore digital Web Apps
3
3
  */
4
- export{T as nano_table}from"./p-add3ac22.js";import"./p-6ef53fa1.js";import"./p-ee045579.js";import"./p-9746b0a5.js";import"./p-b65e0e63.js";
5
- //# sourceMappingURL=p-80ddfa30.entry.js.map
4
+ export{T as nano_table}from"./p-4c5e0c9e.js";import"./p-6ef53fa1.js";import"./p-ee045579.js";import"./p-9746b0a5.js";import"./p-b65e0e63.js";
5
+ //# sourceMappingURL=p-8c04640c.entry.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["renderHiddenInput","container","name","value","disabled","input","querySelector","ownerDocument","createElement","type","classList","add","appendChild","rangeCss","Range","this","noUpdate","hasFocus","clampBounds","clamp","min","max","ensureValueInBounds","dualKnobs","lower","upper","handleKeyboard","knob","isIncrease","step","ratioA","ratioB","updateValue","onBlur","nanoBlur","emit","emitStyle","onFocus","nanoFocus","debounceChanged","nanoChange","debounceEvent","debounce","minChanged","updateRatio","maxChanged","disabledChanged","gesture","enable","valueChanged","connectedCallback","disconnectedCallback","destroy","undefined","async","rangeSlider","import","createGesture","el","gestureName","gesturePriority","threshold","onStart","ev","onMove","onEnd","getValue","nanoStyle","interactive","detail","rect","getBoundingClientRect","currentX","ratio","left","width","document","dir","pressedKnob","Math","abs","setFocus","update","snaps","valueToRatio","ratioToValue","valA","valB","ratioLower","ratioUpper","shadowRoot","knobEl","focus","render","pin","barStart","barEnd","doc","isRTL","start","end","tickStyle","tick","barStyle","ticks","active","push","JSON","stringify","h","Host","onFocusin","onFocusout","class","createColorClasses","color","ref","rangeEl","map","style","role","part","renderKnob","pressed","knobStyle","onKeyDown","key","preventDefault","stopPropagation","tabindex","round"],"sources":["./src/utils/form.ts","./src/components/range/range.scss?tag=nano-range&encapsulation=scoped","./src/components/range/range.tsx"],"sourcesContent":["export const renderHiddenInput = (\n container: HTMLElement,\n name: string,\n value: string | undefined | null,\n disabled: boolean\n) => {\n let input = container.querySelector(\n 'input.aux-input'\n ) as HTMLInputElement | null;\n if (!input) {\n input = container.ownerDocument!.createElement('input');\n input.type = 'hidden';\n input.classList.add('aux-input');\n container.appendChild(input);\n }\n input.disabled = disabled;\n input.name = name;\n input.value = value || '';\n};\n","@import '../../global/style/utilities/globals';\n@import '../../global/style/nano-theme/form';\n\n// Range\n// --------------------------------------------------\n\n:host {\n /**\n * @prop --knob-handle-size: defaults to calc(var(--knob-size) * 2);\n * @prop --rgb-inactive: defaults to #{color-to-rgb-list(#a5a5a5)};\n * @prop --bar-background: Background of the range bar; Defaults to #e2e1e0;\n * @prop --bar-background-active: Background of the active range bar; Defaults to #a5a5a5;\n * @prop --bar-height: Height of the range bar; Defaults to 8px;\n * @prop --bar-border-radius: Border radius of the range bar; Defaults to 4px;\n * @prop --height: Height of the range. Defaults to 42px;\n * @prop --knob-background: Background of the range knob. Defaults to #{nano-color(primary, base)};\n * @prop --knob-border-radius: Border radius of the range knob. Defaults to 50%;\n * @prop --knob-box-shadow: Box shadow of the range knob; Defaults to 0 2px 4px 0 rgba(0, 0, 0, 0.3);\n * @prop --knob-size: Size of the range knob; Defaults to 30px;\n * @prop --pin-background: Background of the range pin; Defaults to #{nano-color(primary, base)};\n * @prop --pin-color: Color of the range pin; Defaults to #{nano-color(primary, contrast)};\n * @prop --focus-style: Focus shadow around knob; Defaults to 0 0 0 5px #{$control-focus-color};\n */\n --knob-handle-size: (var(--knob-size) * 2);\n --rgb-inactive: #{color-to-rgb-list(#a5a5a5)};\n --knob-border-radius: 50%;\n --knob-background: #{nano-color(primary, base)};\n --knob-box-shadow: 0 2px 4px 0 rgb(0 0 0 / 30%);\n --knob-size: 30px;\n --bar-height: 8px;\n --bar-background: #e2e1e0;\n --bar-background-active: #a5a5a5;\n --bar-border-radius: 4px;\n --height: 42px;\n --pin-background: #{nano-color(primary, base)};\n --pin-color: #{nano-color(primary, contrast)};\n --focus-style: 0 0 0 5px #{$control-focus-color};\n}\n\n.range-wrap {\n display: flex;\n position: relative;\n flex: 3;\n align-items: center;\n user-select: none;\n\n ::slotted(ion-icon[slot]) {\n font-size: 1.5em;\n }\n\n ::slotted([slot='start']) {\n margin-inline: 0 14px;\n margin-block: 0;\n font-size: 0.9em;\n }\n\n ::slotted([slot='end']) {\n margin-inline: 14px 0;\n margin-block: 0;\n font-size: 0.9em;\n }\n}\n\n.range-slider {\n position: relative;\n flex: 1;\n width: 100%;\n height: var(--height);\n contain: size layout style;\n cursor: grab;\n touch-action: pan-y;\n}\n\n:host(.range-pressed) .range-slider {\n cursor: grabbing;\n}\n\n// bar\n\n.range-bar {\n border-radius: var(--bar-border-radius);\n inset-block-start: calc((var(--height) - var(--bar-height)) / 2);\n inset-inline-start: 0;\n position: absolute;\n width: 100%;\n height: var(--bar-height);\n background: var(--bar-background);\n pointer-events: none;\n\n :host(.range-snaps) & {\n border-radius: var(--bar-border-radius) 0 0 var(--bar-border-radius);\n }\n}\n\n.range-bar-active {\n inset-block-end: 0;\n width: auto;\n background: var(--bar-background-active);\n\n :host(.range-pressed) {\n will-change: left, right;\n }\n}\n\n// knob\n\n.range-knob {\n border-radius: var(--knob-border-radius);\n inset-block-start: calc(50% - var(--knob-size) / 2);\n inset-inline-start: calc(50% - var(--knob-size) / 2);\n position: absolute;\n width: var(--knob-size);\n height: var(--knob-size);\n background: var(--knob-background);\n box-shadow: var(--knob-box-shadow);\n z-index: 2;\n pointer-events: none;\n transform: scale(0.67);\n transition-duration: 120ms;\n transition-property: transform, background-color, border;\n transition-timing-function: ease;\n\n :host(:not(.range-has-pin)) .range-knob-pressed & {\n transform: scale(1);\n }\n}\n\n.range-knob-handle {\n inset-block-start: calc((var(--height) - var(--knob-handle-size)) / 2);\n inset-inline-start: 0;\n margin-inline-start: calc(0px - var(--knob-handle-size) / 2);\n position: absolute;\n width: calc(var(--knob-handle-size));\n height: calc(var(--knob-handle-size));\n text-align: center;\n\n &:active,\n &:focus {\n outline: none;\n\n .range-knob {\n box-shadow: var(--knob-box-shadow), var(--focus-style);\n }\n }\n}\n\n// ticks\n\n.range-tick {\n position: absolute;\n inset-block-start: calc((var(--height) - var(--bar-height)) / 2);\n width: var(--bar-height);\n height: var(--bar-height);\n background: var(--bar-background-active);\n z-index: 1;\n pointer-events: none;\n\n &:first-of-type {\n border-radius: var(--bar-border-radius) 0 0 var(--bar-border-radius);\n }\n\n &:last-of-type {\n border-radius: 0 var(--bar-border-radius) var(--bar-border-radius) 0;\n }\n\n &-active {\n background: transparent;\n }\n}\n\n// pin\n\n.range-pin {\n transform: translate3d(0, 0, 0) scale(0.01);\n transform-origin: center top;\n padding: 0.66em 0;\n border-radius: 50%;\n text-align: center;\n box-sizing: border-box;\n display: inline-block;\n position: relative;\n min-width: 2.33em;\n height: 2.33em;\n transition: transform 120ms ease, background 120ms ease;\n background: var(--pin-background);\n color: var(--pin-color);\n font-size: 0.75em;\n\n &::before {\n inset-block-start: 0.25em;\n inset-inline-start: 50%;\n margin-inline-start: -1.08em;\n border-radius: 50% 50% 50% 0;\n position: absolute;\n width: 2.16em;\n height: 2.16em;\n transform: rotate(-45deg);\n transition: background 120ms ease;\n background: var(--pin-background);\n content: '';\n z-index: -1;\n }\n\n .range-knob-pressed & {\n transform: translate3d(0, -50%, 0) scale(1);\n transform: translate3d(0, calc((100% - var(--bar-height)) * -1), 0) scale(1);\n }\n}\n\n// disabled\n\n:host(.range-disabled) {\n pointer-events: none;\n\n .range-bar-active,\n .range-bar,\n .range-tick {\n background-color: rgb(var(--rgb-inactive) / 50%);\n }\n\n .range-knob {\n transform: scale(0.55);\n outline: 5px solid #fff;\n background-color: rgb(var(--rgb-inactive) / 50%);\n }\n}\n\n// theme\n\n:host(.nano-color) {\n .range-bar-active,\n .range-knob,\n .range-pin,\n .range-pin::before,\n .range-tick {\n background: current-color(base);\n color: current-color(contrast);\n }\n\n .range-bar {\n background: current-color(base, 0.26);\n }\n\n .range-knob-handle {\n &:active,\n &:focus {\n .range-knob {\n box-shadow: var(--knob-box-shadow), 0 0 0 5px current-color(tint, 0.56);\n }\n }\n }\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Host,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { renderHiddenInput } from '../../utils/form';\nimport { clamp } from '../../utils/math';\nimport { createColorClasses } from '../../utils/theme';\nimport { debounceEvent } from '../../utils/throttle';\nimport type {\n Color,\n Gesture,\n GestureDetail,\n KnobName,\n RangeChangeEventDetail,\n RangeValue,\n StyleEventDetail,\n} from '../../interface';\n\n/**\n * The Range slider lets users select from a range of values by moving\n * the slider knob. It can accept dual knobs, but by default one knob controls the value of the range.\n *\n * Labels can be placed on either side of the range by adding the\n * `slot=\"start\"` or `slot=\"end\"` to the element.\n *\n * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.\n * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.\n */\n@Component({\n tag: 'nano-range',\n styleUrl: 'range.scss',\n scoped: true,\n})\nexport class Range implements ComponentInterface {\n private noUpdate = false;\n private rect!: ClientRect;\n private hasFocus = false;\n private rangeSlider?: HTMLElement;\n private gesture?: Gesture;\n\n @Element() el!: HTMLNanoRangeElement;\n\n @State() private ratioA = 0;\n @State() private ratioB = 0;\n @State() private pressedKnob: KnobName;\n\n /**\n * The color to use from your application's color palette.\n * Default options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`\n */\n @Prop() color?: Color;\n\n /**\n * How long, in milliseconds, to wait to trigger the\n * `nanoChange` event after each change in the range value.\n */\n @Prop() debounce = 0;\n\n @Watch('debounce')\n protected debounceChanged() {\n this.nanoChange = debounceEvent(this.nanoChange, this.debounce);\n }\n\n /**\n * The name of the control, which is submitted with the form data.\n */\n @Prop() name = '';\n\n /**\n * Show two knobs.\n */\n @Prop() dualKnobs = false;\n\n /**\n * Minimum integer value of the range.\n */\n @Prop() min = 0;\n @Watch('min')\n protected minChanged() {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n }\n\n /**\n * Maximum integer value of the range.\n */\n @Prop() max = 100;\n @Watch('max')\n protected maxChanged() {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n }\n\n /**\n * If `true`, a pin with integer value is shown when the knob\n * is pressed.\n */\n @Prop() pin = false;\n\n /**\n * If `true`, the knob snaps to tick marks evenly spaced based\n * on the step property value.\n */\n @Prop() snaps = false;\n\n /**\n * Specifies the value granularity.\n */\n @Prop() step = 1;\n\n /**\n * If `true`, tick marks are displayed based on the step value.\n * Only applies when `snaps` is `true`.\n */\n @Prop() ticks = false;\n\n /**\n * If `true`, the user cannot interact with the range.\n */\n @Prop() disabled = false;\n @Watch('disabled')\n protected disabledChanged() {\n if (this.gesture) {\n this.gesture.enable(!this.disabled);\n }\n this.emitStyle();\n }\n\n /**\n * the value of the range.\n */\n @Prop({ mutable: true }) value: RangeValue = 0;\n @Watch('value')\n protected valueChanged(value: RangeValue) {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n\n value = this.ensureValueInBounds(value);\n\n this.nanoChange.emit({ value });\n }\n\n private clampBounds = (value: any): number => {\n return clamp(this.min, value, this.max);\n };\n\n private ensureValueInBounds = (value: any) => {\n if (this.dualKnobs) {\n return {\n lower: this.clampBounds(value.lower),\n upper: this.clampBounds(value.upper),\n };\n } else {\n return this.clampBounds(value);\n }\n };\n\n /**\n * Emitted when the value property has changed.\n */\n @Event() nanoChange!: EventEmitter<RangeChangeEventDetail>;\n\n /**\n * Emitted when the styles change.\n * @internal\n */\n @Event() nanoStyle!: EventEmitter<StyleEventDetail>;\n\n /**\n * Emitted when the range has focus.\n */\n @Event() nanoFocus!: EventEmitter<void>;\n\n /**\n * Emitted when the range loses focus.\n */\n @Event() nanoBlur!: EventEmitter<void>;\n\n connectedCallback() {\n this.updateRatio();\n this.debounceChanged();\n this.disabledChanged();\n }\n\n disconnectedCallback() {\n if (this.gesture) {\n this.gesture.destroy();\n this.gesture = undefined;\n }\n }\n\n async componentDidLoad() {\n const rangeSlider = this.rangeSlider;\n if (rangeSlider) {\n this.gesture = (await import('../../utils/gesture/index')).createGesture({\n el: rangeSlider,\n gestureName: 'range',\n gesturePriority: 100,\n threshold: 0,\n onStart: (ev) => this.onStart(ev),\n onMove: (ev) => this.onMove(ev),\n onEnd: (ev) => this.onEnd(ev),\n });\n this.gesture.enable(!this.disabled);\n }\n }\n\n private handleKeyboard = (knob: KnobName, isIncrease: boolean) => {\n let step = this.step;\n step = step > 0 ? step : 1;\n step = step / (this.max - this.min);\n if (!isIncrease) {\n step *= -1;\n }\n if (knob === 'A') {\n this.ratioA = clamp(0, this.ratioA + step, 1);\n } else {\n this.ratioB = clamp(0, this.ratioB + step, 1);\n }\n this.updateValue();\n };\n\n private getValue(): RangeValue {\n const value = this.value || 0;\n if (this.dualKnobs) {\n if (typeof value === 'object') {\n return value;\n }\n return {\n lower: 0,\n upper: value,\n };\n } else {\n if (typeof value === 'object') {\n return value.upper;\n }\n return value;\n }\n }\n\n private emitStyle() {\n this.nanoStyle.emit({\n interactive: true,\n 'interactive-disabled': this.disabled,\n });\n }\n\n private onStart(detail: GestureDetail) {\n const rect = (this.rect = this.rangeSlider!.getBoundingClientRect() as any);\n const currentX = detail.currentX;\n\n // figure out which knob they started closer to\n let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);\n if (document.dir === 'rtl') {\n ratio = 1 - ratio;\n }\n\n this.pressedKnob =\n !this.dualKnobs ||\n Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio)\n ? 'A'\n : 'B';\n\n this.setFocus(this.pressedKnob);\n\n // update the active knob's position\n this.update(currentX);\n }\n\n private onMove(detail: GestureDetail) {\n this.update(detail.currentX);\n }\n\n private onEnd(detail: GestureDetail) {\n this.update(detail.currentX);\n this.pressedKnob = undefined;\n }\n\n private update(currentX: number) {\n // figure out where the pointer is currently at\n // update the knob being interacted with\n const rect = this.rect;\n let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);\n if (document.dir === 'rtl') {\n ratio = 1 - ratio;\n }\n\n if (this.snaps) {\n // snaps the ratio to the current value\n ratio = valueToRatio(\n ratioToValue(ratio, this.min, this.max, this.step),\n this.min,\n this.max\n );\n }\n\n // update which knob is pressed\n if (this.pressedKnob === 'A') {\n this.ratioA = ratio;\n } else {\n this.ratioB = ratio;\n }\n\n // Update input value\n this.updateValue();\n }\n\n private get valA() {\n return ratioToValue(this.ratioA, this.min, this.max, this.step);\n }\n\n private get valB() {\n return ratioToValue(this.ratioB, this.min, this.max, this.step);\n }\n\n private get ratioLower() {\n if (this.dualKnobs) {\n return Math.min(this.ratioA, this.ratioB);\n }\n return 0;\n }\n\n private get ratioUpper() {\n if (this.dualKnobs) {\n return Math.max(this.ratioA, this.ratioB);\n }\n return this.ratioA;\n }\n\n private updateRatio() {\n const value = this.getValue() as any;\n const { min, max } = this;\n if (this.dualKnobs) {\n this.ratioA = valueToRatio(value.lower, min, max);\n this.ratioB = valueToRatio(value.upper, min, max);\n } else {\n this.ratioA = valueToRatio(value, min, max);\n }\n }\n\n private updateValue() {\n this.noUpdate = true;\n\n const { valA, valB } = this;\n this.value = !this.dualKnobs\n ? valA\n : {\n lower: Math.min(valA, valB),\n upper: Math.max(valA, valB),\n };\n\n this.noUpdate = false;\n }\n\n private setFocus(knob: KnobName) {\n if (this.el.shadowRoot) {\n const knobEl = this.el.shadowRoot.querySelector(\n knob === 'A' ? '.range-knob-a' : '.range-knob-b'\n ) as HTMLElement | undefined;\n if (knobEl) {\n knobEl.focus();\n }\n }\n }\n\n private onBlur = () => {\n if (this.hasFocus) {\n this.hasFocus = false;\n this.nanoBlur.emit();\n this.emitStyle();\n }\n };\n\n private onFocus = () => {\n if (!this.hasFocus) {\n this.hasFocus = true;\n this.nanoFocus.emit();\n this.emitStyle();\n }\n };\n\n render() {\n const {\n min,\n max,\n step,\n el,\n handleKeyboard,\n pressedKnob,\n disabled,\n pin,\n ratioLower,\n ratioUpper,\n } = this;\n\n const barStart = `${ratioLower * 100}%`;\n const barEnd = `${100 - ratioUpper * 100}%`;\n\n const doc = document;\n const isRTL = doc.dir === 'rtl';\n const start = isRTL ? 'right' : 'left';\n const end = isRTL ? 'left' : 'right';\n\n const tickStyle = (tick: any) => {\n return {\n [start]: tick[start],\n };\n };\n\n const barStyle = {\n [start]: barStart,\n [end]: barEnd,\n };\n\n const ticks = [];\n if (this.snaps && this.ticks) {\n for (let value = min; value <= max; value += step) {\n const ratio = valueToRatio(value, min, max);\n\n const tick: any = {\n ratio,\n active: ratio >= ratioLower && ratio <= ratioUpper,\n };\n\n tick[start] = `${ratio * 100}%`;\n\n ticks.push(tick);\n }\n }\n\n renderHiddenInput(el, this.name, JSON.stringify(this.getValue()), disabled);\n\n return (\n <Host\n onFocusin={this.onFocus}\n onFocusout={this.onBlur}\n class={createColorClasses(this.color, {\n 'range-disabled': disabled,\n 'range-pressed': pressedKnob !== undefined,\n 'range-has-pin': pin,\n 'range-snaps': this.snaps,\n })}\n >\n <div class=\"range-wrap\">\n <slot name=\"start\"></slot>\n <div\n class=\"range-slider\"\n ref={(rangeEl) => (this.rangeSlider = rangeEl)}\n >\n {ticks.map((tick) => (\n <span\n style={tickStyle(tick)}\n role=\"presentation\"\n class={{\n 'range-tick': true,\n 'range-tick-active': tick.active,\n }}\n part={tick.active ? 'tick-active' : 'tick'}\n />\n ))}\n\n <div class=\"range-bar\" role=\"presentation\" part=\"bar\" />\n <div\n class=\"range-bar range-bar-active\"\n role=\"presentation\"\n style={barStyle}\n part=\"bar-active\"\n />\n\n {renderKnob(isRTL, {\n knob: 'A',\n pressed: pressedKnob === 'A',\n value: this.valA,\n ratio: this.ratioA,\n pin,\n disabled,\n handleKeyboard,\n min,\n max,\n })}\n\n {this.dualKnobs &&\n renderKnob(isRTL, {\n knob: 'B',\n pressed: pressedKnob === 'B',\n value: this.valB,\n ratio: this.ratioB,\n pin,\n disabled,\n handleKeyboard,\n min,\n max,\n })}\n </div>\n <slot name=\"end\"></slot>\n </div>\n </Host>\n );\n }\n}\n\ninterface RangeKnob {\n knob: KnobName;\n value: number;\n ratio: number;\n min: number;\n max: number;\n disabled: boolean;\n pressed: boolean;\n pin: boolean;\n\n handleKeyboard: (name: KnobName, isIncrease: boolean) => void;\n}\n\nconst renderKnob = (\n isRTL: boolean,\n {\n knob,\n value,\n ratio,\n min,\n max,\n disabled,\n pressed,\n pin,\n handleKeyboard,\n }: RangeKnob\n) => {\n const start = isRTL ? 'right' : 'left';\n\n const knobStyle = () => {\n const style: any = {};\n style[start] = `${ratio * 100}%`;\n return style;\n };\n\n return (\n <div\n onKeyDown={(ev: KeyboardEvent) => {\n const key = ev.key;\n if (key === 'ArrowLeft' || key === 'ArrowDown') {\n handleKeyboard(knob, false);\n ev.preventDefault();\n ev.stopPropagation();\n } else if (key === 'ArrowRight' || key === 'ArrowUp') {\n handleKeyboard(knob, true);\n ev.preventDefault();\n ev.stopPropagation();\n }\n }}\n class={{\n 'range-knob-handle': true,\n 'range-knob-a': knob === 'A',\n 'range-knob-b': knob === 'B',\n 'range-knob-pressed': pressed,\n 'range-knob-min': value === min,\n 'range-knob-max': value === max,\n }}\n style={knobStyle()}\n role=\"slider\"\n tabindex={disabled ? -1 : 0}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-disabled={disabled ? 'true' : null}\n aria-valuenow={value}\n >\n {pin && (\n <div class=\"range-pin\" role=\"presentation\" part=\"pin\">\n {Math.round(value)}\n </div>\n )}\n <div class=\"range-knob\" role=\"presentation\" part=\"knob\" />\n </div>\n );\n};\n\nconst ratioToValue = (\n ratio: number,\n min: number,\n max: number,\n step: number\n): number => {\n let value = (max - min) * ratio;\n if (step > 0) {\n value = Math.round(value / step) * step + min;\n }\n return clamp(min, value, max);\n};\n\nconst valueToRatio = (value: number, min: number, max: number): number => {\n return clamp(0, (value - min) / (max - min), 1);\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["renderHiddenInput","container","name","value","disabled","input","querySelector","ownerDocument","createElement","type","classList","add","appendChild","rangeCss","Range","this","noUpdate","hasFocus","clampBounds","clamp","min","max","ensureValueInBounds","dualKnobs","lower","upper","handleKeyboard","knob","isIncrease","step","ratioA","ratioB","updateValue","onBlur","nanoBlur","emit","emitStyle","onFocus","nanoFocus","debounceChanged","nanoChange","debounceEvent","debounce","minChanged","updateRatio","maxChanged","disabledChanged","gesture","enable","valueChanged","connectedCallback","disconnectedCallback","destroy","undefined","async","rangeSlider","import","createGesture","el","gestureName","gesturePriority","threshold","onStart","ev","onMove","onEnd","getValue","nanoStyle","interactive","detail","rect","getBoundingClientRect","currentX","ratio","left","width","document","dir","pressedKnob","Math","abs","setFocus","update","snaps","valueToRatio","ratioToValue","valA","valB","ratioLower","ratioUpper","shadowRoot","knobEl","focus","render","pin","barStart","barEnd","doc","isRTL","start","end","tickStyle","tick","barStyle","ticks","active","push","JSON","stringify","h","Host","onFocusin","onFocusout","class","createColorClasses","color","ref","rangeEl","map","style","role","part","renderKnob","pressed","knobStyle","onKeyDown","key","preventDefault","stopPropagation","tabindex","round"],"sources":["./src/utils/form.ts","./src/components/range/range.scss?tag=nano-range&encapsulation=scoped","./src/components/range/range.tsx"],"sourcesContent":["export const renderHiddenInput = (\n container: HTMLElement,\n name: string,\n value: string | undefined | null,\n disabled: boolean\n) => {\n let input = container.querySelector(\n 'input.aux-input'\n ) as HTMLInputElement | null;\n if (!input) {\n input = container.ownerDocument!.createElement('input');\n input.type = 'hidden';\n input.classList.add('aux-input');\n container.appendChild(input);\n }\n input.disabled = disabled;\n input.name = name;\n input.value = value || '';\n};\n","@import '../../global/style/utilities/globals';\n@import '../../global/style/nano-theme/form';\n\n// Range\n// --------------------------------------------------\n\n:host {\n /**\n * @prop --knob-handle-size: defaults to calc(var(--knob-size) * 2);\n * @prop --rgb-inactive: defaults to #{color-to-rgb-list(#a5a5a5)};\n * @prop --bar-background: Background of the range bar; Defaults to #e2e1e0;\n * @prop --bar-background-active: Background of the active range bar; Defaults to #a5a5a5;\n * @prop --bar-height: Height of the range bar; Defaults to 8px;\n * @prop --bar-border-radius: Border radius of the range bar; Defaults to 4px;\n * @prop --height: Height of the range. Defaults to 42px;\n * @prop --knob-background: Background of the range knob. Defaults to #{nano-color(primary, base)};\n * @prop --knob-border-radius: Border radius of the range knob. Defaults to 50%;\n * @prop --knob-box-shadow: Box shadow of the range knob; Defaults to 0 2px 4px 0 rgb(0 0 0 / 30%);\n * @prop --knob-size: Size of the range knob; Defaults to 30px;\n * @prop --pin-background: Background of the range pin; Defaults to #{nano-color(primary, base)};\n * @prop --pin-color: Color of the range pin; Defaults to #{nano-color(primary, contrast)};\n * @prop --focus-style: Focus shadow around knob; Defaults to 0 0 0 5px #{$control-focus-color};\n */\n --knob-handle-size: (var(--knob-size) * 2);\n --rgb-inactive: #{color-to-rgb-list(#a5a5a5)};\n --knob-border-radius: 50%;\n --knob-background: #{nano-color(primary, base)};\n --knob-box-shadow: 0 2px 4px 0 rgb(0 0 0 / 30%);\n --knob-size: 30px;\n --bar-height: 8px;\n --bar-background: #e2e1e0;\n --bar-background-active: #a5a5a5;\n --bar-border-radius: 4px;\n --height: 42px;\n --pin-background: #{nano-color(primary, base)};\n --pin-color: #{nano-color(primary, contrast)};\n --focus-style: 0 0 0 5px #{$control-focus-color};\n}\n\n.range-wrap {\n display: flex;\n position: relative;\n flex: 3;\n align-items: center;\n user-select: none;\n\n ::slotted(ion-icon[slot]) {\n font-size: 1.5em;\n }\n\n ::slotted([slot='start']) {\n margin-inline: 0 14px;\n margin-block: 0;\n font-size: 0.9em;\n }\n\n ::slotted([slot='end']) {\n margin-inline: 14px 0;\n margin-block: 0;\n font-size: 0.9em;\n }\n}\n\n.range-slider {\n position: relative;\n flex: 1;\n width: 100%;\n height: var(--height);\n contain: size layout style;\n cursor: grab;\n touch-action: pan-y;\n}\n\n:host(.range-pressed) .range-slider {\n cursor: grabbing;\n}\n\n// bar\n\n.range-bar {\n border-radius: var(--bar-border-radius);\n inset-block-start: calc((var(--height) - var(--bar-height)) / 2);\n inset-inline-start: 0;\n position: absolute;\n width: 100%;\n height: var(--bar-height);\n background: var(--bar-background);\n pointer-events: none;\n\n :host(.range-snaps) & {\n border-radius: var(--bar-border-radius) 0 0 var(--bar-border-radius);\n }\n}\n\n.range-bar-active {\n inset-block-end: 0;\n width: auto;\n background: var(--bar-background-active);\n\n :host(.range-pressed) {\n will-change: left, right;\n }\n}\n\n// knob\n\n.range-knob {\n border-radius: var(--knob-border-radius);\n inset-block-start: calc(50% - var(--knob-size) / 2);\n inset-inline-start: calc(50% - var(--knob-size) / 2);\n position: absolute;\n width: var(--knob-size);\n height: var(--knob-size);\n background: var(--knob-background);\n box-shadow: var(--knob-box-shadow);\n z-index: 2;\n pointer-events: none;\n transform: scale(0.67);\n transition-duration: 120ms;\n transition-property: transform, background-color, border;\n transition-timing-function: ease;\n\n :host(:not(.range-has-pin)) .range-knob-pressed & {\n transform: scale(1);\n }\n}\n\n.range-knob-handle {\n inset-block-start: calc((var(--height) - var(--knob-handle-size)) / 2);\n inset-inline-start: 0;\n margin-inline-start: calc(0px - var(--knob-handle-size) / 2);\n position: absolute;\n width: calc(var(--knob-handle-size));\n height: calc(var(--knob-handle-size));\n text-align: center;\n\n &:active,\n &:focus {\n outline: none;\n\n .range-knob {\n box-shadow: var(--knob-box-shadow), var(--focus-style);\n }\n }\n}\n\n// ticks\n\n.range-tick {\n position: absolute;\n inset-block-start: calc((var(--height) - var(--bar-height)) / 2);\n width: var(--bar-height);\n height: var(--bar-height);\n background: var(--bar-background-active);\n z-index: 1;\n pointer-events: none;\n\n &:first-of-type {\n border-radius: var(--bar-border-radius) 0 0 var(--bar-border-radius);\n }\n\n &:last-of-type {\n border-radius: 0 var(--bar-border-radius) var(--bar-border-radius) 0;\n }\n\n &-active {\n background: transparent;\n }\n}\n\n// pin\n\n.range-pin {\n transform: translate3d(0, 0, 0) scale(0.01);\n transform-origin: center top;\n padding: 0.66em 0;\n border-radius: 50%;\n text-align: center;\n box-sizing: border-box;\n display: inline-block;\n position: relative;\n min-width: 2.33em;\n height: 2.33em;\n transition: transform 120ms ease, background 120ms ease;\n background: var(--pin-background);\n color: var(--pin-color);\n font-size: 0.75em;\n\n &::before {\n inset-block-start: 0.25em;\n inset-inline-start: 50%;\n margin-inline-start: -1.08em;\n border-radius: 50% 50% 50% 0;\n position: absolute;\n width: 2.16em;\n height: 2.16em;\n transform: rotate(-45deg);\n transition: background 120ms ease;\n background: var(--pin-background);\n content: '';\n z-index: -1;\n }\n\n .range-knob-pressed & {\n transform: translate3d(0, -50%, 0) scale(1);\n transform: translate3d(0, calc((100% - var(--bar-height)) * -1), 0) scale(1);\n }\n}\n\n// disabled\n\n:host(.range-disabled) {\n pointer-events: none;\n\n .range-bar-active,\n .range-bar,\n .range-tick {\n background-color: rgb(var(--rgb-inactive) / 50%);\n }\n\n .range-knob {\n transform: scale(0.55);\n outline: 5px solid #fff;\n background-color: rgb(var(--rgb-inactive) / 50%);\n }\n}\n\n// theme\n\n:host(.nano-color) {\n .range-bar-active,\n .range-knob,\n .range-pin,\n .range-pin::before,\n .range-tick {\n background: current-color(base);\n color: current-color(contrast);\n }\n\n .range-bar {\n background: current-color(base, 0.26);\n }\n\n .range-knob-handle {\n &:active,\n &:focus {\n .range-knob {\n box-shadow: var(--knob-box-shadow), 0 0 0 5px current-color(tint, 0.56);\n }\n }\n }\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Host,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { renderHiddenInput } from '../../utils/form';\nimport { clamp } from '../../utils/math';\nimport { createColorClasses } from '../../utils/theme';\nimport { debounceEvent } from '../../utils/throttle';\nimport type {\n Color,\n Gesture,\n GestureDetail,\n KnobName,\n RangeChangeEventDetail,\n RangeValue,\n StyleEventDetail,\n} from '../../interface';\n\n/**\n * The Range slider lets users select from a range of values by moving\n * the slider knob. It can accept dual knobs, but by default one knob controls the value of the range.\n *\n * Labels can be placed on either side of the range by adding the\n * `slot=\"start\"` or `slot=\"end\"` to the element.\n *\n * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.\n * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.\n */\n@Component({\n tag: 'nano-range',\n styleUrl: 'range.scss',\n scoped: true,\n})\nexport class Range implements ComponentInterface {\n private noUpdate = false;\n private rect!: ClientRect;\n private hasFocus = false;\n private rangeSlider?: HTMLElement;\n private gesture?: Gesture;\n\n @Element() el!: HTMLNanoRangeElement;\n\n @State() private ratioA = 0;\n @State() private ratioB = 0;\n @State() private pressedKnob: KnobName;\n\n /**\n * The color to use from your application's color palette.\n * Default options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`\n */\n @Prop() color?: Color;\n\n /**\n * How long, in milliseconds, to wait to trigger the\n * `nanoChange` event after each change in the range value.\n */\n @Prop() debounce = 0;\n\n @Watch('debounce')\n protected debounceChanged() {\n this.nanoChange = debounceEvent(this.nanoChange, this.debounce);\n }\n\n /**\n * The name of the control, which is submitted with the form data.\n */\n @Prop() name = '';\n\n /**\n * Show two knobs.\n */\n @Prop() dualKnobs = false;\n\n /**\n * Minimum integer value of the range.\n */\n @Prop() min = 0;\n @Watch('min')\n protected minChanged() {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n }\n\n /**\n * Maximum integer value of the range.\n */\n @Prop() max = 100;\n @Watch('max')\n protected maxChanged() {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n }\n\n /**\n * If `true`, a pin with integer value is shown when the knob\n * is pressed.\n */\n @Prop() pin = false;\n\n /**\n * If `true`, the knob snaps to tick marks evenly spaced based\n * on the step property value.\n */\n @Prop() snaps = false;\n\n /**\n * Specifies the value granularity.\n */\n @Prop() step = 1;\n\n /**\n * If `true`, tick marks are displayed based on the step value.\n * Only applies when `snaps` is `true`.\n */\n @Prop() ticks = false;\n\n /**\n * If `true`, the user cannot interact with the range.\n */\n @Prop() disabled = false;\n @Watch('disabled')\n protected disabledChanged() {\n if (this.gesture) {\n this.gesture.enable(!this.disabled);\n }\n this.emitStyle();\n }\n\n /**\n * the value of the range.\n */\n @Prop({ mutable: true }) value: RangeValue = 0;\n @Watch('value')\n protected valueChanged(value: RangeValue) {\n if (!this.noUpdate) {\n this.updateRatio();\n }\n\n value = this.ensureValueInBounds(value);\n\n this.nanoChange.emit({ value });\n }\n\n private clampBounds = (value: any): number => {\n return clamp(this.min, value, this.max);\n };\n\n private ensureValueInBounds = (value: any) => {\n if (this.dualKnobs) {\n return {\n lower: this.clampBounds(value.lower),\n upper: this.clampBounds(value.upper),\n };\n } else {\n return this.clampBounds(value);\n }\n };\n\n /**\n * Emitted when the value property has changed.\n */\n @Event() nanoChange!: EventEmitter<RangeChangeEventDetail>;\n\n /**\n * Emitted when the styles change.\n * @internal\n */\n @Event() nanoStyle!: EventEmitter<StyleEventDetail>;\n\n /**\n * Emitted when the range has focus.\n */\n @Event() nanoFocus!: EventEmitter<void>;\n\n /**\n * Emitted when the range loses focus.\n */\n @Event() nanoBlur!: EventEmitter<void>;\n\n connectedCallback() {\n this.updateRatio();\n this.debounceChanged();\n this.disabledChanged();\n }\n\n disconnectedCallback() {\n if (this.gesture) {\n this.gesture.destroy();\n this.gesture = undefined;\n }\n }\n\n async componentDidLoad() {\n const rangeSlider = this.rangeSlider;\n if (rangeSlider) {\n this.gesture = (await import('../../utils/gesture/index')).createGesture({\n el: rangeSlider,\n gestureName: 'range',\n gesturePriority: 100,\n threshold: 0,\n onStart: (ev) => this.onStart(ev),\n onMove: (ev) => this.onMove(ev),\n onEnd: (ev) => this.onEnd(ev),\n });\n this.gesture.enable(!this.disabled);\n }\n }\n\n private handleKeyboard = (knob: KnobName, isIncrease: boolean) => {\n let step = this.step;\n step = step > 0 ? step : 1;\n step = step / (this.max - this.min);\n if (!isIncrease) {\n step *= -1;\n }\n if (knob === 'A') {\n this.ratioA = clamp(0, this.ratioA + step, 1);\n } else {\n this.ratioB = clamp(0, this.ratioB + step, 1);\n }\n this.updateValue();\n };\n\n private getValue(): RangeValue {\n const value = this.value || 0;\n if (this.dualKnobs) {\n if (typeof value === 'object') {\n return value;\n }\n return {\n lower: 0,\n upper: value,\n };\n } else {\n if (typeof value === 'object') {\n return value.upper;\n }\n return value;\n }\n }\n\n private emitStyle() {\n this.nanoStyle.emit({\n interactive: true,\n 'interactive-disabled': this.disabled,\n });\n }\n\n private onStart(detail: GestureDetail) {\n const rect = (this.rect = this.rangeSlider!.getBoundingClientRect() as any);\n const currentX = detail.currentX;\n\n // figure out which knob they started closer to\n let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);\n if (document.dir === 'rtl') {\n ratio = 1 - ratio;\n }\n\n this.pressedKnob =\n !this.dualKnobs ||\n Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio)\n ? 'A'\n : 'B';\n\n this.setFocus(this.pressedKnob);\n\n // update the active knob's position\n this.update(currentX);\n }\n\n private onMove(detail: GestureDetail) {\n this.update(detail.currentX);\n }\n\n private onEnd(detail: GestureDetail) {\n this.update(detail.currentX);\n this.pressedKnob = undefined;\n }\n\n private update(currentX: number) {\n // figure out where the pointer is currently at\n // update the knob being interacted with\n const rect = this.rect;\n let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);\n if (document.dir === 'rtl') {\n ratio = 1 - ratio;\n }\n\n if (this.snaps) {\n // snaps the ratio to the current value\n ratio = valueToRatio(\n ratioToValue(ratio, this.min, this.max, this.step),\n this.min,\n this.max\n );\n }\n\n // update which knob is pressed\n if (this.pressedKnob === 'A') {\n this.ratioA = ratio;\n } else {\n this.ratioB = ratio;\n }\n\n // Update input value\n this.updateValue();\n }\n\n private get valA() {\n return ratioToValue(this.ratioA, this.min, this.max, this.step);\n }\n\n private get valB() {\n return ratioToValue(this.ratioB, this.min, this.max, this.step);\n }\n\n private get ratioLower() {\n if (this.dualKnobs) {\n return Math.min(this.ratioA, this.ratioB);\n }\n return 0;\n }\n\n private get ratioUpper() {\n if (this.dualKnobs) {\n return Math.max(this.ratioA, this.ratioB);\n }\n return this.ratioA;\n }\n\n private updateRatio() {\n const value = this.getValue() as any;\n const { min, max } = this;\n if (this.dualKnobs) {\n this.ratioA = valueToRatio(value.lower, min, max);\n this.ratioB = valueToRatio(value.upper, min, max);\n } else {\n this.ratioA = valueToRatio(value, min, max);\n }\n }\n\n private updateValue() {\n this.noUpdate = true;\n\n const { valA, valB } = this;\n this.value = !this.dualKnobs\n ? valA\n : {\n lower: Math.min(valA, valB),\n upper: Math.max(valA, valB),\n };\n\n this.noUpdate = false;\n }\n\n private setFocus(knob: KnobName) {\n if (this.el.shadowRoot) {\n const knobEl = this.el.shadowRoot.querySelector(\n knob === 'A' ? '.range-knob-a' : '.range-knob-b'\n ) as HTMLElement | undefined;\n if (knobEl) {\n knobEl.focus();\n }\n }\n }\n\n private onBlur = () => {\n if (this.hasFocus) {\n this.hasFocus = false;\n this.nanoBlur.emit();\n this.emitStyle();\n }\n };\n\n private onFocus = () => {\n if (!this.hasFocus) {\n this.hasFocus = true;\n this.nanoFocus.emit();\n this.emitStyle();\n }\n };\n\n render() {\n const {\n min,\n max,\n step,\n el,\n handleKeyboard,\n pressedKnob,\n disabled,\n pin,\n ratioLower,\n ratioUpper,\n } = this;\n\n const barStart = `${ratioLower * 100}%`;\n const barEnd = `${100 - ratioUpper * 100}%`;\n\n const doc = document;\n const isRTL = doc.dir === 'rtl';\n const start = isRTL ? 'right' : 'left';\n const end = isRTL ? 'left' : 'right';\n\n const tickStyle = (tick: any) => {\n return {\n [start]: tick[start],\n };\n };\n\n const barStyle = {\n [start]: barStart,\n [end]: barEnd,\n };\n\n const ticks = [];\n if (this.snaps && this.ticks) {\n for (let value = min; value <= max; value += step) {\n const ratio = valueToRatio(value, min, max);\n\n const tick: any = {\n ratio,\n active: ratio >= ratioLower && ratio <= ratioUpper,\n };\n\n tick[start] = `${ratio * 100}%`;\n\n ticks.push(tick);\n }\n }\n\n renderHiddenInput(el, this.name, JSON.stringify(this.getValue()), disabled);\n\n return (\n <Host\n onFocusin={this.onFocus}\n onFocusout={this.onBlur}\n class={createColorClasses(this.color, {\n 'range-disabled': disabled,\n 'range-pressed': pressedKnob !== undefined,\n 'range-has-pin': pin,\n 'range-snaps': this.snaps,\n })}\n >\n <div class=\"range-wrap\">\n <slot name=\"start\"></slot>\n <div\n class=\"range-slider\"\n ref={(rangeEl) => (this.rangeSlider = rangeEl)}\n >\n {ticks.map((tick) => (\n <span\n style={tickStyle(tick)}\n role=\"presentation\"\n class={{\n 'range-tick': true,\n 'range-tick-active': tick.active,\n }}\n part={tick.active ? 'tick-active' : 'tick'}\n />\n ))}\n\n <div class=\"range-bar\" role=\"presentation\" part=\"bar\" />\n <div\n class=\"range-bar range-bar-active\"\n role=\"presentation\"\n style={barStyle}\n part=\"bar-active\"\n />\n\n {renderKnob(isRTL, {\n knob: 'A',\n pressed: pressedKnob === 'A',\n value: this.valA,\n ratio: this.ratioA,\n pin,\n disabled,\n handleKeyboard,\n min,\n max,\n })}\n\n {this.dualKnobs &&\n renderKnob(isRTL, {\n knob: 'B',\n pressed: pressedKnob === 'B',\n value: this.valB,\n ratio: this.ratioB,\n pin,\n disabled,\n handleKeyboard,\n min,\n max,\n })}\n </div>\n <slot name=\"end\"></slot>\n </div>\n </Host>\n );\n }\n}\n\ninterface RangeKnob {\n knob: KnobName;\n value: number;\n ratio: number;\n min: number;\n max: number;\n disabled: boolean;\n pressed: boolean;\n pin: boolean;\n\n handleKeyboard: (name: KnobName, isIncrease: boolean) => void;\n}\n\nconst renderKnob = (\n isRTL: boolean,\n {\n knob,\n value,\n ratio,\n min,\n max,\n disabled,\n pressed,\n pin,\n handleKeyboard,\n }: RangeKnob\n) => {\n const start = isRTL ? 'right' : 'left';\n\n const knobStyle = () => {\n const style: any = {};\n style[start] = `${ratio * 100}%`;\n return style;\n };\n\n return (\n <div\n onKeyDown={(ev: KeyboardEvent) => {\n const key = ev.key;\n if (key === 'ArrowLeft' || key === 'ArrowDown') {\n handleKeyboard(knob, false);\n ev.preventDefault();\n ev.stopPropagation();\n } else if (key === 'ArrowRight' || key === 'ArrowUp') {\n handleKeyboard(knob, true);\n ev.preventDefault();\n ev.stopPropagation();\n }\n }}\n class={{\n 'range-knob-handle': true,\n 'range-knob-a': knob === 'A',\n 'range-knob-b': knob === 'B',\n 'range-knob-pressed': pressed,\n 'range-knob-min': value === min,\n 'range-knob-max': value === max,\n }}\n style={knobStyle()}\n role=\"slider\"\n tabindex={disabled ? -1 : 0}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-disabled={disabled ? 'true' : null}\n aria-valuenow={value}\n >\n {pin && (\n <div class=\"range-pin\" role=\"presentation\" part=\"pin\">\n {Math.round(value)}\n </div>\n )}\n <div class=\"range-knob\" role=\"presentation\" part=\"knob\" />\n </div>\n );\n};\n\nconst ratioToValue = (\n ratio: number,\n min: number,\n max: number,\n step: number\n): number => {\n let value = (max - min) * ratio;\n if (step > 0) {\n value = Math.round(value / step) * step + min;\n }\n return clamp(min, value, max);\n};\n\nconst valueToRatio = (value: number, min: number, max: number): number => {\n return clamp(0, (value - min) / (max - min), 1);\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":["spinnerCss","Spinner","componentWillLoad","this","hasText","el","childNodes","length","render","h","class","type","key","overlay"],"sources":["./src/components/spinner/spinner.scss?tag=nano-spinner&encapsulation=shadow","./src/components/spinner/spinner.tsx"],"sourcesContent":["@import '../../global/style/nano-theme/components';\n@import '../../global/style/nano-theme/layers';\n\n:host {\n /**\n * @prop --base-color-rgb: default #{$progress-indicator-color-rgb}\n * @prop --indicator-color: default var(--nano-indicator-color, rgba(var(--base-color-rgb), 1));\n * @prop --track-color: default var(--nano-track-color, rgba(var(--base-color-rgb), 0.2));\n * @prop --spinner-scale: optional scaling of the spinner. default contextual font-size\n * @prop --overlay-color: #{$layer-overlay-light};\n */\n\n display: inline-block;\n\n // --spinner-scale: 5em;\n --base-color-rgb: #{$progress-indicator-color-rgb};\n --indicator-color:\n var(\n --nano-indicator-color,\n rgb(var(--base-color-rgb) / 100%)\n );\n --track-color: var(--nano-track-color, rgb(var(--base-color-rgb) / 20%));\n --overlay-color: #{$layer-overlay-light};\n}\n\n.spinner {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n :host([overlay]:not([overlay='false'])) & {\n position: absolute;\n inset: 0;\n\n .spinner__loader,\n .spinner__text {\n z-index: 1;\n }\n }\n\n &__overlay {\n background: var(--overlay-color);\n position: absolute;\n inset: 0;\n z-index: 0;\n backdrop-filter: blur(#{$layer-overlay-blur});\n }\n\n &__loader {\n font-size: var(--spinner-scale, 1em);\n }\n\n &__spin {\n display: block;\n margin: auto;\n inline-size: 1em;\n block-size: 1em;\n border-radius: 50%;\n border: solid 0.1em var(--track-color);\n border-block-start-color: var(--indicator-color);\n border-inline-end-color: var(--indicator-color);\n border-inline-start-color: var(--indicator-color);\n animation: 1s linear infinite spin;\n }\n\n &__dna {\n font-size: 0.2286em;\n display: flex;\n }\n\n &__dnatrack {\n position: relative;\n padding-block: 0;\n padding-inline: 0.625em;\n block-size: 4.375em;\n inline-size: 0.625em;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n inset-block-start: 1.875em;\n inset-inline-start: 50%;\n transform: translateX(-50%) translateZ(0);\n inline-size: 0.0625em;\n inline-size: #{'max(.0625em, 1px)'};\n block-size: 0.625em;\n background: var(--track-color);\n animation: flex 1.5s linear infinite;\n transform-origin: center center;\n }\n\n &--2::before {\n animation: flex 1.5s -1.3s linear infinite;\n }\n\n &--3::before {\n animation: flex 1.5s -1.1s linear infinite;\n }\n\n &--4::before {\n animation: flex 1.5s -0.9s linear infinite;\n }\n\n &--5::before {\n animation: flex 1.5s -0.75s linear infinite;\n }\n }\n\n &__dnadot {\n position: absolute;\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: 50%;\n background: var(--indicator-color);\n animation: rotate 1.5s linear infinite;\n transform-origin: center center;\n inset-inline-start: 50%;\n transform: translateX(-50%) translateZ(0) translateY(0);\n\n &--2 {\n animation: rotate 1.5s -0.75s linear infinite;\n }\n\n &--3 {\n animation: rotate 1.5s -1.3s linear infinite;\n }\n\n &--4 {\n animation: rotate 1.5s -0.55s linear infinite;\n }\n\n &--5 {\n animation: rotate 1.5s -1.1s linear infinite;\n }\n\n &--6 {\n animation: rotate 1.5s -0.35s linear infinite;\n }\n\n &--7 {\n animation: rotate 1.5s -0.9s linear infinite;\n }\n\n &--8 {\n animation: rotate 1.5s -0.15s linear infinite;\n }\n\n &--9 {\n animation: rotate 1.5s -0.75s linear infinite;\n }\n\n &--10 {\n animation: rotate 1.5s 0s linear infinite;\n }\n }\n\n &__text {\n text-align: center;\n position: relative;\n margin-block-start: 0.5em;\n }\n\n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n }\n\n @keyframes rotate {\n 0%,\n 100% {\n transform: translateX(-50%) translateY(0) scale(1);\n }\n\n 25% {\n transform: translateX(-50%) translateY(1.875em) scale(2);\n }\n\n 50% {\n transform: translateX(-50%) translateY(3.75em) scale(1);\n }\n\n 75% {\n transform: translateX(-50%) translateY(1.875em) scale(0.3);\n }\n }\n\n @keyframes flex {\n 0%,\n 100% {\n transform: translateX(-50%) scaleY(5);\n }\n\n 25% {\n transform: translateX(-50%) scaleY(1);\n }\n\n 50% {\n transform: translateX(-50%) scaleY(5);\n }\n\n 75% {\n transform: translateX(-50%) scaleY(1);\n }\n }\n}\n","import {\n Component,\n h,\n ComponentInterface,\n Prop,\n Element,\n State,\n} from '@stencil/core';\n\n/**\n * Spinners are used to show the progress of an indeterminate operation.\n * @slot - Used for loading messages\n */\n@Component({\n tag: 'nano-spinner',\n styleUrl: 'spinner.scss',\n shadow: true,\n})\nexport class Spinner implements ComponentInterface {\n @Element() el: HTMLNanoSpinnerElement;\n @State() hasText: boolean = false;\n\n /** The type of spinner animation. dna should be used for larger, page loads. Circle for smaller component loaders. */\n @Prop() type: 'dna' | 'circle' = 'dna';\n\n /** Displays absolutely with an overlay */\n @Prop({ reflect: true }) overlay: boolean = false;\n\n componentWillLoad() {\n this.hasText = !!this.el.childNodes.length;\n }\n\n render() {\n return (\n <div class=\"spinner\" aria-busy=\"true\" aria-live=\"polite\">\n <div class=\"spinner__loader\">\n {this.type === 'dna' && (\n <div class=\"spinner__dna\">\n <div class=\"spinner__dnatrack spinner__dnatrack--1\">\n <div class=\"spinner__dnadot spinner__dnadot--1\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--2\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--2\">\n <div class=\"spinner__dnadot spinner__dnadot--3\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--4\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--3\">\n <div class=\"spinner__dnadot spinner__dnadot--5\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--6\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--4\">\n <div class=\"spinner__dnadot spinner__dnadot--7\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--8\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--5\">\n <div class=\"spinner__dnadot spinner__dnadot--9\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--10\"></div>\n </div>\n </div>\n )}\n {this.type === 'circle' && <span class=\"spinner__spin\"></span>}\n </div>\n {this.hasText && (\n <div class=\"spinner__text\" key=\"spinner-text\">\n <slot />\n </div>\n )}\n {this.overlay && (\n <div class=\"spinner__overlay\" key=\"spinner-overlay\"></div>\n )}\n </div>\n );\n }\n}\n"],"mappings":";;;kDAAA,MAAMA,EAAa,09G,MCkBNC,EAAO,M,sCAEU,M,UAGK,M,aAGW,K,CAE5CC,oBACEC,KAAKC,UAAYD,KAAKE,GAAGC,WAAWC,M,CAGtCC,SACE,OACEC,EAAA,OAAKC,MAAM,UAAS,YAAW,OAAM,YAAW,UAC9CD,EAAA,OAAKC,MAAM,mBACRP,KAAKQ,OAAS,OACbF,EAAA,OAAKC,MAAM,gBACTD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,0CAIhBP,KAAKQ,OAAS,UAAYF,EAAA,QAAMC,MAAM,mBAExCP,KAAKC,SACJK,EAAA,OAAKC,MAAM,gBAAgBE,IAAI,gBAC7BH,EAAA,cAGHN,KAAKU,SACJJ,EAAA,OAAKC,MAAM,mBAAmBE,IAAI,oB"}
1
+ {"version":3,"names":["spinnerCss","Spinner","componentWillLoad","this","hasText","el","childNodes","length","render","h","class","type","key","overlay"],"sources":["./src/components/spinner/spinner.scss?tag=nano-spinner&encapsulation=shadow","./src/components/spinner/spinner.tsx"],"sourcesContent":["@import '../../global/style/nano-theme/components';\n@import '../../global/style/nano-theme/layers';\n\n:host {\n /**\n * @prop --base-color-rgb: default #{$progress-indicator-color-rgb}\n * @prop --indicator-color: default var(--nano-indicator-color, rgb(var(--base-color-rgb) / 10%));\n * @prop --track-color: default var(--nano-track-color, rgb(var(--base-color-rgb) / 20%));\n * @prop --spinner-scale: optional scaling of the spinner. default contextual font-size\n * @prop --overlay-color: #{$layer-overlay-light};\n */\n\n display: inline-block;\n\n // --spinner-scale: 5em;\n --base-color-rgb: #{$progress-indicator-color-rgb};\n --indicator-color:\n var(\n --nano-indicator-color,\n rgb(var(--base-color-rgb) / 100%)\n );\n --track-color: var(--nano-track-color, rgb(var(--base-color-rgb) / 20%));\n --overlay-color: #{$layer-overlay-light};\n}\n\n.spinner {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n :host([overlay]:not([overlay='false'])) & {\n position: absolute;\n inset: 0;\n\n .spinner__loader,\n .spinner__text {\n z-index: 1;\n }\n }\n\n &__overlay {\n background: var(--overlay-color);\n position: absolute;\n inset: 0;\n z-index: 0;\n backdrop-filter: blur(#{$layer-overlay-blur});\n }\n\n &__loader {\n font-size: var(--spinner-scale, 1em);\n }\n\n &__spin {\n display: block;\n margin: auto;\n inline-size: 1em;\n block-size: 1em;\n border-radius: 50%;\n border: solid 0.1em var(--track-color);\n border-block-start-color: var(--indicator-color);\n border-inline-end-color: var(--indicator-color);\n border-inline-start-color: var(--indicator-color);\n animation: 1s linear infinite spin;\n }\n\n &__dna {\n font-size: 0.2286em;\n display: flex;\n }\n\n &__dnatrack {\n position: relative;\n padding-block: 0;\n padding-inline: 0.625em;\n block-size: 4.375em;\n inline-size: 0.625em;\n overflow: hidden;\n\n &::before {\n content: '';\n position: absolute;\n inset-block-start: 1.875em;\n inset-inline-start: 50%;\n transform: translateX(-50%) translateZ(0);\n inline-size: 0.0625em;\n inline-size: #{'max(.0625em, 1px)'};\n block-size: 0.625em;\n background: var(--track-color);\n animation: flex 1.5s linear infinite;\n transform-origin: center center;\n }\n\n &--2::before {\n animation: flex 1.5s -1.3s linear infinite;\n }\n\n &--3::before {\n animation: flex 1.5s -1.1s linear infinite;\n }\n\n &--4::before {\n animation: flex 1.5s -0.9s linear infinite;\n }\n\n &--5::before {\n animation: flex 1.5s -0.75s linear infinite;\n }\n }\n\n &__dnadot {\n position: absolute;\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: 50%;\n background: var(--indicator-color);\n animation: rotate 1.5s linear infinite;\n transform-origin: center center;\n inset-inline-start: 50%;\n transform: translateX(-50%) translateZ(0) translateY(0);\n\n &--2 {\n animation: rotate 1.5s -0.75s linear infinite;\n }\n\n &--3 {\n animation: rotate 1.5s -1.3s linear infinite;\n }\n\n &--4 {\n animation: rotate 1.5s -0.55s linear infinite;\n }\n\n &--5 {\n animation: rotate 1.5s -1.1s linear infinite;\n }\n\n &--6 {\n animation: rotate 1.5s -0.35s linear infinite;\n }\n\n &--7 {\n animation: rotate 1.5s -0.9s linear infinite;\n }\n\n &--8 {\n animation: rotate 1.5s -0.15s linear infinite;\n }\n\n &--9 {\n animation: rotate 1.5s -0.75s linear infinite;\n }\n\n &--10 {\n animation: rotate 1.5s 0s linear infinite;\n }\n }\n\n &__text {\n text-align: center;\n position: relative;\n margin-block-start: 0.5em;\n }\n\n @keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n }\n\n @keyframes rotate {\n 0%,\n 100% {\n transform: translateX(-50%) translateY(0) scale(1);\n }\n\n 25% {\n transform: translateX(-50%) translateY(1.875em) scale(2);\n }\n\n 50% {\n transform: translateX(-50%) translateY(3.75em) scale(1);\n }\n\n 75% {\n transform: translateX(-50%) translateY(1.875em) scale(0.3);\n }\n }\n\n @keyframes flex {\n 0%,\n 100% {\n transform: translateX(-50%) scaleY(5);\n }\n\n 25% {\n transform: translateX(-50%) scaleY(1);\n }\n\n 50% {\n transform: translateX(-50%) scaleY(5);\n }\n\n 75% {\n transform: translateX(-50%) scaleY(1);\n }\n }\n}\n","import {\n Component,\n h,\n ComponentInterface,\n Prop,\n Element,\n State,\n} from '@stencil/core';\n\n/**\n * Spinners are used to show the progress of an indeterminate operation.\n * @slot - Used for loading messages\n */\n@Component({\n tag: 'nano-spinner',\n styleUrl: 'spinner.scss',\n shadow: true,\n})\nexport class Spinner implements ComponentInterface {\n @Element() el: HTMLNanoSpinnerElement;\n @State() hasText: boolean = false;\n\n /** The type of spinner animation. dna should be used for larger, page loads. Circle for smaller component loaders. */\n @Prop() type: 'dna' | 'circle' = 'dna';\n\n /** Displays absolutely with an overlay */\n @Prop({ reflect: true }) overlay: boolean = false;\n\n componentWillLoad() {\n this.hasText = !!this.el.childNodes.length;\n }\n\n render() {\n return (\n <div class=\"spinner\" aria-busy=\"true\" aria-live=\"polite\">\n <div class=\"spinner__loader\">\n {this.type === 'dna' && (\n <div class=\"spinner__dna\">\n <div class=\"spinner__dnatrack spinner__dnatrack--1\">\n <div class=\"spinner__dnadot spinner__dnadot--1\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--2\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--2\">\n <div class=\"spinner__dnadot spinner__dnadot--3\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--4\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--3\">\n <div class=\"spinner__dnadot spinner__dnadot--5\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--6\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--4\">\n <div class=\"spinner__dnadot spinner__dnadot--7\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--8\"></div>\n </div>\n <div class=\"spinner__dnatrack spinner__dnatrack--5\">\n <div class=\"spinner__dnadot spinner__dnadot--9\"></div>\n <div class=\"spinner__dnadot spinner__dnadot--10\"></div>\n </div>\n </div>\n )}\n {this.type === 'circle' && <span class=\"spinner__spin\"></span>}\n </div>\n {this.hasText && (\n <div class=\"spinner__text\" key=\"spinner-text\">\n <slot />\n </div>\n )}\n {this.overlay && (\n <div class=\"spinner__overlay\" key=\"spinner-overlay\"></div>\n )}\n </div>\n );\n }\n}\n"],"mappings":";;;kDAAA,MAAMA,EAAa,09G,MCkBNC,EAAO,M,sCAEU,M,UAGK,M,aAGW,K,CAE5CC,oBACEC,KAAKC,UAAYD,KAAKE,GAAGC,WAAWC,M,CAGtCC,SACE,OACEC,EAAA,OAAKC,MAAM,UAAS,YAAW,OAAM,YAAW,UAC9CD,EAAA,OAAKC,MAAM,mBACRP,KAAKQ,OAAS,OACbF,EAAA,OAAKC,MAAM,gBACTD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,wCAEbD,EAAA,OAAKC,MAAM,0CACTD,EAAA,OAAKC,MAAM,uCACXD,EAAA,OAAKC,MAAM,0CAIhBP,KAAKQ,OAAS,UAAYF,EAAA,QAAMC,MAAM,mBAExCP,KAAKC,SACJK,EAAA,OAAKC,MAAM,gBAAgBE,IAAI,gBAC7BH,EAAA,cAGHN,KAAKU,SACJJ,EAAA,OAAKC,MAAM,mBAAmBE,IAAI,oB"}