vectis-ui 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/VColorPicker/color.js +2 -2
- package/dist/components/VColorPicker/color.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.d.ts +10 -0
- package/dist/components/VCombobox/VCombobox.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +177 -159
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.css +1 -1
- package/dist/components/VDataTable/VDataTable.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.css +1 -1
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDialog/VDialog.css +1 -1
- package/dist/components/VDialog/VDialog.js.map +1 -1
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDrawer/VDrawer.css +1 -1
- package/dist/components/VDrawer/VDrawer.js.map +1 -1
- package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMeter/VMeter.css +1 -1
- package/dist/components/VMeter/VMeter.d.ts +24 -8
- package/dist/components/VMeter/VMeter.js.map +1 -1
- package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js +65 -48
- package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMeterGroup/VMeterGroup.css +2 -0
- package/dist/components/VMeterGroup/VMeterGroup.d.ts +101 -0
- package/dist/components/VMeterGroup/VMeterGroup.js +9 -0
- package/dist/components/VMeterGroup/VMeterGroup.js.map +1 -0
- package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js +117 -0
- package/dist/components/VMeterGroup/VMeterGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VNumberInput/number.js +2 -2
- package/dist/components/VNumberInput/number.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +12 -13
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +65 -48
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.css +1 -1
- package/dist/components/VSeparator/VSeparator.d.ts +42 -2
- package/dist/components/VSeparator/VSeparator.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js +50 -9
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.d.ts +6 -0
- package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/state.js +2 -3
- package/dist/components/VSnackbar/state.js.map +1 -1
- package/dist/components/VToast/state.js +2 -3
- package/dist/components/VToast/state.js.map +1 -1
- package/dist/composables/useAriaLabel.d.ts +5 -0
- package/dist/composables/useAriaLabel.js +5 -1
- package/dist/composables/useAriaLabel.js.map +1 -1
- package/dist/composables/useListbox.d.ts +2 -0
- package/dist/composables/useListbox.js +71 -68
- package/dist/composables/useListbox.js.map +1 -1
- package/dist/i18n/en.js +3 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.js +3 -1
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/types.d.ts +6 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +21 -20
- package/dist/styles.css +1 -1
- package/dist/tokens/index.d.ts +10 -5
- package/dist/tokens/semantic.d.ts +10 -5
- package/dist/tokens/semantic.js +10 -5
- package/dist/tokens/semantic.js.map +1 -1
- package/dist/tokens.json +39 -14
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number.js","names":["numberSeparators","parts","locale","part","MINUS","PLAIN","parseNumber","trimmed","text","plain","separators","decimalsOf","value","exponent","point","roundTo","decimals","scale","factor","clamp","max","min","stepValue","step","base","position","steps"],"sources":["../../../src/components/VNumberInput/number.ts"],"sourcesContent":["// @core\n/**\n * The arithmetic and the locale handling of VNumberInput, kept free of Vue: reading what was\n * typed, writing a value back for editing, and stepping on a grid without floating-point drift.\n */\n\n/** The two separators a locale writes numbers with: \"1 234,5\" in French, \"1,234.5\" in English. */\nexport interface NumberSeparators {\n group: string\n decimal: string\n}\n\nexport function numberSeparators(locale: string): NumberSeparators {\n const parts = new Intl.NumberFormat(locale).formatToParts(12345.6)\n return {\n group: parts.find((part) => part.type === 'group')?.value ?? '',\n decimal: parts.find((part) => part.type === 'decimal')?.value ?? '.',\n }\n}\n\n/** The minus signs a keyboard or a paste can bring, besides the hyphen. */\nconst MINUS = /[−‒–﹣-]/g\n\n/** What a number may look like once separators and symbols are gone: \"-12\", \"3.\", \".5\". */\nconst PLAIN = /^-?(\\d
|
|
1
|
+
{"version":3,"file":"number.js","names":["numberSeparators","parts","locale","part","MINUS","PLAIN","parseNumber","trimmed","text","plain","separators","decimalsOf","value","exponent","point","roundTo","decimals","scale","factor","clamp","max","min","stepValue","step","base","position","steps"],"sources":["../../../src/components/VNumberInput/number.ts"],"sourcesContent":["// @core\n/**\n * The arithmetic and the locale handling of VNumberInput, kept free of Vue: reading what was\n * typed, writing a value back for editing, and stepping on a grid without floating-point drift.\n */\n\n/** The two separators a locale writes numbers with: \"1 234,5\" in French, \"1,234.5\" in English. */\nexport interface NumberSeparators {\n group: string\n decimal: string\n}\n\nexport function numberSeparators(locale: string): NumberSeparators {\n const parts = new Intl.NumberFormat(locale).formatToParts(12345.6)\n return {\n group: parts.find((part) => part.type === 'group')?.value ?? '',\n decimal: parts.find((part) => part.type === 'decimal')?.value ?? '.',\n }\n}\n\n/** The minus signs a keyboard or a paste can bring, besides the hyphen. */\nconst MINUS = /[−‒–﹣-]/g\n\n/** What a number may look like once separators and symbols are gone: \"-12\", \"3.\", \".5\". */\nconst PLAIN = /^-?(\\d+(?:\\.\\d*)?|\\.\\d+)$/\n\n/**\n * Reads a typed number: `null` for an empty field, `NaN` for text that is not a number.\n *\n * Group separators and any space are dropped, the locale's decimal separator becomes a point,\n * and a point is also accepted as the decimal separator where the locale does not group with\n * it. Currency, unit and percent symbols around the number are ignored, so a formatted value\n * pasted back in reads as the number it shows.\n */\nexport function parseNumber(text: string, separators: NumberSeparators): number | null {\n const trimmed = text.trim()\n if (!trimmed) return null\n let plain = trimmed.replace(MINUS, '-')\n if (separators.group) plain = plain.split(separators.group).join('')\n plain = plain.replace(/\\s/g, '')\n if (separators.decimal !== '.') plain = plain.split(separators.decimal).join('.')\n // Symbols are only stripped at either end, the minus kept before a leading one (\"-$5.00\"): a\n // letter between digits is a typo, and \"1o0\" read as 10 would be committed silently. The\n // lookbehind starts the trailing run only once, where a scan from each of its letters would\n // take quadratic time.\n plain = plain.replace(/^(-?)[^\\d.-]+/, '$1').replace(/(?<=^|[\\d.])[^\\d.]+$/, '')\n return PLAIN.test(plain) ? Number(plain) : Number.NaN\n}\n\n/** The number of decimals a value is written with: 0.25 has two, 1e-7 has seven. */\nexport function decimalsOf(value: number): number {\n const text = String(value)\n const exponent = text.indexOf('e-')\n if (exponent >= 0)\n return Number(text.slice(exponent + 2)) + decimalsOf(Number(text.slice(0, exponent)))\n const point = text.indexOf('.')\n return point < 0 ? 0 : text.length - point - 1\n}\n\n/** Rounds to a number of decimals, which is what removes the drift of 0.1 + 0.2. */\nfunction roundTo(value: number, decimals: number): number {\n return Number(value.toFixed(Math.min(decimals, 100)))\n}\n\n/** Multiplies by a power of ten without picking up drift: 0.07 × 100 is 7, not 7.000000000000001. */\nexport function scale(value: number, factor: number): number {\n return Number((value * factor).toPrecision(15))\n}\n\nexport function clamp(value: number, min: number | undefined, max: number | undefined): number {\n if (max !== undefined && value > max) value = max\n if (min !== undefined && value < min) value = min\n return value\n}\n\n/**\n * Moves a value by a number of steps on the grid that starts at `base`. A value off the grid\n * lands on the next grid line in the direction of travel first, as a native number input does:\n * up from 1.5 by a step of 1 gives 2, not 2.5.\n */\nexport function stepValue(value: number, steps: number, step: number, base: number): number {\n const decimals = Math.max(decimalsOf(step), decimalsOf(base))\n const position = roundTo((value - base) / step, 10)\n const onGrid = Number.isInteger(position)\n const from = onGrid ? position : steps > 0 ? Math.floor(position) : Math.ceil(position)\n return roundTo(base + (from + steps) * step, decimals)\n}\n"],"mappings":";AAYA,SAAgBA,EAAiB,GAAkC;CACjE,IAAMC,IAAQ,IAAI,KAAK,aAAaC,CAAM,CAAC,CAAC,cAAc,OAAO;CACjE,OAAO;EACL,OAAOD,EAAM,MAAM,MAASE,EAAK,SAAS,OAAO,CAAC,EAAE,SAAS;EAC7D,SAASF,EAAM,MAAM,MAASE,EAAK,SAAS,SAAS,CAAC,EAAE,SAAS;CACnE;AACF;AAGA,IAAMC,IAAQ,YAGRC,IAAQ;AAUd,SAAgBC,EAAY,GAAc,GAA6C;CACrF,IAAMC,IAAUC,EAAK,KAAK;CAC1B,IAAI,CAACD,GAAS,OAAO;CACrB,IAAIE,IAAQF,EAAQ,QAAQH,GAAO,GAAG;CAStC,OARIM,EAAW,UAAO,IAAQD,EAAM,MAAMC,EAAW,KAAK,CAAC,CAAC,KAAK,EAAE,IACnE,IAAQD,EAAM,QAAQ,OAAO,EAAE,GAC3BC,EAAW,YAAY,QAAK,IAAQD,EAAM,MAAMC,EAAW,OAAO,CAAC,CAAC,KAAK,GAAG,IAKhF,IAAQD,EAAM,QAAQ,iBAAiB,IAAI,CAAC,CAAC,QAAQ,wBAAwB,EAAE,GACxEJ,EAAM,KAAKI,CAAK,IAAI,OAAOA,CAAK,IAAI;AAC7C;AAGA,SAAgBE,EAAW,GAAuB;CAChD,IAAMH,IAAO,OAAOI,CAAK,GACnBC,IAAWL,EAAK,QAAQ,IAAI;CAClC,IAAIK,KAAY,GACd,OAAO,OAAOL,EAAK,MAAMK,IAAW,CAAC,CAAC,IAAIF,EAAW,OAAOH,EAAK,MAAM,GAAGK,CAAQ,CAAC,CAAC;CACtF,IAAMC,IAAQN,EAAK,QAAQ,GAAG;CAC9B,OAAOM,IAAQ,IAAI,IAAIN,EAAK,SAASM,IAAQ;AAC/C;AAGA,SAASC,EAAQ,GAAe,GAA0B;CACxD,OAAO,OAAOH,EAAM,QAAQ,KAAK,IAAII,GAAU,GAAG,CAAC,CAAC;AACtD;AAGA,SAAgBC,EAAM,GAAe,GAAwB;CAC3D,OAAO,QAAQL,IAAQM,EAAA,CAAQ,YAAY,EAAE,CAAC;AAChD;AAEA,SAAgBC,EAAM,GAAe,GAAyB,GAAiC;CAG7F,OAFIC,MAAQ,KAAA,KAAaR,IAAQQ,MAAK,IAAQA,IAC1CC,MAAQ,KAAA,KAAaT,IAAQS,MAAK,IAAQA,IACvCT;AACT;AAOA,SAAgBU,EAAU,GAAe,GAAe,GAAc,GAAsB;CAC1F,IAAMN,IAAW,KAAK,IAAIL,EAAWY,CAAI,GAAGZ,EAAWa,CAAI,CAAC,GACtDC,IAAWV,GAASH,IAAQY,KAAQD,GAAM,EAAE;CAGlD,OAAOR,EAAQS,MAFA,OAAO,UAAUC,CACnB,IAASA,IAAWC,IAAQ,IAAI,KAAK,MAAMD,CAAQ,IAAI,KAAK,KAAKA,CAAQ,KACxDC,KAASH,GAAMP,CAAQ;AACvD"}
|
|
@@ -59,8 +59,8 @@ declare const __VLS_base: import('vue').DefineComponent<ProgressCircularProps, {
|
|
|
59
59
|
shape: ProgressCircularShape;
|
|
60
60
|
max: number;
|
|
61
61
|
indeterminate: boolean;
|
|
62
|
-
thickness: number | string;
|
|
63
62
|
showValue: boolean;
|
|
63
|
+
thickness: number | string;
|
|
64
64
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
65
65
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
66
66
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
-
@layer vectis.components{.v-progress-linear-field{--progress-thickness:var(--vectis-control-size-
|
|
2
|
+
@layer vectis.components{.v-progress-linear-field{--progress-thickness:var(--vectis-control-size-bar-thickness-sm);--progress-fill:var(--tone-bg-solid);--progress-track:var(--tone-bg-soft);--progress-text-fallback:var(--tone-text-solid);gap:var(--vectis-space-1);flex-direction:column;display:flex}.v-progress-linear-field[data-size=xs]{--progress-thickness:var(--vectis-control-size-bar-thickness-xs)}.v-progress-linear-field[data-size=md]{--progress-thickness:var(--vectis-control-size-bar-thickness-md)}.v-progress-linear-field[data-size=lg]{--progress-thickness:var(--vectis-control-size-bar-thickness-lg)}.v-progress-linear-field[data-size=xl]{--progress-thickness:var(--vectis-control-size-bar-thickness-xl)}.v-progress-linear-header{align-items:baseline;column-gap:var(--vectis-space-2);font-family:var(--vectis-text-family);flex-wrap:wrap;display:flex}.v-progress-linear-label{color:var(--vectis-color-text);font-size:var(--vectis-text-label-size);font-weight:var(--vectis-text-label-weight);line-height:var(--vectis-text-label-leading)}.v-progress-linear-value{color:var(--vectis-color-text-muted);font-size:var(--vectis-text-body-md-size);font-weight:var(--vectis-text-body-md-weight);line-height:var(--vectis-text-body-md-leading);font-variant-numeric:tabular-nums;margin-inline-start:auto}.v-progress-linear{inline-size:100%;block-size:var(--progress-thickness);border-radius:var(--vectis-radius-pill);background:var(--progress-track);font-family:var(--vectis-text-family);font-size:var(--vectis-text-caption-size);font-weight:var(--vectis-text-control-weight);line-height:var(--vectis-text-control-leading);display:block;position:relative}.v-progress-linear[data-shape=square]{border-radius:0}.v-progress-linear-fill{inline-size:calc(100% * var(--fill-fraction));border-radius:inherit;background:var(--progress-fill);transition:inline-size var(--vectis-duration-base) var(--vectis-ease-default);position:absolute;inset-block:0;inset-inline-start:0}.v-progress-linear-text{--progress-clip-start:calc(100% * var(--fill-fraction));--progress-clip-end:-100vmax;padding-inline:var(--vectis-space-2);color:var(--vectis-color-text);clip-path:inset(-100vmax var(--progress-clip-end) -100vmax var(--progress-clip-start));transition:clip-path var(--vectis-duration-base) var(--vectis-ease-default);writing-mode:horizontal-tb;white-space:nowrap;pointer-events:none;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.v-progress-linear[data-value-position=start] .v-progress-linear-text{justify-content:start}.v-progress-linear[data-value-position=end] .v-progress-linear-text{justify-content:end}.v-progress-linear-text[data-on-fill]{--progress-clip-start:-100vmax;--progress-clip-end:calc(100% * (1 - var(--fill-fraction)));color:var(--progress-text-fallback)}@supports (color:contrast-color(red)){.v-progress-linear-text[data-on-fill]{color:contrast-color(var(--progress-fill))}}.v-progress-linear:dir(rtl) .v-progress-linear-text{clip-path:inset(-100vmax var(--progress-clip-start) -100vmax var(--progress-clip-end))}.v-progress-linear-field[data-orientation=vertical]{block-size:var(--vectis-control-size-bar-length);align-items:flex-start}.v-progress-linear[data-orientation=vertical]{writing-mode:vertical-lr;flex:1 1 0;inline-size:auto}.v-progress-linear[data-orientation=vertical] .v-progress-linear-fill{inset-inline:auto 0}.v-progress-linear[data-orientation=vertical]:dir(rtl) .v-progress-linear-fill{inset-inline:0 auto}.v-progress-linear[data-orientation=vertical] .v-progress-linear-text{padding-inline:0;padding-block:var(--vectis-space-2);flex-direction:column-reverse}.v-progress-linear[data-orientation=vertical] .v-progress-linear-text,.v-progress-linear[data-orientation=vertical]:dir(rtl) .v-progress-linear-text{clip-path:inset(var(--progress-clip-end) -100vmax var(--progress-clip-start) -100vmax)}.v-progress-linear[data-indeterminate]{overflow:hidden}.v-progress-linear[data-indeterminate] .v-progress-linear-fill{--progress-bar:40%;inline-size:var(--progress-bar);animation:v-progress-linear-indeterminate var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite;transition:none;inset-inline:0 auto}@keyframes v-progress-linear-indeterminate{0%{inset-inline-start:calc(-1 * var(--progress-bar))}to{inset-inline-start:100%}}.v-progress-linear[data-orientation=vertical][data-indeterminate] .v-progress-linear-fill{animation-direction:reverse}.v-progress-linear[data-orientation=vertical][data-indeterminate]:dir(rtl) .v-progress-linear-fill{animation-direction:normal}@media (prefers-reduced-motion:reduce){.v-progress-linear-fill,.v-progress-linear-text{transition:none}.v-progress-linear[data-indeterminate] .v-progress-linear-fill{animation-duration:var(--vectis-duration-5000)}}@media (forced-colors:active){.v-progress-linear{forced-color-adjust:none;box-shadow:inset 0 0 0 var(--vectis-control-border-width) CanvasText;background:canvas}.v-progress-linear-fill{background:highlight}.v-progress-linear-text{color:canvastext}.v-progress-linear-text[data-on-fill]{color:highlighttext}}}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
export type ProgressLinearTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning';
|
|
3
3
|
/** How the track and the fill end. */
|
|
4
4
|
export type ProgressLinearShape = 'rounded' | 'square';
|
|
5
|
-
/**
|
|
6
|
-
export type
|
|
5
|
+
/** The thickness of the bar: 2, 4, 8, 12 or 20 pixels. */
|
|
6
|
+
export type ProgressLinearSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
7
|
+
/** Where the value is written: after the label, or inside the bar at its start, centre or end. */
|
|
8
|
+
export type ProgressLinearValuePosition = 'header' | 'start' | 'center' | 'end';
|
|
7
9
|
/** Which way the bar fills. */
|
|
8
10
|
export type ProgressLinearOrientation = 'horizontal' | 'vertical';
|
|
9
11
|
/** What the default slot receives. */
|
|
@@ -38,33 +40,31 @@ interface ProgressLinearProps {
|
|
|
38
40
|
* the dark one.
|
|
39
41
|
*/
|
|
40
42
|
color?: string;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
* default, and showing text inside a bar that thin needs an explicit thickness.
|
|
44
|
-
*/
|
|
45
|
-
thickness?: number | string;
|
|
43
|
+
/** The thickness of the bar. Only `xl` is thick enough to hold the value written inside it. */
|
|
44
|
+
size?: ProgressLinearSize;
|
|
46
45
|
/** Whether the ends of the bar are rounded or square. */
|
|
47
46
|
shape?: ProgressLinearShape;
|
|
48
47
|
/**
|
|
49
|
-
* Writes the percentage
|
|
50
|
-
*
|
|
48
|
+
* Writes the percentage. It is ignored while the progress is unmeasurable, there being no
|
|
49
|
+
* figure to write.
|
|
51
50
|
*/
|
|
52
51
|
showValue?: boolean;
|
|
53
52
|
/**
|
|
54
|
-
* Where that text
|
|
55
|
-
* hence the bottom.
|
|
53
|
+
* Where that text is written: at the end of the label's line, or inside the bar. On a vertical
|
|
54
|
+
* bar the start is the zero end, hence the bottom.
|
|
56
55
|
*/
|
|
57
56
|
valuePosition?: ProgressLinearValuePosition;
|
|
58
57
|
/** Turns the bar upright, filling from the bottom up. */
|
|
59
58
|
orientation?: ProgressLinearOrientation;
|
|
60
59
|
}
|
|
61
60
|
type __VLS_Slots = {
|
|
62
|
-
/** What to write
|
|
61
|
+
/** What to write instead of the percentage. */
|
|
63
62
|
default?(props: ProgressLinearSlotProps): unknown;
|
|
64
63
|
};
|
|
65
64
|
declare const __VLS_base: import('vue').DefineComponent<ProgressLinearProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ProgressLinearProps> & Readonly<{}>, {
|
|
66
65
|
label: string;
|
|
67
66
|
value: number;
|
|
67
|
+
size: ProgressLinearSize;
|
|
68
68
|
tone: ProgressLinearTone;
|
|
69
69
|
color: string;
|
|
70
70
|
shape: ProgressLinearShape;
|
|
@@ -72,7 +72,6 @@ declare const __VLS_base: import('vue').DefineComponent<ProgressLinearProps, {},
|
|
|
72
72
|
hideLabel: boolean;
|
|
73
73
|
max: number;
|
|
74
74
|
indeterminate: boolean;
|
|
75
|
-
thickness: number | string;
|
|
76
75
|
showValue: boolean;
|
|
77
76
|
valuePosition: ProgressLinearValuePosition;
|
|
78
77
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VProgressLinear.js","names":["_sfc_main","VProgressLinear_vue_vue_type_script_setup_true_lang_default","VProgressLinear_default"],"sources":["../../../src/components/VProgressLinear/VProgressLinear.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * CSS draws the fill. JavaScript normalizes values shared by geometry, slots and progressbar\n * ARIA attributes.\n */\nimport { computed, useId } from 'vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useProgressValue } from '../../composables/useProgressValue'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useMessages } from '../../i18n/state'\nimport { px } from '../../utils/css'\n\n/** What the progress means, in colour. */\nexport type ProgressLinearTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\n/** How the track and the fill end. */\nexport type ProgressLinearShape = 'rounded' | 'square'\n\n/** Where the value sits along the bar. */\nexport type ProgressLinearValuePosition = 'start' | 'center' | 'end'\n\n/** Which way the bar fills. */\nexport type ProgressLinearOrientation = 'horizontal' | 'vertical'\n\n/** What the default slot receives. */\nexport interface ProgressLinearSlotProps {\n /** The value, brought back into the range. */\n value: number\n /** The bound, zero or more. */\n max: number\n /** How far along it is, as a percentage and unrounded. */\n percent: number\n}\n\ninterface ProgressLinearProps {\n /** How far along it is. Anything outside the range is brought back into it. */\n value?: number\n /**\n * What is progressing, shown above the bar and naming it for screen readers. Without it, the\n * bar is named from the design system dictionary; an `aria-label` or `aria-labelledby` of your\n * own takes precedence.\n */\n label?: string\n /** Hides the label visually. It still names the bar for screen readers. */\n hideLabel?: boolean\n /** What counts as finished. The other end is always zero. */\n max?: number\n /** Shows progress that cannot be measured, such as a server that reports no percentage. */\n indeterminate?: boolean\n /** What the progress means, expressed as a colour. */\n tone?: ProgressLinearTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. The\n * track's own shade is derived from it against the theme, so it follows the light and\n * the dark one.\n */\n color?: string\n /**\n * How thick the bar is, always in PIXELS: `12` and `'12'` both give 12px. It is 4px by\n * default, and showing text inside a bar that thin needs an explicit thickness.\n */\n thickness?: number | string\n /** Whether the ends of the bar are rounded or square. */\n shape?: ProgressLinearShape\n /**\n * Writes the percentage inside the bar. It is ignored while the progress is\n * unmeasurable, there being no figure to write.\n */\n showValue?: boolean\n /**\n * Where that text sits along the bar. On a vertical bar the start is the zero end,\n * hence the bottom.\n */\n valuePosition?: ProgressLinearValuePosition\n /** Turns the bar upright, filling from the bottom up. */\n orientation?: ProgressLinearOrientation\n}\n\nconst props = withDefaults(defineProps<ProgressLinearProps>(), {\n value: 0,\n label: undefined,\n hideLabel: false,\n max: 100,\n indeterminate: false,\n tone: 'accent',\n color: undefined,\n thickness: undefined,\n shape: 'rounded',\n showValue: false,\n valuePosition: 'center',\n orientation: 'horizontal',\n})\n\ndefineSlots<{\n /** What to write inside the bar instead of the percentage. */\n default?(props: ProgressLinearSlotProps): unknown\n}>()\n\n/* The percent sign, and the non-breaking space French puts before it where English puts\n nothing, are a convention of the language: they belong in the dictionary rather than\n in this file. Any other format goes through the slot above. */\nconst m = useMessages()\n\nconst {\n max: normalizedMax,\n clamped,\n fraction,\n percent,\n roundedPercent,\n} = useProgressValue(\n () => props.value,\n () => props.max,\n)\n\n// The root is a layout box holding the label and the bar: `class` and `style` stay on it, with\n// the tone and the custom properties the bar inherits, and every other attribute goes to the bar.\ndefineOptions({ inheritAttrs: false })\nconst { attrs, rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// @a11y\n// A visible label names the bar by reference, unless the consumer named it themselves; without\n// one, the dictionary does. An indicator takes no name from the text inside it.\nconst labelId = useId()\nconst ariaLabel = useAriaLabel(() => (props.label ? undefined : m.value.progress.label))\nconst labelledBy = computed(() =>\n props.label && attrs['aria-label'] == null && attrs['aria-labelledby'] == null\n ? labelId\n : undefined,\n)\n</script>\n\n<template>\n <div\n class=\"v-progress-linear-field v-tone\"\n :class=\"rootClass\"\n :data-tone=\"tone\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :data-orientation=\"orientation\"\n :style=\"[{ '--custom-color': color, '--progress-thickness': px(thickness) }, rootStyle]\"\n >\n <span\n v-if=\"label\"\n :id=\"labelId\"\n class=\"v-progress-linear-label\"\n :class=\"{ 'v-visually-hidden': hideLabel }\"\n >{{ label }}</span\n >\n <div\n class=\"v-progress-linear\"\n role=\"progressbar\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"forwardedAttrs\"\n :data-shape=\"shape\"\n :data-orientation=\"orientation\"\n :data-value-position=\"valuePosition\"\n :data-indeterminate=\"indeterminate ? '' : undefined\"\n :aria-valuenow=\"indeterminate ? undefined : clamped\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"normalizedMax\"\n :style=\"{ '--fill-fraction': String(fraction) }\"\n >\n <span class=\"v-progress-linear-fill\" />\n <!--\n The same text twice, each copy cut at the fill's edge so that the two complete\n each other exactly: the first in the ordinary text colour over the empty track,\n the second over the filled part, coloured to contrast with it. The second is\n hidden from screen readers, being a duplicate of text already there.\n -->\n <template v-if=\"!indeterminate && (showValue || $slots.default)\">\n <span class=\"v-progress-linear-text\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n <span class=\"v-progress-linear-text\" data-on-fill aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </template>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The root holds the label and the bar, and declares what the bar reads, so a consumer's style\n * on it (outside our layers) overrides the thickness and the colours. The bar takes the whole\n * length available: sizing it is the consumer's business, through the parent or a width of\n * their own on the root.\n */\n .v-progress-linear-field {\n --progress-thickness: var(--vectis-control-size-progress-linear-thickness);\n /* Fill, track and the text over the fill are the tone's solid, soft and on-solid\n colours, read from the shared table (`.v-tone`, set in the template). */\n --progress-fill: var(--tone-bg-solid);\n --progress-track: var(--tone-bg-soft);\n --progress-text-fallback: var(--tone-text-solid);\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n }\n\n .v-progress-linear-label {\n color: var(--vectis-color-text);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n /* The element IS the track. */\n .v-progress-linear {\n position: relative;\n display: block;\n inline-size: 100%;\n block-size: var(--progress-thickness);\n border-radius: var(--vectis-radius-pill);\n background: var(--progress-track);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n .v-progress-linear[data-shape='square'] {\n border-radius: 0;\n }\n\n .v-progress-linear-fill {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n inline-size: calc(100% * var(--fill-fraction));\n border-radius: inherit;\n background: var(--progress-fill);\n /*\n * The fill is animated by changing its LENGTH, which the browser has to lay out again on\n * every frame. Scaling it would be cheaper, but a scale is physical: it would have to be\n * undone for the vertical orientation and again for a right-to-left page, where a logical\n * length simply works.\n */\n transition: inline-size var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n /*\n * The two copies are COMPLEMENTARY and never superimposed: this one is cut OUT of the filled\n * part, the other cut TO it, so every letter is painted exactly once. Removing either clip\n * raises no error and stays invisible for as long as both copies resolve to the same colour,\n * which happens wherever the adaptive colour function is unsupported.\n */\n .v-progress-linear-text {\n /*\n * The two insets of the cut: one on the edge the fill grows FROM, one on the edge it grows\n * towards. They are named after those roles rather than after physical sides, so the three\n * geometry rules further down; horizontal, right-to-left, vertical; all read the same pair.\n */\n --progress-clip-start: calc(100% * var(--fill-fraction));\n --progress-clip-end: -100vmax;\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: var(--vectis-space-2);\n color: var(--vectis-color-text);\n /*\n * The large negative inset on the two sides that do not carry the cut is what stops text\n * taller or wider than the bar from being cropped by its own clip.\n */\n clip-path: inset(-100vmax var(--progress-clip-end) -100vmax var(--progress-clip-start));\n /* The same duration and easing as the fill's own length, or the colour boundary\n would drift away from the fill's edge for the length of the transition. */\n transition: clip-path var(--vectis-duration-base) var(--vectis-ease-default);\n /* The bar itself is turned on its side in vertical mode; the text is put back\n upright here, since a label read sideways is not the point. */\n writing-mode: horizontal-tb;\n white-space: nowrap;\n pointer-events: none;\n }\n\n .v-progress-linear[data-value-position='start'] .v-progress-linear-text {\n justify-content: start;\n }\n\n .v-progress-linear[data-value-position='end'] .v-progress-linear-text {\n justify-content: end;\n }\n\n .v-progress-linear-text[data-on-fill] {\n /* The exact complement of the copy above: the cut moves to the other end of the\n axis, so the two together cover the whole bar and overlap nowhere. */\n --progress-clip-start: -100vmax;\n --progress-clip-end: calc(100% * (1 - var(--fill-fraction)));\n /*\n * The per-tone fallback colour. The adaptive one cannot simply be written as a second\n * declaration after it: because that declaration contains a var(), a browser with no\n * support does not reject it at parse time; it would win the cascade and only then turn\n * invalid, which resets the colour to inherited and leaves the fallback never applied.\n */\n color: var(--progress-text-fallback);\n }\n\n /* Where the adaptive colour function exists, the text picks black or white against\n whatever colour the fill ended up with. */\n @supports (color: contrast-color(red)) {\n .v-progress-linear-text[data-on-fill] {\n color: contrast-color(var(--progress-fill));\n }\n }\n\n /*\n * In a right-to-left page the fill grows from the right, so the two insets change physical\n * sides; the variables themselves keep their meaning.\n */\n .v-progress-linear:dir(rtl) .v-progress-linear-text {\n clip-path: inset(-100vmax var(--progress-clip-start) -100vmax var(--progress-clip-end));\n }\n\n /*\n * Putting zero at the bottom is not done by reversing the direction, which would also apply\n * to the text of the two copies: bidirectional reordering would then display \"50 %\" as \"%\n * 50\". The fill is anchored to the far end of the axis instead.\n */\n /*\n * Upright, the root carries the length, so a consumer's height on it sets the bar's: the bar\n * takes whatever the label leaves, its own inline size being the physical height.\n */\n .v-progress-linear-field[data-orientation='vertical'] {\n align-items: flex-start;\n block-size: var(--vectis-control-size-progress-linear-length);\n }\n\n .v-progress-linear[data-orientation='vertical'] {\n flex: 1 1 0;\n writing-mode: vertical-lr;\n inline-size: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-fill {\n inset-inline-start: auto;\n inset-inline-end: 0;\n }\n\n /*\n * A right-to-left page reverses the inline axis of a vertical writing mode too: `vertical-lr`\n * then runs from the bottom up, so the far end anchored above is the TOP. The fill goes back\n * to the start of the axis, which is now the bottom.\n */\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-fill {\n inset-inline-start: 0;\n inset-inline-end: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text {\n flex-direction: column-reverse;\n padding-inline: 0;\n padding-block: var(--vectis-space-2);\n }\n\n /*\n * The second selector is what neutralizes it, and it is written that way on purpose: it is\n * one step MORE specific than that rule, where the first selector alone would merely tie with\n * it and win by source order; a far more fragile arrangement.\n */\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text,\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-text {\n clip-path: inset(var(--progress-clip-end) -100vmax var(--progress-clip-start) -100vmax);\n }\n\n /*\n * At each extreme it is exactly flush with the edge without ever pulling away from it, which\n * makes the loop invisible and keeps the track from ever looking empty; no second bar is\n * needed. The easing carries the whole impression: a gradual entry, a quick crossing, a\n * damped exit.\n */\n .v-progress-linear[data-indeterminate] {\n overflow: hidden;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n /* The starting position is derived from this size, and the two must stay tied: that\n is what has the bar begin exactly off the track rather than half on it. */\n --progress-bar: 40%;\n /*\n * The anchoring is put back at the start of the axis, vertical case included; where a\n * measurable progress anchors at the far end instead.\n */\n inset-inline-start: 0;\n inset-inline-end: auto;\n inline-size: var(--progress-bar);\n /* The transition of a measurable progress has no place here: switching to this mode\n would otherwise be animated as the bar growing to its new size. */\n transition: none;\n animation: v-progress-linear-indeterminate var(--vectis-duration-1500) var(--vectis-ease-in-out)\n infinite;\n }\n\n @keyframes v-progress-linear-indeterminate {\n from {\n inset-inline-start: calc(-1 * var(--progress-bar));\n }\n\n to {\n inset-inline-start: 100%;\n }\n }\n\n /*\n * The same keyframes are simply read backwards, which changes nothing else BECAUSE the easing\n * curve is symmetric; an asymmetric one would need a second set of keyframes. A horizontal\n * right-to-left page needs nothing: the logical inset already follows the reading direction.\n */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate] .v-progress-linear-fill {\n animation-direction: reverse;\n }\n\n /* On a right-to-left page the vertical axis already runs upwards (see the trap above),\n so the keyframes are read forwards again. */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate]:dir(rtl)\n .v-progress-linear-fill {\n animation-direction: normal;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-progress-linear-fill,\n .v-progress-linear-text {\n transition: none;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n animation-duration: var(--vectis-duration-5000);\n }\n }\n\n /* `forced-color-adjust` inherits, so both copies of the text are given their colour here too. */\n @media (forced-colors: active) {\n .v-progress-linear {\n forced-color-adjust: none;\n background: Canvas;\n box-shadow: inset 0 0 0 var(--vectis-control-border-width) CanvasText;\n }\n\n .v-progress-linear-fill {\n background: Highlight;\n }\n\n .v-progress-linear-text {\n color: CanvasText;\n }\n\n .v-progress-linear-text[data-on-fill] {\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"VProgressLinear.js","names":["_sfc_main","VProgressLinear_vue_vue_type_script_setup_true_lang_default","VProgressLinear_default"],"sources":["../../../src/components/VProgressLinear/VProgressLinear.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * CSS draws the fill. JavaScript normalizes values shared by geometry, slots and progressbar\n * ARIA attributes.\n */\nimport { useId, useSlots } from 'vue'\n\nimport { useAriaLabel, useLabelledBy } from '../../composables/useAriaLabel'\nimport { useProgressValue } from '../../composables/useProgressValue'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useMessages } from '../../i18n/state'\n\n/** What the progress means, in colour. */\nexport type ProgressLinearTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\n/** How the track and the fill end. */\nexport type ProgressLinearShape = 'rounded' | 'square'\n\n/** The thickness of the bar: 2, 4, 8, 12 or 20 pixels. */\nexport type ProgressLinearSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\n/** Where the value is written: after the label, or inside the bar at its start, centre or end. */\nexport type ProgressLinearValuePosition = 'header' | 'start' | 'center' | 'end'\n\n/** Which way the bar fills. */\nexport type ProgressLinearOrientation = 'horizontal' | 'vertical'\n\n/** What the default slot receives. */\nexport interface ProgressLinearSlotProps {\n /** The value, brought back into the range. */\n value: number\n /** The bound, zero or more. */\n max: number\n /** How far along it is, as a percentage and unrounded. */\n percent: number\n}\n\ninterface ProgressLinearProps {\n /** How far along it is. Anything outside the range is brought back into it. */\n value?: number\n /**\n * What is progressing, shown above the bar and naming it for screen readers. Without it, the\n * bar is named from the design system dictionary; an `aria-label` or `aria-labelledby` of your\n * own takes precedence.\n */\n label?: string\n /** Hides the label visually. It still names the bar for screen readers. */\n hideLabel?: boolean\n /** What counts as finished. The other end is always zero. */\n max?: number\n /** Shows progress that cannot be measured, such as a server that reports no percentage. */\n indeterminate?: boolean\n /** What the progress means, expressed as a colour. */\n tone?: ProgressLinearTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. The\n * track's own shade is derived from it against the theme, so it follows the light and\n * the dark one.\n */\n color?: string\n /** The thickness of the bar. Only `xl` is thick enough to hold the value written inside it. */\n size?: ProgressLinearSize\n /** Whether the ends of the bar are rounded or square. */\n shape?: ProgressLinearShape\n /**\n * Writes the percentage. It is ignored while the progress is unmeasurable, there being no\n * figure to write.\n */\n showValue?: boolean\n /**\n * Where that text is written: at the end of the label's line, or inside the bar. On a vertical\n * bar the start is the zero end, hence the bottom.\n */\n valuePosition?: ProgressLinearValuePosition\n /** Turns the bar upright, filling from the bottom up. */\n orientation?: ProgressLinearOrientation\n}\n\nconst props = withDefaults(defineProps<ProgressLinearProps>(), {\n value: 0,\n label: undefined,\n hideLabel: false,\n max: 100,\n indeterminate: false,\n tone: 'accent',\n color: undefined,\n size: 'sm',\n shape: 'rounded',\n showValue: false,\n valuePosition: 'header',\n orientation: 'horizontal',\n})\n\ndefineSlots<{\n /** What to write instead of the percentage. */\n default?(props: ProgressLinearSlotProps): unknown\n}>()\n\n/* The percent sign, and the non-breaking space French puts before it where English puts\n nothing, are a convention of the language: they belong in the dictionary rather than\n in this file. Any other format goes through the slot above. */\nconst m = useMessages()\n\nconst {\n max: normalizedMax,\n clamped,\n fraction,\n percent,\n roundedPercent,\n} = useProgressValue(\n () => props.value,\n () => props.max,\n)\n\n// The root is a layout box holding the label and the bar: `class` and `style` stay on it, with\n// the tone and the custom properties the bar inherits, and every other attribute goes to the bar.\ndefineOptions({ inheritAttrs: false })\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// @a11y\n// A visible label names the bar by reference, unless the consumer named it themselves; without\n// one, the dictionary does. An indicator takes no name from the text inside it.\nconst labelId = useId()\nconst ariaLabel = useAriaLabel(() => (props.label ? undefined : m.value.progress.label))\nconst labelledBy = useLabelledBy(labelId, () => props.label)\n\n// Read during render rather than computed: `slots` is not reactive.\nconst slots = useSlots()\nconst showsValue = (inHeader: boolean) =>\n !props.indeterminate &&\n (props.showValue || !!slots.default) &&\n (props.valuePosition === 'header') === inHeader\n</script>\n\n<template>\n <div\n class=\"v-progress-linear-field v-tone\"\n :class=\"rootClass\"\n :data-tone=\"tone\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :data-orientation=\"orientation\"\n :data-size=\"size\"\n :style=\"[{ '--custom-color': color }, rootStyle]\"\n >\n <div v-if=\"(label && !hideLabel) || showsValue(true)\" class=\"v-progress-linear-header\">\n <span v-if=\"label && !hideLabel\" :id=\"labelId\" class=\"v-progress-linear-label\">{{\n label\n }}</span>\n <!-- The text inside the bar is presentational under the progressbar role; this copy,\n outside it, is hidden to match. -->\n <span v-if=\"showsValue(true)\" class=\"v-progress-linear-value\" aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </div>\n <span v-if=\"label && hideLabel\" :id=\"labelId\" class=\"v-visually-hidden\">{{ label }}</span>\n <div\n class=\"v-progress-linear\"\n role=\"progressbar\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"forwardedAttrs\"\n :data-shape=\"shape\"\n :data-orientation=\"orientation\"\n :data-value-position=\"valuePosition\"\n :data-indeterminate=\"indeterminate ? '' : undefined\"\n :aria-valuenow=\"indeterminate ? undefined : clamped\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"normalizedMax\"\n :style=\"{ '--fill-fraction': String(fraction) }\"\n >\n <span class=\"v-progress-linear-fill\" />\n <!--\n The same text twice, each copy cut at the fill's edge so that the two complete\n each other exactly: the first in the ordinary text colour over the empty track,\n the second over the filled part, coloured to contrast with it. The second is\n hidden from screen readers, being a duplicate of text already there.\n -->\n <template v-if=\"showsValue(false)\">\n <span class=\"v-progress-linear-text\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n <span class=\"v-progress-linear-text\" data-on-fill aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </template>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The root holds the label and the bar, and declares what the bar reads, so a consumer's style\n * on it (outside our layers) overrides the colours. The bar takes the whole length available:\n * sizing it is the consumer's business, through the parent or a width of their own on the root.\n */\n .v-progress-linear-field {\n --progress-thickness: var(--vectis-control-size-bar-thickness-sm);\n /* Fill, track and the text over the fill are the tone's solid, soft and on-solid\n colours, read from the shared table (`.v-tone`, set in the template). */\n --progress-fill: var(--tone-bg-solid);\n --progress-track: var(--tone-bg-soft);\n --progress-text-fallback: var(--tone-text-solid);\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n }\n\n .v-progress-linear-field[data-size='xs'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-xs);\n }\n\n .v-progress-linear-field[data-size='md'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-md);\n }\n\n .v-progress-linear-field[data-size='lg'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-lg);\n }\n\n .v-progress-linear-field[data-size='xl'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-xl);\n }\n\n .v-progress-linear-header {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n column-gap: var(--vectis-space-2);\n font-family: var(--vectis-text-family);\n }\n\n .v-progress-linear-label {\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n /* Pushed to the end even without a label before it. */\n .v-progress-linear-value {\n margin-inline-start: auto;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n font-variant-numeric: tabular-nums;\n }\n\n /* The element IS the track. */\n .v-progress-linear {\n position: relative;\n display: block;\n inline-size: 100%;\n block-size: var(--progress-thickness);\n border-radius: var(--vectis-radius-pill);\n background: var(--progress-track);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n .v-progress-linear[data-shape='square'] {\n border-radius: 0;\n }\n\n .v-progress-linear-fill {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n inline-size: calc(100% * var(--fill-fraction));\n border-radius: inherit;\n background: var(--progress-fill);\n /*\n * The fill is animated by changing its LENGTH, which the browser has to lay out again on\n * every frame. Scaling it would be cheaper, but a scale is physical: it would have to be\n * undone for the vertical orientation and again for a right-to-left page, where a logical\n * length simply works.\n */\n transition: inline-size var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n /*\n * The two copies are COMPLEMENTARY and never superimposed: this one is cut OUT of the filled\n * part, the other cut TO it, so every letter is painted exactly once. Removing either clip\n * raises no error and stays invisible for as long as both copies resolve to the same colour,\n * which happens wherever the adaptive colour function is unsupported.\n */\n .v-progress-linear-text {\n /*\n * The two insets of the cut: one on the edge the fill grows FROM, one on the edge it grows\n * towards. They are named after those roles rather than after physical sides, so the three\n * geometry rules further down; horizontal, right-to-left, vertical; all read the same pair.\n */\n --progress-clip-start: calc(100% * var(--fill-fraction));\n --progress-clip-end: -100vmax;\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: var(--vectis-space-2);\n color: var(--vectis-color-text);\n /*\n * The large negative inset on the two sides that do not carry the cut is what stops text\n * taller or wider than the bar from being cropped by its own clip.\n */\n clip-path: inset(-100vmax var(--progress-clip-end) -100vmax var(--progress-clip-start));\n /* The same duration and easing as the fill's own length, or the colour boundary\n would drift away from the fill's edge for the length of the transition. */\n transition: clip-path var(--vectis-duration-base) var(--vectis-ease-default);\n /* The bar itself is turned on its side in vertical mode; the text is put back\n upright here, since a label read sideways is not the point. */\n writing-mode: horizontal-tb;\n white-space: nowrap;\n pointer-events: none;\n }\n\n .v-progress-linear[data-value-position='start'] .v-progress-linear-text {\n justify-content: start;\n }\n\n .v-progress-linear[data-value-position='end'] .v-progress-linear-text {\n justify-content: end;\n }\n\n .v-progress-linear-text[data-on-fill] {\n /* The exact complement of the copy above: the cut moves to the other end of the\n axis, so the two together cover the whole bar and overlap nowhere. */\n --progress-clip-start: -100vmax;\n --progress-clip-end: calc(100% * (1 - var(--fill-fraction)));\n /*\n * The per-tone fallback colour. The adaptive one cannot simply be written as a second\n * declaration after it: because that declaration contains a var(), a browser with no\n * support does not reject it at parse time; it would win the cascade and only then turn\n * invalid, which resets the colour to inherited and leaves the fallback never applied.\n */\n color: var(--progress-text-fallback);\n }\n\n /* Where the adaptive colour function exists, the text picks black or white against\n whatever colour the fill ended up with. */\n @supports (color: contrast-color(red)) {\n .v-progress-linear-text[data-on-fill] {\n color: contrast-color(var(--progress-fill));\n }\n }\n\n /*\n * In a right-to-left page the fill grows from the right, so the two insets change physical\n * sides; the variables themselves keep their meaning.\n */\n .v-progress-linear:dir(rtl) .v-progress-linear-text {\n clip-path: inset(-100vmax var(--progress-clip-start) -100vmax var(--progress-clip-end));\n }\n\n /*\n * Putting zero at the bottom is not done by reversing the direction, which would also apply\n * to the text of the two copies: bidirectional reordering would then display \"50 %\" as \"%\n * 50\". The fill is anchored to the far end of the axis instead.\n */\n /*\n * Upright, the root carries the length, so a consumer's height on it sets the bar's: the bar\n * takes whatever the label leaves, its own inline size being the physical height.\n */\n .v-progress-linear-field[data-orientation='vertical'] {\n align-items: flex-start;\n block-size: var(--vectis-control-size-bar-length);\n }\n\n .v-progress-linear[data-orientation='vertical'] {\n flex: 1 1 0;\n writing-mode: vertical-lr;\n inline-size: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-fill {\n inset-inline-start: auto;\n inset-inline-end: 0;\n }\n\n /*\n * A right-to-left page reverses the inline axis of a vertical writing mode too: `vertical-lr`\n * then runs from the bottom up, so the far end anchored above is the TOP. The fill goes back\n * to the start of the axis, which is now the bottom.\n */\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-fill {\n inset-inline-start: 0;\n inset-inline-end: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text {\n flex-direction: column-reverse;\n padding-inline: 0;\n padding-block: var(--vectis-space-2);\n }\n\n /*\n * The second selector is what neutralizes it, and it is written that way on purpose: it is\n * one step MORE specific than that rule, where the first selector alone would merely tie with\n * it and win by source order; a far more fragile arrangement.\n */\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text,\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-text {\n clip-path: inset(var(--progress-clip-end) -100vmax var(--progress-clip-start) -100vmax);\n }\n\n /*\n * At each extreme it is exactly flush with the edge without ever pulling away from it, which\n * makes the loop invisible and keeps the track from ever looking empty; no second bar is\n * needed. The easing carries the whole impression: a gradual entry, a quick crossing, a\n * damped exit.\n */\n .v-progress-linear[data-indeterminate] {\n overflow: hidden;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n /* The starting position is derived from this size, and the two must stay tied: that\n is what has the bar begin exactly off the track rather than half on it. */\n --progress-bar: 40%;\n /*\n * The anchoring is put back at the start of the axis, vertical case included; where a\n * measurable progress anchors at the far end instead.\n */\n inset-inline-start: 0;\n inset-inline-end: auto;\n inline-size: var(--progress-bar);\n /* The transition of a measurable progress has no place here: switching to this mode\n would otherwise be animated as the bar growing to its new size. */\n transition: none;\n animation: v-progress-linear-indeterminate var(--vectis-duration-1500) var(--vectis-ease-in-out)\n infinite;\n }\n\n @keyframes v-progress-linear-indeterminate {\n from {\n inset-inline-start: calc(-1 * var(--progress-bar));\n }\n\n to {\n inset-inline-start: 100%;\n }\n }\n\n /*\n * The same keyframes are simply read backwards, which changes nothing else BECAUSE the easing\n * curve is symmetric; an asymmetric one would need a second set of keyframes. A horizontal\n * right-to-left page needs nothing: the logical inset already follows the reading direction.\n */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate] .v-progress-linear-fill {\n animation-direction: reverse;\n }\n\n /* On a right-to-left page the vertical axis already runs upwards (see the trap above),\n so the keyframes are read forwards again. */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate]:dir(rtl)\n .v-progress-linear-fill {\n animation-direction: normal;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-progress-linear-fill,\n .v-progress-linear-text {\n transition: none;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n animation-duration: var(--vectis-duration-5000);\n }\n }\n\n /* `forced-color-adjust` inherits, so both copies of the text are given their colour here too. */\n @media (forced-colors: active) {\n .v-progress-linear {\n forced-color-adjust: none;\n background: Canvas;\n box-shadow: inset 0 0 0 var(--vectis-control-border-width) CanvasText;\n }\n\n .v-progress-linear-fill {\n background: Highlight;\n }\n\n .v-progress-linear-text {\n color: CanvasText;\n }\n\n .v-progress-linear-text[data-on-fill] {\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":""}
|
package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { useMessages as e } from "../../i18n/state.js";
|
|
2
|
-
import {
|
|
3
|
-
import { useAriaLabel as n } from "../../composables/useAriaLabel.js";
|
|
2
|
+
import { useAriaLabel as t, useLabelledBy as n } from "../../composables/useAriaLabel.js";
|
|
4
3
|
import { useRootAttrs as r } from "../../composables/useRootAttrs.js";
|
|
5
4
|
import { useProgressValue as i } from "../../composables/useProgressValue.js";
|
|
6
|
-
import { Fragment as a,
|
|
5
|
+
import { Fragment as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createTextVNode as l, defineComponent as u, mergeProps as d, normalizeClass as f, normalizeStyle as p, openBlock as m, renderSlot as h, toDisplayString as g, unref as _, useId as v, useSlots as y } from "vue";
|
|
7
6
|
//#region src/components/VProgressLinear/VProgressLinear.vue?vue&type=script&setup=true&lang.ts
|
|
8
7
|
var b = [
|
|
9
8
|
"data-tone",
|
|
10
9
|
"data-custom",
|
|
11
|
-
"data-orientation"
|
|
12
|
-
|
|
10
|
+
"data-orientation",
|
|
11
|
+
"data-size"
|
|
12
|
+
], x = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "v-progress-linear-header"
|
|
15
|
+
}, S = ["id"], C = {
|
|
16
|
+
key: 1,
|
|
17
|
+
class: "v-progress-linear-value",
|
|
18
|
+
"aria-hidden": "true"
|
|
19
|
+
}, w = ["id"], T = [
|
|
13
20
|
"aria-labelledby",
|
|
14
21
|
"aria-label",
|
|
15
22
|
"data-shape",
|
|
@@ -18,11 +25,11 @@ var b = [
|
|
|
18
25
|
"data-indeterminate",
|
|
19
26
|
"aria-valuenow",
|
|
20
27
|
"aria-valuemax"
|
|
21
|
-
],
|
|
28
|
+
], E = { class: "v-progress-linear-text" }, D = {
|
|
22
29
|
class: "v-progress-linear-text",
|
|
23
30
|
"data-on-fill": "",
|
|
24
31
|
"aria-hidden": "true"
|
|
25
|
-
},
|
|
32
|
+
}, O = /*@__PURE__*/ u({
|
|
26
33
|
inheritAttrs: !1,
|
|
27
34
|
__name: "VProgressLinear",
|
|
28
35
|
props: {
|
|
@@ -39,56 +46,66 @@ var b = [
|
|
|
39
46
|
},
|
|
40
47
|
tone: { default: "accent" },
|
|
41
48
|
color: { default: void 0 },
|
|
42
|
-
|
|
49
|
+
size: { default: "sm" },
|
|
43
50
|
shape: { default: "rounded" },
|
|
44
51
|
showValue: {
|
|
45
52
|
type: Boolean,
|
|
46
53
|
default: !1
|
|
47
54
|
},
|
|
48
|
-
valuePosition: { default: "
|
|
55
|
+
valuePosition: { default: "header" },
|
|
49
56
|
orientation: { default: "horizontal" }
|
|
50
57
|
},
|
|
51
|
-
setup(
|
|
52
|
-
let
|
|
53
|
-
return (e,
|
|
54
|
-
class:
|
|
55
|
-
"data-tone":
|
|
56
|
-
"data-custom":
|
|
57
|
-
"data-orientation":
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
58
|
+
setup(u) {
|
|
59
|
+
let O = u, k = e(), { max: A, clamped: j, fraction: M, percent: N, roundedPercent: P } = i(() => O.value, () => O.max), { rootClass: F, rootStyle: I, forwardedAttrs: L } = r(), R = v(), z = t(() => O.label ? void 0 : k.value.progress.label), B = n(R, () => O.label), V = y(), H = (e) => !O.indeterminate && (O.showValue || !!V.default) && O.valuePosition === "header" === e;
|
|
60
|
+
return (e, t) => (m(), s("div", {
|
|
61
|
+
class: f(["v-progress-linear-field v-tone", _(F)]),
|
|
62
|
+
"data-tone": u.tone,
|
|
63
|
+
"data-custom": u.color === void 0 ? void 0 : "",
|
|
64
|
+
"data-orientation": u.orientation,
|
|
65
|
+
"data-size": u.size,
|
|
66
|
+
style: p([{ "--custom-color": u.color }, _(I)])
|
|
67
|
+
}, [
|
|
68
|
+
u.label && !u.hideLabel || H(!0) ? (m(), s("div", x, [u.label && !u.hideLabel ? (m(), s("span", {
|
|
69
|
+
key: 0,
|
|
70
|
+
id: _(R),
|
|
71
|
+
class: "v-progress-linear-label"
|
|
72
|
+
}, g(u.label), 9, S)) : o("", !0), H(!0) ? (m(), s("span", C, [h(e.$slots, "default", {
|
|
73
|
+
value: _(j),
|
|
74
|
+
max: _(A),
|
|
75
|
+
percent: _(N)
|
|
76
|
+
}, () => [l(g(_(k).progress.percent(_(P))), 1)])])) : o("", !0)])) : o("", !0),
|
|
77
|
+
u.label && u.hideLabel ? (m(), s("span", {
|
|
78
|
+
key: 1,
|
|
79
|
+
id: _(R),
|
|
80
|
+
class: "v-visually-hidden"
|
|
81
|
+
}, g(u.label), 9, w)) : o("", !0),
|
|
82
|
+
c("div", d({
|
|
83
|
+
class: "v-progress-linear",
|
|
84
|
+
role: "progressbar",
|
|
85
|
+
"aria-labelledby": _(B),
|
|
86
|
+
"aria-label": _(z)
|
|
87
|
+
}, _(L), {
|
|
88
|
+
"data-shape": u.shape,
|
|
89
|
+
"data-orientation": u.orientation,
|
|
90
|
+
"data-value-position": u.valuePosition,
|
|
91
|
+
"data-indeterminate": u.indeterminate ? "" : void 0,
|
|
92
|
+
"aria-valuenow": u.indeterminate ? void 0 : _(j),
|
|
93
|
+
"aria-valuemin": "0",
|
|
94
|
+
"aria-valuemax": _(A),
|
|
95
|
+
style: { "--fill-fraction": String(_(M)) }
|
|
96
|
+
}), [t[0] ||= c("span", { class: "v-progress-linear-fill" }, null, -1), H(!1) ? (m(), s(a, { key: 0 }, [c("span", E, [h(e.$slots, "default", {
|
|
97
|
+
value: _(j),
|
|
98
|
+
max: _(A),
|
|
99
|
+
percent: _(N)
|
|
100
|
+
}, () => [l(g(_(k).progress.percent(_(P))), 1)])]), c("span", D, [h(e.$slots, "default", {
|
|
101
|
+
value: _(j),
|
|
102
|
+
max: _(A),
|
|
103
|
+
percent: _(N)
|
|
104
|
+
}, () => [l(g(_(k).progress.percent(_(P))), 1)])])], 64)) : o("", !0)], 16, T)
|
|
105
|
+
], 14, b));
|
|
89
106
|
}
|
|
90
107
|
});
|
|
91
108
|
//#endregion
|
|
92
|
-
export {
|
|
109
|
+
export { O as default };
|
|
93
110
|
|
|
94
111
|
//# sourceMappingURL=VProgressLinear.vue_vue_type_script_setup_true_lang.js.map
|
package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VProgressLinear.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_toDisplayString","_createCommentVNode","_createElementVNode","_mergeProps","_Fragment","_renderSlot","_createTextVNode","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","VProgressLinear_vue_vue_type_script_setup_true_lang_default","props","__props","m","useMessages","normalizedMax","useProgressValue","useRootAttrs","labelId","useId","ariaLabel","useAriaLabel","labelledBy","computed","attrs","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","px","rootStyle","toDisplayString","createCommentVNode","createElementVNode","mergeProps","forwardedAttrs","clamped","fraction","_cache","_ctx","Fragment","renderSlot","percent","createTextVNode","roundedPercent"],"sources":["../../../src/components/VProgressLinear/VProgressLinear.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * CSS draws the fill. JavaScript normalizes values shared by geometry, slots and progressbar\n * ARIA attributes.\n */\nimport { computed, useId } from 'vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useProgressValue } from '../../composables/useProgressValue'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useMessages } from '../../i18n/state'\nimport { px } from '../../utils/css'\n\n/** What the progress means, in colour. */\nexport type ProgressLinearTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\n/** How the track and the fill end. */\nexport type ProgressLinearShape = 'rounded' | 'square'\n\n/** Where the value sits along the bar. */\nexport type ProgressLinearValuePosition = 'start' | 'center' | 'end'\n\n/** Which way the bar fills. */\nexport type ProgressLinearOrientation = 'horizontal' | 'vertical'\n\n/** What the default slot receives. */\nexport interface ProgressLinearSlotProps {\n /** The value, brought back into the range. */\n value: number\n /** The bound, zero or more. */\n max: number\n /** How far along it is, as a percentage and unrounded. */\n percent: number\n}\n\ninterface ProgressLinearProps {\n /** How far along it is. Anything outside the range is brought back into it. */\n value?: number\n /**\n * What is progressing, shown above the bar and naming it for screen readers. Without it, the\n * bar is named from the design system dictionary; an `aria-label` or `aria-labelledby` of your\n * own takes precedence.\n */\n label?: string\n /** Hides the label visually. It still names the bar for screen readers. */\n hideLabel?: boolean\n /** What counts as finished. The other end is always zero. */\n max?: number\n /** Shows progress that cannot be measured, such as a server that reports no percentage. */\n indeterminate?: boolean\n /** What the progress means, expressed as a colour. */\n tone?: ProgressLinearTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. The\n * track's own shade is derived from it against the theme, so it follows the light and\n * the dark one.\n */\n color?: string\n /**\n * How thick the bar is, always in PIXELS: `12` and `'12'` both give 12px. It is 4px by\n * default, and showing text inside a bar that thin needs an explicit thickness.\n */\n thickness?: number | string\n /** Whether the ends of the bar are rounded or square. */\n shape?: ProgressLinearShape\n /**\n * Writes the percentage inside the bar. It is ignored while the progress is\n * unmeasurable, there being no figure to write.\n */\n showValue?: boolean\n /**\n * Where that text sits along the bar. On a vertical bar the start is the zero end,\n * hence the bottom.\n */\n valuePosition?: ProgressLinearValuePosition\n /** Turns the bar upright, filling from the bottom up. */\n orientation?: ProgressLinearOrientation\n}\n\nconst props = withDefaults(defineProps<ProgressLinearProps>(), {\n value: 0,\n label: undefined,\n hideLabel: false,\n max: 100,\n indeterminate: false,\n tone: 'accent',\n color: undefined,\n thickness: undefined,\n shape: 'rounded',\n showValue: false,\n valuePosition: 'center',\n orientation: 'horizontal',\n})\n\ndefineSlots<{\n /** What to write inside the bar instead of the percentage. */\n default?(props: ProgressLinearSlotProps): unknown\n}>()\n\n/* The percent sign, and the non-breaking space French puts before it where English puts\n nothing, are a convention of the language: they belong in the dictionary rather than\n in this file. Any other format goes through the slot above. */\nconst m = useMessages()\n\nconst {\n max: normalizedMax,\n clamped,\n fraction,\n percent,\n roundedPercent,\n} = useProgressValue(\n () => props.value,\n () => props.max,\n)\n\n// The root is a layout box holding the label and the bar: `class` and `style` stay on it, with\n// the tone and the custom properties the bar inherits, and every other attribute goes to the bar.\ndefineOptions({ inheritAttrs: false })\nconst { attrs, rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// @a11y\n// A visible label names the bar by reference, unless the consumer named it themselves; without\n// one, the dictionary does. An indicator takes no name from the text inside it.\nconst labelId = useId()\nconst ariaLabel = useAriaLabel(() => (props.label ? undefined : m.value.progress.label))\nconst labelledBy = computed(() =>\n props.label && attrs['aria-label'] == null && attrs['aria-labelledby'] == null\n ? labelId\n : undefined,\n)\n</script>\n\n<template>\n <div\n class=\"v-progress-linear-field v-tone\"\n :class=\"rootClass\"\n :data-tone=\"tone\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :data-orientation=\"orientation\"\n :style=\"[{ '--custom-color': color, '--progress-thickness': px(thickness) }, rootStyle]\"\n >\n <span\n v-if=\"label\"\n :id=\"labelId\"\n class=\"v-progress-linear-label\"\n :class=\"{ 'v-visually-hidden': hideLabel }\"\n >{{ label }}</span\n >\n <div\n class=\"v-progress-linear\"\n role=\"progressbar\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"forwardedAttrs\"\n :data-shape=\"shape\"\n :data-orientation=\"orientation\"\n :data-value-position=\"valuePosition\"\n :data-indeterminate=\"indeterminate ? '' : undefined\"\n :aria-valuenow=\"indeterminate ? undefined : clamped\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"normalizedMax\"\n :style=\"{ '--fill-fraction': String(fraction) }\"\n >\n <span class=\"v-progress-linear-fill\" />\n <!--\n The same text twice, each copy cut at the fill's edge so that the two complete\n each other exactly: the first in the ordinary text colour over the empty track,\n the second over the filled part, coloured to contrast with it. The second is\n hidden from screen readers, being a duplicate of text already there.\n -->\n <template v-if=\"!indeterminate && (showValue || $slots.default)\">\n <span class=\"v-progress-linear-text\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n <span class=\"v-progress-linear-text\" data-on-fill aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </template>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The root holds the label and the bar, and declares what the bar reads, so a consumer's style\n * on it (outside our layers) overrides the thickness and the colours. The bar takes the whole\n * length available: sizing it is the consumer's business, through the parent or a width of\n * their own on the root.\n */\n .v-progress-linear-field {\n --progress-thickness: var(--vectis-control-size-progress-linear-thickness);\n /* Fill, track and the text over the fill are the tone's solid, soft and on-solid\n colours, read from the shared table (`.v-tone`, set in the template). */\n --progress-fill: var(--tone-bg-solid);\n --progress-track: var(--tone-bg-soft);\n --progress-text-fallback: var(--tone-text-solid);\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n }\n\n .v-progress-linear-label {\n color: var(--vectis-color-text);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n /* The element IS the track. */\n .v-progress-linear {\n position: relative;\n display: block;\n inline-size: 100%;\n block-size: var(--progress-thickness);\n border-radius: var(--vectis-radius-pill);\n background: var(--progress-track);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n .v-progress-linear[data-shape='square'] {\n border-radius: 0;\n }\n\n .v-progress-linear-fill {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n inline-size: calc(100% * var(--fill-fraction));\n border-radius: inherit;\n background: var(--progress-fill);\n /*\n * The fill is animated by changing its LENGTH, which the browser has to lay out again on\n * every frame. Scaling it would be cheaper, but a scale is physical: it would have to be\n * undone for the vertical orientation and again for a right-to-left page, where a logical\n * length simply works.\n */\n transition: inline-size var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n /*\n * The two copies are COMPLEMENTARY and never superimposed: this one is cut OUT of the filled\n * part, the other cut TO it, so every letter is painted exactly once. Removing either clip\n * raises no error and stays invisible for as long as both copies resolve to the same colour,\n * which happens wherever the adaptive colour function is unsupported.\n */\n .v-progress-linear-text {\n /*\n * The two insets of the cut: one on the edge the fill grows FROM, one on the edge it grows\n * towards. They are named after those roles rather than after physical sides, so the three\n * geometry rules further down; horizontal, right-to-left, vertical; all read the same pair.\n */\n --progress-clip-start: calc(100% * var(--fill-fraction));\n --progress-clip-end: -100vmax;\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: var(--vectis-space-2);\n color: var(--vectis-color-text);\n /*\n * The large negative inset on the two sides that do not carry the cut is what stops text\n * taller or wider than the bar from being cropped by its own clip.\n */\n clip-path: inset(-100vmax var(--progress-clip-end) -100vmax var(--progress-clip-start));\n /* The same duration and easing as the fill's own length, or the colour boundary\n would drift away from the fill's edge for the length of the transition. */\n transition: clip-path var(--vectis-duration-base) var(--vectis-ease-default);\n /* The bar itself is turned on its side in vertical mode; the text is put back\n upright here, since a label read sideways is not the point. */\n writing-mode: horizontal-tb;\n white-space: nowrap;\n pointer-events: none;\n }\n\n .v-progress-linear[data-value-position='start'] .v-progress-linear-text {\n justify-content: start;\n }\n\n .v-progress-linear[data-value-position='end'] .v-progress-linear-text {\n justify-content: end;\n }\n\n .v-progress-linear-text[data-on-fill] {\n /* The exact complement of the copy above: the cut moves to the other end of the\n axis, so the two together cover the whole bar and overlap nowhere. */\n --progress-clip-start: -100vmax;\n --progress-clip-end: calc(100% * (1 - var(--fill-fraction)));\n /*\n * The per-tone fallback colour. The adaptive one cannot simply be written as a second\n * declaration after it: because that declaration contains a var(), a browser with no\n * support does not reject it at parse time; it would win the cascade and only then turn\n * invalid, which resets the colour to inherited and leaves the fallback never applied.\n */\n color: var(--progress-text-fallback);\n }\n\n /* Where the adaptive colour function exists, the text picks black or white against\n whatever colour the fill ended up with. */\n @supports (color: contrast-color(red)) {\n .v-progress-linear-text[data-on-fill] {\n color: contrast-color(var(--progress-fill));\n }\n }\n\n /*\n * In a right-to-left page the fill grows from the right, so the two insets change physical\n * sides; the variables themselves keep their meaning.\n */\n .v-progress-linear:dir(rtl) .v-progress-linear-text {\n clip-path: inset(-100vmax var(--progress-clip-start) -100vmax var(--progress-clip-end));\n }\n\n /*\n * Putting zero at the bottom is not done by reversing the direction, which would also apply\n * to the text of the two copies: bidirectional reordering would then display \"50 %\" as \"%\n * 50\". The fill is anchored to the far end of the axis instead.\n */\n /*\n * Upright, the root carries the length, so a consumer's height on it sets the bar's: the bar\n * takes whatever the label leaves, its own inline size being the physical height.\n */\n .v-progress-linear-field[data-orientation='vertical'] {\n align-items: flex-start;\n block-size: var(--vectis-control-size-progress-linear-length);\n }\n\n .v-progress-linear[data-orientation='vertical'] {\n flex: 1 1 0;\n writing-mode: vertical-lr;\n inline-size: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-fill {\n inset-inline-start: auto;\n inset-inline-end: 0;\n }\n\n /*\n * A right-to-left page reverses the inline axis of a vertical writing mode too: `vertical-lr`\n * then runs from the bottom up, so the far end anchored above is the TOP. The fill goes back\n * to the start of the axis, which is now the bottom.\n */\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-fill {\n inset-inline-start: 0;\n inset-inline-end: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text {\n flex-direction: column-reverse;\n padding-inline: 0;\n padding-block: var(--vectis-space-2);\n }\n\n /*\n * The second selector is what neutralizes it, and it is written that way on purpose: it is\n * one step MORE specific than that rule, where the first selector alone would merely tie with\n * it and win by source order; a far more fragile arrangement.\n */\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text,\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-text {\n clip-path: inset(var(--progress-clip-end) -100vmax var(--progress-clip-start) -100vmax);\n }\n\n /*\n * At each extreme it is exactly flush with the edge without ever pulling away from it, which\n * makes the loop invisible and keeps the track from ever looking empty; no second bar is\n * needed. The easing carries the whole impression: a gradual entry, a quick crossing, a\n * damped exit.\n */\n .v-progress-linear[data-indeterminate] {\n overflow: hidden;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n /* The starting position is derived from this size, and the two must stay tied: that\n is what has the bar begin exactly off the track rather than half on it. */\n --progress-bar: 40%;\n /*\n * The anchoring is put back at the start of the axis, vertical case included; where a\n * measurable progress anchors at the far end instead.\n */\n inset-inline-start: 0;\n inset-inline-end: auto;\n inline-size: var(--progress-bar);\n /* The transition of a measurable progress has no place here: switching to this mode\n would otherwise be animated as the bar growing to its new size. */\n transition: none;\n animation: v-progress-linear-indeterminate var(--vectis-duration-1500) var(--vectis-ease-in-out)\n infinite;\n }\n\n @keyframes v-progress-linear-indeterminate {\n from {\n inset-inline-start: calc(-1 * var(--progress-bar));\n }\n\n to {\n inset-inline-start: 100%;\n }\n }\n\n /*\n * The same keyframes are simply read backwards, which changes nothing else BECAUSE the easing\n * curve is symmetric; an asymmetric one would need a second set of keyframes. A horizontal\n * right-to-left page needs nothing: the logical inset already follows the reading direction.\n */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate] .v-progress-linear-fill {\n animation-direction: reverse;\n }\n\n /* On a right-to-left page the vertical axis already runs upwards (see the trap above),\n so the keyframes are read forwards again. */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate]:dir(rtl)\n .v-progress-linear-fill {\n animation-direction: normal;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-progress-linear-fill,\n .v-progress-linear-text {\n transition: none;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n animation-duration: var(--vectis-duration-5000);\n }\n }\n\n /* `forced-color-adjust` inherits, so both copies of the text are given their colour here too. */\n @media (forced-colors: active) {\n .v-progress-linear {\n forced-color-adjust: none;\n background: Canvas;\n box-shadow: inset 0 0 0 var(--vectis-control-border-width) CanvasText;\n }\n\n .v-progress-linear-fill {\n background: Highlight;\n }\n\n .v-progress-linear-text {\n color: CanvasText;\n }\n\n .v-progress-linear-text[data-on-fill] {\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+EA,IAAMmB,IAAQC,GAuBRC,IAAIC,EAAY,GAEhB,EACJ,KAAKC,GACL,YACA,aACA,YACA,sBACEC,QACIL,EAAM,aACNA,EAAM,GACd,GAKM,EAAE,UAAO,cAAW,cAAW,sBAAmBM,EAAa,GAK/DC,IAAUC,EAAM,GAChBC,IAAYC,QAAoBV,EAAM,QAAQ,KAAA,IAAYE,EAAE,MAAM,SAAS,KAAM,GACjFS,IAAaC,QACjBZ,EAAM,SAASa,EAAM,iBAAiB,QAAQA,EAAM,sBAAsB,OACtEN,IACA,KAAA,CACN;oBAIEzB,EAAA,GAAAC,EAkDM,OAAA;GAjDJ,OAAKC,EAAA,CAAC,kCACEC,EAAAiC,CAAA,CAAS,CAAA;GAChB,aAAWjB,EAAA;GACX,eAAaA,EAAA,UAAU,KAAA,IAAiB,KAAA,IAAR;GAChC,oBAAkBA,EAAA;GAClB,OAAKf,EAAA,CAAA;IAAA,kBAAuBe,EAAA;IAAK,wBAA0BhB,EAAAmC,CAAA,CAAE,CAACnB,EAAA,SAAS;GAAA,GAAKhB,EAAAoC,CAAA,CAAS,CAAA;EAG9E,GAAA,CAAApB,EAAA,SADRnB,EAAA,GAAAC,EAMC,QAAA;;GAJE,IAAIE,EAAAsB,CAAA;GACL,OAAKvB,EAAA,CAAC,2BAAyB,EAAA,qBACAiB,EAAA,UAAS,CAAA,CAAA;EACpC,GAAAd,EAAAc,EAAA,KAAK,GAAA,IAAAN,CAAA,KAAA4B,EAAA,IAAA,EAAA,GAEXlC,EAkCM,OAlCNC,EAkCM;GAjCJ,OAAM;GACN,MAAK;GACJ,mBAAiBqB,EAAA;GACjB,cAAY1B,EAAAwB,CAAA;EACL,GAAAxB,EAAAyC,CAAA,GAAc;GACrB,cAAYzB,EAAA;GACZ,oBAAkBA,EAAA;GAClB,uBAAqBA,EAAA;GACrB,sBAAoBA,EAAA,gBAAa,KAAQ,KAAA;GACzC,iBAAeA,EAAA,gBAAgB,KAAA,IAAYhB,EAAA0C,CAAA;GAC5C,iBAAc;GACb,iBAAe1C,EAAAmB,CAAA;GACf,OAAK,EAAA,mBAAuB,OAAOnB,EAAA2C,CAAA,CAAQ,EAAA;EAE5C,CAAA,GAAA,CAAA,AAAAC,EAAA,OAAAxC,EAAuC,QAAA,EAAjC,OAAM,yBAAwB,GAAA,MAAA,EAAA,GAOnB,CAAAY,EAAA,kBAAkBA,EAAA,aAAapB,EAAAA,OAAO,YAAvDC,EAAA,GAAAC,EAWWQ,GAAA,EAAA,KAAA,EAAA,GAAA,CAVTF,EAIO,QAJPQ,GAIO,CAHLL,EAEOsC,EAAA,QAAA,WAAA;GAFA,OAAO7C,EAAA0C,CAAA;GAAU,KAAK1C,EAAAmB,CAAA;GAAgB,SAASnB,EAAAgD,CAAA;EAAtD,SAEO,CADFxC,EAAAN,EAAAF,EAAAiB,CAAA,CAAC,CAAC,SAAS,QAAQjB,EAAAkD,CAAA,CAAc,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAGxC9C,EAIO,QAJPS,GAIO,CAHLN,EAEOsC,EAAA,QAAA,WAAA;GAFA,OAAO7C,EAAA0C,CAAA;GAAU,KAAK1C,EAAAmB,CAAA;GAAgB,SAASnB,EAAAgD,CAAA;EAAtD,SAEO,CADFxC,EAAAN,EAAAF,EAAAiB,CAAA,CAAC,CAAC,SAAS,QAAQjB,EAAAkD,CAAA,CAAc,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,KAAAZ,EAAA,IAAA,EAAA,CAAA,GAAA,IAAA3B,CAAA,CAAA,GAAA,IAAAF,CAAA"}
|
|
1
|
+
{"version":3,"file":"VProgressLinear.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_toDisplayString","_createCommentVNode","_renderSlot","_createTextVNode","_createElementVNode","_mergeProps","_Fragment","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","VProgressLinear_vue_vue_type_script_setup_true_lang_default","props","__props","m","useMessages","normalizedMax","useProgressValue","useRootAttrs","labelId","useId","ariaLabel","useAriaLabel","labelledBy","useLabelledBy","slots","useSlots","showsValue","inHeader","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","rootStyle","toDisplayString","createCommentVNode","renderSlot","_ctx","clamped","percent","createTextVNode","roundedPercent","createElementVNode","mergeProps","forwardedAttrs","fraction","_cache","Fragment"],"sources":["../../../src/components/VProgressLinear/VProgressLinear.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * CSS draws the fill. JavaScript normalizes values shared by geometry, slots and progressbar\n * ARIA attributes.\n */\nimport { useId, useSlots } from 'vue'\n\nimport { useAriaLabel, useLabelledBy } from '../../composables/useAriaLabel'\nimport { useProgressValue } from '../../composables/useProgressValue'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useMessages } from '../../i18n/state'\n\n/** What the progress means, in colour. */\nexport type ProgressLinearTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\n/** How the track and the fill end. */\nexport type ProgressLinearShape = 'rounded' | 'square'\n\n/** The thickness of the bar: 2, 4, 8, 12 or 20 pixels. */\nexport type ProgressLinearSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\n/** Where the value is written: after the label, or inside the bar at its start, centre or end. */\nexport type ProgressLinearValuePosition = 'header' | 'start' | 'center' | 'end'\n\n/** Which way the bar fills. */\nexport type ProgressLinearOrientation = 'horizontal' | 'vertical'\n\n/** What the default slot receives. */\nexport interface ProgressLinearSlotProps {\n /** The value, brought back into the range. */\n value: number\n /** The bound, zero or more. */\n max: number\n /** How far along it is, as a percentage and unrounded. */\n percent: number\n}\n\ninterface ProgressLinearProps {\n /** How far along it is. Anything outside the range is brought back into it. */\n value?: number\n /**\n * What is progressing, shown above the bar and naming it for screen readers. Without it, the\n * bar is named from the design system dictionary; an `aria-label` or `aria-labelledby` of your\n * own takes precedence.\n */\n label?: string\n /** Hides the label visually. It still names the bar for screen readers. */\n hideLabel?: boolean\n /** What counts as finished. The other end is always zero. */\n max?: number\n /** Shows progress that cannot be measured, such as a server that reports no percentage. */\n indeterminate?: boolean\n /** What the progress means, expressed as a colour. */\n tone?: ProgressLinearTone\n /**\n * A colour of your own (hex, CSS name or `oklch()`), which replaces the tone. The\n * track's own shade is derived from it against the theme, so it follows the light and\n * the dark one.\n */\n color?: string\n /** The thickness of the bar. Only `xl` is thick enough to hold the value written inside it. */\n size?: ProgressLinearSize\n /** Whether the ends of the bar are rounded or square. */\n shape?: ProgressLinearShape\n /**\n * Writes the percentage. It is ignored while the progress is unmeasurable, there being no\n * figure to write.\n */\n showValue?: boolean\n /**\n * Where that text is written: at the end of the label's line, or inside the bar. On a vertical\n * bar the start is the zero end, hence the bottom.\n */\n valuePosition?: ProgressLinearValuePosition\n /** Turns the bar upright, filling from the bottom up. */\n orientation?: ProgressLinearOrientation\n}\n\nconst props = withDefaults(defineProps<ProgressLinearProps>(), {\n value: 0,\n label: undefined,\n hideLabel: false,\n max: 100,\n indeterminate: false,\n tone: 'accent',\n color: undefined,\n size: 'sm',\n shape: 'rounded',\n showValue: false,\n valuePosition: 'header',\n orientation: 'horizontal',\n})\n\ndefineSlots<{\n /** What to write instead of the percentage. */\n default?(props: ProgressLinearSlotProps): unknown\n}>()\n\n/* The percent sign, and the non-breaking space French puts before it where English puts\n nothing, are a convention of the language: they belong in the dictionary rather than\n in this file. Any other format goes through the slot above. */\nconst m = useMessages()\n\nconst {\n max: normalizedMax,\n clamped,\n fraction,\n percent,\n roundedPercent,\n} = useProgressValue(\n () => props.value,\n () => props.max,\n)\n\n// The root is a layout box holding the label and the bar: `class` and `style` stay on it, with\n// the tone and the custom properties the bar inherits, and every other attribute goes to the bar.\ndefineOptions({ inheritAttrs: false })\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// @a11y\n// A visible label names the bar by reference, unless the consumer named it themselves; without\n// one, the dictionary does. An indicator takes no name from the text inside it.\nconst labelId = useId()\nconst ariaLabel = useAriaLabel(() => (props.label ? undefined : m.value.progress.label))\nconst labelledBy = useLabelledBy(labelId, () => props.label)\n\n// Read during render rather than computed: `slots` is not reactive.\nconst slots = useSlots()\nconst showsValue = (inHeader: boolean) =>\n !props.indeterminate &&\n (props.showValue || !!slots.default) &&\n (props.valuePosition === 'header') === inHeader\n</script>\n\n<template>\n <div\n class=\"v-progress-linear-field v-tone\"\n :class=\"rootClass\"\n :data-tone=\"tone\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :data-orientation=\"orientation\"\n :data-size=\"size\"\n :style=\"[{ '--custom-color': color }, rootStyle]\"\n >\n <div v-if=\"(label && !hideLabel) || showsValue(true)\" class=\"v-progress-linear-header\">\n <span v-if=\"label && !hideLabel\" :id=\"labelId\" class=\"v-progress-linear-label\">{{\n label\n }}</span>\n <!-- The text inside the bar is presentational under the progressbar role; this copy,\n outside it, is hidden to match. -->\n <span v-if=\"showsValue(true)\" class=\"v-progress-linear-value\" aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </div>\n <span v-if=\"label && hideLabel\" :id=\"labelId\" class=\"v-visually-hidden\">{{ label }}</span>\n <div\n class=\"v-progress-linear\"\n role=\"progressbar\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"forwardedAttrs\"\n :data-shape=\"shape\"\n :data-orientation=\"orientation\"\n :data-value-position=\"valuePosition\"\n :data-indeterminate=\"indeterminate ? '' : undefined\"\n :aria-valuenow=\"indeterminate ? undefined : clamped\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"normalizedMax\"\n :style=\"{ '--fill-fraction': String(fraction) }\"\n >\n <span class=\"v-progress-linear-fill\" />\n <!--\n The same text twice, each copy cut at the fill's edge so that the two complete\n each other exactly: the first in the ordinary text colour over the empty track,\n the second over the filled part, coloured to contrast with it. The second is\n hidden from screen readers, being a duplicate of text already there.\n -->\n <template v-if=\"showsValue(false)\">\n <span class=\"v-progress-linear-text\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n <span class=\"v-progress-linear-text\" data-on-fill aria-hidden=\"true\">\n <slot :value=\"clamped\" :max=\"normalizedMax\" :percent=\"percent\">\n {{ m.progress.percent(roundedPercent) }}\n </slot>\n </span>\n </template>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The root holds the label and the bar, and declares what the bar reads, so a consumer's style\n * on it (outside our layers) overrides the colours. The bar takes the whole length available:\n * sizing it is the consumer's business, through the parent or a width of their own on the root.\n */\n .v-progress-linear-field {\n --progress-thickness: var(--vectis-control-size-bar-thickness-sm);\n /* Fill, track and the text over the fill are the tone's solid, soft and on-solid\n colours, read from the shared table (`.v-tone`, set in the template). */\n --progress-fill: var(--tone-bg-solid);\n --progress-track: var(--tone-bg-soft);\n --progress-text-fallback: var(--tone-text-solid);\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n }\n\n .v-progress-linear-field[data-size='xs'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-xs);\n }\n\n .v-progress-linear-field[data-size='md'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-md);\n }\n\n .v-progress-linear-field[data-size='lg'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-lg);\n }\n\n .v-progress-linear-field[data-size='xl'] {\n --progress-thickness: var(--vectis-control-size-bar-thickness-xl);\n }\n\n .v-progress-linear-header {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n column-gap: var(--vectis-space-2);\n font-family: var(--vectis-text-family);\n }\n\n .v-progress-linear-label {\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n /* Pushed to the end even without a label before it. */\n .v-progress-linear-value {\n margin-inline-start: auto;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n font-variant-numeric: tabular-nums;\n }\n\n /* The element IS the track. */\n .v-progress-linear {\n position: relative;\n display: block;\n inline-size: 100%;\n block-size: var(--progress-thickness);\n border-radius: var(--vectis-radius-pill);\n background: var(--progress-track);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-control-weight);\n line-height: var(--vectis-text-control-leading);\n }\n\n .v-progress-linear[data-shape='square'] {\n border-radius: 0;\n }\n\n .v-progress-linear-fill {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n inline-size: calc(100% * var(--fill-fraction));\n border-radius: inherit;\n background: var(--progress-fill);\n /*\n * The fill is animated by changing its LENGTH, which the browser has to lay out again on\n * every frame. Scaling it would be cheaper, but a scale is physical: it would have to be\n * undone for the vertical orientation and again for a right-to-left page, where a logical\n * length simply works.\n */\n transition: inline-size var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n /*\n * The two copies are COMPLEMENTARY and never superimposed: this one is cut OUT of the filled\n * part, the other cut TO it, so every letter is painted exactly once. Removing either clip\n * raises no error and stays invisible for as long as both copies resolve to the same colour,\n * which happens wherever the adaptive colour function is unsupported.\n */\n .v-progress-linear-text {\n /*\n * The two insets of the cut: one on the edge the fill grows FROM, one on the edge it grows\n * towards. They are named after those roles rather than after physical sides, so the three\n * geometry rules further down; horizontal, right-to-left, vertical; all read the same pair.\n */\n --progress-clip-start: calc(100% * var(--fill-fraction));\n --progress-clip-end: -100vmax;\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-inline: var(--vectis-space-2);\n color: var(--vectis-color-text);\n /*\n * The large negative inset on the two sides that do not carry the cut is what stops text\n * taller or wider than the bar from being cropped by its own clip.\n */\n clip-path: inset(-100vmax var(--progress-clip-end) -100vmax var(--progress-clip-start));\n /* The same duration and easing as the fill's own length, or the colour boundary\n would drift away from the fill's edge for the length of the transition. */\n transition: clip-path var(--vectis-duration-base) var(--vectis-ease-default);\n /* The bar itself is turned on its side in vertical mode; the text is put back\n upright here, since a label read sideways is not the point. */\n writing-mode: horizontal-tb;\n white-space: nowrap;\n pointer-events: none;\n }\n\n .v-progress-linear[data-value-position='start'] .v-progress-linear-text {\n justify-content: start;\n }\n\n .v-progress-linear[data-value-position='end'] .v-progress-linear-text {\n justify-content: end;\n }\n\n .v-progress-linear-text[data-on-fill] {\n /* The exact complement of the copy above: the cut moves to the other end of the\n axis, so the two together cover the whole bar and overlap nowhere. */\n --progress-clip-start: -100vmax;\n --progress-clip-end: calc(100% * (1 - var(--fill-fraction)));\n /*\n * The per-tone fallback colour. The adaptive one cannot simply be written as a second\n * declaration after it: because that declaration contains a var(), a browser with no\n * support does not reject it at parse time; it would win the cascade and only then turn\n * invalid, which resets the colour to inherited and leaves the fallback never applied.\n */\n color: var(--progress-text-fallback);\n }\n\n /* Where the adaptive colour function exists, the text picks black or white against\n whatever colour the fill ended up with. */\n @supports (color: contrast-color(red)) {\n .v-progress-linear-text[data-on-fill] {\n color: contrast-color(var(--progress-fill));\n }\n }\n\n /*\n * In a right-to-left page the fill grows from the right, so the two insets change physical\n * sides; the variables themselves keep their meaning.\n */\n .v-progress-linear:dir(rtl) .v-progress-linear-text {\n clip-path: inset(-100vmax var(--progress-clip-start) -100vmax var(--progress-clip-end));\n }\n\n /*\n * Putting zero at the bottom is not done by reversing the direction, which would also apply\n * to the text of the two copies: bidirectional reordering would then display \"50 %\" as \"%\n * 50\". The fill is anchored to the far end of the axis instead.\n */\n /*\n * Upright, the root carries the length, so a consumer's height on it sets the bar's: the bar\n * takes whatever the label leaves, its own inline size being the physical height.\n */\n .v-progress-linear-field[data-orientation='vertical'] {\n align-items: flex-start;\n block-size: var(--vectis-control-size-bar-length);\n }\n\n .v-progress-linear[data-orientation='vertical'] {\n flex: 1 1 0;\n writing-mode: vertical-lr;\n inline-size: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-fill {\n inset-inline-start: auto;\n inset-inline-end: 0;\n }\n\n /*\n * A right-to-left page reverses the inline axis of a vertical writing mode too: `vertical-lr`\n * then runs from the bottom up, so the far end anchored above is the TOP. The fill goes back\n * to the start of the axis, which is now the bottom.\n */\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-fill {\n inset-inline-start: 0;\n inset-inline-end: auto;\n }\n\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text {\n flex-direction: column-reverse;\n padding-inline: 0;\n padding-block: var(--vectis-space-2);\n }\n\n /*\n * The second selector is what neutralizes it, and it is written that way on purpose: it is\n * one step MORE specific than that rule, where the first selector alone would merely tie with\n * it and win by source order; a far more fragile arrangement.\n */\n .v-progress-linear[data-orientation='vertical'] .v-progress-linear-text,\n .v-progress-linear[data-orientation='vertical']:dir(rtl) .v-progress-linear-text {\n clip-path: inset(var(--progress-clip-end) -100vmax var(--progress-clip-start) -100vmax);\n }\n\n /*\n * At each extreme it is exactly flush with the edge without ever pulling away from it, which\n * makes the loop invisible and keeps the track from ever looking empty; no second bar is\n * needed. The easing carries the whole impression: a gradual entry, a quick crossing, a\n * damped exit.\n */\n .v-progress-linear[data-indeterminate] {\n overflow: hidden;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n /* The starting position is derived from this size, and the two must stay tied: that\n is what has the bar begin exactly off the track rather than half on it. */\n --progress-bar: 40%;\n /*\n * The anchoring is put back at the start of the axis, vertical case included; where a\n * measurable progress anchors at the far end instead.\n */\n inset-inline-start: 0;\n inset-inline-end: auto;\n inline-size: var(--progress-bar);\n /* The transition of a measurable progress has no place here: switching to this mode\n would otherwise be animated as the bar growing to its new size. */\n transition: none;\n animation: v-progress-linear-indeterminate var(--vectis-duration-1500) var(--vectis-ease-in-out)\n infinite;\n }\n\n @keyframes v-progress-linear-indeterminate {\n from {\n inset-inline-start: calc(-1 * var(--progress-bar));\n }\n\n to {\n inset-inline-start: 100%;\n }\n }\n\n /*\n * The same keyframes are simply read backwards, which changes nothing else BECAUSE the easing\n * curve is symmetric; an asymmetric one would need a second set of keyframes. A horizontal\n * right-to-left page needs nothing: the logical inset already follows the reading direction.\n */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate] .v-progress-linear-fill {\n animation-direction: reverse;\n }\n\n /* On a right-to-left page the vertical axis already runs upwards (see the trap above),\n so the keyframes are read forwards again. */\n .v-progress-linear[data-orientation='vertical'][data-indeterminate]:dir(rtl)\n .v-progress-linear-fill {\n animation-direction: normal;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-progress-linear-fill,\n .v-progress-linear-text {\n transition: none;\n }\n\n .v-progress-linear[data-indeterminate] .v-progress-linear-fill {\n animation-duration: var(--vectis-duration-5000);\n }\n }\n\n /* `forced-color-adjust` inherits, so both copies of the text are given their colour here too. */\n @media (forced-colors: active) {\n .v-progress-linear {\n forced-color-adjust: none;\n background: Canvas;\n box-shadow: inset 0 0 0 var(--vectis-control-border-width) CanvasText;\n }\n\n .v-progress-linear-fill {\n background: Highlight;\n }\n\n .v-progress-linear-text {\n color: CanvasText;\n }\n\n .v-progress-linear-text[data-on-fill] {\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8EA,IAAMqB,IAAQC,GAuBRC,IAAIC,EAAY,GAEhB,EACJ,KAAKC,GACL,YACA,aACA,YACA,sBACEC,QACIL,EAAM,aACNA,EAAM,GACd,GAKM,EAAE,cAAW,cAAW,sBAAmBM,EAAa,GAKxDC,IAAUC,EAAM,GAChBC,IAAYC,QAAoBV,EAAM,QAAQ,KAAA,IAAYE,EAAE,MAAM,SAAS,KAAM,GACjFS,IAAaC,EAAcL,SAAeP,EAAM,KAAK,GAGrDa,IAAQC,EAAS,GACjBC,KAAc,MAClB,CAACf,EAAM,kBACNA,EAAM,aAAa,CAAC,CAACa,EAAM,YAC3Bb,EAAM,kBAAkB,aAAcgB;oBAIvCrC,EAAA,GAAAC,EAyDM,OAAA;GAxDJ,OAAKC,EAAA,CAAC,kCACEC,EAAAuC,CAAA,CAAS,CAAA;GAChB,aAAWpB,EAAA;GACX,eAAaA,EAAA,UAAU,KAAA,IAAiB,KAAA,IAAR;GAChC,oBAAkBA,EAAA;GAClB,aAAWA,EAAA;GACX,OAAKlB,EAAA,CAAA,EAAA,kBAAuBkB,EAAA,MAAK,GAAInB,EAAAyC,CAAA,CAAS,CAAA;;GAEnCtB,EAAA,SAAK,CAAKA,EAAA,aAAcc,EAAU,EAAA,KAA9CpC,EAAA,GAAAC,EAWM,OAXNY,GAWM,CAVQS,EAAA,SAAK,CAAKA,EAAA,aAAtBtB,EAAA,GAAAC,EAES,QAAA;;IAFyB,IAAIE,EAAAyB,CAAA;IAAS,OAAM;GACnD,GAAAvB,EAAAiB,EAAA,KAAK,GAAA,GAAAR,CAAA,KAAAgC,EAAA,IAAA,EAAA,GAIKV,EAAU,EAAA,KAAtBpC,EAAA,GAAAC,EAIO,QAJPc,GAIO,CAHLR,EAEOyC,EAAA,QAAA,WAAA;IAFA,OAAO7C,EAAA8C,CAAA;IAAU,KAAK9C,EAAAsB,CAAA;IAAgB,SAAStB,EAAA+C,CAAA;GAAtD,SAEO,CADF1C,EAAAH,EAAAF,EAAAoB,CAAA,CAAC,CAAC,SAAS,QAAQpB,EAAAiD,CAAA,CAAc,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAAN,EAAA,IAAA,EAAA,CAAA,CAAA,KAAAA,EAAA,IAAA,EAAA;GAI9BxB,EAAA,SAASA,EAAA,aAArBtB,EAAA,GAAAC,EAA0F,QAAA;;IAAzD,IAAIE,EAAAyB,CAAA;IAAS,OAAM;GAAuB,GAAAvB,EAAAiB,EAAA,KAAK,GAAA,GAAAN,CAAA,KAAA8B,EAAA,IAAA,EAAA;GAChFrC,EAkCM,OAlCNC,EAkCM;IAjCJ,OAAM;IACN,MAAK;IACJ,mBAAiBP,EAAA6B,CAAA;IACjB,cAAY7B,EAAA2B,CAAA;GACL,GAAA3B,EAAAoD,CAAA,GAAc;IACrB,cAAYjC,EAAA;IACZ,oBAAkBA,EAAA;IAClB,uBAAqBA,EAAA;IACrB,sBAAoBA,EAAA,gBAAa,KAAQ,KAAA;IACzC,iBAAeA,EAAA,gBAAgB,KAAA,IAAYnB,EAAA8C,CAAA;IAC5C,iBAAc;IACb,iBAAe9C,EAAAsB,CAAA;IACf,OAAK,EAAA,mBAAuB,OAAOtB,EAAAqD,CAAA,CAAQ,EAAA;GAE5C,CAAA,GAAA,CAAA,AAAAC,EAAA,OAAAhD,EAAuC,QAAA,EAAjC,OAAM,yBAAwB,GAAA,MAAA,EAAA,GAOpB2B,EAAU,EAAA,KAA1BpC,EAAA,GAAAC,EAWWU,GAAA,EAAA,KAAA,EAAA,GAAA,CAVTF,EAIO,QAJPS,GAIO,CAHLX,EAEOyC,EAAA,QAAA,WAAA;IAFA,OAAO7C,EAAA8C,CAAA;IAAU,KAAK9C,EAAAsB,CAAA;IAAgB,SAAStB,EAAA+C,CAAA;GAAtD,SAEO,CADF1C,EAAAH,EAAAF,EAAAoB,CAAA,CAAC,CAAC,SAAS,QAAQpB,EAAAiD,CAAA,CAAc,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAGxC3C,EAIO,QAJPU,GAIO,CAHLZ,EAEOyC,EAAA,QAAA,WAAA;IAFA,OAAO7C,EAAA8C,CAAA;IAAU,KAAK9C,EAAAsB,CAAA;IAAgB,SAAStB,EAAA+C,CAAA;GAAtD,SAEO,CADF1C,EAAAH,EAAAF,EAAAoB,CAAA,CAAC,CAAC,SAAS,QAAQpB,EAAAiD,CAAA,CAAc,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,KAAAN,EAAA,IAAA,EAAA,CAAA,GAAA,IAAA7B,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
-
@layer vectis.components{.v-separator{border:0 solid var(--
|
|
2
|
+
@layer vectis.components{.v-separator{--separator-color:var(--vectis-color-border);--separator-thickness:var(--vectis-control-size-separator-sm);border:0 solid var(--separator-color);flex:none;margin:0}.v-separator[data-size=md]{--separator-thickness:var(--vectis-control-size-separator-md)}.v-separator[data-size=lg]{--separator-thickness:var(--vectis-control-size-separator-lg)}.v-separator[data-variant=dashed]{border-style:dashed}.v-separator[data-variant=dotted]{border-style:dotted}.v-separator[data-orientation=vertical]{align-self:stretch}hr.v-separator[data-orientation=horizontal]{border-block-start-width:var(--separator-thickness)}hr.v-separator[data-orientation=vertical]{border-inline-start-width:var(--separator-thickness)}div.v-separator{align-items:center;gap:var(--vectis-space-3);color:var(--vectis-color-text-muted);font-family:var(--vectis-text-family);font-size:var(--vectis-text-caption-size);font-weight:var(--vectis-text-caption-weight);line-height:var(--vectis-text-caption-leading);display:flex}div.v-separator:before,div.v-separator:after{content:"";border-width:0;border-color:inherit;border-style:inherit;flex:1}div.v-separator[data-orientation=horizontal]:before,div.v-separator[data-orientation=horizontal]:after{border-block-start-width:var(--separator-thickness)}div.v-separator[data-orientation=vertical]{flex-direction:column}div.v-separator[data-orientation=vertical]:before,div.v-separator[data-orientation=vertical]:after{border-inline-start-width:var(--separator-thickness)}div.v-separator[data-content-position=start]:before,div.v-separator[data-content-position=end]:after{display:none}.v-separator-content{--vectis-icon-size:var(--vectis-icon-size-sm);align-items:center;gap:var(--vectis-space-2);display:inline-flex}}
|
|
@@ -1,12 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
import { IconSource } from '../VIcon/types.js';
|
|
2
2
|
/** Which way the rule runs. */
|
|
3
3
|
export type SeparatorOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
/** How the rule is stroked. */
|
|
5
|
+
export type SeparatorVariant = 'solid' | 'dashed' | 'dotted';
|
|
6
|
+
/** Where the content sits along the rule. */
|
|
7
|
+
export type SeparatorContentPosition = 'start' | 'center' | 'end';
|
|
8
|
+
/** How thick the rule is. */
|
|
9
|
+
export type SeparatorSize = 'sm' | 'md' | 'lg';
|
|
4
10
|
interface SeparatorProps {
|
|
5
11
|
/** The direction the rule runs in: across by default, or down the page under `vertical`. */
|
|
6
12
|
orientation?: SeparatorOrientation;
|
|
13
|
+
/** How the rule is stroked: a continuous line, dashes or dots. */
|
|
14
|
+
variant?: SeparatorVariant;
|
|
15
|
+
/**
|
|
16
|
+
* How thick the rule is: a 1px hairline (`sm`, the default), 2px or 4px. A thicker rule marks
|
|
17
|
+
* a stronger break, and makes `dotted` read as dots.
|
|
18
|
+
*/
|
|
19
|
+
size?: SeparatorSize;
|
|
20
|
+
/**
|
|
21
|
+
* A colour of your own (hex, CSS name or `oklch()`) for the rule. The label and icon keep the
|
|
22
|
+
* muted text colour, so their contrast stays the design system's.
|
|
23
|
+
*/
|
|
24
|
+
color?: string;
|
|
25
|
+
/** Visible text breaking the rule. It also becomes the separator's accessible name. */
|
|
26
|
+
label?: string;
|
|
27
|
+
/** An icon breaking the rule, before the label when both are set (the VIcon contract). */
|
|
28
|
+
icon?: IconSource;
|
|
29
|
+
/** Where the label and icon sit along the rule: its start, centre or end. */
|
|
30
|
+
contentPosition?: SeparatorContentPosition;
|
|
7
31
|
}
|
|
8
|
-
|
|
32
|
+
type __VLS_Slots = {
|
|
33
|
+
/** Rich content breaking the rule, after the icon and in place of the label. */
|
|
34
|
+
default?(): unknown;
|
|
35
|
+
};
|
|
36
|
+
declare const __VLS_base: import('vue').DefineComponent<SeparatorProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SeparatorProps> & Readonly<{}>, {
|
|
37
|
+
label: string;
|
|
38
|
+
size: SeparatorSize;
|
|
39
|
+
variant: SeparatorVariant;
|
|
40
|
+
color: string;
|
|
41
|
+
icon: IconSource;
|
|
9
42
|
orientation: SeparatorOrientation;
|
|
43
|
+
contentPosition: SeparatorContentPosition;
|
|
10
44
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
45
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
11
46
|
declare const _default: typeof __VLS_export;
|
|
12
47
|
export default _default;
|
|
48
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
49
|
+
new (): {
|
|
50
|
+
$slots: S;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VSeparator.js","names":["_sfc_main","VSeparator_vue_vue_type_script_setup_true_lang_default","VSeparator_default"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n})\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n />\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--
|
|
1
|
+
{"version":3,"file":"VSeparator.js","names":["_sfc_main","VSeparator_vue_vue_type_script_setup_true_lang_default","VSeparator_default"],"sources":["../../../src/components/VSeparator/VSeparator.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/** Use a native hr for separator semantics and borders for visibility in forced colours. */\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\n\n/** Which way the rule runs. */\nexport type SeparatorOrientation = 'horizontal' | 'vertical'\n/** How the rule is stroked. */\nexport type SeparatorVariant = 'solid' | 'dashed' | 'dotted'\n/** Where the content sits along the rule. */\nexport type SeparatorContentPosition = 'start' | 'center' | 'end'\n/** How thick the rule is. */\nexport type SeparatorSize = 'sm' | 'md' | 'lg'\n\ninterface SeparatorProps {\n /** The direction the rule runs in: across by default, or down the page under `vertical`. */\n orientation?: SeparatorOrientation\n /** How the rule is stroked: a continuous line, dashes or dots. */\n variant?: SeparatorVariant\n /**\n * How thick the rule is: a 1px hairline (`sm`, the default), 2px or 4px. A thicker rule marks\n * a stronger break, and makes `dotted` read as dots.\n */\n size?: SeparatorSize\n /**\n * A colour of your own (hex, CSS name or `oklch()`) for the rule. The label and icon keep the\n * muted text colour, so their contrast stays the design system's.\n */\n color?: string\n /** Visible text breaking the rule. It also becomes the separator's accessible name. */\n label?: string\n /** An icon breaking the rule, before the label when both are set (the VIcon contract). */\n icon?: IconSource\n /** Where the label and icon sit along the rule: its start, centre or end. */\n contentPosition?: SeparatorContentPosition\n}\n\nwithDefaults(defineProps<SeparatorProps>(), {\n orientation: 'horizontal',\n variant: 'solid',\n size: 'sm',\n color: undefined,\n label: undefined,\n icon: undefined,\n contentPosition: 'center',\n})\n\nconst slots = defineSlots<{\n /** Rich content breaking the rule, after the icon and in place of the label. */\n default?(): unknown\n}>()\n\n// A function read by the template, never a `computed`: `slots` is not reactive.\nfunction hasSlot() {\n return slots.default !== undefined\n}\n</script>\n\n<template>\n <!--\n Aria-orientation is emitted only when it CONTRADICTS what the role already implies: a\n separator is horizontal by default, so stating it would merely restate the role. This is the\n same convention the VTabs tablist follows.\n -->\n <hr\n v-if=\"!label && !icon && !hasSlot()\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n />\n <!--\n An <hr> cannot hold content. A separator's children are presentational, so the label is\n repeated as its accessible name; slot-only content is named by the consumer's aria-label.\n -->\n <div\n v-else\n role=\"separator\"\n class=\"v-separator\"\n :data-orientation=\"orientation\"\n :data-variant=\"variant\"\n :data-size=\"size\"\n :data-content-position=\"contentPosition\"\n :aria-orientation=\"orientation === 'vertical' ? 'vertical' : undefined\"\n :aria-label=\"label\"\n :style=\"color !== undefined ? { '--separator-color': color } : undefined\"\n >\n <span class=\"v-separator-content\">\n <VIcon v-if=\"icon\" v-bind=\"iconProps(icon)\" />\n <slot>{{ label }}</slot>\n </span>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-separator {\n --separator-color: var(--vectis-color-border);\n --separator-thickness: var(--vectis-control-size-separator-sm);\n\n flex: none;\n /*\n * `.v-menu-separator` and `.v-listbox-separator` override that margin from THEIR own\n * sheet, and which of the two sheets the consumer's bundler puts last is not ours to\n * decide. Both are therefore written as the compound `.v-separator.v-x-separator`, and\n * every declaration added here falls under the same obligation.\n */\n margin: 0;\n border: 0 solid var(--separator-color);\n }\n\n .v-separator[data-size='md'] {\n --separator-thickness: var(--vectis-control-size-separator-md);\n }\n\n .v-separator[data-size='lg'] {\n --separator-thickness: var(--vectis-control-size-separator-lg);\n }\n\n .v-separator[data-variant='dashed'] {\n border-style: dashed;\n }\n\n .v-separator[data-variant='dotted'] {\n border-style: dotted;\n }\n\n /*\n * In ordinary flow it collapses to nothing, silently and with no error; there it is up to the\n * consumer to give it a block-size.\n */\n .v-separator[data-orientation='vertical'] {\n align-self: stretch;\n }\n\n hr.v-separator[data-orientation='horizontal'] {\n border-block-start-width: var(--separator-thickness);\n }\n\n hr.v-separator[data-orientation='vertical'] {\n border-inline-start-width: var(--separator-thickness);\n }\n\n /* With content, the root only lays out; its two pseudo-elements are the strokes. */\n div.v-separator {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-3);\n color: var(--vectis-color-text-muted);\n font-family: var(--vectis-text-family);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n }\n\n div.v-separator::before,\n div.v-separator::after {\n content: '';\n flex: 1;\n /* The initial width is `medium` (3px): every side but the stroke's must be zeroed. */\n border-width: 0;\n border-color: inherit;\n border-style: inherit;\n }\n\n div.v-separator[data-orientation='horizontal']::before,\n div.v-separator[data-orientation='horizontal']::after {\n border-block-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-orientation='vertical'] {\n flex-direction: column;\n }\n\n div.v-separator[data-orientation='vertical']::before,\n div.v-separator[data-orientation='vertical']::after {\n border-inline-start-width: var(--separator-thickness);\n }\n\n div.v-separator[data-content-position='start']::before,\n div.v-separator[data-content-position='end']::after {\n display: none;\n }\n\n .v-separator-content {\n --vectis-icon-size: var(--vectis-icon-size-sm);\n\n display: inline-flex;\n align-items: center;\n gap: var(--vectis-space-2);\n }\n}\n</style>\n"],"mappings":""}
|