Skip to content

docs: enhance ui components, styles, and documentation across the project#2

Merged
elonehoo merged 29 commits into
mainfrom
docs
Mar 3, 2026
Merged

docs: enhance ui components, styles, and documentation across the project#2
elonehoo merged 29 commits into
mainfrom
docs

Conversation

@elonehoo

@elonehoo elonehoo commented Mar 3, 2026

Copy link
Copy Markdown
Member

No description provided.

…n tokens

- Updated landing.css to enhance Starlight structure overrides and remove unnecessary styles.
- Introduced layout.css for header, sidebar, navigation, footer, and mobile menu styles.
- Added tokens.css for design tokens including colors, fonts, shadows, and radii.
- Created typography.css for consistent body and heading styles across the site.
- Updated uno.config.ts to define font families for display and code.
- Rearranged catalog entries in pnpm-workspace.yaml for better organization.
- Added new dependencies: eslint-plugin-astro.
- Updated dark.svg and light.svg logos with new design elements, including additional shapes and color adjustments.
…tation

- Changed the "Get Started" link in Hero component from "/docs/" to "/overview/introduction".
- Added a new introduction page for the documentation with features and benefits of the UI component library.
- Enhanced styles for various components including cards, tabs, and markdown content for better readability and aesthetics.
- Adjusted typography settings for headings and paragraphs to improve visual hierarchy and consistency.
- Updated CSS tokens for colors and layout dimensions to refine the overall design.
- Implemented smooth transitions for theme changes and improved accessibility features across components.
…cumentation

- Introduced DataAttrTable component to render component data attributes.
- Added EmitsTable component to display emitted events with descriptions.
- Created PropsTable component to showcase component props with types and default values.

fix: update MobileTableOfContents and Pagination styles

- Removed unnecessary uppercase text transformation in MobileTableOfContents.
- Adjusted font styles in Pagination for consistency.

chore: enhance Avatar component examples and styles

- Added event handling and root provider examples for Avatar component in Vue.
- Created new CSS files for Avatar event and root provider styles.

style: remove uppercase transformations from various components

- Cleaned up styles across multiple components to remove uppercase text transformations for better readability.

chore: update package dependencies and workspace configuration

- Added @destyler/docs package to pnpm workspace and updated lockfile.
Copilot AI review requested due to automatic review settings March 3, 2026 08:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds and styles a new Astro/Starlight documentation site for the UI library, along with supporting tooling for live component previews and generated type API references.

