@growth-angels/ds-core 0.0.5 → 1.0.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.
Files changed (129) hide show
  1. package/dist/atoms/Button/Button.stories.d.ts +2 -2
  2. package/dist/atoms/Button/Button.stories.js +15 -15
  3. package/dist/atoms/Button/Button.types.d.ts +2 -2
  4. package/dist/atoms/Icon/Icon.d.ts +1 -1
  5. package/dist/atoms/Icon/Icon.js +3 -3
  6. package/dist/atoms/Icon/Icon.types.d.ts +2 -1
  7. package/dist/atoms/Text/Text.d.ts +1 -0
  8. package/dist/atoms/Text/Text.js +4 -3
  9. package/dist/atoms/Text/Text.types.d.ts +5 -1
  10. package/dist/atoms/atoms.d.ts +3 -0
  11. package/dist/atoms/atoms.js +3 -0
  12. package/dist/context/SpoilerContext.d.ts +9 -0
  13. package/dist/context/SpoilerContext.js +15 -0
  14. package/dist/global.types.d.ts +4 -0
  15. package/dist/hooks/useReactAdaptater.d.ts +10 -2
  16. package/dist/hooks/useReactAdaptater.js +6 -3
  17. package/dist/hooks/useSpoilerContext.d.ts +4 -0
  18. package/dist/hooks/useSpoilerContext.js +12 -0
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.js +1 -0
  21. package/dist/layout/Container/Container.d.ts +2 -3
  22. package/dist/layout/Container/Container.js +10 -3
  23. package/dist/layout/Container/Container.types.d.ts +3 -0
  24. package/dist/layout/FlexBlock/FlexBlock.d.ts +2 -0
  25. package/dist/layout/FlexBlock/FlexBlock.js +21 -0
  26. package/dist/layout/FlexBlock/FlexBlock.types.d.ts +10 -0
  27. package/dist/layout/FlexBlock/FlexBlock.types.js +1 -0
  28. package/dist/layout/FlexCol/FlexCol.d.ts +5 -0
  29. package/dist/layout/FlexCol/FlexCol.js +4 -0
  30. package/dist/layout/FlexCol/FlexCol.types.d.ts +3 -0
  31. package/dist/layout/FlexCol/FlexCol.types.js +1 -0
  32. package/dist/layout/Grid/Grid.d.ts +1 -2
  33. package/dist/layout/Grid/Grid.js +3 -3
  34. package/dist/layout/Grid/Grid.types.d.ts +4 -4
  35. package/dist/layout/Grid/GridItem/GridItem.d.ts +2 -2
  36. package/dist/layout/Grid/GridItem/GridItem.js +10 -3
  37. package/dist/layout/Grid/GridItem/GridItem.types.d.ts +3 -2
  38. package/dist/layout/layout.d.ts +7 -0
  39. package/dist/layout/layout.js +7 -0
  40. package/dist/molecules/ButtonGroup/ButtonGroup.d.ts +2 -0
  41. package/dist/molecules/ButtonGroup/ButtonGroup.js +16 -0
  42. package/dist/molecules/ButtonGroup/ButtonGroup.types.d.ts +5 -0
  43. package/dist/molecules/ButtonGroup/ButtonGroup.types.js +1 -0
  44. package/dist/molecules/Spoiler/Spoiler.d.ts +2 -0
  45. package/dist/molecules/Spoiler/Spoiler.js +13 -0
  46. package/dist/molecules/Spoiler/Spoiler.stories.d.ts +7 -0
  47. package/dist/molecules/Spoiler/Spoiler.stories.js +25 -0
  48. package/dist/molecules/Spoiler/Spoiler.types.d.ts +6 -0
  49. package/dist/molecules/Spoiler/Spoiler.types.js +1 -0
  50. package/dist/molecules/molecules.d.ts +2 -0
  51. package/dist/molecules/molecules.js +2 -0
  52. package/dist/organisms/Card/Card.d.ts +3 -3
  53. package/dist/organisms/Card/Card.js +4 -4
  54. package/dist/organisms/Card/Card.types.d.ts +12 -3
  55. package/dist/organisms/Card/CardDefault.stories.d.ts +2 -2
  56. package/dist/organisms/Card/CardDefault.stories.js +17 -17
  57. package/dist/organisms/Carousel/Carousel.js +5 -1
  58. package/dist/organisms/Carousel/Carousel.types.d.ts +2 -1
  59. package/dist/organisms/SpoilerList/SpoilerList.d.ts +2 -0
  60. package/dist/organisms/SpoilerList/SpoilerList.js +11 -0
  61. package/dist/organisms/SpoilerList/SpoilerList.types.d.ts +4 -0
  62. package/dist/organisms/SpoilerList/SpoilerList.types.js +1 -0
  63. package/dist/organisms/organisms.d.ts +2 -0
  64. package/dist/organisms/organisms.js +2 -0
  65. package/dist/styles.d.ts +1 -0
  66. package/dist/styles.js +1 -0
  67. package/package.json +10 -9
  68. package/src/atoms/Button/Button.scss +18 -19
  69. package/src/atoms/Button/Button.stories.tsx +17 -17
  70. package/src/atoms/Button/Button.types.ts +2 -2
  71. package/src/atoms/Icon/Icon.scss +9 -9
  72. package/src/atoms/Icon/Icon.tsx +10 -8
  73. package/src/atoms/Icon/Icon.types.ts +3 -1
  74. package/src/atoms/Text/Text.scss +33 -2
  75. package/src/atoms/Text/Text.tsx +13 -8
  76. package/src/atoms/Text/Text.types.ts +5 -1
  77. package/src/atoms/atoms.scss +3 -3
  78. package/src/atoms/atoms.ts +3 -0
  79. package/src/context/SpoilerContext.tsx +24 -0
  80. package/src/global.types.ts +4 -0
  81. package/src/hooks/useReactAdaptater.ts +20 -4
  82. package/src/hooks/useSpoilerContext.ts +17 -0
  83. package/src/index.scss +2 -0
  84. package/src/index.ts +1 -0
  85. package/src/layout/Container/Container.scss +55 -13
  86. package/src/layout/Container/Container.tsx +17 -9
  87. package/src/layout/Container/Container.types.ts +3 -1
  88. package/src/layout/FlexBlock/FlexBlock.scss +4 -0
  89. package/src/layout/FlexBlock/FlexBlock.tsx +31 -0
  90. package/src/layout/FlexBlock/FlexBlock.types.ts +12 -0
  91. package/src/layout/FlexCol/FlexCol.scss +5 -0
  92. package/src/layout/FlexCol/FlexCol.tsx +12 -0
  93. package/src/layout/FlexCol/FlexCol.types.ts +3 -0
  94. package/src/layout/Grid/Grid.scss +8 -4
  95. package/src/layout/Grid/Grid.tsx +12 -8
  96. package/src/layout/Grid/Grid.types.ts +4 -4
  97. package/src/layout/Grid/GridItem/GridItem.scss +17 -4
  98. package/src/layout/Grid/GridItem/GridItem.tsx +28 -13
  99. package/src/layout/Grid/GridItem/GridItem.types.ts +3 -2
  100. package/src/layout/layout.scss +5 -3
  101. package/src/layout/layout.ts +8 -1
  102. package/src/molecules/ButtonGroup/ButtonGroup.scss +5 -0
  103. package/src/molecules/ButtonGroup/ButtonGroup.tsx +23 -0
  104. package/src/molecules/ButtonGroup/ButtonGroup.types.ts +6 -0
  105. package/src/molecules/Spoiler/Spoiler.scss +47 -0
  106. package/src/molecules/Spoiler/Spoiler.stories.tsx +44 -0
  107. package/src/molecules/Spoiler/Spoiler.tsx +30 -0
  108. package/src/molecules/Spoiler/Spoiler.types.ts +6 -0
  109. package/src/molecules/molecules.scss +2 -0
  110. package/src/molecules/molecules.ts +2 -0
  111. package/src/organisms/Card/Card.scss +50 -10
  112. package/src/organisms/Card/Card.tsx +17 -6
  113. package/src/organisms/Card/Card.types.ts +12 -3
  114. package/src/organisms/Card/CardDefault.stories.tsx +40 -37
  115. package/src/organisms/Carousel/Carousel.scss +3 -0
  116. package/src/organisms/Carousel/Carousel.tsx +7 -1
  117. package/src/organisms/Carousel/Carousel.types.ts +3 -1
  118. package/src/organisms/SpoilerList/SpoilerList.scss +5 -0
  119. package/src/organisms/SpoilerList/SpoilerList.tsx +19 -0
  120. package/src/organisms/SpoilerList/SpoilerList.types.ts +5 -0
  121. package/src/organisms/organisms.scss +3 -2
  122. package/src/organisms/organisms.ts +3 -1
  123. package/src/scss.d.ts +4 -0
  124. package/src/styles.ts +1 -0
  125. package/src/utils/_spacings.scss +17 -0
  126. package/src/utils/utils.scss +1 -0
  127. package/dist/utils.d.ts +0 -0
  128. package/dist/utils.js +0 -1
  129. package/src/utils.ts +0 -0
