@hanamura/rcgen
Version:
Generate optimized React container components from configuration
186 lines (166 loc) • 4.75 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = render;
const utils_1 = require("../../src/utils");
/**
* Render the Reel component
*/
function render(config) {
// If a variable prefix is provided, use it
const prefix = config.variablePrefix ? `${config.variablePrefix}-` : '';
return `// generated by static-generator
import React from 'react'
import { QueryName, Spacing } from '../types'
import { getSpacingValue } from '../utils'
import styles from './Reel.module.css'
/**
* Options for the Reel component
*/
export type ReelOptions = {
/**
* Number of columns or exact column width:
* - Number: Divide container into n equal columns (e.g., 3 = three equal columns)
* - String: Use as exact column width (e.g., '150px', '10rem')
*/
columns?: string | number | undefined
/**
* Gap between items
*/
gap?: Spacing | undefined
/**
* Snap behavior
*/
snap?: 'none' | 'x proximity' | 'x mandatory' | undefined
/**
* Hide scrollbar
*/
hideScrollbar?: boolean | undefined
/**
* Padding block
*/
paddingBlock?: Spacing | [padding: Spacing] | [start: Spacing, end: Spacing] | undefined
/**
* Padding inline
*/
paddingInline?: Spacing | [padding: Spacing] | [start: Spacing, end: Spacing] | undefined
}
/**
* Props for the Reel component
*/
export type ReelProps = {
/**
* Options for the Reel component
*/
options?: ReelOptions | undefined
/**
* Adaptive options for the Reel component
*/
adaptiveOptions?: Record<QueryName, ReelOptions> | undefined
/**
* HTML element for the Reel component
*/
as?: React.ElementType | undefined
/**
* Class name for the Reel component
*/
className?: string | undefined
/**
* Style for the Reel component
*/
style?: React.CSSProperties | undefined
/**
* Children for the Reel component
*/
children?: React.ReactNode | undefined
}
/**
* Reel component
*/
export function Reel({
options,
adaptiveOptions,
as: Component = 'div',
className,
style,
children,
}: ReelProps) {
const columns = {
${config.queries
.map(({ name }) => {
const n = (0, utils_1.normalizeName)(name);
return `'${n}': adaptiveOptions?.['${n}']?.columns ?? options?.columns ?? '100%'`;
})
.join(',\n')}
}
return (
<Component
className={\`\${styles['reel']} \${className ?? ''}\`}
style={
{
${config.queries
.map(({ name }) => {
const n = (0, utils_1.normalizeName)(name);
return [
// columns
[
`'--${prefix}reel-${n}-columns':`,
`typeof columns['${n}'] === 'number'`,
`? \`calc((100% - var(--${prefix}reel-${n}-gap) * \${columns['${n}'] - 1}) / \${columns['${n}']})\``,
`: columns['${n}']`,
].join(' '),
// gap
[
`'--${prefix}reel-${n}-gap':`,
`getSpacingValue(adaptiveOptions?.['${n}']?.gap ?? options?.gap) ?? 0`,
].join(' '),
// snap
[
`'--${prefix}reel-${n}-snap':`,
`adaptiveOptions?.['${n}']?.snap ?? options?.snap ?? 'none'`,
].join(' '),
// hideScrollbar
[
`'--${prefix}reel-${n}-scrollbar-width':`,
`getScrollbarWidth(adaptiveOptions?.['${n}']?.hideScrollbar ?? options?.hideScrollbar)`,
].join(' '),
// scrollbarDisplay
[
`'--${prefix}reel-${n}-scrollbar-display':`,
`getScrollbarDisplay(adaptiveOptions?.['${n}']?.hideScrollbar ?? options?.hideScrollbar)`,
].join(' '),
// padding block
[
`'--${prefix}reel-${n}-padding-block':`,
`getSpacingValue(adaptiveOptions?.['${n}']?.paddingBlock ?? options?.paddingBlock) ?? 0`,
].join(' '),
// padding inline
[
`'--${prefix}reel-${n}-padding-inline':`,
`getSpacingValue(adaptiveOptions?.['${n}']?.paddingInline ?? options?.paddingInline) ?? 0`,
].join(' '),
].join(',\n');
})
.join(',\n') || '...({})' // If no styles are provided, return an empty object
},
...style,
} as React.CSSProperties
}
>
{children}
</Component>
)
}
/**
* Get the scrollbar width
*/
function getScrollbarWidth(hideScrollbar?: boolean) {
return hideScrollbar ? 'none' : 'auto'
}
/**
* Get the scrollbar display
*/
function getScrollbarDisplay(hideScrollbar?: boolean) {
return hideScrollbar ? 'none' : 'block'
}
`;
}