diff --git a/packages/theme/dist/v4/globals.css b/packages/theme/dist/v4/globals.css index 060d77ad1..2557c50d8 100644 --- a/packages/theme/dist/v4/globals.css +++ b/packages/theme/dist/v4/globals.css @@ -669,6 +669,9 @@ --spacing-sm: 0.75rem; --spacing-xs: 0.5rem; --spacing-xxs: 0.25rem; + --z-input-field: 1; + --z-input-popup: 10; + --z-input-overlay: 1100; --text-big-number-md-font-size: 1.25rem; --text-big-number-md-line-height: 1.25; --text-big-number-md-font-weight: 400; diff --git a/packages/theme/dist/v4/globals.scss b/packages/theme/dist/v4/globals.scss index 060d77ad1..2557c50d8 100644 --- a/packages/theme/dist/v4/globals.scss +++ b/packages/theme/dist/v4/globals.scss @@ -669,6 +669,9 @@ --spacing-sm: 0.75rem; --spacing-xs: 0.5rem; --spacing-xxs: 0.25rem; + --z-input-field: 1; + --z-input-popup: 10; + --z-input-overlay: 1100; --text-big-number-md-font-size: 1.25rem; --text-big-number-md-line-height: 1.25; --text-big-number-md-font-weight: 400; diff --git a/packages/theme/src/scripts/build-tokens.mjs b/packages/theme/src/scripts/build-tokens.mjs index 70004177d..187111bc6 100644 --- a/packages/theme/src/scripts/build-tokens.mjs +++ b/packages/theme/src/scripts/build-tokens.mjs @@ -34,6 +34,7 @@ import { compileThemeCss, compileThemeVars } from './compile-theme.js'; import { containersData } from '../tokens/semantic/containers.data.js'; import { spacingsData } from '../tokens/semantic/spacings.data.js'; import { textsData } from '../tokens/semantic/texts.data.js'; +import { zIndicesData } from '../tokens/semantic/z-indices.data.js'; const BREAKPOINT_ORDER = ['sm', 'md', 'lg', 'xl', '2xl']; @@ -91,6 +92,7 @@ const buildFlatModel = () => ({ primitives: flattenPrimitives(), containers: flattenSingleValue(containersData, (k) => `--container-${k}`), spacings: flattenSingleValue(spacingsData, (k) => `--${k}`), + zIndices: flattenSingleValue(zIndicesData, (k) => `--${k}`), texts: flattenBundle(textsData), }); @@ -295,6 +297,7 @@ const emitCssV4 = () => { ...rootPrimitiveVars, ...(m.containers._ || {}), ...(m.spacings._ || {}), + ...(m.zIndices._ || {}), ...(m.texts._ || {}), }; @@ -303,6 +306,7 @@ const emitCssV4 = () => { const merged = { ...(m.containers[bp] || {}), ...(m.spacings[bp] || {}), + ...(m.zIndices[bp] || {}), ...(m.texts[bp] || {}), }; if (Object.keys(merged).length === 0) continue; diff --git a/packages/theme/src/tokens/semantic/z-indices.data.js b/packages/theme/src/tokens/semantic/z-indices.data.js new file mode 100644 index 000000000..ee31fb136 --- /dev/null +++ b/packages/theme/src/tokens/semantic/z-indices.data.js @@ -0,0 +1,30 @@ +/** + * Declarative z-index tokens. + * + * Intra-input stacking: + * + * - `z-input-field` → native field / interactive foreground (e.g. an + * `` or trigger button) sitting above the + * input's own background surface, icons, and + * adornments so keyboard/mouse focus is never + * hijacked by a decorative sibling. + * - `z-input-popup` → inline (non-teleported) overlays anchored to the + * input — dropdown menus, option lists, popovers — + * that must sit above surrounding form content but + * within the current stacking context. + * - `z-input-overlay` → teleported overlays (rendered under `` via + * ``) that must clear application chrome + * such as drawers, modals, and fixed headers. + * + * Values are intentionally small and well-spaced to make future additions + * obvious. Consume as `z-[var(--z-input-*)]` in components — do not + * introduce ad-hoc numeric z-index in input `.vue` files. + */ + +export const zIndicesData = { + 'z-input-field': { _: '1' }, + 'z-input-popup': { _: '10' }, + 'z-input-overlay': { _: '1100' }, +}; + +export default { zIndicesData }; diff --git a/packages/webkit/catalog.json b/packages/webkit/catalog.json index accdbce63..063a1244c 100644 --- a/packages/webkit/catalog.json +++ b/packages/webkit/catalog.json @@ -671,7 +671,10 @@ "--width-md", "--width-sm", "--width-xl", - "--width-xs" + "--width-xs", + "--z-input-field", + "--z-input-overlay", + "--z-input-popup" ], "typography": [ "text-big-number-lg", @@ -1408,6 +1411,11 @@ "--width-sm", "--width-xl", "--width-xs" + ], + "z": [ + "--z-input-field", + "--z-input-overlay", + "--z-input-popup" ] }, "animations": [ diff --git a/packages/webkit/src/components/inputs/chip/chip.vue b/packages/webkit/src/components/inputs/chip/chip.vue index ce2bf8ca7..dfaef57b8 100644 --- a/packages/webkit/src/components/inputs/chip/chip.vue +++ b/packages/webkit/src/components/inputs/chip/chip.vue @@ -109,7 +109,9 @@ @click="onClick" @keydown="onKeydown" > - + @@ -145,21 +145,21 @@ :aria-required="required || undefined" :data-testid="testId" v-bind="passthroughAttrs" - class="relative z-[1] w-full min-w-0 border-0 bg-transparent outline-none px-[var(--spacing-md)] text-label-sm text-[var(--text-default)] placeholder:text-[var(--text-muted)] disabled:cursor-not-allowed disabled:text-[var(--text-disabled)] read-only:cursor-default [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + class="relative z-[var(--z-input-field)] w-full min-w-0 border-0 bg-transparent outline-none px-[var(--spacing-md)] text-label-sm text-[var(--text-default)] placeholder:text-[var(--text-muted)] disabled:cursor-not-allowed disabled:text-[var(--text-disabled)] read-only:cursor-default [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" @input="handleInput" @change="handleChange" />