@@ -1,9 +1,11 @@
1
1
  import { WordpressDefault } from "../../global.types";
2
2
 
3
3
  export type ContainerSize = 'large' | 'medium' | 'small';
4
-
4
+ export type ContainerStretch = 'right' | 'left'
5
5
 
6
6
  export interface ContainerProps extends WordpressDefault {
7
7
  size: ContainerSize;
8
+ stretch?:ContainerStretch
8
9
  children: React.ReactNode | React.ReactNode[];
10
+ style?: React.CSSProperties;
9
11
  }
@@ -0,0 +1,4 @@
1
+ .ga-ds-flex-block {
2
+ display: flex;
3
+ gap: var(--ga-flex-block-gap, 0);
4
+ }
@@ -0,0 +1,31 @@
1
+ import { FlexBlockProps } from "./FlexBlock.types"
2
+
3
+ export const FlexBlock = ({ children, gap, alignItems, justifyContent, flexDirection, extraClassNames }: FlexBlockProps) => {
4
+ const styles = []
5
+ if (gap) {
6
+ styles.push(["gap", `var(--ga-spacings-gap-${gap})`])
7
+ }
8
+
9
+ if (alignItems) {
10
+ styles.push(["alignItems", alignItems])
11
+ }
12
+
13
+ if (justifyContent) {
14
+ styles.push(["justifyContent", justifyContent])
15
+ }
16
+
17
+ if (flexDirection) {
18
+ styles.push(["flexDirection", flexDirection])
19
+ }
20
+
21
+ const classNames = ["ga-ds-flex-block"]
22
+ if (extraClassNames) {
23
+ classNames.push(...extraClassNames)
24
+ }
25
+
26
+ return (
27
+ <div className={classNames.join(" ")} style={Object.fromEntries(styles) as React.CSSProperties}>
28
+ {children}
29
+ </div>
30
+ )
31
+ }
@@ -0,0 +1,12 @@
1
+ import { WordpressDefault } from "../../global.types";
2
+
3
+ export type FlexBlockAttrs = {
4
+ gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
5
+ alignItems?: string;
6
+ justifyContent?: string;
7
+ flexDirection?: 'column';
8
+ }
9
+
10
+ export interface FlexBlockProps extends FlexBlockAttrs, WordpressDefault {
11
+ children: React.ReactNode;
12
+ }
@@ -0,0 +1,5 @@
1
+ .ga-ds-flex-col {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--ga-flex-col-gap, 0);
5
+ }
@@ -0,0 +1,12 @@
1
+ import { FlexColAttrs } from "./FlexCol.types"
2
+
3
+ export const FlexCol = ({ children, gap }: { children: React.ReactNode; gap?: FlexColAttrs["gap"] }) => {
4
+ return (
5
+ <div
6
+ className="ga-ds-flex-col"
7
+ style={{ "--ga-flex-col-gap": `var(--ga-spacings-gap-${gap || "xs"})` } as React.CSSProperties}
8
+ >
9
+ {children}
10
+ </div>
11
+ )
12
+ }
@@ -0,0 +1,3 @@
1
+ export type FlexColAttrs = {
2
+ gap?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
3
+ }
@@ -1,7 +1,11 @@
1
- @use './GridItem/GridItem.scss';
1
+ @use "@growth-angels/foundation/config" as *;
2
+ @use "sass:map";
3
+ @use "./GridItem/GridItem.scss";
2
4
 