Changes:

  • Added a docs/ workspace package (Astro + Starlight + UnoCSS) with custom header/sidebar/TOC/pagination and landing page sections.
  • Implemented live Vue/React example preview + highlighted source display, plus a script to generate API reference JSON from framework dist/*.d.ts.
  • Updated example components and logo assets, plus workspace scripts/configs to support docs development and linting.

Reviewed changes

Copilot reviewed 77 out of 82 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
public/logos/light.svg Updates the light logo asset used by the docs header/branding.
public/logos/dark.svg Updates the dark logo asset used by the docs header/branding.
pnpm-workspace.yaml Adds docs workspace + catalogs for docs/styles/icons dependencies.
packages/vue/src/components/breadcrumbs/examples/RootProvider.vue Adjusts Vue breadcrumbs example to use reactive props + separator logic.
packages/vue/src/components/breadcrumbs/examples/Context.vue Tweaks Vue breadcrumbs context example markup for docs display.
packages/vue/src/components/avatar/examples/RootProvider.vue Updates Vue avatar provider example to change image source dynamically.
packages/vue/src/components/avatar/examples/Event.vue Updates Vue avatar event example to display status in the UI.
packages/vue/src/components/avatar/examples/Basic.vue Minor formatting cleanup in Vue avatar basic example.
packages/vue/src/components/aspect-ratio/examples/Square.vue Moves inline styles to class-based styling for docs theming.
packages/vue/src/components/aspect-ratio/examples/RootProvider.vue Simplifies the image example and removes inline sizing styles.
packages/vue/src/components/aspect-ratio/examples/Portrait.vue Simplifies the image example and removes inline sizing styles.
packages/vue/src/components/aspect-ratio/examples/Basic.vue Simplifies the image example and removes inline sizing styles.
package.json Adds docs scripts + includes eslint-plugin-astro dependency.
eslint.config.mjs Adds Astro ESLint config for files under docs/**.
docs/uno.config.ts Adds UnoCSS config for docs styling + icons.
docs/tsconfig.json Adds strict Astro TS config for docs package.
docs/src/utils/shiki.ts Adds Shiki core highlighter utility with dual themes.
docs/src/styles/typography.css Introduces docs typography overrides.
docs/src/styles/tokens.css Introduces docs design token variables and base theming.
docs/src/styles/layout.css Introduces docs layout overrides (header/sidebar/footer/search).
docs/src/styles/landing.css Adds landing-page-specific structural overrides.
docs/src/styles/content.css Adds markdown content styling overrides.
docs/src/styles/components/token.css Adds demo-specific token variables used by component previews.
docs/src/styles/components/components.css Aggregates component demo styles into a single import.
docs/src/styles/components/breadcrumbs/rootprovider.css Adds docs styles for breadcrumbs RootProvider preview.
docs/src/styles/components/breadcrumbs/context.css Adds docs styles for breadcrumbs Context preview.
docs/src/styles/components/breadcrumbs/breadcrumbs.css Aggregates breadcrumbs demo css imports.
docs/src/styles/components/breadcrumbs/basic.css Adds docs styles for breadcrumbs Basic preview.
docs/src/styles/components/avatar/rootprovider.css Adds docs styles for avatar RootProvider preview.
docs/src/styles/components/avatar/event.css Adds docs styles for avatar Event preview.
docs/src/styles/components/avatar/basic.css Adds docs styles for avatar Basic preview.
docs/src/styles/components/avatar/avatar.css Aggregates avatar demo css imports.
docs/src/styles/components/aspect-ratio/square.css Adds docs styles for aspect-ratio Square preview.
docs/src/styles/components/aspect-ratio/root-provider.css Adds docs styles for aspect-ratio RootProvider preview.
docs/src/styles/components/aspect-ratio/portrait.css Adds docs styles for aspect-ratio Portrait preview.
docs/src/styles/components/aspect-ratio/basic.css Adds docs styles for aspect-ratio Basic preview.
docs/src/styles/components/aspect-ratio/aspect-ratio.css Aggregates aspect-ratio demo css imports.
docs/src/styles/components.css Adds global UI component styling overrides (tabs, cards, code, etc.).
docs/src/styles/bootstrap.css Centralizes docs CSS imports and load order.
docs/src/env.d.ts Adds Astro + Vue module typing for docs integrations.
docs/src/content/docs/overview/introduction.mdx Adds Introduction docs content.
docs/src/content/docs/index.mdx Adds custom landing page (splash template).
docs/src/content/docs/components/breadcrumbs.mdx Adds Breadcrumbs component documentation page.
docs/src/content/docs/components/avatar.mdx Adds Avatar component documentation page.
docs/src/content/docs/components/aspect-ratio.mdx Adds Aspect Ratio component documentation page.
docs/src/content.config.ts Adds Starlight content collection configuration.
docs/src/components/landing/Steps.astro Adds landing “steps” section with Shiki-highlighted code blocks.
docs/src/components/landing/Hero.astro Adds landing hero section.
docs/src/components/landing/Features.astro Adds landing features section.
docs/src/components/landing/Components.astro Adds landing “components list” section.
docs/src/components/landing/CTA.astro Adds landing CTA + custom landing footer.
docs/src/components/header/HeaderThemeToggle.astro Adds a custom theme toggle control for docs header.
docs/src/components/header/HeaderSearch.astro Restyles Starlight search trigger for docs header.
docs/src/components/header/HeaderLogo.astro Adds theme-aware header logo rendering.
docs/src/components/header/HeaderGitHub.astro Adds GitHub icon link in header.
docs/src/components/header/HeaderFramework.astro Adds framework switcher for Vue/React content switching.
docs/src/components/VueExample.vue Loads Vue SFC examples dynamically for previews.
docs/src/components/TableOfContents.astro Adds custom desktop TOC with active-heading tracking.
docs/src/components/Sidebar.astro Adds custom sidebar with state persistence.
docs/src/components/ReactExample.tsx Loads React examples lazily for previews.
docs/src/components/PropsTable.astro Renders props table for generated API reference.
docs/src/components/Pagination.astro Adds custom docs pagination UI.
docs/src/components/MobileTableOfContents.astro Adds custom mobile TOC with active-heading tracking.
docs/src/components/MobileMenuToggle.astro Adds custom mobile menu toggle control.
docs/src/components/Header.astro Composes the custom header from subcomponents.
docs/src/components/FrameworkContent.astro Adds framework-scoped content wrapper for MDX pages.
docs/src/components/EmitsTable.astro Renders emits/events table for generated API reference.
docs/src/components/DataAttrTable.astro Renders data-attribute table for generated API reference.
docs/src/components/ComponentTypes.astro Loads and renders generated per-component type JSON.
docs/src/components/ComponentPreview.astro Adds live preview + “show code/copy code” for component examples.
docs/scripts/generate-type-docs.ts Adds CLI tool to generate docs type JSON from framework d.ts/machine output.
docs/public/logos Links docs public logos to shared public assets.
docs/package.json Adds docs package definition + scripts + deps for Astro/Starlight site.
docs/astro.config.ts Adds Astro config integrating Starlight, UnoCSS, Vue/React, and custom components.
.gitignore Ignores generated docs type JSON output directory.
Comments suppressed due to low confidence (3)

docs/src/components/landing/Hero.astro:1

  • This copy says the library provides “fully styled” components, but elsewhere (and in this PR) the docs emphasize components ship with zero styles/unstyled primitives. Updating the hero tagline to match the unstyled positioning will prevent confusion and contradictory messaging.
    docs/src/components/landing/CTA.astro:1
  • Correct the casing/spelling of 'ToDay' to 'Today' for a consistent, professional CTA headline.
    docs/src/content/docs/components/aspect-ratio.mdx:1
  • The React anatomy section is currently an empty code block, which reads like a rendering bug in the docs. Either add the React example snippet or remove the React block until it’s ready.

Comment on lines +26 to +32
const themeToggle = document.getElementById('ds-theme-toggle')!;
themeToggle.addEventListener('click', () => {
const current = document.documentElement.dataset.theme;
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.dataset.theme = next;
localStorage.setItem('starlight-theme', next);
});

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline browser script contains TypeScript-only syntax (! non-null assertion). In production it will throw a syntax error and break the theme toggle. Fix by either converting the script to valid JavaScript (remove ! and add a runtime null-check) or by marking the script as TypeScript (e.g., lang=\"ts\") so Astro/Vite transpiles it.

Suggested change
const themeToggle = document.getElementById('ds-theme-toggle')!;
themeToggle.addEventListener('click', () => {
const current = document.documentElement.dataset.theme;
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.dataset.theme = next;
localStorage.setItem('starlight-theme', next);
});
const themeToggle = document.getElementById('ds-theme-toggle');
if (themeToggle) {
themeToggle.addEventListener('click', () => {
const current = document.documentElement.dataset.theme;
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.dataset.theme = next;
localStorage.setItem('starlight-theme', next);
});
}

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +134
const trigger = document.getElementById('ds-fw-trigger')!;
const dropdown = document.getElementById('ds-fw-dropdown')!;
const options = document.querySelectorAll<HTMLButtonElement>('.ds-fw-option');

function setFramework(fw: string) {
document.documentElement.dataset.framework = fw;
localStorage.setItem(STORAGE_KEY, fw);
options.forEach((opt) => {
const isActive = opt.dataset.frameworkOption === fw;
opt.setAttribute('aria-selected', String(isActive));
});
}

function openDropdown() {
dropdown.classList.remove('hidden');
trigger.setAttribute('aria-expanded', 'true');
}

function closeDropdown() {
dropdown.classList.add('hidden');
trigger.setAttribute('aria-expanded', 'false');
}

// Initialize
const saved = localStorage.getItem(STORAGE_KEY) || 'vue';
setFramework(saved);

trigger.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = !dropdown.classList.contains('hidden');
isOpen ? closeDropdown() : openDropdown();
});

options.forEach((opt) => {
opt.addEventListener('click', () => {
const fw = opt.dataset.frameworkOption;
if (fw) setFramework(fw);
closeDropdown();
});
});

// Close on outside click
document.addEventListener('click', (e) => {
if (!dropdown.classList.contains('hidden') && !(e.target as HTMLElement).closest('.ds-framework-switcher')) {
closeDropdown();
}
});

// Close on Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !dropdown.classList.contains('hidden')) {
closeDropdown();
trigger.focus();
}
});

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This client-side <script> uses TypeScript syntax (!, generic type params on querySelectorAll, and type annotations like fw: string). Unless this is explicitly transpiled (e.g., <script lang=\"ts\">), the browser will fail to parse it. Convert to plain JS + runtime checks, or switch the script to TS so it gets compiled.

Suggested change
const trigger = document.getElementById('ds-fw-trigger')!;
const dropdown = document.getElementById('ds-fw-dropdown')!;
const options = document.querySelectorAll<HTMLButtonElement>('.ds-fw-option');
function setFramework(fw: string) {
document.documentElement.dataset.framework = fw;
localStorage.setItem(STORAGE_KEY, fw);
options.forEach((opt) => {
const isActive = opt.dataset.frameworkOption === fw;
opt.setAttribute('aria-selected', String(isActive));
});
}
function openDropdown() {
dropdown.classList.remove('hidden');
trigger.setAttribute('aria-expanded', 'true');
}
function closeDropdown() {
dropdown.classList.add('hidden');
trigger.setAttribute('aria-expanded', 'false');
}
// Initialize
const saved = localStorage.getItem(STORAGE_KEY) || 'vue';
setFramework(saved);
trigger.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = !dropdown.classList.contains('hidden');
isOpen ? closeDropdown() : openDropdown();
});
options.forEach((opt) => {
opt.addEventListener('click', () => {
const fw = opt.dataset.frameworkOption;
if (fw) setFramework(fw);
closeDropdown();
});
});
// Close on outside click
document.addEventListener('click', (e) => {
if (!dropdown.classList.contains('hidden') && !(e.target as HTMLElement).closest('.ds-framework-switcher')) {
closeDropdown();
}
});
// Close on Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !dropdown.classList.contains('hidden')) {
closeDropdown();
trigger.focus();
}
});
const trigger = document.getElementById('ds-fw-trigger');
const dropdown = document.getElementById('ds-fw-dropdown');
const options = document.querySelectorAll('.ds-fw-option');
if (!trigger || !dropdown) {
// Required elements are missing; abort initialization.
console.warn('Framework switcher elements not found in the document.');
} else {
function setFramework(fw) {
const value = String(fw);
document.documentElement.dataset.framework = value;
localStorage.setItem(STORAGE_KEY, value);
options.forEach((opt) => {
const frameworkOption = opt.dataset.frameworkOption;
const isActive = frameworkOption === value;
opt.setAttribute('aria-selected', String(isActive));
});
}
function openDropdown() {
dropdown.classList.remove('hidden');
trigger.setAttribute('aria-expanded', 'true');
}
function closeDropdown() {
dropdown.classList.add('hidden');
trigger.setAttribute('aria-expanded', 'false');
}
// Initialize
const saved = localStorage.getItem(STORAGE_KEY) || 'vue';
setFramework(saved);
trigger.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = !dropdown.classList.contains('hidden');
isOpen ? closeDropdown() : openDropdown();
});
options.forEach((opt) => {
opt.addEventListener('click', () => {
const fw = opt.dataset.frameworkOption;
if (fw) setFramework(fw);
closeDropdown();
});
});
// Close on outside click
document.addEventListener('click', (e) => {
const target = e.target;
if (
!dropdown.classList.contains('hidden') &&
(!(target instanceof Element) ||
!target.closest('.ds-framework-switcher'))
) {
closeDropdown();
}
});
// Close on Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !dropdown.classList.contains('hidden')) {
closeDropdown();
trigger.focus();
}
});
}

Copilot uses AI. Check for mistakes.
Comment on lines +140 to +143
class DesktopStarlightTOC extends HTMLElement {
private _current: HTMLAnchorElement | null = null
private minH: number
private maxH: number

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TOC custom element is defined in a browser <script> but uses TypeScript class property modifiers (private) and type annotations, which are invalid JavaScript and will crash at runtime. Remove TS-only syntax (use JS fields) or mark the script as TypeScript (lang=\"ts\") so Vite transpiles it before shipping to the browser.

Copilot uses AI. Check for mistakes.
Comment on lines +90 to +93
class MobileStarlightTOC extends HTMLElement {
private _current: HTMLAnchorElement | null = null
private minH: number
private maxH: number

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as the desktop TOC: this browser script contains TypeScript-only syntax (private + type annotations). This will cause a client-side syntax error and break the mobile TOC behavior. Convert to valid JS or add lang=\"ts\" so it compiles.

Copilot uses AI. Check for mistakes.
Comment thread docs/package.json
@@ -0,0 +1,35 @@
{
"name": "@destyler-ui/docs",
"private": "true",

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private must be a boolean in package.json. Using a string can break tooling that validates package metadata. Change this to \"private\": true.

Suggested change
"private": "true",
"private": true,

Copilot uses AI. Check for mistakes.
Comment on lines +231 to +248
function initComponentPreviews() {
document.querySelectorAll('.ds-show-code-btn').forEach((btn) => {
btn.addEventListener('click', () => {
const preview = btn.closest('.ds-component-preview')
if (!preview) return
const codeContainer = preview.querySelector<HTMLElement>('.ds-code-container')
if (!codeContainer) return

const isCollapsed = codeContainer.style.gridTemplateRows === '0fr'
codeContainer.style.gridTemplateRows = isCollapsed ? '1fr' : '0fr'
btn.setAttribute('aria-expanded', String(isCollapsed))

const label = btn.querySelector('.ds-show-code-label')
if (label) {
label.textContent = isCollapsed ? 'Hide Code' : 'Show Code'
}
})
})

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initComponentPreviews() is called on initial load and on astro:after-swap, but it unconditionally adds new event listeners each run. This will cause duplicate handlers (multiple toggles/copies per click) after navigations. Guard initialization per button (e.g., a data-initialized flag), or use event delegation on a stable ancestor.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +15
<button
aria-expanded="false"
aria-label={Astro.locals.t('menuButton.accessibleLabel')}
aria-controls="starlight__sidebar"
class="fixed top-[calc((var(--sl-nav-height)-2rem)/2)] end-[var(--sl-nav-pad-x)] z-[var(--sl-z-index-navbar)] flex items-center justify-center size-8 p-0 bg-$sl-color-bg-nav text-$sl-color-gray-3 cursor-pointer transition-colors duration-150 hover:(text-$sl-color-text border-$sl-color-accent) group-aria-expanded:(border-$sl-color-accent text-$sl-color-text) min-[50rem]:hidden"
>

Copilot AI Mar 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component toggles aria-expanded on the custom element (starlight-menu-button) but the actual interactive control is the <button>, which stays aria-expanded=\"false\". This makes the control’s expanded state incorrect for assistive tech. Update aria-expanded on the button (and keep the wrapper attribute only if you need it for styling variants).

Copilot uses AI. Check for mistakes.
@elonehoo
elonehoo merged commit 8851b5e into main Mar 3, 2026
4 checks passed
@elonehoo
elonehoo deleted the docs branch March 3, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants