UNPKG

@vtmn/svelte

Version:

Decathlon Design System - Vitamin Svelte components library

1 lines 114 kB
{"version":3,"file":"index.mjs","sources":["../src/utils/classnames.js","../src/utils/style.js","../src/guidelines/iconography/VtmnIcon/enums.js","../src/guidelines/iconography/VtmnIcon/VtmnIcon.svelte","../src/components/actions/VtmnButton/VtmnButton.svelte","../src/components/actions/VtmnDropdown/directives/clickOutsideOpenDropdown.js","../src/components/actions/VtmnDropdown/VtmnDropdown.svelte","../src/utils/math.js","../src/components/structure/VtmnDivider/enums.js","../src/components/structure/VtmnDivider/VtmnDivider.svelte","../src/components/actions/VtmnDropdownItem/VtmnDropdownItem.svelte","../src/components/actions/VtmnLink/enums.js","../src/utils/link.js","../src/components/actions/VtmnLink/VtmnLink.svelte","../src/components/forms/VtmnSelect/VtmnSelect.svelte","../src/components/forms/VtmnTextInput/VtmnTextInput.svelte","../src/components/indicators/VtmnBadge/enums.js","../src/components/indicators/VtmnBadge/VtmnBadge.svelte","../src/components/indicators/VtmnLoader/enums.js","../src/components/indicators/VtmnLoader/VtmnLoader.svelte","../src/components/indicators/VtmnPrice/enums.js","../src/components/indicators/VtmnPrice/VtmnPrice.svelte","../src/components/indicators/VtmnProgressbar/enums.js","../src/components/indicators/VtmnProgressbar/VtmnProgressbarCircular.svelte","../src/components/indicators/VtmnProgressbar/VtmnProgressbarLinear.svelte","../src/components/indicators/VtmnProgressbar/VtmnProgressbar.svelte","../src/components/indicators/VtmnRating/enum.js","../src/components/indicators/VtmnRating/vtmnRating.util.js","../src/components/indicators/VtmnRating/VtmnRating.svelte","../src/components/indicators/VtmnTag/enums.js","../src/components/indicators/VtmnTag/VtmnTag.svelte","../src/components/navigation/VtmnBreadcrumb/VtmnBreadcrumb.svelte","../src/components/navigation/VtmnBreadcrumbItem/VtmnBreadcrumbItem.svelte","../src/components/navigation/VtmnSearch/enums.js","../src/components/navigation/VtmnSearch/VtmnSearch.svelte","../src/components/navigation/VtmnNavbar/VtmnNavbar.svelte","../src/components/navigation/VtmnNavbarLink/VtmnNavbarLink.svelte","../src/components/navigation/VtmnTabs/enums.js","../src/components/navigation/VtmnTabs/VtmnTabs.svelte","../src/components/navigation/VtmnTabsItem/VtmnTabsItem.svelte","../src/components/overlays/VtmnAlert/enums.js","../src/components/overlays/VtmnAlert/vtmnAlertStore.js","../src/components/overlays/VtmnAlert/VtmnAlertItem.svelte","../src/components/overlays/VtmnAlert/VtmnAlert.svelte","../src/components/overlays/VtmnModal/VtmnModal.svelte","../src/components/overlays/VtmnPopover/enums.js","../src/components/overlays/VtmnPopover/VtmnPopover.svelte","../src/components/overlays/VtmnSnackbar/enum.js","../src/components/overlays/VtmnSnackbar/VtmnSnackbarItem.svelte","../src/components/overlays/VtmnSnackbar/vtmnSnackbarStore.js","../src/components/overlays/VtmnSnackbar/VtmnSnackbar.svelte","../src/components/overlays/VtmnToast/enums.js","../src/components/overlays/VtmnToast/vtmnToastStore.js","../src/components/overlays/VtmnToast/VtmnToastItem.svelte","../src/components/overlays/VtmnToast/VtmnToast.svelte","../src/components/overlays/VtmnTooltip/enums.js","../src/components/overlays/VtmnTooltip/VtmnTooltip.svelte","../src/components/selection-controls/VtmnCheckbox/VtmnCheckbox.svelte","../src/components/selection-controls/VtmnChip/enums.js","../src/components/selection-controls/VtmnChip/VtmnChip.svelte","../src/components/selection-controls/VtmnQuantity/VtmnQuantity.svelte","../src/components/selection-controls/VtmnRadioButton/VtmnRadioButton.svelte","../src/components/selection-controls/VtmnToggle/enums.js","../src/components/selection-controls/VtmnToggle/VtmnToggle.svelte","../src/components/structure/VtmnAccordion/VtmnAccordion.svelte","../src/components/structure/VtmnCard/enums.js","../src/components/structure/VtmnCard/VtmnCard.svelte","../src/components/structure/VtmnList/VtmnList.svelte","../src/components/structure/VtmnListItem/enums.js","../src/components/structure/VtmnListItem/VtmnListItem.svelte","../src/utils/keyCodes.js","../src/components/structure/VtmnSkeleton/enums.js","../src/components/structure/VtmnSkeleton/VtmnSkeleton.svelte"],"sourcesContent":["/**\n * @typedef {false|undefined|null|''|0|NaN} FalsyValue\n */\n\n/**\n * Concat all classNames, remove falsy or empty ones.\n * @param {(string|FalsyValue)[]} classNames\n * @returns {string}\n */\nexport const cn = (...classNames) => classNames.filter(Boolean).join(' ');\n","/**\n * Transform an object to a string style\n * @param {*} object\n * @returns {string}\n */\nexport const objectToStyle = (obj) =>\n Object.entries(obj)\n .filter(([, value]) => value != undefined)\n .map(([key, value]) => `${key}:${value}`)\n .join(';');\n","export const VTMN_ICON_VARIANT = {\n DEFAULT: 'default',\n BRAND: 'brand',\n PRIMARY: 'primary',\n SECONDARY: 'secondary',\n TERTIARY: 'tertiary',\n ACTION: 'action',\n ACTIVE: 'active',\n INACTIVE: 'inactive',\n NEGATIVE: 'negative',\n WARNING: 'warning',\n POSITIVE: 'positive',\n INFORMATION: 'information',\n ACCENT: 'accent',\n VISITED: 'visited',\n REVERSED: 'reversed',\n PRIMARY_REVERSED: 'primary-reversed',\n ACTION_REVERSED: 'action-reversed',\n VISITED_REVERSED: 'visited-reversed',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { objectToStyle } from '../../../utils/style';\n import { VTMN_ICON_VARIANT } from './enums';\n\n /**\n * The size of the icon in pixels.\n */\n export let size = 24;\n\n /**\n * The value of the icon.\n */\n export let value;\n\n /**\n * The variant of the icon.\n */\n export let variant = undefined;\n\n /**\n * Target reference of the icon\n */\n export let ref = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n const retrieveSemanticColor = (variant) => {\n switch (variant) {\n case VTMN_ICON_VARIANT.DEFAULT:\n return 'content-primary';\n case VTMN_ICON_VARIANT.BRAND:\n return 'background-brand-primary';\n case VTMN_ICON_VARIANT.REVERSED:\n return 'content-primary-reversed';\n default:\n return `content-${variant}`;\n }\n };\n\n let componentStyle;\n $: componentClass = cn(`vtmx-${value}`, 'vtmn-icon-size', className);\n $: {\n const style = {\n '--vtmn-icon-size': `${size}px`,\n };\n if (variant) {\n style[\n '--vtmn-icon-semantic-color'\n ] = `var(--vtmn-semantic-color_${retrieveSemanticColor(variant)})`;\n }\n componentStyle = objectToStyle(style);\n }\n</script>\n\n<span\n bind:this={ref}\n class={componentClass}\n style={componentStyle}\n {...$$restProps}\n/>\n\n<style>\n @import '@vtmn/icons/dist/vitamix/font/vitamix.css';\n .vtmn-icon-size {\n color: var(--vtmn-icon-semantic-color);\n font-size: var(--vtmn-icon-size);\n }\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VtmnIcon } from '../../../guidelines';\n\n /** @restProps { button } */\n\n /**\n * The variant of the button.\n * @type {'primary' | 'primary-reversed' | 'secondary' | 'tertiary' | 'ghost' | 'ghost-reversed' | 'conversion'}\n * @defaultValue 'primary'\n */\n export let variant = 'primary';\n /**\n * The size of the button.\n * @type {'small' | 'medium' | 'large' | 'stretched'}\n * @defaultValue 'medium'\n */\n export let size = 'medium';\n\n /**\n * Icon to display on the left hand side of button\n * @type string\n * @defaultValue undefined\n */\n export let iconLeft = undefined;\n\n /**\n * Icon to display on the right hand side of button\n * @type string\n * @defaultValue undefined\n */\n export let iconRight = undefined;\n\n /**\n * Icon to display when it is a button with icon only\n * @type string\n * @defaultValue undefined\n */\n export let iconAlone = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n /**\n * Reference of the button\n */\n export let ref = undefined;\n\n $: componentClass = cn(\n 'vtmn-btn',\n variant && `vtmn-btn_variant--${variant}`,\n size && `vtmn-btn_size--${size}`,\n !iconAlone && iconLeft && 'vtmn-btn--icon-left',\n !iconAlone && iconRight && 'vtmn-btn--icon-right',\n iconAlone && 'vtmn-btn--icon-alone',\n className,\n );\n</script>\n\n<button\n on:click\n on:keydown\n type=\"button\"\n bind:this={ref}\n class={componentClass}\n {...$$restProps}\n>\n {#if !iconAlone && iconLeft}\n <VtmnIcon value={iconLeft} />\n {/if}\n {#if iconAlone}\n <VtmnIcon value={iconAlone} />\n {:else}\n <slot />\n {/if}\n {#if !iconAlone && iconRight}\n <VtmnIcon value={iconRight} />\n {/if}\n</button>\n\n<style lang=\"css\">\n @import '@vtmn/css-button';\n</style>\n","/** Dispatch event on click outside of node */\nexport function clickOutsideOpenDropdown(node) {\n const handleClick = (event) => {\n if (\n node &&\n !node.contains(event.target) &&\n !event.defaultPrevented &&\n node.hasAttribute('open')\n ) {\n node.dispatchEvent(new CustomEvent('clickOutside', node));\n }\n };\n\n document.addEventListener('click', handleClick, true);\n\n return {\n destroy() {\n document.removeEventListener('click', handleClick, true);\n },\n };\n}\n","<script>\n import { cn } from '../../../utils/classnames';\n import { clickOutsideOpenDropdown } from './directives/clickOutsideOpenDropdown';\n\n /** @restProps */\n\n /**\n * @type {string} id of the dropdown\n * @requires\n */\n export let id;\n\n /**\n * @type {string} The main label. If not set the labelText is not displayed\n * @requires\n */\n export let label;\n\n /**\n * @type {string} summary of the dropdown\n * @requires\n */\n export let summary;\n\n /**\n * @type {boolean} Set disabled state of list item.\n * @defaultValue false\n */\n export let disabled = false;\n\n /**\n * Custom classes to apply to the component.\n * @type {string} className\n */\n let className = undefined;\n export { className as class };\n\n $: componentClass = cn('vtmn-dropdown', className);\n $: componentItemClass = cn('vtmn-dropdown_items');\n\n let detail;\n\n const handleClickOutside = () => (detail.open = false);\n</script>\n\n<div class={componentClass} aria-disabled={disabled} {...$$restProps}>\n <!-- svelte-ignore a11y-label-has-associated-control -->\n <label {id}>{label}</label>\n <details\n bind:this={detail}\n use:clickOutsideOpenDropdown\n on:clickOutside={handleClickOutside}\n >\n <summary aria-labelledby={id}>{summary}</summary>\n <div class={componentItemClass} role=\"group\" aria-labelledby={id}>\n <slot />\n </div>\n </details>\n</div>\n\n<style lang=\"css\">\n @import '@vtmn/css-dropdown';\n</style>\n","export function isFloat(n) {\n return n === +n && n !== (n | 0);\n}\n\nexport function isInteger(n) {\n return n === +n && n === (n | 0);\n}\n\nexport function uuid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n let r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport function roundToNearestHalf(number) {\n return Math.round(number * 2) / 2;\n}\n","export const VTMN_DIVIDER_ORIENTATION = {\n HORIZONTAL: 'horizontal',\n VERTICAL: 'vertical',\n};\n\nexport const VTMN_DIVIDER_TEXT_POSITION = {\n START: 'start',\n CENTER: 'center',\n END: 'end',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { uuid } from '../../../utils/math';\n\n import {\n VTMN_DIVIDER_ORIENTATION,\n VTMN_DIVIDER_TEXT_POSITION,\n } from './enums';\n\n /**\n * @type {string} Orientation of the divider\n */\n export let orientation = VTMN_DIVIDER_ORIENTATION.HORIZONTAL;\n\n /**\n * @type {string} Position of the text\n */\n export let textPosition = VTMN_DIVIDER_TEXT_POSITION.START;\n\n /**\n * @type {string} Id of the label\n */\n export let labelId = uuid();\n\n let className = undefined;\n\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-divider',\n `vtmn-divider_orientation--${orientation}`,\n `vtmn-divider_text-position--${textPosition}`,\n className,\n );\n</script>\n\n<div\n class={componentClass}\n role=\"separator\"\n aria-orientation={orientation}\n aria-labelledby={labelId}\n {...$$restProps}\n>\n {#if $$slots.default}\n <span id={labelId}>\n <slot />\n </span>\n {/if}\n</div>\n\n<style>\n @import '@vtmn/css-divider';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n import VtmnDivider from '../../structure/VtmnDivider/VtmnDivider.svelte';\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n\n /**\n * @type {string} if of the item\n * @requires\n */\n export let id;\n\n /**\n * @type {object} Value of the dropdown item\n * @requires\n */\n export let value;\n\n /**\n * @type {object[]} Array of selected items\n * @requires\n */\n export let group;\n\n /**\n * @type {boolean} If the dropdown item are selected\n */\n export let selected = false;\n\n /**\n * @type {boolean} Apply divider on the item\n * @defaultValue false\n */\n export let divider = false;\n\n /**\n * @type {string} Icon of menu item.\n */\n export let icon = undefined;\n /**\n * Custom classes to apply to the component.\n * @type {string} className\n */\n let className = undefined;\n\n export { className as class };\n $: componentClass = cn(className);\n\n const updateChekbox = (group) => (selected = group.indexOf(value) >= 0);\n\n const updateGroup = (selected) => {\n const index = group.indexOf(value);\n if (selected) {\n if (index < 0) {\n group.push(value);\n group = group;\n }\n return;\n }\n if (index >= 0) {\n group.splice(index, 1);\n group = group;\n }\n };\n\n $: group && updateChekbox(group);\n $: group && updateGroup(selected);\n</script>\n\n<input\n type=\"checkbox\"\n {id}\n class={componentClass}\n bind:checked={selected}\n on:change\n {value}\n {...$$restProps}\n/>\n\n<label for={id}>\n {#if icon}\n <VtmnIcon value={icon} />\n {/if}\n\n <slot />\n</label>\n\n{#if divider}\n <VtmnDivider orientation=\"horizontal\" role=\"separator\" />\n{/if}\n\n<style lang=\"css\">\n @import '@vtmn/css-dropdown';\n</style>\n","export const VTMN_LINK_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n LARGE: 'large',\n};\n","/**\n * Compute the rel and add noopener and noreferrer if target are _blank\n * https://thecodest.co/blog/web-app-security-target-_blank-vulnerability/\n * @param target\n * @param rel\n * @returns {string|*}\n */\nexport const computeRel = (target, rel = '') =>\n target === '_blank'\n ? Array.from(new Set(rel.split(' ')).add('noopener').add('noreferrer'))\n .join(' ')\n .trim()\n : rel;\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_LINK_SIZE } from './enums';\n import { computeRel } from '../../../utils/link';\n\n /**\n * The href of the link.\n * @type {string}\n * @requires\n */\n export let href;\n\n /**\n * The size of the link.\n * @type {string}\n * @defaultValue 'medium'\n */\n export let size = VTMN_LINK_SIZE.MEDIUM;\n\n /**\n * Whether link is standalone or not.\n * @type {boolean}\n * @defaultValue false\n */\n export let standalone = false;\n\n /**\n * Whether link is reversed or not.\n * @type {boolean}\n * @defaultValue false\n */\n export let reversed = false;\n\n /**\n * Whether link has an icon or not.\n * @type {boolean}\n * @defaultValue false\n */\n export let iconAlong = false;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n /**\n * Reference of the link\n */\n export let ref = undefined;\n\n $: componentClass = cn(\n 'vtmn-link',\n size && `vtmn-link_size--${size}`,\n standalone && 'vtmn-link--standalone',\n reversed && 'vtmn-link--reversed',\n standalone && iconAlong && 'vtmn-link--icon-along',\n className,\n );\n\n let computedRel = computeRel($$restProps['target'], $$restProps['rel']);\n</script>\n\n<a\n bind:this={ref}\n {href}\n class={componentClass}\n on:click\n {...$$restProps}\n rel={computedRel}\n>\n <slot />\n</a>\n\n<style lang=\"css\">\n @import '@vtmn/css-link';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n\n /**\n * @type {boolean} disable the select\n * @default false\n */\n export let disabled = false;\n\n /**\n * @type {string} error message displayed under the select\n */\n export let error = undefined;\n\n /**\n * @type {boolean} the select has a border\n * @default true\n */\n export let border = true;\n\n /**\n * @type {string} id of the select\n * @requires\n */\n export let id;\n\n /**\n * @type {string} name of the select\n * @requires\n */\n export let name;\n\n /**\n * @type {string} label display above the select\n * @requires\n */\n export let label;\n\n /**\n * @type {object} selected value under the select\n * @requires\n */\n export let value;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n /**\n * Reference of the select\n */\n export let ref = undefined;\n\n $: componentClass = cn(\n 'vtmn-select_container',\n !border && `vtmn-select--no-border`,\n className,\n );\n</script>\n\n<div class={componentClass}>\n <label for={id}>{label}</label>\n <select\n bind:this={ref}\n {name}\n {id}\n {disabled}\n bind:value\n on:change\n class:vtmn-select--error={error}\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? `error-text-${id}` : undefined}\n {...$$restProps}\n >\n <slot />\n </select>\n\n {#if error}\n <p id={`error-text-${id}`} class=\"vtmn-select_error-text\">\n {error}\n </p>\n {/if}\n</div>\n\n<style>\n @import '@vtmn/css-select';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n\n /** @restProps { input | textarea } */\n\n /**\n * ID of the input\n * @type {string}\n */\n export let id;\n\n /**\n * Label text linked to the input\n * @type {string}\n */\n export let labelText = undefined;\n\n /**\n * Plaholder of the input\n * @type {string}\n */\n export let placeholder = undefined;\n\n /**\n * Whether input should be disabled or not\n * @type {boolean}\n */\n export let disabled = false;\n\n /**\n * Helper text to help the user\n * @type {string}\n */\n export let helperText = undefined;\n\n /**\n * Whether input is multiline or not\n * @type {boolean}\n */\n export let multiline = false;\n\n /**\n * Whether input is successful or not\n * @type {boolean}\n */\n export let valid = false;\n\n /**\n * Whether input is in error or not\n * @type {boolean}\n */\n export let error = false;\n\n /**\n * Icon to be displayed\n * @type {string}\n */\n export let icon = undefined;\n\n /**\n * The value of the input\n * @type {string}\n */\n export let value;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n /**\n * Reference of the text input\n */\n export let ref = undefined;\n\n $: componentClass = cn(\n 'vtmn-text-input',\n valid && 'vtmn-text-input--valid',\n error && 'vtmn-text-input--error',\n className,\n );\n</script>\n\n{#if $$slots.labelComponent || labelText}\n <label class=\"vtmn-text-input_label\" for={id}>\n {#if $$slots.labelComponent}\n <slot name=\"labelComponent\" />\n {:else}\n {labelText}\n {/if}\n </label>\n{/if}\n{#if multiline}\n <textarea\n bind:this={ref}\n bind:value\n on:input\n on:change\n on:blur\n on:focus\n on:keyup\n on:keydown\n on:keypress\n class={componentClass}\n {id}\n {disabled}\n {placeholder}\n {...$$restProps}\n />\n{:else}\n <div class=\"vtmn-text-input_container\">\n <input\n bind:this={ref}\n bind:value\n on:input\n on:change\n on:blur\n on:focus\n on:keyup\n on:keydown\n on:keypress\n class={componentClass}\n type=\"text\"\n {id}\n {disabled}\n {placeholder}\n {...$$restProps}\n />\n {#if icon}\n <VtmnIcon value={icon} />\n {/if}\n </div>\n{/if}\n{#if helperText}\n <p\n class={cn(\n 'vtmn-text-input_helper-text',\n error && 'vtmn-text-input_helper-text--error',\n )}\n >\n {helperText}\n </p>\n{/if}\n\n<style lang=\"css\">\n @import '@vtmn/css-text-input';\n</style>\n","export const VTMN_BADGE_VARIANT = {\n DEFAULT: 'default',\n BRAND: 'brand',\n REVERSED: 'reversed',\n ACCENT: 'accent',\n ALERT: 'alert',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_BADGE_VARIANT } from './enums';\n /**\n * The value of the badge\n * @type {number}\n */\n export let value;\n\n /**\n * The variant of the badge\n * @type {'default' | 'brand' | 'reversed' | 'accent' | 'alert'}\n */\n export let variant = VTMN_BADGE_VARIANT.DEFAULT;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-badge',\n variant && `vtmn-badge_variant--${variant}`,\n className,\n );\n\n $: computedValue = value > 99 ? '99+' : value || '';\n</script>\n\n<span class={componentClass} {...$$restProps}>{computedValue}</span>\n\n<style lang=\"css\">\n @import '@vtmn/css-badge';\n</style>\n","export const VTMN_LOADER_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n LARGE: 'large',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_LOADER_SIZE } from './enums';\n\n /**\n * The size of the loader.\n * @type {'small' | 'medium' | 'large'}\n */\n export let size = VTMN_LOADER_SIZE.MEDIUM;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-loader',\n size && `vtmn-loader_size--${size}`,\n className,\n );\n</script>\n\n<div class={componentClass} {...$$restProps} />\n\n<style lang=\"css\">\n @import '@vtmn/css-loader';\n</style>\n","export const VTMN_PRICE_VARIANT = {\n DEFAULT: 'default',\n ACCENT: 'accent',\n ALERT: 'alert',\n STRIKETHROUGH: 'strikethrough',\n};\n\nexport const VTMN_PRICE_SIZE = {\n XSMALL: 'xsmall',\n SMALL: 'small',\n MEDIUM: 'medium',\n LARGE: 'large',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_PRICE_VARIANT, VTMN_PRICE_SIZE } from './enums';\n\n /**\n * Size of the price\n * @type { 'xsmall' | 'small' | 'medium' | 'large' }\n * @defaultValue 'medium'\n */\n export let size = VTMN_PRICE_SIZE.MEDIUM;\n\n /**\n * Variant of the price\n * @type {'default' | 'accent' | 'alert' | 'strikethrough'}\n * @defaultValue 'default'\n */\n export let variant = VTMN_PRICE_VARIANT.DEFAULT;\n\n /**\n * No padding on the price\n * @type boolean\n * @defaultValue false\n */\n export let noPadding = false;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-price',\n size && `vtmn-price_size--${size}`,\n variant && `vtmn-price_variant--${variant}`,\n noPadding && 'vtmn-price--no-padding',\n className,\n );\n</script>\n\n<span class={componentClass} {...$$restProps}>\n <slot />\n</span>\n\n<style lang=\"css\">\n @import '@vtmn/css-price';\n</style>\n","export const VTMN_PROGRESSBAR_VARIANT = {\n CIRCULAR: 'circular',\n LINEAR: 'linear',\n};\n\nexport const VTMN_PROGRESSBAR_SIZE = {\n MEDIUM: 'medium',\n SMALL: 'small',\n LARGE: 'large',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_PROGRESSBAR_SIZE } from './enums';\n\n /**\n * @type {number} progress value\n * @default 0\n */\n export let progress = 0;\n\n /**\n * @type {boolean} display progress value under the circle\n * @default false\n */\n export let label = false;\n\n /**\n * @type {boolean} enable track circle around the circle\n * @default false\n */\n export let track = false;\n\n /**\n * @type {boolean} set the progressbar to intermediate\n * @default false\n */\n export let indeterminate = false;\n\n /**\n * @type {'small'|'medium'} size of the progressbar\n * @default medium\n */\n export let size = VTMN_PROGRESSBAR_SIZE.MEDIUM;\n\n /**\n * @type {string} image src displayed on the progressbar\n */\n export let img = undefined;\n\n /**\n * @type {string} alt applied on the image\n */\n export let imgAlt = undefined;\n\n /**\n * @type {string} Id of the label\n * @default undefined\n */\n export let labelId = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n const DEFAULT_RADIUS = 32;\n const DEFAULT_DASHOFFSET = 200;\n\n $: componentClass = cn(\n 'vtmn-progressbar_container',\n 'vtmn-progressbar_variant--circular',\n indeterminate && 'vtmn-progressbar--indeterminate',\n size === VTMN_PROGRESSBAR_SIZE.SMALL && `vtmn-progressbar_size--small`,\n className,\n );\n\n let sizeMultiplier = 1;\n $: {\n sizeMultiplier = VTMN_PROGRESSBAR_SIZE.SMALL === size ? 1 : 2;\n }\n const computeDashoffset = () =>\n DEFAULT_DASHOFFSET * sizeMultiplier -\n (DEFAULT_DASHOFFSET * sizeMultiplier * (indeterminate ? 100 : progress)) /\n 100;\n</script>\n\n<div\n class={componentClass}\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-valuenow={indeterminate ? undefined : progress}\n aria-labelledby={labelId}\n {...$$restProps}\n>\n {#if img}\n <img class=\"vtmn-progressbar_image\" src={img} alt={imgAlt} />\n {/if}\n {#if label && !indeterminate}\n <span class=\"vtmn-progressbar_label\" aria-live=\"assertive\">{progress}%</span\n >\n {/if}\n {#if indeterminate}\n <span id={labelId} class=\"vtmn-sr-only\">{label}</span>\n {/if}\n <svg>\n {#if track}\n <circle\n class=\"vtmn-progressbar_track\"\n cx=\"50%\"\n cy=\"50%\"\n r={DEFAULT_RADIUS * sizeMultiplier}\n />\n {/if}\n <circle\n class=\"vtmn-progressbar_indicator\"\n stroke-dashoffset={computeDashoffset(sizeMultiplier)}\n cx=\"50%\"\n cy=\"50%\"\n r={DEFAULT_RADIUS * sizeMultiplier}\n />\n </svg>\n</div>\n\n<style>\n .vtmn-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_PROGRESSBAR_SIZE } from './enums';\n\n /**\n * @type {string} label display above the progress bar.\n * Hidden when indeterminate is true\n * @requires\n */\n export let label;\n\n /**\n * @type {'small'|'medium'|'large'} size of the progressbar\n * @default medium\n */\n export let size = VTMN_PROGRESSBAR_SIZE.MEDIUM;\n\n /**\n * @type {number} progress value\n * @default 0\n */\n export let progress;\n\n /**\n * @type {boolean} Set the progressbar to indeterminate\n * @default false\n */\n export let indeterminate = false;\n\n /**\n * @type {string} Id of the label\n * @default undefined\n */\n export let labelId = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-progressbar_container',\n 'vtmn-progressbar_variant--linear',\n size && `vtmn-progressbar_size--${size}`,\n indeterminate && `vtmn-progressbar--indeterminate`,\n className,\n );\n\n $: ariaProps = {\n 'aria-labelledby': labelId,\n ...(!indeterminate\n ? {\n 'aria-valuenow': progress,\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n }\n : {}),\n };\n</script>\n\n<div class={componentClass} role=\"progressbar\" {...ariaProps} {...$$restProps}>\n {#if label && !indeterminate}\n <div class=\"vtmn-progressbar_label\">\n <span id={labelId}>{label}</span>\n <span aria-live=\"assertive\">{progress}%</span>\n </div>\n {/if}\n {#if indeterminate}\n <span id={labelId} class=\"vtmn-sr-only\">{label}</span>\n {/if}\n <svg>\n <line\n class=\"vtmn-progressbar_indicator\"\n x1=\"0\"\n x2=\"100%\"\n y1=\"50%\"\n y2=\"50%\"\n style={`--vtmn-progressbar_progress-transform:${\n !indeterminate\n ? `translateX(${progress - 100}%) scale(${+(progress > 0)})`\n : undefined\n };`}\n />\n </svg>\n</div>\n\n<style>\n .vtmn-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n</style>\n","<script>\n import { VTMN_PROGRESSBAR_VARIANT, VTMN_PROGRESSBAR_SIZE } from './enums';\n import VtmnProgressbarCircular from './VtmnProgressbarCircular.svelte';\n import VtmnProgressbarLinear from './VtmnProgressbarLinear.svelte';\n\n /**\n * @type {'linear'|'circular'} variant of the progressbar\n * @default linear\n * @requires\n */\n export let variant = VTMN_PROGRESSBAR_VARIANT.LINEAR;\n\n /**\n * @type {'small'|'medium'|'large'} size of the progressbar\n * 'small' | 'medium' | 'large' for variant linear\n * 'small' | 'medium' for variant circular\n * @default medium\n * @requires\n */\n export let size = VTMN_PROGRESSBAR_SIZE.MEDIUM;\n\n /**\n * @type {string|boolean} label of the progressbar\n * For variant linear must be a string. Displayed above the progressbar\n * For variant circular must be a boolean. Display progress on the progressbar\n */\n export let label = undefined;\n\n /**\n * @type {number} progress value\n * @requires\n */\n export let progress = 0;\n\n /**\n * @type {boolean} set the progress bar to indeterminate value\n * @default false\n */\n export let indeterminate = false;\n\n /**\n * @type {boolean} display track circle on progressbar cicular\n * @default false\n */\n export let track = false;\n\n /**\n * @type {string} image src in order to display it on the progress circular\n */\n export let img = undefined;\n\n /**\n * @type {string} alt text displayed for the image\n */\n export let imgAlt = undefined;\n\n /**\n * @type {string} Id of the label\n * @default undefined\n */\n export let labelId = undefined;\n</script>\n\n{#if variant === VTMN_PROGRESSBAR_VARIANT.LINEAR}\n <VtmnProgressbarLinear\n {label}\n {labelId}\n {size}\n {progress}\n {indeterminate}\n {...$$restProps}\n />\n{:else if variant === VTMN_PROGRESSBAR_VARIANT.CIRCULAR}\n <VtmnProgressbarCircular\n {progress}\n {label}\n {labelId}\n {track}\n {indeterminate}\n {size}\n {img}\n {imgAlt}\n {...$$restProps}\n />\n{/if}\n\n<style>\n @import '@vtmn/css-progressbar';\n</style>\n","export const VTMN_RATING_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n};\n","import { isFloat, roundToNearestHalf } from '../../../utils/math';\n\n/**\n * Compute the vtmn-icon who has to be displayed on the position\n * @param {boolean} isCompact If the rating is compact\n * @param {number} currentRatingStarPosition Current position of the star on the component (range [1-5])\n * @param {number} ratingValue Value of the rating\n * @returns {'line'|'half-fill'|'fill'} Vtmn icon id\n */\nexport const computeRatingFill = (\n isCompact,\n currentRatingStarPosition,\n ratingValue,\n) => {\n if (isCompact) {\n return ratingValue === 0 ? 'line' : 'fill';\n }\n\n const computedRating = roundToNearestHalf(ratingValue);\n if (currentRatingStarPosition <= computedRating) {\n return 'fill';\n }\n return Math.ceil(computedRating) === currentRatingStarPosition &&\n isFloat(computedRating)\n ? 'half-fill'\n : 'line';\n};\n","<script>\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n import { cn } from '../../../utils/classnames';\n import { VTMN_RATING_SIZE } from './enum';\n import { computeRatingFill } from './vtmnRating.util';\n\n /**\n * @type {string} name used on interactive mode to name the inputs\n * @required\n */\n export let name;\n\n /**\n * @type {boolean} use the emphasis mode. Only if readonly is true.\n * @default false\n */\n export let emphasis = false;\n\n /**\n * @type {string} size of the component\n * @default medium\n */\n export let size = VTMN_RATING_SIZE.MEDIUM;\n\n /**\n * @type {boolean} disable the component\n * @default false\n */\n export let disabled = false;\n\n /**\n * @type {boolean} is readonly component\n * @default false\n */\n export let readonly = false;\n\n /**\n * @type {boolean} enable the compact mode. Only if readonly is true.\n * @default false\n */\n export let compact = false;\n\n /**\n * @type {number} rating to display on the component\n * @requires\n */\n export let value;\n\n /**\n * @type {boolean} display the rating value. Only if readonly is true.\n * default false\n */\n export let showValue = false;\n\n /**\n * @type {number} Comments displayed after the rating. Only if readonly is true.\n */\n export let comments = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-rating',\n size && `vtmn-rating_size--${size}`,\n emphasis && 'vtmn-rating_variant--brand',\n className,\n );\n $: starsCnt = compact && readonly ? 1 : 5;\n</script>\n\n<div\n class={componentClass}\n aria-disabled={disabled}\n {...readonly && $$restProps}\n>\n {#if readonly}\n {#each Array(starsCnt) as _, index}\n {@const position = index + 1}\n <VtmnIcon\n value={`star-${computeRatingFill(compact, position, value)}`}\n role=\"presentation\"\n />\n {/each}\n {#if showValue}\n <span class=\"vtmn-rating_comment--primary\">\n {value}/5\n </span>\n {/if}\n {#if comments}\n <span class=\"vtmn-rating_comment--secondary\">\n {comments}\n </span>\n {/if}\n {:else}\n <div\n class=\"vtmn-rating--interactive\"\n role=\"radiogroup\"\n data-rating={value}\n {...$$restProps}\n >\n {#each Array(starsCnt) as _, index}\n {@const position = index + 1}\n <input\n type=\"radio\"\n bind:group={value}\n {name}\n value={position}\n id={`${name}-${position}`}\n aria-label={`${position}/5`}\n {disabled}\n />\n <label for={`${name}-${position}`} />\n {/each}\n </div>\n {/if}\n</div>\n\n<style>\n @import '@vtmn/css-rating';\n</style>\n","export const VTMN_TAG_VARIANT = {\n ACCENT: 'accent',\n ALERT: 'alert',\n BRAND: 'brand',\n DECORATIVE_GRAVEL: 'decorative_gravel',\n DECORATIVE_BRICK: 'decorative_brick',\n DECORATIVE_SAFFRON: 'decorative_saffron',\n DECORATIVE_GOLD: 'decorative_gold',\n DECORATIVE_JADE: 'decorative_jade',\n DECORATIVE_EMERALD: 'decorative_emerald',\n DECORATIVE_COBALT: 'decorative_cobalt',\n DECORATIVE_AMETHYST: 'decorative_amethyst',\n};\n\nexport const VTMN_TAG_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import { VTMN_TAG_SIZE, VTMN_TAG_VARIANT } from './enums';\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n\n /**\n * Size of the tag\n * @type {'small' | 'medium'}\n * @defaultValue 'medium'\n */\n export let size = VTMN_TAG_SIZE.MEDIUM;\n\n /**\n * The variant of the tag\n * @type {'accent' | 'alert' | 'brand' | 'decorative_gravel' | 'decorative_brick' |'decorative_saffron' | 'decorative_gold' | 'decorative_jade' | 'decorative_emerald' | 'decorative_cobalt' | 'decorative_amethyst'}\n */\n export let variant = VTMN_TAG_VARIANT.ACCENT;\n\n /**\n * The icon to display at the start side of the tag.\n * Only for 'input' variant\n */\n export let icon = undefined;\n\n /**\n * The href that makes the tag interactive.\n * @type {string}\n */\n export let href = undefined;\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n\n $: componentClass = cn(\n 'vtmn-tag',\n size && `vtmn-tag_size--${size}`,\n variant && `vtmn-tag_variant--${variant}`,\n className,\n );\n</script>\n\n{#if href}\n <a {href} class={componentClass} {...$$restProps}>\n {#if icon}\n <VtmnIcon value={icon} aria-hidden=\"true\" />\n {/if}\n <slot />\n </a>\n{:else}\n <span class={componentClass} {...$$restProps}>\n {#if icon}\n <VtmnIcon value={icon} aria-hidden=\"true\" />\n {/if}\n <slot />\n </span>\n{/if}\n\n<style lang=\"css\">\n @import '@vtmn/css-tag';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n /** @restProps */\n\n /**\n * Custom classes to apply to the component.\n * @type {string}\n */\n export let className = undefined;\n\n /**\n * Properties applied on the `ol` node\n * @type {object}\n */\n export let orderedListAttributes = {};\n\n $: componentClass = cn('vtmn-breadcrumb', className);\n</script>\n\n<nav class={componentClass} {...$$restProps}>\n <ol {...orderedListAttributes}>\n <slot />\n </ol>\n</nav>\n\n<style lang=\"css\">\n @import '@vtmn/css-breadcrumb';\n</style>\n","<script>\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n\n /**\n * The icon to display on the left side of the breadcrumb.\n * @type {string}\n */\n export let icon = undefined;\n\n /**\n * The href that makes the tag interactive.\n * @type {string}\n */\n export let href = undefined;\n</script>\n\n<li {...$$restProps}>\n {#if icon}\n <VtmnIcon value={icon} aria-hidden=\"true\" size=\"16\" />\n {/if}\n\n {#if href}\n <a {href}>\n <slot />\n </a>\n {:else}\n <slot />\n {/if}\n</li>\n","export const VTMN_SEARCH_VARIANT = {\n DEFAULT: 'default',\n PERSISTENT: 'persistent',\n ON_CONTENT: 'on-content',\n};\n\nexport const VTMN_SEARCH_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n\n import VtmnButton from '../../actions/VtmnButton/VtmnButton.svelte';\n import { createEventDispatcher } from 'svelte';\n import { VTMN_SEARCH_VARIANT, VTMN_SEARCH_SIZE } from './enums';\n\n /** @restProps { button } */\n\n /**\n * The variant of the button.\n * @type {'default' | 'persistent' | 'on-content'}\n * @defaultValue 'default'\n */\n export let variant = VTMN_SEARCH_VARIANT.DEFAULT;\n\n /**\n * @type {boolean} disabled.\n * @defaultValue false\n */\n export let disabled = false;\n\n /**\n * @type {boolean} Displays the search button.\n * @defaultValue true\n */\n export let showSearchButton = true;\n\n /**\n * @type {'small' | 'medium'}\n * @defaultValue 'medium'\n */\n export let size = VTMN_SEARCH_SIZE.MEDIUM;\n\n /**\n * The value of the input\n * @type {string}\n */\n export let value;\n\n /**\n * Reference of the search input\n * @type {HTMLElement}\n */\n export let inputRef;\n\n /**\n * @typedef AriaLabels\n * @type {object}\n * @property {string} clearButton - Aria label of the clear button.\n * @property {string} searchButton - Aria label of the search button.\n */\n\n /**\n * @type {AriaLabels} Aria labels of the component.\n */\n export let ariaLabels = {};\n\n let className = undefined;\n /**\n * Custom classes to apply to the component.\n *\n * @type {string}\n */\n export { className as class };\n\n const dispatch = createEventDispatcher();\n\n const resetInputValue = () => {\n value = '';\n };\n\n const onSearch = () => {\n dispatch('search', {\n text: value,\n });\n };\n\n $: componentClass = cn(\n 'vtmn-search',\n variant && `vtmn-search_variant--${variant}`,\n size && `vtmn-search_size--${size}`,\n className,\n );\n</script>\n\n<div class={componentClass} role=\"search\">\n <input\n type=\"search\"\n bind:this={inputRef}\n {...$$restProps}\n on:click\n on:input\n on:mouseover\n on:mouseenter\n on:mouseout\n on:focus\n on:blur\n on:keydown\n on:keypress\n on:keyup\n bind:value\n {disabled}\n />\n\n <div class=\"vtmn-search_buttons\">\n {#if value}\n <VtmnButton\n iconAlone=\"close-line\"\n variant=\"ghost\"\n {disabled}\n {size}\n on:click={resetInputValue}\n aria-label={ariaLabels.clearButton}\n aria-disabled={disabled}\n />\n {/if}\n\n {#if showSearchButton}\n <VtmnButton\n iconAlone=\"search-line\"\n variant=\"ghost\"\n {disabled}\n {size}\n on:click={onSearch}\n type=\"submit\"\n aria-label={ariaLabels.searchButton}\n />\n {/if}\n </div>\n</div>\n\n<style lang=\"css\">\n @import '@vtmn/css-search';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n\n /** @restProps { button } */\n\n let className = undefined;\n /**\n * Custom classes to apply to the component.\n *\n * @type {string}\n */\n export { className as class };\n\n $: componentClass = cn('vtmn-navbar', className);\n\n /**\n * Delete slot div from de DOM if slot doesn't exist.\n *\n * @param {'left-nav' | 'logo' | 'middle-area' | 'right-nav'} slotName\n * @returns {boolean} slotExists\n */\n const checkSlotExists = (slotName) => {\n return $$slots[slotName];\n };\n</script>\n\n<nav class={componentClass} aria-label=\"navbar\" {...$$restProps}>\n {#if checkSlotExists('left-nav')}\n <div class=\"vtmn-navbar_left-navigation\">\n <slot name=\"left-nav\" />\n </div>\n {/if}\n\n {#if checkSlotExists('logo')}\n <div class=\"vtmn-navbar_logo\">\n <slot name=\"logo\" />\n </div>\n {/if}\n\n {#if checkSlotExists('middle-area')}\n <div class=\"vtmn-navbar_middle-area\">\n <slot name=\"middle-area\" />\n </div>\n {/if}\n\n {#if checkSlotExists('right-nav')}\n <div class=\"vtmn-navbar_right-navigation\">\n <slot name=\"right-nav\" />\n </div>\n {/if}\n</nav>\n\n<style lang=\"css\">\n @import '@vtmn/css-navbar';\n</style>\n","<script>\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n import { cn } from '../../../utils/classnames';\n import { computeRel } from '../../../utils/link';\n\n /** @restProps { a } */\n\n /**\n * Icon of the navbar link.\n * @type {string}\n * @defaultValue undefined\n */\n export let icon;\n\n let className = undefined;\n /**\n * Custom classes to apply to the component.\n *\n * @type {string}\n */\n export { className as class };\n\n $: componentClass = cn('vtmn-navbar_link', className);\n let computedRel = computeRel($$restProps['target'], $$restProps['rel']);\n</script>\n\n<!-- svelte-ignore a11y-missing-attribute -->\n<!-- because href comes through $$restProps -->\n<a\n class={componentClass}\n {...$$restProps}\n rel={computedRel}\n on:click\n on:mouseover\n on:mouseenter\n on:mouseout\n on:focus\n on:blur\n on:keydown\n>\n <div class=\"vtmn-relative\">\n <slot name=\"badge\" />\n <VtmnIcon value={icon} aria-hidden=\"true\" />\n </div>\n <slot />\n</a>\n","export const VTMN_TABS_ALIGN = {\n START: 'start',\n CENTER: 'center',\n END: 'end',\n};\n\nexport const VTMN_TABS_SIZE = {\n SMALL: 'small',\n MEDIUM: 'medium',\n};\n","<script>\n import { cn } from '../../../utils/classnames';\n import VtmnDivider from '../../structure/VtmnDivider/VtmnDivider.svelte';\n import { VTMN_TABS_ALIGN, VTMN_TABS_SIZE } from './enums';\n\n /**\n * @type {'start' | 'center' | 'end'}\n * @defaultValue 'start'\n */\n export let align = VTMN_TABS_ALIGN.START;\n\n /**\n * @type {'small' | 'medium'}\n * @defaultValue 'medium'\n */\n export let size = VTMN_TABS_SIZE.MEDIUM;\n\n /**\n * Custom classes to apply to the component.\n * @type {string}\n */\n export let className = '';\n\n $: componentClass = cn(\n 'vtmn-tabs',\n align && `vtmn-tabs_align--${align}`,\n size && `vtmn-tabs_size--${size}`,\n className,\n );\n</script>\n\n<ul class={componentClass} role=\"tablist\" {...$$restProps}>\n <slot />\n</ul>\n<VtmnDivider />\n\n<style lang=\"css\">\n @import '@vtmn/css-tabs';\n</style>\n","<script>\n import { cn } from '../../../utils/classnames';\n import VtmnBadge from '../../indicators/VtmnBadge/VtmnBadge.svelte';\n import VtmnIcon from '../../../guidelines/iconography/VtmnIcon/VtmnIcon.svelte';\n export let badgeValue = undefined;\n export let icon = undefined;\n export let selected = false;\n\n $: componentClass = cn(selected && 'selected');\n</script>\n\n<li>\n <button\n class={componentClass}\n role=\"tab\"\n {...$$restProps}\n on:click|preventDefault\n on:mouseover\n on:mouseenter\n on:mouseout\n on:focus\n on:blur\n on:keydown\n >\n {#if icon}\n <VtmnIcon value={icon} aria-hidden=\"true\" />\n {/if}\n <slot />\n {#if badgeValue}\n <VtmnBadge value={badgeValue} />\n {/if}\n </button>\n</li>\n","export const VTMN_ALERT_TIMEOUT = 8000;\n\nexport const CSS_ANIMATION_TIME_MS = 700;\n\nexport const INFINITE_TIMEOUT_MS = 9999000;\n\nexport const VTMN_ALERT_VARIANT = {\n INFO: 'info',\n WARNING: 'warning',\n SUCCESS: 'success',\n DANGER: 'danger',\n};\n","import { writable } from 'svelte/store';\nimport { uuid } from '../../../utils/math';\n\nclass VtmnAlertStore {\n constructor() {\n this._alerts = writable([]);\n }\n\n send({\n variant,\n title,\n description,\n withCloseButton,\n ariaLabelCloseButton,\n ...attributes\n }) {\n this._alerts.update((state) => [\n ...state,\n {\n ...attributes,\n variant,\n title,\n description,\n withCloseButton,\n ariaLabelCloseButton,\n id: `vtmn-alert-${uuid()}`,\n },\n ]);\n }\n\n close(alertId) {\n this._alerts.update((n) => {\n return n.filter((i) => i.id !== alertId);\n });\n }\n\n subscribe(run) {\n return this._alerts.subscribe(run);\n }\n}\n\nexport const vtmnAlertStore = new VtmnAlertStore();\n","<script>\n import VtmnButton from '../../actions/VtmnButton/VtmnButton.svelte';\n import { createEventDispatcher, onDestroy, onMount } from 'svelte';\n import { cn } from '../../../utils/classnames';\n import {\n VTMN_ALERT_TIMEOUT,\n VTMN_ALERT_VARIANT,\n CSS_ANIMATION_TIME_MS,\n INFINITE_TIMEOUT_MS,\n } from './enums';\n\n /**\n * @type {'info'|'success'|'danger'|'warning'} variant of the alert\n * @defaultValue info\n */\n export let variant = VTMN_ALERT_VARIANT.INFO;\n\n /**\n * @type {string} title of the alert\n * Can also be set with a slot=\"title\"\n */\n export let title = undefined;\n\n /**\n * @type {string} description of the alert\n * Can also be set with a slot=\"description\"\n */\n export let description = undefined;\n\n /**\n * @type {boolean} display with a close button\n */\n export let withCloseButton = false;\n\n /**\n * @type {number} time (ms) before the alert disappears\n * Set to Infinity to keep the alert visible\n */\n export let timeout = VTMN_ALERT_TIMEOUT;\n\n /**\n * @type {string} aria label on the button\n */\n export let ariaLabelCloseButton = 'Close alert';\n\n let className = undefined;\n /**\n * @type {string} Custom classes to apply to the component.\n */\n export { className as class };\n let timeoutId;\n const dispatch = createEventDispatcher();\n const closeHandler = () => dispatch('close');\n const _clearTimeout = () => timeoutId && clearTimeout(timeoutId);\n const _setTimeout = () =>\n (timeoutId =\n typeof timeout === 'number' &&\n timeout > 0 &&\n setTimeout(\n closeHandler,\n (timeout < Infinity ? timeout : INFINITE_TIMEOUT_MS) +\n CSS_ANIMATION_TIME_MS,\n ));\n onDestroy(_clearTimeout);\n onMount(_setTimeout);\n\n $: componentClass = cn(\n 'vtmn-alert',\n typeof timeout === 'number' && timeout > 0 && 'show animate-delay',\n variant && `vtmn-alert_variant--${variant}`,\n className,\n );\n</script>\n\n<div\n class={componentClass}\n style:--vtmn-animation_alert-duration={typeof timeout === 'number' &&\n timeout < Infinity\n ? `${timeout}ms`\n : `${INFINITE_TIMEOUT_MS}ms`}\n role=\"alert\"\n tabindex=\"-1\"\n {...$$restProps}\n>\n <div class=\"vtmn-alert_content\" role=\"document\">\n <div class=\"vtmn-alert_content-title\">\n {#if $$slots.title}\n <slot name=\"title\" />\n {:else}\n