@vectoriox/iox-ui 5.81.0 → 5.82.1
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/design-core/index.d.ts +48 -9
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +76 -11
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +110 -0
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui.mjs +270 -32
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/index.d.ts +166 -19
- package/package.json +1 -1
- package/src/design-core/element-styles.ts +14 -2
- package/src/design-core/entrance-timing.ts +14 -3
- package/src/design-core/flavor-spec.generated.ts +12 -6
- package/src/design-core/public-api.ts +1 -0
- package/src/design-core/theme-color.ts +41 -0
- package/src/generation-core/node-baselines.generated.ts +110 -0
- package/styles/iox-design.css +33 -11
- package/styles/iox-forms.css +5 -0
|
@@ -1556,7 +1556,15 @@ const MARKER_FUNS = [
|
|
|
1556
1556
|
['markerColor', 'color'],
|
|
1557
1557
|
['markerFontSize', 'fontSize'],
|
|
1558
1558
|
];
|
|
1559
|
-
const TRANSITION_KEYS = ['transitionDuration', 'transitionTimingFunction', 'transitionDelay'];
|
|
1559
|
+
const TRANSITION_KEYS = ['transitionDuration', 'transitionTimingFunction', 'transitionDelay', 'transitionProperty'];
|
|
1560
|
+
/** The Transition ▸ Properties trait (G2): what a transition names, comma-separated. Unset, the renderers fill in the
|
|
1561
|
+
* properties the node's states change (`withStateTransitions`); a transition never names `all` unless an author
|
|
1562
|
+
* typed it. */
|
|
1563
|
+
const TRANSITION_PROPERTY_KEY = 'transitionProperty';
|
|
1564
|
+
/** The property list a `transitionProperty` value names (`color, transform` → two entries). */
|
|
1565
|
+
function transitionPropertyList(value) {
|
|
1566
|
+
return String(value ?? '').split(',').map(p => p.trim()).filter(Boolean);
|
|
1567
|
+
}
|
|
1560
1568
|
// ─── Max lines (line clamp) ─────────────────────────────────────────────────────
|
|
1561
1569
|
/** "Max lines" (Card v2, board 8 — opt-in on a Title / Text): a whole number clamps the text to that many
|
|
1562
1570
|
* lines with an ellipsis. It composes into the four declarations a line clamp takes; anything else
|
|
@@ -1740,13 +1748,15 @@ function composeVirtualTraits(raw, base = raw) {
|
|
|
1740
1748
|
const transformStr = buildFns(TRANSFORM_FUNS, merged(TRANSFORM_FUNS));
|
|
1741
1749
|
if (transformStr)
|
|
1742
1750
|
result['transform'] = transformStr;
|
|
1743
|
-
// transition — only
|
|
1751
|
+
// transition — only when it is timed (a non-zero duration) and names what it moves: one entry per property
|
|
1752
|
+
// (G2, Emil 183 — never `transition: all`); nothing to name, nothing to transition.
|
|
1744
1753
|
const dur = raw['transitionDuration'] ?? base['transitionDuration'];
|
|
1745
1754
|
const ease = raw['transitionTimingFunction'] ?? base['transitionTimingFunction'];
|
|
1746
1755
|
const del = raw['transitionDelay'] ?? base['transitionDelay'];
|
|
1747
|
-
|
|
1756
|
+
const props = transitionPropertyList(raw[TRANSITION_PROPERTY_KEY] ?? base[TRANSITION_PROPERTY_KEY]);
|
|
1757
|
+
if (dur && ease && dur !== '0ms' && dur !== '0s' && props.length) {
|
|
1748
1758
|
const delPart = del && del !== '0ms' && del !== '0s' ? ` ${del}` : '';
|
|
1749
|
-
result['transition'] =
|
|
1759
|
+
result['transition'] = props.map(p => `${p} ${dur} ${ease}${delPart}`).join(', ');
|
|
1750
1760
|
}
|
|
1751
1761
|
// Max lines: the clamp takes over the node's display and overflow.
|
|
1752
1762
|
const clamp = lineClamp(raw[MAX_LINES_KEY] ?? base[MAX_LINES_KEY]);
|
|
@@ -1858,6 +1868,8 @@ const NOOP_INITIAL_VALUES = {
|
|
|
1858
1868
|
'aspect-ratio': ['auto'],
|
|
1859
1869
|
'mix-blend-mode': ['normal'],
|
|
1860
1870
|
'transform': ['none'], 'box-shadow': ['none'],
|
|
1871
|
+
// G3: the Transform origin trait's default is the CSS initial (the centre) — never emitted on every node.
|
|
1872
|
+
'transform-origin': ['center', 'center center', '50% 50%', '50% 50% 0', '50% 50% 0px'],
|
|
1861
1873
|
// overflow initial is `visible`. A self-describing node serialises the Overflow trait's default,
|
|
1862
1874
|
// so WITHOUT this the emitted `overflow: visible` would override component baselines that clip
|
|
1863
1875
|
// (e.g. `.iox-card__img-wrap`, `.iox-slider`, `.iox-gallery` all set `overflow: hidden`), breaking
|
|
@@ -1978,12 +1990,41 @@ var ComponentState;
|
|
|
1978
1990
|
* `targetedStateSelector`. On a node OUTSIDE every item (composite T20, CC4a) the author PICKS the item — "when tab
|
|
1979
1991
|
* Night is on" — the same state and the same `:has()` scoped to the nearest common ancestor. */
|
|
1980
1992
|
ComponentState["ItemOpen"] = "trigger-on";
|
|
1993
|
+
/** G4: a control that cannot be used — a disabled button, or one marked aria-disabled. */
|
|
1994
|
+
ComponentState["Disabled"] = "disabled";
|
|
1995
|
+
/** G4: busy — a submit button while its form sends (`syncSubmitButtons`), a form while it sends. */
|
|
1996
|
+
ComponentState["Busy"] = "busy";
|
|
1997
|
+
/** G4: chosen — a toggle button pressed, an option checked or selected. */
|
|
1998
|
+
ComponentState["Selected"] = "selected";
|
|
1999
|
+
/** G4: the page has scrolled (a header that firms up once the page moves) — `SCROLLED_ATTRIBUTE` on the root. */
|
|
2000
|
+
ComponentState["Scrolled"] = "scrolled";
|
|
1981
2001
|
})(ComponentState || (ComponentState = {}));
|
|
1982
|
-
/** The
|
|
2002
|
+
/** The page has scrolled: written on the document element by the live site (and on the canvas page by the builder). */
|
|
2003
|
+
const SCROLLED_ATTRIBUTE = 'data-iox-scrolled';
|
|
2004
|
+
/** The selector each (non-targeted) component state compiles to — an attribute, or an `:is()` of the ways a node can
|
|
2005
|
+
* be in it (a native `:disabled` or `aria-disabled`; pressed / checked / selected), so one rule covers every markup. */
|
|
1983
2006
|
const COMPONENT_STATE_SELECTOR = {
|
|
1984
2007
|
[ComponentState.Current]: '[aria-current="page"]',
|
|
1985
2008
|
[ComponentState.On]: '[data-iox-on]',
|
|
2009
|
+
[ComponentState.Disabled]: ':is(:disabled, [aria-disabled="true"])',
|
|
2010
|
+
[ComponentState.Busy]: '[aria-busy="true"]',
|
|
2011
|
+
[ComponentState.Selected]: ':is([aria-pressed="true"], [aria-checked="true"], [aria-selected="true"])',
|
|
2012
|
+
[ComponentState.Scrolled]: `:is([${SCROLLED_ATTRIBUTE}], [${SCROLLED_ATTRIBUTE}] *)`,
|
|
1986
2013
|
};
|
|
2014
|
+
/** Which types offer each control state (G4) in the Style panel's Component state group. */
|
|
2015
|
+
const G4_STATE_TYPES = [
|
|
2016
|
+
[ComponentState.Disabled, ['ButtonBlock', 'Button', 'SubmitButton']],
|
|
2017
|
+
[ComponentState.Busy, ['SubmitButton', 'ButtonBlock', 'Form']],
|
|
2018
|
+
[ComponentState.Selected, ['ButtonBlock', 'LinkedContainer']],
|
|
2019
|
+
];
|
|
2020
|
+
/** Scrolled is offered on the site header and its parts — generation-core's NavRole family (`nav`, `nav.brand`…), the
|
|
2021
|
+
* drawer's parts aside (the drawer is a dialog over the page). Spelled here — the main entry does not import
|
|
2022
|
+
* generation-core; style-compiler.spec pins it to the enum. */
|
|
2023
|
+
const SCROLLED_STATE_ROLE = 'nav';
|
|
2024
|
+
const DRAWER_ROLE_PREFIX = 'nav.drawer';
|
|
2025
|
+
function offersScrolled(role) {
|
|
2026
|
+
return !!role && (role === SCROLLED_STATE_ROLE || role.startsWith(`${SCROLLED_STATE_ROLE}.`)) && !role.startsWith(DRAWER_ROLE_PREFIX);
|
|
2027
|
+
}
|
|
1987
2028
|
/** The composite roles that are themselves "on" when their item is open (they carry `data-iox-on`): an accordion's
|
|
1988
2029
|
* item, header and panel; a disclosure (its own item), its toggle and its panel (CC2.1); a tab and its panel (CC4a —
|
|
1989
2030
|
* "Active"). The main entry does not import composite-core, so the roles are spelled here — `style-compiler.spec` pins
|
|
@@ -2008,6 +2049,11 @@ function componentStatesFor(type, role, insideItem = false, itemsToPick = false)
|
|
|
2008
2049
|
out.push(ComponentState.Current);
|
|
2009
2050
|
if (insideItem || itemsToPick)
|
|
2010
2051
|
out.push(ComponentState.ItemOpen);
|
|
2052
|
+
for (const [state, types] of G4_STATE_TYPES)
|
|
2053
|
+
if (type && types.includes(type))
|
|
2054
|
+
out.push(state);
|
|
2055
|
+
if (offersScrolled(role))
|
|
2056
|
+
out.push(ComponentState.Scrolled);
|
|
2011
2057
|
return out;
|
|
2012
2058
|
}
|
|
2013
2059
|
/**
|
|
@@ -2042,29 +2088,73 @@ function hasHoverState(stateStyles) {
|
|
|
2042
2088
|
* The base-rule transition a hovering node gets when it declares none of its own, so a hover
|
|
2043
2089
|
* animates instead of snapping. ONE copy for the builder canvas, the style panel and the engine.
|
|
2044
2090
|
*
|
|
2045
|
-
* Two
|
|
2091
|
+
* Two timings, chosen by the element-style MARKER (§3b-bis): a node wearing an element style takes
|
|
2046
2092
|
* the motion tokens; a node without one (saved before DS2, not adopted) keeps the pre-DS2 literal
|
|
2047
|
-
*
|
|
2093
|
+
* timing — seeding an org's tokens must never change how a legacy page hovers. WHAT transitions is the
|
|
2094
|
+
* list of properties the node's states change (G2 — never `transition: all`).
|
|
2048
2095
|
*/
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2096
|
+
const HOVER_DEFAULT_TRANSITION_TRAITS = {
|
|
2097
|
+
transitionDuration: 'var(--iox-dur-fast)', transitionTimingFunction: 'var(--iox-ease-standard)',
|
|
2098
|
+
};
|
|
2099
|
+
const LEGACY_HOVER_TRANSITION_TRAITS = { transitionDuration: '0.2s', transitionTimingFunction: 'ease' };
|
|
2100
|
+
/** The default hover timing for a node that wears `elementStyle` (or none). */
|
|
2101
|
+
function defaultHoverTransitionTraits(elementStyle) {
|
|
2102
|
+
return elementStyle ? HOVER_DEFAULT_TRANSITION_TRAITS : LEGACY_HOVER_TRANSITION_TRAITS;
|
|
2103
|
+
}
|
|
2104
|
+
const isFilled = (v) => v !== undefined && v !== null && String(v).trim() !== '';
|
|
2105
|
+
const isZeroDuration = (v) => /^-?0+(\.0+)?(ms|s)?$/.test(String(v ?? '').trim());
|
|
2106
|
+
/** True when the RAW style map times a transition of its own (an explicit `transition`, or the
|
|
2107
|
+
* transitionDuration / TimingFunction an element style writes). */
|
|
2057
2108
|
function hasOwnTransition(styleProps) {
|
|
2058
2109
|
const sp = styleProps ?? {};
|
|
2059
|
-
if (sp['transition']
|
|
2110
|
+
if (isFilled(sp['transition']))
|
|
2060
2111
|
return true;
|
|
2061
|
-
return
|
|
2112
|
+
return isFilled(sp['transitionDuration']) && !isZeroDuration(sp['transitionDuration']) && isFilled(sp['transitionTimingFunction']);
|
|
2113
|
+
}
|
|
2114
|
+
/** Keys a composed state map holds that are not properties a transition can name. */
|
|
2115
|
+
const NOT_TRANSITIONED = new Set(['__markerStyles', 'WebkitBackdropFilter', 'transition', 'transitionDuration', 'transitionTimingFunction', 'transitionDelay', 'transitionProperty']);
|
|
2116
|
+
/**
|
|
2117
|
+
* The CSS properties a node's states change — what its transition names (G2, Emil 183: never `transition: all`).
|
|
2118
|
+
* Every state the node holds, at every breakpoint, composed as the renderers compose it (translateX / scaleX → one
|
|
2119
|
+
* `transform`, a gradient background → `background-image`…), in a stable order so both renderers emit one string.
|
|
2120
|
+
*/
|
|
2121
|
+
function stateTransitionProperties(stateStyles, responsive, type) {
|
|
2122
|
+
const maps = [];
|
|
2123
|
+
for (const map of Object.values(stateStyles ?? {}))
|
|
2124
|
+
if (map)
|
|
2125
|
+
maps.push(map);
|
|
2126
|
+
for (const layer of Object.values(responsive ?? {}))
|
|
2127
|
+
for (const map of Object.values(layer?.stateStyles ?? {}))
|
|
2128
|
+
if (map)
|
|
2129
|
+
maps.push(map);
|
|
2130
|
+
const out = [];
|
|
2131
|
+
// A prop the type's renderer owns (a Dialog's positioning) never reaches a rule — nor the transition's list.
|
|
2132
|
+
for (const map of maps.map(m => (type ? stripSuppressedProps(type, m) : m))) {
|
|
2133
|
+
for (const key of Object.keys(composeVirtualTraits(map, map))) {
|
|
2134
|
+
if (NOT_TRANSITIONED.has(key))
|
|
2135
|
+
continue;
|
|
2136
|
+
const prop = styleKeyToKebab(key);
|
|
2137
|
+
if (!out.includes(prop))
|
|
2138
|
+
out.push(prop);
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
return out;
|
|
2062
2142
|
}
|
|
2063
|
-
/**
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2143
|
+
/**
|
|
2144
|
+
* `styleProps` as a renderer compiles them: a hovering node with no timing of its own takes the default hover timing,
|
|
2145
|
+
* and a node whose transition names no properties gets the ones its states change. An author's own `transitionProperty`
|
|
2146
|
+
* (or a raw `transition`) always wins. Pure: the node's stored styles are never touched.
|
|
2147
|
+
*/
|
|
2148
|
+
function withStateTransitions(styleProps, stateStyles, elementStyle, responsive, type) {
|
|
2149
|
+
let out = styleProps;
|
|
2150
|
+
if (hasHoverState(stateStyles) && !hasOwnTransition(styleProps))
|
|
2151
|
+
out = { ...out, ...defaultHoverTransitionTraits(elementStyle) };
|
|
2152
|
+
if (!isFilled(out['transitionProperty']) && !isFilled(out['transition'])) {
|
|
2153
|
+
const props = stateTransitionProperties(stateStyles, responsive, type);
|
|
2154
|
+
if (props.length)
|
|
2155
|
+
out = { ...out, transitionProperty: props.join(', ') };
|
|
2156
|
+
}
|
|
2157
|
+
return out;
|
|
2068
2158
|
}
|
|
2069
2159
|
/**
|
|
2070
2160
|
* Per-type default `width` that the builder applies from each component's config
|
|
@@ -2088,12 +2178,13 @@ const DEFAULT_WIDTH_BY_TYPE = {
|
|
|
2088
2178
|
* behaviour, which the engine must re-apply explicitly for parity. Returns `"prop: value"`
|
|
2089
2179
|
* declarations to append AFTER the node's own compiled declarations.
|
|
2090
2180
|
*
|
|
2181
|
+
* The default hover transition is no longer one of them: it is composed into the node's own rule by
|
|
2182
|
+
* `withStateTransitions` (both renderers), listing the properties its states change (G2).
|
|
2183
|
+
*
|
|
2091
2184
|
* @param type Node type (registry key).
|
|
2092
2185
|
* @param styleProps The node's persisted styleProps.
|
|
2093
|
-
* @param hasHoverState Whether the node has a non-empty hover / parent-hover state.
|
|
2094
|
-
* @param elementStyle The element style the node wears — picks the default hover transition.
|
|
2095
2186
|
*/
|
|
2096
|
-
function renderDefaultDeclarations(type, styleProps
|
|
2187
|
+
function renderDefaultDeclarations(type, styleProps) {
|
|
2097
2188
|
const sp = styleProps ?? {};
|
|
2098
2189
|
const out = [];
|
|
2099
2190
|
const isOutOfFlow = sp['position'] === 'fixed' || sp['position'] === 'absolute';
|
|
@@ -2121,12 +2212,6 @@ function renderDefaultDeclarations(type, styleProps, hasHoverState, elementStyle
|
|
|
2121
2212
|
if (sp['borderWidth'] && sp['borderStyle'] === undefined) {
|
|
2122
2213
|
out.push('border-style: solid');
|
|
2123
2214
|
}
|
|
2124
|
-
// Default transition so own/parent hover animates smoothly (parity with the builder). Skipped
|
|
2125
|
-
// when the node composes its own (an element style's transitionDuration) — appended after the
|
|
2126
|
-
// node's declarations, it would otherwise beat them in the engine only.
|
|
2127
|
-
if (hasHoverState && !hasOwnTransition(sp)) {
|
|
2128
|
-
out.push(`transition: ${defaultHoverTransition(elementStyle)}`);
|
|
2129
|
-
}
|
|
2130
2215
|
// Image defaults reapplied when unset (the config defaults aren't always persisted). height:auto
|
|
2131
2216
|
// is only a DEFAULT — when the user sets an explicit height (e.g. 100%) it must WIN, so guard it
|
|
2132
2217
|
// on `sp['height'] === undefined` (matching the builder, which respects a configured height). An
|
|
@@ -6220,6 +6305,20 @@ function splitOuterProps(styles) {
|
|
|
6220
6305
|
(OUTER_STYLE_PROPS.has(k) ? outer : inner)[k] = v;
|
|
6221
6306
|
return { inner, outer };
|
|
6222
6307
|
}
|
|
6308
|
+
/**
|
|
6309
|
+
* The devices a hover rule is for (G1 — Emil 91, mobile-native M1): a phone has no hover, and a tap fires a false
|
|
6310
|
+
* one that STICKS until the next tap elsewhere. Every hover, parent-hover and trigger-hover rule — the node's own and
|
|
6311
|
+
* a part's — is emitted inside this query by both renderers; `:active` (a real press on touch) never is.
|
|
6312
|
+
*/
|
|
6313
|
+
const HOVER_MEDIA_QUERY = '(hover: hover) and (pointer: fine)';
|
|
6314
|
+
/** True for a state driven by a pointer hovering something (its own, its parent's, a chosen trigger's). */
|
|
6315
|
+
function isHoverState(state) {
|
|
6316
|
+
return !!state && HOVER_STATES.includes(state);
|
|
6317
|
+
}
|
|
6318
|
+
/** `css` as it is emitted for `state`: inside `HOVER_MEDIA_QUERY` for a hover state, unchanged otherwise. */
|
|
6319
|
+
function gateHoverRule(state, css) {
|
|
6320
|
+
return css && isHoverState(state) ? `@media ${HOVER_MEDIA_QUERY} {\n${css}\n}` : css;
|
|
6321
|
+
}
|
|
6223
6322
|
|
|
6224
6323
|
/**
|
|
6225
6324
|
* "This link is the page you're on" (CC1, N2). ONE decision for the builder canvas and both engine
|
|
@@ -6654,6 +6753,145 @@ function finalKeyframe(frames) {
|
|
|
6654
6753
|
return typeof last['clipPath'] === 'string' && FULLY_SHOWN_CLIP.test(last['clipPath']) ? { ...last, clipPath: 'none' } : last;
|
|
6655
6754
|
}
|
|
6656
6755
|
|
|
6756
|
+
/**
|
|
6757
|
+
* What an interaction's easing may be (G6, decision D8): one of the five CSS keywords, a `cubic-bezier()`, or the
|
|
6758
|
+
* NAME of one of the look's easing tokens — so an author's entrance moves on the same curve as the site's buttons and
|
|
6759
|
+
* dialogs (Emil 21: one token system), and Spring plays the look's spring (a `linear()` curve, `springToLinear`).
|
|
6760
|
+
* Both runtimes resolve it the same way, through the CSS custom property on the element itself.
|
|
6761
|
+
*/
|
|
6762
|
+
var EasingKeyword;
|
|
6763
|
+
(function (EasingKeyword) {
|
|
6764
|
+
EasingKeyword["Linear"] = "linear";
|
|
6765
|
+
EasingKeyword["Ease"] = "ease";
|
|
6766
|
+
EasingKeyword["EaseIn"] = "ease-in";
|
|
6767
|
+
EasingKeyword["EaseOut"] = "ease-out";
|
|
6768
|
+
EasingKeyword["EaseInOut"] = "ease-in-out";
|
|
6769
|
+
})(EasingKeyword || (EasingKeyword = {}));
|
|
6770
|
+
/** The look's easing tokens an interaction may name (their `--iox-<name>` holds the curve). */
|
|
6771
|
+
var EasingToken;
|
|
6772
|
+
(function (EasingToken) {
|
|
6773
|
+
EasingToken["Standard"] = "ease-standard";
|
|
6774
|
+
EasingToken["Enter"] = "ease-enter";
|
|
6775
|
+
EasingToken["Exit"] = "ease-exit";
|
|
6776
|
+
EasingToken["Spring"] = "ease-spring";
|
|
6777
|
+
})(EasingToken || (EasingToken = {}));
|
|
6778
|
+
const EASING_KEYWORDS = Object.values(EasingKeyword);
|
|
6779
|
+
const EASING_TOKENS = Object.values(EasingToken);
|
|
6780
|
+
/** What an unknown or unresolvable easing plays as: a deceleration, never ease-in (Emil 17). */
|
|
6781
|
+
const DEFAULT_INTERACTION_EASING = EasingKeyword.EaseOut;
|
|
6782
|
+
const NUMBER = '\\s*(-?\\d*\\.?\\d+)\\s*';
|
|
6783
|
+
const CUBIC_BEZIER = new RegExp(`^cubic-bezier\\(${NUMBER},${NUMBER},${NUMBER},${NUMBER}\\)$`);
|
|
6784
|
+
/** A well-formed `cubic-bezier(x1, y1, x2, y2)` whose x values sit in [0, 1] (what CSS and WAAPI accept). */
|
|
6785
|
+
function isCubicBezier(value) {
|
|
6786
|
+
const m = CUBIC_BEZIER.exec(String(value ?? '').trim());
|
|
6787
|
+
if (!m)
|
|
6788
|
+
return false;
|
|
6789
|
+
const [x1, , x2] = [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
6790
|
+
return x1 >= 0 && x1 <= 1 && x2 >= 0 && x2 <= 1;
|
|
6791
|
+
}
|
|
6792
|
+
function isEasingToken(value) {
|
|
6793
|
+
return EASING_TOKENS.includes(String(value ?? ''));
|
|
6794
|
+
}
|
|
6795
|
+
/** True for anything an interaction may store as its easing. */
|
|
6796
|
+
function isInteractionEasing(value) {
|
|
6797
|
+
return EASING_KEYWORDS.includes(String(value ?? '')) || isEasingToken(value) || isCubicBezier(value);
|
|
6798
|
+
}
|
|
6799
|
+
/** A token's value is a timing function WAAPI plays: a keyword, a cubic-bezier, or a `linear()` / `steps()` curve (the
|
|
6800
|
+
* spring's). Read by shape, so it answers alike in every browser, on the server and in a spec. */
|
|
6801
|
+
const TIMING_FUNCTION = /^(linear|steps)\(.+\)$/;
|
|
6802
|
+
function supportedEasing(value) {
|
|
6803
|
+
return EASING_KEYWORDS.includes(value) || isCubicBezier(value) || TIMING_FUNCTION.test(value);
|
|
6804
|
+
}
|
|
6805
|
+
/**
|
|
6806
|
+
* The timing function WAAPI plays for `easing` on `el`: a keyword or a curve as stored; a token name → the token's
|
|
6807
|
+
* value as the element sees it (`--iox-ease-spring` → its `linear()`), so a section scheme or the canvas's token scope
|
|
6808
|
+
* applies; anything else, or a token the element cannot resolve → `fallback`.
|
|
6809
|
+
*/
|
|
6810
|
+
function resolveInteractionEasing(easing, el, fallback = DEFAULT_INTERACTION_EASING) {
|
|
6811
|
+
const value = String(easing ?? '').trim();
|
|
6812
|
+
if (EASING_KEYWORDS.includes(value) || isCubicBezier(value))
|
|
6813
|
+
return value;
|
|
6814
|
+
if (!isEasingToken(value))
|
|
6815
|
+
return fallback;
|
|
6816
|
+
const resolved = el?.ownerDocument?.defaultView?.getComputedStyle(el).getPropertyValue(`--iox-${value}`)?.trim();
|
|
6817
|
+
return resolved && supportedEasing(resolved) ? resolved : fallback;
|
|
6818
|
+
}
|
|
6819
|
+
|
|
6820
|
+
/**
|
|
6821
|
+
* When a pointer event should move something (G7 — Emil 85/86/91, mobile-native M1/M5). Both runtimes ask here.
|
|
6822
|
+
*
|
|
6823
|
+
* · A hover trigger answers a mouse or a pen only: a finger has no hover, and a tap's emulated mouseenter left the
|
|
6824
|
+
* hover state on until the next tap elsewhere.
|
|
6825
|
+
* · Press feedback lands on pointer-DOWN, at once — the click (pointer-up) commits. Only an action that is pure
|
|
6826
|
+
* feedback moves early: an animation of the pressed element itself that hides nothing and shows nothing. Opening,
|
|
6827
|
+
* closing, navigating and toggling stay on the click, so dragging away still cancels them. A keyboard press (Enter,
|
|
6828
|
+
* Space) has no pointer-down, so it never animates (Emil 2).
|
|
6829
|
+
*/
|
|
6830
|
+
var PointerKind;
|
|
6831
|
+
(function (PointerKind) {
|
|
6832
|
+
PointerKind["Mouse"] = "mouse";
|
|
6833
|
+
PointerKind["Pen"] = "pen";
|
|
6834
|
+
PointerKind["Touch"] = "touch";
|
|
6835
|
+
})(PointerKind || (PointerKind = {}));
|
|
6836
|
+
const HOVERING_POINTERS = new Set([PointerKind.Mouse, PointerKind.Pen]);
|
|
6837
|
+
/** True for a pointer that really hovers — a mouse or a pen, never a finger. An event with no pointer type (a synthetic
|
|
6838
|
+
* `mouseenter`) counts as a mouse. */
|
|
6839
|
+
function isHoverPointer(event) {
|
|
6840
|
+
const kind = event?.pointerType;
|
|
6841
|
+
return !kind || HOVERING_POINTERS.has(kind);
|
|
6842
|
+
}
|
|
6843
|
+
/** True for an action that is press FEEDBACK: it animates the pressed element itself and neither hides nor shows it. */
|
|
6844
|
+
function isPressFeedback(action) {
|
|
6845
|
+
if (!action || action.disabled)
|
|
6846
|
+
return false;
|
|
6847
|
+
if (action.target && action.target !== 'self')
|
|
6848
|
+
return false;
|
|
6849
|
+
if (ENTRANCE_ACTION_TYPES.has(action.type) || EXIT_ACTION_TYPES.has(action.type) || action.type === VisibilityActionType.Toggle)
|
|
6850
|
+
return false;
|
|
6851
|
+
return !!buildInteractionKeyframes(action.type, action.params);
|
|
6852
|
+
}
|
|
6853
|
+
/** A click interaction's actions split by when they run: the feedback on pointer-down, the rest on the click. */
|
|
6854
|
+
function splitPressFeedback(actions) {
|
|
6855
|
+
const onPress = [];
|
|
6856
|
+
const onClick = [];
|
|
6857
|
+
for (const action of actions ?? [])
|
|
6858
|
+
(isPressFeedback(action) ? onPress : onClick).push(action);
|
|
6859
|
+
return { onPress, onClick };
|
|
6860
|
+
}
|
|
6861
|
+
|
|
6862
|
+
/** How far the page has to move before it counts as scrolled — past a trackpad's rest jitter. */
|
|
6863
|
+
const SCROLLED_THRESHOLD_PX = 8;
|
|
6864
|
+
/** True once `offset` has passed the threshold. */
|
|
6865
|
+
function isScrolled(offset, threshold = SCROLLED_THRESHOLD_PX) {
|
|
6866
|
+
return Number.isFinite(offset) && offset > threshold;
|
|
6867
|
+
}
|
|
6868
|
+
/**
|
|
6869
|
+
* Keep `SCROLLED_ATTRIBUTE` on `target` while `source` has scrolled past the threshold — what the Scrolled state (G4)
|
|
6870
|
+
* compiles against, on the live site (the window → the document element) and on the canvas (its scroller → the page).
|
|
6871
|
+
* One passive listener, read once per frame, written only when it changes. Returns the stop.
|
|
6872
|
+
*/
|
|
6873
|
+
function watchScrolled(source, target, threshold = SCROLLED_THRESHOLD_PX) {
|
|
6874
|
+
let frame = 0;
|
|
6875
|
+
const raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : (fn) => setTimeout(() => fn(0), 16);
|
|
6876
|
+
const caf = typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
6877
|
+
const sync = () => {
|
|
6878
|
+
frame = 0;
|
|
6879
|
+
const scrolled = isScrolled(source.scrollY ?? source.scrollTop ?? 0, threshold);
|
|
6880
|
+
if (scrolled !== target.hasAttribute(SCROLLED_ATTRIBUTE))
|
|
6881
|
+
target.toggleAttribute(SCROLLED_ATTRIBUTE, scrolled);
|
|
6882
|
+
};
|
|
6883
|
+
const onScroll = () => { if (!frame)
|
|
6884
|
+
frame = raf(sync); };
|
|
6885
|
+
source.addEventListener('scroll', onScroll, { passive: true });
|
|
6886
|
+
sync();
|
|
6887
|
+
return () => {
|
|
6888
|
+
source.removeEventListener('scroll', onScroll);
|
|
6889
|
+
if (frame)
|
|
6890
|
+
caf(frame);
|
|
6891
|
+
target.removeAttribute(SCROLLED_ATTRIBUTE);
|
|
6892
|
+
};
|
|
6893
|
+
}
|
|
6894
|
+
|
|
6657
6895
|
/**
|
|
6658
6896
|
* page-style — the ONE compiler that turns a page's style settings into CSS.
|
|
6659
6897
|
*
|
|
@@ -8721,5 +8959,5 @@ function attachStringForm(form, options = {}) {
|
|
|
8721
8959
|
* Generated bundle index. Do not edit.
|
|
8722
8960
|
*/
|
|
8723
8961
|
|
|
8724
|
-
export { A11yAttribute, A11yTrait, ACCESSIBLE_NAME_TYPES, AOSService, ARIA_CURRENT_PAGE, BACKDROP_TWIN_KEY, BACKDROP_WHOLE_KEY, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, COMPONENT_STATE_SELECTOR, CONTAINER_HTML_TAGS, CONTEXT_ACTION_TYPES, CURRENT_LINK_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ComponentState, ContainerComponent, ContextStore, DECORATIVE_TYPES, DEFAULT_GALLERY_SCHEDULER, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DIALOG_CLOSE_ABOVE_ATTRIBUTE, DIALOG_NODE_TYPE, DeclarationContext, ENTRANCE_ACTION_TYPES, ENTRANCE_FALLBACK_CSS, ENTRANCE_NOSCRIPT_CSS, ENTRANCE_PRESTATE_ATTRIBUTE, EXIT_ACTION_TYPES, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop,
|
|
8962
|
+
export { A11yAttribute, A11yTrait, ACCESSIBLE_NAME_TYPES, AOSService, ARIA_CURRENT_PAGE, BACKDROP_TWIN_KEY, BACKDROP_WHOLE_KEY, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, COMPONENT_STATE_SELECTOR, CONTAINER_HTML_TAGS, CONTEXT_ACTION_TYPES, CURRENT_LINK_TYPES, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ComponentState, ContainerComponent, ContextStore, DECORATIVE_TYPES, DEFAULT_GALLERY_SCHEDULER, DEFAULT_INTERACTION_EASING, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DIALOG_CLOSE_ABOVE_ATTRIBUTE, DIALOG_NODE_TYPE, DeclarationContext, EASING_KEYWORDS, EASING_TOKENS, ENTRANCE_ACTION_TYPES, ENTRANCE_FALLBACK_CSS, ENTRANCE_NOSCRIPT_CSS, ENTRANCE_PRESTATE_ATTRIBUTE, EXIT_ACTION_TYPES, EasingKeyword, EasingToken, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, HOVER_DEFAULT_TRANSITION_TRAITS, HOVER_MEDIA_QUERY, HOVER_STATES, INTERACTION_ANIMATION_ID, INTERACTION_HIDDEN_ATTRIBUTE, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxDialogComponent, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, IoxVideoComponent, LAST_EMITTED_STATES, LEGACY_DIRECTION_KEY, LEGACY_HOVER_TRANSITION_TRAITS, LEGACY_SWIPER_CONTROLS, LinkedContainerComponent, MANAGED_A11Y_ATTRIBUTES, MAX_LINES_KEY, NAMED_GROUP_ROLES, NO_PAGE_TRANSITION, ON_STATE_ROLES, OUTER_STYLE_PROPS, PAGE_STYLE_TOKENS, PAGE_TOKEN_FALLBACKS, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PART_CLASS_NAMES, PART_PAGINATION_MODIFIER, PHONE_TRANSITION_QUERY, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PageStyleField, PageStyleSource, PointerKind, REDUCED_MOTION_QUERY, RELATIONAL_STATE_PSEUDO, RevealActionType, SCROLLED_ATTRIBUTE, SCROLLED_STATE_ROLE, SCROLLED_THRESHOLD_PX, SCROLL_EASINGS, SELF_PLAYING_TRIGGERS, SLIDER_INPUTS_ATTRIBUTE, SLIDER_INPUT_NAMES, STATE_PSEUDO_CLASS, STRUCTURAL_STATES, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_A11Y_OPTIONS, SWIPER_RESPONSIVE_TRAITS, SWIPER_TRIGGER_EVENTS, ScrollEasing, SectionComponent, SettleMode, StringFormRuntime, SwiperModuleName, TARGETED_STATE_SUFFIX, TEXT_ALIGN_KEY, TEXT_DIRECTION_KEY, TRANSITION_FEELS, TRANSITION_PROPERTY_KEY, TextAlign, TextBlockComponent, VALIDATION_STATES, VALIDATION_STATE_CLASS, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, VisibilityActionType, activeActions, animateAction, applyBindingPipes, applyFeel, attachStringForm, bootSlider, breakpointDef, breakpointForWidth, breakpointQueryFor, buildInteractionKeyframes, buildPartSelector, buildSwiperBreakpoints, buildTargetedStateSelector, buildTargetedSuffixSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, closeAboveMediaQuery, collectContextSlotKeys, compileDeclarations, compilePageStyle, componentStatesFor, composeVirtualTraits, containerHtmlTag, contextActionEffect, contextSlotKeys, countOverrides, declaredInputNames, decomposeBackdropFilter, defaultHoverTransitionTraits, defaultMessageResolver, deriveSeoFromContent, describePageStyle, describeSeoFields, dialogCloseAboveMinWidth, domHasSliderParts, effectiveActionType, effectiveTransitionId, entrancePreStateStyle, entranceStartsHidden, feelFor, finalKeyframe, framesFromLiveValue, gateHoverRule, getSeoValue, hasHoverState, hasOwnPageTransition, hasOwnTransition, initialSlotValues, isActionEnabled, isContextAction, isCubicBezier, isCurrentLink, isEasingToken, isExternalOrFragment, isGradientPaint, isHoverPointer, isHoverState, isInputOverriddenAt, isInteractionEasing, isLastEmittedStateKey, isOverriddenAt, isPressFeedback, isScrolled, isStructuralState, isValidSlotKey, isWholeBackdropSet, keyframePropertyName, keyframeStyleEntries, legacyEnterToTransition, mediaQueryFor, mergeSwiperBreakpoints, migrateLegacyDirection, migrateLegacyTextAlign, motionAllowed, nearestCommonAncestorId, needsAccessibleName, needsGroupName, nodeA11yAttributes, nodeCssId, nodeTraitValue, nodeUsesContext, normalizeAppPath, normalizeGalleryImage, normalizeIconClass, orderStatesForEmit, pageTransitionOf, parentBreakpoint, parseUrlList, partClassName, planPartRule, planResponsiveRules, planScroll, planStateRule, planSwiperOptions, playDualLayerTransition, playInteraction, prefersReducedMotion, renderDefaultDeclarations, resetPageStyleField, resetSeoField, resolveBoundValue, resolveContextValue, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolveInteractionEasing, resolvePageTransition, resolvePath, resolveSeo, resolveStateStyles, resolveStyleProps, resolveToggleVisibility, resolveValueChain, rewriteViewportUnits, safeSetInput, serializeA11yAttributes, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, setSeoValue, settleInteraction, settleModeFor, sliderControlElements, sliderInputsFromProps, sliderInputsOf, splitOuterProps, splitPressFeedback, stateNamesIn, statePseudoClass, stateSelectorSuffix, stateTransitionProperties, stringFormRuntimeOf, stripSuppressedProps, swiperAutoplayAllowed, swiperLoopOptions, swiperModuleNames, syncNodeA11yAttributes, syncSubmitButtons, targetedStateSelector, transitionPropertyList, viewportTransitionContext, watchScrolled, withContextSlots, withStateTransitions, wrapInBreakpointQuery, wrapInMediaQuery };
|
|
8725
8963
|
//# sourceMappingURL=vectoriox-iox-ui.mjs.map
|