@purpur/library 9.4.3 → 9.6.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/CHANGELOG.json +27 -0
- package/CHANGELOG.md +16 -1
- package/dist/LICENSE.txt +23 -2
- package/dist/avatar-CYnD57o4.js +2 -0
- package/dist/avatar-CYnD57o4.js.map +1 -0
- package/dist/avatar-CzbDD1MK.mjs +27 -0
- package/dist/avatar-CzbDD1MK.mjs.map +1 -0
- package/dist/avatar.cjs.js +2 -0
- package/dist/avatar.cjs.js.map +1 -0
- package/dist/avatar.es.js +5 -0
- package/dist/avatar.es.js.map +1 -0
- package/dist/color-dot-BEE5rKco.js +2 -0
- package/dist/color-dot-BEE5rKco.js.map +1 -0
- package/dist/color-dot-Dz9yzVX3.mjs +28 -0
- package/dist/color-dot-Dz9yzVX3.mjs.map +1 -0
- package/dist/color-dot.cjs.js +1 -1
- package/dist/color-dot.es.js +4 -3
- package/dist/comparison-table-CZMKl1TX.mjs +292 -0
- package/dist/comparison-table-CZMKl1TX.mjs.map +1 -0
- package/dist/comparison-table-Nhp5W6Yc.js +2 -0
- package/dist/comparison-table-Nhp5W6Yc.js.map +1 -0
- package/dist/comparison-table.cjs.js +1 -1
- package/dist/comparison-table.es.js +1 -1
- package/dist/components/avatar/src/avatar-constants.d.ts +2 -0
- package/dist/components/avatar/src/avatar-constants.d.ts.map +1 -0
- package/dist/components/avatar/src/avatar.d.ts +26 -0
- package/dist/components/avatar/src/avatar.d.ts.map +1 -0
- package/dist/components/color-dot/src/color-dot.d.ts +18 -8
- package/dist/components/color-dot/src/color-dot.d.ts.map +1 -1
- package/dist/components/comparison-table/src/components/OptionCard/option-card.d.ts.map +1 -1
- package/dist/components/loading/src/loading-dots.d.ts +19 -0
- package/dist/components/loading/src/loading-dots.d.ts.map +1 -0
- package/dist/components/loading/src/loading-text.d.ts +21 -0
- package/dist/components/loading/src/loading-text.d.ts.map +1 -0
- package/dist/components/loading/src/loading.d.ts +10 -0
- package/dist/components/loading/src/loading.d.ts.map +1 -0
- package/dist/components/message/src/message-bubble.d.ts +22 -0
- package/dist/components/message/src/message-bubble.d.ts.map +1 -0
- package/dist/components/message/src/message-stamp.d.ts +26 -0
- package/dist/components/message/src/message-stamp.d.ts.map +1 -0
- package/dist/components/message/src/message-utils.d.ts +3 -0
- package/dist/components/message/src/message-utils.d.ts.map +1 -0
- package/dist/components/message/src/message.d.ts +42 -0
- package/dist/components/message/src/message.d.ts.map +1 -0
- package/dist/components-metadata.js +33 -2
- package/dist/libraries/library/src/avatar.d.ts +6 -0
- package/dist/libraries/library/src/avatar.d.ts.map +1 -0
- package/dist/libraries/library/src/library.d.ts +3 -0
- package/dist/libraries/library/src/library.d.ts.map +1 -1
- package/dist/libraries/library/src/loading.d.ts +6 -0
- package/dist/libraries/library/src/loading.d.ts.map +1 -0
- package/dist/libraries/library/src/message.d.ts +6 -0
- package/dist/libraries/library/src/message.d.ts.map +1 -0
- package/dist/library.cjs.js +1 -1
- package/dist/library.es.js +632 -625
- package/dist/library.es.js.map +1 -1
- package/dist/loading-Dwtkjstg.js +2 -0
- package/dist/loading-Dwtkjstg.js.map +1 -0
- package/dist/loading-r23nxJSz.mjs +107 -0
- package/dist/loading-r23nxJSz.mjs.map +1 -0
- package/dist/loading.cjs.js +2 -0
- package/dist/loading.cjs.js.map +1 -0
- package/dist/loading.es.js +5 -0
- package/dist/loading.es.js.map +1 -0
- package/dist/message-0yTS5pOF.js +3 -0
- package/dist/message-0yTS5pOF.js.map +1 -0
- package/dist/message-D9CDwcw9.mjs +132 -0
- package/dist/message-D9CDwcw9.mjs.map +1 -0
- package/dist/message.cjs.js +2 -0
- package/dist/message.cjs.js.map +1 -0
- package/dist/message.es.js +5 -0
- package/dist/message.es.js.map +1 -0
- package/dist/{product-card-CoY1KggV.js → product-card-8X-Ld2d_.js} +2 -2
- package/dist/{product-card-CoY1KggV.js.map → product-card-8X-Ld2d_.js.map} +1 -1
- package/dist/{product-card-C3_N0t-R.mjs → product-card-Bt-F0wKr.mjs} +10 -10
- package/dist/{product-card-C3_N0t-R.mjs.map → product-card-Bt-F0wKr.mjs.map} +1 -1
- package/dist/product-card.cjs.js +1 -1
- package/dist/product-card.es.js +1 -1
- package/dist/purpur.css +1 -1
- package/package.json +29 -26
- package/src/aliases.ts +12 -0
- package/src/avatar.ts +6 -0
- package/src/entries.js +3 -0
- package/src/library.ts +6 -0
- package/src/loading.ts +6 -0
- package/src/message.ts +6 -0
- package/dist/color-dot-6Mxngvce.mjs +0 -34
- package/dist/color-dot-6Mxngvce.mjs.map +0 -1
- package/dist/color-dot-B9w_ucWb.js +0 -2
- package/dist/color-dot-B9w_ucWb.js.map +0 -1
- package/dist/comparison-table-C74IAVqz.js +0 -2
- package/dist/comparison-table-C74IAVqz.js.map +0 -1
- package/dist/comparison-table-DctKxmX9.mjs +0 -267
- package/dist/comparison-table-DctKxmX9.mjs.map +0 -1
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@purpur/library",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"version": "9.6.0",
|
|
6
|
+
"tag": "@purpur/library_v9.6.0",
|
|
7
|
+
"date": "Tue, 26 May 2026 14:12:15 GMT",
|
|
8
|
+
"comments": {
|
|
9
|
+
"none": [
|
|
10
|
+
{
|
|
11
|
+
"comment": "ComparisonTable: Update option cards to show the read more control based on measured description overflow instead of character count, and add more specific selectors to improve style targeting."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"comment": "Avatar: Create Avatar component"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"comment": "Loading: Create Loading component"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"comment": "Message: Create Message component"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"version": "9.5.0",
|
|
27
|
+
"tag": "@purpur/library_v9.5.0",
|
|
28
|
+
"date": "Fri, 22 May 2026 12:47:40 GMT",
|
|
29
|
+
"comments": {}
|
|
30
|
+
},
|
|
4
31
|
{
|
|
5
32
|
"version": "9.4.3",
|
|
6
33
|
"tag": "@purpur/library_v9.4.3",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# Change Log - @purpur/library
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Tue, 26 May 2026 14:12:15 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 9.6.0
|
|
6
|
+
Tue, 26 May 2026 14:12:15 GMT
|
|
7
|
+
|
|
8
|
+
### Updates
|
|
9
|
+
|
|
10
|
+
- ComparisonTable: Update option cards to show the read more control based on measured description overflow instead of character count, and add more specific selectors to improve style targeting.
|
|
11
|
+
- Avatar: Create Avatar component
|
|
12
|
+
- Loading: Create Loading component
|
|
13
|
+
- Message: Create Message component
|
|
14
|
+
|
|
15
|
+
## 9.5.0
|
|
16
|
+
Fri, 22 May 2026 12:47:40 GMT
|
|
17
|
+
|
|
18
|
+
_Version update only_
|
|
4
19
|
|
|
5
20
|
## 9.4.3
|
|
6
21
|
Fri, 22 May 2026 09:13:07 GMT
|
package/dist/LICENSE.txt
CHANGED
|
@@ -176,6 +176,13 @@ Private: false
|
|
|
176
176
|
|
|
177
177
|
---
|
|
178
178
|
|
|
179
|
+
Name: @purpur/avatar
|
|
180
|
+
Version: 1.0.0
|
|
181
|
+
License: AGPL-3.0-only
|
|
182
|
+
Private: false
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
179
186
|
Name: @purpur/color-dot
|
|
180
187
|
Version: 8.21.0
|
|
181
188
|
License: AGPL-3.0-only
|
|
@@ -570,6 +577,20 @@ Private: false
|
|
|
570
577
|
|
|
571
578
|
---
|
|
572
579
|
|
|
580
|
+
Name: @purpur/loading
|
|
581
|
+
Version: 1.0.0
|
|
582
|
+
License: AGPL-3.0-only
|
|
583
|
+
Private: false
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
Name: @purpur/message
|
|
588
|
+
Version: 1.0.0
|
|
589
|
+
License: AGPL-3.0-only
|
|
590
|
+
Private: false
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
573
594
|
Name: @purpur/modal
|
|
574
595
|
Version: 8.21.0
|
|
575
596
|
License: AGPL-3.0-only
|
|
@@ -814,14 +835,14 @@ Private: false
|
|
|
814
835
|
|
|
815
836
|
---
|
|
816
837
|
|
|
817
|
-
Name: @purpur/
|
|
838
|
+
Name: @purpur/cta-link
|
|
818
839
|
Version: 8.21.0
|
|
819
840
|
License: AGPL-3.0-only
|
|
820
841
|
Private: false
|
|
821
842
|
|
|
822
843
|
---
|
|
823
844
|
|
|
824
|
-
Name: @purpur/
|
|
845
|
+
Name: @purpur/hero-banner
|
|
825
846
|
Version: 8.21.0
|
|
826
847
|
License: AGPL-3.0-only
|
|
827
848
|
Private: false
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const s=require("react/jsx-runtime"),l=require("./paragraph-By4jMjnH.js"),c=require("./bind-DeUYJ6m9.js"),v={"purpur-avatar":"_purpur-avatar_gfshm_1","purpur-avatar--xxs":"_purpur-avatar--xxs_gfshm_9","purpur-avatar--xs":"_purpur-avatar--xs_gfshm_13","purpur-avatar--sm":"_purpur-avatar--sm_gfshm_17","purpur-avatar--md":"_purpur-avatar--md_gfshm_21","purpur-avatar--lg":"_purpur-avatar--lg_gfshm_25","purpur-avatar__label":"_purpur-avatar__label_gfshm_29"},t=c.c.bind(v),r="purpur-avatar",u=a=>{const{className:e,label:p,size:i="xxs"}=a,_=a.decorative===!0?{"aria-hidden":!0}:{"aria-label":a["aria-label"],role:"img"};return s.jsx("div",{..._,className:t(r,`${r}--${i}`,e),children:s.jsx(l.Paragraph,{className:t(`${r}__label`),variant:"additional-100-medium",children:p})})};u.displayName="Avatar";exports.Avatar=u;
|
|
2
|
+
//# sourceMappingURL=avatar-CYnD57o4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar-CYnD57o4.js","sources":["../../../components/avatar/src/avatar.tsx"],"sourcesContent":["import React, { type ReactNode } from \"react\";\nimport { Paragraph } from \"@purpur/paragraph\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./avatar.module.scss\";\nimport type { AVATAR_SIZE } from \"./avatar-constants\";\n\nconst cx = c.bind(styles);\nconst rootClassName = \"purpur-avatar\";\n\nexport type AvatarSize = (typeof AVATAR_SIZE)[number];\n\ntype AvatarBaseProps = {\n className?: string;\n /** Text or element rendered inside the avatar, typically initials. */\n label: ReactNode;\n size?: AvatarSize;\n};\n\ntype AvatarDecorativeProps = AvatarBaseProps & {\n /** Hides the avatar from assistive technologies. */\n decorative: true;\n \"aria-label\"?: never;\n};\n\ntype AvatarAccessibleProps = AvatarBaseProps & {\n /** Accessible label for assistive technologies. Required when avatar is not decorative. */\n \"aria-label\": string;\n decorative?: false;\n};\n\nexport type AvatarProps = AvatarDecorativeProps | AvatarAccessibleProps;\n\nexport const Avatar = (props: AvatarProps) => {\n const { className, label, size = \"xxs\" } = props;\n const isDecorative = props.decorative === true;\n const accessibilityProps = isDecorative\n ? { \"aria-hidden\": true as const }\n : { \"aria-label\": props[\"aria-label\"], role: \"img\" as const };\n\n return (\n <div\n {...accessibilityProps}\n className={cx(rootClassName, `${rootClassName}--${size}`, className)}\n >\n <Paragraph className={cx(`${rootClassName}__label`)} variant=\"additional-100-medium\">\n {label}\n </Paragraph>\n </div>\n );\n};\n\nAvatar.displayName = \"Avatar\";\n"],"names":["cx","c","styles","rootClassName","Avatar","props","className","label","size","accessibilityProps","jsx","Paragraph"],"mappings":"udAOMA,EAAKC,EAAAA,EAAE,KAAKC,CAAM,EAClBC,EAAgB,gBAyBTC,EAAUC,GAAuB,CAC5C,KAAM,CAAE,UAAAC,EAAW,MAAAC,EAAO,KAAAC,EAAO,OAAUH,EAErCI,EADeJ,EAAM,aAAe,GAEtC,CAAE,cAAe,EAAA,EACjB,CAAE,aAAcA,EAAM,YAAY,EAAG,KAAM,KAAA,EAE/C,OACEK,EAAAA,IAAC,MAAA,CACE,GAAGD,EACJ,UAAWT,EAAGG,EAAe,GAAGA,CAAa,KAAKK,CAAI,GAAIF,CAAS,EAEnE,SAAAI,EAAAA,IAACC,EAAAA,UAAA,CAAU,UAAWX,EAAG,GAAGG,CAAa,SAAS,EAAG,QAAQ,wBAC1D,SAAAI,CAAA,CACH,CAAA,CAAA,CAGN,EAEAH,EAAO,YAAc"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { P as i } from "./paragraph-DSxXmX_0.mjs";
|
|
3
|
+
import { c as l } from "./bind-CU-R61T-.mjs";
|
|
4
|
+
const m = {
|
|
5
|
+
"purpur-avatar": "_purpur-avatar_gfshm_1",
|
|
6
|
+
"purpur-avatar--xxs": "_purpur-avatar--xxs_gfshm_9",
|
|
7
|
+
"purpur-avatar--xs": "_purpur-avatar--xs_gfshm_13",
|
|
8
|
+
"purpur-avatar--sm": "_purpur-avatar--sm_gfshm_17",
|
|
9
|
+
"purpur-avatar--md": "_purpur-avatar--md_gfshm_21",
|
|
10
|
+
"purpur-avatar--lg": "_purpur-avatar--lg_gfshm_25",
|
|
11
|
+
"purpur-avatar__label": "_purpur-avatar__label_gfshm_29"
|
|
12
|
+
}, t = l.bind(m), r = "purpur-avatar", v = (a) => {
|
|
13
|
+
const { className: u, label: p, size: e = "xxs" } = a, _ = a.decorative === !0 ? { "aria-hidden": !0 } : { "aria-label": a["aria-label"], role: "img" };
|
|
14
|
+
return /* @__PURE__ */ s(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
..._,
|
|
18
|
+
className: t(r, `${r}--${e}`, u),
|
|
19
|
+
children: /* @__PURE__ */ s(i, { className: t(`${r}__label`), variant: "additional-100-medium", children: p })
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
v.displayName = "Avatar";
|
|
24
|
+
export {
|
|
25
|
+
v as A
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=avatar-CzbDD1MK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar-CzbDD1MK.mjs","sources":["../../../components/avatar/src/avatar.tsx"],"sourcesContent":["import React, { type ReactNode } from \"react\";\nimport { Paragraph } from \"@purpur/paragraph\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./avatar.module.scss\";\nimport type { AVATAR_SIZE } from \"./avatar-constants\";\n\nconst cx = c.bind(styles);\nconst rootClassName = \"purpur-avatar\";\n\nexport type AvatarSize = (typeof AVATAR_SIZE)[number];\n\ntype AvatarBaseProps = {\n className?: string;\n /** Text or element rendered inside the avatar, typically initials. */\n label: ReactNode;\n size?: AvatarSize;\n};\n\ntype AvatarDecorativeProps = AvatarBaseProps & {\n /** Hides the avatar from assistive technologies. */\n decorative: true;\n \"aria-label\"?: never;\n};\n\ntype AvatarAccessibleProps = AvatarBaseProps & {\n /** Accessible label for assistive technologies. Required when avatar is not decorative. */\n \"aria-label\": string;\n decorative?: false;\n};\n\nexport type AvatarProps = AvatarDecorativeProps | AvatarAccessibleProps;\n\nexport const Avatar = (props: AvatarProps) => {\n const { className, label, size = \"xxs\" } = props;\n const isDecorative = props.decorative === true;\n const accessibilityProps = isDecorative\n ? { \"aria-hidden\": true as const }\n : { \"aria-label\": props[\"aria-label\"], role: \"img\" as const };\n\n return (\n <div\n {...accessibilityProps}\n className={cx(rootClassName, `${rootClassName}--${size}`, className)}\n >\n <Paragraph className={cx(`${rootClassName}__label`)} variant=\"additional-100-medium\">\n {label}\n </Paragraph>\n </div>\n );\n};\n\nAvatar.displayName = \"Avatar\";\n"],"names":["cx","c","styles","rootClassName","Avatar","props","className","label","size","accessibilityProps","jsx","Paragraph"],"mappings":";;;;;;;;;;;GAOMA,IAAKC,EAAE,KAAKC,CAAM,GAClBC,IAAgB,iBAyBTC,IAAS,CAACC,MAAuB;AAC5C,QAAM,EAAE,WAAAC,GAAW,OAAAC,GAAO,MAAAC,IAAO,UAAUH,GAErCI,IADeJ,EAAM,eAAe,KAEtC,EAAE,eAAe,GAAA,IACjB,EAAE,cAAcA,EAAM,YAAY,GAAG,MAAM,MAAA;AAE/C,SACE,gBAAAK;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGD;AAAA,MACJ,WAAWT,EAAGG,GAAe,GAAGA,CAAa,KAAKK,CAAI,IAAIF,CAAS;AAAA,MAEnE,UAAA,gBAAAI,EAACC,GAAA,EAAU,WAAWX,EAAG,GAAGG,CAAa,SAAS,GAAG,SAAQ,yBAC1D,UAAAI,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAH,EAAO,cAAc;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const c=require("react/jsx-runtime"),e=require("./bind-DeUYJ6m9.js"),s={"purpur-color-dot":"_purpur-color-dot_ywkxi_1","purpur-color-dot--xs":"_purpur-color-dot--xs_ywkxi_11","purpur-color-dot--sm":"_purpur-color-dot--sm_ywkxi_14","purpur-color-dot--md":"_purpur-color-dot--md_ywkxi_17","purpur-color-dot--lg":"_purpur-color-dot--lg_ywkxi_20","purpur-color-dot--with-border":"_purpur-color-dot--with-border_ywkxi_23","purpur-color-dot--button":"_purpur-color-dot--button_ywkxi_26","purpur-color-dot--selected":"_purpur-color-dot--selected_ywkxi_29"},i=e.c.bind(s),r="purpur-color-dot",l=["xs","sm","md","lg"],n=l.filter(t=>t!=="xs"),p=({size:t,withBorder:_,variant:u="static",...o})=>{const d=i(o.className,r,`${r}--${t}`,{[`${r}--with-border`]:_,[`${r}--selected`]:o.isSelected,[`${r}--button`]:u==="button"});return o.className=d,o.style={...o.style,backgroundColor:o.color},u==="button"?c.jsx("button",{...o}):c.jsx("div",{...o})};exports.BUTTON_COLOR_DOT_SIZE=n;exports.ColorDot=p;exports.STATIC_COLOR_DOT_SIZE=l;
|
|
2
|
+
//# sourceMappingURL=color-dot-BEE5rKco.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-dot-BEE5rKco.js","sources":["../../../components/color-dot/src/color-dot.tsx"],"sourcesContent":["import React, { type HTMLAttributes } from \"react\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./color-dot.module.scss\";\n\nconst cx = c.bind(styles);\nconst rootClassName = \"purpur-color-dot\";\n\nexport const STATIC_COLOR_DOT_SIZE = [\"xs\", \"sm\", \"md\", \"lg\"] as const;\nexport const BUTTON_COLOR_DOT_SIZE = STATIC_COLOR_DOT_SIZE.filter((size) => size !== \"xs\");\n\nexport type StaticColorDotSize = (typeof STATIC_COLOR_DOT_SIZE)[number];\nexport type ButtonColorDotSize = (typeof BUTTON_COLOR_DOT_SIZE)[number];\nexport type StaticColorDotProps = HTMLAttributes<HTMLDivElement> & {\n variant?: \"static\";\n isSelected?: never;\n size: StaticColorDotSize;\n};\n\nexport type ButtonColorDotProps = HTMLAttributes<HTMLButtonElement> & {\n variant?: \"button\";\n isSelected?: boolean;\n size: ButtonColorDotSize;\n};\n\nexport type ColorDotProps = {\n color: string;\n withBorder?: boolean;\n} & (StaticColorDotProps | ButtonColorDotProps);\n\nexport const ColorDot = ({ size, withBorder, variant = \"static\", ...props }: ColorDotProps) => {\n const className = cx(props.className, rootClassName, `${rootClassName}--${size}`, {\n [`${rootClassName}--with-border`]: withBorder,\n [`${rootClassName}--selected`]: props.isSelected,\n [`${rootClassName}--button`]: variant === \"button\",\n });\n\n props.className = className;\n props.style = {\n ...props.style,\n backgroundColor: props.color,\n };\n\n if (variant === \"button\") {\n return <button {...(props as ButtonColorDotProps)} />;\n }\n return <div {...(props as StaticColorDotProps)} />;\n};\n"],"names":["cx","c","styles","rootClassName","STATIC_COLOR_DOT_SIZE","BUTTON_COLOR_DOT_SIZE","size","ColorDot","withBorder","variant","props","className","jsx"],"mappings":"mjBAKMA,EAAKC,EAAAA,EAAE,KAAKC,CAAM,EAClBC,EAAgB,mBAETC,EAAwB,CAAC,KAAM,KAAM,KAAM,IAAI,EAC/CC,EAAwBD,EAAsB,OAAQE,GAASA,IAAS,IAAI,EAqB5EC,EAAW,CAAC,CAAE,KAAAD,EAAM,WAAAE,EAAY,QAAAC,EAAU,SAAU,GAAGC,KAA2B,CAC7F,MAAMC,EAAYX,EAAGU,EAAM,UAAWP,EAAe,GAAGA,CAAa,KAAKG,CAAI,GAAI,CAChF,CAAC,GAAGH,CAAa,eAAe,EAAGK,EACnC,CAAC,GAAGL,CAAa,YAAY,EAAGO,EAAM,WACtC,CAAC,GAAGP,CAAa,UAAU,EAAGM,IAAY,QAAA,CAC3C,EAQD,OANAC,EAAM,UAAYC,EAClBD,EAAM,MAAQ,CACZ,GAAGA,EAAM,MACT,gBAAiBA,EAAM,KAAA,EAGrBD,IAAY,SACPG,MAAC,SAAA,CAAQ,GAAIF,CAAA,CAA+B,EAE9CE,MAAC,MAAA,CAAK,GAAIF,CAAA,CAA+B,CAClD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { c as _ } from "./bind-CU-R61T-.mjs";
|
|
3
|
+
const s = {
|
|
4
|
+
"purpur-color-dot": "_purpur-color-dot_ywkxi_1",
|
|
5
|
+
"purpur-color-dot--xs": "_purpur-color-dot--xs_ywkxi_11",
|
|
6
|
+
"purpur-color-dot--sm": "_purpur-color-dot--sm_ywkxi_14",
|
|
7
|
+
"purpur-color-dot--md": "_purpur-color-dot--md_ywkxi_17",
|
|
8
|
+
"purpur-color-dot--lg": "_purpur-color-dot--lg_ywkxi_20",
|
|
9
|
+
"purpur-color-dot--with-border": "_purpur-color-dot--with-border_ywkxi_23",
|
|
10
|
+
"purpur-color-dot--button": "_purpur-color-dot--button_ywkxi_26",
|
|
11
|
+
"purpur-color-dot--selected": "_purpur-color-dot--selected_ywkxi_29"
|
|
12
|
+
}, e = _.bind(s), r = "purpur-color-dot", p = ["xs", "sm", "md", "lg"], x = p.filter((t) => t !== "xs"), m = ({ size: t, withBorder: l, variant: u = "static", ...o }) => {
|
|
13
|
+
const d = e(o.className, r, `${r}--${t}`, {
|
|
14
|
+
[`${r}--with-border`]: l,
|
|
15
|
+
[`${r}--selected`]: o.isSelected,
|
|
16
|
+
[`${r}--button`]: u === "button"
|
|
17
|
+
});
|
|
18
|
+
return o.className = d, o.style = {
|
|
19
|
+
...o.style,
|
|
20
|
+
backgroundColor: o.color
|
|
21
|
+
}, u === "button" ? /* @__PURE__ */ c("button", { ...o }) : /* @__PURE__ */ c("div", { ...o });
|
|
22
|
+
};
|
|
23
|
+
export {
|
|
24
|
+
x as B,
|
|
25
|
+
m as C,
|
|
26
|
+
p as S
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=color-dot-Dz9yzVX3.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-dot-Dz9yzVX3.mjs","sources":["../../../components/color-dot/src/color-dot.tsx"],"sourcesContent":["import React, { type HTMLAttributes } from \"react\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./color-dot.module.scss\";\n\nconst cx = c.bind(styles);\nconst rootClassName = \"purpur-color-dot\";\n\nexport const STATIC_COLOR_DOT_SIZE = [\"xs\", \"sm\", \"md\", \"lg\"] as const;\nexport const BUTTON_COLOR_DOT_SIZE = STATIC_COLOR_DOT_SIZE.filter((size) => size !== \"xs\");\n\nexport type StaticColorDotSize = (typeof STATIC_COLOR_DOT_SIZE)[number];\nexport type ButtonColorDotSize = (typeof BUTTON_COLOR_DOT_SIZE)[number];\nexport type StaticColorDotProps = HTMLAttributes<HTMLDivElement> & {\n variant?: \"static\";\n isSelected?: never;\n size: StaticColorDotSize;\n};\n\nexport type ButtonColorDotProps = HTMLAttributes<HTMLButtonElement> & {\n variant?: \"button\";\n isSelected?: boolean;\n size: ButtonColorDotSize;\n};\n\nexport type ColorDotProps = {\n color: string;\n withBorder?: boolean;\n} & (StaticColorDotProps | ButtonColorDotProps);\n\nexport const ColorDot = ({ size, withBorder, variant = \"static\", ...props }: ColorDotProps) => {\n const className = cx(props.className, rootClassName, `${rootClassName}--${size}`, {\n [`${rootClassName}--with-border`]: withBorder,\n [`${rootClassName}--selected`]: props.isSelected,\n [`${rootClassName}--button`]: variant === \"button\",\n });\n\n props.className = className;\n props.style = {\n ...props.style,\n backgroundColor: props.color,\n };\n\n if (variant === \"button\") {\n return <button {...(props as ButtonColorDotProps)} />;\n }\n return <div {...(props as StaticColorDotProps)} />;\n};\n"],"names":["cx","c","styles","rootClassName","STATIC_COLOR_DOT_SIZE","BUTTON_COLOR_DOT_SIZE","size","ColorDot","withBorder","variant","props","className","jsx"],"mappings":";;;;;;;;;;;GAKMA,IAAKC,EAAE,KAAKC,CAAM,GAClBC,IAAgB,oBAETC,IAAwB,CAAC,MAAM,MAAM,MAAM,IAAI,GAC/CC,IAAwBD,EAAsB,OAAO,CAACE,MAASA,MAAS,IAAI,GAqB5EC,IAAW,CAAC,EAAE,MAAAD,GAAM,YAAAE,GAAY,SAAAC,IAAU,UAAU,GAAGC,QAA2B;AAC7F,QAAMC,IAAYX,EAAGU,EAAM,WAAWP,GAAe,GAAGA,CAAa,KAAKG,CAAI,IAAI;AAAA,IAChF,CAAC,GAAGH,CAAa,eAAe,GAAGK;AAAA,IACnC,CAAC,GAAGL,CAAa,YAAY,GAAGO,EAAM;AAAA,IACtC,CAAC,GAAGP,CAAa,UAAU,GAAGM,MAAY;AAAA,EAAA,CAC3C;AAQD,SANAC,EAAM,YAAYC,GAClBD,EAAM,QAAQ;AAAA,IACZ,GAAGA,EAAM;AAAA,IACT,iBAAiBA,EAAM;AAAA,EAAA,GAGrBD,MAAY,WACP,gBAAAG,EAAC,UAAA,EAAQ,GAAIF,EAAA,CAA+B,IAE9C,gBAAAE,EAAC,OAAA,EAAK,GAAIF,EAAA,CAA+B;AAClD;"}
|
package/dist/color-dot.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("./color-dot-BEE5rKco.js");exports.BUTTON_COLOR_DOT_SIZE=O.BUTTON_COLOR_DOT_SIZE;exports.ColorDot=O.ColorDot;exports.STATIC_COLOR_DOT_SIZE=O.STATIC_COLOR_DOT_SIZE;
|
|
2
2
|
//# sourceMappingURL=color-dot.cjs.js.map
|
package/dist/color-dot.es.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { B as _, C as o, S as C } from "./color-dot-Dz9yzVX3.mjs";
|
|
2
2
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
_ as BUTTON_COLOR_DOT_SIZE,
|
|
4
|
+
o as ColorDot,
|
|
5
|
+
C as STATIC_COLOR_DOT_SIZE
|
|
5
6
|
};
|
|
6
7
|
//# sourceMappingURL=color-dot.es.js.map
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { jsx as o, jsxs as u } from "react/jsx-runtime";
|
|
2
|
+
import { isValidElement as W, useRef as A, useState as V, useEffect as M, useCallback as C, useId as G, createElement as J } from "react";
|
|
3
|
+
import { c as D } from "./bind-CU-R61T-.mjs";
|
|
4
|
+
import { a as Q } from "./checkmark.es-DdgIZN2R.mjs";
|
|
5
|
+
import { e as U } from "./minus.es-BK9qA9iJ.mjs";
|
|
6
|
+
import { l as F } from "./chevron-down.es-PCIIj6oG.mjs";
|
|
7
|
+
import { P as q } from "./paragraph-DSxXmX_0.mjs";
|
|
8
|
+
import { a as X } from "./badge-DalD-yqG.mjs";
|
|
9
|
+
import { b as P } from "./button-4-yWOgtD.mjs";
|
|
10
|
+
import { H as Y } from "./heading-xwBuT_-9.mjs";
|
|
11
|
+
import { l as Z } from "./arrow-left.es-DU-PX-Il.mjs";
|
|
12
|
+
import { i as rr } from "./arrow-right.es-C7SkjAB6.mjs";
|
|
13
|
+
const er = {
|
|
14
|
+
"purpur-comparison-table__wrapper": "_purpur-comparison-table__wrapper_1udkj_1",
|
|
15
|
+
"purpur-comparison-table": "_purpur-comparison-table_1udkj_1",
|
|
16
|
+
"purpur-comparison-table--primary": "_purpur-comparison-table--primary_1udkj_11",
|
|
17
|
+
"purpur-comparison-table--secondary": "_purpur-comparison-table--secondary_1udkj_15",
|
|
18
|
+
"purpur-comparison-table__feature-row": "_purpur-comparison-table__feature-row_1udkj_32",
|
|
19
|
+
"purpur-comparison-table__cards": "_purpur-comparison-table__cards_1udkj_32",
|
|
20
|
+
"purpur-comparison-table__separator": "_purpur-comparison-table__separator_1udkj_49"
|
|
21
|
+
}, or = {
|
|
22
|
+
"purpur-comparison-table-cell": "_purpur-comparison-table-cell_17tn6_1",
|
|
23
|
+
"purpur-comparison-table-cell--check": "_purpur-comparison-table-cell--check_17tn6_16",
|
|
24
|
+
"purpur-comparison-table-cell--minus": "_purpur-comparison-table-cell--minus_17tn6_19",
|
|
25
|
+
"purpur-comparison-table-cell__icon": "_purpur-comparison-table-cell__icon_17tn6_22"
|
|
26
|
+
}, H = D.bind(or), L = "purpur-comparison-table-cell", tr = ({ value: t }) => {
|
|
27
|
+
const n = W(t) || ["string", "number"].includes(typeof t), a = H(L, [n ? "" : `${L}--${t ? "check" : "minus"}`]), y = t ? Q : U;
|
|
28
|
+
return /* @__PURE__ */ o("span", { className: H(a), children: n ? t : /* @__PURE__ */ o(y, { size: "xs", className: H(`${L}__icon`) }) });
|
|
29
|
+
}, ar = {
|
|
30
|
+
"purpur-comparison-table-lead-cell": "_purpur-comparison-table-lead-cell_rqs9w_1",
|
|
31
|
+
"purpur-comparison-table-lead-cell__description": "_purpur-comparison-table-lead-cell__description_rqs9w_5",
|
|
32
|
+
"purpur-comparison-table-lead-cell__summary": "_purpur-comparison-table-lead-cell__summary_rqs9w_40",
|
|
33
|
+
"purpur-comparison-table-lead-cell__summary-title": "_purpur-comparison-table-lead-cell__summary-title_rqs9w_48",
|
|
34
|
+
"purpur-comparison-table-lead-cell__summary-icon": "_purpur-comparison-table-lead-cell__summary-icon_rqs9w_51"
|
|
35
|
+
}, O = D.bind(ar), j = "purpur-comparison-table-lead-cell", sr = ({ title: t, description: n }) => {
|
|
36
|
+
const p = typeof n == "string", a = O(j);
|
|
37
|
+
return /* @__PURE__ */ u("details", { className: a, "data-is-expandable": p, children: [
|
|
38
|
+
/* @__PURE__ */ u("summary", { className: O(`${j}__summary`), tabIndex: p ? 0 : -1, children: [
|
|
39
|
+
/* @__PURE__ */ o(q, { className: O(`${j}__summary-title`), variant: "paragraph-100-bold", children: t }),
|
|
40
|
+
/* @__PURE__ */ o(F, { className: O(`${j}__summary-icon`), size: "sm" })
|
|
41
|
+
] }),
|
|
42
|
+
n && /* @__PURE__ */ o(q, { variant: "paragraph-100", className: O(`${j}__description`), children: n })
|
|
43
|
+
] });
|
|
44
|
+
}, nr = {
|
|
45
|
+
"purpur-comparison-table-option-card": "_purpur-comparison-table-option-card_18fdt_1",
|
|
46
|
+
"purpur-comparison-table-option-card--highlighted": "_purpur-comparison-table-option-card--highlighted_18fdt_11",
|
|
47
|
+
"purpur-comparison-table-option-card__badge": "_purpur-comparison-table-option-card__badge_18fdt_14",
|
|
48
|
+
"purpur-comparison-table-option-card__main-content": "_purpur-comparison-table-option-card__main-content_18fdt_19",
|
|
49
|
+
"purpur-comparison-table-option-card__image": "_purpur-comparison-table-option-card__image_18fdt_25",
|
|
50
|
+
"purpur-comparison-table-option-card__body": "_purpur-comparison-table-option-card__body_18fdt_31",
|
|
51
|
+
"purpur-comparison-table-option-card__description": "_purpur-comparison-table-option-card__description_18fdt_36",
|
|
52
|
+
"purpur-comparison-table-option-card__description-text": "_purpur-comparison-table-option-card__description-text_18fdt_41",
|
|
53
|
+
"purpur-comparison-table-option-card__read-more": "_purpur-comparison-table-option-card__read-more_18fdt_50",
|
|
54
|
+
"purpur-comparison-table-option-card__read-more--hidden": "_purpur-comparison-table-option-card__read-more--hidden_18fdt_54",
|
|
55
|
+
"purpur-comparison-table-option-card__read-more-icon": "_purpur-comparison-table-option-card__read-more-icon_18fdt_57",
|
|
56
|
+
"purpur-comparison-table-option-card__footer": "_purpur-comparison-table-option-card__footer_18fdt_65",
|
|
57
|
+
"purpur-comparison-table-option-card__price": "_purpur-comparison-table-option-card__price_18fdt_70",
|
|
58
|
+
"purpur-comparison-table-option-card--show-full-descriptions": "_purpur-comparison-table-option-card--show-full-descriptions_18fdt_77",
|
|
59
|
+
"purpur-comparison-table-option-card--first-card": "_purpur-comparison-table-option-card--first-card_18fdt_110"
|
|
60
|
+
}, m = D.bind(nr), c = "purpur-comparison-table-option-card", cr = ({
|
|
61
|
+
id: t,
|
|
62
|
+
cardIndex: n,
|
|
63
|
+
description: p,
|
|
64
|
+
variablePriceText: a,
|
|
65
|
+
price: y,
|
|
66
|
+
isHighlighted: f,
|
|
67
|
+
ariaLabels: g,
|
|
68
|
+
badge: h,
|
|
69
|
+
actions: N,
|
|
70
|
+
isFirstCard: I,
|
|
71
|
+
image: r,
|
|
72
|
+
title: i,
|
|
73
|
+
showFullDescriptions: _,
|
|
74
|
+
toggleShowFullDescriptions: d
|
|
75
|
+
}) => {
|
|
76
|
+
const l = A(null), s = A(null), e = A(_), [b, w] = V(!1), k = m(c, {
|
|
77
|
+
[`${c}--highlighted`]: f,
|
|
78
|
+
[`${c}--first-card`]: I,
|
|
79
|
+
[`${c}--show-full-descriptions`]: _
|
|
80
|
+
});
|
|
81
|
+
M(() => {
|
|
82
|
+
e.current = _;
|
|
83
|
+
}, [_]);
|
|
84
|
+
const S = C(() => {
|
|
85
|
+
if (e.current)
|
|
86
|
+
return;
|
|
87
|
+
const z = l.current, E = s.current;
|
|
88
|
+
if (!z || !E) {
|
|
89
|
+
w(!1);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const B = z.clientHeight, K = E.offsetHeight;
|
|
93
|
+
w(K > B + 1);
|
|
94
|
+
}, []);
|
|
95
|
+
M(() => {
|
|
96
|
+
const z = l.current;
|
|
97
|
+
if (S(), !z || typeof ResizeObserver > "u")
|
|
98
|
+
return;
|
|
99
|
+
const E = new ResizeObserver(S);
|
|
100
|
+
return E.observe(z), () => {
|
|
101
|
+
E.disconnect();
|
|
102
|
+
};
|
|
103
|
+
}, [S, p]);
|
|
104
|
+
const T = () => p ? /* @__PURE__ */ u("div", { className: m(`${c}__description`), children: [
|
|
105
|
+
/* @__PURE__ */ o(q, { ref: l, className: m(`${c}__description-text`), children: /* @__PURE__ */ o("span", { ref: s, children: p }) }),
|
|
106
|
+
/* @__PURE__ */ u(
|
|
107
|
+
P,
|
|
108
|
+
{
|
|
109
|
+
variant: "text",
|
|
110
|
+
size: "xs",
|
|
111
|
+
className: m(`${c}__read-more`, {
|
|
112
|
+
[`${c}__read-more--hidden`]: !b
|
|
113
|
+
}),
|
|
114
|
+
onClick: d,
|
|
115
|
+
"aria-hidden": !b,
|
|
116
|
+
tabIndex: b ? void 0 : -1,
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ o("span", { className: m(`${c}__read-more-text`), children: _ ? g.readLess : g.readMore }),
|
|
119
|
+
/* @__PURE__ */ o(F, { className: m(`${c}__read-more-icon`), size: "xs" })
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] }) : null;
|
|
124
|
+
return /* @__PURE__ */ u("article", { className: k, "data-card-id": t, "data-card-index": n, children: [
|
|
125
|
+
h && /* @__PURE__ */ o(X, { ...h, className: m(`${c}__badge`) }),
|
|
126
|
+
/* @__PURE__ */ u("section", { className: m(`${c}__main-content`), children: [
|
|
127
|
+
/* @__PURE__ */ o("img", { src: r.src, alt: r.alt, className: m(`${c}__image`) }),
|
|
128
|
+
/* @__PURE__ */ u("div", { className: m(`${c}__body`), children: [
|
|
129
|
+
/* @__PURE__ */ o(Y, { tag: "h3", variant: "title-200", className: m(`${c}__title`), children: i }),
|
|
130
|
+
T()
|
|
131
|
+
] })
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ u("footer", { className: m(`${c}__footer`), children: [
|
|
134
|
+
/* @__PURE__ */ u("span", { className: m(`${c}__price`), id: t, children: [
|
|
135
|
+
/* @__PURE__ */ o(q, { variant: "paragraph-100", children: a }),
|
|
136
|
+
/* @__PURE__ */ o(q, { variant: "paragraph-100-bold", children: y })
|
|
137
|
+
] }),
|
|
138
|
+
N
|
|
139
|
+
] })
|
|
140
|
+
] });
|
|
141
|
+
}, ir = "_active_kvsnm_44", pr = {
|
|
142
|
+
"purpur-comparison-table-scroll-progress": "_purpur-comparison-table-scroll-progress_kvsnm_1",
|
|
143
|
+
"purpur-comparison-table-scroll-progress__indicators": "_purpur-comparison-table-scroll-progress__indicators_kvsnm_15",
|
|
144
|
+
"purpur-comparison-table-scroll-progress__indicator": "_purpur-comparison-table-scroll-progress__indicator_kvsnm_15",
|
|
145
|
+
active: ir,
|
|
146
|
+
"purpur-comparison-table-scroll-progress__buttons": "_purpur-comparison-table-scroll-progress__buttons_kvsnm_48",
|
|
147
|
+
"purpur-comparison-table-scroll-progress__button": "_purpur-comparison-table-scroll-progress__button_kvsnm_48",
|
|
148
|
+
"purpur-comparison-table-scroll-progress__button-icon": "_purpur-comparison-table-scroll-progress__button-icon_kvsnm_57"
|
|
149
|
+
}, $ = D.bind(pr), v = "purpur-comparison-table-scroll-progress", lr = ({ items: t, container: n, ariaLabels: p }) => {
|
|
150
|
+
const [a, y] = V(/* @__PURE__ */ new Set()), f = C(
|
|
151
|
+
(r) => {
|
|
152
|
+
const i = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
153
|
+
n.current?.querySelector(
|
|
154
|
+
`[data-card-index="${r}"]`
|
|
155
|
+
)?.scrollIntoView({ behavior: i ? "instant" : "smooth", block: "nearest" });
|
|
156
|
+
},
|
|
157
|
+
[n]
|
|
158
|
+
), g = C(() => {
|
|
159
|
+
if (a.size === 0) return;
|
|
160
|
+
const i = Math.min(...Array.from(a)) - 1;
|
|
161
|
+
i < 0 || f(i);
|
|
162
|
+
}, [a, f]), h = C(() => {
|
|
163
|
+
if (a.size === 0) return;
|
|
164
|
+
const i = Math.max(...Array.from(a)) + 1;
|
|
165
|
+
i >= t.length || f(i);
|
|
166
|
+
}, [a, t.length, f]), N = C(
|
|
167
|
+
(r) => {
|
|
168
|
+
(r.key === "ArrowRight" || r.key === "ArrowLeft") && (r.preventDefault(), r.key === "ArrowRight" ? h() : r.key === "ArrowLeft" && g());
|
|
169
|
+
},
|
|
170
|
+
[h, g]
|
|
171
|
+
);
|
|
172
|
+
M(() => {
|
|
173
|
+
const r = n.current;
|
|
174
|
+
if (!r) return;
|
|
175
|
+
const i = new IntersectionObserver(
|
|
176
|
+
(_) => {
|
|
177
|
+
y((d) => {
|
|
178
|
+
const l = new Set(d);
|
|
179
|
+
return _.forEach((s) => {
|
|
180
|
+
const e = Number(s.target.getAttribute("data-card-index"));
|
|
181
|
+
Number.isNaN(e) || (s.isIntersecting ? l.add(e) : l.delete(e));
|
|
182
|
+
}), l;
|
|
183
|
+
});
|
|
184
|
+
},
|
|
185
|
+
{ root: r, threshold: 0.5 }
|
|
186
|
+
);
|
|
187
|
+
return t.forEach((_, d) => {
|
|
188
|
+
const l = r.querySelector(`[data-card-index="${d}"]`);
|
|
189
|
+
l && i.observe(l);
|
|
190
|
+
}), () => i.disconnect();
|
|
191
|
+
}, [n, t]), M(() => {
|
|
192
|
+
const r = n.current;
|
|
193
|
+
if (r)
|
|
194
|
+
return r.addEventListener("keydown", N), () => r.removeEventListener("keydown", N);
|
|
195
|
+
}, [n, N]);
|
|
196
|
+
const I = () => {
|
|
197
|
+
if (a.size === 0) return;
|
|
198
|
+
const r = [], i = a.size, _ = Math.min(...Array.from(a)), d = t.slice(0, _).length, l = t.slice(_ + i).length;
|
|
199
|
+
let s = 0;
|
|
200
|
+
for (let e = 0; e < t.length; e++) {
|
|
201
|
+
if (d + 1 !== e && d <= e && e < t.length - l) continue;
|
|
202
|
+
let b = "active";
|
|
203
|
+
(e < d || e > t.length - 1 - l) && (b = ""), r.push(
|
|
204
|
+
/* @__PURE__ */ o("li", { className: $(`${v}__indicator`, b) }, `indicator-${s++}`)
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
return r.length < 2 ? null : r;
|
|
208
|
+
};
|
|
209
|
+
return /* @__PURE__ */ u("li", { className: $(v), children: [
|
|
210
|
+
/* @__PURE__ */ o("ul", { className: $(`${v}__indicators`), children: I() }),
|
|
211
|
+
/* @__PURE__ */ u("div", { className: $(`${v}__buttons`), children: [
|
|
212
|
+
/* @__PURE__ */ o(
|
|
213
|
+
P,
|
|
214
|
+
{
|
|
215
|
+
"aria-label": p.previous,
|
|
216
|
+
variant: "secondary",
|
|
217
|
+
iconOnly: !0,
|
|
218
|
+
className: $(`${v}__button`),
|
|
219
|
+
disabled: a.has(0),
|
|
220
|
+
onClick: g,
|
|
221
|
+
children: /* @__PURE__ */ o(Z, { className: $(`${v}__button-icon`), size: "xs" })
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
/* @__PURE__ */ o(
|
|
225
|
+
P,
|
|
226
|
+
{
|
|
227
|
+
"aria-label": p.next,
|
|
228
|
+
variant: "secondary",
|
|
229
|
+
iconOnly: !0,
|
|
230
|
+
className: $(`${v}__button`),
|
|
231
|
+
disabled: a.has(t.length - 1),
|
|
232
|
+
onClick: h,
|
|
233
|
+
children: /* @__PURE__ */ o(rr, { className: $(`${v}__button-icon`), size: "xs" })
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
] })
|
|
237
|
+
] });
|
|
238
|
+
}, R = D.bind(er), x = "purpur-comparison-table", _r = ({
|
|
239
|
+
classname: t,
|
|
240
|
+
features: n,
|
|
241
|
+
items: p,
|
|
242
|
+
ariaLabels: a,
|
|
243
|
+
variant: y = "primary"
|
|
244
|
+
}) => {
|
|
245
|
+
const f = G(), g = R(t, x, `${x}--${y}`), h = A(null), [N, I] = V(!1), r = C(() => {
|
|
246
|
+
I((s) => !s);
|
|
247
|
+
}, []), i = () => /* @__PURE__ */ u("li", { className: R(`${x}__cards`), children: [
|
|
248
|
+
/* @__PURE__ */ o("div", { className: R(`${x}__separator`) }),
|
|
249
|
+
p.map((s, e) => /* @__PURE__ */ J(
|
|
250
|
+
cr,
|
|
251
|
+
{
|
|
252
|
+
...s,
|
|
253
|
+
showFullDescriptions: N,
|
|
254
|
+
toggleShowFullDescriptions: r,
|
|
255
|
+
key: e,
|
|
256
|
+
isFirstCard: e === 0,
|
|
257
|
+
ariaLabels: a,
|
|
258
|
+
cardIndex: e,
|
|
259
|
+
id: `${e}-${f}`
|
|
260
|
+
}
|
|
261
|
+
))
|
|
262
|
+
] }), _ = () => Object.entries(n).map(([s, e], b) => /* @__PURE__ */ u("li", { className: R(`${x}__feature-row`), children: [
|
|
263
|
+
/* @__PURE__ */ o(sr, { title: s, description: e }),
|
|
264
|
+
p.map((w, k) => /* @__PURE__ */ o(tr, { value: w.features[s] ?? !1 }, k))
|
|
265
|
+
] }, b)), d = A(0), l = (s) => {
|
|
266
|
+
const e = s.currentTarget, b = e.querySelector("[data-card-id]")?.clientWidth ?? 0, w = Math.round(e.scrollLeft / b), k = w * b + w, S = s.timeStamp - d.current, T = Math.abs(e.scrollLeft - k);
|
|
267
|
+
d.current && S < 200 || T < 10 || (d.current = s.timeStamp, e.scrollTo({ left: k, behavior: "smooth" }));
|
|
268
|
+
};
|
|
269
|
+
return /* @__PURE__ */ o("div", { className: R(x + "__wrapper"), children: /* @__PURE__ */ u(
|
|
270
|
+
"ul",
|
|
271
|
+
{
|
|
272
|
+
id: x + `-${f}`,
|
|
273
|
+
ref: h,
|
|
274
|
+
className: g,
|
|
275
|
+
onScrollEnd: l,
|
|
276
|
+
style: {
|
|
277
|
+
// @ts-expect-error | Typescript doesn't recognize the CSS variable, but it works as intended
|
|
278
|
+
"--initial-columns": p.length + 1
|
|
279
|
+
},
|
|
280
|
+
children: [
|
|
281
|
+
/* @__PURE__ */ o(lr, { items: p, container: h, ariaLabels: a }),
|
|
282
|
+
i(),
|
|
283
|
+
_()
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
) });
|
|
287
|
+
};
|
|
288
|
+
_r.displayName = "ComparisonTable";
|
|
289
|
+
export {
|
|
290
|
+
_r as C
|
|
291
|
+
};
|
|
292
|
+
//# sourceMappingURL=comparison-table-CZMKl1TX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparison-table-CZMKl1TX.mjs","sources":["../../../components/comparison-table/src/components/Cell/cell.tsx","../../../components/comparison-table/src/components/LeadCell/lead-cell.tsx","../../../components/comparison-table/src/components/OptionCard/option-card.tsx","../../../components/comparison-table/src/components/ScrollProgress/scroll-progress.tsx","../../../components/comparison-table/src/comparison-table.tsx"],"sourcesContent":["import React, { isValidElement, type ReactNode } from \"react\";\nimport { IconCheckmark } from \"@purpur/icon/checkmark\";\nimport { IconMinus } from \"@purpur/icon/minus\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./cell.module.scss\";\n\ntype CellProps = {\n value: boolean | ReactNode;\n};\n\nconst cx = c.bind(styles);\n\nconst rootClassName = \"purpur-comparison-table-cell\";\n\nexport const Cell = ({ value }: CellProps) => {\n const isReactNode = isValidElement(value) || [\"string\", \"number\"].includes(typeof value);\n\n const getClassName = () => {\n if (isReactNode) return \"\";\n return `${rootClassName}--${value ? \"check\" : \"minus\"}`;\n };\n\n const classes = cx(rootClassName, [getClassName()]);\n\n const Icon = value ? IconCheckmark : IconMinus;\n\n return (\n <span className={cx(classes)}>\n {isReactNode ? value : <Icon size=\"xs\" className={cx(`${rootClassName}__icon`)} />}\n </span>\n );\n};\n","import React, { type ReactNode } from \"react\";\nimport { IconChevronDown } from \"@purpur/icon/chevron-down\";\nimport { Paragraph } from \"@purpur/paragraph\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./lead-cell.module.scss\";\n\ntype LeadCellProps = {\n title: string;\n description?: ReactNode;\n};\n\nconst cx = c.bind(styles);\n\nconst rootClassName = \"purpur-comparison-table-lead-cell\";\n\nexport const LeadCell = ({ title, description }: LeadCellProps) => {\n const isExpandable = typeof description === \"string\";\n const classes = cx(rootClassName);\n\n return (\n <details className={classes} data-is-expandable={isExpandable}>\n <summary className={cx(`${rootClassName}__summary`)} tabIndex={isExpandable ? 0 : -1}>\n <Paragraph className={cx(`${rootClassName}__summary-title`)} variant=\"paragraph-100-bold\">\n {title}\n </Paragraph>\n <IconChevronDown className={cx(`${rootClassName}__summary-icon`)} size=\"sm\" />\n </summary>\n {description && (\n <Paragraph variant=\"paragraph-100\" className={cx(`${rootClassName}__description`)}>\n {description}\n </Paragraph>\n )}\n </details>\n );\n};\n","import React, { type ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { Badge, type BadgeProps } from \"@purpur/badge\";\nimport { Button } from \"@purpur/button\";\nimport { Heading } from \"@purpur/heading\";\nimport { IconChevronDown } from \"@purpur/icon/chevron-down\";\nimport { Paragraph } from \"@purpur/paragraph\";\nimport c from \"classnames/bind\";\n\nimport { type ComparisonTableProps } from \"../../comparison-table\";\nimport styles from \"./option-card.module.scss\";\n\nconst cx = c.bind(styles);\n\nconst rootClassName = \"purpur-comparison-table-option-card\";\n\nexport type OptionCardProps = {\n image: {\n src: string;\n alt: string;\n };\n\n title: string;\n description: string;\n variablePriceText: string;\n price: string;\n\n actions: ReactNode;\n\n badge?: BadgeProps;\n isHighlighted?: boolean;\n};\n\ntype OptionCardPropsAdditions = {\n id: string;\n cardIndex: number;\n isFirstCard: boolean;\n ariaLabels: ComparisonTableProps[\"ariaLabels\"];\n\n showFullDescriptions: boolean;\n toggleShowFullDescriptions: () => void;\n};\n\nexport const OptionCard = ({\n id,\n cardIndex,\n description,\n variablePriceText,\n price,\n isHighlighted,\n ariaLabels,\n badge,\n actions,\n isFirstCard,\n image,\n title,\n showFullDescriptions,\n toggleShowFullDescriptions,\n}: OptionCardProps & OptionCardPropsAdditions) => {\n const descriptionRef = useRef<HTMLParagraphElement>(null);\n const descriptionContentRef = useRef<HTMLSpanElement>(null);\n const showFullDescriptionsRef = useRef(showFullDescriptions);\n const [descriptionOverflows, setDescriptionOverflows] = useState(false);\n\n const classes = cx(rootClassName, {\n [`${rootClassName}--highlighted`]: isHighlighted,\n [`${rootClassName}--first-card`]: isFirstCard,\n [`${rootClassName}--show-full-descriptions`]: showFullDescriptions,\n });\n\n useEffect(() => {\n showFullDescriptionsRef.current = showFullDescriptions;\n }, [showFullDescriptions]);\n\n const checkDescriptionOverflow = useCallback(() => {\n if (showFullDescriptionsRef.current) {\n return;\n }\n\n const description = descriptionRef.current;\n const descriptionContent = descriptionContentRef.current;\n\n if (!description || !descriptionContent) {\n setDescriptionOverflows(false);\n return;\n }\n\n const descriptionHeight = description.clientHeight;\n const contentHeight = descriptionContent.offsetHeight;\n\n setDescriptionOverflows(contentHeight > descriptionHeight + 1);\n }, []);\n\n useEffect(() => {\n const descriptionElement = descriptionRef.current;\n\n checkDescriptionOverflow();\n\n if (!descriptionElement || typeof ResizeObserver === \"undefined\") {\n return undefined;\n }\n\n const resizeObserver = new ResizeObserver(checkDescriptionOverflow);\n resizeObserver.observe(descriptionElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [checkDescriptionOverflow, description]);\n\n const renderDescription = () => {\n if (!description) return null;\n\n return (\n <div className={cx(`${rootClassName}__description`)}>\n <Paragraph ref={descriptionRef} className={cx(`${rootClassName}__description-text`)}>\n <span ref={descriptionContentRef}>{description}</span>\n </Paragraph>\n <Button\n variant=\"text\"\n size=\"xs\"\n className={cx(`${rootClassName}__read-more`, {\n [`${rootClassName}__read-more--hidden`]: !descriptionOverflows,\n })}\n onClick={toggleShowFullDescriptions}\n aria-hidden={!descriptionOverflows}\n tabIndex={descriptionOverflows ? undefined : -1}\n >\n <span className={cx(`${rootClassName}__read-more-text`)}>\n {showFullDescriptions ? ariaLabels.readLess : ariaLabels.readMore}\n </span>\n <IconChevronDown className={cx(`${rootClassName}__read-more-icon`)} size=\"xs\" />\n </Button>\n </div>\n );\n };\n\n return (\n <article className={classes} data-card-id={id} data-card-index={cardIndex}>\n {badge && <Badge {...badge} className={cx(`${rootClassName}__badge`)} />}\n\n <section className={cx(`${rootClassName}__main-content`)}>\n <img src={image.src} alt={image.alt} className={cx(`${rootClassName}__image`)} />\n\n <div className={cx(`${rootClassName}__body`)}>\n <Heading tag=\"h3\" variant=\"title-200\" className={cx(`${rootClassName}__title`)}>\n {title}\n </Heading>\n {renderDescription()}\n </div>\n </section>\n\n <footer className={cx(`${rootClassName}__footer`)}>\n <span className={cx(`${rootClassName}__price`)} id={id}>\n <Paragraph variant=\"paragraph-100\">{variablePriceText}</Paragraph>\n <Paragraph variant=\"paragraph-100-bold\">{price}</Paragraph>\n </span>\n\n {actions}\n </footer>\n </article>\n );\n};\n","import React, { type RefObject, useCallback, useEffect, useState } from \"react\";\nimport { Button } from \"@purpur/button\";\nimport { IconArrowLeft } from \"@purpur/icon/arrow-left\";\nimport { IconArrowRight } from \"@purpur/icon/arrow-right\";\nimport c from \"classnames/bind\";\n\nimport { type ComparisonTableProps, type Features, type Item } from \"../../comparison-table\";\nimport styles from \"./scroll-progress.module.scss\";\n\nconst cx = c.bind(styles);\nconst rootClassName = \"purpur-comparison-table-scroll-progress\";\n\ntype ScrollProgressProps = {\n items: Array<Item<Features>>;\n container: RefObject<HTMLUListElement | null>;\n ariaLabels: ComparisonTableProps[\"ariaLabels\"];\n};\n\nexport const ScrollProgress = ({ items, container, ariaLabels }: ScrollProgressProps) => {\n const [inViewSet, setInViewSet] = useState<Set<number>>(new Set());\n\n const scrollToCard = useCallback(\n (index: number) => {\n const reduceMotion = window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\n const card = container.current?.querySelector(\n `[data-card-index=\"${index}\"]`\n ) as HTMLElement | null;\n card?.scrollIntoView({ behavior: reduceMotion ? \"instant\" : \"smooth\", block: \"nearest\" });\n },\n [container]\n );\n\n const previousCard = useCallback(() => {\n if (inViewSet.size === 0) return;\n\n const leftmostactiveIndex = Math.min(...Array.from(inViewSet));\n const targetIndex = leftmostactiveIndex - 1;\n\n if (targetIndex < 0) return;\n\n scrollToCard(targetIndex);\n }, [inViewSet, scrollToCard]);\n\n const nextCard = useCallback(() => {\n if (inViewSet.size === 0) return;\n\n const rightmostactiveIndex = Math.max(...Array.from(inViewSet));\n const targetIndex = rightmostactiveIndex + 1;\n\n if (targetIndex >= items.length) return;\n\n scrollToCard(targetIndex);\n }, [inViewSet, items.length, scrollToCard]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"ArrowRight\" || e.key === \"ArrowLeft\") {\n e.preventDefault();\n\n if (e.key === \"ArrowRight\") nextCard();\n else if (e.key === \"ArrowLeft\") previousCard();\n }\n },\n [nextCard, previousCard]\n );\n\n useEffect(() => {\n const root = container.current;\n\n if (!root) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n setInViewSet((prev) => {\n const next = new Set(prev);\n\n entries.forEach((entry) => {\n const index = Number(entry.target.getAttribute(\"data-card-index\"));\n\n if (Number.isNaN(index)) return;\n\n if (entry.isIntersecting) {\n next.add(index);\n } else {\n next.delete(index);\n }\n });\n return next;\n });\n },\n { root, threshold: 0.5 }\n );\n\n items.forEach((_, index) => {\n const card = root.querySelector(`[data-card-index=\"${index}\"]`) as HTMLElement | null;\n\n if (card) observer.observe(card);\n });\n\n return () => observer.disconnect();\n }, [container, items]);\n\n useEffect(() => {\n const root = container.current;\n\n if (!root) return;\n\n root.addEventListener(\"keydown\", handleKeyDown);\n\n return () => root.removeEventListener(\"keydown\", handleKeyDown);\n }, [container, handleKeyDown]);\n\n const renderIndicators = () => {\n if (inViewSet.size === 0) return;\n\n const indicators = [];\n const viewCapacity = inViewSet.size;\n const leftmostActiveIndex = Math.min(...Array.from(inViewSet));\n const head = items.slice(0, leftmostActiveIndex).length;\n const trail = items.slice(leftmostActiveIndex + viewCapacity).length;\n\n let key = 0;\n\n for (let i = 0; i < items.length; i++) {\n if (head + 1 !== i && head <= i && i < items.length - trail) continue;\n\n let status = \"active\";\n\n if (i < head || i > items.length - 1 - trail) status = \"\";\n\n indicators.push(\n <li key={`indicator-${key++}`} className={cx(`${rootClassName}__indicator`, status)} />\n );\n }\n\n if (indicators.length < 2) return null;\n\n return indicators;\n };\n\n return (\n <li className={cx(rootClassName)}>\n <ul className={cx(`${rootClassName}__indicators`)}>{renderIndicators()}</ul>\n\n <div className={cx(`${rootClassName}__buttons`)}>\n <Button\n aria-label={ariaLabels.previous}\n variant=\"secondary\"\n iconOnly\n className={cx(`${rootClassName}__button`)}\n disabled={inViewSet.has(0)}\n onClick={previousCard}\n >\n <IconArrowLeft className={cx(`${rootClassName}__button-icon`)} size=\"xs\" />\n </Button>\n <Button\n aria-label={ariaLabels.next}\n variant=\"secondary\"\n iconOnly\n className={cx(`${rootClassName}__button`)}\n disabled={inViewSet.has(items.length - 1)}\n onClick={nextCard}\n >\n <IconArrowRight className={cx(`${rootClassName}__button-icon`)} size=\"xs\" />\n </Button>\n </div>\n </li>\n );\n};\n","import React, { type ReactNode, type UIEvent, useCallback, useId, useRef, useState } from \"react\";\nimport c from \"classnames/bind\";\n\nimport styles from \"./comparison-table.module.scss\";\nimport { Cell } from \"./components/Cell/cell\";\nimport { LeadCell } from \"./components/LeadCell/lead-cell\";\nimport { OptionCard, type OptionCardProps } from \"./components/OptionCard/option-card\";\nimport { ScrollProgress } from \"./components/ScrollProgress/scroll-progress\";\n\nconst cx = c.bind(styles);\n\nconst rootClassName = \"purpur-comparison-table\";\n\nexport type Features = Record<string, ReactNode | null>;\n\nexport type Item<TFeatures extends Features = Features> = OptionCardProps & {\n features: Partial<Record<keyof TFeatures, ReactNode | string | boolean>>;\n};\n\nexport type ComparisonTableProps<TFeatures extends Features = Features> = {\n /** List of features that can be supported by the comparison table\n *\n * string = description of the feature that can be viewed by expanding cell.\n *\n * null = no description\n *\n {\n [featureName]: ReactNode | null\n }\n */\n features: TFeatures;\n\n /** List of items to be displayed in the comparison table\n *\n *\n Item = {\n image: {\n src: string;\n alt: string;\n };\n\n title: string;\n description: string;\n variablePriceText: string;\n price: string;\n actions: ReactNode;\n badge?: BadgeProps;\n isHighlighted?: boolean;\n\n features: {\n [featureName in keyof Features]?: string | boolean;\n };\n }\n */\n items: Array<Item<TFeatures>>;\n\n /** Aria labels for the comparison table and various components\n *\n {\n previous: string;\n next: string;\n readMore: string;\n readLess: string;\n }\n */\n ariaLabels: {\n previous: string;\n next: string;\n readMore: string;\n readLess: string;\n };\n variant?: \"primary\" | \"secondary\";\n classname?: string;\n};\n\nexport const ComparisonTable = <TFeatures extends Features>({\n classname,\n features,\n items,\n ariaLabels,\n variant = \"primary\",\n}: ComparisonTableProps<TFeatures>) => {\n const id = useId();\n const classes = cx(classname, rootClassName, `${rootClassName}--${variant}`);\n const containerRef = useRef<HTMLUListElement>(null);\n const [showFullDescriptions, setShowFullDescriptions] = useState(false);\n\n const handleToggleShowFullDescriptions = useCallback(() => {\n setShowFullDescriptions((prev) => !prev);\n }, []);\n\n const renderCards = () => {\n return (\n <li className={cx(`${rootClassName}__cards`)}>\n <div className={cx(`${rootClassName}__separator`)} />\n {items.map((item, index) => (\n <OptionCard\n {...item}\n showFullDescriptions={showFullDescriptions}\n toggleShowFullDescriptions={handleToggleShowFullDescriptions}\n key={index}\n isFirstCard={index === 0}\n ariaLabels={ariaLabels}\n cardIndex={index}\n id={`${index}-${id}`}\n />\n ))}\n </li>\n );\n };\n\n const renderFeatures = () => {\n return Object.entries(features).map(([title, description], i) => (\n <li key={i} className={cx(`${rootClassName}__feature-row`)}>\n <LeadCell title={title} description={description} />\n {items.map((item, index) => (\n <Cell key={index} value={item.features[title as keyof TFeatures] ?? false} />\n ))}\n </li>\n ));\n };\n\n const deltaTime = useRef(0);\n\n const handleScrollEnd = (e: UIEvent<HTMLUListElement>) => {\n /**\n * This function makes sure that the scroll position is never stuck between two cards, since scroll snap is not fully reliable.\n */\n\n const target = e.currentTarget;\n const cardwidth = target.querySelector(\"[data-card-id]\")?.clientWidth ?? 0;\n const cardPos = Math.round(target.scrollLeft / cardwidth);\n const scrollTarget = cardPos * cardwidth + cardPos;\n const timeDiff = e.timeStamp - deltaTime.current;\n const scrollDiff = Math.abs(target.scrollLeft - scrollTarget);\n\n if (deltaTime.current && timeDiff < 200) return;\n if (scrollDiff < 10) return;\n\n deltaTime.current = e.timeStamp;\n\n target.scrollTo({ left: scrollTarget, behavior: \"smooth\" });\n };\n\n return (\n <div className={cx(rootClassName + \"__wrapper\")}>\n <ul\n id={rootClassName + `-${id}`}\n ref={containerRef}\n className={classes}\n // eslint-disable-next-line react/no-unknown-property\n onScrollEnd={handleScrollEnd}\n style={{\n // @ts-expect-error | Typescript doesn't recognize the CSS variable, but it works as intended\n [\"--initial-columns\"]: items.length + 1,\n }}\n >\n <ScrollProgress items={items} container={containerRef} ariaLabels={ariaLabels} />\n {renderCards()}\n {renderFeatures()}\n </ul>\n </div>\n );\n};\n\nComparisonTable.displayName = \"ComparisonTable\";\n"],"names":["cx","c","styles","rootClassName","Cell","value","isReactNode","isValidElement","classes","Icon","IconCheckmark","IconMinus","jsx","LeadCell","title","description","isExpandable","jsxs","Paragraph","IconChevronDown","OptionCard","id","cardIndex","variablePriceText","price","isHighlighted","ariaLabels","badge","actions","isFirstCard","image","showFullDescriptions","toggleShowFullDescriptions","descriptionRef","useRef","descriptionContentRef","showFullDescriptionsRef","descriptionOverflows","setDescriptionOverflows","useState","useEffect","checkDescriptionOverflow","useCallback","descriptionContent","descriptionHeight","contentHeight","descriptionElement","resizeObserver","renderDescription","Button","Badge","Heading","ScrollProgress","items","container","inViewSet","setInViewSet","scrollToCard","index","reduceMotion","previousCard","targetIndex","nextCard","handleKeyDown","e","root","observer","entries","prev","next","entry","card","renderIndicators","indicators","viewCapacity","leftmostActiveIndex","head","trail","key","i","status","IconArrowLeft","IconArrowRight","ComparisonTable","classname","features","variant","useId","containerRef","setShowFullDescriptions","handleToggleShowFullDescriptions","renderCards","item","createElement","renderFeatures","deltaTime","handleScrollEnd","target","cardwidth","cardPos","scrollTarget","timeDiff","scrollDiff"],"mappings":"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"}
|