Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/boxel-ui/addon/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import EntityDisplayWithIcon from './components/entity-icon-display/index.gts';
import EntityDisplayWithThumbnail from './components/entity-thumbnail-display/index.gts';
import FieldContainer from './components/field-container/index.gts';
import FilterList, { type Filter } from './components/filter-list/index.gts';
import FittedCardContainer from './components/fitted-card-container/index.gts';
import GridContainer from './components/grid-container/index.gts';
import BoxelHeader from './components/header/index.gts';
import Header from './components/header/index.gts';
Expand Down Expand Up @@ -115,6 +116,7 @@ export {
EntityDisplayWithThumbnail,
FieldContainer,
FilterList,
FittedCardContainer,
GridContainer,
Header,
IconButton,
Expand Down
132 changes: 8 additions & 124 deletions packages/boxel-ui/addon/src/components/basic-fitted/usage.gts
Original file line number Diff line number Diff line change
Expand Up @@ -5,134 +5,18 @@ import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import FreestyleUsage from 'ember-freestyle/components/freestyle/usage';

import { cn, gt, gte } from '../../helpers.ts';
import {
cn,
gt,
gte,
FITTED_FORMATS,
type FittedFormatSpec,
} from '../../helpers.ts';
import type { Icon } from '../../icons.ts';
import CardContainer from '../card-container/index.gts';
import BasicFitted from './index.gts';

type Spec = { height: number; title?: string; width: number };

// These can be imported from the @cardstack/runtime-common package:
// `import { FITTED_FORMATS } from '@cardstack/runtime-common'`
// For various build problems, could not do that here.
const FITTED_FORMATS = [
{
name: 'Badges',
specs: [
{
id: 'small-badge',
title: 'Small Badge',
width: 150,
height: 40,
},
{
id: 'medium-badge',
title: 'Medium Badge',
width: 150,
height: 65,
},
{
id: 'large-badge',
title: 'Large Badge',
width: 150,
height: 105,
},
],
},
{
name: 'Strips',
specs: [
{
id: 'single-strip',
title: 'Single Strip',
width: 250,
height: 40,
},
{
id: 'double-strip',
title: 'Double Strip',
width: 250,
height: 65,
},
{
id: 'triple-strip',
title: 'Triple Strip',
width: 250,
height: 105,
},
{
id: 'double-wide-strip',
title: 'Double Wide Strip',
width: 400,
height: 65,
},
{
id: 'triple-wide-strip',
title: 'Triple Wide Strip',
width: 400,
height: 105,
},
],
},
{
name: 'Tiles',
specs: [
{
id: 'small-tile',
title: 'Small Tile',
width: 150,
height: 170,
},
{
id: 'regular-tile',
title: 'Regular Tile',
width: 250,
height: 170,
},
{
id: 'cardsgrid-tile',
title: 'CardsGrid Tile',
width: 170,
height: 250,
},
{
id: 'tall-tile',
title: 'Tall Tile',
width: 150,
height: 275,
},
{
id: 'large-tile',
title: 'Large Tile',
width: 250,
height: 275,
},
],
},
{
name: 'Cards',
specs: [
{
id: 'compact-card',
title: 'Compact Card',
width: 400,
height: 170,
},
{
id: 'full-card',
title: 'Full Card',
width: 400,
height: 275,
},
{
id: 'expanded-card',
title: 'Expanded Card',
width: 400,
height: 445,
},
],
},
];
type Spec = Partial<FittedFormatSpec> & { width: number; height: number };

const OTHER_SIZES: Spec[] = [
{ width: 226, height: 226 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,9 @@ const CardContainer: TemplateOnlyComponent<Signature> = <template>
width: 100%;
overflow: hidden;
}
:global(.boxel-card-container--boundaries) {
:global(.boxel-card-container--boundaries:not(.hide-boundaries)) {
box-shadow: 0 0 0 1px var(--border, var(--boxel-border-color));
}
:global(.boxel-card-container--boundaries.hide-boundaries) {
box-shadow: none;
}

:global(.boxel-card-container--themed) {
--_theme-heading-font-size: var(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Component from '@glimmer/component';

import {
fittedFormatById,
fittedFormatIds,
sanitizeHtmlSafe,
type FittedFormatId,
} from '../../helpers.ts';

interface Signature {
Args: {
size?: FittedFormatId;
fullWidth?: boolean;
};
Blocks: { default: [] };
Element: HTMLDivElement;
}

export default class FittedCardContainer extends Component<Signature> {
<template>
<div
class='boxel-fitted-card-container'
style={{this.containerStyle}}
...attributes
>
{{yield}}
</div>
</template>

get formatSpec() {
let size = this.args.size;

if (!size) {
return null;
}

if (!fittedFormatIds?.includes(size)) {
console.error(
`Size "${size}" does not exist in fitted format sizes. Please choose from ${fittedFormatIds.join(', ')}`,
);
return null;
}

return fittedFormatById.get(size) ?? null;
}

get containerStyle() {
let style = ``;
let formatSpec = this.formatSpec;

if (!formatSpec) {
return sanitizeHtmlSafe(style);
}

if (this.args.fullWidth) {
style += `width: 100%; height: ${formatSpec.height}px;`;
} else {
style += `width: ${formatSpec.width}px; height: ${formatSpec.height}px;`;
}

return sanitizeHtmlSafe(style);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Component from '@glimmer/component';
import FreestyleUsage from 'ember-freestyle/components/freestyle/usage';

import {
fittedFormatById,
fittedFormatIds,
type FittedFormatId,
} from '../../helpers.ts';
import FittedCardContainer from './index.gts';

export default class FittedCardContainerUsage extends Component {
sampleSizes = fittedFormatIds;

formatTitle(size: FittedFormatId) {
return fittedFormatById.get(size)?.title ?? size;
}

formatDimensions(size: FittedFormatId) {
let spec = fittedFormatById.get(size);
return spec ? `${spec.width}px × ${spec.height}px` : '';
}

<template>
<FreestyleUsage @name='FittedCardContainer'>
<:description>
Constrains card content to a fixed fitted size so layouts stay aligned.
</:description>
<:example>
<div class='fitted-card-container-usage-grid'>
{{#each this.sampleSizes as |size|}}
<FittedCardContainer @size={{size}}>
<div class='fitted-card-container-usage-card'>
<div class='fitted-card-container-usage-title'>
{{this.formatTitle size}}
</div>
<div class='fitted-card-container-usage-meta'>
{{this.formatDimensions size}}
</div>
</div>
</FittedCardContainer>
{{/each}}
</div>
</:example>
<:api as |Args|>
<Args.String
@name='size'
@description='Fitted size id from the fitted formats list.'
/>
<Args.Yield
@description='Card content rendered inside the sized container.'
/>
</:api>
</FreestyleUsage>
<style scoped>
.fitted-card-container-usage-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: var(--boxel-sp);
align-items: start;
}
.fitted-card-container-usage-card {
width: 100%;
height: 100%;
padding: var(--boxel-sp);
display: grid;
gap: var(--boxel-sp-2xs);
place-content: center;
text-align: center;
border: var(--boxel-border-card);
border-radius: var(--boxel-border-radius);
background: color-mix(
in oklab,
var(--background, var(--boxel-light)) 92%,
var(--foreground, var(--boxel-dark))
);
color: var(--foreground, var(--boxel-dark));
font: var(--boxel-font-sm);
}
.fitted-card-container-usage-title {
font-weight: 600;
}
.fitted-card-container-usage-meta {
color: var(--muted-foreground, var(--boxel-500));
font: var(--boxel-font-xs);
}
</style>
</template>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Component from '@glimmer/component';

import FittedCardContainer from '../../fitted-card-container/index.gts';
import { type FittedFormatId } from '../../../helpers.ts';

export interface GridItemContainerSignature {
Args: { size?: FittedFormatId; fullWidth?: boolean };
Blocks: {
default: [];
before?: [];
after?: [];
};
Element: HTMLElement;
}

export default class GridItemContainer extends Component<GridItemContainerSignature> {
<template>
<div class='boxel-grid-item-container' ...attributes>
{{#if (has-block 'before')}}
{{yield to='before'}}
{{/if}}

<FittedCardContainer @size={{@size}} @fullWidth={{@fullWidth}}>
{{yield}}
</FittedCardContainer>

{{#if (has-block 'after')}}
{{yield to='after'}}
{{/if}}
</div>
</template>
}
Loading
Loading