Skip to content

Commit c191122

Browse files
committed
feat: add stylelint configuration and implement sticky toolbar feature in timeline components
1 parent 27dd6d7 commit c191122

18 files changed

+138
-78
lines changed

.stylelintrc.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"customSyntax": "postcss-styled-syntax",
3+
"extends": [
4+
"stylelint-config-recommended",
5+
"stylelint-config-recess-order"
6+
],
7+
"rules": {
8+
"alpha-value-notation": "number",
9+
"color-function-notation": "modern",
10+
"color-hex-case": "lower",
11+
"color-hex-length": "short",
12+
"color-no-invalid-hex": true,
13+
"declaration-block-no-duplicate-properties": true,
14+
"declaration-block-no-redundant-longhand-properties": true,
15+
"declaration-block-single-line-max-declarations": 1,
16+
"font-family-name-quotes": "always-unless-keyword",
17+
"function-calc-no-unspaced-operator": true,
18+
"function-linear-gradient-no-nonstandard-direction": true,
19+
"function-name-case": "lower",
20+
"length-zero-no-unit": true,
21+
"max-nesting-depth": 3,
22+
"no-descending-specificity": null,
23+
"no-duplicate-selectors": true,
24+
"no-empty-source": null,
25+
"no-invalid-double-slash-comments": null,
26+
"number-leading-zero": "always",
27+
"property-no-vendor-prefix": [
28+
true,
29+
{
30+
"ignoreProperties": ["appearance", "background-clip", "backdrop-filter"]
31+
}
32+
],
33+
"selector-class-pattern": null,
34+
"selector-id-pattern": null,
35+
"selector-max-id": 0,
36+
"selector-no-vendor-prefix": true,
37+
"selector-pseudo-class-no-unknown": [
38+
true,
39+
{
40+
"ignorePseudoClasses": ["global", "local"]
41+
}
42+
],
43+
"shorthand-property-no-redundant-values": true,
44+
"string-quotes": "single",
45+
"unit-no-unknown": true,
46+
"value-keyword-case": [
47+
"lower",
48+
{
49+
"ignoreKeywords": ["currentColor"]
50+
}
51+
],
52+
"value-no-vendor-prefix": true
53+
},
54+
"ignoreFiles": [
55+
"node_modules/**/*",
56+
"dist/**/*",
57+
"coverage/**/*",
58+
"**/*.ts",
59+
"**/*.tsx",
60+
"**/*.js",
61+
"**/*.jsx",
62+
"**/*.css.ts",
63+
"**/*.css.js"
64+
]
65+
}

MIGRATION.md