3
5
  .ga-ds-grid {
4
- display: grid;
5
- gap: var(--ga-grid-gutter);
6
- grid-template-columns: repeat(var(--ga-grid-columns), 1fr);
6
+ display: flex;
7
+ margin-left: calc(-1 * map.get($ga-grid, "gutter-width") / 2);
8
+ margin-right: calc(-1 * map.get($ga-grid, "gutter-width") / 2);
9
+ margin-bottom: calc(-1 * map.get($ga-grid, "gutter-width") / 2);
10
+ flex-wrap: wrap;
7
11
  }
@@ -1,10 +1,14 @@
1
- import type { JSX } from 'react/jsx-runtime'
2
- import { GridProps } from './Grid.types'
1
+ import { GridProps } from "./Grid.types"
3
2
  export const Grid = (props: GridProps): JSX.Element => {
4
- const { children, alignItems, justifyContent, extraClassNames } = props
5
- const classNames = ['ga-ds-grid', ...(extraClassNames || [])]
3
+ const { children, alignItems, justifyContent, extraClassNames, padding } = props
4
+ const classNames = ["ga-ds-grid", ...(padding ? [`ga-ds-util-padding--${padding}`] : []), ...(extraClassNames || [])]
6
5
 
7
- return <div className={classNames.join(' ')} style={{ alignItems, justifyContent }}>
8
- {children}
9
- </div>
10
- }
6
+ return (
7
+ <div
8
+ className={classNames.join(" ")}
9
+ style={{ ...(alignItems !== "none" && { alignItems }), ...(justifyContent !== "none" && { justifyContent }) }}
10
+ >
11
+ {children}
12
+ </div>
13
+ )
14
+ }
@@ -1,10 +1,10 @@
1
1
  import { WordpressDefault } from "../../global.types";
