@reusable-ui/collapse
Version:
A generic element with dynamic visibility (show/hide).
158 lines (157 loc) • 6.65 kB
JavaScript
// cssfn:
import {
// writes css in javascript:
keyframes, fallback, style,
// strongly typed of css variables:
switchOf,
// reads/writes css variables configuration:
cssConfig, } from '@cssfn/core'; // writes css in javascript
// reusable-ui core:
import {
// padding (inner spacing) stuff of UI:
usesPadding,
// a capability of UI to expand/reduce its size or toggle the visibility:
usesLastKnownExpandedSize, } from '@reusable-ui/core'; // a set of reusable-ui packages which are responsible for building any component
// TODO: experimental
// // internals:
// import {
// // features:
// usesCollapse,
// } from '../features/collapse.js'
// configs:
export const [collapses, collapseValues, cssCollapseConfig] = cssConfig(() => {
// features:
const { paddingVars } = usesPadding();
const { lastKnownExpandedSizeVars } = usesLastKnownExpandedSize();
// const {collapseVars } = usesCollapse(); // TODO: experimental
//#region keyframes
const frameCollapsedBlock = style({
maxBlockSize: 0,
paddingBlock: 0,
overflowY: 'clip',
...fallback({
overflowY: 'hidden',
}),
});
const frameIntermediateBlock = style({
// blockSize : `calc-size(${collapseVars.blockSize }, size * 1.05)`, // TODO: experimental
// maxBlockSize : `calc-size(${collapseVars.blockSize }, size * 1.05)`, // TODO: experimental
...fallback({
blockSize: `calc(${switchOf(lastKnownExpandedSizeVars.blockSize, '100vh')} * 1.05)`,
maxBlockSize: `calc(${switchOf(lastKnownExpandedSizeVars.blockSize, '100vh')} * 1.05)`,
}),
paddingBlock: `calc(${paddingVars.paddingBlock} * 1.05)`,
});
const frameFinalizingBlock = style({
overflowY: 'clip',
...fallback({
overflowY: 'hidden',
}),
});
const frameExpandedBlock = style({
// blockSize : `calc-size(${collapseVars.blockSize }, size)`, // TODO: experimental
// maxBlockSize : `calc-size(${collapseVars.blockSize }, size)`, // TODO: experimental
...fallback({
blockSize: switchOf(lastKnownExpandedSizeVars.blockSize, '100vh'),
maxBlockSize: switchOf(lastKnownExpandedSizeVars.blockSize, '100vh'),
}),
paddingBlock: paddingVars.paddingBlock,
overflowY: 'unset',
});
const [keyframesExpandBlockRule, keyframesExpandBlock] = keyframes({
from: frameCollapsedBlock,
'70%': frameIntermediateBlock,
'99%': frameFinalizingBlock,
to: frameExpandedBlock,
});
keyframesExpandBlock.value = 'expandBlock'; // the @keyframes name should contain 'expand' in order to be recognized by `useCollapsible`
const [keyframesCollapseBlockRule, keyframesCollapseBlock] = keyframes({
from: frameExpandedBlock,
'30%': frameIntermediateBlock,
'1%': frameFinalizingBlock,
to: frameCollapsedBlock,
});
keyframesCollapseBlock.value = 'collapseBlock'; // the @keyframes name should contain 'collapse' in order to be recognized by `useCollapsible`
const frameCollapsedInline = style({
maxInlineSize: 0,
paddingInline: 0,
overflowX: 'clip',
...fallback({
overflowX: 'hidden',
}),
});
const frameIntermediateInline = style({
// inlineSize : `calc-size(${collapseVars.inlineSize}, size * 1.05)`, // TODO: experimental
// maxInlineSize : `calc-size(${collapseVars.inlineSize}, size * 1.05)`, // TODO: experimental
...fallback({
inlineSize: `calc(${switchOf(lastKnownExpandedSizeVars.inlineSize, '100vw')} * 1.05)`,
maxInlineSize: `calc(${switchOf(lastKnownExpandedSizeVars.inlineSize, '100vw')} * 1.05)`,
}),
paddingInline: `calc(${paddingVars.paddingInline} * 1.05)`,
});
const frameFinalizingInline = style({
overflowX: 'clip',
...fallback({
overflowX: 'hidden',
}),
});
const frameExpandedInline = style({
// inlineSize : `calc-size(${collapseVars.inlineSize}, size)`, // TODO: experimental
// maxInlineSize : `calc-size(${collapseVars.inlineSize}, size)`, // TODO: experimental
...fallback({
inlineSize: switchOf(lastKnownExpandedSizeVars.inlineSize, '100vw'),
maxInlineSize: switchOf(lastKnownExpandedSizeVars.inlineSize, '100vw'),
}),
paddingInline: paddingVars.paddingInline,
overflowX: 'unset',
});
const [keyframesExpandInlineRule, keyframesExpandInline] = keyframes({
from: frameCollapsedInline,
'70%': frameIntermediateInline,
'99%': frameFinalizingInline,
to: frameExpandedInline,
});
keyframesExpandInline.value = 'expandInline'; // the @keyframes name should contain 'expand' in order to be recognized by `useCollapsible`
const [keyframesCollapseInlineRule, keyframesCollapseInline] = keyframes({
from: frameExpandedInline,
'30%': frameIntermediateInline,
'1%': frameFinalizingInline,
to: frameCollapsedInline,
});
keyframesCollapseInline.value = 'collapseInline'; // the @keyframes name should contain 'collapse' in order to be recognized by `useCollapsible`
//#endregion keyframes
const bases = {
// sizes:
inlineSize: '100%', // in usual `block` layout (regradless the collapsing orientation: 'inline|block'), the width is usually `100%`, except when `position: 'absolute'`
blockSize: 'fit-content', // in usual `block` layout (regradless the collapsing orientation: 'inline|block'), the height is usually `fit-content`
// animations:
...keyframesExpandBlockRule,
...keyframesCollapseBlockRule,
animExpandBlock: [
['300ms', 'ease-out', 'both', keyframesExpandBlock],
],
animCollapseBlock: [
['300ms', 'ease-out', 'both', keyframesCollapseBlock],
],
...keyframesExpandInlineRule,
...keyframesCollapseInlineRule,
animExpandInline: [
['300ms', 'ease-out', 'both', keyframesExpandInline],
],
animCollapseInline: [
['300ms', 'ease-out', 'both', keyframesCollapseInline],
],
// spacings:
paddingInline: '0px',
paddingBlock: '0px',
};
const defaults = {
// animations:
animExpand: bases.animExpandBlock,
animCollapse: bases.animCollapseBlock,
};
return {
...bases,
...defaults,
};
}, { prefix: 'clp' });