Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4fba00f
initial stubbing (#5915)
caseyisonit Dec 2, 2025
afbb342
docs(a11y): added a11y guides to storybook (#5919)
nikkimk Dec 5, 2025
054a200
chore: two doc blocks to get custom docs added to the template (#5917)
caseyisonit Dec 5, 2025
ececb42
docs: updated and formatted next-gen docs (#5924)
nikkimk Dec 5, 2025
0905bbd
docs(asset): modified asset story (#5926)
nikkimk Dec 9, 2025
3e4e946
docs: migrated contributor and project-planning docs (#5928)
nikkimk Dec 9, 2025
9843253
docs: updated docs, decorators, and cursor rules (#5931)
nikkimk Dec 10, 2025
ad8079b
Merge branch 'main' into garage-week/docs-rocks
caseyisonit Dec 11, 2025
2d33184
garage week: docs rocks refinements (#5934)
nikkimk Dec 11, 2025
96e554d
chore: fix weird react error, remove unused assets
caseyisonit Dec 11, 2025
6a24b0f
chore: removed unused helper and update docs
caseyisonit Dec 11, 2025
f36f647
chore: merge base
caseyisonit Dec 11, 2025
c6a3541
chore: clean up a little, test the template pattern with slots
caseyisonit Dec 12, 2025
8ed187d
chore: adobt size arg fix from ruben and clean up
caseyisonit Dec 12, 2025
c4eb76c
chore: direction addon in toolbar and some global controls
caseyisonit Dec 12, 2025
458da4d
chore: status light story cleanup
caseyisonit Dec 12, 2025
0fab704
docs: Kari's edits (#5938)
nikkimk Dec 15, 2025
0aedbfc
chore: story clean up
caseyisonit Dec 15, 2025
1a5463b
chore: clean up and stories with types
caseyisonit Dec 16, 2025
baafc62
Merge branch 'garage-week/docs-rocks' into caseyisonit/addon-party
caseyisonit Dec 16, 2025
023ed17
chore: applying cleaner pattern
caseyisonit Dec 16, 2025
39c9524
chore: fix broken badge type
caseyisonit Dec 16, 2025
aa1bff8
chore: update rules and final styling
caseyisonit Dec 16, 2025
7bfee9f
chore: clean up of flex styling
caseyisonit Dec 17, 2025
b334b10
chore: progress circle clean
caseyisonit Dec 17, 2025
147d96c
chore: asset and divider clean
caseyisonit Dec 17, 2025
02a4b14
chore: doc clean up with new patterns
caseyisonit Dec 17, 2025
10c6c52
chore: docs have pretty pictures and source code is linted
caseyisonit Dec 17, 2025
e3c853d
chore: the final pass
caseyisonit Dec 17, 2025
db0ff48
docs: make next round of Kari's edits (#5939)
nikkimk Dec 17, 2025
3a56a73
docs: moved docs to learn-about-swc
nikkimk Dec 17, 2025
fb66326
Merge branch 'garage-week/docs-rocks' of github.com:adobe/spectrum-we…
nikkimk Dec 17, 2025
31f00f8
chore: clean up patterns (#5935)
caseyisonit Dec 17, 2025
c4a3e99
docs: added images for docs
nikkimk Dec 18, 2025
78ad8e3
docs: made an image list for when to use page
nikkimk Dec 18, 2025
3d240a4
Merge branch 'garage-week/docs-rocks' of github.com:adobe/spectrum-we…
nikkimk Dec 18, 2025
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
875 changes: 875 additions & 0 deletions .cursor/rules/stories-documentation.mdc

Large diffs are not rendered by default.

684 changes: 684 additions & 0 deletions .cursor/rules/stories-format.mdc

Large diffs are not rendered by default.

117 changes: 117 additions & 0 deletions .cursor/rules/storybook-mdx-conversion.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Storybook MDX conversion

Converts markdown files to MDX format compatible with Storybook rendering.

## When to apply

Apply this rule when converting `.md` files to `.mdx` files for display in Storybook, particularly for documentation pages in the 2nd-gen SWC Storybook guides.

## Conversion steps

### 1. File extension and imports

- Change file extension from `.md` to `.mdx`
- Add Storybook imports at the top of the file:

```typescript
import { Meta } from '@storybook/addon-docs/blocks';
```

- Add a blank line after imports

### 2. Meta tag

- Add a `<Meta title="Your Title Here" />` tag after the imports
- The title should match the document's main heading
- Add a blank line after the Meta tag

### 3. Convert HTML comments to JSX comments

Replace HTML comments with JSX-style comments:

**Before (Markdown):**

```markdown
<!-- Document title (editable) -->
```

**After (MDX):**

```mdx
{/* Document title (editable) */}
```

### 4. Preserve all other content

- Keep all markdown syntax as-is (headings, lists, links, code blocks, etc.)
- Keep all `<details>` and `<summary>` HTML elements unchanged
- Keep all list formatting and indentation unchanged
- Preserve all relative link paths (e.g., `./01_contributor-guides/README.md`)
- Do not modify any content within `<details>` blocks or navigation lists

## Example transformation

**Before (README.md):**

```markdown
<!-- Document title (editable) -->

# Contributor Documentation

<!-- Generated TOC - DO NOT EDIT -->

<details open>
<summary><strong>In this doc</strong></summary>

- [About Spectrum Web Components](#about-spectrum-web-components)

</details>

<!-- Document content (editable) -->

## About Spectrum Web Components

Content here...
```

**After (README.mdx):**

```mdx
import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Contributor Documentation" />
{/* Document title (editable) */}

# Contributor Documentation

{/* Generated TOC - DO NOT EDIT */}

<details open>
<summary><strong>In this doc</strong></summary>

- [About Spectrum Web Components](#about-spectrum-web-components)

</details>

{/* Document content (editable) */}

## About Spectrum Web Components

Content here...
```

## Critical rules

1. **Only add imports and Meta tag** - Do not modify any other structural elements
2. **Preserve exact formatting** - Keep all whitespace, indentation, and line breaks
3. **Convert ALL HTML comments** - Every `<!-- comment -->` must become `{/* comment */}`
4. **Keep markdown links** - Do not convert `.md` links to `.mdx` (Storybook may need the original paths)
5. **Blank lines matter** - Maintain blank line after imports and after Meta tag

## Common mistakes to avoid

❌ Don't change the document's heading structure
❌ Don't modify navigation lists or TOC content
❌ Don't convert markdown to JSX (keep lists as markdown lists)
❌ Don't add extra formatting or styling
❌ Don't forget to convert ALL HTML comments to JSX comments
5 changes: 4 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"recommendations": ["runem.lit-plugin"]
"recommendations": [
"runem.lit-plugin",
"bierner.jsdoc-markdown-highlighting"
]
}
9 changes: 9 additions & 0 deletions .vscode/local-extensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Installing local extensions in Cursor

The extensions in this directory are not available in Cursor but are in VSCode. The `vsix` file can be uploaded to Cursor locally to install the extension for usage.

The following steps will get you started:

1. Go to cursor, hit Cmd + Shift + P
2. Search for “Extensions: Install from VSIX…”
3. Select the extension file from this directory and download
Binary file not shown.
7 changes: 6 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,10 @@
},
"typescript.tsdk": "node_modules/typescript/lib",
"lit-plugin.strict": true,
"cSpell.words": ["activedescendant", "coachmark", "valuetext"]
"cSpell.words": ["activedescendant", "AUTODOCS", "coachmark", "valuetext"],
"[mdx]": {
"editor.codeActionsOnSave": {
"source.organizeImports": "never"
}
}
}
2 changes: 1 addition & 1 deletion 2nd-gen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This workspace contains the second generation of Spectrum Web Components, built
- **[@spectrum-web-components/core](./packages/core)** - Abstract base classes providing shared functionality
- **[@adobe/swc](./packages/swc)** - Concrete component implementations with styling

## Getting Started
## About SWC

```bash
# Install dependencies from repository root
Expand Down
22 changes: 17 additions & 5 deletions 2nd-gen/packages/core/components/badge/Badge.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@
* governing permissions and limitations under the License.
*/

import type { ElementSize } from '@spectrum-web-components/core/shared/base/index.js';

/*
* @todo The S1 types can be removed once we are no longer maintaining 1st-gen.
*/

export const FIXED_VALUES = [
'inline-start',
'inline-end',
'block-start',
'block-end',
'inline-start',
'inline-end',
] as const;

export type FixedValues = (typeof FIXED_VALUES)[number];
export const BADGE_VALID_SIZES = [
's',
'm',
'l',
'xl',
] as const satisfies readonly ElementSize[];

export const BADGE_VARIANTS_SEMANTIC = [
'accent',
'neutral',
'informative',
'neutral',
'positive',
'negative',
'notice',
'negative',
] as const;

export const BADGE_VARIANTS_COLOR_S1 = [
Expand Down Expand Up @@ -68,6 +75,11 @@ export const BADGE_VARIANTS_S2 = [
...BADGE_VARIANTS_COLOR_S2,
] as const;

export type FixedValues = (typeof FIXED_VALUES)[number];
export type BadgeSize = (typeof BADGE_VALID_SIZES)[number];
export type BadgeSemanticVariant = (typeof BADGE_VARIANTS_SEMANTIC)[number];
export type BadgeColorVariantS1 = (typeof BADGE_VARIANTS_COLOR_S1)[number];
export type BadgeColorVariantS2 = (typeof BADGE_VARIANTS_COLOR_S2)[number];
export type BadgeVariantS1 = (typeof BADGE_VARIANTS_S1)[number];
export type BadgeVariantS2 = (typeof BADGE_VARIANTS_S2)[number];
export type BadgeVariant = BadgeVariantS1 | BadgeVariantS2;
1 change: 1 addition & 0 deletions 2nd-gen/packages/core/components/divider/Divider.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
*/
export abstract class DividerBase extends SizedMixin(SpectrumElement, {
validSizes: DIVIDER_VALID_SIZES,
/**@todo the design spec says the default size is small but we declare no default size */
noDefaultSize: true,
}) {
/**
Expand Down
8 changes: 7 additions & 1 deletion 2nd-gen/packages/core/components/divider/Divider.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@

import type { ElementSize } from '@spectrum-web-components/core/shared/base/index.js';

export const DIVIDER_VALID_SIZES: ElementSize[] = ['s', 'm', 'l'] as const;
export const DIVIDER_VALID_SIZES = [
's',
'm',
'l',
] as const satisfies ElementSize[];
export const DIVIDER_STATIC_COLORS = ['white', 'black'] as const;

export type DividerStaticColor = (typeof DIVIDER_STATIC_COLORS)[number];

export type DividerSize = (typeof DIVIDER_VALID_SIZES)[number];
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ import {
* @slot - Accessible label for the progress circle.
*
* Used to provide context about what is loading or progressing.
*
* @fires progress-change - Dispatched when the progress value changes
*/
export abstract class ProgressCircleBase extends SizedMixin(SpectrumElement, {
validSizes: PROGRESS_CIRCLE_VALID_SIZES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const PROGRESS_CIRCLE_VALID_SIZES: ElementSize[] = [
's',
'm',
'l',
] as const;
] as const satisfies ElementSize[];
export const PROGRESS_CIRCLE_STATIC_COLORS_S1 = ['white'] as const;
export const PROGRESS_CIRCLE_STATIC_COLORS_S2 = [
...PROGRESS_CIRCLE_STATIC_COLORS_S1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ export const STATUSLIGHT_VARIANTS_S2 = [
...STATUSLIGHT_VARIANTS_COLOR_S2,
] as const;

export type StatusLightSemanticVariantS1 =
(typeof STATUSLIGHT_VARIANTS_SEMANTIC_S1)[number];
export type StatusLightSemanticVariantS2 =
(typeof STATUSLIGHT_VARIANTS_SEMANTIC_S2)[number];
export type StatusLightSemanticVariant =
| StatusLightSemanticVariantS1
| StatusLightSemanticVariantS2;

export type StatusLightColorVariantS1 =
(typeof STATUSLIGHT_VARIANTS_COLOR_S1)[number];
export type StatusLightColorVariantS2 =
(typeof STATUSLIGHT_VARIANTS_COLOR_S2)[number];
export type StatusLightColorVariant =
| StatusLightColorVariantS1
| StatusLightColorVariantS2;

export type StatusLightVariantS1 = (typeof STATUSLIGHT_VARIANTS_S1)[number];
export type StatusLightVariantS2 = (typeof STATUSLIGHT_VARIANTS_S2)[number];
export type StatusLightVariant = StatusLightVariantS1 | StatusLightVariantS2;
10 changes: 6 additions & 4 deletions 2nd-gen/packages/core/shared/base/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,25 @@ export function SpectrumMixin<T extends Constructor<ReactiveElement>>(
): T & Constructor<SpectrumInterface> {
class SpectrumMixinElement extends constructor {
/**
* @private
* @internal
*/
public override shadowRoot!: ShadowRoot;
private _dirParent?: HTMLElement;

/**
* @private
* @internal
*/
public override dir!: 'ltr' | 'rtl';

/**
* @private
* @internal
*/
public get isLTR(): boolean {
return this.dir === 'ltr';
}

/**
* @internal
*/
public hasVisibleFocusInTree(): boolean {
const getAncestors = (root: Document = document): HTMLElement[] => {
// eslint-disable-next-line @spectrum-web-components/document-active-element
Expand Down
12 changes: 0 additions & 12 deletions 2nd-gen/packages/core/shared/base/version.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,2 @@
/**
* Copyright 2025 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

// Generated by genversion.
export const version = '1.10.0';
8 changes: 7 additions & 1 deletion 2nd-gen/packages/core/shared/observe-slot-presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function ObserveSlotPresence<T extends Constructor<ReactiveElement>>(
}

/**
* @private
* @internal
*/
public get slotContentIsPresent(): boolean {
if (lightDomSelectors.length === 1) {
Expand All @@ -71,6 +71,9 @@ export function ObserveSlotPresence<T extends Constructor<ReactiveElement>>(
}
private [slotContentIsPresent]: Map<string, boolean> = new Map();

/**
* @internal
*/
public getSlotContentPresence(selector: string): boolean {
if (this[slotContentIsPresent].has(selector)) {
return this[slotContentIsPresent].get(selector) || false;
Expand All @@ -80,6 +83,9 @@ export function ObserveSlotPresence<T extends Constructor<ReactiveElement>>(
);
}

/**
* @internal
*/
public managePresenceObservedSlot = (): void => {
let changes = false;
lightDomSelectors.forEach((selector) => {
Expand Down
6 changes: 6 additions & 0 deletions 2nd-gen/packages/core/shared/observe-slot-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export function ObserveSlotText<T extends Constructor<ReactiveElement>>(
});
}

/**
* @internal
*/
@property({ type: Boolean, attribute: false })
public slotHasContent = false;

Expand All @@ -68,6 +71,9 @@ export function ObserveSlotText<T extends Constructor<ReactiveElement>>(
})
private [assignedNodesList]!: NodeListOf<HTMLElement>;

/**
* @internal
*/
public manageTextObservedSlot(): void {
if (!this[assignedNodesList]) {
return;
Expand Down
32 changes: 32 additions & 0 deletions 2nd-gen/packages/core/shared/utilities/capitalize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright 2025 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

/**
* Capitalizes the first character of a string.
*
* @param str - The string to capitalize
* @returns The capitalized string, or an empty string if the input is not a string
*
* @example
* ```typescript
* capitalize('hello') // Returns: 'Hello'
* capitalize('world') // Returns: 'World'
* capitalize('') // Returns: ''
* capitalize(undefined) // Returns: ''
* ```
*/
export function capitalize(str?: string): string {
if (typeof str !== 'string') {
return '';
}
return str.charAt(0).toUpperCase() + str.slice(1);
}
Loading
Loading