2
2
 
3
- export interface Attributes {
4
- alignItems: 'flex-start' | 'center' | 'flex-end' | 'stretch' | 'baseline'
5
- justifyContent: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around'
3
+ export interface GridAttributes {
4
+ alignItems: 'flex-start' | 'center' | 'flex-end' | 'none'
5
+ justifyContent: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'none'
6
6
  }
7
7
 
8
- export interface GridProps extends WordpressDefault, Attributes {
8
+ export interface GridProps extends WordpressDefault, GridAttributes {
9
9
  children: React.ReactNode | React.ReactNode[];
10
10
  }
@@ -1,17 +1,30 @@
1
1
  @use "@growth-angels/foundation/config" as *;
2
+ @use "sass:map";
2
3
 
3
4
  .ga-ds-grid-item {
4
- grid-column: span var(--ga-ds-grid-item-size-xs);
5
+ --flex-size: var(--ga-ds-grid-item-size-xs);
6
+ flex: 0 0 calc(100% * var(--flex-size) / map.get($ga-grid, "columns"));
7
+ padding-left: calc(map.get($ga-grid, "gutter-width") / 2);
8
+ padding-right: calc(map.get($ga-grid, "gutter-width") / 2);
9
+ margin-bottom: map.get($ga-grid, "gutter-width");
5
10
 
6
11
  @include bp-up(sm) {
7
- grid-column: span var(--ga-ds-grid-item-size-sm);
12
+ --flex-size: var(--ga-ds-grid-item-size-sm);
8
13
  }
9
14
 
10
15
  @include bp-up(md) {
11
- grid-column: span var(--ga-ds-grid-item-size-md);
16
+ --flex-size: var(--ga-ds-grid-item-size-md);
12
17
  }
13
18
 
14
19
  @include bp-up(lg) {
15
- grid-column: span var(--ga-ds-grid-item-size-lg);
20
+ --flex-size: var(--ga-ds-grid-item-size-lg);
21
+ }
22
+
23
+ > figure {
24
+ width: 100%;
25
+ img {
26
+ width: 100%;
27
+ height: auto;
28
+ }
16
29
  }
17
30
  }
@@ -1,15 +1,30 @@
1
- import type { JSX } from 'react/jsx-runtime'
2
- import { GridItemProps } from './GridItem.types'
1
+ import type { JSX } from "react/jsx-runtime"
2
+ import { GridItemProps } from "./GridItem.types"
3
3
  export const GridItem = (props: GridItemProps): JSX.Element => {
4
- const { children, sizes = {
5
- xs: 12,
6
- sm: 12,
7
- md: 12,
8
- lg: 12,
9
- } } = props
4
+ const {
5
+ children,
6
+ sizes = {
7
+ xs: 12,
8
+ sm: 12,
9
+ md: 12,
10
+ lg: 12,
11
+ },
12
+ style: givenStyle,
13
+ extraClassNames,
14
+ } = props
10
15
 
11
- const style = Object.fromEntries(Object.entries(sizes).map(([key, value]) => [`--ga-ds-grid-item-size-${key}`, `${value}`]))
12
- return <div className="ga-ds-grid-item" style={style}>
13
- {children}
14
- </div>
15
- }
16
+ const style = {
17
+ ...Object.fromEntries(Object.entries(sizes).map(([key, value]) => [`--ga-ds-grid-item-size-${key}`, `${value}`])),
18
+ ...givenStyle,
19
+ }
20
+
21
+ const classNames = ["ga-ds-grid-item"]
22
+ if (extraClassNames) {
23
+ classNames.push(...extraClassNames)
24
+ }
25
+ return (
26
+ <div className={classNames.join(" ")} style={style}>
27
+ {children}
28
+ </div>
29
+ )
30
+ }
@@ -2,7 +2,7 @@ import { WordpressDefault } from "../../../global.types";
2
2
 
3
3
  export type ColumnSize = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12'
4
4
 
5
- export interface Attributes {
5
+ export interface GridItemAttributes {
6
6
  sizes: {
7
7
  xs: ColumnSize;
8
8
  sm: ColumnSize;
@@ -11,6 +11,7 @@ export interface Attributes {
11
11
  }
12
12
  }
13
13
 
14
- export interface GridItemProps extends WordpressDefault, Attributes {
14
+ export interface GridItemProps extends WordpressDefault, GridItemAttributes {
15
15
  children: React.ReactNode | React.ReactNode[];
16
+ style?: React.CSSProperties;
16
17
  }
@@ -1,3 +1,5 @@
1
- @use './Container/Container.scss';
2
- @use './Grid/Grid.scss';
3
- @use './Grid/GridItem/GridItem.scss';
1
+ @use "./Container/Container.scss";
2
+ @use "./Grid/Grid.scss";
3
+ @use "./Grid/GridItem/GridItem.scss";
4
+ @use "./FlexCol/FlexCol.scss";
5
+ @use "./FlexBlock/FlexBlock.scss";
@@ -1,3 +1,10 @@
1
1
  export * from './Container/Container'
2
+ export * from './Container/Container.types'
2
3
  export * from './Grid/Grid'
3
- export * from './Grid/GridItem/GridItem'
4
+ export * from './Grid/Grid.types'
5
+ export * from './Grid/GridItem/GridItem'
6
+ export * from './Grid/GridItem/GridItem.types'
7
+ export * from './FlexCol/FlexCol'
8
+ export * from './FlexCol/FlexCol.types'
9
+ export * from './FlexBlock/FlexBlock'
10
+ export * from './FlexBlock/FlexBlock.types'
@@ -0,0 +1,5 @@
1
+ .ga-ds-btn-group {
2
+ display: flex;
3
+ gap: 0.8rem;
4
+ justify-content: var(--alignment, flex-start);
5
+ }
@@ -0,0 +1,23 @@
1
+ import { ButtonGroupProps } from "./ButtonGroup.types"
2
+
3
+ export const ButtonGroup = ({ alignment, children, extraClassNames }: ButtonGroupProps) => {
4
+ const style = {} as React.CSSProperties & Record<string, string | number | undefined>
5
+ const cssAlignmentsMap = {
6
+ center: "center",
7
+ right: "flex-end",
8
+ }
9
+ if (alignment && cssAlignmentsMap[alignment]) {
10
+ style["--alignment"] = cssAlignmentsMap[alignment] as string
11
+ }
12
+
13
+ const classes = ["ga-ds-btn-group"]
14
+ if (extraClassNames) {
15
+ classes.push(...extraClassNames)
16
+ }
17
+
18
+ return (
19
+ <div className={classes.join(" ")} {...(Object.entries(style).length ? { style } : {})}>
20
+ {children}
21
+ </div>
22
+ )
23
+ }
@@ -0,0 +1,6 @@
1
+ import { WordpressDefault } from "../../global.types";
2
+
3
+ export interface ButtonGroupProps extends WordpressDefault {
4
+ alignment?: 'center' | 'right';
5
+ children?: React.ReactNode;
6
+ }
@@ -0,0 +1,47 @@
1
+ .ga-ds-spoiler {
2
+ overflow: hidden;
3
+
4
+ &__summary {
5
+ cursor: pointer;
6
+ font-weight: var(--ga-ds-spoiler--summary-weight, 500);
7
+ padding: var(--ga-ds-spoiler--summary-padding, 0rem);
8
+ font-size: var(--ga-ds-spoiler--summary-font-size, 1.6rem);
9
+ user-select: none;
10
+ display: flex;
11
+ align-items: center;
12
+ justify-content: space-between;
13
+ outline: none;
14
+ }
15
+
16
+ &__content {
17
+ display: grid;
18
+ grid-template-rows: 0fr;
19
+ transition: grid-template-rows 0.4s ease;
20
+ overflow: hidden;
21
+ }
22
+
23
+ &__indicator {
24
+ transition: transform 0.3s ease;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ aspect-ratio: 1 / 1;
29
+ width: var(--indicator-size, 2.8rem);
30
+ height: var(--indicator-size, 2.8rem);
31
+ transform: rotate(-90deg);
32
+ transform-origin: center center;
33
+ }
34
+
35
+ &__body {
36
+ overflow: hidden;
37
+ }
38
+
39
+ &.is-open {
40
+ .ga-ds-spoiler__indicator {
41
+ transform: rotate(90deg);
42
+ }
43
+ .ga-ds-spoiler__content {
44
+ grid-template-rows: 1fr;
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite"
2
+ import { Spoiler } from "./Spoiler"
3
+ import { SpoilerProvider } from "../../context/SpoilerContext"
4
+
5
+ const meta: Meta<typeof Spoiler> = {
6
+ title: "Molecules/Spoiler",
7
+ component: Spoiler,
8
+ tags: ["autodocs"],
9
+ decorators: [
10
+ (Story) => (
11
+ <SpoilerProvider>
12
+ <Story />
13
+ </SpoilerProvider>
14
+ ),
15
+ ],
16
+ }
17
+
18
+ export default meta
19
+ type Story = StoryObj<typeof Spoiler>
20
+
21
+ export const Default: Story = {
22
+ args: {
23
+ summary: "Click to reveal the spoiler content",
24
+ children: (
25
+ <>
26
+ <p>This is the hidden spoiler content.</p>
27
+ <p>It can include any React nodes.</p>
28
+ </>
29
+ ),
30
+ },
31
+ }
32
+
33
+ export const OpenByDefault: Story = {
34
+ args: {
35
+ summary: "This spoiler is open by default",
36
+ children: (
37
+ <>
38
+ <p>The spoiler content is visible on load.</p>
39
+ <p>You can still toggle it closed.</p>
40
+ </>
41
+ ),
42
+ defaultOpen: true,
43
+ },
44
+ }
@@ -0,0 +1,30 @@
1
+ import { SpoilerProps } from "./Spoiler.types"
2
+ import { useReactAdapter } from "../../hooks/useReactAdaptater"
3
+ import { Icon } from "../../atoms/Icon/Icon"
4
+ import { useSpoilerContext } from "../../context/SpoilerContext"
5
+
6
+ export const Spoiler = (props: SpoilerProps) => {
7
+ const { summary, children, defaultOpen = false, index } = props
8
+ const { activeIndex, setActiveIndex } = useSpoilerContext()
9
+ const isOpen = activeIndex === index ? true : defaultOpen
10
+
11
+ const handleToggle = (e: React.MouseEvent) => {
12
+ e.preventDefault()
13
+ setActiveIndex(index)
14
+ }
15
+
16
+ return (
17
+ <div className={`ga-ds-spoiler ${isOpen ? "is-open" : ""}`}>
18
+ <div className="ga-ds-spoiler__separator"></div>
19
+ <div className="ga-ds-spoiler__summary" onClick={handleToggle} role="button" tabIndex={0}>
20
+ {summary}
21
+ <span className="ga-ds-spoiler__indicator">
22
+ <Icon name={"chevron-right"} size="sm" />
23
+ </span>
24
+ </div>
25
+ <div className="ga-ds-spoiler__content">
26
+ <div className="ga-ds-spoiler__body">{children}</div>
27
+ </div>
28
+ </div>
29
+ )
30
+ }
@@ -0,0 +1,6 @@
1
+ export interface SpoilerProps {
2
+ summary: string;
3
+ children: React.ReactNode | React.ReactNode[];
4
+ defaultOpen?: boolean;
5
+ index: number;
6
+ }
@@ -0,0 +1,2 @@
1
+ @use "./ButtonGroup/ButtonGroup.scss";
2
+ @use "./Spoiler/Spoiler.scss";
@@ -0,0 +1,2 @@
1
+ export * from './ButtonGroup/ButtonGroup';
2
+ export * from './Spoiler/Spoiler';
@@ -1,16 +1,21 @@
1
1
  .ga-ds-card {
2
2
  --card-spacing: var(--ga-card-spacing);
3
3
  width: 100%;
4
+ height: auto;
4
5
  display: flex;
5
6
  flex-direction: column;
6
- gap: var(--ga-card-gap);
7
- border-radius: var(--ga-card-radius, 0);
8
- overflow: hidden;
7
+ gap: var(--ga-card-gap-global);
9
8
 
10
9
  &__header {
11
10
  overflow: hidden;
12
11
  }
13
12
 
13
+ &__content {
14
+ gap: var(--ga-card-gap-content);
15
+ display: flex;
16
+ flex-direction: column;
17
+ }
18
+
14
19
  &__title,
15
20
  &__content,
16
21
  &__footer {
@@ -22,14 +27,19 @@
22
27
  padding-bottom: var(--card-spacing);
23
28
  }
24
29
 
25
- &--primary {
26
- background-color: var(--ga-card-background-primary);
27
- color: var(--ga-card-background-primary-reverted);
28
- }
30
+ &:not(.ga-ds-card--editorial) {
31
+ border-radius: var(--ga-card-radius, 0);
32
+ overflow: hidden;
33
+ &:not(:has(.ga-ds-card__footer)) {
34
+ padding-bottom: var(--card-spacing);
35
+ }
36
+ &:not(:has(.ga-ds-card__header)):not(.ga-ds-card--background-image) {
37
+ padding-top: var(--card-spacing);
38
+ }
29
39
 
30
- &--secondary {
31
- background-color: var(--ga-card-background-secondary);
32
- color: var(--ga-card-background-secondary-reverted);
40
+ &.ga-ds-card--primary {
41
+ background-color: var(--ga-card-background-primary);
42
+ }
33
43
  }
34
44
  }
35
45
 
@@ -50,11 +60,41 @@
50
60
  object-position: center;
51
61
  }
52
62
  }
63
+ .ga-ds-card--primary {
64
+ background-color: var(--ga-card-background-primary);
65
+ color: var(--ga-card-background-primary-reverted);
66
+ }
67
+
68
+ .ga-ds-card--secondary {
69
+ background-color: var(--ga-card-background-secondary);
70
+ color: var(--ga-card-background-secondary-reverted);
71
+ }
53
72
  }
54
73
 
55
74
  .ga-ds-card--editorial {
75
+ --ga-card-spacing: 0;
76
+ }
77
+
78
+ .ga-ds-card--icon {
79
+ border-radius: var(--ga-card-radius, 0);
80
+ overflow: hidden;
56
81
  .ga-ds-card__header {
57
82
  padding-top: var(--card-spacing);
58
83
  padding-left: var(--card-spacing);
84
+ padding-right: var(--card-spacing);
85
+ }
86
+ }
87
+
88
+ .ga-ds-card--background-image {
89
+ position: relative;
90
+ padding-top: var(--card-background-image-height, 17.3rem);
91
+ z-index: 1;
92
+ > img {
93
+ position: absolute;
94
+ top: 0;
95
+ left: 0;
96
+ width: 100%;
97
+ z-index: -1;
98
+ height: auto;
59
99
  }
60
100
  }
@@ -1,8 +1,19 @@
1
- import { JSX } from 'react/jsx-runtime'
2
- import type { CardProps } from './Card.types'
1
+ import { JSX } from "react/jsx-runtime"
2
+ import type { CardProps } from "./Card.types"
3
3
 
4
- export const Card = ({ children, variant = 'primary', extraClassNames, type = 'default' }: CardProps): JSX.Element => {
5
- const classNames = ['ga-ds-card', `ga-ds-card--${variant}`, `ga-ds-card--${type}`, ...(extraClassNames || [])]
6
-
7
- return <div className={classNames.join(' ')}>{children}</div>
4
+ export const Card = ({
5
+ children,
6
+ variant = "primary",
7
+ extraClassNames,
8
+ type = "image",
9
+ style,
10
+ backgroundImage,
11
+ }: CardProps): JSX.Element => {
12
+ const classNames = ["ga-ds-card", `ga-ds-card--${variant}`, `ga-ds-card--${type}`, ...(extraClassNames || [])]
13
+ return (
14
+ <div {...(style && { style })} className={classNames.join(" ")}>
15
+ {backgroundImage && <img src={backgroundImage.sizes?.full?.url} alt={backgroundImage?.alt} />}
16
+ {children}
17
+ </div>
18
+ )
8
19
  }
@@ -1,8 +1,17 @@
1
- export type Variant = 'primary' | 'secondary'
2
- export type CardType = 'default' | 'editorial' | 'image' | 'icon'
1
+ export type CardVariant = 'primary' | 'secondary'
2
+ export type CardType = 'editorial' | 'image' | 'icon' | 'background-image'
3
3
  export interface CardProps {
4
4
  children: React.ReactNode | React.ReactNode[] | JSX.Element
5
- variant: Variant
5
+ variant: CardVariant
6
6
  type?: CardType
7
+ backgroundImage?: {
8
+ alt?: string;
9
+ sizes: {
10
+ full: {
11
+ url: string
12
+ }
13
+ }
14
+ },
7
15
  extraClassNames?: string[]
16
+ style?: React.CSSProperties
8
17
  }