Lines changed: 0 additions & 43 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,7 @@ const handleFullscreenChange = (isFullscreen) => {
975975
| `uniqueId` | `string` | | Sets a custom unique ID for the timeline wrapper. Useful with `noUniqueId={true}`. |
976976
| `disableToolbar` | `boolean` | `false` | Hides the entire toolbar/control panel. |
977977
| `toolbarPosition` | `'top'` or `'bottom'` | `'top'` | Positions the toolbar at the top or bottom of the timeline. |
978+
| `stickyToolbar` | `boolean` | `false` | Makes the toolbar sticky at the top while scrolling, keeping controls visible for long timelines. |
978979
| `highlightCardsOnHover` | `boolean` | `false` | Highlights timeline cards on mouse hover. |
979980

980981
## 🎨 Customization

src/components/index.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,18 @@ function convertToLegacyProps(props: TimelinePropsV2): TimelineProps {
3232
activeItemIndex: props.activeItemIndex,
3333
allowDynamicUpdate: props.allowDynamicUpdate,
3434
uniqueId: props.id,
35-
onItemSelected: props.onItemSelected,
35+
onItemSelected: props.onItemSelected ?
36+
(data: any) => {
37+
// Convert from legacy flat structure to new nested structure
38+
if ('item' in data) {
39+
// Already in new format
40+
props.onItemSelected!(data);
41+
} else {
42+
// Convert from legacy format
43+
const { index, ...item } = data;
44+
props.onItemSelected!({ item, index });
45+
}
46+
} : undefined,
3647
onScrollEnd: props.onScrollEnd,
3748
onThemeChange: props.onThemeChange as any,
3849
onRestartSlideshow: props.onRestartSlideshow,
@@ -402,7 +413,9 @@ const Chrono: React.FunctionComponent<ChronoProps> = (
402413
// This prevents unwanted resets during dynamic loading and circular updates
403414
if (activeItemIndex !== previousActiveItemIndexRef.current) {
404415
previousActiveItemIndexRef.current = activeItemIndex;
405-
handleTimelineUpdate(activeItemIndex);
416+
if (activeItemIndex !== undefined) {
417+
handleTimelineUpdate(activeItemIndex);
418+
}
406419
}
407420
}, [activeItemIndex, handleTimelineUpdate]);
408421

@@ -427,15 +440,15 @@ const Chrono: React.FunctionComponent<ChronoProps> = (
427440
if (!timeLineItems.length) {
428441
return;
429442
}
430-
if (activeTimelineItem < timeLineItems.length - 1) {
443+
if (activeTimelineItem !== undefined && activeTimelineItem < timeLineItems.length - 1) {
431444
const newTimeLineItem = activeTimelineItem + 1;
432445

433446
// Update timeline state and trigger smooth navigation
434447
handleTimelineUpdate(newTimeLineItem);
435448
setActiveTimelineItem(newTimeLineItem);
436449

437450
if (
438-
mode === 'HORIZONTAL' &&
451+
mapNewModeToLegacy(mode) === 'HORIZONTAL' &&
439452
slideShowActive &&
440453
items &&
441454
items.length - 1 === newTimeLineItem
@@ -453,7 +466,7 @@ const Chrono: React.FunctionComponent<ChronoProps> = (
453466
]);
454467

455468
const handleOnPrevious = useCallback(() => {
456-
if (activeTimelineItem > 0) {
469+
if (activeTimelineItem !== undefined && activeTimelineItem > 0) {
457470
const newTimeLineItem = activeTimelineItem - 1;
458471

459472
// Update timeline state and trigger smooth navigation
@@ -537,7 +550,7 @@ const Chrono: React.FunctionComponent<ChronoProps> = (
537550
id="testette"
538551
>
539552
<Timeline
540-
activeTimelineItem={activeTimelineItem}
553+
activeTimelineItem={activeTimelineItem ?? 0}
541554
contentDetailsChildren={contentDetailsChildren}
542555
iconChildren={iconChildren}
543556
items={timeLineItems}
@@ -553,7 +566,7 @@ const Chrono: React.FunctionComponent<ChronoProps> = (
553566
slideItemDuration={slideItemDuration}
554567
{...pickDefined({
555568
onScrollEnd,
556-
onItemSelected,
569+
onItemSelected: legacyProps.onItemSelected,
557570
})}
558571
onOutlineSelection={handleOutlineSelection}
559572
mode={mapNewModeToLegacy(mode)}

src/components/timeline-elements/timeline-card/timeline-horizontal-card-ve.css.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ globalStyle(`${shape} img`, {
246246
// Timeline title container using new patterns
247247
export const timelineTitleContainer = recipe({
248248
base: [
249-
patterns.text({ variant: 'title' }),
249+
patterns.text({ variant: 'h3' }),
250250
sprinkles({
251251
display: 'flex',
252252
alignItems: 'center',
@@ -294,7 +294,7 @@ export const timelineTitleContainer = recipe({
294294

295295
// Base timeline content container using new system
296296
const baseTimelineContentContainer = style([
297-
patterns.card({ size: 'md', elevation: 'medium' }),
297+
patterns.card({ size: 'md', elevation: 'low' }),
298298
sprinkles({
299299
alignItems: 'flex-start',
300300
}),
@@ -408,7 +408,7 @@ globalStyle(`${timelineContentContainer}.vertical`, {
408408

409409
// Card container using new unified system
410410
export const cardContainer = style([
411-
patterns.card({ size: 'lg', elevation: 'medium' }),
411+
patterns.card({ size: 'lg', elevation: 'low' }),
412412
sprinkles({
413413
display: 'flex',
414414
flexDirection: 'column',

src/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const TimelineCard: React.FunctionComponent<TimelineCardModel> = ({
5959
} = useTimelineCard({
6060
cardLess,
6161
showAllCardsHorizontal,
62-
mode,
62+
mode: mode as 'HORIZONTAL' | 'VERTICAL' | 'VERTICAL_ALTERNATING' | 'HORIZONTAL_ALL',
6363
position,
6464
iconChild,
6565
...pickDefined({

src/components/timeline/timeline-popover-elements.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ const QuickJump: FunctionComponent<QuickJumpProp> = ({
118118

119119
return (
120120
<PopOver
121-
placeholder={buttonTexts?.jumpToTimeline || "Jump to timeline item"}
121+
placeholder={buttonTexts?.jumpTo || "Jump to timeline item"}
122122
position={position}
123123
theme={theme}
124124
width={400}

src/components/timeline/timeline.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ const Timeline: React.FunctionComponent<TimelineModel> = (
640640
console.error('Fullscreen error:', error);
641641
setIsFullscreen(false);
642642
}}
643-
stickyToolbar={props.stickyToolbar}
643+
stickyToolbar={props.stickyToolbar ?? false}
644644
/>
645645
)}
646646

src/demo/App.css.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export const componentContainerTree = style({
6464
borderRadius: '4px',
6565
height: '300px',
6666
margin: '0 auto',
67+
width: "100%",
68+
border: '1px solid #ccc',
6769
});
6870

6971
export const componentContainerTreeDesktop = style([

src/demo/components/vertical/AlternatingVertical.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ export const AlternatingVertical: FunctionComponent<AlternatingVerticalProps> =
4949

5050
display={{
5151
toolbar: {
52-
enabled: true
52+
enabled: true,
53+
sticky: true
5354
},
5455
}}
55-
stickyToolbar={true}
5656

5757
animation={{
5858
slideshow: {

0 commit comments

Comments
 (0)