@feugene/granularity 0.5.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{adapter-K6zZTzBi.js.map → adapter-CRyH4YC8.js.map} +1 -1
- package/dist/chunks/{config-Cgk5ti-b.js.map → config-3SftO0uG.js.map} +1 -1
- package/dist/chunks/{config-BN-B2K4r.js.map → config-B44QVIge.js.map} +1 -1
- package/dist/chunks/{config-C-GVBa19.js.map → config-B8rC_K97.js.map} +1 -1
- package/dist/chunks/{config-DEv4m-ZP.js.map → config-BXffa3ta.js.map} +1 -1
- package/dist/chunks/{config-CUgvsjZx.js.map → config-BhvNm4Pp.js.map} +1 -1
- package/dist/chunks/{config-BNOf_qjD.js.map → config-C0b_3LJV.js.map} +1 -1
- package/dist/chunks/config-C0rHS1-l.js.map +1 -0
- package/dist/chunks/{config-fCcRwjIB.js.map → config-C4qAA0Sb.js.map} +1 -1
- package/dist/chunks/{config-XwI6t8cn.js.map → config-C5TN9J2Z.js.map} +1 -1
- package/dist/chunks/config-CVnluhKO.js.map +1 -0
- package/dist/chunks/{config-DUtUkSzc.js.map → config-CjEplP6D.js.map} +1 -1
- package/dist/chunks/{config-D19pyP4D.js.map → config-CtomKf-k.js.map} +1 -1
- package/dist/chunks/{config-BvuQUBtZ.js.map → config-CxCAfXZ1.js.map} +1 -1
- package/dist/chunks/{config-BDiLiqSk.js.map → config-D1DI3roo.js.map} +1 -1
- package/dist/chunks/{config-CgjOJ3aF.js.map → config-D27BL0H9.js.map} +1 -1
- package/dist/chunks/config-D32znLtV2.js.map +1 -0
- package/dist/chunks/{config-YSOeh6cy.js.map → config-D6Af6WZw.js.map} +1 -1
- package/dist/chunks/{config-BulF0Bf-.js.map → config-D98m8iyz.js.map} +1 -1
- package/dist/chunks/config-DDLoUczC.js.map +1 -0
- package/dist/chunks/{config-CFcv0hjb.js.map → config-DQOSlWvp.js.map} +1 -1
- package/dist/chunks/{config-ndXqsz5A.js.map → config-DbqFk-IW.js.map} +1 -1
- package/dist/chunks/{config-CdHY0Z7L.js.map → config-DnsISjD8.js.map} +1 -1
- package/dist/chunks/{config-BFZN9-vt.js.map → config-DudL02ag.js.map} +1 -1
- package/dist/chunks/{config-DgRJlF00.js.map → config-Dusr9jcE.js.map} +1 -1
- package/dist/chunks/{config-CWvHiaqr2.js.map → config-DxqMXzNV2.js.map} +1 -1
- package/dist/chunks/config-Mp9DJ9Mq2.js.map +1 -0
- package/dist/chunks/{config-R0jaXatX.js → config-XoANT5mU.js} +1 -1
- package/dist/chunks/{config-R0jaXatX.js.map → config-XoANT5mU.js.map} +1 -1
- package/dist/chunks/config-ZJVOVgqR.js +22 -0
- package/dist/chunks/config-ZJVOVgqR.js.map +1 -0
- package/dist/chunks/{config-CM7nbATU2.js.map → config-rxFL-6yF2.js.map} +1 -1
- package/dist/chunks/{config-bpQYM5O-.js.map → config-wo-ncgTH.js.map} +1 -1
- package/dist/chunks/{en-BeJa78lP.js.map → en-BMjJZttK.js.map} +1 -1
- package/dist/chunks/{es-BPqm7rLm.js → es-Cu_RlgIr.js} +3 -3
- package/dist/chunks/{es-BPqm7rLm.js.map → es-Cu_RlgIr.js.map} +1 -1
- package/dist/chunks/{es-axYOwwWD.js.map → es-EYCf8G_1.js.map} +1 -1
- package/dist/chunks/{grSelectStyles-daEeDlBn.js.map → grSelectStyles-DTAYNzxn.js.map} +1 -1
- package/dist/chunks/grStyle-5EMYYctb.js +19 -0
- package/dist/chunks/grStyle-5EMYYctb.js.map +1 -0
- package/dist/chunks/{granularityI18n-GCqUz_lo.js → granularityI18n-Dm4DuCS9.js} +1 -1
- package/dist/chunks/{granularityI18n-GCqUz_lo.js.map → granularityI18n-Dm4DuCS9.js.map} +1 -1
- package/dist/chunks/{ru-Dqh-2C00.js.map → ru-DKswMSdd.js.map} +1 -1
- package/dist/chunks/{shared-CyCPkimZ.js → shared-DO3Sr5FJ.js} +30 -30
- package/dist/chunks/{shared-CyCPkimZ.js.map → shared-DO3Sr5FJ.js.map} +1 -1
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-u01j9S0t.js → GrFileUpload-DYRERhI2.js} +258 -37
- package/dist/components/GrFileUpload/chunks/GrFileUpload-DYRERhI2.js.map +1 -0
- package/dist/components/GrFileUpload/index.js +3 -3
- package/dist/components/GrFormField/chunks/{GrFormField-C6PfAs4u.js.map → GrFormField-C1oWTT_0.js.map} +1 -1
- package/dist/components/GrFormField/index.js +2 -2
- package/dist/components/GrFormFile/chunks/{GrFormFile-DdM8Bc2B.js.map → GrFormFile-deDPicM2.js.map} +1 -1
- package/dist/components/GrFormFile/index.js +2 -2
- package/dist/components/GrFormSection/chunks/{GrFormSection-5djEaQZQ.js.map → GrFormSection-CWBk2EUm.js.map} +1 -1
- package/dist/components/GrFormSection/index.js +2 -2
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-CjSnohW7.js.map → GrImageViewer-Cpj5zyZQ.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +2 -2
- package/dist/components/GrInput/chunks/{GrInput-ghxaTf6d.js.map → GrInput-CfO2RsM-.js.map} +1 -1
- package/dist/components/GrInput/index.js +2 -2
- package/dist/components/GrInputTag/chunks/{GrInputTag-B0x4U0Yk.js → GrInputTag-G_VYJPF9.js} +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-B0x4U0Yk.js.map → GrInputTag-G_VYJPF9.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +2 -2
- package/dist/components/GrLink/chunks/{GrLink-DvvNkP0M.js → GrLink-BLPigqij.js} +1 -1
- package/dist/components/GrLink/chunks/{GrLink-DvvNkP0M.js.map → GrLink-BLPigqij.js.map} +1 -1
- package/dist/components/GrLink/index.js +2 -2
- package/dist/components/GrList/chunks/{GrList--Ib4zLNw.js.map → GrList-BPjQf-72.js.map} +1 -1
- package/dist/components/GrList/index.js +2 -2
- package/dist/components/GrLoading/index.js +1 -1
- package/dist/components/GrModal/index.js +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-nIyuiVj1.js → GrNavbar-BDIKAYfN.js} +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-nIyuiVj1.js.map → GrNavbar-BDIKAYfN.js.map} +1 -1
- package/dist/components/GrNavbar/index.js +2 -2
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-B0mPLjdv.js → GrNumberInput-ECtFCIKV.js} +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-B0mPLjdv.js.map → GrNumberInput-ECtFCIKV.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-C_rxGwfY.js → GrPagination-BZlH-uEd.js} +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-C_rxGwfY.js.map → GrPagination-BZlH-uEd.js.map} +1 -1
- package/dist/components/GrPagination/index.js +2 -2
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-MvMnzsJl.js → GrProgressBar-hQQK8cYh.js} +1 -1
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-MvMnzsJl.js.map → GrProgressBar-hQQK8cYh.js.map} +1 -1
- package/dist/components/GrProgressBar/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-DKhbN6ji.js → GrPromptDialog-CUMW6_58.js} +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-DKhbN6ji.js.map → GrPromptDialog-CUMW6_58.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +2 -2
- package/dist/components/GrRadio/chunks/{GrRadio-BxBs3WHq.js → GrRadio-B_t_ZNVl.js} +1 -1
- package/dist/components/GrRadio/chunks/{GrRadio-BxBs3WHq.js.map → GrRadio-B_t_ZNVl.js.map} +1 -1
- package/dist/components/GrRadio/index.js +2 -2
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-CEAfJQ6A.js → GrRadioGroup-CVlgpUBr.js} +1 -1
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-CEAfJQ6A.js.map → GrRadioGroup-CVlgpUBr.js.map} +1 -1
- package/dist/components/GrRadioGroup/index.js +2 -2
- package/dist/components/GrSegmented/chunks/{GrSegmented-Bwn2qOY4.js → GrSegmented-BPl1koHc.js} +1 -1
- package/dist/components/GrSegmented/chunks/{GrSegmented-Bwn2qOY4.js.map → GrSegmented-BPl1koHc.js.map} +1 -1
- package/dist/components/GrSegmented/index.js +2 -2
- package/dist/components/GrSelect/chunks/{GrSelect-BMMT5MrT.js → GrSelect-C3NAfTqL.js} +2 -2
- package/dist/components/GrSelect/chunks/{GrSelect-BMMT5MrT.js.map → GrSelect-C3NAfTqL.js.map} +1 -1
- package/dist/components/GrSelect/index.js +2 -2
- package/dist/components/GrSidebar/chunks/{GrSidebar-CSZ3RpFB.js.map → GrSidebar-DVucgcfV.js.map} +1 -1
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSkeleton/chunks/{GrSkeleton-DKXkqWDa.js.map → GrSkeleton-CDTvCSoH.js.map} +1 -1
- package/dist/components/GrSkeleton/index.js +2 -2
- package/dist/components/GrSwitch/chunks/{GrSwitch-CdBxwV3k.js → GrSwitch-Bnamgqb2.js} +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-CdBxwV3k.js.map → GrSwitch-Bnamgqb2.js.map} +1 -1
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTable/index.js +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-BpF8AAUz.js.map → GrTabs-CiGmcmvm.js.map} +1 -1
- package/dist/components/GrTabs/index.js +2 -2
- package/dist/components/GrTextarea/chunks/{GrTextarea-DFS9ZkrA.js → GrTextarea-VBSc6A7D.js} +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-DFS9ZkrA.js.map → GrTextarea-VBSc6A7D.js.map} +1 -1
- package/dist/components/GrTextarea/index.js +2 -2
- package/dist/components/GrToaster/chunks/{GrToaster-3Mf0Moxt.js → GrToaster-I1e-zCpf.js} +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-3Mf0Moxt.js.map → GrToaster-I1e-zCpf.js.map} +1 -1
- package/dist/components/GrToaster/index.js +2 -2
- package/dist/components/GrTooltip/chunks/{GrTooltip-BvmsukLW.js.map → GrTooltip-CrV1gI_c.js.map} +1 -1
- package/dist/components/GrTooltip/index.js +2 -2
- package/dist/components/GrTree/chunks/{GrTree-C2kN-O4Q.js.map → GrTree-Dlev9oBd.js.map} +1 -1
- package/dist/components/GrTree/index.js +2 -2
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-N-oPAOFj.js → GrTreeSelect-n0CZT4Ic.js} +4 -4
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-N-oPAOFj.js.map → GrTreeSelect-n0CZT4Ic.js.map} +1 -1
- package/dist/components/GrTreeSelect/index.js +2 -2
- package/dist/directives/loading.js +15 -0
- package/dist/directives/loading.js.map +1 -1
- package/dist/granular-provider-node.js +2 -2
- package/dist/granular-provider.js +1 -1
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/index.js +59 -58
- package/dist/index.js.map +1 -1
- package/dist/types/src/components/GrFileUpload/GrFileUpload.vue.d.ts +58 -5
- package/dist/types/src/components/GrFileUpload/index.d.ts +4 -0
- package/dist/types/src/components/GrFileUpload/uploadState.d.ts +38 -0
- package/dist/types/src/components/GrFileUpload/uploadViaXhr.d.ts +33 -0
- package/dist/types/src/components/GrImageViewer/GrImageViewer.vue.d.ts +1 -1
- package/dist/types/src/components/GrInput/GrInput.vue.d.ts +1 -1
- package/dist/types/src/components/GrNumberInput/GrNumberInput.vue.d.ts +1 -1
- package/dist/types/src/components/GrTextarea/GrTextarea.vue.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunks/config-BGmiXpR82.js.map +0 -1
- package/dist/chunks/config-CA9XwYnZ2.js.map +0 -1
- package/dist/chunks/config-CsMIhZfM.js.map +0 -1
- package/dist/chunks/config-CwLoozAz2.js.map +0 -1
- package/dist/chunks/config-DCQO6H6h.js.map +0 -1
- package/dist/chunks/config-Da90XGsi.js +0 -38
- package/dist/chunks/config-Da90XGsi.js.map +0 -1
- package/dist/components/GrFileUpload/chunks/GrFileUpload-u01j9S0t.js.map +0 -1
- /package/dist/chunks/{adapter-K6zZTzBi.js → adapter-CRyH4YC8.js} +0 -0
- /package/dist/chunks/{config-Cgk5ti-b.js → config-3SftO0uG.js} +0 -0
- /package/dist/chunks/{config-BN-B2K4r.js → config-B44QVIge.js} +0 -0
- /package/dist/chunks/{config-C-GVBa19.js → config-B8rC_K97.js} +0 -0
- /package/dist/chunks/{config-DEv4m-ZP.js → config-BXffa3ta.js} +0 -0
- /package/dist/chunks/{config-CUgvsjZx.js → config-BhvNm4Pp.js} +0 -0
- /package/dist/chunks/{config-BNOf_qjD.js → config-C0b_3LJV.js} +0 -0
- /package/dist/chunks/{config-CA9XwYnZ2.js → config-C0rHS1-l.js} +0 -0
- /package/dist/chunks/{config-fCcRwjIB.js → config-C4qAA0Sb.js} +0 -0
- /package/dist/chunks/{config-XwI6t8cn.js → config-C5TN9J2Z.js} +0 -0
- /package/dist/chunks/{config-BGmiXpR82.js → config-CVnluhKO.js} +0 -0
- /package/dist/chunks/{config-DUtUkSzc.js → config-CjEplP6D.js} +0 -0
- /package/dist/chunks/{config-D19pyP4D.js → config-CtomKf-k.js} +0 -0
- /package/dist/chunks/{config-BvuQUBtZ.js → config-CxCAfXZ1.js} +0 -0
- /package/dist/chunks/{config-BDiLiqSk.js → config-D1DI3roo.js} +0 -0
- /package/dist/chunks/{config-CgjOJ3aF.js → config-D27BL0H9.js} +0 -0
- /package/dist/chunks/{config-DCQO6H6h.js → config-D32znLtV2.js} +0 -0
- /package/dist/chunks/{config-YSOeh6cy.js → config-D6Af6WZw.js} +0 -0
- /package/dist/chunks/{config-BulF0Bf-.js → config-D98m8iyz.js} +0 -0
- /package/dist/chunks/{config-CwLoozAz2.js → config-DDLoUczC.js} +0 -0
- /package/dist/chunks/{config-CFcv0hjb.js → config-DQOSlWvp.js} +0 -0
- /package/dist/chunks/{config-ndXqsz5A.js → config-DbqFk-IW.js} +0 -0
- /package/dist/chunks/{config-CdHY0Z7L.js → config-DnsISjD8.js} +0 -0
- /package/dist/chunks/{config-BFZN9-vt.js → config-DudL02ag.js} +0 -0
- /package/dist/chunks/{config-DgRJlF00.js → config-Dusr9jcE.js} +0 -0
- /package/dist/chunks/{config-CWvHiaqr2.js → config-DxqMXzNV2.js} +0 -0
- /package/dist/chunks/{config-CsMIhZfM.js → config-Mp9DJ9Mq2.js} +0 -0
- /package/dist/chunks/{config-CM7nbATU2.js → config-rxFL-6yF2.js} +0 -0
- /package/dist/chunks/{config-bpQYM5O-.js → config-wo-ncgTH.js} +0 -0
- /package/dist/chunks/{en-BeJa78lP.js → en-BMjJZttK.js} +0 -0
- /package/dist/chunks/{es-axYOwwWD.js → es-EYCf8G_1.js} +0 -0
- /package/dist/chunks/{grSelectStyles-daEeDlBn.js → grSelectStyles-DTAYNzxn.js} +0 -0
- /package/dist/chunks/{ru-Dqh-2C00.js → ru-DKswMSdd.js} +0 -0
- /package/dist/components/GrFormField/chunks/{GrFormField-C6PfAs4u.js → GrFormField-C1oWTT_0.js} +0 -0
- /package/dist/components/GrFormFile/chunks/{GrFormFile-DdM8Bc2B.js → GrFormFile-deDPicM2.js} +0 -0
- /package/dist/components/GrFormSection/chunks/{GrFormSection-5djEaQZQ.js → GrFormSection-CWBk2EUm.js} +0 -0
- /package/dist/components/GrImageViewer/chunks/{GrImageViewer-CjSnohW7.js → GrImageViewer-Cpj5zyZQ.js} +0 -0
- /package/dist/components/GrInput/chunks/{GrInput-ghxaTf6d.js → GrInput-CfO2RsM-.js} +0 -0
- /package/dist/components/GrList/chunks/{GrList--Ib4zLNw.js → GrList-BPjQf-72.js} +0 -0
- /package/dist/components/GrSidebar/chunks/{GrSidebar-CSZ3RpFB.js → GrSidebar-DVucgcfV.js} +0 -0
- /package/dist/components/GrSkeleton/chunks/{GrSkeleton-DKXkqWDa.js → GrSkeleton-CDTvCSoH.js} +0 -0
- /package/dist/components/GrTabs/chunks/{GrTabs-BpF8AAUz.js → GrTabs-CiGmcmvm.js} +0 -0
- /package/dist/components/GrTooltip/chunks/{GrTooltip-BvmsukLW.js → GrTooltip-CrV1gI_c.js} +0 -0
- /package/dist/components/GrTree/chunks/{GrTree-C2kN-O4Q.js → GrTree-Dlev9oBd.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrInput-ghxaTf6d.js","names":["$slots","$attrs"],"sources":["../../../../src/components/GrInput/GrInput.vue","../../../../src/components/GrInput/GrInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"className\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"className\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrInput-CfO2RsM-.js","names":["$slots","$attrs"],"sources":["../../../../src/components/GrInput/GrInput.vue","../../../../src/components/GrInput/GrInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"className\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"className\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWA,MAAM,QAAQ;EA0Cd,MAAM,OAAO;EAIb,MAAM,UAAU,IAA6B,KAAI;EAEjD,SAAS,QAAc;AACrB,WAAQ,OAAO,OAAM;;AAGvB,WAAa,EACX,OACD,CAAA;EAED,MAAM,QAAQ,UAAS;EAEvB,MAAM,YAAY,eAAe,QAAQ,MAAM,OAAO,CAAA;EACtD,MAAM,YAAY,eAAe,QAAQ,MAAM,OAAO,CAAA;EAEtD,MAAM,uBAAuB,eAAe;AAQ1C,UAP4D;IAC1D,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACN,CAEW,MAAM;IAClB;EAED,MAAM,iBAAiB,eAAe,MAAM,kBAAkB,qBAAqB,MAAK;EACxF,MAAM,iBAAiB,eAAe,MAAM,kBAAkB,qBAAqB,MAAK;EAExF,MAAM,WAAW,IAAwB,KAAI;EAC7C,MAAM,WAAW,IAAwB,KAAI;EAE7C,MAAM,sBAAsB,IAAwB,KAAA,EAAS;EAC7D,MAAM,sBAAsB,IAAwB,KAAA,EAAS;EAE7D,IAAI,KAA4B;EAChC,IAAI,YAAY;EAEhB,SAAS,YAAY,IAA4C;AAC/D,OAAI,CAAC,GAAI,QAAO,KAAA;GAEhB,MAAM,QAAQ,KAAK,KAAK,GAAG,uBAAuB,CAAC,SAAS,EAAC;AAE7D,OAAI,SAAS,EAAG,QAAO,KAAA;AAEvB,UAAO,GAAG,MAAM;;EAGlB,SAAS,UAAgB;AACvB,uBAAoB,QAAQ,UAAU,QAAQ,YAAY,SAAS,MAAM,GAAG,KAAA;AAC5E,uBAAoB,QAAQ,UAAU,QAAQ,YAAY,SAAS,MAAM,GAAG,KAAA;;EAG9E,SAAS,kBAAwB;AAC/B,OAAI,OAAO,mBAAmB,YAAa;AAC3C,OAAI,CAAC,GAAI,MAAK,IAAI,qBAAqB,SAAS,CAAA;AAEhD,MAAG,YAAW;AACd,OAAI,SAAS,MAAO,IAAG,QAAQ,SAAS,MAAK;AAC7C,OAAI,SAAS,MAAO,IAAG,QAAQ,SAAS,MAAK;;EAG/C,SAAS,kBAAwB;AAC/B,OAAI,UAAW;AACf,eAAY;AAEP,kBAAe;AAClB,gBAAY;AACZ,aAAQ;AACR,qBAAgB;KACjB;;AAGH,kBAAgB,iBAAiB,CAAA;AACjC,kBAAgB,iBAAiB,CAAA;AACjC,wBAAsB,IAAI,YAAY,CAAA;EAEtC,SAAS,OAAO,GAAW,GAAmB;AAC5C,OAAI,MAAM,MAAO,QAAO;AACxB,OAAI,MAAM,MAAO,QAAO;GAExB,MAAM,MAAM,EAAE,SAAS,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG;GACxD,MAAM,MAAM,EAAE,SAAS,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG;AAExD,OAAI,QAAQ,QAAQ,OAAO,SAAS,IAAI,IAAI,QAAQ,QAAQ,OAAO,SAAS,IAAI,CAC9E,QAAO,GAAG,MAAM,IAAI;AAGtB,UAAO,QAAQ,EAAE,KAAK,EAAE;;EAG1B,MAAM,kBAAkB,eAAe;AASrC,UAP4D;IAC1D,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACN,CAEW,MAAM;IAClB;EAED,MAAM,aAAa,eAAe;GAChC,MAAM,eAAe,UAAU,QAAQ,oBAAoB,SAAS,eAAe,QAAQ;GAC3F,MAAM,gBAAgB,UAAU,QAAQ,oBAAoB,SAAS,eAAe,QAAQ;AAM5F,UAAO;IACL,aAJW,UAAU,QAAQ,OAAO,cAAc,gBAAgB,MAAM,GAAG,KAAA;IAK3E,cAJY,UAAU,QAAQ,OAAO,eAAe,gBAAgB,MAAM,GAAG,KAAA;IAK9E;IACF;EAED,MAAM,cAAc,eAAe;AACjC,UAAO;IACL,UAAU,eAAe;IACzB,UAAU,MAAM;IACjB;IACF;EAED,MAAM,cAAc,eAAe;AACjC,UAAO;IACL,UAAU,eAAe;IACzB,UAAU,MAAM;IACjB;IACF;EAED,MAAM,YAAY,eAAe;AAQ/B,UAP4D;IAC1D,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACN,CAEW,MAAM;IAClB;EAED,MAAM,iBAAiB,eAAe;AAOpC,UANiE;IAC/D,MAAM;IACN,QAAQ;IACR,OAAO;IACT,CAEW,MAAM;IAClB;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,QAAQ,MAAM;GAEpB,MAAM,gBAA8C;IAClD,SAAS;IACT,SAAS;IACT,SAAS;IACT,QAAQ;IACV;AAEA,UAAO;IACL,UAAU;IACV,eAAe;IACf,MAAM,UAAU,cAAc,SAAS,cAAc;IACtD,CAAC,KAAK,IAAG;IACX;EAED,SAAS,QAAQ,GAAgB;AAC/B,QAAK,qBAAsB,EAAE,OAA4B,MAAK;;;uBAK9D,mBAwCM,OAxCN,YAwCM;IAtCMA,KAAAA,OAAO,UAAA,WAAA,EADjB,mBASM,OAAA;;cAPE;KAAJ,KAAI;KACJ,eAAY;KACZ,OAAM;KACL,OAAK,eAAE,YAAA,MAAW;KACnB,eAAY;QAEd,WAAsB,KAAA,QAAA,SAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA;IAGxB,mBAgBC,SAhBD,WAgBC;KAfI,IAAI,MAAM;cACP;KAAJ,KAAI;OACIC,KAAAA,QAAM;KACb,MAAM,MAAM;KACZ,MAAM,MAAM;KACZ,WAAW,MAAM;KACjB,cAAc,MAAM;KACpB,aAAa,MAAM;KACnB,UAAU,MAAM;KAChB,OAAO,MAAM;KACb,gBAAc,MAAM,UAAO,SAAY,KAAA;KACxC,OAAK,CAAC,0RACE,UAAA,MAAS;KAChB,OAAO,WAAA;KACA;;IAIFD,KAAAA,OAAO,UAAA,WAAA,EADjB,mBASM,OAAA;;cAPE;KAAJ,KAAI;KACJ,eAAY;KACZ,OAAM;KACL,OAAK,eAAE,YAAA,MAAW;KACnB,eAAY;QAEd,WAAsB,KAAA,QAAA,SAAA,CAAA,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrInput_default } from "./chunks/GrInput-
|
|
2
|
-
import { n as grInputSafelist, t as grInputConfig } from "../../chunks/config-
|
|
1
|
+
import { t as GrInput_default } from "./chunks/GrInput-CfO2RsM-.js";
|
|
2
|
+
import { n as grInputSafelist, t as grInputConfig } from "../../chunks/config-CtomKf-k.js";
|
|
3
3
|
export { GrInput_default as GrInput, GrInput_default as default, grInputConfig, grInputSafelist };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as x_default } from "../../../chunks/x-Pa6C2hwi.js";
|
|
2
2
|
import { t as GrBadge_default } from "../../GrBadge/chunks/GrBadge-wuIb4_2K.js";
|
|
3
3
|
import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BV7RBU_0.js";
|
|
4
|
-
import { i as grInputTagWrapperClass, r as grInputTagInputClass } from "../../../chunks/config-
|
|
4
|
+
import { i as grInputTagWrapperClass, r as grInputTagInputClass } from "../../../chunks/config-Dusr9jcE.js";
|
|
5
5
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, renderList, renderSlot, toDisplayString, unref, withCtx, withModifiers } from "vue";
|
|
6
6
|
//#region src/components/GrInputTag/GrInputTag.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var _hoisted_1 = { class: "truncate max-w-[18rem]" };
|
package/dist/components/GrInputTag/chunks/{GrInputTag-B0x4U0Yk.js.map → GrInputTag-G_VYJPF9.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrInputTag-B0x4U0Yk.js","names":[],"sources":["../../../../src/components/GrInputTag/GrInputTag.vue","../../../../src/components/GrInputTag/GrInputTag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrInputTag-G_VYJPF9.js","names":[],"sources":["../../../../src/components/GrInputTag/GrInputTag.vue","../../../../src/components/GrInputTag/GrInputTag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as grInputTagSafelist, t as grInputTagConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrInputTag_default } from "./chunks/GrInputTag-
|
|
1
|
+
import { n as grInputTagSafelist, t as grInputTagConfig } from "../../chunks/config-Dusr9jcE.js";
|
|
2
|
+
import { t as GrInputTag_default } from "./chunks/GrInputTag-G_VYJPF9.js";
|
|
3
3
|
export { GrInputTag_default as GrInputTag, GrInputTag_default as default, grInputTagConfig, grInputTagSafelist };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as grLinkClass, i as focusRingClass, r as baseRootClass } from "../../../chunks/config-
|
|
1
|
+
import { a as grLinkClass, i as focusRingClass, r as baseRootClass } from "../../../chunks/config-CjEplP6D.js";
|
|
2
2
|
import { computed, createBlock, defineComponent, markRaw, mergeProps, openBlock, renderSlot, resolveDynamicComponent, unref, useAttrs, withCtx } from "vue";
|
|
3
3
|
//#endregion
|
|
4
4
|
//#region src/components/GrLink/GrLink.vue
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrLink-
|
|
1
|
+
{"version":3,"file":"GrLink-BLPigqij.js","names":[],"sources":["../../../../src/components/GrLink/GrLink.vue","../../../../src/components/GrLink/GrLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ;EA4Bd,MAAM,QAAQ,UAAS;EAIvB,MAAM,gBAAgB,eAAe,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,MAAM,MAAK;EAEpF,MAAM,WAAW,eAAmC;AAClD,OAAI,CAAC,cAAc,MAAO,QAAO;AACjC,OAAI,MAAM,GAIR,QAAO,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,GAAE;AAEnE,UAAO;IACR;EAED,MAAM,iBAAiB,eAAe;AACpC,OAAI,MAAM,OACR,QAAO,MAAM;AAEf,OAAI,MAAM,SACR,QAAO;IAGV;EAED,MAAM,cAAc,eAAe;AACjC,OAAI,MAAM,IACR,QAAO,MAAM;AAIf,OAAI,eAAe,UAAU,SAC3B,QAAO;IAGV;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,eAAe,YAAY;IAC/B,MAAM,MAAM;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;AAID,UAAO,MAAM,WACT,GAAG,cAAc,GAAG,iBACpB,GAAG,cAAc,GAAG,eAAe,GAAG;IAC3C;;uBAIC,YAWY,wBAVL,SAAA,MAAQ,EADf,WAEU,MASE,MATG,EAAA;IACZ,MAAM,cAAA,QAAgB,QAAA,OAAO,KAAA;IAC7B,QAAQ,cAAA,QAAgB,eAAA,QAAiB,KAAA;IACzC,KAAK,cAAA,QAAgB,YAAA,QAAc,KAAA;IACnC,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;IACnC,OAAO,UAAA;;2BAEA,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as grLinkSafelist, t as grLinkConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrLink_default } from "./chunks/GrLink-
|
|
1
|
+
import { n as grLinkSafelist, t as grLinkConfig } from "../../chunks/config-CjEplP6D.js";
|
|
2
|
+
import { t as GrLink_default } from "./chunks/GrLink-BLPigqij.js";
|
|
3
3
|
export { GrLink_default as GrLink, GrLink_default as default, grLinkConfig, grLinkSafelist };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrList
|
|
1
|
+
{"version":3,"file":"GrList-BPjQf-72.js","names":["$slots"],"sources":["../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrListItem.vue","../../../../src/components/GrList/GrListItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>"],"mappings":";;;;;;;;;;;;;;;;;;;;;;uBAcE,YAcS,MAAA,eAAA,EAAA,MAAA;2BAPD,CALE,QAAA,WAAA,WAAA,EADR,mBAMM,OANN,cAMM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,KAAA,WAAA,EAEV,mBAKM,OALN,cAKM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEZd,MAAM,QAAQ;EAMd,MAAM,QAAQ,UAAS;EAEvB,MAAM,eAAe,eACnB,MAAM,YAAY,YAAY,cAAc,YAC9C;EAEA,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,MAAM,MAAK;EAC9D,MAAM,iBAAiB,eAAe,CAAC,CAAC,MAAM,eAAe,CAAC,CAAC,MAAM,YAAW;;uBAI9E,mBA0BM,OAAA;IAzBJ,MAAK;IACL,OAAK,eAAA,CAAC,0CACE,aAAA,MAAY,CAAA;;IAETA,KAAAA,OAAO,UAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAsB,KAAA,QAAA,SAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;IAExB,mBAcM,OAdN,YAcM,CAbO,SAAA,SAAA,WAAA,EAAX,mBAIM,OAJN,YAIM,CAHJ,WAED,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,EAIM,eAAA,SAAA,WAAA,EADR,mBAOM,OAPN,YAOM,CAHJ,WAED,KAAA,QAAA,eAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,YAAW,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA;IAICA,KAAAA,OAAO,WAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as GrList_default, t as GrListItem_default } from "./chunks/GrList
|
|
2
|
-
import { t as grListConfig } from "../../chunks/config-
|
|
1
|
+
import { n as GrList_default, t as GrListItem_default } from "./chunks/GrList-BPjQf-72.js";
|
|
2
|
+
import { t as grListConfig } from "../../chunks/config-C4qAA0Sb.js";
|
|
3
3
|
export { GrList_default as GrList, GrList_default as default, GrListItem_default as GrListItem, grListConfig };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { t as GrLoading_default } from "./chunks/GrLoading-C3QZKwE-.js";
|
|
2
|
-
import { n as grLoadingSafelist, t as grLoadingConfig } from "../../chunks/config-
|
|
2
|
+
import { n as grLoadingSafelist, t as grLoadingConfig } from "../../chunks/config-B44QVIge.js";
|
|
3
3
|
export { GrLoading_default as GrLoading, GrLoading_default as default, grLoadingConfig, grLoadingSafelist };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { t as getGrModalPanelClass } from "../../chunks/grModalStyles-Dv2NXBKi.js";
|
|
2
2
|
import { t as GrModal_default } from "./chunks/GrModal-gvfvlp7k.js";
|
|
3
|
-
import { n as grModalClassTokens, r as grModalSafelist, t as grModalConfig } from "../../chunks/config-
|
|
3
|
+
import { n as grModalClassTokens, r as grModalSafelist, t as grModalConfig } from "../../chunks/config-C5TN9J2Z.js";
|
|
4
4
|
export { GrModal_default as GrModal, GrModal_default as default, getGrModalPanelClass, grModalClassTokens, grModalConfig, grModalSafelist };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as GrButton_default } from "../../GrButton/chunks/GrButton-BmGdp8-4.js";
|
|
2
2
|
import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BV7RBU_0.js";
|
|
3
|
-
import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-
|
|
3
|
+
import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-Dm4DuCS9.js";
|
|
4
4
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, markRaw, normalizeClass, openBlock, renderSlot, toDisplayString, unref, withCtx } from "vue";
|
|
5
5
|
//#region ~icons/lucide/menu
|
|
6
6
|
var _hoisted_1$1 = {
|
package/dist/components/GrNavbar/chunks/{GrNavbar-nIyuiVj1.js.map → GrNavbar-BDIKAYfN.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrNavbar-
|
|
1
|
+
{"version":3,"file":"GrNavbar-BDIKAYfN.js","names":[],"sources":["../../../../src/components/GrNavbar/GrNavbar.vue","../../../../src/components/GrNavbar/GrNavbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconMenu from '~icons/lucide/menu'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\n\n/**\n * GrNavbar — верхняя панель приложения (header) с заголовком,\n * опциональной кнопкой меню (обычно — для мобильных) и правым слотом\n * для действий/аватара.\n *\n * - Корень — `<header>` (landmark), без собственного `role`.\n * - `aria-label` кнопки меню локализуется через `useGranularityTranslations`.\n */\nexport interface GrNavbarProps {\n title: string\n showMenuButton?: boolean\n /** Extra classes applied to the menu button wrapper (e.g. `sm:hidden`). */\n menuButtonClass?: string\n}\n\nwithDefaults(defineProps<GrNavbarProps>(), {\n showMenuButton: false,\n menuButtonClass: '',\n})\n\nconst emit = defineEmits<{\n (e: 'menu'): void\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst menuAriaLabel = computed(() => t('gr.navbar.openMenu', 'Open menu'))\n</script>\n\n<template>\n <header\n data-ds-navbar\n class=\"h-[56px] border-b border-[var(--brd)] bg-[var(--bg)] flex items-center justify-between px-4 sm:px-6\"\n >\n <div class=\"flex items-center gap-3\">\n <GrButton\n v-if=\"showMenuButton\"\n data-ds-navbar-menu\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"menuAriaLabel\"\n :class=\"menuButtonClass\"\n @click=\"emit('menu')\"\n >\n <GrIcon :size=\"16\">\n <IconMenu aria-hidden=\"true\" />\n </GrIcon>\n </GrButton>\n <div data-ds-navbar-title class=\"text-[14px] font-700\">\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n </div>\n\n <div class=\"flex items-center gap-3\">\n <slot />\n </div>\n </header>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconMenu from '~icons/lucide/menu'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\n\n/**\n * GrNavbar — верхняя панель приложения (header) с заголовком,\n * опциональной кнопкой меню (обычно — для мобильных) и правым слотом\n * для действий/аватара.\n *\n * - Корень — `<header>` (landmark), без собственного `role`.\n * - `aria-label` кнопки меню локализуется через `useGranularityTranslations`.\n */\nexport interface GrNavbarProps {\n title: string\n showMenuButton?: boolean\n /** Extra classes applied to the menu button wrapper (e.g. `sm:hidden`). */\n menuButtonClass?: string\n}\n\nwithDefaults(defineProps<GrNavbarProps>(), {\n showMenuButton: false,\n menuButtonClass: '',\n})\n\nconst emit = defineEmits<{\n (e: 'menu'): void\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst menuAriaLabel = computed(() => t('gr.navbar.openMenu', 'Open menu'))\n</script>\n\n<template>\n <header\n data-ds-navbar\n class=\"h-[56px] border-b border-[var(--brd)] bg-[var(--bg)] flex items-center justify-between px-4 sm:px-6\"\n >\n <div class=\"flex items-center gap-3\">\n <GrButton\n v-if=\"showMenuButton\"\n data-ds-navbar-menu\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"menuAriaLabel\"\n :class=\"menuButtonClass\"\n @click=\"emit('menu')\"\n >\n <GrIcon :size=\"16\">\n <IconMenu aria-hidden=\"true\" />\n </GrIcon>\n </GrButton>\n <div data-ds-navbar-title class=\"text-[14px] font-700\">\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n </div>\n\n <div class=\"flex items-center gap-3\">\n <slot />\n </div>\n </header>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,MAAM,OAAO;EAIb,MAAM,EAAE,MAAM,4BAA2B;EAEzC,MAAM,gBAAgB,eAAe,EAAE,sBAAsB,YAAY,CAAA;;uBAIvE,mBA6BS,UA7BT,YA6BS,CAzBP,mBAoBM,OApBN,YAoBM,CAlBI,QAAA,kBAAA,WAAA,EADR,YAaW,kBAAA;;IAXT,uBAAA;IACA,SAAQ;IACR,MAAK;IACL,QAAA;IACC,cAAY,cAAA;IACZ,OAAK,eAAE,QAAA,gBAAe;IACtB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,OAAA;;2BAIH,CAFT,YAES,gBAAA,EAFA,MAAM,IAAE,EAAA;4BACgB,CAA/B,YAA+B,MAAA,aAAA,EAAA,EAArB,eAAY,QAAM,CAAA,CAAA,CAAA;;;;mEAGhC,mBAIM,OAJN,YAIM,CAHJ,WAEO,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,gBAAA,gBADF,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAKd,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrNavbar_default } from "./chunks/GrNavbar-
|
|
2
|
-
import { t as grNavbarConfig } from "../../chunks/config-
|
|
1
|
+
import { t as GrNavbar_default } from "./chunks/GrNavbar-BDIKAYfN.js";
|
|
2
|
+
import { t as grNavbarConfig } from "../../chunks/config-D1DI3roo.js";
|
|
3
3
|
export { GrNavbar_default as GrNavbar, GrNavbar_default as default, grNavbarConfig };
|
package/dist/components/GrNumberInput/chunks/{GrNumberInput-B0mPLjdv.js → GrNumberInput-ECtFCIKV.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as grNumberInputShellClass, r as grNumberInputInputClass } from "../../../chunks/config-
|
|
1
|
+
import { i as grNumberInputShellClass, r as grNumberInputInputClass } from "../../../chunks/config-wo-ncgTH.js";
|
|
2
2
|
import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onUpdated, openBlock, ref, renderSlot, useSlots, withModifiers } from "vue";
|
|
3
3
|
//#region src/components/GrNumberInput/GrNumberInput.vue?vue&type=script&setup=true&lang.ts
|
|
4
4
|
var _hoisted_1 = [
|