Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0fd3ef5
feat(InteractiveCard): made the boilerplate for component
HaykKirakosyanSoft Nov 26, 2025
4683776
feat(InteractiveCard): component UI
petrosyansos Nov 27, 2025
eb747f4
feat(InteractiveCard): added starting props for the component
HaykKirakosyanSoft Dec 3, 2025
13cd76e
feat(InteractiveCard): updated stories file accordingly to new props
HaykKirakosyanSoft Dec 3, 2025
430e5f6
feat(InteractiveCard): added stories for non interactive state of card
HaykKirakosyanSoft Dec 8, 2025
799107b
feat(InteractiveCard): created pillprops and actionprops objects to p…
HaykKirakosyanSoft Dec 9, 2025
41f5e8f
feat(InteractiveCard): added subcomponents for documentation
HaykKirakosyanSoft Dec 11, 2025
3e39f5f
feat(InteractiveCard): added disabled state and default for actions
HaykKirakosyanSoft Dec 11, 2025
25ad434
fix(InteractiveCard): fixed the imports of components
HaykKirakosyanSoft Dec 11, 2025
8b81ca0
feat(InteractiveCard): added tests for the component
HaykKirakosyanSoft Dec 12, 2025
9cd274e
Merge branch 'release/3.0.0' of github.com:softconstruct/gene-ui-comp…
GaroGabrielyan Dec 23, 2025
9d276a0
fix(InteractiveCard): bEM className
GaroGabrielyan Dec 23, 2025
cffee35
feat(InteractiveCard): made a new interface for actions and refactore…
HaykKirakosyanSoft Dec 25, 2025
7e3d5c2
Merge branch 'feature/add-interactive-card-component' of github.com:s…
HaykKirakosyanSoft Dec 25, 2025
ceec902
feat(InteractiveCard): refactored interactive check from flag to actions
HaykKirakosyanSoft Dec 26, 2025
e3c1d80
feat(Switch): made the onclick prop not required
HaykKirakosyanSoft Dec 26, 2025
3d616bf
feat(InteractiveCard): refactored test file, added and updated the te…
HaykKirakosyanSoft Dec 29, 2025
cb96c64
feat(InteractiveCard): changed the description of pill to meet new us…
HaykKirakosyanSoft Jan 5, 2026
06915be
Merge branch 'release/3.0.0' of github.com:softconstruct/gene-ui-comp…
GaroGabrielyan Jan 7, 2026
8b8e62e
fix(InteractiveCard): add missed css class
GaroGabrielyan Jan 7, 2026
4240cce
fix(Pill): default size
GaroGabrielyan Jan 7, 2026
0e9da67
fix(InteractiveCard): min-width
GaroGabrielyan Jan 7, 2026
0772a7f
fix(InteractiveCard): story improvement
GaroGabrielyan Jan 7, 2026
40e8c15
fix(InteractiveCard): test
GaroGabrielyan Jan 7, 2026
f849718
fix(package-lock): update-browserslist-db@latest
GaroGabrielyan Jan 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/atoms/Pill/Pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ interface IPillProps {
*/
const Pill: FC<IPillProps> = ({
appearance = "informative",
size = "medium",
size = "small",
text,
iconAlignment = "before",
filled,
Expand Down
129 changes: 129 additions & 0 deletions src/components/molecules/InteractiveCard/InteractiveCard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
@use "../../../assets/styles/mixins";

.interactiveCard {
$this: &;

display: flex;
align-items: flex-start;
width: 100%;
min-width: 0;
border: var(--guit-ref-border-width-thin) var(--guit-ref-border-style-solid) var(--guit-sem-color-border-neutral-2);
background-color: var(--guit-sem-color-background-neutral-1);

&_size {
&_large {
gap: var(--guit-ref-spacing-large);
padding: var(--guit-ref-spacing-large);
border-radius: var(--guit-ref-radius-2xsmall);

&#{ $this }_withIcon {
padding-inline-start: var(--guit-ref-spacing-medium);
}

&#{ $this }_withAction {
padding-inline-end: var(--guit-ref-spacing-medium);
}

#{ $this }__main {
gap: var(--guit-ref-spacing-medium);
}
}

&_medium {
gap: var(--guit-ref-spacing-medium);
padding: var(--guit-ref-spacing-medium);
border-radius: var(--guit-ref-radius-3xsmall);

&#{ $this }_withIcon {
padding-inline-start: var(--guit-ref-spacing-small);
}

&#{ $this }_withAction {
padding-inline-end: var(--guit-ref-spacing-small);
}

#{ $this }__main {
gap: var(--guit-ref-spacing-xsmall);
}
}

&_small {
gap: var(--guit-ref-spacing-xsmall);
padding: var(--guit-ref-spacing-small);
border-radius: var(--guit-ref-radius-3xsmall);

&#{ $this }_withIcon {
padding-inline-start: var(--guit-ref-spacing-xsmall);
}

&#{ $this }_withAction {
padding-inline-end: var(--guit-ref-spacing-xsmall);
}

