@felleslosninger/minid-elements 0.0.110 → 0.0.111

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 (33) hide show
  1. package/dist/components/checkbox.component.d.ts +0 -14
  2. package/dist/components/checkbox.component.d.ts.map +1 -1
  3. package/dist/components/checkbox.js +1 -21
  4. package/dist/components/checkbox.js.map +1 -1
  5. package/dist/components/code-input-old.component.d.ts +55 -0
  6. package/dist/components/code-input-old.component.d.ts.map +1 -0
  7. package/dist/components/code-input-old.js +313 -0
  8. package/dist/components/code-input-old.js.map +1 -0
  9. package/dist/components/code-input.component.d.ts +59 -33
  10. package/dist/components/code-input.component.d.ts.map +1 -1
  11. package/dist/components/code-input.js +244 -230
  12. package/dist/components/code-input.js.map +1 -1
  13. package/dist/components/dropdown.js +1 -1
  14. package/dist/components/dropdown.js.map +1 -1
  15. package/dist/components/menu.component.d.ts.map +1 -1
  16. package/dist/components/menu.js +1 -3
  17. package/dist/components/menu.js.map +1 -1
  18. package/dist/components/textfield.component.d.ts +0 -1
  19. package/dist/components/textfield.component.d.ts.map +1 -1
  20. package/dist/components/textfield.js +0 -3
  21. package/dist/components/textfield.js.map +1 -1
  22. package/dist/designsystemet-tailwind.css +43 -13
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/mixins/validators.js +2 -2
  28. package/dist/mixins/validators.js.map +1 -1
  29. package/package.json +2 -1
  30. package/dist/components/code-input-2.component.d.ts +0 -15
  31. package/dist/components/code-input-2.component.d.ts.map +0 -1
  32. package/dist/components/code-input-2.js +0 -82
  33. package/dist/components/code-input-2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown.js","sources":["../../src/components/dropdown.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport './popup.component';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry.ts';\nimport { waitForEvent } from '../internal/event.ts';\nimport { MinidPopup } from './popup.component';\nimport { watch } from '../internal/watch.ts';\nimport { animateTo, stopAnimations } from '../internal/animate.ts';\nimport { getTabbableBoundary } from '../internal/tabbable.ts';\nimport { MinidButton } from '../components/button.component.ts';\nimport type { MidSelectEvent } from '../events/mid-select.ts';\nimport { MinidMenu } from '../components/menu.component.ts';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-dropdown': MinidDropdown;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: inline-flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n * @part panel - Select the dropdown panel host element\n */\n@customElement('mid-dropdown')\nexport class MinidDropdown extends styled(LitElement, styles) {\n private readonly popupId = `mid-dropdown-${nextUniqueId++}`;\n private closeWatcher?: CloseWatcher | null;\n\n @query('.popup')\n popup!: MinidPopup;\n\n @query('.trigger')\n trigger!: HTMLSlotElement;\n\n @query('.panel')\n panel!: HTMLSlotElement;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * By default, the dropdown is closed when an item is selected. This attribute will keep it open instead. Useful for\n * dropdowns that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'bottom-end';\n\n /**\n * Sync the dropdown panel size with the trigger element\n */\n @property({ reflect: true })\n sync?: 'width' | 'height' | 'both';\n\n /**\n * Distance between trigger and dropdown panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the dropdown panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n @property({ type: Boolean })\n arrow = false;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n /**\n * The dropdown will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a dropdown internally.\n */\n @property({ attribute: false })\n containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n this.panel.hidden = !this.open;\n\n // If the dropdown is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open dropdown. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the dropdown and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the dropdown is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: MidSelectEvent) => {\n const target = event.target as HTMLElement;\n\n // Hide the dropdown when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n this.handleTriggerClick();\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the dropdown to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n firstMenuItem.focus();\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n lastMenuItem.focus();\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n if (accessibleTrigger) {\n if (accessibleTrigger.tagName.toLowerCase() === 'mid-button') {\n target = (accessibleTrigger as MinidButton).button;\n } else {\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the dropdown panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the dropdown panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the dropdown menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n this.panel.addEventListener('mid-select', this.handlePanelSelect);\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n } else {\n this.panel.addEventListener('keydown', this.handleKeyDown);\n }\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n if (this.panel) {\n this.panel.removeEventListener('mid-select', this.handlePanelSelect);\n this.panel.removeEventListener('keydown', this.handleKeyDown);\n }\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'dropdown.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'dropdown.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"${this.popupId}\"\n class=\"${classMap({\n 'text-body-sm': this.size === 'sm',\n 'text-body-md': this.size === 'md',\n 'text-body-lg': this.size === 'lg',\n })} popup [--arrow-border-color:var(--border-color-neutral-subtle)] [--arrow-size:8px]\"\n distance=${this.distance}\n placement=\"${this.placement}\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=${ifDefined(this.sync)}\n ?arrow=${this.arrow}\n >\n <slot\n class=\"trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n >\n </slot>\n <div\n class=\"bg-accent min-w-68\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"${this.popupId}\"\n >\n <slot part=\"panel\" class=\"panel\"></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('dropdown.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('dropdown.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dropdown.js","sources":["../../src/components/dropdown.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport './popup.component';\nimport {\n getAnimation,\n setDefaultAnimation,\n} from '../utilities/animation-registry.ts';\nimport { waitForEvent } from '../internal/event.ts';\nimport { MinidPopup } from './popup.component';\nimport { watch } from '../internal/watch.ts';\nimport { animateTo, stopAnimations } from '../internal/animate.ts';\nimport { getTabbableBoundary } from '../internal/tabbable.ts';\nimport { MinidButton } from '../components/button.component.ts';\nimport type { MidSelectEvent } from '../events/mid-select.ts';\nimport { MinidMenu } from '../components/menu.component.ts';\nimport { MinidMenuItem } from '../components/menu-item.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-dropdown': MinidDropdown;\n }\n}\n\nlet nextUniqueId = 0;\n\nconst styles = [\n css`\n :host {\n display: inline-flex;\n }\n `,\n];\n\n/**\n * @slot -- Default slot for content of the dropdown panel\n * @slot trigger - Used for the button element that will be used to open the dropdown menu\n * @part panel - Select the dropdown panel host element\n */\n@customElement('mid-dropdown')\nexport class MinidDropdown extends styled(LitElement, styles) {\n private readonly popupId = `mid-dropdown-${nextUniqueId++}`;\n private closeWatcher?: CloseWatcher | null;\n\n @query('.popup')\n popup!: MinidPopup;\n\n @query('.trigger')\n trigger!: HTMLSlotElement;\n\n @query('.panel')\n panel!: HTMLSlotElement;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * By default, the dropdown is closed when an item is selected. This attribute will keep it open instead. Useful for\n * dropdowns that allow for multiple interactions.\n */\n @property({ type: Boolean, reflect: true })\n stayopenonselect = false;\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ reflect: true })\n placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'bottom-end';\n\n /**\n * Sync the dropdown panel size with the trigger element\n */\n @property({ reflect: true })\n sync?: 'width' | 'height' | 'both';\n\n /**\n * Distance between trigger and dropdown panel\n */\n @property({ type: Number })\n distance = 4;\n\n /**\n * Nudge the dropdown panel position. Accepts a negative or positive number.\n */\n @property({ type: Number })\n skidding = 0;\n\n @property({ type: Boolean })\n arrow = false;\n\n /**\n * Choose if position is `fixed` or `absolute`. `absolute` is more performant,\n * but `fixed` can solve issues with overflow clipping\n */\n @property({ type: Boolean })\n hoist = false;\n\n /**\n * The dropdown will close when the user interacts outside of this element (e.g. clicking). Useful for composing other\n * components that use a dropdown internally.\n */\n @property({ attribute: false })\n containingElement?: HTMLElement;\n\n connectedCallback() {\n super.connectedCallback();\n\n if (!this.containingElement) {\n this.containingElement = this;\n }\n }\n\n firstUpdated() {\n this.panel.hidden = !this.open;\n\n // If the dropdown is visible on init, update its position\n if (this.open) {\n this.addOpenListeners();\n this.popup.active = true;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeOpenListeners();\n this.hide();\n }\n\n focusOnTrigger() {\n const trigger = this.trigger.assignedElements({ flatten: true })[0] as\n | HTMLElement\n | undefined;\n if (typeof trigger?.focus === 'function') {\n trigger.focus();\n }\n }\n\n getMenu() {\n return this.panel\n .assignedElements({ flatten: true })\n .find((el) => el.tagName.toLowerCase() === 'mid-menu') as\n | MinidMenu\n | undefined;\n }\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Close when escape is pressed inside an open dropdown. We need to listen on the panel itself and stop propagation\n // in case any ancestors are also listening for this key.\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n // Close when escape or tab is pressed\n if (event.key === 'Escape' && this.open && !this.closeWatcher) {\n event.stopPropagation();\n this.focusOnTrigger();\n this.hide();\n return;\n }\n\n // Handle tabbing\n if (event.key === 'Tab') {\n const composedPath = event.composedPath();\n const tabbedIsMenuItem = composedPath.some(\n (e): e is MinidMenuItem =>\n (e as HTMLElement).tagName?.toLowerCase() === 'mid-menu-item'\n );\n\n // Tabbing within an open menu should close the dropdown and refocus the trigger\n if (this.open && tabbedIsMenuItem) {\n event.preventDefault();\n this.hide();\n this.focusOnTrigger();\n return;\n }\n\n // Tabbing outside of the containing element closes the panel\n //\n // If the dropdown is used within a shadow DOM, we need to obtain the activeElement within that shadowRoot,\n // otherwise `document.activeElement` will only return the name of the parent shadow DOM element.\n setTimeout(() => {\n if (composedPath.every((target) => target !== this.containingElement)) {\n this.hide();\n }\n });\n }\n };\n\n private handleDocumentMouseDown = (event: MouseEvent) => {\n // Close when clicking outside of the containing element\n const path = event.composedPath();\n\n if (this.containingElement && !path.includes(this.containingElement)) {\n this.hide();\n }\n };\n\n private handlePanelSelect = (event: MidSelectEvent) => {\n const target = event.target as HTMLElement;\n\n // Hide the dropdown when a menu item is selected\n if (!this.stayopenonselect && target.tagName.toLowerCase() === 'mid-menu') {\n this.hide();\n this.focusOnTrigger();\n }\n };\n\n handleTriggerClick() {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n this.focusOnTrigger();\n }\n }\n\n async handleTriggerKeyDown(event: KeyboardEvent) {\n // When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same\n // key again to hide the menu in case they don't want to make a selection.\n if ([' ', 'Enter'].includes(event.key)) {\n event.preventDefault();\n this.handleTriggerClick();\n return;\n }\n\n const menu = this.getMenu();\n\n if (menu) {\n const menuItems = menu.getAllSelectableItems();\n const firstMenuItem = menuItems[0];\n const lastMenuItem = menuItems[menuItems.length - 1];\n\n // When up/down is pressed, we make the assumption that the user is familiar with the menu and plans to make a\n // selection. Rather than toggle the panel, we focus on the menu (if one exists) and activate the first item for\n // faster navigation.\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n\n // Show the menu if it's not already open\n if (!this.open) {\n this.show();\n\n // Wait for the dropdown to open before focusing, but not the animation\n await this.updateComplete;\n }\n\n if (menuItems.length > 0) {\n // Focus on the first/last menu item after showing\n this.updateComplete.then(() => {\n if (event.key === 'ArrowDown' || event.key === 'Home') {\n menu.setCurrentItem(firstMenuItem);\n firstMenuItem.focus();\n }\n\n if (event.key === 'ArrowUp' || event.key === 'End') {\n menu.setCurrentItem(lastMenuItem);\n lastMenuItem.focus();\n }\n });\n }\n }\n }\n }\n\n handleTriggerKeyUp(event: KeyboardEvent) {\n // Prevent space from triggering a click event in Firefox\n if (event.key === ' ') {\n event.preventDefault();\n }\n }\n\n handleTriggerSlotChange() {\n this.updateAccessibleTrigger();\n }\n\n updateAccessibleTrigger() {\n const assignedElements = this.trigger.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n const accessibleTrigger = assignedElements.find(\n (el) => getTabbableBoundary(el).start\n );\n let target: HTMLElement;\n if (accessibleTrigger) {\n if (accessibleTrigger.tagName.toLowerCase() === 'mid-button') {\n target = (accessibleTrigger as MinidButton).button;\n } else {\n target = accessibleTrigger;\n }\n\n target.setAttribute('aria-haspopup', 'true');\n target.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n }\n\n /**\n * Shows the dropdown panel.\n */\n async show() {\n if (this.open) {\n return undefined;\n }\n\n this.open = true;\n return waitForEvent(this, 'mid-after-show');\n }\n\n /**\n * Hides the dropdown panel\n */\n async hide() {\n if (!this.open) {\n return undefined;\n }\n\n this.open = false;\n return waitForEvent(this, 'mid-after-hide');\n }\n\n /**\n * Instructs the dropdown menu to reposition. Useful when the position or size of the trigger changes when the menu\n * is activated.\n */\n reposition() {\n this.popup.reposition();\n }\n\n addOpenListeners() {\n this.panel.addEventListener('mid-select', this.handlePanelSelect);\n if ('CloseWatcher' in window) {\n this.closeWatcher?.destroy();\n this.closeWatcher = new CloseWatcher();\n this.closeWatcher.onclose = () => {\n this.hide();\n this.focusOnTrigger();\n };\n } else {\n this.panel.addEventListener('keydown', this.handleKeyDown);\n }\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n }\n\n removeOpenListeners() {\n if (this.panel) {\n this.panel.removeEventListener('mid-select', this.handlePanelSelect);\n this.panel.removeEventListener('keydown', this.handleKeyDown);\n }\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n this.closeWatcher?.destroy();\n }\n\n @watch('open', { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.disabled) {\n this.open = false;\n return;\n }\n\n this.updateAccessibleTrigger();\n\n if (this.open) {\n // Show\n this.dispatchEvent(\n new Event('mid-show', { bubbles: true, composed: true })\n );\n this.addOpenListeners();\n\n await stopAnimations(this);\n this.panel.hidden = false;\n this.popup.active = true;\n const { keyframes, options } = getAnimation(this, 'dropdown.show');\n await animateTo(this.popup.popup, keyframes, options);\n\n this.dispatchEvent(\n new Event('mid-after-show', { bubbles: true, composed: true })\n );\n } else {\n // Hide\n this.dispatchEvent(\n new Event('mid-hide', { bubbles: true, composed: true })\n );\n this.removeOpenListeners();\n\n await stopAnimations(this);\n const { keyframes, options } = getAnimation(this, 'dropdown.hide');\n await animateTo(this.popup.popup, keyframes, options);\n this.panel.hidden = true;\n this.popup.active = false;\n\n this.dispatchEvent(\n new Event('mid-after-hide', { bubbles: true, composed: true })\n );\n }\n }\n\n override render() {\n return html`\n <mid-popup\n id=\"${this.popupId}\"\n class=\"${classMap({\n 'text-body-sm': this.size === 'sm',\n 'text-body-md': this.size === 'md',\n 'text-body-lg': this.size === 'lg',\n })} popup [--arrow-border-color:var(--border-color-neutral-subtle)] [--arrow-size:8px]\"\n distance=${this.distance}\n placement=\"${this.placement}\"\n skidding=${this.skidding}\n strategy=${this.hoist ? 'fixed' : 'absolute'}\n flip\n shift\n auto-size=\"vertical\"\n auto-size-padding=\"10\"\n sync=${ifDefined(this.sync)}\n ?arrow=${this.arrow}\n >\n <slot\n class=\"trigger\"\n slot=\"anchor\"\n name=\"trigger\"\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeyDown}\n @keyup=${this.handleTriggerKeyUp}\n @slotchange=${this.handleTriggerSlotChange}\n >\n </slot>\n <div\n class=\"bg-accent\"\n aria-hidden=${this.open ? 'false' : 'true'}\n aria-labelledby=\"${this.popupId}\"\n >\n <slot part=\"panel\" class=\"panel\"></slot>\n </div>\n </mid-popup>\n `;\n }\n}\n\nsetDefaultAnimation('dropdown.show', {\n keyframes: [\n { opacity: 0, scale: 0.9 },\n { opacity: 1, scale: 1 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n\nsetDefaultAnimation('dropdown.hide', {\n keyframes: [\n { opacity: 1, scale: 1 },\n { opacity: 0, scale: 0.9 },\n ],\n options: { duration: 100, easing: 'ease' },\n});\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"menu.component.d.ts","sourceRoot":"","sources":["../../src/components/menu.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,SAAS,CAAC;KACvB;CACF;;AAWD;;GAEG;AACH,qBACa,SAAU,SAAQ,cAA0B;IAEvD,WAAW,EAAG,eAAe,CAAC;IAG9B,WAAW,EAAG,gBAAgB,CAAC;IAG/B,QAAQ,EAAG,gBAAgB,CAAC;IAE5B;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IAEH,OAAO,EAAE,UAAU,GAAG,UAAU,CAAc;IAG9C,eAAe,UAAS;IAExB,SAAS,CAAC,YAAY,IAAI,IAAI;IAS9B,iBAAiB;IAKjB,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IASlB;;;OAGG;IACH,MAAM,GAAI,UAAU,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,UAUlD;IAEF,WAAW;IAMX;;OAEG;IACH,qBAAqB;IAQrB,WAAW;IAQX;;;OAGG;IACH,cAAc;IAMd;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,aAAa;IAUlC,gBAAgB;IAMP,MAAM;CAwChB"}
1
+ {"version":3,"file":"menu.component.d.ts","sourceRoot":"","sources":["../../src/components/menu.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAGrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,SAAS,CAAC;KACvB;CACF;;AAWD;;GAEG;AACH,qBACa,SAAU,SAAQ,cAA0B;IAEvD,WAAW,EAAG,eAAe,CAAC;IAG9B,WAAW,EAAG,gBAAgB,CAAC;IAG/B,QAAQ,EAAG,gBAAgB,CAAC;IAE5B;;OAEG;IAEH,UAAU,UAAS;IAEnB;;OAEG;IAEH,OAAO,EAAE,UAAU,GAAG,UAAU,CAAc;IAG9C,eAAe,UAAS;IAExB,SAAS,CAAC,YAAY,IAAI,IAAI;IAS9B,iBAAiB;IAKjB,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,aAAa;IAgDrB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IASlB;;;OAGG;IACH,MAAM,GAAI,UAAU,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,UAUlD;IAEF,WAAW;IAMX;;OAEG;IACH,qBAAqB;IAQrB,WAAW;IAQX;;;OAGG;IACH,cAAc;IAMd;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,aAAa;IAUlC,gBAAgB;IAMP,MAAM;CAsChB"}
@@ -186,9 +186,7 @@ let MinidMenu = class extends styled(LitElement, styles) {
186
186
  }
187
187
  render() {
188
188
  return html`
189
- <div
190
- class="text-neutral border-neutral-subtle rounded-md border shadow-md"
191
- >
189
+ <div class="border-neutral-subtle rounded-md border shadow-md">
192
190
  ${!this.searchable ? nothing : html`<div
193
191
  class="border-neutral-subtle flex items-center gap-2 border-b p-2"
194
192
  >
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sources":["../../src/components/menu.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidMenuItem } from './menu-item.component';\nimport { scrollIntoView } from '../internal/scroll';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-menu': MinidMenu;\n }\n}\n\nconst styles = [\n css`\n :host {\n --max-height: none;\n --max-width: none;\n }\n `,\n];\n\n/**\n * @event {{ detail: { item: MidMenuItem } }} mid-select - Emitted when a menu item is selected.\n */\n@customElement('mid-menu')\nexport class MinidMenu extends styled(LitElement, styles) {\n @query('slot')\n defaultSlot!: HTMLSlotElement;\n\n @query('.filter-input')\n filterInput!: HTMLInputElement;\n\n @query('.item-list')\n itemList!: HTMLUListElement;\n\n /**\n * Adds an input element that filters selectable menu items\n */\n @property({ type: Boolean })\n searchable = false;\n\n /**\n * Wether the menu should be styled as a dropdown or a combobox\n */\n @property()\n variant: 'combobox' | 'dropdown' = 'dropdown';\n\n @state()\n isEmptyItemList = false;\n\n protected firstUpdated(): void {\n this.getAllItems().forEach((item) => {\n item.variant = this.variant;\n item.addEventListener('mouseenter', () => {\n this.setCurrentItem(item);\n });\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'menu');\n }\n\n private handleClick(event: MouseEvent) {\n const menuItemTypes = ['menuitem', 'menuitemcheckbox'];\n\n const composedPath = event.composedPath();\n const target = composedPath.find((el) =>\n menuItemTypes.includes((el as HTMLElement)?.getAttribute?.('role') || '')\n );\n\n if (!target) return;\n\n const closestMenu = composedPath.find(\n (el) => (el as HTMLElement)?.getAttribute?.('role') === 'menu'\n );\n const clickHasSubmenu = closestMenu !== this;\n\n // Make sure we're the menu thats supposed to be handling the click event.\n if (clickHasSubmenu) {\n return;\n }\n\n // This isn't true. But we use it for TypeScript checks below.\n const item = target as MinidMenuItem;\n\n // if (item.type === 'checkbox') {\n // item.checked = !item.checked;\n // }\n\n this.dispatchEvent(\n new CustomEvent('mid-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n })\n );\n }\n\n private handleFilterItems() {\n this.filter((item) =>\n item.innerText\n .toLowerCase()\n .includes(this.filterInput.value.toLowerCase())\n );\n\n const items = this.getAllSelectableItems();\n this.isEmptyItemList = items.length === 0;\n this.setCurrentItem(items[0]);\n }\n\n private scrollOptionIntoView(item: MinidMenuItem): void {\n scrollIntoView(item, this.itemList, 'vertical', 'auto');\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n // Make a selection when pressing enter or space\n if (event.key === 'Enter' || event.key === ' ') {\n const item = this.getCurrentItem();\n event.preventDefault();\n event.stopPropagation();\n\n // Simulate a click to support @click handlers on menu items that also work with the keyboard\n item?.click();\n }\n\n // Move the selection when pressing down or up\n else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n const items = this.getAllSelectableItems();\n const activeItem = this.getCurrentItem();\n let index = activeItem ? items.indexOf(activeItem) : 0;\n\n if (items.length > 0) {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'ArrowDown') {\n index++;\n } else if (event.key === 'ArrowUp') {\n index--;\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = items.length - 1;\n }\n\n if (index < 0) {\n index = items.length - 1;\n }\n if (index > items.length - 1) {\n index = 0;\n }\n\n this.setCurrentItem(items[index]);\n this.scrollOptionIntoView(items[index]);\n\n if (!this.searchable) {\n items[index].focus();\n }\n }\n }\n }\n\n private handleMouseDown(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (this.isMenuItem(target)) {\n this.setCurrentItem(target as MinidMenuItem);\n }\n }\n\n private handleSlotChange() {\n const items = this.getAllSelectableItems();\n\n // Reset the roving tab index when the slotted items change\n if (items.length > 0) {\n this.setCurrentItem(items[0]);\n }\n }\n\n private isMenuItem(item: HTMLElement) {\n return (\n item.tagName.toLowerCase() === 'mid-menu-item' ||\n ['menuitem', 'menuitemcheckbox', 'menuitemradio'].includes(\n item.getAttribute('role') ?? ''\n )\n );\n }\n\n /**\n * Pass a filter function to enable/disable menu items in the menu\n * @type {(item: MinidMenuItem) => boolean}\n */\n filter = (filterFn: (item: MinidMenuItem) => boolean) => {\n this.getAllItems().forEach((item) => {\n if (filterFn(item)) {\n item.removeAttribute('hidden');\n item.removeAttribute('inert');\n } else {\n item.setAttribute('inert', 'true');\n item.setAttribute('hidden', 'true');\n }\n });\n };\n\n clearFilter() {\n this.filterInput.value = '';\n this.itemList.scrollTop = 0;\n this.filterInput.dispatchEvent(new Event('input'));\n }\n\n /**\n * @internal Gets all slotted menu items, ignoring dividers, headers, and other elements.\n */\n getAllSelectableItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => !(el.inert || !this.isMenuItem(el)));\n }\n\n getAllItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => this.isMenuItem(el));\n }\n\n /**\n * @internal Gets the current menu item, which is the menu item that has `tabindex=\"0\"` within the roving tab index.\n * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the \"active\" item.\n */\n getCurrentItem() {\n return this.getAllSelectableItems().find(\n (i) => i.getAttribute('tabindex') === '0'\n );\n }\n\n /**\n * @internal Sets the current menu item to the specified element. This sets `tabindex=\"0\"` on the target element and\n * `tabindex=\"-1\"` to all other items. This method must be called prior to setting focus on a menu item.\n */\n setCurrentItem(item: MinidMenuItem) {\n const items = this.getAllSelectableItems();\n\n // Update tab indexes\n items.forEach((i) => {\n i.setActive(i === item);\n i.setAttribute('tabindex', i === item ? '0' : '-1');\n });\n }\n\n focusSearchField() {\n if (this.searchable) {\n this.filterInput.focus();\n }\n }\n\n override render() {\n return html`\n <div\n class=\"text-neutral border-neutral-subtle rounded-md border shadow-md\"\n >\n ${!this.searchable\n ? nothing\n : html`<div\n class=\"border-neutral-subtle flex items-center gap-2 border-b p-2\"\n >\n <mid-icon\n class=\"text-6\"\n slot=\"prefix\"\n library=\"system\"\n name=\"magnifying-glass\"\n >\n </mid-icon>\n <input\n @input=${this.handleFilterItems}\n @keydown=${this.handleKeyDown}\n class=\"filter-input border-neutral-subtle focus-visible:outline-focus-outer h-8 w-full rounded border px-2\"\n type=\"search\"\n />\n </div>`}\n <ul\n class=\"item-list max-h-(--max-height) max-w-(--max-width) overflow-y-auto px-2 py-3\"\n >\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n @mousedown=${this.handleMouseDown}\n ></slot>\n ${this.isEmptyItemList\n ? html`<div class=\"p-2\">Fant ingen treff</div>`\n : nothing}\n </ul>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"menu.js","sources":["../../src/components/menu.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { MinidMenuItem } from './menu-item.component';\nimport { scrollIntoView } from '../internal/scroll';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-menu': MinidMenu;\n }\n}\n\nconst styles = [\n css`\n :host {\n --max-height: none;\n --max-width: none;\n }\n `,\n];\n\n/**\n * @event {{ detail: { item: MidMenuItem } }} mid-select - Emitted when a menu item is selected.\n */\n@customElement('mid-menu')\nexport class MinidMenu extends styled(LitElement, styles) {\n @query('slot')\n defaultSlot!: HTMLSlotElement;\n\n @query('.filter-input')\n filterInput!: HTMLInputElement;\n\n @query('.item-list')\n itemList!: HTMLUListElement;\n\n /**\n * Adds an input element that filters selectable menu items\n */\n @property({ type: Boolean })\n searchable = false;\n\n /**\n * Wether the menu should be styled as a dropdown or a combobox\n */\n @property()\n variant: 'combobox' | 'dropdown' = 'dropdown';\n\n @state()\n isEmptyItemList = false;\n\n protected firstUpdated(): void {\n this.getAllItems().forEach((item) => {\n item.variant = this.variant;\n item.addEventListener('mouseenter', () => {\n this.setCurrentItem(item);\n });\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'menu');\n }\n\n private handleClick(event: MouseEvent) {\n const menuItemTypes = ['menuitem', 'menuitemcheckbox'];\n\n const composedPath = event.composedPath();\n const target = composedPath.find((el) =>\n menuItemTypes.includes((el as HTMLElement)?.getAttribute?.('role') || '')\n );\n\n if (!target) return;\n\n const closestMenu = composedPath.find(\n (el) => (el as HTMLElement)?.getAttribute?.('role') === 'menu'\n );\n const clickHasSubmenu = closestMenu !== this;\n\n // Make sure we're the menu thats supposed to be handling the click event.\n if (clickHasSubmenu) {\n return;\n }\n\n // This isn't true. But we use it for TypeScript checks below.\n const item = target as MinidMenuItem;\n\n // if (item.type === 'checkbox') {\n // item.checked = !item.checked;\n // }\n\n this.dispatchEvent(\n new CustomEvent('mid-select', {\n bubbles: true,\n composed: true,\n detail: { item },\n })\n );\n }\n\n private handleFilterItems() {\n this.filter((item) =>\n item.innerText\n .toLowerCase()\n .includes(this.filterInput.value.toLowerCase())\n );\n\n const items = this.getAllSelectableItems();\n this.isEmptyItemList = items.length === 0;\n this.setCurrentItem(items[0]);\n }\n\n private scrollOptionIntoView(item: MinidMenuItem): void {\n scrollIntoView(item, this.itemList, 'vertical', 'auto');\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n // Make a selection when pressing enter or space\n if (event.key === 'Enter' || event.key === ' ') {\n const item = this.getCurrentItem();\n event.preventDefault();\n event.stopPropagation();\n\n // Simulate a click to support @click handlers on menu items that also work with the keyboard\n item?.click();\n }\n\n // Move the selection when pressing down or up\n else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n const items = this.getAllSelectableItems();\n const activeItem = this.getCurrentItem();\n let index = activeItem ? items.indexOf(activeItem) : 0;\n\n if (items.length > 0) {\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'ArrowDown') {\n index++;\n } else if (event.key === 'ArrowUp') {\n index--;\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = items.length - 1;\n }\n\n if (index < 0) {\n index = items.length - 1;\n }\n if (index > items.length - 1) {\n index = 0;\n }\n\n this.setCurrentItem(items[index]);\n this.scrollOptionIntoView(items[index]);\n\n if (!this.searchable) {\n items[index].focus();\n }\n }\n }\n }\n\n private handleMouseDown(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n if (this.isMenuItem(target)) {\n this.setCurrentItem(target as MinidMenuItem);\n }\n }\n\n private handleSlotChange() {\n const items = this.getAllSelectableItems();\n\n // Reset the roving tab index when the slotted items change\n if (items.length > 0) {\n this.setCurrentItem(items[0]);\n }\n }\n\n private isMenuItem(item: HTMLElement) {\n return (\n item.tagName.toLowerCase() === 'mid-menu-item' ||\n ['menuitem', 'menuitemcheckbox', 'menuitemradio'].includes(\n item.getAttribute('role') ?? ''\n )\n );\n }\n\n /**\n * Pass a filter function to enable/disable menu items in the menu\n * @type {(item: MinidMenuItem) => boolean}\n */\n filter = (filterFn: (item: MinidMenuItem) => boolean) => {\n this.getAllItems().forEach((item) => {\n if (filterFn(item)) {\n item.removeAttribute('hidden');\n item.removeAttribute('inert');\n } else {\n item.setAttribute('inert', 'true');\n item.setAttribute('hidden', 'true');\n }\n });\n };\n\n clearFilter() {\n this.filterInput.value = '';\n this.itemList.scrollTop = 0;\n this.filterInput.dispatchEvent(new Event('input'));\n }\n\n /**\n * @internal Gets all slotted menu items, ignoring dividers, headers, and other elements.\n */\n getAllSelectableItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => !(el.inert || !this.isMenuItem(el)));\n }\n\n getAllItems() {\n return [\n ...(this.defaultSlot.assignedElements({\n flatten: true,\n }) as MinidMenuItem[]),\n ].filter((el) => this.isMenuItem(el));\n }\n\n /**\n * @internal Gets the current menu item, which is the menu item that has `tabindex=\"0\"` within the roving tab index.\n * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the \"active\" item.\n */\n getCurrentItem() {\n return this.getAllSelectableItems().find(\n (i) => i.getAttribute('tabindex') === '0'\n );\n }\n\n /**\n * @internal Sets the current menu item to the specified element. This sets `tabindex=\"0\"` on the target element and\n * `tabindex=\"-1\"` to all other items. This method must be called prior to setting focus on a menu item.\n */\n setCurrentItem(item: MinidMenuItem) {\n const items = this.getAllSelectableItems();\n\n // Update tab indexes\n items.forEach((i) => {\n i.setActive(i === item);\n i.setAttribute('tabindex', i === item ? '0' : '-1');\n });\n }\n\n focusSearchField() {\n if (this.searchable) {\n this.filterInput.focus();\n }\n }\n\n override render() {\n return html`\n <div class=\"border-neutral-subtle rounded-md border shadow-md\">\n ${!this.searchable\n ? nothing\n : html`<div\n class=\"border-neutral-subtle flex items-center gap-2 border-b p-2\"\n >\n <mid-icon\n class=\"text-6\"\n slot=\"prefix\"\n library=\"system\"\n name=\"magnifying-glass\"\n >\n </mid-icon>\n <input\n @input=${this.handleFilterItems}\n @keydown=${this.handleKeyDown}\n class=\"filter-input border-neutral-subtle focus-visible:outline-focus-outer h-8 w-full rounded border px-2\"\n type=\"search\"\n />\n </div>`}\n <ul\n class=\"item-list max-h-(--max-height) max-w-(--max-width) overflow-y-auto px-2 py-3\"\n >\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n @mousedown=${this.handleMouseDown}\n ></slot>\n ${this.isEmptyItemList\n ? html`<div class=\"p-2\">Fant ingen treff</div>`\n : nothing}\n </ul>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -96,7 +96,6 @@ export declare class MinidTextfield extends MinidTextfield_base {
96
96
  hidelabel: boolean;
97
97
  hasFocus: boolean;
98
98
  static get formControlValidators(): import('../types/validator.type.ts').Validator[];
99
- get validationTarget(): HTMLInputElement;
100
99
  constructor();
101
100
  connectedCallback(): void;
102
101
  private handleKeydown;
@@ -1 +1 @@
1
- {"version":3,"file":"textfield.component.d.ts","sourceRoot":"","sources":["../../src/components/textfield.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAgBrD,OAAO,0BAA0B,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,cAAc,CAAC;KACjC;CACF;;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,cAAe,SAAQ,mBAEnC;IACC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,YAAY,CAAM;IAG1B,KAAK,EAAG,gBAAgB,CAAC;IAGzB,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,KAAK,SAAM;IAGX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,YAAY,CAAC,EAAE,QAAQ,CAAC;IAExB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,cAAc,SAAM;IAGpB,IAAI,EACA,MAAM,GACN,gBAAgB,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,MAAM,CAAU;IAEpB;;SAEK;IAEL,SAAS,UAAS;IAElB;;;OAGG;IAEH,cAAc,UAAS;IAEvB;;;OAGG;IAEH,eAAe,UAAS;IAGxB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAGlB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAO/B;IAED,IAAI,gBAAgB,qBAEnB;;IAUQ,iBAAiB,IAAI,IAAI;IAKlC,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,gBAAgB;IAmBxB,KAAK;IAKL,gBAAgB;IAKhB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAKlC,iBAAiB;IAIR,MAAM;CA+JhB"}
1
+ {"version":3,"file":"textfield.component.d.ts","sourceRoot":"","sources":["../../src/components/textfield.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAW,MAAM,KAAK,CAAC;AAgBrD,OAAO,0BAA0B,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,cAAc,CAAC;KACjC;CACF;;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,cAAe,SAAQ,mBAEnC;IACC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IACzE,OAAO,CAAC,YAAY,CAAM;IAG1B,KAAK,EAAG,gBAAgB,CAAC;IAGzB,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,KAAK,SAAM;IAGX,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAQ;IAGhC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IAEH,SAAS,UAAS;IAElB;;OAEG;IAEH,YAAY,CAAC,EAAE,QAAQ,CAAC;IAExB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB;;OAEG;IAEH,cAAc,SAAM;IAGpB,IAAI,EACA,MAAM,GACN,gBAAgB,GAChB,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,MAAM,CAAU;IAEpB;;SAEK;IAEL,SAAS,UAAS;IAElB;;;OAGG;IAEH,cAAc,UAAS;IAEvB;;;OAGG;IAEH,eAAe,UAAS;IAGxB,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB;;OAEG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IAEH,QAAQ,UAAS;IAEjB;;OAEG;IAEH,SAAS,UAAS;IAGlB,QAAQ,UAAS;IAEjB,MAAM,KAAK,qBAAqB,qDAO/B;;IAUQ,iBAAiB,IAAI,IAAI;IAKlC,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,gBAAgB;IAmBxB,KAAK;IAKL,gBAAgB;IAKhB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAKlC,iBAAiB;IAIR,MAAM;CA+JhB"}
@@ -63,9 +63,6 @@ let MinidTextfield = class extends FormControlMixin(
63
63
  patternValidator
64
64
  ];
65
65
  }
66
- get validationTarget() {
67
- return this.input;
68
- }
69
66
  connectedCallback() {
70
67
  super.connectedCallback();
71
68
  this.initialValue = this.value;
@@ -1 +1 @@
1
- {"version":3,"file":"textfield.js","sources":["../../src/components/textfield.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { stringConverter } from '../internal/string-converter';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HasSlotController } from '../internal/slot';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n} from '../mixins/validators';\nimport { watch } from '../internal/watch';\nimport './icon/icon.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-textfield': MinidTextfield;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n `,\n];\n\nlet nextUniqueId = 0;\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-clear - Emitted when the input value is cleared\n * @event mid-focus - Emitted when input element is focused\n * @event mid-blur - Emitted when focus moves away from input element\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot prefix - Used for decoration to the left of the input\n * @slot suffix - Used for decoration to the right of the input\n * @slot label - The input's label. Alternatively, you can use the `label` attribute.\n *\n * @csspart base - The input's wrapper that has the input field styling.\n * @csspart input - The internal `<input>` element.\n * @csspart field - The element that wraps the label, input, and help text.\n * @csspart clear-button - The clear button\n * @csspart password-toggle-button - The button for toggling password visibility\n */\n@customElement('mid-textfield')\nexport class MinidTextfield extends FormControlMixin(\n styled(LitElement, styles)\n) {\n private readonly inputId!: string;\n private readonly descriptionId!: string;\n private readonly validationId!: string;\n private readonly hasSlotControler = new HasSlotController(this, 'label');\n private initialValue = '';\n\n @query('.input')\n input!: HTMLInputElement;\n\n @property()\n label = '';\n\n @property()\n description = '';\n\n @property()\n value = '';\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ converter: stringConverter })\n placeholder?: string;\n\n /**\n * Autofocus the input field on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * User agent autocomplete hint\n */\n @property()\n autocomplete?: AutoFill;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * The maximum length of input that will be considered valid.\n */\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * The input's minimum value. Only applies to date and number input types.\n */\n @property()\n min?: number | string;\n\n /**\n * The input's maximum value. Only applies to date and number input types.\n */\n @property()\n max?: number | string;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n @property()\n type:\n | 'date'\n | 'datetime-local'\n | 'email'\n | 'file'\n | 'month'\n | 'number'\n | 'password'\n | 'search'\n | 'tel'\n | 'text'\n | 'time'\n | 'url'\n | 'week' = 'text';\n\n /**\n * Adds a clear button when the input is not empty.\n * */\n @property({ type: Boolean })\n clearable = false;\n\n /**\n * Adds a button to toggle the password's visibility.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordtoggle = false;\n\n /**\n * Determines wether the password is currently visible.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordvisible = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * Visually hides `label` and `description` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n @state()\n hasFocus = false;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n ];\n }\n\n get validationTarget() {\n return this.input;\n }\n\n constructor() {\n super();\n nextUniqueId++;\n this.inputId = `mid-textfield-input-${nextUniqueId}`;\n this.descriptionId = `mid-textfield-description-${nextUniqueId}`;\n this.validationId = `mid-textfield-validation-${nextUniqueId}`;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.initialValue = this.value;\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n //\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new Event('mid-blur', { bubbles: true, composed: true })\n );\n }\n\n private handleChange() {\n this.value = this.input.value;\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n }\n\n private handleInput() {\n this.value = this.input.value;\n this.setValue(this.value);\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new Event('mid-focus', { composed: true, bubbles: true })\n );\n }\n\n private handlePasswordToggle() {\n this.passwordvisible = !this.passwordvisible;\n }\n\n private handleClearClick(event: MouseEvent) {\n event.preventDefault();\n\n if (this.value !== '') {\n this.value = '';\n this.dispatchEvent(\n new Event('mid-clear', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-change', { composed: true, bubbles: true })\n );\n }\n\n this.input.focus();\n }\n\n focus() {\n this.hasFocus = true;\n this.input.focus();\n }\n\n resetFormControl() {\n this.invalidmessage = '';\n this.value = this.initialValue;\n }\n\n forceError(message?: string): void {\n super.forceError(message);\n }\n\n @watch('value')\n handleValueUpdate() {\n this.setValue(this.value);\n }\n\n override render() {\n const lg = this.size === 'lg';\n const md = this.size === 'md';\n const sm = this.size === 'sm';\n\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const hasClearIcon = this.clearable && !this.disabled && !this.readonly;\n const isClearIconVisible =\n hasClearIcon && (typeof this.value === 'number' || this.value.length > 0);\n\n return html`\n <div\n part=\"field\"\n class=\"${classMap({\n 'opacity-disabled': this.disabled,\n 'text-body-sm': sm,\n 'text-body-md': md,\n 'text-body-lg': lg,\n })} max-w-full\"\n >\n <label\n for=\"${this.inputId}\"\n class=\"${classMap({\n 'sr-only': this.hidelabel || !hasLabel,\n })} mb-2 inline-flex items-center gap-1 font-medium\"\n >\n ${this.readonly\n ? html`<mid-icon\n class=\"size-5\"\n library=\"system\"\n name=\"padlock-locked-fill\"\n ></mid-icon>`\n : nothing}\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n ${this.description\n ? html`\n <div\n id=\"${this.descriptionId}\"\n part=\"description\"\n class=\"${classMap({\n 'sr-only': this.hidelabel,\n })} text-neutral-subtle mb-2\"\n >\n ${this.description}\n </div>\n `\n : nothing}\n <div\n part=\"base\"\n class=\"${classMap({\n 'border-neutral': !this.invalidmessage && !this.readonly,\n 'border-danger': this.invalidmessage && !this.readonly,\n 'border-neutral-subtle': this.readonly,\n 'bg-neutral-surface-tinted': this.readonly,\n 'bg-neutral-surface': !this.readonly,\n border: !this.invalidmessage,\n 'border-2': this.invalidmessage,\n })} focus-within:focus-ring flex h-12 items-center rounded-md px-3\"\n >\n <span class=\"slotted:!mr-2 slotted:rounded flex items-center\">\n <slot name=\"prefix\"></slot>\n </span>\n <input\n id=\"${this.inputId}\"\n class=\"${classMap({\n 'w-full': !isClearIconVisible,\n 'w-[calc(100%-var(--spacing)*7)]': isClearIconVisible,\n '[&::-webkit-search-cancel-button]:appearance-none':\n this.type === 'search',\n })} input grow overflow-clip focus-visible:outline-0\"\n part=\"input\"\n .value=${live(this.value)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?autofocus=${this.autofocus}\n autocomplete=${ifDefined(this.autocomplete as any)}\n type=${this.type === 'password' && this.passwordvisible\n ? 'text'\n : this.type}\n aria-describedby=\"${this.descriptionId}\"\n aria-errormessage=\"${this.validationId}\"\n placeholder=${ifDefined(this.placeholder)}\n minlength=${ifDefined(this.minlength)}\n maxlength=${ifDefined(this.maxlength)}\n min=${ifDefined(this.min)}\n max=${ifDefined(this.max)}\n pattern=${ifDefined(this.pattern)}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n @keydown=${this.handleKeydown}\n />\n ${isClearIconVisible\n ? html`\n <button\n part=\"clear-button\"\n type=\"button\"\n class=\"focus-visible:focus-ring ml-2 flex items-center justify-center rounded-sm\"\n aria-label=\"Tøm\"\n @click=${this.handleClearClick}\n >\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"xmark\"\n ></mid-icon>\n </button>\n `\n : ''}\n ${this.passwordtoggle && !this.disabled\n ? html`\n <button\n part=\"password-toggle-button\"\n type=\"button\"\n class=\"ml-2 flex items-center justify-center rounded-sm\"\n aria-label=${this.passwordvisible\n ? 'skjul passord'\n : 'vis passord'}\n @click=${this.handlePasswordToggle}\n tabindex=\"-1\"\n >\n ${this.passwordvisible\n ? html` <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye-slash\"\n ></mid-icon>`\n : html`\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye\"\n ></mid-icon>\n `}\n </button>\n `\n : ''}\n <span part=\"suffix\" class=\"slotted:!ml-2 slotted:rounded\">\n <slot name=\"suffix\"></slot>\n </span>\n </div>\n <div\n class=\"text-danger-subtle mt-2 flex gap-1\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n ?hidden=${!this.invalidmessage}\n >\n <mid-icon\n name=\"xmark-octagon-fill\"\n class=\"mt-1 min-h-5 min-w-5\"\n ></mid-icon>\n ${this.invalidmessage}\n </div>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,SAAS;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAKF;AAEA,IAAI,eAAe;AAuBZ,IAAM,iBAAN,cAA6B;AAAA,EAClC,OAAO,YAAY,MAAM;AAC3B,EAAE;AAAA,EA+IA,cAAc;AACN,UAAA;AA5IR,SAAiB,mBAAmB,IAAI,kBAAkB,MAAM,OAAO;AACvE,SAAQ,eAAe;AAMf,SAAA,QAAA;AAGM,SAAA,cAAA;AAGN,SAAA,QAAA;AAGmB,SAAA,OAAA;AASf,SAAA,YAAA;AAoCK,SAAA,iBAAA;AAgBJ,SAAA,OAAA;AAMD,SAAA,YAAA;AAOK,SAAA,iBAAA;AAOC,SAAA,kBAAA;AAGP,SAAA,WAAA;AAGA,SAAA,WAAA;AAYA,SAAA,WAAA;AAMC,SAAA,YAAA;AAGD,SAAA,WAAA;AAiBT;AACK,SAAA,UAAU,uBAAuB,YAAY;AAC7C,SAAA,gBAAgB,6BAA6B,YAAY;AACzD,SAAA,eAAe,4BAA4B,YAAY;AAAA,EAAA;AAAA,EAlB9D,WAAW,wBAAwB;AAC1B,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EAAA;AAAA,EAGF,IAAI,mBAAmB;AACrB,WAAO,KAAK;AAAA,EAAA;AAAA,EAWL,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,eAAe,KAAK;AAAA,EAAA;AAAA,EAGnB,cAAc,OAAsB;AAC1C,UAAM,cACJ,MAAM,WAAW,MAAM,WAAW,MAAM,YAAY,MAAM;AAI5D,QAAI,MAAM,QAAQ,WAAW,CAAC,aAAa;AACzC,iBAAW,MAAM;AAIf,YAAI,CAAC,MAAM,oBAAoB,CAAC,MAAM,aAAa;AACjD,eAAK,KAAK,cAAc;AAAA,QAAA;AAAA,MAC1B,CACD;AAAA,IAAA;AAAA,EACH;AAAA,EAGM,aAAa;AACnB,SAAK,WAAW;AACX,SAAA;AAAA,MACH,IAAI,MAAM,YAAY,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IACzD;AAAA,EAAA;AAAA,EAGM,eAAe;AAChB,SAAA,QAAQ,KAAK,MAAM;AACnB,SAAA;AAAA,MACH,IAAI,MAAM,cAAc,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IAC3D;AAAA,EAAA;AAAA,EAGM,cAAc;AACf,SAAA,QAAQ,KAAK,MAAM;AACnB,SAAA,SAAS,KAAK,KAAK;AACnB,SAAA;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IAC1D;AAAA,EAAA;AAAA,EAGM,cAAc;AACpB,SAAK,WAAW;AACX,SAAA;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,IAC1D;AAAA,EAAA;AAAA,EAGM,uBAAuB;AACxB,SAAA,kBAAkB,CAAC,KAAK;AAAA,EAAA;AAAA,EAGvB,iBAAiB,OAAmB;AAC1C,UAAM,eAAe;AAEjB,QAAA,KAAK,UAAU,IAAI;AACrB,WAAK,QAAQ;AACR,WAAA;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC1D;AACK,WAAA;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC1D;AACK,WAAA;AAAA,QACH,IAAI,MAAM,cAAc,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC3D;AAAA,IAAA;AAGF,SAAK,MAAM,MAAM;AAAA,EAAA;AAAA,EAGnB,QAAQ;AACN,SAAK,WAAW;AAChB,SAAK,MAAM,MAAM;AAAA,EAAA;AAAA,EAGnB,mBAAmB;AACjB,SAAK,iBAAiB;AACtB,SAAK,QAAQ,KAAK;AAAA,EAAA;AAAA,EAGpB,WAAW,SAAwB;AACjC,UAAM,WAAW,OAAO;AAAA,EAAA;AAAA,EAI1B,oBAAoB;AACb,SAAA,SAAS,KAAK,KAAK;AAAA,EAAA;AAAA,EAGjB,SAAS;AACV,UAAA,KAAK,KAAK,SAAS;AACnB,UAAA,KAAK,KAAK,SAAS;AACnB,UAAA,KAAK,KAAK,SAAS;AAEzB,UAAM,eAAe,KAAK,iBAAiB,KAAK,OAAO;AACvD,UAAM,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;AACnC,UAAM,eAAe,KAAK,aAAa,CAAC,KAAK,YAAY,CAAC,KAAK;AACzD,UAAA,qBACJ,iBAAiB,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,SAAS;AAElE,WAAA;AAAA;AAAA;AAAA,iBAGM,SAAS;AAAA,MAChB,oBAAoB,KAAK;AAAA,MACzB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA;AAAA,iBAGO,KAAK,OAAO;AAAA,mBACV,SAAS;AAAA,MAChB,WAAW,KAAK,aAAa,CAAC;AAAA,IAAA,CAC/B,CAAC;AAAA;AAAA,YAEA,KAAK,WACH;AAAA;AAAA;AAAA;AAAA,8BAKA,OAAO;AAAA,gCACW,KAAK,KAAK;AAAA;AAAA,UAEhC,KAAK,cACH;AAAA;AAAA,sBAEU,KAAK,aAAa;AAAA;AAAA,yBAEf,SAAS;AAAA,MAChB,WAAW,KAAK;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA,kBAEA,KAAK,WAAW;AAAA;AAAA,gBAGtB,OAAO;AAAA;AAAA;AAAA,mBAGA,SAAS;AAAA,MAChB,kBAAkB,CAAC,KAAK,kBAAkB,CAAC,KAAK;AAAA,MAChD,iBAAiB,KAAK,kBAAkB,CAAC,KAAK;AAAA,MAC9C,yBAAyB,KAAK;AAAA,MAC9B,6BAA6B,KAAK;AAAA,MAClC,sBAAsB,CAAC,KAAK;AAAA,MAC5B,QAAQ,CAAC,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,IAAA,CAClB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMM,KAAK,OAAO;AAAA,qBACT,SAAS;AAAA,MAChB,UAAU,CAAC;AAAA,MACX,mCAAmC;AAAA,MACnC,qDACE,KAAK,SAAS;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA,qBAEO,KAAK,KAAK,KAAK,CAAC;AAAA,wBACb,KAAK,QAAQ;AAAA,wBACb,KAAK,QAAQ;AAAA,yBACZ,KAAK,SAAS;AAAA,2BACZ,UAAU,KAAK,YAAmB,CAAC;AAAA,mBAC3C,KAAK,SAAS,cAAc,KAAK,kBACpC,SACA,KAAK,IAAI;AAAA,gCACO,KAAK,aAAa;AAAA,iCACjB,KAAK,YAAY;AAAA,0BACxB,UAAU,KAAK,WAAW,CAAC;AAAA,wBAC7B,UAAU,KAAK,SAAS,CAAC;AAAA,wBACzB,UAAU,KAAK,SAAS,CAAC;AAAA,kBAC/B,UAAU,KAAK,GAAG,CAAC;AAAA,kBACnB,UAAU,KAAK,GAAG,CAAC;AAAA,sBACf,UAAU,KAAK,OAAO,CAAC;AAAA,qBACxB,KAAK,WAAW;AAAA,sBACf,KAAK,YAAY;AAAA,qBAClB,KAAK,WAAW;AAAA,oBACjB,KAAK,UAAU;AAAA,uBACZ,KAAK,aAAa;AAAA;AAAA,YAE7B,qBACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAMa,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBASlC,EAAE;AAAA,YACJ,KAAK,kBAAkB,CAAC,KAAK,WAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,+BAKiB,KAAK,kBACd,kBACA,aAAa;AAAA,2BACR,KAAK,oBAAoB;AAAA;AAAA;AAAA,oBAGhC,KAAK,kBACH;AAAA;AAAA;AAAA;AAAA,sCAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAMC;AAAA;AAAA,kBAGT,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAOA,KAAK,YAAY;AAAA;AAAA,oBAEb,CAAC,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAM5B,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA,EAAA;AAK/B;AA5YE,gBAAA;AAAA,EADC,MAAM,QAAQ;AAAA,GATJ,eAUX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAZC,eAaX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAfC,eAgBX,WAAA,eAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlBC,eAmBX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GArBC,eAsBX,WAAA,QAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,WAAW,gBAAiB,CAAA;AAAA,GAxB7B,eAyBX,WAAA,eAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA9BhB,eA+BX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GApCC,eAqCX,WAAA,gBAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAQ,CAAA;AAAA,GA1Cf,eA2CX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAQ,CAAA;AAAA,GAhDf,eAiDX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAtDC,eAuDX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GA5DC,eA6DX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlEC,eAmEX,WAAA,kBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GArEC,eAsEX,WAAA,QAAA,CAAA;AAmBA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAxFhB,eAyFX,WAAA,aAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA/FhB,eAgGX,WAAA,kBAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAtGhB,eAuGX,WAAA,mBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAM,CAAA;AAAA,GAzG/B,eA0GX,WAAA,YAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAM,CAAA;AAAA,GA5G/B,eA6GX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlHC,eAmHX,WAAA,WAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAxHhB,eAyHX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA9HhB,eA+HX,WAAA,aAAA,CAAA;AAGA,gBAAA;AAAA,EADC,MAAM;AAAA,GAjII,eAkIX,WAAA,YAAA,CAAA;AAiHA,gBAAA;AAAA,EADC,MAAM,OAAO;AAAA,GAlPH,eAmPX,WAAA,qBAAA,CAAA;AAnPW,iBAAN,gBAAA;AAAA,EADN,cAAc,eAAe;AAAA,GACjB,cAAA;"}
1
+ {"version":3,"file":"textfield.js","sources":["../../src/components/textfield.component.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { stringConverter } from '../internal/string-converter';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styled } from '../mixins/tailwind.mixin.ts';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { HasSlotController } from '../internal/slot';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport {\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n requiredValidator,\n} from '../mixins/validators';\nimport { watch } from '../internal/watch';\nimport './icon/icon.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-textfield': MinidTextfield;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n `,\n];\n\nlet nextUniqueId = 0;\n\n/**\n *\n * @event mid-change - Emitted when a change to the input value is comitted by the user\n * @event mid-input - Emitted when the input element recieves input\n * @event mid-clear - Emitted when the input value is cleared\n * @event mid-focus - Emitted when input element is focused\n * @event mid-blur - Emitted when focus moves away from input element\n * @event {detail: { validity: ValidityState }} mid-invalid-hide - Emitted when the error message should be hidden\n * @event {detail: { validity: ValidityState }} mid-invalid-show - Emitted when the error message should be shown\n *\n * @slot prefix - Used for decoration to the left of the input\n * @slot suffix - Used for decoration to the right of the input\n * @slot label - The input's label. Alternatively, you can use the `label` attribute.\n *\n * @csspart base - The input's wrapper that has the input field styling.\n * @csspart input - The internal `<input>` element.\n * @csspart field - The element that wraps the label, input, and help text.\n * @csspart clear-button - The clear button\n * @csspart password-toggle-button - The button for toggling password visibility\n */\n@customElement('mid-textfield')\nexport class MinidTextfield extends FormControlMixin(\n styled(LitElement, styles)\n) {\n private readonly inputId!: string;\n private readonly descriptionId!: string;\n private readonly validationId!: string;\n private readonly hasSlotControler = new HasSlotController(this, 'label');\n private initialValue = '';\n\n @query('.input')\n input!: HTMLInputElement;\n\n @property()\n label = '';\n\n @property()\n description = '';\n\n @property()\n value = '';\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ converter: stringConverter })\n placeholder?: string;\n\n /**\n * Autofocus the input field on page load\n */\n @property({ type: Boolean })\n autofocus = false;\n\n /**\n * User agent autocomplete hint\n */\n @property()\n autocomplete?: AutoFill;\n\n /**\n * The minimum length of input that will be considered valid.\n */\n @property({ type: Number })\n minlength?: number;\n\n /**\n * The maximum length of input that will be considered valid.\n */\n @property({ type: Number })\n maxlength?: number;\n\n /**\n * The input's minimum value. Only applies to date and number input types.\n */\n @property()\n min?: number | string;\n\n /**\n * The input's maximum value. Only applies to date and number input types.\n */\n @property()\n max?: number | string;\n\n /**\n * Error message to display when the input is invalid, also activates invalid styling\n */\n @property()\n invalidmessage = '';\n\n @property()\n type:\n | 'date'\n | 'datetime-local'\n | 'email'\n | 'file'\n | 'month'\n | 'number'\n | 'password'\n | 'search'\n | 'tel'\n | 'text'\n | 'time'\n | 'url'\n | 'week' = 'text';\n\n /**\n * Adds a clear button when the input is not empty.\n * */\n @property({ type: Boolean })\n clearable = false;\n\n /**\n * Adds a button to toggle the password's visibility.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordtoggle = false;\n\n /**\n * Determines wether the password is currently visible.\n * Only applies if type is password\n */\n @property({ type: Boolean })\n passwordvisible = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /**\n * A regular expression pattern to validate input against.\n */\n @property()\n pattern?: string;\n\n /**\n * Makes the input required\n */\n @property({ type: Boolean })\n required = false;\n\n /**\n * Visually hides `label` and `description` (still available for screen readers)\n */\n @property({ type: Boolean })\n hidelabel = false;\n\n @state()\n hasFocus = false;\n\n static get formControlValidators() {\n return [\n requiredValidator,\n maxLengthValidator,\n minLengthValidator,\n patternValidator,\n ];\n }\n\n constructor() {\n super();\n nextUniqueId++;\n this.inputId = `mid-textfield-input-${nextUniqueId}`;\n this.descriptionId = `mid-textfield-description-${nextUniqueId}`;\n this.validationId = `mid-textfield-validation-${nextUniqueId}`;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.initialValue = this.value;\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n //\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new Event('mid-blur', { bubbles: true, composed: true })\n );\n }\n\n private handleChange() {\n this.value = this.input.value;\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n }\n\n private handleInput() {\n this.value = this.input.value;\n this.setValue(this.value);\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new Event('mid-focus', { composed: true, bubbles: true })\n );\n }\n\n private handlePasswordToggle() {\n this.passwordvisible = !this.passwordvisible;\n }\n\n private handleClearClick(event: MouseEvent) {\n event.preventDefault();\n\n if (this.value !== '') {\n this.value = '';\n this.dispatchEvent(\n new Event('mid-clear', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { composed: true, bubbles: true })\n );\n this.dispatchEvent(\n new Event('mid-change', { composed: true, bubbles: true })\n );\n }\n\n this.input.focus();\n }\n\n focus() {\n this.hasFocus = true;\n this.input.focus();\n }\n\n resetFormControl() {\n this.invalidmessage = '';\n this.value = this.initialValue;\n }\n\n forceError(message?: string): void {\n super.forceError(message);\n }\n\n @watch('value')\n handleValueUpdate() {\n this.setValue(this.value);\n }\n\n override render() {\n const lg = this.size === 'lg';\n const md = this.size === 'md';\n const sm = this.size === 'sm';\n\n const hasLabelSlot = this.hasSlotControler.test('label');\n const hasLabel = !!this.label || !!hasLabelSlot;\n const hasClearIcon = this.clearable && !this.disabled && !this.readonly;\n const isClearIconVisible =\n hasClearIcon && (typeof this.value === 'number' || this.value.length > 0);\n\n return html`\n <div\n part=\"field\"\n class=\"${classMap({\n 'opacity-disabled': this.disabled,\n 'text-body-sm': sm,\n 'text-body-md': md,\n 'text-body-lg': lg,\n })} max-w-full\"\n >\n <label\n for=\"${this.inputId}\"\n class=\"${classMap({\n 'sr-only': this.hidelabel || !hasLabel,\n })} mb-2 inline-flex items-center gap-1 font-medium\"\n >\n ${this.readonly\n ? html`<mid-icon\n class=\"size-5\"\n library=\"system\"\n name=\"padlock-locked-fill\"\n ></mid-icon>`\n : nothing}\n <slot name=\"label\"> ${this.label} </slot>\n </label>\n ${this.description\n ? html`\n <div\n id=\"${this.descriptionId}\"\n part=\"description\"\n class=\"${classMap({\n 'sr-only': this.hidelabel,\n })} text-neutral-subtle mb-2\"\n >\n ${this.description}\n </div>\n `\n : nothing}\n <div\n part=\"base\"\n class=\"${classMap({\n 'border-neutral': !this.invalidmessage && !this.readonly,\n 'border-danger': this.invalidmessage && !this.readonly,\n 'border-neutral-subtle': this.readonly,\n 'bg-neutral-surface-tinted': this.readonly,\n 'bg-neutral-surface': !this.readonly,\n border: !this.invalidmessage,\n 'border-2': this.invalidmessage,\n })} focus-within:focus-ring flex h-12 items-center rounded-md px-3\"\n >\n <span class=\"slotted:!mr-2 slotted:rounded flex items-center\">\n <slot name=\"prefix\"></slot>\n </span>\n <input\n id=\"${this.inputId}\"\n class=\"${classMap({\n 'w-full': !isClearIconVisible,\n 'w-[calc(100%-var(--spacing)*7)]': isClearIconVisible,\n '[&::-webkit-search-cancel-button]:appearance-none':\n this.type === 'search',\n })} input grow overflow-clip focus-visible:outline-0\"\n part=\"input\"\n .value=${live(this.value)}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?autofocus=${this.autofocus}\n autocomplete=${ifDefined(this.autocomplete as any)}\n type=${this.type === 'password' && this.passwordvisible\n ? 'text'\n : this.type}\n aria-describedby=\"${this.descriptionId}\"\n aria-errormessage=\"${this.validationId}\"\n placeholder=${ifDefined(this.placeholder)}\n minlength=${ifDefined(this.minlength)}\n maxlength=${ifDefined(this.maxlength)}\n min=${ifDefined(this.min)}\n max=${ifDefined(this.max)}\n pattern=${ifDefined(this.pattern)}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n @keydown=${this.handleKeydown}\n />\n ${isClearIconVisible\n ? html`\n <button\n part=\"clear-button\"\n type=\"button\"\n class=\"focus-visible:focus-ring ml-2 flex items-center justify-center rounded-sm\"\n aria-label=\"Tøm\"\n @click=${this.handleClearClick}\n >\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"xmark\"\n ></mid-icon>\n </button>\n `\n : ''}\n ${this.passwordtoggle && !this.disabled\n ? html`\n <button\n part=\"password-toggle-button\"\n type=\"button\"\n class=\"ml-2 flex items-center justify-center rounded-sm\"\n aria-label=${this.passwordvisible\n ? 'skjul passord'\n : 'vis passord'}\n @click=${this.handlePasswordToggle}\n tabindex=\"-1\"\n >\n ${this.passwordvisible\n ? html` <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye-slash\"\n ></mid-icon>`\n : html`\n <mid-icon\n class=\"size-7\"\n library=\"system\"\n name=\"eye\"\n ></mid-icon>\n `}\n </button>\n `\n : ''}\n <span part=\"suffix\" class=\"slotted:!ml-2 slotted:rounded\">\n <slot name=\"suffix\"></slot>\n </span>\n </div>\n <div\n class=\"text-danger-subtle mt-2 flex gap-1\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n ?hidden=${!this.invalidmessage}\n >\n <mid-icon\n name=\"xmark-octagon-fill\"\n class=\"mt-1 min-h-5 min-w-5\"\n ></mid-icon>\n ${this.invalidmessage}\n </div>\n </div>\n `;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,SAAS;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAKF;AAEA,IAAI,eAAe;AAuBZ,IAAM,iBAAN,cAA6B;AAAA,EAClC,OAAO,YAAY,MAAM;AAC3B,EAAE;AAAA,EA2IA,cAAc;AACN,UAAA;AAxIR,SAAiB,mBAAmB,IAAI,kBAAkB,MAAM,OAAO;AACvE,SAAQ,eAAe;AAMf,SAAA,QAAA;AAGM,SAAA,cAAA;AAGN,SAAA,QAAA;AAGmB,SAAA,OAAA;AASf,SAAA,YAAA;AAoCK,SAAA,iBAAA;AAgBJ,SAAA,OAAA;AAMD,SAAA,YAAA;AAOK,SAAA,iBAAA;AAOC,SAAA,kBAAA;AAGP,SAAA,WAAA;AAGA,SAAA,WAAA;AAYA,SAAA,WAAA;AAMC,SAAA,YAAA;AAGD,SAAA,WAAA;AAaT;AACK,SAAA,UAAU,uBAAuB,YAAY;AAC7C,SAAA,gBAAgB,6BAA6B,YAAY;AACzD,SAAA,eAAe,4BAA4B,YAAY;AAAA,EAAA;AAAA,EAd9D,WAAW,wBAAwB;AAC1B,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EAAA;AAAA,EAWO,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,eAAe,KAAK;AAAA,EAAA;AAAA,EAGnB,cAAc,OAAsB;AAC1C,UAAM,cACJ,MAAM,WAAW,MAAM,WAAW,MAAM,YAAY,MAAM;AAI5D,QAAI,MAAM,QAAQ,WAAW,CAAC,aAAa;AACzC,iBAAW,MAAM;AAIf,YAAI,CAAC,MAAM,oBAAoB,CAAC,MAAM,aAAa;AACjD,eAAK,KAAK,cAAc;AAAA,QAAA;AAAA,MAC1B,CACD;AAAA,IAAA;AAAA,EACH;AAAA,EAGM,aAAa;AACnB,SAAK,WAAW;AACX,SAAA;AAAA,MACH,IAAI,MAAM,YAAY,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IACzD;AAAA,EAAA;AAAA,EAGM,eAAe;AAChB,SAAA,QAAQ,KAAK,MAAM;AACnB,SAAA;AAAA,MACH,IAAI,MAAM,cAAc,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IAC3D;AAAA,EAAA;AAAA,EAGM,cAAc;AACf,SAAA,QAAQ,KAAK,MAAM;AACnB,SAAA,SAAS,KAAK,KAAK;AACnB,SAAA;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,SAAS,MAAM,UAAU,KAAM,CAAA;AAAA,IAC1D;AAAA,EAAA;AAAA,EAGM,cAAc;AACpB,SAAK,WAAW;AACX,SAAA;AAAA,MACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,IAC1D;AAAA,EAAA;AAAA,EAGM,uBAAuB;AACxB,SAAA,kBAAkB,CAAC,KAAK;AAAA,EAAA;AAAA,EAGvB,iBAAiB,OAAmB;AAC1C,UAAM,eAAe;AAEjB,QAAA,KAAK,UAAU,IAAI;AACrB,WAAK,QAAQ;AACR,WAAA;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC1D;AACK,WAAA;AAAA,QACH,IAAI,MAAM,aAAa,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC1D;AACK,WAAA;AAAA,QACH,IAAI,MAAM,cAAc,EAAE,UAAU,MAAM,SAAS,KAAM,CAAA;AAAA,MAC3D;AAAA,IAAA;AAGF,SAAK,MAAM,MAAM;AAAA,EAAA;AAAA,EAGnB,QAAQ;AACN,SAAK,WAAW;AAChB,SAAK,MAAM,MAAM;AAAA,EAAA;AAAA,EAGnB,mBAAmB;AACjB,SAAK,iBAAiB;AACtB,SAAK,QAAQ,KAAK;AAAA,EAAA;AAAA,EAGpB,WAAW,SAAwB;AACjC,UAAM,WAAW,OAAO;AAAA,EAAA;AAAA,EAI1B,oBAAoB;AACb,SAAA,SAAS,KAAK,KAAK;AAAA,EAAA;AAAA,EAGjB,SAAS;AACV,UAAA,KAAK,KAAK,SAAS;AACnB,UAAA,KAAK,KAAK,SAAS;AACnB,UAAA,KAAK,KAAK,SAAS;AAEzB,UAAM,eAAe,KAAK,iBAAiB,KAAK,OAAO;AACvD,UAAM,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;AACnC,UAAM,eAAe,KAAK,aAAa,CAAC,KAAK,YAAY,CAAC,KAAK;AACzD,UAAA,qBACJ,iBAAiB,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,SAAS;AAElE,WAAA;AAAA;AAAA;AAAA,iBAGM,SAAS;AAAA,MAChB,oBAAoB,KAAK;AAAA,MACzB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA;AAAA,iBAGO,KAAK,OAAO;AAAA,mBACV,SAAS;AAAA,MAChB,WAAW,KAAK,aAAa,CAAC;AAAA,IAAA,CAC/B,CAAC;AAAA;AAAA,YAEA,KAAK,WACH;AAAA;AAAA;AAAA;AAAA,8BAKA,OAAO;AAAA,gCACW,KAAK,KAAK;AAAA;AAAA,UAEhC,KAAK,cACH;AAAA;AAAA,sBAEU,KAAK,aAAa;AAAA;AAAA,yBAEf,SAAS;AAAA,MAChB,WAAW,KAAK;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA,kBAEA,KAAK,WAAW;AAAA;AAAA,gBAGtB,OAAO;AAAA;AAAA;AAAA,mBAGA,SAAS;AAAA,MAChB,kBAAkB,CAAC,KAAK,kBAAkB,CAAC,KAAK;AAAA,MAChD,iBAAiB,KAAK,kBAAkB,CAAC,KAAK;AAAA,MAC9C,yBAAyB,KAAK;AAAA,MAC9B,6BAA6B,KAAK;AAAA,MAClC,sBAAsB,CAAC,KAAK;AAAA,MAC5B,QAAQ,CAAC,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,IAAA,CAClB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAMM,KAAK,OAAO;AAAA,qBACT,SAAS;AAAA,MAChB,UAAU,CAAC;AAAA,MACX,mCAAmC;AAAA,MACnC,qDACE,KAAK,SAAS;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA,qBAEO,KAAK,KAAK,KAAK,CAAC;AAAA,wBACb,KAAK,QAAQ;AAAA,wBACb,KAAK,QAAQ;AAAA,yBACZ,KAAK,SAAS;AAAA,2BACZ,UAAU,KAAK,YAAmB,CAAC;AAAA,mBAC3C,KAAK,SAAS,cAAc,KAAK,kBACpC,SACA,KAAK,IAAI;AAAA,gCACO,KAAK,aAAa;AAAA,iCACjB,KAAK,YAAY;AAAA,0BACxB,UAAU,KAAK,WAAW,CAAC;AAAA,wBAC7B,UAAU,KAAK,SAAS,CAAC;AAAA,wBACzB,UAAU,KAAK,SAAS,CAAC;AAAA,kBAC/B,UAAU,KAAK,GAAG,CAAC;AAAA,kBACnB,UAAU,KAAK,GAAG,CAAC;AAAA,sBACf,UAAU,KAAK,OAAO,CAAC;AAAA,qBACxB,KAAK,WAAW;AAAA,sBACf,KAAK,YAAY;AAAA,qBAClB,KAAK,WAAW;AAAA,oBACjB,KAAK,UAAU;AAAA,uBACZ,KAAK,aAAa;AAAA;AAAA,YAE7B,qBACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAMa,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBASlC,EAAE;AAAA,YACJ,KAAK,kBAAkB,CAAC,KAAK,WAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,+BAKiB,KAAK,kBACd,kBACA,aAAa;AAAA,2BACR,KAAK,oBAAoB;AAAA;AAAA;AAAA,oBAGhC,KAAK,kBACH;AAAA;AAAA;AAAA;AAAA,sCAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAMC;AAAA;AAAA,kBAGT,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAOA,KAAK,YAAY;AAAA;AAAA,oBAEb,CAAC,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAM5B,KAAK,cAAc;AAAA;AAAA;AAAA;AAAA,EAAA;AAK/B;AAxYE,gBAAA;AAAA,EADC,MAAM,QAAQ;AAAA,GATJ,eAUX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAZC,eAaX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAfC,eAgBX,WAAA,eAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlBC,eAmBX,WAAA,SAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GArBC,eAsBX,WAAA,QAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,WAAW,gBAAiB,CAAA;AAAA,GAxB7B,eAyBX,WAAA,eAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA9BhB,eA+BX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GApCC,eAqCX,WAAA,gBAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAQ,CAAA;AAAA,GA1Cf,eA2CX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,OAAQ,CAAA;AAAA,GAhDf,eAiDX,WAAA,aAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAtDC,eAuDX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GA5DC,eA6DX,WAAA,OAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlEC,eAmEX,WAAA,kBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS;AAAA,GArEC,eAsEX,WAAA,QAAA,CAAA;AAmBA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAxFhB,eAyFX,WAAA,aAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA/FhB,eAgGX,WAAA,kBAAA,CAAA;AAOA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAtGhB,eAuGX,WAAA,mBAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAM,CAAA;AAAA,GAzG/B,eA0GX,WAAA,YAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAM,CAAA;AAAA,GA5G/B,eA6GX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS;AAAA,GAlHC,eAmHX,WAAA,WAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GAxHhB,eAyHX,WAAA,YAAA,CAAA;AAMA,gBAAA;AAAA,EADC,SAAS,EAAE,MAAM,QAAS,CAAA;AAAA,GA9HhB,eA+HX,WAAA,aAAA,CAAA;AAGA,gBAAA;AAAA,EADC,MAAM;AAAA,GAjII,eAkIX,WAAA,YAAA,CAAA;AA6GA,gBAAA;AAAA,EADC,MAAM,OAAO;AAAA,GA9OH,eA+OX,WAAA,qBAAA,CAAA;AA/OW,iBAAN,gBAAA;AAAA,EADN,cAAc,eAAe;AAAA,GACjB,cAAA;"}
@@ -22,6 +22,16 @@
22
22
  --font-sans: 'Inter', 'Arial', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
23
23
  --font-sans--font-feature-settings: 'cv05' 1;
24
24
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
25
+ --text-1: 0.75rem;
26
+ --text-2: 0.875rem;
27
+ --text-3: 1rem;
28
+ --text-4: 1.125rem;
29
+ --text-5: 1.3125rem;
30
+ --text-6: 1.5rem;
31
+ --text-7: 1.875rem;
32
+ --text-8: 2.25rem;
33
+ --text-9: 3rem;
34
+ --text-10: 3.75rem;
25
35
  --text-heading-2xl--font-weight: 500;
26
36
  --text-heading-2xl--line-height: 1.3;
27
37
  --text-heading-2xl: 3.75rem;
@@ -110,19 +120,6 @@
110
120
  --text-body-long-xs--line-height: 1.7;
111
121
  --text-body-long-xs: 0.875rem;
112
122
  --text-body-long-xs--letter-spacing: 0.15%;
113
- --text-1: 0.75rem;
114
- --text-2: 0.875rem;
115
- --text-3: 1rem;
116
- --text-4: 1.125rem;
117
- --text-5: 1.3125rem;
118
- --text-6: 1.5rem;
119
- --text-7: 1.875rem;
120
- --text-8: 2.25rem;
121
- --text-9: 3rem;
122
- --text-10: 3.75rem;
123
- --font-weight-medium: 500;
124
- --font-weight-semibold: 600;
125
- --font-weight-regular: 400;
126
123
  --leading-sm: 1.3;
127
124
  --leading-md: 1.5;
128
125
  --leading-lg: 1.7;
@@ -135,6 +132,9 @@
135
132
  --tracking-7: 0.25%;
136
133
  --tracking-8: 0.5%;
137
134
  --tracking-9: 1.5%;
135
+ --font-weight-medium: 500;
136
+ --font-weight-semibold: 600;
137
+ --font-weight-regular: 400;
138
138
 
139
139
  /******************************
140
140
  * Color
@@ -301,6 +301,10 @@
301
301
  @apply ring-focus-inner outline-focus-outer ring-[3px] outline-[3px] outline-offset-[3px];
302
302
  }
303
303
 
304
+ @utility focus-ring-sm {
305
+ @apply ring-focus-inner outline-focus-outer ring-2 outline-2 outline-offset-2;
306
+ }
307
+
304
308
  @custom-variant slotted (& ::slotted(*));
305
309
 
306
310
  @theme {
@@ -333,3 +337,29 @@
333
337
  }
334
338
  }
335
339
  }
340
+
341
+ @layer components {
342
+ .mid-input {
343
+ @apply focus-within:focus-ring border-neutral bg-neutral-surface h-12 items-center rounded-md border px-3;
344
+ }
345
+
346
+ .mid-menu {
347
+ @apply border-neutral-subtle rounded-md border shadow-md;
348
+ }
349
+
350
+ .mid-menu-item {
351
+ @apply bg-neutral block w-full rounded border-l-[5px] border-transparent px-3 py-2 font-medium;
352
+ }
353
+
354
+ .mid-menu-item:hover {
355
+ @apply border-accent-base bg-accent-tinted;
356
+ }
357
+
358
+ .mid-menu-item:focus {
359
+ @apply border-accent-base bg-accent-tinted outline-0;
360
+ }
361
+
362
+ .mid-menu-item:active {
363
+ @apply border-accent-base bg-accent-tinted;
364
+ }
365
+ }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { MinidAlert } from './components/alert.component.ts';
2
2
  export { MinidButton } from './components/button.component.ts';
3
3
  export { MinidCheckbox } from './components/checkbox.component.ts';
4
+ export { MinidCodeInputOld } from './components/code-input-old.component.ts';
4
5
  export { MinidCodeInput } from './components/code-input.component.ts';
5
6
  export { MinidCombobox } from './components/combobox.component.ts';
6
7
  export { MinidCountdown } from './components/countdown.component.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { MinidAlert } from "./components/alert.js";
2
2
  import { MinidButton } from "./components/button.js";
3
3
  import { MinidCheckbox } from "./components/checkbox.js";
4
+ import { MinidCodeInputOld } from "./components/code-input-old.js";
4
5
  import { MinidCodeInput } from "./components/code-input.js";
5
6
  import { MinidCombobox } from "./components/combobox.js";
6
7
  import { MinidCountdown } from "./components/countdown.js";
@@ -31,6 +32,7 @@ export {
31
32
  MinidButton,
32
33
  MinidCheckbox,
33
34
  MinidCodeInput,
35
+ MinidCodeInputOld,
34
36
  MinidCombobox,
35
37
  MinidCountdown,
36
38
  MinidDialog,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -15,13 +15,13 @@ const minLengthValidator = {
15
15
  key: "tooShort",
16
16
  message(instance, value) {
17
17
  const _value = value || "";
18
- return `Please use at least ${instance.minLength} characters (you are currently using ${_value.length} characters).`;
18
+ return `Please use at least ${instance.minlength} characters (you are currently using ${_value.length} characters).`;
19
19
  },
20
20
  isValid(instance, value) {
21
21
  if (!value) {
22
22
  return true;
23
23
  }
24
- if (!!value && instance.minLength > value.length) {
24
+ if (!!value && instance.minlength > value.length) {
25
25
  return false;
26
26
  }
27
27
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sources":["../../src/mixins/validators.ts"],"sourcesContent":["import type { FormControlInterface } from '../types/form-control';\nimport type { FormValue } from '../types/form-value';\nimport type { Validator } from '../types/validator.type';\n\nexport const requiredValidator: Validator = {\n attribute: 'required',\n key: 'valueMissing',\n message: 'Please fill out this field',\n isValid(\n instance: HTMLElement & { required: boolean },\n value: FormValue\n ): boolean {\n let valid = true;\n\n if ((instance.hasAttribute('required') || instance.required) && !value) {\n valid = false;\n }\n\n return valid;\n },\n};\n\nexport const minLengthValidator: Validator = {\n attribute: 'minlength',\n key: 'tooShort',\n message(\n instance: FormControlInterface & { minLength: number },\n value: FormValue\n ): string {\n const _value = (value as string) || '';\n return `Please use at least ${instance.minLength} characters (you are currently using ${_value.length} characters).`;\n },\n isValid(\n instance: HTMLElement & { minLength: number },\n value: string\n ): boolean {\n /** If no value is provided, this validator should return true */\n if (!value) {\n return true;\n }\n\n if (!!value && instance.minLength > value.length) {\n return false;\n }\n\n return true;\n },\n};\n\nexport const maxLengthValidator: Validator = {\n attribute: 'maxlength',\n key: 'tooLong',\n message(\n instance: FormControlInterface & { maxLength: number },\n value: FormValue\n ): string {\n const _value = (value as string) || '';\n return `Please use no more than ${instance.maxLength} characters (you are currently using ${_value.length} characters).`;\n },\n isValid(\n instance: HTMLElement & { maxLength: number },\n value: string\n ): boolean {\n /** If maxLength isn't set, this is valid */\n if (!instance.maxLength) {\n return true;\n }\n\n if (!!value && instance.maxLength < value.length) {\n return false;\n }\n\n return true;\n },\n};\n\nexport const patternValidator: Validator = {\n attribute: 'pattern',\n key: 'patternMismatch',\n message: 'Please match the requested format',\n isValid(instance: HTMLElement & { pattern: string }, value: string): boolean {\n /** If no value is provided, this validator should return true */\n if (!value || !instance.pattern) {\n return true;\n }\n\n const regExp = new RegExp(instance.pattern);\n return !!regExp.exec(value);\n },\n};\n"],"names":[],"mappings":"AAIO,MAAM,oBAA+B;AAAA,EAC1C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,QACE,UACA,OACS;AACT,QAAI,QAAQ;AAEZ,SAAK,SAAS,aAAa,UAAU,KAAK,SAAS,aAAa,CAAC,OAAO;AAC9D,cAAA;AAAA,IAAA;AAGH,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,qBAAgC;AAAA,EAC3C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,QACE,UACA,OACQ;AACR,UAAM,SAAU,SAAoB;AACpC,WAAO,uBAAuB,SAAS,SAAS,wCAAwC,OAAO,MAAM;AAAA,EACvG;AAAA,EACA,QACE,UACA,OACS;AAET,QAAI,CAAC,OAAO;AACH,aAAA;AAAA,IAAA;AAGT,QAAI,CAAC,CAAC,SAAS,SAAS,YAAY,MAAM,QAAQ;AACzC,aAAA;AAAA,IAAA;AAGF,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,qBAAgC;AAAA,EAC3C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,QACE,UACA,OACQ;AACR,UAAM,SAAU,SAAoB;AACpC,WAAO,2BAA2B,SAAS,SAAS,wCAAwC,OAAO,MAAM;AAAA,EAC3G;AAAA,EACA,QACE,UACA,OACS;AAEL,QAAA,CAAC,SAAS,WAAW;AAChB,aAAA;AAAA,IAAA;AAGT,QAAI,CAAC,CAAC,SAAS,SAAS,YAAY,MAAM,QAAQ;AACzC,aAAA;AAAA,IAAA;AAGF,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,mBAA8B;AAAA,EACzC,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,QAAQ,UAA6C,OAAwB;AAE3E,QAAI,CAAC,SAAS,CAAC,SAAS,SAAS;AACxB,aAAA;AAAA,IAAA;AAGT,UAAM,SAAS,IAAI,OAAO,SAAS,OAAO;AAC1C,WAAO,CAAC,CAAC,OAAO,KAAK,KAAK;AAAA,EAAA;AAE9B;"}
1
+ {"version":3,"file":"validators.js","sources":["../../src/mixins/validators.ts"],"sourcesContent":["import type { FormControlInterface } from '../types/form-control';\nimport type { FormValue } from '../types/form-value';\nimport type { Validator } from '../types/validator.type';\n\nexport const requiredValidator: Validator = {\n attribute: 'required',\n key: 'valueMissing',\n message: 'Please fill out this field',\n isValid(\n instance: HTMLElement & { required: boolean },\n value: FormValue\n ): boolean {\n let valid = true;\n\n if ((instance.hasAttribute('required') || instance.required) && !value) {\n valid = false;\n }\n\n return valid;\n },\n};\n\nexport const minLengthValidator: Validator = {\n attribute: 'minlength',\n key: 'tooShort',\n message(\n instance: FormControlInterface & { minlength: number },\n value: FormValue\n ): string {\n const _value = (value as string) || '';\n return `Please use at least ${instance.minlength} characters (you are currently using ${_value.length} characters).`;\n },\n isValid(\n instance: HTMLElement & { minlength: number },\n value: string\n ): boolean {\n /** If no value is provided, this validator should return true */\n if (!value) {\n return true;\n }\n\n if (!!value && instance.minlength > value.length) {\n return false;\n }\n\n return true;\n },\n};\n\nexport const maxLengthValidator: Validator = {\n attribute: 'maxlength',\n key: 'tooLong',\n message(\n instance: FormControlInterface & { maxLength: number },\n value: FormValue\n ): string {\n const _value = (value as string) || '';\n return `Please use no more than ${instance.maxLength} characters (you are currently using ${_value.length} characters).`;\n },\n isValid(\n instance: HTMLElement & { maxLength: number },\n value: string\n ): boolean {\n /** If maxLength isn't set, this is valid */\n if (!instance.maxLength) {\n return true;\n }\n\n if (!!value && instance.maxLength < value.length) {\n return false;\n }\n\n return true;\n },\n};\n\nexport const patternValidator: Validator = {\n attribute: 'pattern',\n key: 'patternMismatch',\n message: 'Please match the requested format',\n isValid(instance: HTMLElement & { pattern: string }, value: string): boolean {\n /** If no value is provided, this validator should return true */\n if (!value || !instance.pattern) {\n return true;\n }\n\n const regExp = new RegExp(instance.pattern);\n return !!regExp.exec(value);\n },\n};\n"],"names":[],"mappings":"AAIO,MAAM,oBAA+B;AAAA,EAC1C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,QACE,UACA,OACS;AACT,QAAI,QAAQ;AAEZ,SAAK,SAAS,aAAa,UAAU,KAAK,SAAS,aAAa,CAAC,OAAO;AAC9D,cAAA;AAAA,IAAA;AAGH,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,qBAAgC;AAAA,EAC3C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,QACE,UACA,OACQ;AACR,UAAM,SAAU,SAAoB;AACpC,WAAO,uBAAuB,SAAS,SAAS,wCAAwC,OAAO,MAAM;AAAA,EACvG;AAAA,EACA,QACE,UACA,OACS;AAET,QAAI,CAAC,OAAO;AACH,aAAA;AAAA,IAAA;AAGT,QAAI,CAAC,CAAC,SAAS,SAAS,YAAY,MAAM,QAAQ;AACzC,aAAA;AAAA,IAAA;AAGF,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,qBAAgC;AAAA,EAC3C,WAAW;AAAA,EACX,KAAK;AAAA,EACL,QACE,UACA,OACQ;AACR,UAAM,SAAU,SAAoB;AACpC,WAAO,2BAA2B,SAAS,SAAS,wCAAwC,OAAO,MAAM;AAAA,EAC3G;AAAA,EACA,QACE,UACA,OACS;AAEL,QAAA,CAAC,SAAS,WAAW;AAChB,aAAA;AAAA,IAAA;AAGT,QAAI,CAAC,CAAC,SAAS,SAAS,YAAY,MAAM,QAAQ;AACzC,aAAA;AAAA,IAAA;AAGF,WAAA;AAAA,EAAA;AAEX;AAEO,MAAM,mBAA8B;AAAA,EACzC,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,QAAQ,UAA6C,OAAwB;AAE3E,QAAI,CAAC,SAAS,CAAC,SAAS,SAAS;AACxB,aAAA;AAAA,IAAA;AAGT,UAAM,SAAS,IAAI,OAAO,SAAS,OAAO;AAC1C,WAAO,CAAC,CAAC,OAAO,KAAK,KAAK;AAAA,EAAA;AAE9B;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@felleslosninger/minid-elements",
3
- "version": "0.0.110",
3
+ "version": "0.0.111",
4
4
  "description": "MinID Web Components",
5
5
  "author": "Digitaliseringsdirektoratet",
6
6
  "license": "MIT",
@@ -181,6 +181,7 @@
181
181
  "@types/webappsec-credential-management": "^0.6.9",
182
182
  "@typescript-eslint/eslint-plugin": "^8.31.0",
183
183
  "@typescript-eslint/parser": "^8.31.0",
184
+ "@u-elements/u-datalist": "^1.0.5",
184
185
  "@vitejs/plugin-basic-ssl": "^2.0.0",
185
186
  "@vitejs/plugin-legacy": "^6.1.0",
186
187
  "composed-offset-position": "^0.0.6",
@@ -1,15 +0,0 @@
1
- import { LitElement } from 'lit';
2
- declare const MinidCodeInput2_base: typeof LitElement;
3
- export declare class MinidCodeInput2 extends MinidCodeInput2_base {
4
- private values;
5
- inputElements: NodeList;
6
- value: string;
7
- length: number;
8
- connectedCallback(): void;
9
- handleKeydown(index: number): (event: KeyboardEvent) => void;
10
- handleInput(index: number): (event: InputEvent) => void;
11
- private input;
12
- render(): import('lit-html').TemplateResult<1>;
13
- }
14
- export {};
15
- //# sourceMappingURL=code-input-2.component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-input-2.component.d.ts","sourceRoot":"","sources":["../../src/components/code-input-2.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;;AAM5C,qBACa,eAAgB,SAAQ,oBAA0B;IAC7D,OAAO,CAAC,MAAM,CAAmB;IAGjC,aAAa,EAAG,QAAQ,CAAC;IAGzB,KAAK,SAAM;IAGX,MAAM,SAAK;IAEX,iBAAiB,IAAI,IAAI;IAWzB,aAAa,CAAC,KAAK,EAAE,MAAM,IACjB,OAAO,aAAa;IAoB9B,WAAW,CAAC,KAAK,EAAE,MAAM,IACf,OAAO,UAAU;IAK3B,OAAO,CAAC,KAAK;IAeJ,MAAM;CAOhB"}
@@ -1,82 +0,0 @@
1
- import { css, LitElement, html } from "lit";
2
- import { queryAll, property, customElement } from "lit/decorators.js";
3
- import { styled } from "../mixins/tailwind.mixin.js";
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __decorateClass = (decorators, target, key, kind) => {
7
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
8
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
9
- if (decorator = decorators[i])
10
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
11
- if (kind && result) __defProp(target, key, result);
12
- return result;
13
- };
14
- const styles = [css``];
15
- let MinidCodeInput2 = class extends styled(LitElement, styles) {
16
- constructor() {
17
- super(...arguments);
18
- this.values = Array();
19
- this.value = "";
20
- this.length = 5;
21
- }
22
- connectedCallback() {
23
- super.connectedCallback();
24
- this.values = new Array(this.length).fill("");
25
- }
26
- // el.addEventListener('input', (evt) => this.onInput(evt, index));
27
- // el.addEventListener('paste', (evt) => this.onPaste(evt));
28
- // el.addEventListener('keydown', (evt) => this.onKeydown(evt, index));
29
- // el.addEventListener('focusin', () => this.onFocusIn(index));
30
- // el.addEventListener('focusout', () => this.onFocusOut(index));
31
- handleKeydown(index) {
32
- return (event) => {
33
- console.log(index, event);
34
- this.values[index] = event.target.value;
35
- this.value = this.values.join("");
36
- console.log(this.values, this.value);
37
- console.log(this.inputElements);
38
- };
39
- }
40
- handleInput(index) {
41
- return (event) => {
42
- console.log(index, event);
43
- };
44
- }
45
- input(index) {
46
- return html`
47
- <input
48
- id=${"code-input-" + index}
49
- class="bg-neutral-subtle"
50
- min="0"
51
- max="9"
52
- size="1"
53
- maxlength="1"
54
- @keydown=${this.handleKeydown(index)}
55
- @input=${this.handleInput(index)}
56
- />
57
- `;
58
- }
59
- render() {
60
- const fields = [];
61
- for (let index = 0; index < this.length; index++) {
62
- fields.push(this.input(index));
63
- }
64
- return html` <div class="flex">${fields}</div> `;
65
- }
66
- };
67
- __decorateClass([
68
- queryAll("input")
69
- ], MinidCodeInput2.prototype, "inputElements", 2);
70
- __decorateClass([
71
- property()
72
- ], MinidCodeInput2.prototype, "value", 2);
73
- __decorateClass([
74
- property({ type: Number })
75
- ], MinidCodeInput2.prototype, "length", 2);
76
- MinidCodeInput2 = __decorateClass([
77
- customElement("mid-code-input-2")
78
- ], MinidCodeInput2);
79
- export {
80
- MinidCodeInput2
81
- };
82
- //# sourceMappingURL=code-input-2.js.map