@dnanpm/ui-components 0.6.0 → 0.8.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 (205) hide show
  1. package/dist/components/AccordionItem/AccordionItem.css +16 -16
  2. package/dist/components/AccordionItem/AccordionItem.module.css.cjs +11 -11
  3. package/dist/components/AccordionItem/AccordionItem.module.css.js +11 -11
  4. package/dist/components/Breadcrumb/Breadcrumb.css +9 -9
  5. package/dist/components/Breadcrumb/Breadcrumb.module.css.cjs +6 -6
  6. package/dist/components/Breadcrumb/Breadcrumb.module.css.js +6 -6
  7. package/dist/components/Button/Button.css +32 -30
  8. package/dist/components/Button/Button.module.css.cjs +11 -11
  9. package/dist/components/Button/Button.module.css.js +11 -11
  10. package/dist/components/ButtonCard/ButtonCard.cjs +105 -0
  11. package/dist/components/ButtonCard/ButtonCard.cjs.map +1 -0
  12. package/dist/components/ButtonCard/ButtonCard.css +167 -0
  13. package/dist/components/ButtonCard/ButtonCard.d.ts +3 -0
  14. package/dist/components/ButtonCard/ButtonCard.d.ts.map +1 -0
  15. package/dist/components/ButtonCard/ButtonCard.js +105 -0
  16. package/dist/components/ButtonCard/ButtonCard.js.map +1 -0
  17. package/dist/components/ButtonCard/ButtonCard.module.css.cjs +18 -0
  18. package/dist/components/ButtonCard/ButtonCard.module.css.cjs.map +1 -0
  19. package/dist/components/ButtonCard/ButtonCard.module.css.js +19 -0
  20. package/dist/components/ButtonCard/ButtonCard.module.css.js.map +1 -0
  21. package/dist/components/ButtonCard/ButtonCard.types.d.ts +103 -0
  22. package/dist/components/ButtonCard/ButtonCard.types.d.ts.map +1 -0
  23. package/dist/components/ButtonCard/index.d.ts +3 -0
  24. package/dist/components/ButtonCard/index.d.ts.map +1 -0
  25. package/dist/components/Drawer/Drawer.cjs +101 -0
  26. package/dist/components/Drawer/Drawer.cjs.map +1 -0
  27. package/dist/components/Drawer/Drawer.css +219 -0
  28. package/dist/components/Drawer/Drawer.d.ts +3 -0
  29. package/dist/components/Drawer/Drawer.d.ts.map +1 -0
  30. package/dist/components/Drawer/Drawer.js +101 -0
  31. package/dist/components/Drawer/Drawer.js.map +1 -0
  32. package/dist/components/Drawer/Drawer.module.css.cjs +37 -0
  33. package/dist/components/Drawer/Drawer.module.css.cjs.map +1 -0
  34. package/dist/components/Drawer/Drawer.module.css.js +37 -0
  35. package/dist/components/Drawer/Drawer.module.css.js.map +1 -0
  36. package/dist/components/Drawer/Drawer.types.d.ts +63 -0
  37. package/dist/components/Drawer/Drawer.types.d.ts.map +1 -0
  38. package/dist/components/Drawer/index.d.ts +3 -0
  39. package/dist/components/Drawer/index.d.ts.map +1 -0
  40. package/dist/components/Footer/Footer.cjs +272 -0
  41. package/dist/components/Footer/Footer.cjs.map +1 -0
  42. package/dist/components/Footer/Footer.css +473 -0
  43. package/dist/components/Footer/Footer.d.ts +3 -0
  44. package/dist/components/Footer/Footer.d.ts.map +1 -0
  45. package/dist/components/Footer/Footer.js +272 -0
  46. package/dist/components/Footer/Footer.js.map +1 -0
  47. package/dist/components/Footer/Footer.module.css.cjs +80 -0
  48. package/dist/components/Footer/Footer.module.css.cjs.map +1 -0
  49. package/dist/components/Footer/Footer.module.css.js +80 -0
  50. package/dist/components/Footer/Footer.module.css.js.map +1 -0
  51. package/dist/components/Footer/Footer.types.d.ts +128 -0
  52. package/dist/components/Footer/Footer.types.d.ts.map +1 -0
  53. package/dist/components/Footer/Footer.utils.cjs +41 -0
  54. package/dist/components/Footer/Footer.utils.cjs.map +1 -0
  55. package/dist/components/Footer/Footer.utils.d.ts +13 -0
  56. package/dist/components/Footer/Footer.utils.d.ts.map +1 -0
  57. package/dist/components/Footer/Footer.utils.js +41 -0
  58. package/dist/components/Footer/Footer.utils.js.map +1 -0
  59. package/dist/components/Footer/assets/app-store-badge.svg.cjs +4 -0
  60. package/dist/components/Footer/assets/app-store-badge.svg.cjs.map +1 -0
  61. package/dist/components/Footer/assets/app-store-badge.svg.js +5 -0
  62. package/dist/components/Footer/assets/app-store-badge.svg.js.map +1 -0
  63. package/dist/components/Footer/assets/google-play-badge.svg.cjs +4 -0
  64. package/dist/components/Footer/assets/google-play-badge.svg.cjs.map +1 -0
  65. package/dist/components/Footer/assets/google-play-badge.svg.js +5 -0
  66. package/dist/components/Footer/assets/google-play-badge.svg.js.map +1 -0
  67. package/dist/components/Footer/index.d.ts +3 -0
  68. package/dist/components/Footer/index.d.ts.map +1 -0
  69. package/dist/components/FunctionButton/FunctionButton.cjs +34 -0
  70. package/dist/components/FunctionButton/FunctionButton.cjs.map +1 -0
  71. package/dist/components/FunctionButton/FunctionButton.css +125 -0
  72. package/dist/components/FunctionButton/FunctionButton.d.ts +3 -0
  73. package/dist/components/FunctionButton/FunctionButton.d.ts.map +1 -0
  74. package/dist/components/FunctionButton/FunctionButton.js +34 -0
  75. package/dist/components/FunctionButton/FunctionButton.js.map +1 -0
  76. package/dist/components/FunctionButton/FunctionButton.module.css.cjs +11 -0
  77. package/dist/components/FunctionButton/FunctionButton.module.css.cjs.map +1 -0
  78. package/dist/components/FunctionButton/FunctionButton.module.css.js +12 -0
  79. package/dist/components/FunctionButton/FunctionButton.module.css.js.map +1 -0
  80. package/dist/components/FunctionButton/FunctionButton.types.d.ts +21 -0
  81. package/dist/components/FunctionButton/FunctionButton.types.d.ts.map +1 -0
  82. package/dist/components/FunctionButton/index.d.ts +3 -0
  83. package/dist/components/FunctionButton/index.d.ts.map +1 -0
  84. package/dist/components/Hero/Hero.cjs +44 -30
  85. package/dist/components/Hero/Hero.cjs.map +1 -1
  86. package/dist/components/Hero/Hero.css +89 -100
  87. package/dist/components/Hero/Hero.d.ts +1 -1
  88. package/dist/components/Hero/Hero.d.ts.map +1 -1
  89. package/dist/components/Hero/Hero.js +45 -31
  90. package/dist/components/Hero/Hero.js.map +1 -1
  91. package/dist/components/Hero/Hero.module.css.cjs +17 -20
  92. package/dist/components/Hero/Hero.module.css.cjs.map +1 -1
  93. package/dist/components/Hero/Hero.module.css.js +17 -20
  94. package/dist/components/Hero/Hero.module.css.js.map +1 -1
  95. package/dist/components/Hero/Hero.types.d.ts +8 -3
  96. package/dist/components/Hero/Hero.types.d.ts.map +1 -1
  97. package/dist/components/Hero/Hero.utils.cjs +5 -8
  98. package/dist/components/Hero/Hero.utils.cjs.map +1 -1
  99. package/dist/components/Hero/Hero.utils.d.ts +2 -2
  100. package/dist/components/Hero/Hero.utils.d.ts.map +1 -1
  101. package/dist/components/Hero/Hero.utils.js +5 -8
  102. package/dist/components/Hero/Hero.utils.js.map +1 -1
  103. package/dist/components/IconButton/IconButton.css +31 -32
  104. package/dist/components/IconButton/IconButton.module.css.cjs +9 -9
  105. package/dist/components/IconButton/IconButton.module.css.js +9 -9
  106. package/dist/components/MainNavigation/MainNavigation.cjs +1094 -0
  107. package/dist/components/MainNavigation/MainNavigation.cjs.map +1 -0
  108. package/dist/components/MainNavigation/MainNavigation.css +948 -0
  109. package/dist/components/MainNavigation/MainNavigation.d.ts +3 -0
  110. package/dist/components/MainNavigation/MainNavigation.d.ts.map +1 -0
  111. package/dist/components/MainNavigation/MainNavigation.js +1094 -0
  112. package/dist/components/MainNavigation/MainNavigation.js.map +1 -0
  113. package/dist/components/MainNavigation/MainNavigation.module.css.cjs +74 -0
  114. package/dist/components/MainNavigation/MainNavigation.module.css.cjs.map +1 -0
  115. package/dist/components/MainNavigation/MainNavigation.module.css.js +75 -0
  116. package/dist/components/MainNavigation/MainNavigation.module.css.js.map +1 -0
  117. package/dist/components/MainNavigation/MainNavigation.types.d.ts +149 -0
  118. package/dist/components/MainNavigation/MainNavigation.types.d.ts.map +1 -0
  119. package/dist/components/MainNavigation/MainNavigation.utils.cjs +168 -0
  120. package/dist/components/MainNavigation/MainNavigation.utils.cjs.map +1 -0
  121. package/dist/components/MainNavigation/MainNavigation.utils.d.ts +29 -0
  122. package/dist/components/MainNavigation/MainNavigation.utils.d.ts.map +1 -0
  123. package/dist/components/MainNavigation/MainNavigation.utils.js +168 -0
  124. package/dist/components/MainNavigation/MainNavigation.utils.js.map +1 -0
  125. package/dist/components/MainNavigation/index.d.ts +3 -0
  126. package/dist/components/MainNavigation/index.d.ts.map +1 -0
  127. package/dist/components/Modal/Modal.cjs +101 -0
  128. package/dist/components/Modal/Modal.cjs.map +1 -0
  129. package/dist/components/Modal/Modal.css +205 -0
  130. package/dist/components/Modal/Modal.d.ts +3 -0
  131. package/dist/components/Modal/Modal.d.ts.map +1 -0
  132. package/dist/components/Modal/Modal.js +101 -0
  133. package/dist/components/Modal/Modal.js.map +1 -0
  134. package/dist/components/Modal/Modal.module.css.cjs +39 -0
  135. package/dist/components/Modal/Modal.module.css.cjs.map +1 -0
  136. package/dist/components/Modal/Modal.module.css.js +39 -0
  137. package/dist/components/Modal/Modal.module.css.js.map +1 -0
  138. package/dist/components/Modal/Modal.types.d.ts +62 -0
  139. package/dist/components/Modal/Modal.types.d.ts.map +1 -0
  140. package/dist/components/Modal/index.d.ts +3 -0
  141. package/dist/components/Modal/index.d.ts.map +1 -0
  142. package/dist/components/Modal/useDialogDismissal.cjs +41 -0
  143. package/dist/components/Modal/useDialogDismissal.cjs.map +1 -0
  144. package/dist/components/Modal/useDialogDismissal.d.ts +17 -0
  145. package/dist/components/Modal/useDialogDismissal.d.ts.map +1 -0
  146. package/dist/components/Modal/useDialogDismissal.js +41 -0
  147. package/dist/components/Modal/useDialogDismissal.js.map +1 -0
  148. package/dist/components/Modal/useNativeDialog.cjs +126 -0
  149. package/dist/components/Modal/useNativeDialog.cjs.map +1 -0
  150. package/dist/components/Modal/useNativeDialog.d.ts +14 -0
  151. package/dist/components/Modal/useNativeDialog.d.ts.map +1 -0
  152. package/dist/components/Modal/useNativeDialog.js +126 -0
  153. package/dist/components/Modal/useNativeDialog.js.map +1 -0
  154. package/dist/components/Pictograph/Pictograph.css +69 -57
  155. package/dist/components/Pictograph/Pictograph.module.css.cjs +11 -11
  156. package/dist/components/Pictograph/Pictograph.module.css.js +11 -11
  157. package/dist/components/Pictograph/Pictograph.types.d.ts +2 -2
  158. package/dist/components/Pictograph/PictographItem.cjs +15 -4
  159. package/dist/components/Pictograph/PictographItem.cjs.map +1 -1
  160. package/dist/components/Pictograph/PictographItem.css +26 -23
  161. package/dist/components/Pictograph/PictographItem.d.ts.map +1 -1
  162. package/dist/components/Pictograph/PictographItem.js +15 -4
  163. package/dist/components/Pictograph/PictographItem.js.map +1 -1
  164. package/dist/components/Pictograph/PictographItem.module.css.cjs +3 -3
  165. package/dist/components/Pictograph/PictographItem.module.css.js +3 -3
  166. package/dist/components/Quote/Quote.cjs +32 -0
  167. package/dist/components/Quote/Quote.cjs.map +1 -0
  168. package/dist/components/Quote/Quote.css +95 -0
  169. package/dist/components/Quote/Quote.d.ts +3 -0
  170. package/dist/components/Quote/Quote.d.ts.map +1 -0
  171. package/dist/components/Quote/Quote.js +32 -0
  172. package/dist/components/Quote/Quote.js.map +1 -0
  173. package/dist/components/Quote/Quote.module.css.cjs +22 -0
  174. package/dist/components/Quote/Quote.module.css.cjs.map +1 -0
  175. package/dist/components/Quote/Quote.module.css.js +22 -0
  176. package/dist/components/Quote/Quote.module.css.js.map +1 -0
  177. package/dist/components/Quote/Quote.types.d.ts +12 -0
  178. package/dist/components/Quote/Quote.types.d.ts.map +1 -0
  179. package/dist/components/Quote/index.d.ts +3 -0
  180. package/dist/components/Quote/index.d.ts.map +1 -0
  181. package/dist/index.cjs +14 -0
  182. package/dist/index.cjs.map +1 -1
  183. package/dist/index.d.ts +14 -0
  184. package/dist/index.d.ts.map +1 -1
  185. package/dist/index.js +14 -0
  186. package/dist/index.js.map +1 -1
  187. package/dist/styles/utils/elevation.module.css.cjs +3 -0
  188. package/dist/styles/utils/elevation.module.css.cjs.map +1 -1
  189. package/dist/styles/utils/elevation.module.css.js +4 -1
  190. package/dist/styles/utils/elevation.module.css.js.map +1 -1
  191. package/dist/styles/utils/focus.css +21 -13
  192. package/dist/styles/utils/focus.module.css.cjs +3 -3
  193. package/dist/styles/utils/focus.module.css.js +3 -3
  194. package/dist/styles/utils/overlay.css +37 -0
  195. package/dist/styles/utils/overlay.module.css.cjs +13 -0
  196. package/dist/styles/utils/overlay.module.css.cjs.map +1 -0
  197. package/dist/styles/utils/overlay.module.css.js +13 -0
  198. package/dist/styles/utils/overlay.module.css.js.map +1 -0
  199. package/dist/styles/utils/text-decoration.css +9 -1
  200. package/dist/styles/utils/text-decoration.module.css.cjs +5 -2
  201. package/dist/styles/utils/text-decoration.module.css.cjs.map +1 -1
  202. package/dist/styles/utils/text-decoration.module.css.js +6 -3
  203. package/dist/styles/utils/text-decoration.module.css.js.map +1 -1
  204. package/dist/styles.css +24 -7
  205. package/package.json +4 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.cjs","sources":["../../../src/components/ButtonCard/ButtonCard.tsx"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode, Ref } from 'react';\nimport { ChevronRight, Open } from '@dnanpm/icons';\nimport { cn } from '../../utils/cn';\nimport focusStyles from '../../styles/utils/focus.module.css';\nimport elevationStyles from '../../styles/utils/elevation.module.css';\nimport styles from './ButtonCard.module.css';\nimport type { ButtonCardLinkProps, ButtonCardProps } from './ButtonCard.types';\n\nexport const ButtonCard = ({\n title,\n subtitle,\n size = 'medium',\n icon,\n image,\n isExternal = false,\n externalLinkAriaLabel = 'avautuu uuteen välilehteen',\n className,\n ref,\n ...props\n}: ButtonCardProps) => {\n const isAnchor = 'href' in props && (props as { href?: string }).href != null;\n\n const classes = cn(\n styles['button-card'],\n styles[`button-card--${size}`],\n focusStyles.focusable,\n elevationStyles.elevationLow,\n className,\n );\n\n const IconComponent = icon;\n\n const media =\n IconComponent != null ? (\n <span\n className={cn(styles['button-card__media'], styles['button-card__media--icon'])}\n aria-hidden=\"true\"\n >\n <IconComponent aria-hidden=\"true\" />\n </span>\n ) : image ? (\n <span className={cn(styles['button-card__media'], styles['button-card__media--image'])}>\n {image}\n </span>\n ) : null;\n\n const explicitTarget = isAnchor\n ? (props as { target?: string }).target?.toLowerCase()\n : undefined;\n // The link opens a new tab when isExternal is set or the target is _blank.\n const opensInNewTab = isExternal || explicitTarget === '_blank';\n const Indicator = opensInNewTab ? Open : ChevronRight;\n\n const content = (\n <>\n {media}\n <span className={styles['button-card__content']}>\n <span className={styles['button-card__text']}>\n <span className={styles['button-card__title']}>{title}</span>\n {subtitle != null && (\n <span className={styles['button-card__subtitle']}>{subtitle}</span>\n )}\n </span>\n <span className={styles['button-card__indicator']} aria-hidden=\"true\">\n <Indicator aria-hidden=\"true\" />\n </span>\n </span>\n {opensInNewTab && externalLinkAriaLabel && (\n <span className={styles['button-card__sr-only']}>\n {` (${externalLinkAriaLabel})`}\n </span>\n )}\n </>\n );\n\n if (isAnchor) {\n const {\n href,\n renderLink,\n target: targetProp,\n rel,\n disabled: _disabled,\n ...safeAnchorProps\n } = props as unknown as ComponentPropsWithRef<'a'> & {\n href: string;\n renderLink?: (props: ButtonCardLinkProps) => ReactNode;\n disabled?: boolean;\n };\n\n // isExternal is authoritative and forces a new tab; an explicit _blank is preserved.\n const target = isExternal ? '_blank' : targetProp;\n const shouldHardenRel = target?.toLowerCase() === '_blank';\n const relTokens = new Set(\n (rel ?? '')\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.toLowerCase()),\n );\n\n if (shouldHardenRel) {\n relTokens.add('noopener');\n relTokens.add('noreferrer');\n }\n\n const hardenedRel = relTokens.size > 0 ? Array.from(relTokens).join(' ') : undefined;\n\n const linkProps = {\n ...safeAnchorProps,\n ref: ref as Ref<HTMLAnchorElement>,\n href,\n target,\n rel: hardenedRel,\n className: classes,\n children: content,\n };\n\n if (renderLink) {\n return <>{renderLink(linkProps)}</>;\n }\n\n return <a {...linkProps} />;\n }\n\n const {\n type = 'button',\n href: _href,\n target: _target,\n rel: _rel,\n renderLink: _renderLink,\n ...buttonProps\n } = props as unknown as ComponentPropsWithRef<'button'> & {\n href?: string;\n target?: string;\n rel?: string;\n renderLink?: unknown;\n };\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type={type}\n className={classes}\n {...buttonProps}\n >\n {content}\n </button>\n );\n};\n"],"names":["cn","styles","focusStyles","elevationStyles","jsx","Open","ChevronRight","jsxs","Fragment"],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ @layer dds-components {._button-card_14hpp_1 {
2
+ --_button-card-padding: var(--spacing-space-16);
3
+ --_button-card-gap: var(--spacing-space-16);
4
+ --_button-card-content-gap: var(--spacing-space-16);
5
+ --_button-card-text-gap: var(--spacing-space-4);
6
+ --_button-card-line-clamp: 2;
7
+ --_button-card-media-box: 56px;
8
+ --_button-card-media-icon: 40px;
9
+ --_button-card-indicator: 24px;
10
+ --_button-card-title-font: var(--typography-label-lg-bold);
11
+ --_button-card-subtitle-font: var(--typography-label-md);
12
+
13
+ display: flex;
14
+ align-items: center;
15
+ gap: var(--_button-card-gap);
16
+ width: 100%;
17
+ box-sizing: border-box;
18
+ margin: 0;
19
+ padding: var(--_button-card-padding);
20
+ font: inherit;
21
+ text-align: start;
22
+ text-decoration: none;
23
+ color: var(--color-semantic-foreground-default);
24
+ background-color: var(--color-semantic-surface-base);
25
+ border-color: var(--color-semantic-border-neutral-soft);
26
+ border-radius: var(--radius-semantic-md);
27
+ cursor: pointer;
28
+ appearance: none;
29
+ }
30
+
31
+ ._button-card_14hpp_1:where(:hover, :focus-visible) {
32
+ border-color: var(--color-semantic-border-neutral-mid);
33
+ }
34
+
35
+ /* === Size variants (base holds the medium/default values) === */
36
+
37
+ ._button-card--large_14hpp_37 {
38
+ --_button-card-title-font: var(--typography-heading-xs);
39
+ --_button-card-subtitle-font: var(--typography-label-lg);
40
+ }
41
+
42
+ ._button-card--small_14hpp_42 {
43
+ flex-direction: column;
44
+ align-items: stretch;
45
+ --_button-card-padding: var(--spacing-space-8);
46
+ --_button-card-gap: var(--spacing-space-4);
47
+ --_button-card-content-gap: var(--spacing-space-8);
48
+ --_button-card-text-gap: 0;
49
+ --_button-card-line-clamp: 1;
50
+ --_button-card-media-box: 40px;
51
+ --_button-card-media-icon: 24px;
52
+ --_button-card-indicator: 16px;
53
+ --_button-card-title-font: var(--typography-label-md);
54
+ --_button-card-subtitle-font: var(--typography-label-sm);
55
+ }
56
+
57
+ /* === Media === */
58
+
59
+ ._button-card__media_14hpp_59 {
60
+ display: inline-flex;
61
+ flex-shrink: 0;
62
+ align-self: center;
63
+ align-items: center;
64
+ justify-content: center;
65
+ overflow: hidden;
66
+ }
67
+
68
+ ._button-card--small_14hpp_42 ._button-card__media_14hpp_59 {
69
+ align-self: flex-start;
70
+ }
71
+
72
+ ._button-card__media--icon_14hpp_72 {
73
+ width: var(--_button-card-media-box);
74
+ height: var(--_button-card-media-box);
75
+ background-color: var(--color-semantic-surface-neutral-mid);
76
+ border-radius: var(--radius-semantic-md);
77
+ }
78
+
79
+ ._button-card__media--icon_14hpp_72 svg {
80
+ display: block;
81
+ width: var(--_button-card-media-icon);
82
+ height: var(--_button-card-media-icon);
83
+ }
84
+
85
+ ._button-card__media--image_14hpp_85 {
86
+ position: relative;
87
+ width: var(--_button-card-media-box);
88
+ height: var(--_button-card-media-box);
89
+ }
90
+
91
+ ._button-card__media--image_14hpp_85 :where(img, picture, video, svg, canvas) {
92
+ display: block;
93
+ width: 100%;
94
+ height: 100%;
95
+ object-fit: cover;
96
+ }
97
+
98
+ /* === Text === */
99
+
100
+ ._button-card__content_14hpp_100 {
101
+ display: flex;
102
+ flex: 1 1 0;
103
+ min-width: 0;
104
+ align-items: center;
105
+ gap: var(--_button-card-content-gap);
106
+ }
107
+
108
+ ._button-card__text_14hpp_108 {
109
+ display: flex;
110
+ flex: 1 1 0;
111
+ min-width: 0;
112
+ flex-direction: column;
113
+ justify-content: center;
114
+ gap: var(--_button-card-text-gap);
115
+ }
116
+
117
+ ._button-card__title_14hpp_117,
118
+ ._button-card__subtitle_14hpp_118 {
119
+ display: -webkit-box;
120
+ margin: 0;
121
+ overflow: hidden;
122
+ overflow-wrap: anywhere;
123
+ -webkit-box-orient: vertical;
124
+ -webkit-line-clamp: var(--_button-card-line-clamp);
125
+ line-clamp: var(--_button-card-line-clamp);
126
+ }
127
+
128
+ ._button-card__title_14hpp_117 {
129
+ color: var(--color-semantic-foreground-default);
130
+ font: var(--_button-card-title-font);
131
+ }
132
+
133
+ ._button-card__subtitle_14hpp_118 {
134
+ color: var(--color-semantic-foreground-muted);
135
+ font: var(--_button-card-subtitle-font);
136
+ }
137
+
138
+ /* === Indicator === */
139
+
140
+ ._button-card__indicator_14hpp_140 {
141
+ display: inline-flex;
142
+ flex-shrink: 0;
143
+ align-items: center;
144
+ justify-content: center;
145
+ color: var(--color-semantic-foreground-primary-strong);
146
+ }
147
+
148
+ ._button-card__indicator_14hpp_140 svg {
149
+ display: block;
150
+ width: var(--_button-card-indicator);
151
+ height: var(--_button-card-indicator);
152
+ }
153
+
154
+ /* === Visually hidden === */
155
+
156
+ ._button-card__sr-only_14hpp_156 {
157
+ position: absolute;
158
+ width: 1px;
159
+ height: 1px;
160
+ padding: 0;
161
+ margin: -1px;
162
+ overflow: hidden;
163
+ white-space: nowrap;
164
+ border: 0;
165
+ clip: rect(0, 0, 0, 0);
166
+ }
167
+ }
@@ -0,0 +1,3 @@
1
+ import { ButtonCardProps } from './ButtonCard.types';
2
+ export declare const ButtonCard: ({ title, subtitle, size, icon, image, isExternal, externalLinkAriaLabel, className, ref, ...props }: ButtonCardProps) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=ButtonCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/ButtonCard.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE/E,eAAO,MAAM,UAAU,GAAI,qGAWxB,eAAe,4CAgIjB,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
+ import { Open, ChevronRight } from "@dnanpm/icons";
3
+ import focusStyles from "../../styles/utils/focus.module.css.js";
4
+ import elevationStyles from "../../styles/utils/elevation.module.css.js";
5
+ import styles from "./ButtonCard.module.css.js";
6
+ import { cn } from "../../utils/cn/cn.js";
7
+ const ButtonCard = ({
8
+ title,
9
+ subtitle,
10
+ size = "medium",
11
+ icon,
12
+ image,
13
+ isExternal = false,
14
+ externalLinkAriaLabel = "avautuu uuteen välilehteen",
15
+ className,
16
+ ref,
17
+ ...props
18
+ }) => {
19
+ const isAnchor = "href" in props && props.href != null;
20
+ const classes = cn(
21
+ styles["button-card"],
22
+ styles[`button-card--${size}`],
23
+ focusStyles.focusable,
24
+ elevationStyles.elevationLow,
25
+ className
26
+ );
27
+ const IconComponent = icon;
28
+ const media = IconComponent != null ? /* @__PURE__ */ jsx(
29
+ "span",
30
+ {
31
+ className: cn(styles["button-card__media"], styles["button-card__media--icon"]),
32
+ "aria-hidden": "true",
33
+ children: /* @__PURE__ */ jsx(IconComponent, { "aria-hidden": "true" })
34
+ }
35
+ ) : image ? /* @__PURE__ */ jsx("span", { className: cn(styles["button-card__media"], styles["button-card__media--image"]), children: image }) : null;
36
+ const explicitTarget = isAnchor ? props.target?.toLowerCase() : void 0;
37
+ const opensInNewTab = isExternal || explicitTarget === "_blank";
38
+ const Indicator = opensInNewTab ? Open : ChevronRight;
39
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
40
+ media,
41
+ /* @__PURE__ */ jsxs("span", { className: styles["button-card__content"], children: [
42
+ /* @__PURE__ */ jsxs("span", { className: styles["button-card__text"], children: [
43
+ /* @__PURE__ */ jsx("span", { className: styles["button-card__title"], children: title }),
44
+ subtitle != null && /* @__PURE__ */ jsx("span", { className: styles["button-card__subtitle"], children: subtitle })
45
+ ] }),
46
+ /* @__PURE__ */ jsx("span", { className: styles["button-card__indicator"], "aria-hidden": "true", children: /* @__PURE__ */ jsx(Indicator, { "aria-hidden": "true" }) })
47
+ ] }),
48
+ opensInNewTab && externalLinkAriaLabel && /* @__PURE__ */ jsx("span", { className: styles["button-card__sr-only"], children: ` (${externalLinkAriaLabel})` })
49
+ ] });
50
+ if (isAnchor) {
51
+ const {
52
+ href,
53
+ renderLink,
54
+ target: targetProp,
55
+ rel,
56
+ disabled: _disabled,
57
+ ...safeAnchorProps
58
+ } = props;
59
+ const target = isExternal ? "_blank" : targetProp;
60
+ const shouldHardenRel = target?.toLowerCase() === "_blank";
61
+ const relTokens = new Set(
62
+ (rel ?? "").split(/\s+/).filter(Boolean).map((token) => token.toLowerCase())
63
+ );
64
+ if (shouldHardenRel) {
65
+ relTokens.add("noopener");
66
+ relTokens.add("noreferrer");
67
+ }
68
+ const hardenedRel = relTokens.size > 0 ? Array.from(relTokens).join(" ") : void 0;
69
+ const linkProps = {
70
+ ...safeAnchorProps,
71
+ ref,
72
+ href,
73
+ target,
74
+ rel: hardenedRel,
75
+ className: classes,
76
+ children: content
77
+ };
78
+ if (renderLink) {
79
+ return /* @__PURE__ */ jsx(Fragment, { children: renderLink(linkProps) });
80
+ }
81
+ return /* @__PURE__ */ jsx("a", { ...linkProps });
82
+ }
83
+ const {
84
+ type = "button",
85
+ href: _href,
86
+ target: _target,
87
+ rel: _rel,
88
+ renderLink: _renderLink,
89
+ ...buttonProps
90
+ } = props;
91
+ return /* @__PURE__ */ jsx(
92
+ "button",
93
+ {
94
+ ref,
95
+ type,
96
+ className: classes,
97
+ ...buttonProps,
98
+ children: content
99
+ }
100
+ );
101
+ };
102
+ export {
103
+ ButtonCard
104
+ };
105
+ //# sourceMappingURL=ButtonCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.js","sources":["../../../src/components/ButtonCard/ButtonCard.tsx"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode, Ref } from 'react';\nimport { ChevronRight, Open } from '@dnanpm/icons';\nimport { cn } from '../../utils/cn';\nimport focusStyles from '../../styles/utils/focus.module.css';\nimport elevationStyles from '../../styles/utils/elevation.module.css';\nimport styles from './ButtonCard.module.css';\nimport type { ButtonCardLinkProps, ButtonCardProps } from './ButtonCard.types';\n\nexport const ButtonCard = ({\n title,\n subtitle,\n size = 'medium',\n icon,\n image,\n isExternal = false,\n externalLinkAriaLabel = 'avautuu uuteen välilehteen',\n className,\n ref,\n ...props\n}: ButtonCardProps) => {\n const isAnchor = 'href' in props && (props as { href?: string }).href != null;\n\n const classes = cn(\n styles['button-card'],\n styles[`button-card--${size}`],\n focusStyles.focusable,\n elevationStyles.elevationLow,\n className,\n );\n\n const IconComponent = icon;\n\n const media =\n IconComponent != null ? (\n <span\n className={cn(styles['button-card__media'], styles['button-card__media--icon'])}\n aria-hidden=\"true\"\n >\n <IconComponent aria-hidden=\"true\" />\n </span>\n ) : image ? (\n <span className={cn(styles['button-card__media'], styles['button-card__media--image'])}>\n {image}\n </span>\n ) : null;\n\n const explicitTarget = isAnchor\n ? (props as { target?: string }).target?.toLowerCase()\n : undefined;\n // The link opens a new tab when isExternal is set or the target is _blank.\n const opensInNewTab = isExternal || explicitTarget === '_blank';\n const Indicator = opensInNewTab ? Open : ChevronRight;\n\n const content = (\n <>\n {media}\n <span className={styles['button-card__content']}>\n <span className={styles['button-card__text']}>\n <span className={styles['button-card__title']}>{title}</span>\n {subtitle != null && (\n <span className={styles['button-card__subtitle']}>{subtitle}</span>\n )}\n </span>\n <span className={styles['button-card__indicator']} aria-hidden=\"true\">\n <Indicator aria-hidden=\"true\" />\n </span>\n </span>\n {opensInNewTab && externalLinkAriaLabel && (\n <span className={styles['button-card__sr-only']}>\n {` (${externalLinkAriaLabel})`}\n </span>\n )}\n </>\n );\n\n if (isAnchor) {\n const {\n href,\n renderLink,\n target: targetProp,\n rel,\n disabled: _disabled,\n ...safeAnchorProps\n } = props as unknown as ComponentPropsWithRef<'a'> & {\n href: string;\n renderLink?: (props: ButtonCardLinkProps) => ReactNode;\n disabled?: boolean;\n };\n\n // isExternal is authoritative and forces a new tab; an explicit _blank is preserved.\n const target = isExternal ? '_blank' : targetProp;\n const shouldHardenRel = target?.toLowerCase() === '_blank';\n const relTokens = new Set(\n (rel ?? '')\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => token.toLowerCase()),\n );\n\n if (shouldHardenRel) {\n relTokens.add('noopener');\n relTokens.add('noreferrer');\n }\n\n const hardenedRel = relTokens.size > 0 ? Array.from(relTokens).join(' ') : undefined;\n\n const linkProps = {\n ...safeAnchorProps,\n ref: ref as Ref<HTMLAnchorElement>,\n href,\n target,\n rel: hardenedRel,\n className: classes,\n children: content,\n };\n\n if (renderLink) {\n return <>{renderLink(linkProps)}</>;\n }\n\n return <a {...linkProps} />;\n }\n\n const {\n type = 'button',\n href: _href,\n target: _target,\n rel: _rel,\n renderLink: _renderLink,\n ...buttonProps\n } = props as unknown as ComponentPropsWithRef<'button'> & {\n href?: string;\n target?: string;\n rel?: string;\n renderLink?: unknown;\n };\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type={type}\n className={classes}\n {...buttonProps}\n >\n {content}\n </button>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ require('./ButtonCard.css');
2
+ "use strict";
3
+ const styles = {
4
+ "button-card": "_button-card_14hpp_1",
5
+ "button-card--large": "_button-card--large_14hpp_37",
6
+ "button-card--small": "_button-card--small_14hpp_42",
7
+ "button-card__media": "_button-card__media_14hpp_59",
8
+ "button-card__media--icon": "_button-card__media--icon_14hpp_72",
9
+ "button-card__media--image": "_button-card__media--image_14hpp_85",
10
+ "button-card__content": "_button-card__content_14hpp_100",
11
+ "button-card__text": "_button-card__text_14hpp_108",
12
+ "button-card__title": "_button-card__title_14hpp_117",
13
+ "button-card__subtitle": "_button-card__subtitle_14hpp_118",
14
+ "button-card__indicator": "_button-card__indicator_14hpp_140",
15
+ "button-card__sr-only": "_button-card__sr-only_14hpp_156"
16
+ };
17
+ module.exports = styles;
18
+ //# sourceMappingURL=ButtonCard.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.module.css.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
@@ -0,0 +1,19 @@
1
+ import './ButtonCard.css';
2
+ const styles = {
3
+ "button-card": "_button-card_14hpp_1",
4
+ "button-card--large": "_button-card--large_14hpp_37",
5
+ "button-card--small": "_button-card--small_14hpp_42",
6
+ "button-card__media": "_button-card__media_14hpp_59",
7
+ "button-card__media--icon": "_button-card__media--icon_14hpp_72",
8
+ "button-card__media--image": "_button-card__media--image_14hpp_85",
9
+ "button-card__content": "_button-card__content_14hpp_100",
10
+ "button-card__text": "_button-card__text_14hpp_108",
11
+ "button-card__title": "_button-card__title_14hpp_117",
12
+ "button-card__subtitle": "_button-card__subtitle_14hpp_118",
13
+ "button-card__indicator": "_button-card__indicator_14hpp_140",
14
+ "button-card__sr-only": "_button-card__sr-only_14hpp_156"
15
+ };
16
+ export {
17
+ styles as default
18
+ };
19
+ //# sourceMappingURL=ButtonCard.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
@@ -0,0 +1,103 @@
1
+ import { ComponentPropsWithRef, ComponentType, ReactNode, SVGProps } from 'react';
2
+ /**
3
+ * Size variant of the Button card.
4
+ *
5
+ * - `large` — Large text title (Heading XS).
6
+ * - `medium` — Default title (Label LG Bold).
7
+ * - `small` — Compact vertical layout (Label MD title).
8
+ */
9
+ export type ButtonCardSize = 'large' | 'medium' | 'small';
10
+ /** SVG icon component, for example `ChevronRight` from `@dnanpm/icons`. */
11
+ export type ButtonCardIcon = ComponentType<SVGProps<SVGSVGElement>>;
12
+ export interface ButtonCardLinkProps extends ComponentPropsWithRef<'a'> {
13
+ readonly href: string;
14
+ readonly children: ReactNode;
15
+ }
16
+ interface ButtonCardBaseProps {
17
+ /**
18
+ * Primary title. Keep it short; the card clamps it as a layout fallback
19
+ * (two lines, or one line in the small size) and is not designed for long
20
+ * titles.
21
+ */
22
+ readonly title: ReactNode;
23
+ /**
24
+ * Optional subtitle. Keep it short; the card clamps it as a layout fallback
25
+ * (two lines, or one line in the small size) and is not designed for long
26
+ * subtitles.
27
+ */
28
+ readonly subtitle?: ReactNode;
29
+ /**
30
+ * Size variant controlling layout and typography.
31
+ * @default 'medium'
32
+ */
33
+ readonly size?: ButtonCardSize;
34
+ /**
35
+ * Marks the action as opening in a new tab/window: shows the external-link
36
+ * indicator icon and appends the hidden `externalLinkAriaLabel` hint. In link
37
+ * mode (`href`) it is authoritative and forces `target="_blank"` with a
38
+ * hardened `rel`, overriding any explicit `target`; in button mode the
39
+ * consumer opens the new window (for example `window.open`).
40
+ * @default false
41
+ */
42
+ readonly isExternal?: boolean;
43
+ /**
44
+ * Visually hidden hint appended to the accessible name when `isExternal` is
45
+ * true. Defaults to Finnish per the design system aria-label policy.
46
+ * @default 'avautuu uuteen välilehteen'
47
+ */
48
+ readonly externalLinkAriaLabel?: string;
49
+ }
50
+ /**
51
+ * Media is optional and mutually exclusive: provide either `icon` or `image`,
52
+ * never both. Omitting both renders the card without a media area.
53
+ */
54
+ type ButtonCardMediaProps = {
55
+ /** Decorative SVG icon rendered in a neutral media box. */
56
+ readonly icon?: ButtonCardIcon;
57
+ readonly image?: never;
58
+ } | {
59
+ readonly icon?: never;
60
+ /**
61
+ * Image slot rendered inside the DS-sized, clipped media box. The
62
+ * client owns the rendering, so an optimized image component (for
63
+ * example `next/image` or an app's own `OptimizedImage`) can be dropped
64
+ * in. The box is `position: relative`, so `next/image` `fill` works.
65
+ * Mark decorative images with an empty `alt`.
66
+ */
67
+ readonly image?: ReactNode;
68
+ };
69
+ export type ButtonCardAsButton = ButtonCardBaseProps & ButtonCardMediaProps & Omit<ComponentPropsWithRef<'button'>, keyof ButtonCardBaseProps | 'children' | 'disabled'> & {
70
+ /** When omitted, the card renders as a `<button>`. */
71
+ readonly href?: never;
72
+ readonly target?: never;
73
+ readonly rel?: never;
74
+ readonly renderLink?: never;
75
+ /** ButtonCard has no disabled state by design; render it conditionally instead. */
76
+ readonly disabled?: never;
77
+ };
78
+ export type ButtonCardAsAnchor = ButtonCardBaseProps & ButtonCardMediaProps & Omit<ComponentPropsWithRef<'a'>, keyof ButtonCardBaseProps | 'children'> & {
79
+ /** When provided, the card renders as an `<a>`. */
80
+ readonly href: string;
81
+ readonly disabled?: never;
82
+ readonly type?: never;
83
+ readonly name?: never;
84
+ /**
85
+ * Custom render function for the link element. Use this to integrate with
86
+ * client-side routing libraries like Next.js or React Router.
87
+ *
88
+ * @example
89
+ * // Next.js
90
+ * import Link from 'next/link';
91
+ * <ButtonCard href="/page" title="Open" renderLink={(props) => <Link {...props} />} />
92
+ */
93
+ readonly renderLink?: (props: ButtonCardLinkProps) => ReactNode;
94
+ };
95
+ /**
96
+ * Props for the Button card component.
97
+ *
98
+ * When `href` is provided the component renders as an `<a>` element;
99
+ * otherwise it renders as a `<button>`.
100
+ */
101
+ export type ButtonCardProps = ButtonCardAsButton | ButtonCardAsAnchor;
102
+ export {};
103
+ //# sourceMappingURL=ButtonCard.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ButtonCard.types.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/ButtonCard.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEvF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB,CAAC,GAAG,CAAC;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAChC;AAED,UAAU,mBAAmB;IACzB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED;;;GAGG;AACH,KAAK,oBAAoB,GACnB;IACI,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CAC1B,GACD;IACI,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC9B,CAAC;AAER,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAChD,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,mBAAmB,GAAG,UAAU,GAAG,UAAU,CAAC,GAAG;IACzF,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CAC7B,CAAC;AAEN,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAChD,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,MAAM,mBAAmB,GAAG,UAAU,CAAC,GAAG;IACvE,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACtB;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,SAAS,CAAC;CACnE,CAAC;AAEN;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ButtonCard } from './ButtonCard';
2
+ export type { ButtonCardIcon, ButtonCardLinkProps, ButtonCardProps, ButtonCardSize, } from './ButtonCard.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ButtonCard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EACR,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,cAAc,GACjB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const icons = require("@dnanpm/icons");
6
+ const elevation_module = require("../../styles/utils/elevation.module.css.cjs");
7
+ const focus_module = require("../../styles/utils/focus.module.css.cjs");
8
+ const useDialogDismissal = require("../Modal/useDialogDismissal.cjs");
9
+ const useNativeDialog = require("../Modal/useNativeDialog.cjs");
10
+ const Drawer_module = require("./Drawer.module.css.cjs");
11
+ const cn = require("../../utils/cn/cn.cjs");
12
+ const Drawer = ({
13
+ open,
14
+ onOpenChange,
15
+ title,
16
+ description,
17
+ children,
18
+ footer,
19
+ size = "small",
20
+ headerStyle = "light",
21
+ side = "right",
22
+ fixedTitle = false,
23
+ disableCloseOptions = false,
24
+ closeLabel = "Sulje dialogi",
25
+ keepMounted = false,
26
+ className,
27
+ ref,
28
+ onKeyDown,
29
+ onClick,
30
+ onPointerDown,
31
+ "aria-label": ariaLabel,
32
+ "aria-labelledby": ariaLabelledBy,
33
+ "aria-describedby": ariaDescribedBy,
34
+ ...props
35
+ }) => {
36
+ const titleId = react.useId();
37
+ const descriptionId = react.useId();
38
+ const { dialogRef, close, phase, isPresent } = useNativeDialog.useNativeDialog({
39
+ open: open ?? false,
40
+ keepMounted,
41
+ onOpenChange
42
+ });
43
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
44
+ const dialogDismissalProps = useDialogDismissal.useDialogDismissal({
45
+ close,
46
+ disableCloseOptions,
47
+ onClick,
48
+ onKeyDown,
49
+ onPointerDown
50
+ });
51
+ if (!isPresent) return null;
52
+ return /* @__PURE__ */ jsxRuntime.jsxs(
53
+ "dialog",
54
+ {
55
+ ...props,
56
+ ref: (node) => {
57
+ dialogRef.current = node;
58
+ if (typeof ref === "function") ref(node);
59
+ else if (ref) ref.current = node;
60
+ },
61
+ className: cn.cn(
62
+ Drawer_module.default.drawer,
63
+ elevation_module.default.elevationHigh,
64
+ Drawer_module.default[`drawer--${size}`],
65
+ Drawer_module.default[`drawer--${headerStyle}`],
66
+ Drawer_module.default[`drawer--${side}`],
67
+ { [Drawer_module.default["drawer--fixed-title"]]: fixedTitle },
68
+ { [Drawer_module.default["drawer--opening"]]: phase !== "closing" },
69
+ { [Drawer_module.default["drawer--closing"]]: phase === "closing" },
70
+ className
71
+ ),
72
+ "aria-label": ariaLabel,
73
+ "aria-labelledby": ariaLabelledBy ?? (!ariaLabel && title ? titleId : void 0),
74
+ "aria-describedby": describedBy,
75
+ ...dialogDismissalProps,
76
+ children: [
77
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Drawer_module.default.drawer__container, children: [
78
+ !disableCloseOptions && /* @__PURE__ */ jsxRuntime.jsx(
79
+ "button",
80
+ {
81
+ type: "button",
82
+ className: cn.cn(Drawer_module.default.drawer__close, focus_module.default.focusable),
83
+ "aria-label": closeLabel,
84
+ "data-dialog-autofocus": "true",
85
+ onClick: close,
86
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Close, { "aria-hidden": "true" })
87
+ }
88
+ ),
89
+ (title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Drawer_module.default.drawer__title, children: [
90
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: titleId, className: Drawer_module.default.drawer__heading, children: title }),
91
+ description && /* @__PURE__ */ jsxRuntime.jsx("div", { id: descriptionId, className: Drawer_module.default.drawer__description, children: description })
92
+ ] }),
93
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: Drawer_module.default.drawer__content, children })
94
+ ] }),
95
+ footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn.cn(Drawer_module.default["drawer__bottom-bar"], elevation_module.default.elevationMedium), children: footer })
96
+ ]
97
+ }
98
+ );
99
+ };
100
+ exports.Drawer = Drawer;
101
+ //# sourceMappingURL=Drawer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.cjs","sources":["../../../src/components/Drawer/Drawer.tsx"],"sourcesContent":["import { useId } from 'react';\nimport { Close } from '@dnanpm/icons';\nimport { cn } from '../../utils/cn';\nimport elevationStyles from '../../styles/utils/elevation.module.css';\nimport focusStyles from '../../styles/utils/focus.module.css';\nimport { useDialogDismissal } from '../Modal/useDialogDismissal';\nimport { useNativeDialog } from '../Modal/useNativeDialog';\nimport styles from './Drawer.module.css';\nimport type { DrawerProps } from './Drawer.types';\n\nexport const Drawer = ({\n open,\n onOpenChange,\n title,\n description,\n children,\n footer,\n size = 'small',\n headerStyle = 'light',\n side = 'right',\n fixedTitle = false,\n disableCloseOptions = false,\n closeLabel = 'Sulje dialogi',\n keepMounted = false,\n className,\n ref,\n onKeyDown,\n onClick,\n onPointerDown,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n ...props\n}: DrawerProps) => {\n const titleId = useId();\n const descriptionId = useId();\n const { dialogRef, close, phase, isPresent } = useNativeDialog({\n open: open ?? false,\n keepMounted,\n onOpenChange,\n });\n const describedBy =\n [description ? descriptionId : undefined, ariaDescribedBy].filter(Boolean).join(' ') ||\n undefined;\n const dialogDismissalProps = useDialogDismissal({\n close,\n disableCloseOptions,\n onClick,\n onKeyDown,\n onPointerDown,\n });\n\n if (!isPresent) return null;\n\n return (\n <dialog\n {...props}\n ref={(node) => {\n dialogRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }}\n className={cn(\n styles.drawer,\n elevationStyles.elevationHigh,\n styles[`drawer--${size}`],\n styles[`drawer--${headerStyle}`],\n styles[`drawer--${side}`],\n { [styles['drawer--fixed-title']]: fixedTitle },\n { [styles['drawer--opening']]: phase !== 'closing' },\n { [styles['drawer--closing']]: phase === 'closing' },\n className,\n )}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy ?? (!ariaLabel && title ? titleId : undefined)}\n aria-describedby={describedBy}\n {...dialogDismissalProps}\n >\n <div className={styles.drawer__container}>\n {!disableCloseOptions && (\n <button\n type=\"button\"\n className={cn(styles.drawer__close, focusStyles.focusable)}\n aria-label={closeLabel}\n data-dialog-autofocus=\"true\"\n onClick={close}\n >\n <Close aria-hidden=\"true\" />\n </button>\n )}\n {(title || description) && (\n <div className={styles.drawer__title}>\n {title && (\n <h2 id={titleId} className={styles.drawer__heading}>\n {title}\n </h2>\n )}\n {description && (\n <div id={descriptionId} className={styles.drawer__description}>\n {description}\n </div>\n )}\n </div>\n )}\n <div className={styles.drawer__content}>{children}</div>\n </div>\n {footer && (\n <div className={cn(styles['drawer__bottom-bar'], elevationStyles.elevationMedium)}>\n {footer}\n </div>\n )}\n </dialog>\n );\n};\n"],"names":["useId","useNativeDialog","useDialogDismissal","jsxs","cn","styles","elevationStyles","jsx","focusStyles","Close"],"mappings":"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"}