#{ $this }__main {
gap: var(--guit-ref-spacing-2xsmall);
}
}
}

&__main {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
}

&__icon {
flex: 0 0 auto;
color: var(--guit-sem-color-foreground-accent-blue);
}

&__content {
display: flex;
flex-direction: column;
gap: var(--guit-ref-spacing-4xsmall);
flex: 1;
min-width: 0;

&_onlyDescription {
align-self: flex-end;
}
}

&__description {
color: var(--guit-sem-color-foreground-neutral-1);
word-break: break-word;
}

&__actions {
display: flex;
align-items: center;
gap: var(--guit-ref-spacing-xsmall);
flex: 0 0 auto;
}

&_mode {
&_interactive {
@include mixins.media-hover {
&:hover {
background-color: var(--guit-sem-color-background-neutral-1-hover);
}
}

&:active {
background-color: var(--guit-sem-color-background-neutral-1-pressed);
}

&#{ $this }_disabled {
pointer-events: none;
user-select: none;
border-color: var(--guit-sem-color-border-disabled-1);

#{ $this }__icon,
#{ $this }__description {
color: var(--guit-sem-color-foreground-disabled);
}
}
}
}
}
141 changes: 141 additions & 0 deletions src/components/molecules/InteractiveCard/InteractiveCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import React, { ComponentType, FC } from "react";
import { Meta, StoryObj } from "@storybook/react";

import { AppGrid, ArchiveFilled, Calculator, CheckMarkCircleFilled, Flask, Globe, Power } from "@geneui/icons";

// Components
import { Col, Grid, Row } from "@components/atoms/Grid";
import Pill from "@components/atoms/Pill";
import Checkbox from "@components/molecules/Checkbox";
import InteractiveCard, { IInteractiveCardProps } from "@components/molecules/InteractiveCard";
import Switch from "@components/molecules/Switch";

// Helpers
import { args, propCategory } from "../../../../stories/assets/storybook.globals";

const meta: Meta<IInteractiveCardProps> = {
title: "Molecules/InteractiveCard",
component: InteractiveCard,
subcomponents: {
Pill: Pill as ComponentType<unknown>,
Checkbox: Checkbox as ComponentType<unknown>,
Switch: Switch as ComponentType<unknown>
},
argTypes: {
className: args({ control: "false", ...propCategory.appearance }),
size: args({ control: "select", ...propCategory.appearance }),
label: args({ control: "text", ...propCategory.content }),
infoText: args({ control: "text", ...propCategory.content }),
description: args({ control: "text", ...propCategory.content }),
Icon: args({ control: "false", ...propCategory.content }),
disabled: args({ control: "boolean", ...propCategory.states }),
onClick: args({ control: "false", ...propCategory.action }),
actionProps: args({ control: "false", ...propCategory.functionality }),
pill: args({ control: "false", ...propCategory.content }),
onFocus: args({ control: "false", ...propCategory.action })
},
args: {}
};

export default meta;

type Story = StoryObj<IInteractiveCardProps>;

export const Default: Story = {
args: {
size: "medium",
label: "Label",
infoText: "info text",
description: "description",
Icon: Globe,
disabled: false,
onClick: (e) => e.preventDefault()
}
};

const InteractiveCardsCombinationComponent: FC<IInteractiveCardProps> = (props) => {
const { disabled } = props;
return (
<Grid>
<Row flexible={false}>
<Col size={6}>
<InteractiveCard
label="Card 1"
disabled={disabled}
description="With Checkbox"
Icon={AppGrid}
actionProps={{
type: "checkbox"
}}
pill={{
text: "Pill",
filled: true,
appearance: "magenta",
Icon: CheckMarkCircleFilled,
size: "small"
}}
{...props}
/>
</Col>
<Col size={6}>
<InteractiveCard
disabled={disabled}
label="Card 2"
description="With Switch"
Icon={ArchiveFilled}
actionProps={{
type: "switch"
}}
{...props}
/>
</Col>
</Row>
<Row>
<Col size={4}>
<InteractiveCard
label="Card 3"
description="Full Interactive"
Icon={Calculator}
disabled={disabled}
{...props}
/>
</Col>
<Col size={4}>
<InteractiveCard
label="Card 4"
description="Full Interactive"
Icon={CheckMarkCircleFilled}
disabled={disabled}
{...props}
/>
</Col>
<Col size={4}>
<InteractiveCard
label="Card 5"
description="Full Interactive"
Icon={Flask}
disabled={disabled}
{...props}
/>
</Col>
</Row>
<Row>
<Col size={12}>
<InteractiveCard
disabled={disabled}
label="Ineractive"
description="With Size Large and long description. Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source."
infoText="info text"
Icon={Power}
size="large"
{...props}
/>
</Col>
</Row>
</Grid>
);
};

export const InteractiveCardsCombination: Story = {
render: (props) => <InteractiveCardsCombinationComponent {...props} />
};
Loading
Loading