@ds-gn/ui 0.8.0 → 0.9.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/custom-elements.json +77 -0
- package/dist/common/props/motion/motion.props.d.ts +10 -0
- package/dist/components/FeatureTabs/src/FeatureTabs.d.ts +19 -0
- package/dist/components/FeatureTabs/src/FeatureTabs.js +83 -3
- package/dist/components/FeatureTabs/src/FeatureTabs.props.d.ts +1 -1
- package/dist/components/Hero/src/Hero.d.ts +11 -0
- package/dist/components/Hero/src/Hero.js +39 -0
- package/dist/styles/hero-fallback.css +5 -0
- package/package.json +2 -2
package/custom-elements.json
CHANGED
|
@@ -1520,6 +1520,15 @@
|
|
|
1520
1520
|
"privacy": "private",
|
|
1521
1521
|
"description": "The feature whose detail last faded in; the fade replays when it changes."
|
|
1522
1522
|
},
|
|
1523
|
+
{
|
|
1524
|
+
"kind": "field",
|
|
1525
|
+
"name": "_motionState",
|
|
1526
|
+
"type": {
|
|
1527
|
+
"text": "'static' | 'held' | 'played' | undefined"
|
|
1528
|
+
},
|
|
1529
|
+
"privacy": "private",
|
|
1530
|
+
"description": "Motion progress, decided by the first visibility report."
|
|
1531
|
+
},
|
|
1523
1532
|
{
|
|
1524
1533
|
"kind": "field",
|
|
1525
1534
|
"name": "surface",
|
|
@@ -1606,6 +1615,32 @@
|
|
|
1606
1615
|
"description": "Accessible label for the tab list.",
|
|
1607
1616
|
"attribute": "tabs-aria-label"
|
|
1608
1617
|
},
|
|
1618
|
+
{
|
|
1619
|
+
"kind": "field",
|
|
1620
|
+
"name": "motion",
|
|
1621
|
+
"type": {
|
|
1622
|
+
"text": "MotionType"
|
|
1623
|
+
},
|
|
1624
|
+
"description": "Animate the section in when it scrolls into view: the header's heading\nletter by letter, then its description, then the tabs as a whole. The\neyebrow stays static. A section already in view when it loads, and\nreduced motion, stay static.",
|
|
1625
|
+
"attribute": "motion",
|
|
1626
|
+
"reflects": true
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
"kind": "method",
|
|
1630
|
+
"name": "_updateMotion",
|
|
1631
|
+
"privacy": "private",
|
|
1632
|
+
"description": "Decide the motion from the first visibility report: a section already\non screen stays static; one off screen holds its parts hidden (from\nscript, so nothing is hidden when scripts do not run) and plays when it\ncomes into view, so even a jump to it shows no unanimated frame."
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
"kind": "method",
|
|
1636
|
+
"name": "_motionParts",
|
|
1637
|
+
"privacy": "private"
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
"kind": "method",
|
|
1641
|
+
"name": "_playMotion",
|
|
1642
|
+
"privacy": "private"
|
|
1643
|
+
},
|
|
1609
1644
|
{
|
|
1610
1645
|
"kind": "method",
|
|
1611
1646
|
"name": "_fadeInDetail",
|
|
@@ -1862,6 +1897,14 @@
|
|
|
1862
1897
|
},
|
|
1863
1898
|
"default": "DEFAULT_TABS_ARIA_LABEL",
|
|
1864
1899
|
"description": "Accessible label for the tab list."
|
|
1900
|
+
},
|
|
1901
|
+
{
|
|
1902
|
+
"name": "motion",
|
|
1903
|
+
"fieldName": "motion",
|
|
1904
|
+
"type": {
|
|
1905
|
+
"text": "MotionType"
|
|
1906
|
+
},
|
|
1907
|
+
"description": "Animate the section in when it scrolls into view: the header's heading\nletter by letter, then its description, then the tabs as a whole. The\neyebrow stays static. A section already in view when it loads, and\nreduced motion, stay static."
|
|
1865
1908
|
}
|
|
1866
1909
|
]
|
|
1867
1910
|
}
|
|
@@ -2642,6 +2685,32 @@
|
|
|
2642
2685
|
"description": "Space below the section. Unset follows the inherited section space.",
|
|
2643
2686
|
"attribute": "padding-bottom",
|
|
2644
2687
|
"reflects": true
|
|
2688
|
+
},
|
|
2689
|
+
{
|
|
2690
|
+
"kind": "field",
|
|
2691
|
+
"name": "motion",
|
|
2692
|
+
"type": {
|
|
2693
|
+
"text": "MotionType"
|
|
2694
|
+
},
|
|
2695
|
+
"description": "Animate the content's eyebrow in letter by letter once the hero loads,\neach letter fading in with a small rise.\nEverything else stays static, so the hero's largest text paints at once.\nUnder reduced motion the eyebrow is static too.",
|
|
2696
|
+
"attribute": "motion",
|
|
2697
|
+
"reflects": true
|
|
2698
|
+
},
|
|
2699
|
+
{
|
|
2700
|
+
"kind": "field",
|
|
2701
|
+
"name": "_motion",
|
|
2702
|
+
"privacy": "private",
|
|
2703
|
+
"default": "new MotionController(this)"
|
|
2704
|
+
},
|
|
2705
|
+
{
|
|
2706
|
+
"kind": "method",
|
|
2707
|
+
"name": "_eyebrows",
|
|
2708
|
+
"privacy": "private",
|
|
2709
|
+
"return": {
|
|
2710
|
+
"type": {
|
|
2711
|
+
"text": "Element[]"
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2645
2714
|
}
|
|
2646
2715
|
],
|
|
2647
2716
|
"superclass": {
|
|
@@ -2698,6 +2767,14 @@
|
|
|
2698
2767
|
"text": "SectionSpaceType | undefined"
|
|
2699
2768
|
},
|
|
2700
2769
|
"description": "Space below the section. Unset follows the inherited section space."
|
|
2770
|
+
},
|
|
2771
|
+
{
|
|
2772
|
+
"name": "motion",
|
|
2773
|
+
"fieldName": "motion",
|
|
2774
|
+
"type": {
|
|
2775
|
+
"text": "MotionType"
|
|
2776
|
+
},
|
|
2777
|
+
"description": "Animate the content's eyebrow in letter by letter once the hero loads,\neach letter fading in with a small rise.\nEverything else stays static, so the hero's largest text paints at once.\nUnder reduced motion the eyebrow is static too."
|
|
2701
2778
|
}
|
|
2702
2779
|
]
|
|
2703
2780
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a section animates in. Components with their own motion
|
|
3
|
+
* vocabulary (Modal's direction values) declare their own `motion` values.
|
|
4
|
+
*/
|
|
5
|
+
export declare const motionValues: {
|
|
6
|
+
readonly ON: "on";
|
|
7
|
+
readonly OFF: "off";
|
|
8
|
+
};
|
|
9
|
+
export declare const motionProps: import("lit").PropertyDeclaration<unknown, unknown>;
|
|
10
|
+
export type MotionType = (typeof motionValues)[keyof typeof motionValues];
|
|
@@ -8,6 +8,7 @@ import '../../Icon/src/Icon.js';
|
|
|
8
8
|
import { Base } from '../../../common/Base/Base.js';
|
|
9
9
|
import { type SurfaceType } from '../../../common/props/surface/surface.props.js';
|
|
10
10
|
import { type CSSResultGroup } from 'lit';
|
|
11
|
+
import { type MotionType } from '../../../common/props/motion/motion.props.js';
|
|
11
12
|
import { type SectionSpaceType } from '../../Container/src/Container.props.js';
|
|
12
13
|
import { type FeatureTabData } from './FeatureTabs.props.js';
|
|
13
14
|
/** @slot header - Optional content above the tab interface. */
|
|
@@ -22,6 +23,8 @@ export declare class FeatureTabs extends Base {
|
|
|
22
23
|
private _motion;
|
|
23
24
|
/** The feature whose detail last faded in; the fade replays when it changes. */
|
|
24
25
|
private _shownIndex?;
|
|
26
|
+
/** Motion progress, decided by the first visibility report. */
|
|
27
|
+
private _motionState?;
|
|
25
28
|
surface: SurfaceType;
|
|
26
29
|
features: FeatureTabData[];
|
|
27
30
|
duration: number;
|
|
@@ -37,8 +40,24 @@ export declare class FeatureTabs extends Base {
|
|
|
37
40
|
resumeAriaLabel: string;
|
|
38
41
|
/** Accessible label for the tab list. */
|
|
39
42
|
tabsAriaLabel: string;
|
|
43
|
+
/**
|
|
44
|
+
* Animate the section in when it scrolls into view: the header's heading
|
|
45
|
+
* letter by letter, then its description, then the tabs as a whole. The
|
|
46
|
+
* eyebrow stays static. A section already in view when it loads, and
|
|
47
|
+
* reduced motion, stay static.
|
|
48
|
+
*/
|
|
49
|
+
motion: MotionType;
|
|
40
50
|
constructor();
|
|
41
51
|
firstUpdated(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Decide the motion from the first visibility report: a section already
|
|
54
|
+
* on screen stays static; one off screen holds its parts hidden (from
|
|
55
|
+
* script, so nothing is hidden when scripts do not run) and plays when it
|
|
56
|
+
* comes into view, so even a jump to it shows no unanimated frame.
|
|
57
|
+
*/
|
|
58
|
+
private _updateMotion;
|
|
59
|
+
private _motionParts;
|
|
60
|
+
private _playMotion;
|
|
42
61
|
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
43
62
|
/**
|
|
44
63
|
* Fade the detail in whenever the active feature changes. `keyed` renders a
|
|
@@ -218,6 +218,10 @@ var surfaceValues = {
|
|
|
218
218
|
var surfaceProps = enumCreator(Object.values(surfaceValues), "surface", String, { reflect: true });
|
|
219
219
|
|
|
220
220
|
// components/FeatureTabs/src/FeatureTabs.ts
|
|
221
|
+
import {
|
|
222
|
+
prefersReducedMotion as prefersReducedMotion2,
|
|
223
|
+
splitText
|
|
224
|
+
} from "@ds-gn/motion";
|
|
221
225
|
import { MotionController } from "@ds-gn/motion/lit";
|
|
222
226
|
|
|
223
227
|
// ../../node_modules/.bun/lit-html@3.3.3/node_modules/lit-html/development/is-server.js
|
|
@@ -294,6 +298,15 @@ import {
|
|
|
294
298
|
import { property } from "lit/decorators.js";
|
|
295
299
|
import { keyed } from "lit/directives/keyed.js";
|
|
296
300
|
import { styleMap } from "lit/directives/style-map.js";
|
|
301
|
+
|
|
302
|
+
// common/props/motion/motion.props.ts
|
|
303
|
+
var motionValues = {
|
|
304
|
+
ON: "on",
|
|
305
|
+
OFF: "off"
|
|
306
|
+
};
|
|
307
|
+
var motionProps = enumCreator(Object.values(motionValues), "motion", String, { reflect: true });
|
|
308
|
+
|
|
309
|
+
// components/FeatureTabs/src/FeatureTabs.ts
|
|
297
310
|
import {
|
|
298
311
|
containerSizeValues,
|
|
299
312
|
paddingBottomProps,
|
|
@@ -1003,13 +1016,20 @@ var dotPipInnerClassNames = (active) => clsx_default("block", "rounded-full", "h
|
|
|
1003
1016
|
var playPauseClassNames = () => clsx_default("appearance-none", "border-0", "outline-none", "bg-transparent", "cursor-pointer", "text-accent", "py-[10px]", "px-[8px]", "flex", "items-center", "justify-center", "rounded-full", "transition-colors", "duration-150");
|
|
1004
1017
|
|
|
1005
1018
|
// components/FeatureTabs/src/FeatureTabs.ts
|
|
1019
|
+
var holdHidden = (el) => el.style.setProperty("opacity", "0");
|
|
1020
|
+
var releaseHidden = (el) => el.style.removeProperty("opacity");
|
|
1021
|
+
var HEADING_STAGGER = 20;
|
|
1022
|
+
var HEADING_MAX_SPREAD = 500;
|
|
1023
|
+
var HEADING_RISE = 4;
|
|
1024
|
+
var MOTION_OVERLAP = 160;
|
|
1006
1025
|
var FEATURE_TAB_ICONS = {
|
|
1007
1026
|
terminal: svg`<polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/>`,
|
|
1008
1027
|
brain: svg`<path d="M9 4.5a2.5 2.5 0 0 0-2.5 2.5v.5a2.5 2.5 0 0 0-2 4 2.5 2.5 0 0 0 2 4v.5A2.5 2.5 0 0 0 9 18.5a2.5 2.5 0 0 0 3-2.5V6a2.5 2.5 0 0 0-3-1.5z"/><path d="M15 4.5A2.5 2.5 0 0 1 17.5 7v.5a2.5 2.5 0 0 1 2 4 2.5 2.5 0 0 1-2 4v.5A2.5 2.5 0 0 1 15 18.5a2.5 2.5 0 0 1-3-2.5V6a2.5 2.5 0 0 1 3-1.5z"/>`,
|
|
1009
1028
|
cpu: svg`<rect x="5" y="5" width="14" height="14" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="2" x2="9" y2="5"/><line x1="15" y1="2" x2="15" y2="5"/><line x1="9" y1="19" x2="9" y2="22"/><line x1="15" y1="19" x2="15" y2="22"/><line x1="2" y1="9" x2="5" y2="9"/><line x1="2" y1="15" x2="5" y2="15"/><line x1="19" y1="9" x2="22" y2="9"/><line x1="19" y1="15" x2="22" y2="15"/>`,
|
|
1010
1029
|
palette: svg`<circle cx="12" cy="12" r="9"/><circle cx="7.5" cy="10.5" r="1" fill="currentColor"/><circle cx="12" cy="7.5" r="1" fill="currentColor"/><circle cx="16.5" cy="10.5" r="1" fill="currentColor"/><path d="M12 21a3 3 0 0 1-3-3c0-1.5 1-2 1-3a2 2 0 0 0-2-2"/>`,
|
|
1011
1030
|
plug: svg`<path d="M9 2v6"/><path d="M15 2v6"/><path d="M7 8h10v3a5 5 0 0 1-5 5 5 5 0 0 1-5-5z"/><path d="M12 16v6"/>`,
|
|
1012
|
-
shield: svg`<path d="M12 3l8 3v5c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V6z"/><path d="M9 12l2 2 4-4"
|
|
1031
|
+
shield: svg`<path d="M12 3l8 3v5c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V6z"/><path d="M9 12l2 2 4-4"/>`,
|
|
1032
|
+
zap: svg`<path d="M13 2 4 14h7l-1 8 9-12h-7z"/>`
|
|
1013
1033
|
};
|
|
1014
1034
|
var nextTabIndex = (key, index, lastIndex) => {
|
|
1015
1035
|
switch (key) {
|
|
@@ -1046,11 +1066,67 @@ class FeatureTabs extends Base {
|
|
|
1046
1066
|
this.pauseAriaLabel = DEFAULT_PAUSE_ARIA_LABEL;
|
|
1047
1067
|
this.resumeAriaLabel = DEFAULT_RESUME_ARIA_LABEL;
|
|
1048
1068
|
this.tabsAriaLabel = DEFAULT_TABS_ARIA_LABEL;
|
|
1069
|
+
this.motion = motionValues.OFF;
|
|
1049
1070
|
this._rotate = new AutoRotateController(this, DEFAULT_DURATION, () => this._inView.value === true);
|
|
1050
1071
|
}
|
|
1051
1072
|
firstUpdated() {
|
|
1052
1073
|
this._rotate.resume(this.features.length);
|
|
1053
1074
|
}
|
|
1075
|
+
_updateMotion() {
|
|
1076
|
+
const inView = this._inView.value;
|
|
1077
|
+
if (inView === undefined)
|
|
1078
|
+
return;
|
|
1079
|
+
if (this._motionState === undefined) {
|
|
1080
|
+
const play = this.motion === motionValues.ON && !inView && !prefersReducedMotion2();
|
|
1081
|
+
this._motionState = play ? "held" : "static";
|
|
1082
|
+
if (play)
|
|
1083
|
+
this._motionParts().forEach(holdHidden);
|
|
1084
|
+
}
|
|
1085
|
+
if (this._motionState === "held" && inView) {
|
|
1086
|
+
this._motionState = "played";
|
|
1087
|
+
this._playMotion();
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
_motionParts() {
|
|
1091
|
+
const header = Array.from(this.children).filter((el) => el.slot === "header");
|
|
1092
|
+
const find = (slot) => header.map((el) => el.querySelector(`[slot="${slot}"]`)).find((el) => el !== null);
|
|
1093
|
+
return [
|
|
1094
|
+
find("heading"),
|
|
1095
|
+
find("description"),
|
|
1096
|
+
...this.renderRoot.querySelectorAll("[data-motion-body]")
|
|
1097
|
+
].filter((el) => el !== undefined);
|
|
1098
|
+
}
|
|
1099
|
+
_playMotion() {
|
|
1100
|
+
const parts = this._motionParts();
|
|
1101
|
+
parts.forEach(releaseHidden);
|
|
1102
|
+
const heading = parts.find((el) => el.slot === "heading");
|
|
1103
|
+
const description = parts.find((el) => el.slot === "description");
|
|
1104
|
+
const split = heading ? splitText(heading) : undefined;
|
|
1105
|
+
const steps = [
|
|
1106
|
+
...split ? [
|
|
1107
|
+
{
|
|
1108
|
+
targets: split.chars,
|
|
1109
|
+
preset: "fade",
|
|
1110
|
+
y: HEADING_RISE,
|
|
1111
|
+
stagger: HEADING_STAGGER,
|
|
1112
|
+
maxDuration: HEADING_MAX_SPREAD
|
|
1113
|
+
}
|
|
1114
|
+
] : [],
|
|
1115
|
+
...description ? [
|
|
1116
|
+
{
|
|
1117
|
+
el: description,
|
|
1118
|
+
preset: "fade",
|
|
1119
|
+
overlap: MOTION_OVERLAP
|
|
1120
|
+
}
|
|
1121
|
+
] : [],
|
|
1122
|
+
{
|
|
1123
|
+
targets: parts.filter((el) => el.hasAttribute("data-motion-body")),
|
|
1124
|
+
preset: "fade",
|
|
1125
|
+
overlap: MOTION_OVERLAP
|
|
1126
|
+
}
|
|
1127
|
+
];
|
|
1128
|
+
this._motion.timeline(steps).finished.then(() => split?.revert());
|
|
1129
|
+
}
|
|
1054
1130
|
updated(changedProperties) {
|
|
1055
1131
|
super.updated(changedProperties);
|
|
1056
1132
|
this.updateTheme(changedProperties, this.surface);
|
|
@@ -1058,6 +1134,7 @@ class FeatureTabs extends Base {
|
|
|
1058
1134
|
this._rotate.setDuration(this.duration);
|
|
1059
1135
|
}
|
|
1060
1136
|
this._fadeInDetail();
|
|
1137
|
+
this._updateMotion();
|
|
1061
1138
|
}
|
|
1062
1139
|
_fadeInDetail() {
|
|
1063
1140
|
const index = this._rotate.activeIndex;
|
|
@@ -1262,12 +1339,12 @@ class FeatureTabs extends Base {
|
|
|
1262
1339
|
</div>
|
|
1263
1340
|
|
|
1264
1341
|
<!-- Mobile: detail panel only, no grid -->
|
|
1265
|
-
<div class="lg:hidden">
|
|
1342
|
+
<div class="lg:hidden" data-motion-body>
|
|
1266
1343
|
${this._renderDetailPanel(idx, activeFeature, progress, total, paused, features)}
|
|
1267
1344
|
</div>
|
|
1268
1345
|
|
|
1269
1346
|
<!-- Desktop: full grid with tabs + detail -->
|
|
1270
|
-
<div class="hidden lg:block">
|
|
1347
|
+
<div class="hidden lg:block" data-motion-body>
|
|
1271
1348
|
<dsgn-grid cols="7-5" gap="xl" ?reverse=${true}>
|
|
1272
1349
|
${this._renderTabList(features, idx, progress, paused, "col-2")}
|
|
1273
1350
|
${this._renderDetailPanel(idx, activeFeature, progress, total, paused, features, "col-1")}
|
|
@@ -1311,6 +1388,9 @@ __legacyDecorateClassTS([
|
|
|
1311
1388
|
__legacyDecorateClassTS([
|
|
1312
1389
|
property({ type: String, attribute: "tabs-aria-label" })
|
|
1313
1390
|
], FeatureTabs.prototype, "tabsAriaLabel", undefined);
|
|
1391
|
+
__legacyDecorateClassTS([
|
|
1392
|
+
property({ ...motionProps })
|
|
1393
|
+
], FeatureTabs.prototype, "motion", undefined);
|
|
1314
1394
|
defineElement("dsgn-feature-tabs", FeatureTabs);
|
|
1315
1395
|
export {
|
|
1316
1396
|
FeatureTabs
|
|
@@ -5,6 +5,7 @@ import '../../Grid/src/Grid.js';
|
|
|
5
5
|
import '../../HeadingBlock/src/HeadingBlock.js';
|
|
6
6
|
import { type CSSResultGroup } from 'lit';
|
|
7
7
|
import { Base } from '../../../common/Base/Base.js';
|
|
8
|
+
import { type MotionType } from '../../../common/props/motion/motion.props.js';
|
|
8
9
|
import { type SurfaceType } from '../../../common/props/surface/surface.props.js';
|
|
9
10
|
import { type SectionSpaceType } from '../../Container/src/Container.props.js';
|
|
10
11
|
import { type HeroContentAlignType, type HeroLayoutType, type HeroMinHeightType } from './Hero.props.js';
|
|
@@ -37,6 +38,16 @@ export declare class Hero extends Base {
|
|
|
37
38
|
paddingTop?: SectionSpaceType;
|
|
38
39
|
/** Space below the section. Unset follows the inherited section space. */
|
|
39
40
|
paddingBottom?: SectionSpaceType;
|
|
41
|
+
/**
|
|
42
|
+
* Animate the content's eyebrow in letter by letter once the hero loads,
|
|
43
|
+
* each letter fading in with a small rise.
|
|
44
|
+
* Everything else stays static, so the hero's largest text paints at once.
|
|
45
|
+
* Under reduced motion the eyebrow is static too.
|
|
46
|
+
*/
|
|
47
|
+
motion: MotionType;
|
|
48
|
+
private _motion;
|
|
49
|
+
firstUpdated(): void;
|
|
50
|
+
private _eyebrows;
|
|
40
51
|
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
41
52
|
render(): import("lit").TemplateResult<1>;
|
|
42
53
|
}
|
|
@@ -14,6 +14,8 @@ import"../../Container/src/Container.js";
|
|
|
14
14
|
import"../../FormBlock/src/FormBlock.js";
|
|
15
15
|
import"../../Grid/src/Grid.js";
|
|
16
16
|
import"../../HeadingBlock/src/HeadingBlock.js";
|
|
17
|
+
import { prefersReducedMotion, splitText } from "@ds-gn/motion";
|
|
18
|
+
import { MotionController } from "@ds-gn/motion/lit";
|
|
17
19
|
import { html as html2 } from "lit";
|
|
18
20
|
import { property } from "lit/decorators.js";
|
|
19
21
|
|
|
@@ -118,6 +120,13 @@ var enumCreator = (acceptableValues, propName, type, other = {}) => {
|
|
|
118
120
|
};
|
|
119
121
|
};
|
|
120
122
|
|
|
123
|
+
// common/props/motion/motion.props.ts
|
|
124
|
+
var motionValues = {
|
|
125
|
+
ON: "on",
|
|
126
|
+
OFF: "off"
|
|
127
|
+
};
|
|
128
|
+
var motionProps = enumCreator(Object.values(motionValues), "motion", String, { reflect: true });
|
|
129
|
+
|
|
121
130
|
// common/props/surface/surface.props.ts
|
|
122
131
|
var surfaceValues = {
|
|
123
132
|
LIGHT: "light",
|
|
@@ -189,6 +198,9 @@ var styles2 = css2`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.co
|
|
|
189
198
|
.grid {
|
|
190
199
|
display: grid;
|
|
191
200
|
}
|
|
201
|
+
.hidden {
|
|
202
|
+
display: none;
|
|
203
|
+
}
|
|
192
204
|
.h-64 {
|
|
193
205
|
height: calc(var(--spacing) * 64);
|
|
194
206
|
}
|
|
@@ -412,6 +424,11 @@ var centeredFormClassNames = (contentAlign) => {
|
|
|
412
424
|
};
|
|
413
425
|
|
|
414
426
|
// components/Hero/src/Hero.ts
|
|
427
|
+
var EYEBROW_DELAY = 500;
|
|
428
|
+
var EYEBROW_STAGGER = 30;
|
|
429
|
+
var EYEBROW_MAX_SPREAD = 600;
|
|
430
|
+
var EYEBROW_RISE = 4;
|
|
431
|
+
|
|
415
432
|
class Hero extends Base {
|
|
416
433
|
constructor() {
|
|
417
434
|
super(...arguments);
|
|
@@ -419,8 +436,27 @@ class Hero extends Base {
|
|
|
419
436
|
this.layout = heroLayoutValues.ASSET_RIGHT;
|
|
420
437
|
this.minHeight = heroMinHeightValues.MD;
|
|
421
438
|
this.contentAlign = heroContentAlignValues.START;
|
|
439
|
+
this.motion = motionValues.OFF;
|
|
440
|
+
this._motion = new MotionController(this);
|
|
422
441
|
}
|
|
423
442
|
static styles = [Base.styles, Hero_default];
|
|
443
|
+
firstUpdated() {
|
|
444
|
+
if (this.motion !== motionValues.ON || prefersReducedMotion())
|
|
445
|
+
return;
|
|
446
|
+
this._eyebrows().forEach((eyebrow) => {
|
|
447
|
+
const split = splitText(eyebrow);
|
|
448
|
+
this._motion.sequence(split.chars, {
|
|
449
|
+
preset: "fade",
|
|
450
|
+
y: EYEBROW_RISE,
|
|
451
|
+
delay: EYEBROW_DELAY,
|
|
452
|
+
stagger: EYEBROW_STAGGER,
|
|
453
|
+
maxDuration: EYEBROW_MAX_SPREAD
|
|
454
|
+
}).finished.then(split.revert);
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
_eyebrows() {
|
|
458
|
+
return Array.from(this.children).filter((el) => el.slot === "content").flatMap((el) => Array.from(el.querySelectorAll('[slot="eyebrow"]')));
|
|
459
|
+
}
|
|
424
460
|
updated(changedProperties) {
|
|
425
461
|
super.updated(changedProperties);
|
|
426
462
|
this.updateTheme(changedProperties, this.surface);
|
|
@@ -526,6 +562,9 @@ __legacyDecorateClassTS([
|
|
|
526
562
|
__legacyDecorateClassTS([
|
|
527
563
|
property({ ...paddingBottomProps })
|
|
528
564
|
], Hero.prototype, "paddingBottom", undefined);
|
|
565
|
+
__legacyDecorateClassTS([
|
|
566
|
+
property({ ...motionProps })
|
|
567
|
+
], Hero.prototype, "motion", undefined);
|
|
529
568
|
defineElement("dsgn-hero", Hero);
|
|
530
569
|
export {
|
|
531
570
|
Hero
|
|
@@ -489,6 +489,11 @@ dsgn-hero:not(:defined)[layout='asset-background']:not(:has(> [slot='features'])
|
|
|
489
489
|
padding-bottom: calc(var(--spacing) * 6);
|
|
490
490
|
grid-row: 3;
|
|
491
491
|
}
|
|
492
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
493
|
+
dsgn-hero:not(:defined)[motion='on'] > [slot='content'] [slot='eyebrow'] {
|
|
494
|
+
opacity: 0;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
492
497
|
@property --tw-tracking {
|
|
493
498
|
syntax: "*";
|
|
494
499
|
inherits: false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ds-gn/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "UI components for the DS-GN Design System",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -346,7 +346,7 @@
|
|
|
346
346
|
"react-dom": "19.2.4"
|
|
347
347
|
},
|
|
348
348
|
"dependencies": {
|
|
349
|
-
"@ds-gn/motion": "0.
|
|
349
|
+
"@ds-gn/motion": "0.9.0",
|
|
350
350
|
"@ds-gn/tokens": "0.8.0",
|
|
351
351
|
"@lit-labs/observers": "^2.0.5",
|
|
352
352
|
"@lit/react": "^1.0.7",
|