@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
1 lines • 6.07 kB
Source Map (JSON)
{"version":3,"file":"Spoiler.cjs","names":["createVarsResolver","factory","useProps","useStyles","Box","Anchor","rem","classes"],"sources":["../../../src/components/Spoiler/Spoiler.tsx"],"sourcesContent":["import { useElementSize, useId, useUncontrolled } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n rem,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport { Anchor } from '../Anchor';\nimport classes from './Spoiler.module.css';\n\nexport type SpoilerStylesNames = 'root' | 'control' | 'content';\nexport type SpoilerCssVariables = {\n root: '--spoiler-transition-duration';\n};\n\nexport interface SpoilerProps\n extends BoxProps, StylesApiProps<SpoilerFactory>, ElementProps<'div'> {\n /** Maximum height of visible content in px. When content exceeds this height, the toggle control appears @default 100 */\n maxHeight?: number;\n\n /** Content displayed in the toggle button when content is collapsed (to expand) */\n showLabel: React.ReactNode;\n\n /** Content displayed in the toggle button when content is expanded (to collapse) */\n hideLabel: React.ReactNode;\n\n /** Ref of the toggle button element */\n controlRef?: React.Ref<HTMLButtonElement>;\n\n /** Initial expanded state in uncontrolled mode. If `true`, content starts expanded. If `false`, content starts collapsed @default false */\n defaultExpanded?: boolean;\n\n /** Controlled expanded state value */\n expanded?: boolean;\n\n /** Called when expanded state changes (when spoiler visibility is toggled by the user) */\n onExpandedChange?: (expanded: boolean) => void;\n\n /** Spoiler reveal transition duration in ms. Set to 0 to disable animation @default 200 */\n transitionDuration?: number;\n\n /** Accessible label for the toggle button when collapsed. If not set, `showLabel` is used */\n showAriaLabel?: string;\n\n /** Accessible label for the toggle button when expanded. If not set, `hideLabel` is used */\n hideAriaLabel?: string;\n}\n\nexport type SpoilerFactory = Factory<{\n props: SpoilerProps;\n ref: HTMLDivElement;\n stylesNames: SpoilerStylesNames;\n vars: SpoilerCssVariables;\n}>;\n\nconst defaultProps = {\n maxHeight: 100,\n defaultExpanded: false,\n} satisfies Partial<SpoilerProps>;\n\nconst varsResolver = createVarsResolver<SpoilerFactory>((_, { transitionDuration }) => ({\n root: {\n '--spoiler-transition-duration':\n transitionDuration !== undefined ? `${transitionDuration}ms` : undefined,\n },\n}));\n\nexport const Spoiler = factory<SpoilerFactory>((_props) => {\n const props = useProps('Spoiler', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n defaultExpanded,\n maxHeight,\n hideLabel,\n showLabel,\n children,\n controlRef,\n transitionDuration,\n id,\n expanded,\n onExpandedChange,\n showAriaLabel,\n hideAriaLabel,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<SpoilerFactory>({\n name: 'Spoiler',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const _id = useId(id);\n const regionId = `${_id}-region`;\n const [show, setShowState] = useUncontrolled({\n value: expanded,\n defaultValue: defaultExpanded,\n finalValue: false,\n onChange: onExpandedChange,\n });\n const { ref: contentRef, height } = useElementSize();\n const spoilerMoreContent = show ? hideLabel : showLabel;\n const spoiler = spoilerMoreContent !== null && maxHeight! < height;\n const ariaLabel = show ? hideAriaLabel : showAriaLabel;\n\n return (\n <Box {...getStyles('root')} id={_id} data-has-spoiler={spoiler || undefined} {...others}>\n {spoiler && (\n <Anchor\n component=\"button\"\n type=\"button\"\n ref={controlRef}\n onClick={() => setShowState(!show)}\n aria-expanded={show}\n aria-controls={regionId}\n aria-label={ariaLabel}\n {...getStyles('control')}\n >\n {spoilerMoreContent}\n </Anchor>\n )}\n <div\n {...getStyles('content', {\n style: { maxHeight: !show ? rem(maxHeight) : height ? rem(height) : undefined },\n })}\n data-reduce-motion\n role=\"region\"\n id={regionId}\n >\n <div ref={contentRef}>{children}</div>\n </div>\n </Box>\n );\n});\n\nSpoiler.classes = classes;\nSpoiler.varsResolver = varsResolver;\nSpoiler.displayName = '@mantine/core/Spoiler';\n"],"mappings":";;;;;;;;;;;;;AA6DA,MAAM,eAAe;CACnB,WAAW;CACX,iBAAiB;CAClB;AAED,MAAM,eAAeA,6BAAAA,oBAAoC,GAAG,EAAE,0BAA0B,EACtF,MAAM,EACJ,iCACE,uBAAuB,KAAA,IAAY,GAAG,mBAAmB,MAAM,KAAA,GAClE,EACF,EAAE;AAEH,MAAa,UAAUC,gBAAAA,SAAyB,WAAW;CACzD,MAAM,QAAQC,kBAAAA,SAAS,WAAW,cAAc,OAAO;CACvD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,iBACA,WACA,WACA,WACA,UACA,YACA,oBACA,IACA,UACA,kBACA,eACA,eACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAYC,mBAAAA,UAA0B;EAC1C,MAAM;EACN,SAAA,uBAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,OAAA,GAAA,eAAA,OAAY,GAAG;CACrB,MAAM,WAAW,GAAG,IAAI;CACxB,MAAM,CAAC,MAAM,iBAAA,GAAA,eAAA,iBAAgC;EAC3C,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU;EACX,CAAC;CACF,MAAM,EAAE,KAAK,YAAY,YAAA,GAAA,eAAA,iBAA2B;CACpD,MAAM,qBAAqB,OAAO,YAAY;CAC9C,MAAM,UAAU,uBAAuB,QAAQ,YAAa;CAC5D,MAAM,YAAY,OAAO,gBAAgB;AAEzC,QACE,iBAAA,GAAA,kBAAA,MAACC,YAAAA,KAAD;EAAK,GAAI,UAAU,OAAO;EAAE,IAAI;EAAK,oBAAkB,WAAW,KAAA;EAAW,GAAI;YAAjF,CACG,WACC,iBAAA,GAAA,kBAAA,KAACC,eAAAA,QAAD;GACE,WAAU;GACV,MAAK;GACL,KAAK;GACL,eAAe,aAAa,CAAC,KAAK;GAClC,iBAAe;GACf,iBAAe;GACf,cAAY;GACZ,GAAI,UAAU,UAAU;aAEvB;GACM,CAAA,EAEX,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACE,GAAI,UAAU,WAAW,EACvB,OAAO,EAAE,WAAW,CAAC,OAAOC,YAAAA,IAAI,UAAU,GAAG,SAASA,YAAAA,IAAI,OAAO,GAAG,KAAA,GAAW,EAChF,CAAC;GACF,sBAAA;GACA,MAAK;GACL,IAAI;aAEJ,iBAAA,GAAA,kBAAA,KAAC,OAAD;IAAK,KAAK;IAAa;IAAe,CAAA;GAClC,CAAA,CACF;;EAER;AAEF,QAAQ,UAAUC,uBAAAA;AAClB,QAAQ,eAAe;AACvB,QAAQ,cAAc"}