# Show More

Clips text or composes separate preview, full-content, and trigger snippets for an accessible disclosure.

- Package: `@mielui/svelte`
- Component version: `1.0.0`
- Depends on Mielui components: _internal/utils
- Shared utilities: utils.cn

## Install

~~~~sh
pnpm dlx @mielui/svelte add show-more
~~~~

## API

This reference is generated at build time from the component manifest, public `index.ts`, and documentation examples below. Changes to those source files are reflected here in the published Markdown. Standard Svelte and HTML attributes accepted by the exported prop types are supported.


### ShowMore

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |
| labels | ShowMoreLabels \| undefined | - | No | No | Overrides the built-in text and accessible names. Every key is optional and English is the fallback. |
| lines | number \| undefined | 3 | No | No | Number of visible text lines while collapsed. |
| maxHeight | number \| undefined | 320 | No | No | Maximum expanded height before the content becomes scrollable. |
| defaultExpanded | boolean \| undefined | false | No | No | Initial expanded state when `expanded` is not bound. |
| expanded | boolean \| undefined | defaultExpanded | No | Yes | Bindable disclosure state. |
| onExpandedChange | ((expanded: boolean) => void) \| undefined | - | No | No | Called with the new state when it expands or collapses. |
| children | Snippet<[]> \| undefined | - | No | No | Full content. With preview, this subtree is hidden and inert while collapsed. Content rendered inside. |
| preview | Snippet<[]> \| undefined | - | No | No | Separate collapsed content for disclosures containing interactive controls. |
| trigger | Snippet<[{ expanded: boolean; props: Pick<HTMLButtonAttributes, "id" \| "aria-controls" \| "aria-expanded" \| "onclick" \| "type">; }]> \| undefined | - | No | No | Custom control. Forward props to its native button to preserve disclosure semantics. |
| class | string \| undefined | - | No | No | Classes added to the element. |

Also accepts the native HTML attributes and events listed in the rendered API reference.

### Public types

~~~~ts
import type { DefaultProps } from '@mielui/svelte/utils';
import type { Snippet } from 'svelte';
import type { HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
import ShowMore from './show-more.svelte';

export type ShowMoreLabels = {
    /** Text of the button while collapsed. */
    more?: string;
    /** Text of the button while expanded. */
    less?: string;
    /** Accessible name of the content region when it scrolls or has a preview. */
    region?: string;
};

export type ShowMoreProps = {
    /**
     * Overrides the built-in text and accessible names. Every key is optional and English is the
     * fallback.
     */
    labels?: ShowMoreLabels;
    /** Number of visible text lines while collapsed. */
    lines?: number;
    /** Maximum expanded height before the content becomes scrollable. */
    maxHeight?: number;
    /** Initial expanded state when `expanded` is not bound. */
    defaultExpanded?: boolean;
    /** Bindable disclosure state. */
    expanded?: boolean;
    /** Called with the new state when it expands or collapses. */
    onExpandedChange?: (expanded: boolean) => void;
    /** Full content. With preview, this subtree is hidden and inert while collapsed. */
    children?: Snippet;
    /** Separate collapsed content for disclosures containing interactive controls. */
    preview?: Snippet;
    /** Custom control. Forward props to its native button to preserve disclosure semantics. */
    trigger?: Snippet<
        [
            {
                expanded: boolean;
                props: Pick<
                    HTMLButtonAttributes,
                    'type' | 'id' | 'aria-expanded' | 'aria-controls' | 'onclick'
                >;
            }
        ]
    >;
} & DefaultProps &
    Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'class'>;

export { ShowMore };
export default ShowMore;
~~~~

## Examples

### Capped

~~~~svelte
<script lang="ts">
    import { ShowMore } from '@mielui/svelte/components/show-more';

    const entries = [
        '09:00 — Paused scheduled reports and confirmed the latest backup.',
        '09:03 — Copied project records into the new workspace.',
        '09:06 — Verified uploaded files against their stored checksums.',
        '09:08 — Restored team roles and notification preferences.',
        '09:11 — Ran a sample export and checked the downloaded report.',
        '09:14 — Resumed scheduled jobs. Workspace owners can continue editing.'
    ];
</script>

<ShowMore lines={2} maxHeight={112} labels={{ region: 'Migration activity' }}>
    <div class="flex flex-col gap-2">
        {#each entries as entry (entry)}
            <p>{entry}</p>
        {/each}
    </div>
</ShowMore>
~~~~

### Interactive

~~~~svelte
<script lang="ts">
    import { Button } from '@mielui/svelte/components/button';
    import { ShowMore } from '@mielui/svelte/components/show-more';
</script>

<ShowMore labels={{ region: 'Project details' }} class="w-full max-w-lg">
    {#snippet preview()}
        <p>Project details include the setup guide and support contact.</p>
    {/snippet}
    {#snippet trigger({ expanded, props })}
        <Button
            {...props}
            onclick={(event) => {
                if (event.currentTarget instanceof HTMLButtonElement) {
                    props.onclick?.(event as MouseEvent & { currentTarget: HTMLButtonElement });
                }
            }}
            variant="outline"
            class="mt-3"
        >
            {expanded ? 'Hide project details' : 'View project details'}
        </Button>
    {/snippet}
    <div class="flex flex-col gap-3">
        <p>
            Use the setup guide to configure your workspace, then contact support if you need help.
        </p>
        <div class="flex flex-wrap gap-2">
            <Button href="/docs/installation" variant="outline">Setup guide</Button>
            <Button href="mailto:support@example.com" variant="ghost">Contact support</Button>
        </div>
    </div>
</ShowMore>
~~~~

### Labels

~~~~svelte
<script lang="ts">
    import { ShowMore } from '@mielui/svelte/components/show-more';

    const comments = [
        'Maya: The new limiter looks right to me.',
        'Theo: Can we log the key when a client is throttled?',
        'Amira: Docs need the retry header explained.',
        'Jordan: Approved once the log line is in.',
        'Maya: Log line added in the last commit.'
    ];

    let toggles = $state(0);
</script>

<div class="flex w-full max-w-md flex-col gap-3">
    <ShowMore
        lines={2}
        defaultExpanded
        labels={{
            more: 'Show all 5 comments',
            less: 'Hide older comments'
        }}
        onExpandedChange={() => {
            toggles += 1;
        }}
    >
        <div class="flex flex-col gap-2 text-sm">
            {#each comments as comment (comment)}
                <p>{comment}</p>
            {/each}
        </div>
    </ShowMore>
    <p class="text-sm text-foreground-muted">Toggled {toggles} times</p>
</div>
~~~~

For the rendered reference, visit [/docs/components/show-more](/docs/components/show-more).
