Skip to content

Commit e550a7e

Browse files
committed
chore: migrate asset
1 parent 1691e33 commit e550a7e

File tree

7 files changed

+191
-91
lines changed

7 files changed

+191
-91
lines changed

2nd-gen/packages/core/components/asset/Asset.base.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,67 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13+
import { PropertyValues } from 'lit';
1314
import { property } from 'lit/decorators.js';
1415

1516
import { SpectrumElement } from '@spectrum-web-components/core/shared/base/index.js';
1617

18+
import { ASSET_VARIANTS, type AssetVariant } from './Asset.types.js';
19+
20+
/**
21+
* @slot - The content to render when no `variant` is provided (typically an <img> element)
22+
*/
1723
export abstract class AssetBase extends SpectrumElement {
24+
// ─────────────────────────
25+
// API TO OVERRIDE
26+
// ─────────────────────────
27+
28+
/**
29+
* @internal
30+
*
31+
* A readonly array of all valid variants for the asset.
32+
*
33+
* This is an actual internal property, intended not for customer use
34+
*/
35+
static readonly VARIANTS: readonly AssetVariant[] = ASSET_VARIANTS;
36+
37+
// ─────────────────
38+
// SHARED API
39+
// ─────────────────
40+
41+
/**
42+
* The variant of the asset. When not provided, slot content is rendered (e.g., an image).
43+
*/
1844
@property({ type: String, reflect: true })
19-
public variant: 'file' | 'folder' | undefined;
45+
public variant: AssetVariant | undefined;
2046

47+
/**
48+
* Accessible label for the asset’s SVG variant.
49+
*/
2150
@property()
2251
public label = '';
52+
53+
// ──────────────────────
54+
// IMPLEMENTATION
55+
// ──────────────────────
56+
57+
protected override updated(changes: PropertyValues): void {
58+
super.updated(changes);
59+
if (window.__swc?.DEBUG) {
60+
const constructor = this.constructor as typeof AssetBase;
61+
if (
62+
typeof this.variant !== 'undefined' &&
63+
!constructor.VARIANTS.includes(this.variant)
64+
) {
65+
window.__swc.warn(
66+
this,
67+
`<${this.localName}> element expects the "variant" attribute to be one of the following:`,
68+
'https://opensource.adobe.com/spectrum-web-components/components/asset/',
69+
{
70+
issues: [...constructor.VARIANTS],
71+
}
72+
);
73+
}
74+
}
75+
}
2376
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
export const ASSET_VARIANTS = ['file', 'folder'] as const;
14+
15+
export type AssetVariant = (typeof ASSET_VARIANTS)[number];

2nd-gen/packages/core/components/asset/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212
export * from './Asset.base.js';
13+
export * from './Asset.types.js';

2nd-gen/packages/swc/components/asset/Asset.ts

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,62 +11,89 @@
1111
*/
1212

1313
import { CSSResultArray, html, TemplateResult } from 'lit';
14+
import { classMap } from 'lit/directives/class-map.js';
1415

1516
import { AssetBase } from '@spectrum-web-components/core/components/asset';
1617

1718
import styles from './asset.css';
1819

1920
const file = (label: string): TemplateResult => html`
2021
<svg
21-
class="file"
22+
class="spectrum-Asset-file"
2223
role="img"
2324
viewBox="0 0 128 128"
2425
aria-label=${label || 'File'}
2526
>
2627
<path
27-
class="fileBackground"
28+
class="spectrum-Asset-fileBackground"
2829
d="M24,126c-5.5,0-10-4.5-10-10V12c0-5.5,4.5-10,10-10h61.5c2.1,0,4.1,0.8,5.6,2.3l20.5,20.4c1.5,1.5,2.4,3.5,2.4,5.7V116c0,5.5-4.5,10-10,10H24z"
2930
></path>
3031
<path
31-
class="fileOutline"
32+
class="spectrum-Asset-fileOutline"
3233
d="M113.1,23.3L92.6,2.9C90.7,1,88.2,0,85.5,0H24c-6.6,0-12,5.4-12,12v104c0,6.6,5.4,12,12,12h80c6.6,0,12-5.4,12-12V30.4C116,27.8,114.9,25.2,113.1,23.3z M90,6l20.1,20H92c-1.1,0-2-0.9-2-2V6z M112,116c0,4.4-3.6,8-8,8H24c-4.4,0-8-3.6-8-8V12c0-4.4,3.6-8,8-8h61.5c0.2,0,0.3,0,0.5,0v20c0,3.3,2.7,6,6,6h20c0,0.1,0,0.3,0,0.4V116z"
3334
></path>
3435
</svg>
3536
`;
3637

3738
const folder = (label: string): TemplateResult => html`
3839
<svg
39-
class="folder"
40+
class="spectrum-Asset-folder"
4041
role="img"
4142
viewBox="0 0 32 32"
4243
aria-label=${label || 'Folder'}
4344
>
4445
<path
45-
class="folderBackground"
46+
class="spectrum-Asset-folderBackground"
4647
d="M3,29.5c-1.4,0-2.5-1.1-2.5-2.5V5c0-1.4,1.1-2.5,2.5-2.5h10.1c0.5,0,1,0.2,1.4,0.6l3.1,3.1c0.2,0.2,0.4,0.3,0.7,0.3H29c1.4,0,2.5,1.1,2.5,2.5v18c0,1.4-1.1,2.5-2.5,2.5H3z"
4748
></path>
4849
<path
49-
class="folderOutline"
50+
class="spectrum-Asset-folderOutline"
5051
d="M29,6H18.3c-0.1,0-0.2,0-0.4-0.2l-3.1-3.1C14.4,2.3,13.8,2,13.1,2H3C1.3,2,0,3.3,0,5v22c0,1.6,1.3,3,3,3h26c1.7,0,3-1.4,3-3V9C32,7.3,30.7,6,29,6z M31,27c0,1.1-0.9,2-2,2H3c-1.1,0-2-0.9-2-2V7h28c1.1,0,2,0.9,2,2V27z"
5152
></path>
5253
</svg>
5354
`;
5455

5556
/**
57+
* Use an asset element to visually represent a file, folder, or image.
58+
* File and folder representations center themselves within the available space.
59+
* Images are contained to the element’s size and centered.
60+
*
5661
* @element swc-asset
57-
* @slot - content to be displayed in the asset when an acceptable value for `file` is not present
62+
* @slot - content to be displayed when no `variant` is set (typically an <img>)
63+
*
64+
* @example
65+
* <swc-asset style="block-size: 128px">
66+
* <img class="spectrum-Asset-image" src="example.png" alt="Example image" />
67+
* </swc-asset>
68+
*
69+
* @example
70+
* <swc-asset variant="file" style="min-inline-size: 150px; block-size: 128px"></swc-asset>
71+
*
72+
* @example
73+
* <swc-asset variant="folder" style="min-inline-size: 150px; block-size: 128px"></swc-asset>
5874
*/
5975
export class Asset extends AssetBase {
76+
// ──────────────────────────────
77+
// RENDERING & STYLING
78+
// ──────────────────────────────
79+
6080
public static override get styles(): CSSResultArray {
6181
return [styles];
6282
}
6383

6484
protected override render(): TemplateResult {
65-
if (this.variant === 'file') {
66-
return file(this.label);
67-
} else if (this.variant === 'folder') {
68-
return folder(this.label);
69-
}
70-
return html` <slot></slot> `;
85+
return html`
86+
<div
87+
class=${classMap({
88+
['spectrum-Asset']: true,
89+
})}
90+
>
91+
${this.variant === 'file'
92+
? file(this.label)
93+
: this.variant === 'folder'
94+
? folder(this.label)
95+
: html` <slot></slot> `}
96+
</div>
97+
`;
7198
}
7299
}
Lines changed: 19 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,49 @@
1-
/**
1+
/*!
22
* Copyright 2025 Adobe. All rights reserved.
3+
*
34
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
45
* you may not use this file except in compliance with the License. You may obtain a copy
5-
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
* of the License at <http://www.apache.org/licenses/LICENSE-2.0>
67
*
78
* Unless required by applicable law or agreed to in writing, software distributed under
89
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
910
* OF ANY KIND, either express or implied. See the License for the specific language
1011
* governing permissions and limitations under the License.
1112
*/
1213

13-
:host {
14-
--spectrum-asset-folder-background: var(
15-
--highcontrast-asset-icon-background-color,
16-
var(
17-
--mod-asset-folder-background-color,
18-
var(--spectrum-asset-folder-background-color)
19-
)
20-
);
21-
--spectrum-asset-file-background: var(
22-
--highcontrast-asset-icon-background-color,
23-
var(
24-
--mod-asset-file-background-color,
25-
var(--spectrum-asset-file-background-color)
26-
)
27-
);
28-
--spectrum-asset-folder-outline: var(
29-
--mod-asset-icon-outline-color,
30-
var(--spectrum-asset-icon-outline-color)
31-
);
32-
--spectrum-asset-file-outline: var(
33-
--mod-asset-icon-outline-color,
34-
var(--spectrum-asset-icon-outline-color)
35-
);
36-
14+
.spectrum-Asset {
15+
display: flex;
16+
align-items: center;
17+
justify-content: center;
3718
inline-size: 100%;
3819
block-size: 100%;
39-
justify-content: center;
40-
align-items: center;
41-
display: flex;
42-
43-
--spectrum-asset-folder-background-color: var(
44-
--system-asset-folder-background-color
45-
);
46-
--spectrum-asset-file-background-color: var(
47-
--system-asset-file-background-color
48-
);
49-
--spectrum-asset-icon-outline-color: var(--system-asset-icon-outline-color);
5020
}
5121

52-
::slotted(*) {
22+
.spectrum-Asset-image {
5323
max-inline-size: 100%;
5424
max-block-size: 100%;
5525
object-fit: contain;
56-
transition: opacity var(--spectrum-animation-duration-100);
5726
}
5827

59-
.file,
60-
.folder {
61-
inline-size: max(48px, min(100%, 80px));
62-
inline-size: max(
63-
var(--mod-asset-icon-min-width, 48px),
64-
min(100%, var(--mod-asset-icon-max-width, 80px))
65-
);
28+
.spectrum-Asset-folder,
29+
.spectrum-Asset-file {
30+
inline-size: clamp(48px, 100%, 80px);
6631
block-size: 100%;
6732
margin: 20px;
68-
margin: var(--mod-asset-icon-margin, 20px);
69-
}
70-
71-
.folderBackground {
72-
fill: var(--spectrum-asset-folder-background);
7333
}
7434

75-
.fileBackground {
76-
fill: var(--spectrum-asset-file-background);
35+
.spectrum-Asset-folderBackground {
36+
fill: var(--spectrum-gray-200);
7737
}
7838

79-
.folderOutline {
80-
fill: var(--spectrum-asset-folder-outline);
39+
.spectrum-Asset-fileBackground {
40+
fill: var(--spectrum-gray-25);
8141
}
8242

83-
.fileOutline {
84-
fill: var(--spectrum-asset-file-outline);
43+
.spectrum-Asset-folderOutline {
44+
fill: var(--spectrum-gray-500);
8545
}
8646

87-
@media (forced-colors: active) {
88-
:host {
89-
--highcontrast-asset-icon-background-color: currentcolor;
90-
}
47+
.spectrum-Asset-fileOutline {
48+
fill: var(--spectrum-gray-500);
9149
}

2nd-gen/packages/swc/components/asset/stories/asset.stories.ts

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,80 @@
1111
*/
1212

1313
import { html } from 'lit';
14-
import type { Meta, StoryObj } from '@storybook/web-components';
14+
import type { Meta, StoryObj as Story } from '@storybook/web-components';
15+
import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers';
16+
17+
import { Asset } from '@adobe/swc/asset';
1518

1619
import '@adobe/swc/asset';
1720

21+
// ────────────────
22+
// METADATA
23+
// ────────────────
24+
25+
const { events, args, argTypes, template } = getStorybookHelpers('swc-asset');
26+
27+
argTypes.variant = {
28+
...argTypes.variant,
29+
control: { type: 'select' },
30+
options: [undefined, ...Asset.VARIANTS],
31+
};
32+
1833
const meta: Meta = {
1934
title: 'Asset',
2035
component: 'swc-asset',
21-
argTypes: {
22-
variant: {
23-
control: { type: 'select' },
24-
options: ['file', 'folder', undefined],
36+
args,
37+
argTypes,
38+
parameters: {
39+
actions: {
40+
handles: events,
2541
},
2642
},
43+
tags: ['migrated'],
2744
};
2845

2946
export default meta;
30-
type Story = StoryObj;
3147

32-
// export const Default: Story = {
33-
// render: (args) => html` <swc-asset variant="${args.variant}"></swc-asset> `,
34-
// };
48+
// ───────────────
49+
// STORIES
50+
// ───────────────
51+
52+
args['default-slot'] = IMAGE_PLACEHOLDER_STRING();
3553

3654
export const Default: Story = {
37-
render: (args) => html` <swc-asset variant="${args.variant}"></swc-asset> `,
55+
render: (args) => template(args),
56+
};
3857

39-
// render: () => html`
40-
// <swc-asset style="height: 128px">
41-
// <img src=${portrait} alt="Demo Graphic" />
42-
// </swc-asset>
43-
// `,
58+
export const File: Story = {
59+
args: {
60+
variant: 'file',
61+
},
62+
render: (args) =>
63+
html`<swc-asset
64+
style="min-inline-size: 150px; block-size: 128px"
65+
variant=${args.variant as 'file'}
66+
></swc-asset>`,
67+
tags: ['!dev'],
68+
};
69+
70+
export const Folder: Story = {
71+
args: {
72+
variant: 'folder',
73+
},
74+
render: (args) =>
75+
html`<swc-asset
76+
style="min-inline-size: 150px; block-size: 128px"
77+
variant=${args.variant as 'folder'}
78+
></swc-asset>`,
79+
tags: ['!dev'],
4480
};
81+
82+
// ────────────────────────
83+
// HELPER FUNCTIONS
84+
// ────────────────────────
85+
86+
function IMAGE_PLACEHOLDER_STRING(): string {
87+
const data =
88+
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='128' height='128'><rect width='100%' height='100%' fill='%23eeeeee'/><text x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' font-size='12' fill='%23999999'>Image</text></svg>";
89+
return `<img class="spectrum-Asset-image" alt="Example image" src="${data}">`;
90+
}

0 commit comments

Comments
 (0)